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