##// END OF EJS Templates
Added support for ContentPane, corrected widget startup calls
cin -
r48:030ea350f98b v1.0.3 default
parent child
Show More
@@ -32,12 +32,12 typescript {
32 32
33 33 configureTsMain {
34 34 compilerOptions {
35 /*baseUrl = "$projectDir/src"
36 paths = [
35 //baseUrl = "$projectDir/src"
36 /*paths = [
37 37 "dojo/*" : [ "typings/dojo/*" ],
38 38 "dijit/*" : [ "typings/dijit/*" ]
39 39 ]*/
40 types = ["requirejs", "dojo-typings"]
40 types = ["requirejs", "dojo-typings", "$projectDir/src/main/typings"]
41 41 }
42 42 }
43 43
@@ -1,9 +1,10
1 1 import { isNull, mixin } from "@implab/core-amd/safe";
2 import { isPlainObject, isNode, isBuildContext, DojoNodePosition, BuildContext } from "./traits";
2 import { isPlainObject, isNode, isBuildContext, DojoNodePosition, BuildContext, isInPage } from "./traits";
3 3
4 4 import dom = require("dojo/dom-construct");
5 5 import registry = require("dijit/registry");
6 6
7
7 8 export abstract class BuildContextBase<TNode extends Node> implements BuildContext<TNode> {
8 9 private _attrs = {};
9 10
@@ -72,7 +73,14 export abstract class BuildContextBase<T
72 73 placeAt(refNode: string | Node, position?: DojoNodePosition) {
73 74 const domNode = this.getDomNode();
74 75 dom.place(domNode, refNode, position);
75 registry.findWidgets(domNode).forEach(w => w.startup());
76 const parentWidget = domNode.parentNode ? registry.getEnclosingWidget(domNode.parentNode) : null;
77
78 if ((parentWidget && parentWidget._started) || isInPage(domNode))
79 this._startup();
80 }
81
82 _startup () {
83 registry.findWidgets(this._getDomNode()).forEach(w => w.startup());
76 84 }
77 85
78 86 abstract _create(attrs: object, children: any[]): void;
@@ -2,14 +2,15 import dom = require("dojo/dom-construct
2 2 import attr = require("dojo/dom-attr");
3 3 import { argumentNotNull } from "@implab/core-amd/safe";
4 4 import { BuildContextBase } from "./BuildContextBase";
5 import registry = require("dijit/registry");
5 6
6 7
7 export class FunctionComponentContext extends BuildContextBase<Element> {
8 private _component: (props: any) => Element;
8 export class FunctionComponentContext extends BuildContextBase<Node> {
9 private _component: (props: any) => any;
9 10
10 private _element: Element | undefined;
11 private _node: Node | undefined;
11 12
12 constructor(component: (props: any) => Element) {
13 constructor(component: (props: any) => any) {
13 14 super();
14 15 argumentNotNull(component, "component");
15 16
@@ -20,13 +21,13 export class FunctionComponentContext ex
20 21 const _attrs: any = attrs || {};
21 22 _attrs.children = children.map(x => this.getChildDom(x));
22 23
23 this._element = this._component.call(null, _attrs);
24 this._node = this.getChildDom(this._component.call(null, _attrs));
24 25 }
25 26
26 27 _getDomNode() {
27 if (!this._element)
28 if (!this._node)
28 29 throw new Error("The instance of the widget isn't created");
29 return this._element;
30 return this._node;
30 31 }
31 32
32 33 }
@@ -2,6 +2,7 import dom = require("dojo/dom-construct
2 2 import attr = require("dojo/dom-attr");
3 3 import { argumentNotEmptyString } from "@implab/core-amd/safe";
4 4 import { BuildContextBase } from "./BuildContextBase";
5 import registry = require("dijit/registry");
5 6
6 7 export class HtmlElementContext extends BuildContextBase<HTMLElement> {
7 8 elementType: string;
@@ -1,7 +1,9
1 1 import dom = require("dojo/dom-construct");
2 2 import { argumentNotNull } from "@implab/core-amd/safe";
3 3 import { BuildContextBase } from "./BuildContextBase";
4 import { DojoNodePosition, isWidget } from "./traits";
4 import { DojoNodePosition, isInPage, isWidget } from "./traits";
5 import registry = require("dijit/registry");
6 import ContentPane = require("dijit/layout/ContentPane");
5 7
6 8 // tslint:disable-next-line: class-name
7 9 export interface _Widget {
@@ -33,13 +35,18 export class WidgetContext extends Build
33 35 const instance = this._getInstance();
34 36
35 37 if (instance.addChild) {
36 if (child instanceof WidgetContext)
38 if (child instanceof WidgetContext) {
37 39 // layout containers add custom logic to addChild methods
38 40 instance.addChild(child.getWidgetInstance());
39 else if (isWidget(child))
41 } else if (isWidget(child)) {
40 42 instance.addChild(child);
41 else
42 instance.addChild(this.getChildDom(child));
43 } else {
44 if (!instance.containerNode)
45 throw new Error("The widget doesn't have neither addChild nor containerNode");
46
47 // the current widget isn't started, it's children shouldn't start too
48 dom.place(this.getChildDom(child), instance.containerNode);
49 }
43 50 } else {
44 51 if (!instance.containerNode)
45 52 throw new Error("The widget doesn't have neither addChild nor containerNode");
@@ -49,10 +56,25 export class WidgetContext extends Build
49 56 }
50 57 }
51 58
52 _create(attrs: object, children: any[]) {
53 this._instance = new this.widgetClass(attrs);
54 if (children)
59 _create(attrs: any, children: any[]) {
60 if (this.widgetClass.prototype instanceof ContentPane) {
61 // a special case for the ContentPane this is for
62 // the compatibility with this heavy widget, all
63 // regular containers could be easily manipulated
64 // through `containerNode` property or `addChild` method.
65
66 // render children to the DocumentFragment
67 const content = document.createDocumentFragment();
68 children.forEach(child => content.appendChild(this.getChildDom(child)));
69
70 // set the content property to the parameters of the widget
71 const _attrs = { ...attrs, content };
72 this._instance = new this.widgetClass(_attrs);
73 } else {
74 this._instance = new this.widgetClass(attrs);
55 75 children.forEach(x => this._addChild(x));
76 }
77
56 78 }
57 79
58 80 private _getInstance() {
@@ -79,14 +101,25 export class WidgetContext extends Build
79 101 if (typeof instance.placeAt === "function") {
80 102 instance.placeAt(refNode, position);
81 103
82 // do we need to force widget startup?
83 if (typeof instance.startup === "function")
84 instance.startup();
104 // fix the dojo startup behavior when the widget is placed
105 // directly to the document and doesn't have any enclosing widgets
106 const parentWidget = instance.domNode.parentNode ?
107 registry.getEnclosingWidget(instance.domNode.parentNode) : null
108 if (!parentWidget && isInPage(instance.domNode))
109 this._startup();
85 110 } else {
111 // the widget doesn't have a placeAt method, strange but whatever
86 112 super.placeAt(refNode, position);
87 113 }
88 114 }
89 115
116 _startup() {
117 const instance = this._getInstance();
118
119 if (typeof instance.startup === "function")
120 instance.startup();
121 }
122
90 123 getWidgetInstance() {
91 124 this.ensureCreated();
92 125 return this._getInstance();
@@ -64,3 +64,10 export function isWidgetConstructor(v: a
64 64 "buildRendering" in v.prototype
65 65 );
66 66 }
67
68 /** Tests whether the specified node is placed in visible dom.
69 * @param {Node} node The node to test
70 */
71 export function isInPage(node: Node) {
72 return (node === document.body) ? false : document.body.contains(node);
73 }
General Comments 0
You need to be logged in to leave comments. Login now