|
|
import { AbstractConstructor, djbase, djclass } from "../declare";
|
|
|
import _WidgetBase = require("dijit/_WidgetBase");
|
|
|
import _AttachMixin = require("dijit/_AttachMixin");
|
|
|
import { Rendition, isNode, startupWidgets } from "./traits";
|
|
|
import registry = require("dijit/registry");
|
|
|
|
|
|
// type Handle = dojo.Handle;
|
|
|
|
|
|
export interface EventArgs {
|
|
|
bubbles?: boolean;
|
|
|
|
|
|
cancelable?: boolean;
|
|
|
|
|
|
composed?: boolean;
|
|
|
}
|
|
|
|
|
|
export interface DjxWidgetBase<Attrs = {}, Events extends { [name in keyof Events]: Event } = {}> extends
|
|
|
_WidgetBase<Events> {
|
|
|
}
|
|
|
|
|
|
type _super = {
|
|
|
startup(): void;
|
|
|
}
|
|
|
|
|
|
@djclass
|
|
|
export abstract class DjxWidgetBase<Attrs = {}, Events = {}> extends djbase<_super, _AttachMixin>(_WidgetBase, _AttachMixin) {
|
|
|
|
|
|
buildRendering() {
|
|
|
this.domNode = this.render().getDomNode();
|
|
|
super.buildRendering();
|
|
|
|
|
|
// now we should get assigned data-dojo-attach-points
|
|
|
// place the contents of the original srcNode to the containerNode
|
|
|
const src = this.srcNodeRef;
|
|
|
const dest = this.containerNode;
|
|
|
|
|
|
if (src && dest) {
|
|
|
while (src.firstChild)
|
|
|
dest.appendChild(src.firstChild);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
abstract render(): Rendition<HTMLElement>;
|
|
|
|
|
|
_processTemplateNode<T extends (Element | Node | _WidgetBase)>(
|
|
|
baseNode: T,
|
|
|
getAttrFunc: (baseNode: T, attr: string) => any,
|
|
|
// tslint:disable-next-line: ban-types
|
|
|
attachFunc: (node: T, type: string, func?: Function) => dojo.Handle
|
|
|
): boolean {
|
|
|
if (isNode(baseNode)) {
|
|
|
const w = registry.byNode(baseNode);
|
|
|
if (w) {
|
|
|
// from dijit/_WidgetsInTemplateMixin
|
|
|
this._processTemplateNode(w,
|
|
|
(n, p) => n.get(p as any), // callback to get a property of a widget
|
|
|
(widget, type, callback) => {
|
|
|
if (!callback)
|
|
|
throw new Error("The callback must be specified");
|
|
|
|
|
|
// callback to do data-dojo-attach-event to a widget
|
|
|
if (type in widget) {
|
|
|
// back-compat, remove for 2.0
|
|
|
return widget.connect(widget, type, callback as EventListener);
|
|
|
} else {
|
|
|
// 1.x may never hit this branch, but it's the default for 2.0
|
|
|
return widget.on(type, callback);
|
|
|
}
|
|
|
|
|
|
});
|
|
|
// don't process widgets internals
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
return super._processTemplateNode(baseNode, getAttrFunc, attachFunc);
|
|
|
}
|
|
|
|
|
|
/** Starts current widget and all its supporting widgets (placed outside
|
|
|
* `containerNode`) and child widgets (placed inside `containerNode`)
|
|
|
*/
|
|
|
startup() {
|
|
|
// startup supporting widgets
|
|
|
registry.findWidgets(this.domNode, this.containerNode).forEach(w => w.startup());
|
|
|
super.startup();
|
|
|
}
|
|
|
}
|
|
|
|