##// 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 configureTsMain {
33 configureTsMain {
34 compilerOptions {
34 compilerOptions {
35 /*baseUrl = "$projectDir/src"
35 //baseUrl = "$projectDir/src"
36 paths = [
36 /*paths = [
37 "dojo/*" : [ "typings/dojo/*" ],
37 "dojo/*" : [ "typings/dojo/*" ],
38 "dijit/*" : [ "typings/dijit/*" ]
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 import { isNull, mixin } from "@implab/core-amd/safe";
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 import dom = require("dojo/dom-construct");
4 import dom = require("dojo/dom-construct");
5 import registry = require("dijit/registry");
5 import registry = require("dijit/registry");
6
6
7
7 export abstract class BuildContextBase<TNode extends Node> implements BuildContext<TNode> {
8 export abstract class BuildContextBase<TNode extends Node> implements BuildContext<TNode> {
8 private _attrs = {};
9 private _attrs = {};
9
10
@@ -72,7 +73,14 export abstract class BuildContextBase<T
72 placeAt(refNode: string | Node, position?: DojoNodePosition) {
73 placeAt(refNode: string | Node, position?: DojoNodePosition) {
73 const domNode = this.getDomNode();
74 const domNode = this.getDomNode();
74 dom.place(domNode, refNode, position);
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 abstract _create(attrs: object, children: any[]): void;
86 abstract _create(attrs: object, children: any[]): void;
@@ -2,14 +2,15 import dom = require("dojo/dom-construct
2 import attr = require("dojo/dom-attr");
2 import attr = require("dojo/dom-attr");
3 import { argumentNotNull } from "@implab/core-amd/safe";
3 import { argumentNotNull } from "@implab/core-amd/safe";
4 import { BuildContextBase } from "./BuildContextBase";
4 import { BuildContextBase } from "./BuildContextBase";
5 import registry = require("dijit/registry");
5
6
6
7
7 export class FunctionComponentContext extends BuildContextBase<Element> {
8 export class FunctionComponentContext extends BuildContextBase<Node> {
8 private _component: (props: any) => Element;
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 super();
14 super();
14 argumentNotNull(component, "component");
15 argumentNotNull(component, "component");
15
16
@@ -20,13 +21,13 export class FunctionComponentContext ex
20 const _attrs: any = attrs || {};
21 const _attrs: any = attrs || {};
21 _attrs.children = children.map(x => this.getChildDom(x));
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 _getDomNode() {
27 _getDomNode() {
27 if (!this._element)
28 if (!this._node)
28 throw new Error("The instance of the widget isn't created");
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 import attr = require("dojo/dom-attr");
2 import attr = require("dojo/dom-attr");
3 import { argumentNotEmptyString } from "@implab/core-amd/safe";
3 import { argumentNotEmptyString } from "@implab/core-amd/safe";
4 import { BuildContextBase } from "./BuildContextBase";
4 import { BuildContextBase } from "./BuildContextBase";
5 import registry = require("dijit/registry");
5
6
6 export class HtmlElementContext extends BuildContextBase<HTMLElement> {
7 export class HtmlElementContext extends BuildContextBase<HTMLElement> {
7 elementType: string;
8 elementType: string;
@@ -1,7 +1,9
1 import dom = require("dojo/dom-construct");
1 import dom = require("dojo/dom-construct");
2 import { argumentNotNull } from "@implab/core-amd/safe";
2 import { argumentNotNull } from "@implab/core-amd/safe";
3 import { BuildContextBase } from "./BuildContextBase";
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 // tslint:disable-next-line: class-name
8 // tslint:disable-next-line: class-name
7 export interface _Widget {
9 export interface _Widget {
@@ -33,13 +35,18 export class WidgetContext extends Build
33 const instance = this._getInstance();
35 const instance = this._getInstance();
34
36
35 if (instance.addChild) {
37 if (instance.addChild) {
36 if (child instanceof WidgetContext)
38 if (child instanceof WidgetContext) {
37 // layout containers add custom logic to addChild methods
39 // layout containers add custom logic to addChild methods
38 instance.addChild(child.getWidgetInstance());
40 instance.addChild(child.getWidgetInstance());
39 else if (isWidget(child))
41 } else if (isWidget(child)) {
40 instance.addChild(child);
42 instance.addChild(child);
41 else
43 } else {
42 instance.addChild(this.getChildDom(child));
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 } else {
50 } else {
44 if (!instance.containerNode)
51 if (!instance.containerNode)
45 throw new Error("The widget doesn't have neither addChild nor containerNode");
52 throw new Error("The widget doesn't have neither addChild nor containerNode");
@@ -49,12 +56,27 export class WidgetContext extends Build
49 }
56 }
50 }
57 }
51
58
52 _create(attrs: object, children: any[]) {
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 {
53 this._instance = new this.widgetClass(attrs);
74 this._instance = new this.widgetClass(attrs);
54 if (children)
55 children.forEach(x => this._addChild(x));
75 children.forEach(x => this._addChild(x));
56 }
76 }
57
77
78 }
79
58 private _getInstance() {
80 private _getInstance() {
59 if (!this._instance)
81 if (!this._instance)
60 throw new Error("The instance of the widget isn't created");
82 throw new Error("The instance of the widget isn't created");
@@ -79,12 +101,23 export class WidgetContext extends Build
79 if (typeof instance.placeAt === "function") {
101 if (typeof instance.placeAt === "function") {
80 instance.placeAt(refNode, position);
102 instance.placeAt(refNode, position);
81
103
82 // do we need to force widget 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();
110 } else {
111 // the widget doesn't have a placeAt method, strange but whatever
112 super.placeAt(refNode, position);
113 }
114 }
115
116 _startup() {
117 const instance = this._getInstance();
118
83 if (typeof instance.startup === "function")
119 if (typeof instance.startup === "function")
84 instance.startup();
120 instance.startup();
85 } else {
86 super.placeAt(refNode, position);
87 }
88 }
121 }
89
122
90 getWidgetInstance() {
123 getWidgetInstance() {
@@ -64,3 +64,10 export function isWidgetConstructor(v: a
64 "buildRendering" in v.prototype
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