##// END OF EJS Templates
start implementing traits::placeAt
cin -
r95:65559e82c81e v1.3
parent child
Show More
@@ -1,161 +1,206
1 import { IDestroyable } from "@implab/core-amd/interfaces";
1 import { IDestroyable } from "@implab/core-amd/interfaces";
2 import { isDestroyable } from "@implab/core-amd/safe";
2 import { isDestroyable } from "@implab/core-amd/safe";
3 import _WidgetBase = require("dijit/_WidgetBase");
3 import _WidgetBase = require("dijit/_WidgetBase");
4 import registry = require("dijit/registry");
4 import registry = require("dijit/registry");
5 import dom = require("dojo/dom-construct");
5 import dom = require("dojo/dom-construct");
6
6
7 type _WidgetBaseConstructor = typeof _WidgetBase;
7 type _WidgetBaseConstructor = typeof _WidgetBase;
8
8
9 export type DojoNodePosition = "first" | "after" | "before" | "last" | "replace" | "only" | number;
9 export type DojoNodePosition = "first" | "after" | "before" | "last" | "replace" | "only" | number;
10
10
11 export type DojoNodeLocation = [Node | null, DojoNodePosition];
11 export type DojoNodeLocation = [Node | null, DojoNodePosition];
12
12
13 export interface Rendition<TNode extends Node = Node> {
13 export interface Rendition<TNode extends Node = Node> {
14 getDomNode(): TNode;
14 getDomNode(): TNode;
15
15
16 placeAt(refNode: string | Node, position?: DojoNodePosition): void;
16 placeAt(refNode: string | Node, position?: DojoNodePosition): void;
17 }
17 }
18
18
19 /**
19 /**
20 * @deprecated use Rendition
20 * @deprecated use Rendition
21 */
21 */
22 export type BuildContext<TNode extends Node = Node> = Rendition<TNode>;
22 export type BuildContext<TNode extends Node = Node> = Rendition<TNode>;
23
23
24 export interface IRecursivelyDestroyable {
24 export interface IRecursivelyDestroyable {
25 destroyRecursive(): void;
25 destroyRecursive(): void;
26 }
26 }
27
27
28 export function isNode(el: any): el is Node {
28 export function isNode(el: any): el is Node {
29 return el && el.nodeName && el.nodeType;
29 return el && el.nodeName && el.nodeType;
30 }
30 }
31
31
32 export function isElementNode(el: any): el is Element {
32 export function isElementNode(el: any): el is Element {
33 return isNode(el) && el.nodeType === 1;
33 return isNode(el) && el.nodeType === 1;
34 }
34 }
35
35
36 export function isTextNode(el: any): el is Text {
36 export function isTextNode(el: any): el is Text {
37 return isNode(el) && el.nodeType === 3;
37 return isNode(el) && el.nodeType === 3;
38 }
38 }
39
39
40 export function isProcessingInstructionNode(el: any): el is ProcessingInstruction {
40 export function isProcessingInstructionNode(el: any): el is ProcessingInstruction {
41 return isNode(el) && el.nodeType === 7;
41 return isNode(el) && el.nodeType === 7;
42 }
42 }
43
43
44 export function isCommentNode(el: any): el is Comment {
44 export function isCommentNode(el: any): el is Comment {
45 return isNode(el) && el.nodeType === 8;
45 return isNode(el) && el.nodeType === 8;
46 }
46 }
47
47
48 export function isDocumentNode(el: any): el is Document {
48 export function isDocumentNode(el: any): el is Document {
49 return isNode(el) && el.nodeType === 9;
49 return isNode(el) && el.nodeType === 9;
50 }
50 }
51
51
52 export function isDocumentTypeNode(el: any): el is DocumentType {
52 export function isDocumentTypeNode(el: any): el is DocumentType {
53 return isNode(el) && el.nodeType === 10;
53 return isNode(el) && el.nodeType === 10;
54 }
54 }
55
55
56 export function isDocumentFragmentNode(el: any): el is DocumentFragment {
56 export function isDocumentFragmentNode(el: any): el is DocumentFragment {
57 return isNode(el) && el.nodeType === 11;
57 return isNode(el) && el.nodeType === 11;
58 }
58 }
59
59
60 export function isWidget(v: any): v is _WidgetBase {
60 export function isWidget(v: any): v is _WidgetBase {
61 return v && "domNode" in v;
61 return v && "domNode" in v;
62 }
62 }
63
63
64 export function isRendition(v: any): v is Rendition {
64 export function isRendition(v: any): v is Rendition {
65 return v && typeof v.getDomElement === "function";
65 return v && typeof v.getDomElement === "function";
66 }
66 }
67
67
68 /**
68 /**
69 * @deprecated use isRendition
69 * @deprecated use isRendition
70 */
70 */
71 export const isBuildContext = isRendition;
71 export const isBuildContext = isRendition;
72
72
73 export function isPlainObject(v: object) {
73 export function isPlainObject(v: object) {
74 if (typeof v !== "object")
74 if (typeof v !== "object")
75 return false;
75 return false;
76
76
77 const vp = Object.getPrototypeOf(v);
77 const vp = Object.getPrototypeOf(v);
78 return !vp || vp === Object.prototype;
78 return !vp || vp === Object.prototype;
79 }
79 }
80
80
81 export function isWidgetConstructor(v: any): v is _WidgetBaseConstructor {
81 export function isWidgetConstructor(v: any): v is _WidgetBaseConstructor {
82 return typeof v === "function" && v.prototype && (
82 return typeof v === "function" && v.prototype && (
83 "domNode" in v.prototype ||
83 "domNode" in v.prototype ||
84 "buildRendering" in v.prototype
84 "buildRendering" in v.prototype
85 );
85 );
86 }
86 }
87
87
88 /** Tests whether the specified node is placed in visible dom.
88 /** Tests whether the specified node is placed in visible dom.
89 * @param {Node} node The node to test
89 * @param {Node} node The node to test
90 */
90 */
91 export function isInPage(node: Node) {
91 export function isInPage(node: Node) {
92 return (node === document.body) ? false : document.body.contains(node);
92 return (node === document.body) ? false : document.body.contains(node);
93 }
93 }
94
94
95 export function isRecursivelyDestroyable(target: any): target is IRecursivelyDestroyable {
95 export function isRecursivelyDestroyable(target: any): target is IRecursivelyDestroyable {
96 return target && typeof target.destroyRecursive === "function";
96 return target && typeof target.destroyRecursive === "function";
97 }
97 }
98
98
99
99
100 /** Destroys DOM Node with all contained widgets.
100 /** Destroys DOM Node with all contained widgets.
101 * If the specified node is the root node of a widget, then the
101 * If the specified node is the root node of a widget, then the
102 * widget will be destroyed.
102 * widget will be destroyed.
103 *
103 *
104 * @param target DOM Node or widget to destroy
104 * @param target DOM Node or widget to destroy
105 */
105 */
106 export function destroy(target: Node | IDestroyable | IRecursivelyDestroyable) {
106 export function destroy(target: Node | IDestroyable | IRecursivelyDestroyable) {
107 if (isRecursivelyDestroyable(target)) {
107 if (isRecursivelyDestroyable(target)) {
108 target.destroyRecursive();
108 target.destroyRecursive();
109 } else if (isDestroyable(target)) {
109 } else if (isDestroyable(target)) {
110 target.destroy();
110 target.destroy();
111 } else if (isNode(target)) {
111 } else if (isNode(target)) {
112 if (isElementNode(target)) {
112 if (isElementNode(target)) {
113 const w = registry.byNode(target);
113 const w = registry.byNode(target);
114 if (w) {
114 if (w) {
115 w.destroyRecursive();
115 w.destroyRecursive();
116 } else {
116 } else {
117 registry.findWidgets(target).forEach(destroy);
117 registry.findWidgets(target).forEach(destroy);
118 dom.destroy(target);
118 dom.destroy(target);
119 }
119 }
120 }
120 }
121 }
121 }
122 }
122 }
123
123
124 /** Empties a content of the specified node and destroys all contained widgets.
124 /** Empties a content of the specified node and destroys all contained widgets.
125 *
125 *
126 * @param target DOM node to .
126 * @param target DOM node to .
127 */
127 */
128 export function emptyNode(target: Node) {
128 export function emptyNode(target: Node) {
129 registry.findWidgets(target).forEach(destroy);
129 registry.findWidgets(target).forEach(destroy);
130 dom.empty(target);
130 dom.empty(target);
131 }
131 }
132
132
133 /** This function starts all widgets inside the DOM node if the target is a node
133 /** This function starts all widgets inside the DOM node if the target is a node
134 * or starts widget itself if the target is the widget. If the specified node
134 * or starts widget itself if the target is the widget. If the specified node
135 * associated with the widget that widget will be started.
135 * associated with the widget that widget will be started.
136 *
136 *
137 * @param target DOM node to find and start widgets or the widget itself.
137 * @param target DOM node to find and start widgets or the widget itself.
138 */
138 */
139 export function startupWidgets(target: Node | _WidgetBase, skipNode?: Node) {
139 export function startupWidgets(target: Node | _WidgetBase, skipNode?: Node) {
140 if (isNode(target)) {
140 if (isNode(target)) {
141 if (isElementNode(target)) {
141 if (isElementNode(target)) {
142 const w = registry.byNode(target);
142 const w = registry.byNode(target);
143 if (w) {
143 if (w) {
144 if (w.startup)
144 if (w.startup)
145 w.startup();
145 w.startup();
146 } else {
146 } else {
147 registry.findWidgets(target, skipNode).forEach(x => x.startup());
147 registry.findWidgets(target, skipNode).forEach(x => x.startup());
148 }
148 }
149 }
149 }
150 } else {
150 } else {
151 if (target.startup)
151 if (target.startup)
152 target.startup();
152 target.startup();
153 }
153 }
154 }
154 }
155
155
156 export function locateNode(node: Node): DojoNodeLocation {
156 export function locateNode(node: Node): DojoNodeLocation {
157 const next = node.nextSibling;
157 const next = node.nextSibling;
158 return next ?
158 return next ?
159 [next, "before"] :
159 [next, "before"] :
160 [node.parentNode, "last"];
160 [node.parentNode, "last"];
161 }
162
163 export const placeAt = (node: Node, refNodeOrId: string | Node, position: DojoNodePosition) => {
164 const collect = (collection: HTMLCollection) => {
165 const items = [];
166 for (let i = 0, n = collection.length; i < n; i++) {
167 items.push(collection[i]);
168 }
169 return items;
170 };
171
172 const startup = (node: Node) => {
173 if (node.parentNode) {
174 const parentWidget = registry.getEnclosingWidget(node.parentNode);
175 if (parentWidget && parentWidget._started)
176 return startupWidgets(node);
177 }
178 if (isInPage(node))
179 startupWidgets(node);
180 };
181
182 const ref = typeof refNodeOrId == "string" ? document.getElementById(refNodeOrId) : refNodeOrId;
183 if (!ref)
184 return;
185
186 const parent = ref.parentNode;
187
188 if (typeof position == "number") {
189
190 } else {
191 switch(position) {
192 case "before":
193 if (parent)
194 parent.insertBefore(node,ref);
195 case "after":
196 if (parent)
197 parent.insertBefore(node, ref.nextSibling);
198 }
199 }
200
201 const startupPending = isDocumentFragmentNode(node) ? collect(node.children) : [node];
202
203 dom.place(node, refNodeOrId, position);
204
205 startupPending.forEach(startup);
161 } No newline at end of file
206 }
General Comments 0
You need to be logged in to leave comments. Login now