This repository has been archived on 2023-03-18. You can view files and clone it, but cannot push or open issues or pull requests.
osr-discourse-src/app/assets/javascripts/discourse/widgets/glue.js.es6

72 lines
1.9 KiB
JavaScript

import { cancel } from "@ember/runloop";
import { scheduleOnce } from "@ember/runloop";
import { diff, patch } from "virtual-dom";
import { queryRegistry } from "discourse/widgets/widget";
import DirtyKeys from "discourse/lib/dirty-keys";
import ENV from "discourse-common/config/environment";
export default class WidgetGlue {
constructor(name, register, attrs) {
this._tree = null;
this._rootNode = null;
this.register = register;
this.attrs = attrs;
this._timeout = null;
this.dirtyKeys = new DirtyKeys(name);
this._widgetClass =
queryRegistry(name) || this.register.lookupFactory(`widget:${name}`);
if (!this._widgetClass) {
// eslint-disable-next-line no-console
console.error(`Error: Could not find widget: ${name}`);
}
}
appendTo(elem) {
this._rootNode = elem;
this.queueRerender();
}
queueRerender() {
this._timeout = scheduleOnce("render", this, this.rerenderWidget);
}
rerenderWidget() {
cancel(this._timeout);
// in test mode return early if store cannot be found
if (ENV.environment === "test") {
try {
this.register.lookup("service:store");
} catch (e) {
return;
}
}
const newTree = new this._widgetClass(this.attrs, this.register, {
dirtyKeys: this.dirtyKeys
});
const patches = diff(this._tree || this._rootNode, newTree);
newTree._rerenderable = this;
this._rootNode = patch(this._rootNode, patches);
this._tree = newTree;
}
cleanUp() {
const widgets = [];
const findWidgets = widget => {
widget.vnode.children.forEach(child => {
if (child.constructor.name === "CustomWidget") {
widgets.push(child);
findWidgets(child, widgets);
}
});
};
findWidgets(this._tree, widgets);
widgets.reverse().forEach(widget => widget.destroy());
cancel(this._timeout);
}
}