UNPKG

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