import { isNull, mixin } from "@implab/core-amd/safe"; import { isPlainObject, isNode, isBuildContext, DojoNodePosition, BuildContext } from "./traits"; import dom = require("dojo/dom-construct"); import registry = require("dijit/registry"); export abstract class BuildContextBase implements BuildContext { private _attrs = {}; private _children = new Array(); private _created: boolean = false; visitNext(v: any) { if (this._created) throw new Error("The Element is already created"); if (isNull(v)) return; if (isPlainObject(v)) { mixin(this._attrs, v); } else if (v instanceof Array) { v.forEach(x => this.visitNext(x)); } else { this._children.push(v); } } getChildDom(v: any) { const tv = typeof v; if (tv === "string" || tv === "number" || tv === "boolean" || v instanceof RegExp || v instanceof Date) { return document.createTextNode(v.toString()); } else if (isNode(v)) { return v; } else if (isBuildContext(v)) { return v.getDomNode(); } else { throw new Error("Invalid parameter"); } } ensureCreated() { if (!this._created) { this._create(this._attrs, this._children); this._children = []; this._attrs = {}; this._created = true; } } /** @deprecated will be removed in 1.0.0, use getDomNode() */ getDomElement() { return this.getDomNode(); } /** Creates DOM node if not created. No additional actions are taken. */ getDomNode() { this.ensureCreated(); return this._getDomNode(); } /** Creates DOM node if not created, places it to the specified position * and calls startup() method for all widgets contained by this node. * * @param {string | Node} refNode The reference node where the created * DOM should be placed. * @param {DojoNodePosition} position Optional parameter, specifies the * position relative to refNode. Default is "last" (i.e. last child). */ placeAt(refNode: string | Node, position?: DojoNodePosition) { const domNode = this.getDomNode(); dom.place(domNode, refNode, position); registry.findWidgets(domNode).forEach(w => w.startup()); } abstract _create(attrs: object, children: any[]): void; abstract _getDomNode(): TNode; }