import { djbase, djclass } from "../declare"; import _WidgetBase = require("dijit/_WidgetBase"); import _AttachMixin = require("dijit/_AttachMixin"); import { BuildContext, 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 { set(key: K, value: Attrs[K]): this; set(props: Partial): this; get(key: K): Attrs[K]; on(eventName: K, cb: (evt: Events[K]) => void): dojo.WatchHandle; emit(eventName: K, evt: Omit & EventArgs): void; } @djclass export abstract class DjxWidgetBase extends djbase(_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(): BuildContext; _processTemplateNode( baseNode: T, getAttrFunc: (baseNode: T, attr: string) => string, // 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), // 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 startupWidgets(this.domNode, this.containerNode); super.startup(); } }