]> git.wh0rd.org - tt-rss.git/blob - lib/dojo/NodeList-manipulate.js.uncompressed.js
make precache_headlines_idle() start slower
[tt-rss.git] / lib / dojo / NodeList-manipulate.js.uncompressed.js
1 define("dojo/NodeList-manipulate", ["./query", "./_base/lang", "./_base/array", "./dom-construct", "./NodeList-dom"], function(dquery, lang, array, construct) {
2 // module:
3 // dojo/NodeList-manipulate
4 // summary:
5 // TODOC
6
7 var NodeList = dquery.NodeList;
8
9 /*=====
10 dojo["NodeList-manipulate"] = {
11 // summary: Adds a chainable methods to dojo.query() / Nodelist instances for manipulating HTML
12 // and DOM nodes and their properties.
13 };
14
15 // doc alias helpers:
16 NodeList = dojo.NodeList;
17 =====*/
18
19 //TODO: add a way to parse for widgets in the injected markup?
20
21 function getText(/*DOMNode*/node){
22 // summary:
23 // recursion method for text() to use. Gets text value for a node.
24 // description:
25 // Juse uses nodedValue so things like <br/> tags do not end up in
26 // the text as any sort of line return.
27 var text = "", ch = node.childNodes;
28 for(var i = 0, n; n = ch[i]; i++){
29 //Skip comments.
30 if(n.nodeType != 8){
31 if(n.nodeType == 1){
32 text += getText(n);
33 }else{
34 text += n.nodeValue;
35 }
36 }
37 }
38 return text;
39 }
40
41 function getWrapInsertion(/*DOMNode*/node){
42 // summary:
43 // finds the innermost element to use for wrap insertion.
44
45 //Make it easy, assume single nesting, no siblings.
46 while(node.childNodes[0] && node.childNodes[0].nodeType == 1){
47 node = node.childNodes[0];
48 }
49 return node; //DOMNode
50 }
51
52 function makeWrapNode(/*DOMNode||String*/html, /*DOMNode*/refNode){
53 // summary:
54 // convert HTML into nodes if it is not already a node.
55 if(typeof html == "string"){
56 html = construct.toDom(html, (refNode && refNode.ownerDocument));
57 if(html.nodeType == 11){
58 //DocumentFragment cannot handle cloneNode, so choose first child.
59 html = html.childNodes[0];
60 }
61 }else if(html.nodeType == 1 && html.parentNode){
62 //This element is already in the DOM clone it, but not its children.
63 html = html.cloneNode(false);
64 }
65 return html; /*DOMNode*/
66 }
67
68 lang.extend(NodeList, {
69 _placeMultiple: function(/*String||Node||NodeList*/query, /*String*/position){
70 // summary:
71 // private method for inserting queried nodes into all nodes in this NodeList
72 // at different positions. Differs from NodeList.place because it will clone
73 // the nodes in this NodeList if the query matches more than one element.
74 var nl2 = typeof query == "string" || query.nodeType ? dquery(query) : query;
75 var toAdd = [];
76 for(var i = 0; i < nl2.length; i++){
77 //Go backwards in DOM to make dom insertions easier via insertBefore
78 var refNode = nl2[i];
79 var length = this.length;
80 for(var j = length - 1, item; item = this[j]; j--){
81 if(i > 0){
82 //Need to clone the item. This also means
83 //it needs to be added to the current NodeList
84 //so it can also be the target of other chaining operations.
85 item = this._cloneNode(item);
86 toAdd.unshift(item);
87 }
88 if(j == length - 1){
89 construct.place(item, refNode, position);
90 }else{
91 refNode.parentNode.insertBefore(item, refNode);
92 }
93 refNode = item;
94 }
95 }
96
97 if(toAdd.length){
98 //Add the toAdd items to the current NodeList. Build up list of args
99 //to pass to splice.
100 toAdd.unshift(0);
101 toAdd.unshift(this.length - 1);
102 Array.prototype.splice.apply(this, toAdd);
103 }
104
105 return this; //dojo.NodeList
106 },
107
108 innerHTML: function(/*String?||DOMNode?|NodeList?*/value){
109 // summary:
110 // allows setting the innerHTML of each node in the NodeList,
111 // if there is a value passed in, otherwise, reads the innerHTML value of the first node.
112 // description:
113 // This method is simpler than the dojo.NodeList.html() method provided by
114 // `dojo.NodeList-html`. This method just does proper innerHTML insertion of HTML fragments,
115 // and it allows for the innerHTML to be read for the first node in the node list.
116 // Since dojo.NodeList-html already took the "html" name, this method is called
117 // "innerHTML". However, if dojo.NodeList-html has not been loaded yet, this
118 // module will define an "html" method that can be used instead. Be careful if you
119 // are working in an environment where it is possible that dojo.NodeList-html could
120 // have been loaded, since its definition of "html" will take precedence.
121 // The nodes represented by the value argument will be cloned if more than one
122 // node is in this NodeList. The nodes in this NodeList are returned in the "set"
123 // usage of this method, not the HTML that was inserted.
124 // returns:
125 // if no value is passed, the result is String, the innerHTML of the first node.
126 // If a value is passed, the return is this dojo.NodeList
127 // example:
128 // assume a DOM created by this markup:
129 // | <div id="foo"></div>
130 // | <div id="bar"></div>
131 // This code inserts <p>Hello World</p> into both divs:
132 // | dojo.query("div").innerHTML("<p>Hello World</p>");
133 // example:
134 // assume a DOM created by this markup:
135 // | <div id="foo"><p>Hello Mars</p></div>
136 // | <div id="bar"><p>Hello World</p></div>
137 // This code returns "<p>Hello Mars</p>":
138 // | var message = dojo.query("div").innerHTML();
139 if(arguments.length){
140 return this.addContent(value, "only"); //dojo.NodeList
141 }else{
142 return this[0].innerHTML; //String
143 }
144 },
145
146 /*=====
147 html: function(value){
148 // summary:
149 // see the information for "innerHTML". "html" is an alias for "innerHTML", but is
150 // only defined if dojo.NodeList-html has not been loaded.
151 // description:
152 // An alias for the "innerHTML" method, but only defined if there is not an existing
153 // "html" method on dojo.NodeList. Be careful if you are working in an environment
154 // where it is possible that dojo.NodeList-html could have been loaded, since its
155 // definition of "html" will take precedence. If you are not sure if dojo.NodeList-html
156 // could be loaded, use the "innerHTML" method.
157 // value: String?||DOMNode?||NodeList?
158 // optional. The HTML fragment to use as innerHTML. If value is not passed, then the innerHTML
159 // of the first element in this NodeList is returned.
160 // returns:
161 // if no value is passed, the result is String, the innerHTML of the first node.
162 // If a value is passed, the return is this dojo.NodeList
163 return; // dojo.NodeList
164 return; // String
165 },
166 =====*/
167
168 text: function(/*String*/value){
169 // summary:
170 // allows setting the text value of each node in the NodeList,
171 // if there is a value passed in, otherwise, returns the text value for all the
172 // nodes in the NodeList in one string.
173 // example:
174 // assume a DOM created by this markup:
175 // | <div id="foo"></div>
176 // | <div id="bar"></div>
177 // This code inserts "Hello World" into both divs:
178 // | dojo.query("div").text("Hello World");
179 // example:
180 // assume a DOM created by this markup:
181 // | <div id="foo"><p>Hello Mars <span>today</span></p></div>
182 // | <div id="bar"><p>Hello World</p></div>
183 // This code returns "Hello Mars today":
184 // | var message = dojo.query("div").text();
185 // returns:
186 // if no value is passed, the result is String, the text value of the first node.
187 // If a value is passed, the return is this dojo.NodeList
188 if(arguments.length){
189 for(var i = 0, node; node = this[i]; i++){
190 if(node.nodeType == 1){
191 construct.empty(node);
192 node.appendChild(node.ownerDocument.createTextNode(value));
193 }
194 }
195 return this; //dojo.NodeList
196 }else{
197 var result = "";
198 for(i = 0; node = this[i]; i++){
199 result += getText(node);
200 }
201 return result; //String
202 }
203 },
204
205 val: function(/*String||Array*/value){
206 // summary:
207 // If a value is passed, allows seting the value property of form elements in this
208 // NodeList, or properly selecting/checking the right value for radio/checkbox/select
209 // elements. If no value is passed, the value of the first node in this NodeList
210 // is returned.
211 // returns:
212 // if no value is passed, the result is String or an Array, for the value of the
213 // first node.
214 // If a value is passed, the return is this dojo.NodeList
215 // example:
216 // assume a DOM created by this markup:
217 // | <input type="text" value="foo">
218 // | <select multiple>
219 // | <option value="red" selected>Red</option>
220 // | <option value="blue">Blue</option>
221 // | <option value="yellow" selected>Yellow</option>
222 // | </select>
223 // This code gets and sets the values for the form fields above:
224 // | dojo.query('[type="text"]').val(); //gets value foo
225 // | dojo.query('[type="text"]').val("bar"); //sets the input's value to "bar"
226 // | dojo.query("select").val() //gets array value ["red", "yellow"]
227 // | dojo.query("select").val(["blue", "yellow"]) //Sets the blue and yellow options to selected.
228
229 //Special work for input elements.
230 if(arguments.length){
231 var isArray = lang.isArray(value);
232 for(var index = 0, node; node = this[index]; index++){
233 var name = node.nodeName.toUpperCase();
234 var type = node.type;
235 var newValue = isArray ? value[index] : value;
236
237 if(name == "SELECT"){
238 var opts = node.options;
239 for(var i = 0; i < opts.length; i++){
240 var opt = opts[i];
241 if(node.multiple){
242 opt.selected = (array.indexOf(value, opt.value) != -1);
243 }else{
244 opt.selected = (opt.value == newValue);
245 }
246 }
247 }else if(type == "checkbox" || type == "radio"){
248 node.checked = (node.value == newValue);
249 }else{
250 node.value = newValue;
251 }
252 }
253 return this; //dojo.NodeList
254 }else{
255 //node already declared above.
256 node = this[0];
257 if(!node || node.nodeType != 1){
258 return undefined;
259 }
260 value = node.value || "";
261 if(node.nodeName.toUpperCase() == "SELECT" && node.multiple){
262 //A multivalued selectbox. Do the pain.
263 value = [];
264 //opts declared above in if block.
265 opts = node.options;
266 //i declared above in if block;
267 for(i = 0; i < opts.length; i++){
268 //opt declared above in if block
269 opt = opts[i];
270 if(opt.selected){
271 value.push(opt.value);
272 }
273 }
274 if(!value.length){
275 value = null;
276 }
277 }
278 return value; //String||Array
279 }
280 },
281
282 append: function(/*String||DOMNode||NodeList*/content){
283 // summary:
284 // appends the content to every node in the NodeList.
285 // description:
286 // The content will be cloned if the length of NodeList
287 // is greater than 1. Only the DOM nodes are cloned, not
288 // any attached event handlers.
289 // returns:
290 // dojo.NodeList, the nodes currently in this NodeList will be returned,
291 // not the appended content.
292 // example:
293 // assume a DOM created by this markup:
294 // | <div id="foo"><p>Hello Mars</p></div>
295 // | <div id="bar"><p>Hello World</p></div>
296 // Running this code:
297 // | dojo.query("div").append("<span>append</span>");
298 // Results in this DOM structure:
299 // | <div id="foo"><p>Hello Mars</p><span>append</span></div>
300 // | <div id="bar"><p>Hello World</p><span>append</span></div>
301 return this.addContent(content, "last"); //dojo.NodeList
302 },
303
304 appendTo: function(/*String*/query){
305 // summary:
306 // appends nodes in this NodeList to the nodes matched by
307 // the query passed to appendTo.
308 // description:
309 // The nodes in this NodeList will be cloned if the query
310 // matches more than one element. Only the DOM nodes are cloned, not
311 // any attached event handlers.
312 // returns:
313 // dojo.NodeList, the nodes currently in this NodeList will be returned,
314 // not the matched nodes from the query.
315 // example:
316 // assume a DOM created by this markup:
317 // | <span>append</span>
318 // | <p>Hello Mars</p>
319 // | <p>Hello World</p>
320 // Running this code:
321 // | dojo.query("span").appendTo("p");
322 // Results in this DOM structure:
323 // | <p>Hello Mars<span>append</span></p>
324 // | <p>Hello World<span>append</span></p>
325 return this._placeMultiple(query, "last"); //dojo.NodeList
326 },
327
328 prepend: function(/*String||DOMNode||NodeList*/content){
329 // summary:
330 // prepends the content to every node in the NodeList.
331 // description:
332 // The content will be cloned if the length of NodeList
333 // is greater than 1. Only the DOM nodes are cloned, not
334 // any attached event handlers.
335 // returns:
336 // dojo.NodeList, the nodes currently in this NodeList will be returned,
337 // not the appended content.
338 // assume a DOM created by this markup:
339 // | <div id="foo"><p>Hello Mars</p></div>
340 // | <div id="bar"><p>Hello World</p></div>
341 // Running this code:
342 // | dojo.query("div").prepend("<span>prepend</span>");
343 // Results in this DOM structure:
344 // | <div id="foo"><span>prepend</span><p>Hello Mars</p></div>
345 // | <div id="bar"><span>prepend</span><p>Hello World</p></div>
346 return this.addContent(content, "first"); //dojo.NodeList
347 },
348
349 prependTo: function(/*String*/query){
350 // summary:
351 // prepends nodes in this NodeList to the nodes matched by
352 // the query passed to prependTo.
353 // description:
354 // The nodes in this NodeList will be cloned if the query
355 // matches more than one element. Only the DOM nodes are cloned, not
356 // any attached event handlers.
357 // returns:
358 // dojo.NodeList, the nodes currently in this NodeList will be returned,
359 // not the matched nodes from the query.
360 // example:
361 // assume a DOM created by this markup:
362 // | <span>prepend</span>
363 // | <p>Hello Mars</p>
364 // | <p>Hello World</p>
365 // Running this code:
366 // | dojo.query("span").prependTo("p");
367 // Results in this DOM structure:
368 // | <p><span>prepend</span>Hello Mars</p>
369 // | <p><span>prepend</span>Hello World</p>
370 return this._placeMultiple(query, "first"); //dojo.NodeList
371 },
372
373 after: function(/*String||Element||NodeList*/content){
374 // summary:
375 // Places the content after every node in the NodeList.
376 // description:
377 // The content will be cloned if the length of NodeList
378 // is greater than 1. Only the DOM nodes are cloned, not
379 // any attached event handlers.
380 // returns:
381 // dojo.NodeList, the nodes currently in this NodeList will be returned,
382 // not the appended content.
383 // example:
384 // assume a DOM created by this markup:
385 // | <div id="foo"><p>Hello Mars</p></div>
386 // | <div id="bar"><p>Hello World</p></div>
387 // Running this code:
388 // | dojo.query("div").after("<span>after</span>");
389 // Results in this DOM structure:
390 // | <div id="foo"><p>Hello Mars</p></div><span>after</span>
391 // | <div id="bar"><p>Hello World</p></div><span>after</span>
392 return this.addContent(content, "after"); //dojo.NodeList
393 },
394
395 insertAfter: function(/*String*/query){
396 // summary:
397 // The nodes in this NodeList will be placed after the nodes
398 // matched by the query passed to insertAfter.
399 // description:
400 // The nodes in this NodeList will be cloned if the query
401 // matches more than one element. Only the DOM nodes are cloned, not
402 // any attached event handlers.
403 // returns:
404 // dojo.NodeList, the nodes currently in this NodeList will be returned,
405 // not the matched nodes from the query.
406 // example:
407 // assume a DOM created by this markup:
408 // | <span>after</span>
409 // | <p>Hello Mars</p>
410 // | <p>Hello World</p>
411 // Running this code:
412 // | dojo.query("span").insertAfter("p");
413 // Results in this DOM structure:
414 // | <p>Hello Mars</p><span>after</span>
415 // | <p>Hello World</p><span>after</span>
416 return this._placeMultiple(query, "after"); //dojo.NodeList
417 },
418
419 before: function(/*String||DOMNode||NodeList*/content){
420 // summary:
421 // Places the content before every node in the NodeList.
422 // description:
423 // The content will be cloned if the length of NodeList
424 // is greater than 1. Only the DOM nodes are cloned, not
425 // any attached event handlers.
426 // returns:
427 // dojo.NodeList, the nodes currently in this NodeList will be returned,
428 // not the appended content.
429 // example:
430 // assume a DOM created by this markup:
431 // | <div id="foo"><p>Hello Mars</p></div>
432 // | <div id="bar"><p>Hello World</p></div>
433 // Running this code:
434 // | dojo.query("div").before("<span>before</span>");
435 // Results in this DOM structure:
436 // | <span>before</span><div id="foo"><p>Hello Mars</p></div>
437 // | <span>before</span><div id="bar"><p>Hello World</p></div>
438 return this.addContent(content, "before"); //dojo.NodeList
439 },
440
441 insertBefore: function(/*String*/query){
442 // summary:
443 // The nodes in this NodeList will be placed after the nodes
444 // matched by the query passed to insertAfter.
445 // description:
446 // The nodes in this NodeList will be cloned if the query
447 // matches more than one element. Only the DOM nodes are cloned, not
448 // any attached event handlers.
449 // returns:
450 // dojo.NodeList, the nodes currently in this NodeList will be returned,
451 // not the matched nodes from the query.
452 // example:
453 // assume a DOM created by this markup:
454 // | <span>before</span>
455 // | <p>Hello Mars</p>
456 // | <p>Hello World</p>
457 // Running this code:
458 // | dojo.query("span").insertBefore("p");
459 // Results in this DOM structure:
460 // | <span>before</span><p>Hello Mars</p>
461 // | <span>before</span><p>Hello World</p>
462 return this._placeMultiple(query, "before"); //dojo.NodeList
463 },
464
465 /*=====
466 remove: function(simpleFilter){
467 // summary:
468 // alias for dojo.NodeList's orphan method. Removes elements
469 // in this list that match the simple filter from their parents
470 // and returns them as a new NodeList.
471 // simpleFilter: String
472 // single-expression CSS rule. For example, ".thinger" or
473 // "#someId[attrName='value']" but not "div > span". In short,
474 // anything which does not invoke a descent to evaluate but
475 // can instead be used to test a single node is acceptable.
476 // returns:
477 // dojo.NodeList
478 return; // dojo.NodeList
479 },
480 =====*/
481 remove: NodeList.prototype.orphan,
482
483 wrap: function(/*String||DOMNode*/html){
484 // summary:
485 // Wrap each node in the NodeList with html passed to wrap.
486 // description:
487 // html will be cloned if the NodeList has more than one
488 // element. Only DOM nodes are cloned, not any attached
489 // event handlers.
490 // returns:
491 // dojo.NodeList, the nodes in the current NodeList will be returned,
492 // not the nodes from html argument.
493 // example:
494 // assume a DOM created by this markup:
495 // | <b>one</b>
496 // | <b>two</b>
497 // Running this code:
498 // | dojo.query("b").wrap("<div><span></span></div>");
499 // Results in this DOM structure:
500 // | <div><span><b>one</b></span></div>
501 // | <div><span><b>two</b></span></div>
502 if(this[0]){
503 html = makeWrapNode(html, this[0]);
504
505 //Now cycle through the elements and do the insertion.
506 for(var i = 0, node; node = this[i]; i++){
507 //Always clone because if html is used to hold one of
508 //the "this" nodes, then on the clone of html it will contain
509 //that "this" node, and that would be bad.
510 var clone = this._cloneNode(html);
511 if(node.parentNode){
512 node.parentNode.replaceChild(clone, node);
513 }
514 //Find deepest element and insert old node in it.
515 var insertion = getWrapInsertion(clone);
516 insertion.appendChild(node);
517 }
518 }
519 return this; //dojo.NodeList
520 },
521
522 wrapAll: function(/*String||DOMNode*/html){
523 // summary:
524 // Insert html where the first node in this NodeList lives, then place all
525 // nodes in this NodeList as the child of the html.
526 // returns:
527 // dojo.NodeList, the nodes in the current NodeList will be returned,
528 // not the nodes from html argument.
529 // example:
530 // assume a DOM created by this markup:
531 // | <div class="container">
532 // | <div class="red">Red One</div>
533 // | <div class="blue">Blue One</div>
534 // | <div class="red">Red Two</div>
535 // | <div class="blue">Blue Two</div>
536 // | </div>
537 // Running this code:
538 // | dojo.query(".red").wrapAll('<div class="allRed"></div>');
539 // Results in this DOM structure:
540 // | <div class="container">
541 // | <div class="allRed">
542 // | <div class="red">Red One</div>
543 // | <div class="red">Red Two</div>
544 // | </div>
545 // | <div class="blue">Blue One</div>
546 // | <div class="blue">Blue Two</div>
547 // | </div>
548 if(this[0]){
549 html = makeWrapNode(html, this[0]);
550
551 //Place the wrap HTML in place of the first node.
552 this[0].parentNode.replaceChild(html, this[0]);
553
554 //Now cycle through the elements and move them inside
555 //the wrap.
556 var insertion = getWrapInsertion(html);
557 for(var i = 0, node; node = this[i]; i++){
558 insertion.appendChild(node);
559 }
560 }
561 return this; //dojo.NodeList
562 },
563
564 wrapInner: function(/*String||DOMNode*/html){
565 // summary:
566 // For each node in the NodeList, wrap all its children with the passed in html.
567 // description:
568 // html will be cloned if the NodeList has more than one
569 // element. Only DOM nodes are cloned, not any attached
570 // event handlers.
571 // returns:
572 // dojo.NodeList, the nodes in the current NodeList will be returned,
573 // not the nodes from html argument.
574 // example:
575 // assume a DOM created by this markup:
576 // | <div class="container">
577 // | <div class="red">Red One</div>
578 // | <div class="blue">Blue One</div>
579 // | <div class="red">Red Two</div>
580 // | <div class="blue">Blue Two</div>
581 // | </div>
582 // Running this code:
583 // | dojo.query(".red").wrapInner('<span class="special"></span>');
584 // Results in this DOM structure:
585 // | <div class="container">
586 // | <div class="red"><span class="special">Red One</span></div>
587 // | <div class="blue">Blue One</div>
588 // | <div class="red"><span class="special">Red Two</span></div>
589 // | <div class="blue">Blue Two</div>
590 // | </div>
591 if(this[0]){
592 html = makeWrapNode(html, this[0]);
593 for(var i = 0; i < this.length; i++){
594 //Always clone because if html is used to hold one of
595 //the "this" nodes, then on the clone of html it will contain
596 //that "this" node, and that would be bad.
597 var clone = this._cloneNode(html);
598
599 //Need to convert the childNodes to an array since wrapAll modifies the
600 //DOM and can change the live childNodes NodeList.
601 this._wrap(lang._toArray(this[i].childNodes), null, this._NodeListCtor).wrapAll(clone);
602 }
603 }
604 return this; //dojo.NodeList
605 },
606
607 replaceWith: function(/*String||DOMNode||NodeList*/content){
608 // summary:
609 // Replaces each node in ths NodeList with the content passed to replaceWith.
610 // description:
611 // The content will be cloned if the length of NodeList
612 // is greater than 1. Only the DOM nodes are cloned, not
613 // any attached event handlers.
614 // returns:
615 // The nodes currently in this NodeList will be returned, not the replacing content.
616 // Note that the returned nodes have been removed from the DOM.
617 // example:
618 // assume a DOM created by this markup:
619 // | <div class="container">
620 // | <div class="red">Red One</div>
621 // | <div class="blue">Blue One</div>
622 // | <div class="red">Red Two</div>
623 // | <div class="blue">Blue Two</div>
624 // | </div>
625 // Running this code:
626 // | dojo.query(".red").replaceWith('<div class="green">Green</div>');
627 // Results in this DOM structure:
628 // | <div class="container">
629 // | <div class="green">Green</div>
630 // | <div class="blue">Blue One</div>
631 // | <div class="green">Green</div>
632 // | <div class="blue">Blue Two</div>
633 // | </div>
634 content = this._normalize(content, this[0]);
635 for(var i = 0, node; node = this[i]; i++){
636 this._place(content, node, "before", i > 0);
637 node.parentNode.removeChild(node);
638 }
639 return this; //dojo.NodeList
640 },
641
642 replaceAll: function(/*String*/query){
643 // summary:
644 // replaces nodes matched by the query passed to replaceAll with the nodes
645 // in this NodeList.
646 // description:
647 // The nodes in this NodeList will be cloned if the query
648 // matches more than one element. Only the DOM nodes are cloned, not
649 // any attached event handlers.
650 // returns:
651 // The nodes currently in this NodeList will be returned, not the matched nodes
652 // from the query. The nodes currently in this NodeLIst could have
653 // been cloned, so the returned NodeList will include the cloned nodes.
654 // example:
655 // assume a DOM created by this markup:
656 // | <div class="container">
657 // | <div class="spacer">___</div>
658 // | <div class="red">Red One</div>
659 // | <div class="spacer">___</div>
660 // | <div class="blue">Blue One</div>
661 // | <div class="spacer">___</div>
662 // | <div class="red">Red Two</div>
663 // | <div class="spacer">___</div>
664 // | <div class="blue">Blue Two</div>
665 // | </div>
666 // Running this code:
667 // | dojo.query(".red").replaceAll(".blue");
668 // Results in this DOM structure:
669 // | <div class="container">
670 // | <div class="spacer">___</div>
671 // | <div class="spacer">___</div>
672 // | <div class="red">Red One</div>
673 // | <div class="red">Red Two</div>
674 // | <div class="spacer">___</div>
675 // | <div class="spacer">___</div>
676 // | <div class="red">Red One</div>
677 // | <div class="red">Red Two</div>
678 // | </div>
679 var nl = dquery(query);
680 var content = this._normalize(this, this[0]);
681 for(var i = 0, node; node = nl[i]; i++){
682 this._place(content, node, "before", i > 0);
683 node.parentNode.removeChild(node);
684 }
685 return this; //dojo.NodeList
686 },
687
688 clone: function(){
689 // summary:
690 // Clones all the nodes in this NodeList and returns them as a new NodeList.
691 // description:
692 // Only the DOM nodes are cloned, not any attached event handlers.
693 // returns:
694 // dojo.NodeList, a cloned set of the original nodes.
695 // example:
696 // assume a DOM created by this markup:
697 // | <div class="container">
698 // | <div class="red">Red One</div>
699 // | <div class="blue">Blue One</div>
700 // | <div class="red">Red Two</div>
701 // | <div class="blue">Blue Two</div>
702 // | </div>
703 // Running this code:
704 // | dojo.query(".red").clone().appendTo(".container");
705 // Results in this DOM structure:
706 // | <div class="container">
707 // | <div class="red">Red One</div>
708 // | <div class="blue">Blue One</div>
709 // | <div class="red">Red Two</div>
710 // | <div class="blue">Blue Two</div>
711 // | <div class="red">Red One</div>
712 // | <div class="red">Red Two</div>
713 // | </div>
714
715 //TODO: need option to clone events?
716 var ary = [];
717 for(var i = 0; i < this.length; i++){
718 ary.push(this._cloneNode(this[i]));
719 }
720 return this._wrap(ary, this, this._NodeListCtor); //dojo.NodeList
721 }
722 });
723
724 //set up html method if one does not exist
725 if(!NodeList.prototype.html){
726 NodeList.prototype.html = NodeList.prototype.innerHTML;
727 }
728
729 return NodeList;
730 });