]> git.wh0rd.org - tt-rss.git/blame - lib/dojo/NodeList-dom.js.uncompressed.js
modify dojo rebuild script to remove uncompressed files
[tt-rss.git] / lib / dojo / NodeList-dom.js.uncompressed.js
CommitLineData
f0cfe83e
AD
1define("dojo/NodeList-dom", ["./_base/kernel", "./query", "./_base/array", "./_base/lang", "./dom-class", "./dom-construct", "./dom-geometry", "./dom-attr", "./dom-style"], function(dojo, query, array, lang, domCls, domCtr, domGeom, domAttr, domStyle){
2
3 // module:
4 // dojo/NodeList-dom.js
5
6 /*=====
7 return function(){
8 // summary:
9 // Adds DOM related methods to NodeList, and returns NodeList constructor.
10 };
11 =====*/
12
13 var magicGuard = function(a){
14 // summary:
15 // the guard function for dojo.attr() and dojo.style()
16 return a.length == 1 && (typeof a[0] == "string"); // inline'd type check
17 };
18
19 var orphan = function(node){
20 // summary:
21 // function to orphan nodes
22 var p = node.parentNode;
23 if(p){
24 p.removeChild(node);
25 }
26 };
27 // FIXME: should we move orphan() to dojo.html?
28
29 var NodeList = query.NodeList,
30 awc = NodeList._adaptWithCondition,
31 aafe = NodeList._adaptAsForEach,
32 aam = NodeList._adaptAsMap;
33
34 function getSet(module){
35 return function(node, name, value){
36 if(arguments.length == 2){
37 return module[typeof name == "string" ? "get" : "set"](node, name);
38 }
39 // setter
40 return module.set(node, name, value);
41 };
42 }
43
44 lang.extend(NodeList, {
45 _normalize: function(/*String||Element||Object||NodeList*/content, /*DOMNode?*/refNode){
46 // summary:
47 // normalizes data to an array of items to insert.
48 // description:
49 // If content is an object, it can have special properties "template" and
50 // "parse". If "template" is defined, then the template value is run through
51 // dojo.string.substitute (if dojo/string.substitute() has been dojo.required elsewhere),
52 // or if templateFunc is a function on the content, that function will be used to
53 // transform the template into a final string to be used for for passing to dojo/dom-construct.toDom().
54 // If content.parse is true, then it is remembered for later, for when the content
55 // nodes are inserted into the DOM. At that point, the nodes will be parsed for widgets
56 // (if dojo.parser has been dojo.required elsewhere).
57
58 //Wanted to just use a DocumentFragment, but for the array/NodeList
59 //case that meant using cloneNode, but we may not want that.
60 //Cloning should only happen if the node operations span
61 //multiple refNodes. Also, need a real array, not a NodeList from the
62 //DOM since the node movements could change those NodeLists.
63
64 var parse = content.parse === true;
65
66 //Do we have an object that needs to be run through a template?
67 if(typeof content.template == "string"){
68 var templateFunc = content.templateFunc || (dojo.string && dojo.string.substitute);
69 content = templateFunc ? templateFunc(content.template, content) : content;
70 }
71
72 var type = (typeof content);
73 if(type == "string" || type == "number"){
74 content = domCtr.toDom(content, (refNode && refNode.ownerDocument));
75 if(content.nodeType == 11){
76 //DocumentFragment. It cannot handle cloneNode calls, so pull out the children.
77 content = lang._toArray(content.childNodes);
78 }else{
79 content = [content];
80 }
81 }else if(!lang.isArrayLike(content)){
82 content = [content];
83 }else if(!lang.isArray(content)){
84 //To get to this point, content is array-like, but
85 //not an array, which likely means a DOM NodeList. Convert it now.
86 content = lang._toArray(content);
87 }
88
89 //Pass around the parse info
90 if(parse){
91 content._runParse = true;
92 }
93 return content; //Array
94 },
95
96 _cloneNode: function(/*DOMNode*/ node){
97 // summary:
98 // private utility to clone a node. Not very interesting in the vanilla
99 // dojo/NodeList case, but delegates could do interesting things like
100 // clone event handlers if that is derivable from the node.
101 return node.cloneNode(true);
102 },
103
104 _place: function(/*Array*/ary, /*DOMNode*/refNode, /*String*/position, /*Boolean*/useClone){
105 // summary:
106 // private utility to handle placing an array of nodes relative to another node.
107 // description:
108 // Allows for cloning the nodes in the array, and for
109 // optionally parsing widgets, if ary._runParse is true.
110
111 //Avoid a disallowed operation if trying to do an innerHTML on a non-element node.
112 if(refNode.nodeType != 1 && position == "only"){
113 return;
114 }
115 var rNode = refNode, tempNode;
116
117 //Always cycle backwards in case the array is really a
118 //DOM NodeList and the DOM operations take it out of the live collection.
119 var length = ary.length;
120 for(var i = length - 1; i >= 0; i--){
121 var node = (useClone ? this._cloneNode(ary[i]) : ary[i]);
122
123 //If need widget parsing, use a temp node, instead of waiting after inserting into
124 //real DOM because we need to start widget parsing at one node up from current node,
125 //which could cause some already parsed widgets to be parsed again.
126 if(ary._runParse && dojo.parser && dojo.parser.parse){
127 if(!tempNode){
128 tempNode = rNode.ownerDocument.createElement("div");
129 }
130 tempNode.appendChild(node);
131 dojo.parser.parse(tempNode);
132 node = tempNode.firstChild;
133 while(tempNode.firstChild){
134 tempNode.removeChild(tempNode.firstChild);
135 }
136 }
137
138 if(i == length - 1){
139 domCtr.place(node, rNode, position);
140 }else{
141 rNode.parentNode.insertBefore(node, rNode);
142 }
143 rNode = node;
144 }
145 },
146
147
148 position: aam(domGeom.position),
149 /*=====
150 position: function(){
151 // summary:
152 // Returns border-box objects (x/y/w/h) of all elements in a node list
153 // as an Array (*not* a NodeList). Acts like `dojo.position`, though
154 // assumes the node passed is each node in this list.
155
156 return dojo.map(this, dojo.position); // Array
157 },
158 =====*/
159
160 attr: awc(getSet(domAttr), magicGuard),
161 /*=====
162 attr: function(property, value){
163 // summary:
164 // gets or sets the DOM attribute for every element in the
165 // NodeList. See also `dojo.attr`
166 // property: String
167 // the attribute to get/set
168 // value: String?
169 // optional. The value to set the property to
170 // returns:
171 // if no value is passed, the result is an array of attribute values
172 // If a value is passed, the return is this NodeList
173 // example:
174 // Make all nodes with a particular class focusable:
175 // | dojo.query(".focusable").attr("tabIndex", -1);
176 // example:
177 // Disable a group of buttons:
178 // | dojo.query("button.group").attr("disabled", true);
179 // example:
180 // innerHTML can be assigned or retrieved as well:
181 // | // get the innerHTML (as an array) for each list item
182 // | var ih = dojo.query("li.replaceable").attr("innerHTML");
183 return; // dojo/NodeList|Array
184 },
185 =====*/
186
187 style: awc(getSet(domStyle), magicGuard),
188 /*=====
189 style: function(property, value){
190 // summary:
191 // gets or sets the CSS property for every element in the NodeList
192 // property: String
193 // the CSS property to get/set, in JavaScript notation
194 // ("lineHieght" instead of "line-height")
195 // value: String?
196 // optional. The value to set the property to
197 // returns:
198 // if no value is passed, the result is an array of strings.
199 // If a value is passed, the return is this NodeList
200 return; // dojo/NodeList
201 return; // Array
202 },
203 =====*/
204
205 addClass: aafe(domCls.add),
206 /*=====
207 addClass: function(className){
208 // summary:
209 // adds the specified class to every node in the list
210 // className: String|Array
211 // A String class name to add, or several space-separated class names,
212 // or an array of class names.
213 return; // dojo/NodeList
214 },
215 =====*/
216
217 removeClass: aafe(domCls.remove),
218 /*=====
219 removeClass: function(className){
220 // summary:
221 // removes the specified class from every node in the list
222 // className: String|Array?
223 // An optional String class name to remove, or several space-separated
224 // class names, or an array of class names. If omitted, all class names
225 // will be deleted.
226 // returns:
227 // this list
228 return; // dojo/NodeList
229 },
230 =====*/
231
232 toggleClass: aafe(domCls.toggle),
233 /*=====
234 toggleClass: function(className, condition){
235 // summary:
236 // Adds a class to node if not present, or removes if present.
237 // Pass a boolean condition if you want to explicitly add or remove.
238 // condition: Boolean?
239 // If passed, true means to add the class, false means to remove.
240 // className: String
241 // the CSS class to add
242 return; // dojo/NodeList
243 },
244 =====*/
245
246 replaceClass: aafe(domCls.replace),
247 /*=====
248 replaceClass: function(addClassStr, removeClassStr){
249 // summary:
250 // Replaces one or more classes on a node if not present.
251 // Operates more quickly than calling `removeClass()` and `addClass()`
252 // addClassStr: String|Array
253 // A String class name to add, or several space-separated class names,
254 // or an array of class names.
255 // removeClassStr: String|Array?
256 // A String class name to remove, or several space-separated class names,
257 // or an array of class names.
258 return; // dojo/NodeList
259 },
260 =====*/
261
262 empty: aafe(domCtr.empty),
263 /*=====
264 empty: function(){
265 // summary:
266 // clears all content from each node in the list. Effectively
267 // equivalent to removing all child nodes from every item in
268 // the list.
269 return this.forEach("item.innerHTML='';"); // dojo/NodeList
270 // FIXME: should we be checking for and/or disposing of widgets below these nodes?
271 },
272 =====*/
273
274 removeAttr: aafe(domAttr.remove),
275 /*=====
276 removeAttr: function(name){
277 // summary:
278 // Removes an attribute from each node in the list.
279 // name: String
280 // the name of the attribute to remove
281 return; // dojo/NodeList
282 },
283 =====*/
284
285 marginBox: aam(domGeom.getMarginBox),
286 /*=====
287 marginBox: function(){
288 // summary:
289 // Returns margin-box size of nodes
290 return; // dojo/NodeList
291 },
292 =====*/
293
294 // FIXME: connectPublisher()? connectRunOnce()?
295
296 /*
297 destroy: function(){
298 // summary:
299 // destroys every item in the list.
300 this.forEach(d.destroy);
301 // FIXME: should we be checking for and/or disposing of widgets below these nodes?
302 },
303 */
304
305 place: function(/*String||Node*/ queryOrNode, /*String*/ position){
306 // summary:
307 // places elements of this node list relative to the first element matched
308 // by queryOrNode. Returns the original NodeList. See: `dojo.place`
309 // queryOrNode:
310 // may be a string representing any valid CSS3 selector or a DOM node.
311 // In the selector case, only the first matching element will be used
312 // for relative positioning.
313 // position:
314 // can be one of:
315 //
316 // - "last" (default)
317 // - "first"
318 // - "before"
319 // - "after"
320 // - "only"
321 // - "replace"
322 //
323 // or an offset in the childNodes property
324 var item = query(queryOrNode)[0];
325 return this.forEach(function(node){ domCtr.place(node, item, position); }); // dojo/NodeList
326 },
327
328 orphan: function(/*String?*/ filter){
329 // summary:
330 // removes elements in this list that match the filter
331 // from their parents and returns them as a new NodeList.
332 // filter:
333 // CSS selector like ".foo" or "div > span"
334 // returns:
335 // NodeList containing the orphaned elements
336 return (filter ? query._filterResult(this, filter) : this).forEach(orphan); // dojo/NodeList
337 },
338
339 adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
340 // summary:
341 // places any/all elements in queryOrListOrNode at a
342 // position relative to the first element in this list.
343 // Returns a dojo/NodeList of the adopted elements.
344 // queryOrListOrNode:
345 // a DOM node or a query string or a query result.
346 // Represents the nodes to be adopted relative to the
347 // first element of this NodeList.
348 // position:
349 // can be one of:
350 //
351 // - "last" (default)
352 // - "first"
353 // - "before"
354 // - "after"
355 // - "only"
356 // - "replace"
357 //
358 // or an offset in the childNodes property
359 return query(queryOrListOrNode).place(this[0], position)._stash(this); // dojo/NodeList
360 },
361
362 // FIXME: do we need this?
363 query: function(/*String*/ queryStr){
364 // summary:
365 // Returns a new list whose members match the passed query,
366 // assuming elements of the current NodeList as the root for
367 // each search.
368 // example:
369 // assume a DOM created by this markup:
370 // | <div id="foo">
371 // | <p>
372 // | bacon is tasty, <span>dontcha think?</span>
373 // | </p>
374 // | </div>
375 // | <div id="bar">
376 // | <p>great comedians may not be funny <span>in person</span></p>
377 // | </div>
378 // If we are presented with the following definition for a NodeList:
379 // | var l = new NodeList(dojo.byId("foo"), dojo.byId("bar"));
380 // it's possible to find all span elements under paragraphs
381 // contained by these elements with this sub-query:
382 // | var spans = l.query("p span");
383
384 // FIXME: probably slow
385 if(!queryStr){ return this; }
386 var ret = new NodeList;
387 this.map(function(node){
388 // FIXME: why would we ever get undefined here?
389 query(queryStr, node).forEach(function(subNode){
390 if(subNode !== undefined){
391 ret.push(subNode);
392 }
393 });
394 });
395 return ret._stash(this); // dojo/NodeList
396 },
397
398 filter: function(/*String|Function*/ filter){
399 // summary:
400 // "masks" the built-in javascript filter() method (supported
401 // in Dojo via `dojo.filter`) to support passing a simple
402 // string filter in addition to supporting filtering function
403 // objects.
404 // filter:
405 // If a string, a CSS rule like ".thinger" or "div > span".
406 // example:
407 // "regular" JS filter syntax as exposed in dojo.filter:
408 // | dojo.query("*").filter(function(item){
409 // | // highlight every paragraph
410 // | return (item.nodeName == "p");
411 // | }).style("backgroundColor", "yellow");
412 // example:
413 // the same filtering using a CSS selector
414 // | dojo.query("*").filter("p").styles("backgroundColor", "yellow");
415
416 var a = arguments, items = this, start = 0;
417 if(typeof filter == "string"){ // inline'd type check
418 items = query._filterResult(this, a[0]);
419 if(a.length == 1){
420 // if we only got a string query, pass back the filtered results
421 return items._stash(this); // dojo/NodeList
422 }
423 // if we got a callback, run it over the filtered items
424 start = 1;
425 }
426 return this._wrap(array.filter(items, a[start], a[start + 1]), this); // dojo/NodeList
427 },
428
429 /*
430 // FIXME: should this be "copyTo" and include parenting info?
431 clone: function(){
432 // summary:
433 // creates node clones of each element of this list
434 // and returns a new list containing the clones
435 },
436 */
437
438 addContent: function(/*String||DomNode||Object||dojo/NodeList*/ content, /*String||Integer?*/ position){
439 // summary:
440 // add a node, NodeList or some HTML as a string to every item in the
441 // list. Returns the original list.
442 // description:
443 // a copy of the HTML content is added to each item in the
444 // list, with an optional position argument. If no position
445 // argument is provided, the content is appended to the end of
446 // each item.
447 // content:
448 // DOM node, HTML in string format, a NodeList or an Object. If a DOM node or
449 // NodeList, the content will be cloned if the current NodeList has more than one
450 // element. Only the DOM nodes are cloned, no event handlers. If it is an Object,
451 // it should be an object with at "template" String property that has the HTML string
452 // to insert. If dojo.string has already been dojo.required, then dojo.string.substitute
453 // will be used on the "template" to generate the final HTML string. Other allowed
454 // properties on the object are: "parse" if the HTML
455 // string should be parsed for widgets (dojo.require("dojo.parser") to get that
456 // option to work), and "templateFunc" if a template function besides dojo.string.substitute
457 // should be used to transform the "template".
458 // position:
459 // can be one of:
460 //
461 // - "last"||"end" (default)
462 // - "first||"start"
463 // - "before"
464 // - "after"
465 // - "replace" (replaces nodes in this NodeList with new content)
466 // - "only" (removes other children of the nodes so new content is the only child)
467 //
468 // or an offset in the childNodes property
469 // example:
470 // appends content to the end if the position is omitted
471 // | dojo.query("h3 > p").addContent("hey there!");
472 // example:
473 // add something to the front of each element that has a
474 // "thinger" property:
475 // | dojo.query("[thinger]").addContent("...", "first");
476 // example:
477 // adds a header before each element of the list
478 // | dojo.query(".note").addContent("<h4>NOTE:</h4>", "before");
479 // example:
480 // add a clone of a DOM node to the end of every element in
481 // the list, removing it from its existing parent.
482 // | dojo.query(".note").addContent(dojo.byId("foo"));
483 // example:
484 // Append nodes from a templatized string.
485 // | dojo.require("dojo.string");
486 // | dojo.query(".note").addContent({
487 // | template: '<b>${id}: </b><span>${name}</span>',
488 // | id: "user332",
489 // | name: "Mr. Anderson"
490 // | });
491 // example:
492 // Append nodes from a templatized string that also has widgets parsed.
493 // | dojo.require("dojo.string");
494 // | dojo.require("dojo.parser");
495 // | var notes = dojo.query(".note").addContent({
496 // | template: '<button dojoType="dijit/form/Button">${text}</button>',
497 // | parse: true,
498 // | text: "Send"
499 // | });
500 content = this._normalize(content, this[0]);
501 for(var i = 0, node; (node = this[i]); i++){
502 this._place(content, node, position, i > 0);
503 }
504 return this; // dojo/NodeList
505 }
506 });
507
508 return NodeList;
509});