]>
git.wh0rd.org - tt-rss.git/blob - lib/dojo/dom-construct.js.uncompressed.js
1 define("dojo/dom-construct", ["exports", "./_base/kernel", "./sniff", "./_base/window", "./dom", "./dom-attr", "./on"],
2 function(exports
, dojo
, has
, win
, dom
, attr
, on
){
6 // This module defines the core dojo DOM construction API.
8 // TODOC: summary not showing up in output, see https://github.com/csnover/js-doc-parse/issues/42
10 // support stuff for toDom()
16 tr
: ["table", "tbody"],
17 td
: ["table", "tbody", "tr"],
18 th
: ["table", "thead", "tr"],
22 col
: ["table", "colgroup"],
25 reTag
= /<\s*([\w\:]+)/,
26 masterNode
= {}, masterNum
= 0,
27 masterName
= "__" + dojo
._scopeName
+ "ToDomId";
29 // generate start/end tag strings to use
30 // for the injection for each special tag wrap case.
31 for(var param
in tagWrap
){
32 if(tagWrap
.hasOwnProperty(param
)){
33 var tw
= tagWrap
[param
];
34 tw
.pre
= param
== "option" ? '<select multiple="multiple">' : "<" + tw
.join("><") + ">";
35 tw
.post
= "</" + tw
.reverse().join("></") + ">";
36 // the last line is destructive: it reverses the array,
37 // but we don't care at this point
41 function _insertBefore(/*DomNode*/ node
, /*DomNode*/ ref
){
42 var parent
= ref
.parentNode
;
44 parent
.insertBefore(node
, ref
);
48 function _insertAfter(/*DomNode*/ node
, /*DomNode*/ ref
){
50 // Try to insert node after ref
51 var parent
= ref
.parentNode
;
53 if(parent
.lastChild
== ref
){
54 parent
.appendChild(node
);
56 parent
.insertBefore(node
, ref
.nextSibling
);
61 exports
.toDom
= function toDom(frag
, doc
){
63 // instantiates an HTML fragment returning the corresponding DOM.
67 // optional document to use when creating DOM nodes, defaults to
68 // dojo.doc if not specified.
70 // Document fragment, unless it's a single node in which case it returns the node itself
72 // Create a table row:
73 // | var tr = dojo.toDom("<tr><td>First!</td></tr>");
76 var masterId
= doc
[masterName
];
78 doc
[masterName
] = masterId
= ++masterNum
+ "";
79 masterNode
[masterId
] = doc
.createElement("div");
82 // make sure the frag is a string.
85 // find the starting tag, and get node wrapper
86 var match
= frag
.match(reTag
),
87 tag
= match
? match
[1].toLowerCase() : "",
88 master
= masterNode
[masterId
],
90 if(match
&& tagWrap
[tag
]){
92 master
.innerHTML
= wrap
.pre
+ frag
+ wrap
.post
;
93 for(i
= wrap
.length
; i
; --i
){
94 master
= master
.firstChild
;
97 master
.innerHTML
= frag
;
100 // one node shortcut => return the node itself
101 if(master
.childNodes
.length
== 1){
102 return master
.removeChild(master
.firstChild
); // DOMNode
105 // return multiple nodes as a document fragment
106 df
= doc
.createDocumentFragment();
107 while((fc
= master
.firstChild
)){ // intentional assignment
110 return df
; // DocumentFragment
113 exports
.place
= function place(/*DOMNode|String*/ node
, /*DOMNode|String*/ refNode
, /*String|Number?*/ position
){
115 // Attempt to insert node into the DOM, choosing from various positioning options.
116 // Returns the first argument resolved to a DOM node.
117 // node: DOMNode|String
118 // id or node reference, or HTML fragment starting with "<" to place relative to refNode
119 // refNode: DOMNode|String
120 // id or node reference to use as basis for placement
121 // position: String|Number?
122 // string noting the position of node relative to refNode or a
123 // number indicating the location in the childNodes collection of refNode.
124 // Accepted string values are:
133 // "first" and "last" indicate positions as children of refNode, "replace" replaces refNode,
134 // "only" replaces all children. position defaults to "last" if not specified
136 // Returned values is the first argument resolved to a DOM node.
138 // .place() is also a method of `dojo/NodeList`, allowing `dojo.query` node lookups.
140 // Place a node by string id as the last child of another node by string id:
141 // | dojo.place("someNode", "anotherNode");
143 // Place a node by string id before another node by string id
144 // | dojo.place("someNode", "anotherNode", "before");
146 // Create a Node, and place it in the body element (last child):
147 // | dojo.place("<div></div>", dojo.body());
149 // Put a new LI as the first child of a list by id:
150 // | dojo.place("<li></li>", "someUl", "first");
152 refNode
= dom
.byId(refNode
);
153 if(typeof node
== "string"){ // inline'd type check
154 node
= /^\s*</.test(node
) ? exports
.toDom(node
, refNode
.ownerDocument
) : dom
.byId(node
);
156 if(typeof position
== "number"){ // inline'd type check
157 var cn
= refNode
.childNodes
;
158 if(!cn
.length
|| cn
.length
<= position
){
159 refNode
.appendChild(node
);
161 _insertBefore(node
, cn
[position
< 0 ? 0 : position
]);
166 _insertBefore(node
, refNode
);
169 _insertAfter(node
, refNode
);
172 refNode
.parentNode
.replaceChild(node
, refNode
);
175 exports
.empty(refNode
);
176 refNode
.appendChild(node
);
179 if(refNode
.firstChild
){
180 _insertBefore(node
, refNode
.firstChild
);
183 // else fallthrough...
184 default: // aka: last
185 refNode
.appendChild(node
);
188 return node
; // DomNode
191 exports
.create
= function create(/*DOMNode|String*/ tag
, /*Object*/ attrs
, /*DOMNode|String?*/ refNode
, /*String?*/ pos
){
193 // Create an element, allowing for optional attribute decoration
196 // A DOM Element creation function. A shorthand method for creating a node or
197 // a fragment, and allowing for a convenient optional attribute setting step,
198 // as well as an optional DOM placement reference.
200 // Attributes are set by passing the optional object through `dojo.setAttr`.
201 // See `dojo.setAttr` for noted caveats and nuances, and API if applicable.
203 // Placement is done via `dojo.place`, assuming the new node to be the action
204 // node, passing along the optional reference node and position.
205 // tag: DOMNode|String
206 // A string of the element to create (eg: "div", "a", "p", "li", "script", "br"),
207 // or an existing DOM node to process.
209 // An object-hash of attributes to set on the newly created node.
210 // Can be null, if you don't want to set any attributes/styles.
211 // See: `dojo.setAttr` for a description of available attributes.
212 // refNode: DOMNode|String?
213 // Optional reference node. Used by `dojo.place` to place the newly created
214 // node somewhere in the dom relative to refNode. Can be a DomNode reference
215 // or String ID of a node.
217 // Optional positional reference. Defaults to "last" by way of `dojo.place`,
218 // though can be set to "first","after","before","last", "replace" or "only"
219 // to further control the placement of the new node relative to the refNode.
220 // 'refNode' is required if a 'pos' is specified.
223 // | var n = dojo.create("div");
226 // Create a DIV with content:
227 // | var n = dojo.create("div", { innerHTML:"<p>hi</p>" });
230 // Place a new DIV in the BODY, with no attributes set
231 // | var n = dojo.create("div", null, dojo.body());
234 // Create an UL, and populate it with LI's. Place the list as the first-child of a
235 // node with id="someId":
236 // | var ul = dojo.create("ul", null, "someId", "first");
237 // | var items = ["one", "two", "three", "four"];
238 // | dojo.forEach(items, function(data){
239 // | dojo.create("li", { innerHTML: data }, ul);
243 // Create an anchor, with an href. Place in BODY:
244 // | dojo.create("a", { href:"foo.html", title:"Goto FOO!" }, dojo.body());
247 // Create a `dojo/NodeList()` from a new element (for syntactic sugar):
248 // | dojo.query(dojo.create('div'))
249 // | .addClass("newDiv")
250 // | .onclick(function(e){ console.log('clicked', e.target) })
251 // | .place("#someNode"); // redundant, but cleaner.
255 refNode
= dom
.byId(refNode
);
256 doc
= refNode
.ownerDocument
;
258 if(typeof tag
== "string"){ // inline'd type check
259 tag
= doc
.createElement(tag
);
261 if(attrs
){ attr
.set(tag
, attrs
); }
262 if(refNode
){ exports
.place(tag
, refNode
, pos
); }
263 return tag
; // DomNode
266 var _empty
= has("ie") ?
267 function(/*DomNode*/ node
){
269 node
.innerHTML
= ""; // really fast when it works
270 }catch(e
){ // IE can generate Unknown Error
271 for(var c
; c
= node
.lastChild
;){ // intentional assignment
272 _destroy(c
, node
); // destroy is better than removeChild so TABLE elements are removed in proper order
276 function(/*DomNode*/ node
){
280 exports
.empty
= function empty(/*DOMNode|String*/ node
){
282 // safely removes all children of the node.
283 // node: DOMNode|String
284 // a reference to a DOM node or an id.
286 // Destroy node's children byId:
287 // | dojo.empty("someId");
290 // Destroy all nodes' children in a list by reference:
291 // | dojo.query(".someNode").forEach(dojo.empty);
293 _empty(dom
.byId(node
));
297 function _destroy(/*DomNode*/ node
, /*DomNode*/ parent
){
302 parent
.removeChild(node
);
305 exports
.destroy
= function destroy(/*DOMNode|String*/ node
){
307 // Removes a node from its parent, clobbering it and all of its
311 // Removes a node from its parent, clobbering it and all of its
312 // children. Function only works with DomNodes, and returns nothing.
314 // node: DOMNode|String
315 // A String ID or DomNode reference of the element to be destroyed
318 // Destroy a node byId:
319 // | dojo.destroy("someId");
322 // Destroy all nodes in a list by reference:
323 // | dojo.query(".someNode").forEach(dojo.destroy);
325 node
= dom
.byId(node
);
327 _destroy(node
, node
.parentNode
);