mirror of
https://github.com/discourse/discourse.git
synced 2025-01-19 07:52:45 +08:00
DEV: Refactor user-tip to avoid unneeded wrapper element (#29365)
We were using a modifier purely for its lifecycle hooks - not to modify an element. This commit switches to using a helper, which provides a similar lifecycle, but without needing to be attached to an element.
This commit is contained in:
parent
adef7081a2
commit
c6c09db5b0
|
@ -4,6 +4,7 @@ import { schedule } from "@ember/runloop";
|
||||||
import { service } from "@ember/service";
|
import { service } from "@ember/service";
|
||||||
import { modifier } from "ember-modifier";
|
import { modifier } from "ember-modifier";
|
||||||
import UserTipContainer from "discourse/components/user-tip-container";
|
import UserTipContainer from "discourse/components/user-tip-container";
|
||||||
|
import helperFn from "discourse/helpers/helper-fn";
|
||||||
import escape from "discourse-common/lib/escape";
|
import escape from "discourse-common/lib/escape";
|
||||||
import { iconHTML } from "discourse-common/lib/icon-library";
|
import { iconHTML } from "discourse-common/lib/icon-library";
|
||||||
import I18n from "discourse-i18n";
|
import I18n from "discourse-i18n";
|
||||||
|
@ -14,7 +15,7 @@ export default class UserTip extends Component {
|
||||||
@service userTips;
|
@service userTips;
|
||||||
@service tooltip;
|
@service tooltip;
|
||||||
|
|
||||||
registerTip = modifier(() => {
|
registerTip = helperFn((_, on) => {
|
||||||
const tip = {
|
const tip = {
|
||||||
id: this.args.id,
|
id: this.args.id,
|
||||||
priority: this.args.priority ?? 0,
|
priority: this.args.priority ?? 0,
|
||||||
|
@ -22,9 +23,9 @@ export default class UserTip extends Component {
|
||||||
|
|
||||||
this.userTips.addAvailableTip(tip);
|
this.userTips.addAvailableTip(tip);
|
||||||
|
|
||||||
return () => {
|
on.cleanup(() => {
|
||||||
this.userTips.removeAvailableTip(tip);
|
this.userTips.removeAvailableTip(tip);
|
||||||
};
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
tip = modifier((element) => {
|
tip = modifier((element) => {
|
||||||
|
@ -82,10 +83,9 @@ export default class UserTip extends Component {
|
||||||
}
|
}
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div {{this.registerTip}}>
|
{{this.registerTip}}
|
||||||
{{#if this.shouldRenderTip}}
|
{{#if this.shouldRenderTip}}
|
||||||
<span {{this.tip}}></span>
|
<span {{this.tip}}></span>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
}
|
}
|
||||||
|
|
50
app/assets/javascripts/discourse/app/helpers/helper-fn.js
Normal file
50
app/assets/javascripts/discourse/app/helpers/helper-fn.js
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import Helper from "@ember/component/helper";
|
||||||
|
import { registerDestructor } from "@ember/destroyable";
|
||||||
|
import { bind } from "discourse-common/utils/decorators";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build an Ember helper with cleanup logic. The passed function will be called with the named argument,
|
||||||
|
* and an 'on' utility object which allows you to register a cleanup function via `on.cleanup(...)`.
|
||||||
|
*
|
||||||
|
* Whenever any autotracked state is changed, the cleanup function will be run, and your function
|
||||||
|
* will be re-evaluated.
|
||||||
|
*
|
||||||
|
* @param {(args: object, on: { cleanup: () => void } ) => any} fn - The helper function.
|
||||||
|
*/
|
||||||
|
export default function helperFn(callback) {
|
||||||
|
return class extends Helper {
|
||||||
|
cleanupFn = null;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super(...arguments);
|
||||||
|
registerDestructor(this, this.cleanup);
|
||||||
|
}
|
||||||
|
|
||||||
|
compute(positional, named) {
|
||||||
|
if (positional.length) {
|
||||||
|
throw new Error(
|
||||||
|
"Positional arguments are not permitted for helperFn-defined helpers. Use named arguments instead."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.cleanup();
|
||||||
|
|
||||||
|
const on = {
|
||||||
|
cleanup: (fn) => {
|
||||||
|
if (this.cleanupFn) {
|
||||||
|
throw new Error("on.cleanup can only be called once");
|
||||||
|
}
|
||||||
|
this.cleanupFn = fn;
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return callback(named, on);
|
||||||
|
}
|
||||||
|
|
||||||
|
@bind
|
||||||
|
cleanup() {
|
||||||
|
this.cleanupFn?.();
|
||||||
|
this.cleanupFn = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user