| 1 | dojo.provide("dojo._base.NodeList"); |
|---|
| 2 | dojo.require("dojo._base.lang"); |
|---|
| 3 | dojo.require("dojo._base.array"); |
|---|
| 4 | |
|---|
| 5 | //>>excludeStart("webkitMobile", kwArgs.webkitMobile); |
|---|
| 6 | (function(){ |
|---|
| 7 | |
|---|
| 8 | var d = dojo; |
|---|
| 9 | //>>excludeEnd("webkitMobile"); |
|---|
| 10 | |
|---|
| 11 | var ap = Array.prototype, aps = ap.slice, apc = ap.concat; |
|---|
| 12 | |
|---|
| 13 | var tnl = function(a){ |
|---|
| 14 | // decorate an array to make it look like a NodeList |
|---|
| 15 | a.constructor = d.NodeList; |
|---|
| 16 | dojo._mixin(a, d.NodeList.prototype); |
|---|
| 17 | return a; |
|---|
| 18 | }; |
|---|
| 19 | |
|---|
| 20 | var loopBody = function(f, a, o){ |
|---|
| 21 | a = [0].concat(aps.call(a, 0)); |
|---|
| 22 | o = o || d.global; |
|---|
| 23 | return function(node){ |
|---|
| 24 | a[0] = node; |
|---|
| 25 | return f.apply(o, a); |
|---|
| 26 | }; |
|---|
| 27 | }; |
|---|
| 28 | |
|---|
| 29 | // adapters |
|---|
| 30 | |
|---|
| 31 | var adaptAsForEach = function(f, o){ |
|---|
| 32 | // summary: adapts a single node function to be used in the forEach-type actions |
|---|
| 33 | // f: Function: a function to adapt |
|---|
| 34 | // o: Object?: an optional context for f |
|---|
| 35 | return function(){ |
|---|
| 36 | this.forEach(loopBody(f, arguments, o)); |
|---|
| 37 | return this; // self |
|---|
| 38 | }; |
|---|
| 39 | }; |
|---|
| 40 | |
|---|
| 41 | var adaptAsMap = function(f, o){ |
|---|
| 42 | // summary: adapts a single node function to be used in the map-type actions |
|---|
| 43 | // f: Function: a function to adapt |
|---|
| 44 | // o: Object?: an optional context for f |
|---|
| 45 | return function(){ |
|---|
| 46 | return this.map(loopBody(f, arguments, o)); |
|---|
| 47 | }; |
|---|
| 48 | }; |
|---|
| 49 | |
|---|
| 50 | var adaptAsFilter = function(f, o){ |
|---|
| 51 | // summary: adapts a single node function to be used in the filter-type actions |
|---|
| 52 | // f: Function: a function to adapt |
|---|
| 53 | // o: Object?: an optional context for f |
|---|
| 54 | return function(){ |
|---|
| 55 | return this.filter(loopBody(f, arguments, o)); |
|---|
| 56 | }; |
|---|
| 57 | }; |
|---|
| 58 | |
|---|
| 59 | var adaptWithCondition = function(f, g, o){ |
|---|
| 60 | // summary: adapts a single node function to be used in the map-type actions, |
|---|
| 61 | // behaves like forEach() or map() depending on arguments |
|---|
| 62 | // f: Function: a function to adapt |
|---|
| 63 | // g: Function: a condition function, if true runs as map(), otherwise runs as forEach() |
|---|
| 64 | // o: Object?: an optional context for f and g |
|---|
| 65 | return function(){ |
|---|
| 66 | var a = arguments, body = loopBody(f, a, o); |
|---|
| 67 | if(g.call(o || d.global, a)){ |
|---|
| 68 | return this.map(body); // self |
|---|
| 69 | } |
|---|
| 70 | this.forEach(body); |
|---|
| 71 | return this; // self |
|---|
| 72 | }; |
|---|
| 73 | }; |
|---|
| 74 | |
|---|
| 75 | // the guard function for dojo.attr() and dojo.style() |
|---|
| 76 | var magicGuard = function(a){ |
|---|
| 77 | return a.length == 1 && d.isString(a[0]) |
|---|
| 78 | }; |
|---|
| 79 | |
|---|
| 80 | // function to orphan nodes |
|---|
| 81 | var orphan = function(node){ |
|---|
| 82 | var p = node.parentNode; |
|---|
| 83 | if(p){ |
|---|
| 84 | p.removeChild(node); |
|---|
| 85 | } |
|---|
| 86 | }; |
|---|
| 87 | // FIXME: should we move orphan() to dojo.html? |
|---|
| 88 | |
|---|
| 89 | dojo.NodeList = function(){ |
|---|
| 90 | // summary: |
|---|
| 91 | // dojo.NodeList is as pseudo-subclass of Array which adds syntactic |
|---|
| 92 | // sugar for chaining, common iteration operations, animation, and |
|---|
| 93 | // node manipulation. NodeLists are most often returned as the result |
|---|
| 94 | // of dojo.query() calls. |
|---|
| 95 | // example: |
|---|
| 96 | // create a node list from a node |
|---|
| 97 | // | new dojo.NodeList(dojo.byId("foo")); |
|---|
| 98 | |
|---|
| 99 | return tnl(Array.apply(null, arguments)); |
|---|
| 100 | }; |
|---|
| 101 | |
|---|
| 102 | var nl = d.NodeList, nlp = nl.prototype; |
|---|
| 103 | |
|---|
| 104 | // expose adapters and the wrapper as private functions |
|---|
| 105 | |
|---|
| 106 | nl._wrap = tnl; |
|---|
| 107 | nl._adaptAsMap = adaptAsMap; |
|---|
| 108 | nl._adaptAsForEach = adaptAsForEach; |
|---|
| 109 | nl._adaptAsFilter = adaptAsFilter; |
|---|
| 110 | nl._adaptWithCondition = adaptWithCondition; |
|---|
| 111 | |
|---|
| 112 | // mass assignment |
|---|
| 113 | |
|---|
| 114 | // add array redirectors |
|---|
| 115 | d.forEach(["slice", "splice"], function(name){ |
|---|
| 116 | var f = ap[name]; |
|---|
| 117 | nlp[name] = function(){ return tnl(f.apply(this, arguments)); }; |
|---|
| 118 | }); |
|---|
| 119 | // concat should be here but some browsers with native NodeList have problems with it |
|---|
| 120 | |
|---|
| 121 | // add array.js redirectors |
|---|
| 122 | d.forEach(["indexOf", "lastIndexOf", "every", "some"], function(name){ |
|---|
| 123 | var f = d[name]; |
|---|
| 124 | nlp[name] = function(){ return f.apply(d, [this].concat(aps.call(arguments, 0))); }; |
|---|
| 125 | }); |
|---|
| 126 | |
|---|
| 127 | // add conditional methods |
|---|
| 128 | d.forEach(["attr", "style"], function(name){ |
|---|
| 129 | nlp[name] = adaptWithCondition(d[name], magicGuard); |
|---|
| 130 | }); |
|---|
| 131 | |
|---|
| 132 | // add forEach actions |
|---|
| 133 | d.forEach(["connect", "addClass", "removeClass", "toggleClass", "empty"], function(name){ |
|---|
| 134 | nlp[name] = adaptAsForEach(d[name]); |
|---|
| 135 | }); |
|---|
| 136 | |
|---|
| 137 | dojo.extend(dojo.NodeList, { |
|---|
| 138 | // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods |
|---|
| 139 | |
|---|
| 140 | // FIXME: handle return values for #3244 |
|---|
| 141 | // http://trac.dojotoolkit.org/ticket/3244 |
|---|
| 142 | |
|---|
| 143 | // FIXME: |
|---|
| 144 | // need to wrap or implement: |
|---|
| 145 | // join (perhaps w/ innerHTML/outerHTML overload for toString() of items?) |
|---|
| 146 | // reduce |
|---|
| 147 | // reduceRight |
|---|
| 148 | |
|---|
| 149 | /*===== |
|---|
| 150 | slice: function(begin, end){ |
|---|
| 151 | // summary: |
|---|
| 152 | // Returns a new NodeList, maintaining this one in place |
|---|
| 153 | // description: |
|---|
| 154 | // This method behaves exactly like the Array.slice method |
|---|
| 155 | // with the caveat that it returns a dojo.NodeList and not a |
|---|
| 156 | // raw Array. For more details, see: |
|---|
| 157 | // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice |
|---|
| 158 | // begin: Integer |
|---|
| 159 | // Can be a positive or negative integer, with positive |
|---|
| 160 | // integers noting the offset to begin at, and negative |
|---|
| 161 | // integers denoting an offset from the end (i.e., to the left |
|---|
| 162 | // of the end) |
|---|
| 163 | // end: Integer? |
|---|
| 164 | // Optional parameter to describe what position relative to |
|---|
| 165 | // the NodeList's zero index to end the slice at. Like begin, |
|---|
| 166 | // can be positive or negative. |
|---|
| 167 | return tnl(a.slice.apply(this, arguments)); |
|---|
| 168 | }, |
|---|
| 169 | |
|---|
| 170 | splice: function(index, howmany, item){ |
|---|
| 171 | // summary: |
|---|
| 172 | // Returns a new NodeList, manipulating this NodeList based on |
|---|
| 173 | // the arguments passed, potentially splicing in new elements |
|---|
| 174 | // at an offset, optionally deleting elements |
|---|
| 175 | // description: |
|---|
| 176 | // This method behaves exactly like the Array.splice method |
|---|
| 177 | // with the caveat that it returns a dojo.NodeList and not a |
|---|
| 178 | // raw Array. For more details, see: |
|---|
| 179 | // <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice> |
|---|
| 180 | // index: Integer |
|---|
| 181 | // begin can be a positive or negative integer, with positive |
|---|
| 182 | // integers noting the offset to begin at, and negative |
|---|
| 183 | // integers denoting an offset from the end (i.e., to the left |
|---|
| 184 | // of the end) |
|---|
| 185 | // howmany: Integer? |
|---|
| 186 | // Optional parameter to describe what position relative to |
|---|
| 187 | // the NodeList's zero index to end the slice at. Like begin, |
|---|
| 188 | // can be positive or negative. |
|---|
| 189 | // item: Object...? |
|---|
| 190 | // Any number of optional parameters may be passed in to be |
|---|
| 191 | // spliced into the NodeList |
|---|
| 192 | // returns: |
|---|
| 193 | // dojo.NodeList |
|---|
| 194 | return tnl(a.splice.apply(this, arguments)); |
|---|
| 195 | }, |
|---|
| 196 | |
|---|
| 197 | indexOf: function(value, fromIndex){ |
|---|
| 198 | // summary: |
|---|
| 199 | // see dojo.indexOf(). The primary difference is that the acted-on |
|---|
| 200 | // array is implicitly this NodeList |
|---|
| 201 | // value: Object: |
|---|
| 202 | // The value to search for. |
|---|
| 203 | // fromIndex: Integer?: |
|---|
| 204 | // The loction to start searching from. Optional. Defaults to 0. |
|---|
| 205 | // description: |
|---|
| 206 | // For more details on the behavior of indexOf, see: |
|---|
| 207 | // <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf> |
|---|
| 208 | // returns: |
|---|
| 209 | // Positive Integer or 0 for a match, -1 of not found. |
|---|
| 210 | return d.indexOf(this, value, fromIndex); // Integer |
|---|
| 211 | }, |
|---|
| 212 | |
|---|
| 213 | lastIndexOf: function(value, fromIndex){ |
|---|
| 214 | // summary: |
|---|
| 215 | // see dojo.lastIndexOf(). The primary difference is that the |
|---|
| 216 | // acted-on array is implicitly this NodeList |
|---|
| 217 | // description: |
|---|
| 218 | // For more details on the behavior of lastIndexOf, see: |
|---|
| 219 | // <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf> |
|---|
| 220 | // value: Object: |
|---|
| 221 | // The value to search for. |
|---|
| 222 | // fromIndex: Integer?: |
|---|
| 223 | // The loction to start searching from. Optional. Defaults to 0. |
|---|
| 224 | // returns: |
|---|
| 225 | // Positive Integer or 0 for a match, -1 of not found. |
|---|
| 226 | return d.lastIndexOf(this, value, fromIndex); // Integer |
|---|
| 227 | }, |
|---|
| 228 | |
|---|
| 229 | every: function(callback, thisObject){ |
|---|
| 230 | // summary: |
|---|
| 231 | // see `dojo.every()` and: |
|---|
| 232 | // <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every> |
|---|
| 233 | // Takes the same structure of arguments and returns as |
|---|
| 234 | // dojo.every() with the caveat that the passed array is |
|---|
| 235 | // implicitly this NodeList |
|---|
| 236 | // callback: Function: the callback |
|---|
| 237 | // thisObject: Object?: the context |
|---|
| 238 | return d.every(this, callback, thisObject); // Boolean |
|---|
| 239 | }, |
|---|
| 240 | |
|---|
| 241 | some: function(callback, thisObject){ |
|---|
| 242 | // summary: |
|---|
| 243 | // see dojo.some() and: |
|---|
| 244 | // http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some |
|---|
| 245 | // Takes the same structure of arguments and returns as |
|---|
| 246 | // dojo.some() with the caveat that the passed array is |
|---|
| 247 | // implicitly this NodeList |
|---|
| 248 | // callback: Function: the callback |
|---|
| 249 | // thisObject: Object?: the context |
|---|
| 250 | return d.some(this, callback, thisObject); // Boolean |
|---|
| 251 | }, |
|---|
| 252 | =====*/ |
|---|
| 253 | |
|---|
| 254 | concat: function(item){ |
|---|
| 255 | // summary: |
|---|
| 256 | // Returns a new NodeList comprised of items in this NodeList |
|---|
| 257 | // as well as items passed in as parameters |
|---|
| 258 | // description: |
|---|
| 259 | // This method behaves exactly like the Array.concat method |
|---|
| 260 | // with the caveat that it returns a dojo.NodeList and not a |
|---|
| 261 | // raw Array. For more details, see: |
|---|
| 262 | // <http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat> |
|---|
| 263 | // item: Object...? |
|---|
| 264 | // Any number of optional parameters may be passed in to be |
|---|
| 265 | // spliced into the NodeList |
|---|
| 266 | // returns: |
|---|
| 267 | // dojo.NodeList |
|---|
| 268 | |
|---|
| 269 | //return tnl(apc.apply(this, arguments)); |
|---|
| 270 | // the line above won't work for the native NodeList :-( |
|---|
| 271 | |
|---|
| 272 | // implementation notes: |
|---|
| 273 | // 1) Native NodeList is not an array, and cannot be used directly |
|---|
| 274 | // in concat() --- the latter doesn't recognize it as an array, and |
|---|
| 275 | // does not inline it, but append as a single entity. |
|---|
| 276 | // 2) On some browsers (e.g., Safari) the "constructor" property is |
|---|
| 277 | // read-only and cannot be changed. So we have to test for both |
|---|
| 278 | // native NodeList and dojo.NodeList in this property to recognize |
|---|
| 279 | // the node list. |
|---|
| 280 | |
|---|
| 281 | var t = d.isArray(this) ? this : aps.call(this, 0), |
|---|
| 282 | m = d.map(arguments, function(a){ |
|---|
| 283 | return a && !d.isArray(a) && |
|---|
| 284 | (a.constructor === NodeList || a.constructor == nl) ? |
|---|
| 285 | aps.call(a, 0) : a; |
|---|
| 286 | }); |
|---|
| 287 | return tnl(apc.apply(t, m)); // dojo.NodeList |
|---|
| 288 | }, |
|---|
| 289 | |
|---|
| 290 | map: function(/*Function*/ func, /*Function?*/ obj){ |
|---|
| 291 | // summary: |
|---|
| 292 | // see dojo.map(). The primary difference is that the acted-on |
|---|
| 293 | // array is implicitly this NodeList and the return is a |
|---|
| 294 | // dojo.NodeList (a subclass of Array) |
|---|
| 295 | ///return d.map(this, func, obj, d.NodeList); // dojo.NodeList |
|---|
| 296 | return tnl(d.map(this, func, obj)); // dojo.NodeList |
|---|
| 297 | }, |
|---|
| 298 | |
|---|
| 299 | forEach: function(callback, thisObj){ |
|---|
| 300 | // summary: |
|---|
| 301 | // see dojo.forEach(). The primary difference is that the acted-on |
|---|
| 302 | // array is implicitly this NodeList |
|---|
| 303 | d.forEach(this, callback, thisObj); |
|---|
| 304 | // non-standard return to allow easier chaining |
|---|
| 305 | return this; // dojo.NodeList |
|---|
| 306 | }, |
|---|
| 307 | |
|---|
| 308 | |
|---|
| 309 | /*===== |
|---|
| 310 | coords: function(){ |
|---|
| 311 | // summary: |
|---|
| 312 | // Returns the box objects all elements in a node list as |
|---|
| 313 | // an Array (*not* a NodeList) |
|---|
| 314 | |
|---|
| 315 | return d.map(this, d.coords); // Array |
|---|
| 316 | }, |
|---|
| 317 | |
|---|
| 318 | attr: function(property, value){ |
|---|
| 319 | // summary: |
|---|
| 320 | // gets or sets the DOM attribute for every element in the |
|---|
| 321 | // NodeList |
|---|
| 322 | // property: String |
|---|
| 323 | // the attribute to get/set |
|---|
| 324 | // value: String? |
|---|
| 325 | // optional. The value to set the property to |
|---|
| 326 | // returns: |
|---|
| 327 | // if no value is passed, the result is an array of attribute values |
|---|
| 328 | // If a value is passed, the return is this NodeList |
|---|
| 329 | return; // dojo.NodeList |
|---|
| 330 | return; // Array |
|---|
| 331 | }, |
|---|
| 332 | |
|---|
| 333 | style: function(property, value){ |
|---|
| 334 | // summary: |
|---|
| 335 | // gets or sets the CSS property for every element in the NodeList |
|---|
| 336 | // property: String |
|---|
| 337 | // the CSS property to get/set, in JavaScript notation |
|---|
| 338 | // ("lineHieght" instead of "line-height") |
|---|
| 339 | // value: String? |
|---|
| 340 | // optional. The value to set the property to |
|---|
| 341 | // returns: |
|---|
| 342 | // if no value is passed, the result is an array of strings. |
|---|
| 343 | // If a value is passed, the return is this NodeList |
|---|
| 344 | return; // dojo.NodeList |
|---|
| 345 | return; // Array |
|---|
| 346 | }, |
|---|
| 347 | |
|---|
| 348 | addClass: function(className){ |
|---|
| 349 | // summary: |
|---|
| 350 | // adds the specified class to every node in the list |
|---|
| 351 | // className: String |
|---|
| 352 | // the CSS class to add |
|---|
| 353 | return; // dojo.NodeList |
|---|
| 354 | }, |
|---|
| 355 | |
|---|
| 356 | removeClass: function(className){ |
|---|
| 357 | // summary: |
|---|
| 358 | // removes the specified class from every node in the list |
|---|
| 359 | // className: String |
|---|
| 360 | // the CSS class to add |
|---|
| 361 | // returns: |
|---|
| 362 | // dojo.NodeList, this list |
|---|
| 363 | return; // dojo.NodeList |
|---|
| 364 | }, |
|---|
| 365 | |
|---|
| 366 | toggleClass: function(className, condition){ |
|---|
| 367 | // summary: |
|---|
| 368 | // Adds a class to node if not present, or removes if present. |
|---|
| 369 | // Pass a boolean condition if you want to explicitly add or remove. |
|---|
| 370 | // condition: Boolean? |
|---|
| 371 | // If passed, true means to add the class, false means to remove. |
|---|
| 372 | // className: String |
|---|
| 373 | // the CSS class to add |
|---|
| 374 | return; // dojo.NodeList |
|---|
| 375 | }, |
|---|
| 376 | |
|---|
| 377 | connect: function(methodName, objOrFunc, funcName){ |
|---|
| 378 | // summary: |
|---|
| 379 | // attach event handlers to every item of the NodeList. Uses dojo.connect() |
|---|
| 380 | // so event properties are normalized |
|---|
| 381 | // methodName: String |
|---|
| 382 | // the name of the method to attach to. For DOM events, this should be |
|---|
| 383 | // the lower-case name of the event |
|---|
| 384 | // objOrFunc: Object|Function|String |
|---|
| 385 | // if 2 arguments are passed (methodName, objOrFunc), objOrFunc should |
|---|
| 386 | // reference a function or be the name of the function in the global |
|---|
| 387 | // namespace to attach. If 3 arguments are provided |
|---|
| 388 | // (methodName, objOrFunc, funcName), objOrFunc must be the scope to |
|---|
| 389 | // locate the bound function in |
|---|
| 390 | // funcName: String? |
|---|
| 391 | // optional. A string naming the function in objOrFunc to bind to the |
|---|
| 392 | // event. May also be a function reference. |
|---|
| 393 | // example: |
|---|
| 394 | // add an onclick handler to every button on the page |
|---|
| 395 | // | dojo.query("div:nth-child(odd)").connect("onclick", function(e){ |
|---|
| 396 | // | console.log("clicked!"); |
|---|
| 397 | // | }); |
|---|
| 398 | // example: |
|---|
| 399 | // attach foo.bar() to every odd div's onmouseover |
|---|
| 400 | // | dojo.query("div:nth-child(odd)").connect("onmouseover", foo, "bar"); |
|---|
| 401 | }, |
|---|
| 402 | |
|---|
| 403 | empty: function(){ |
|---|
| 404 | // summary: |
|---|
| 405 | // clears all content from each node in the list. Effectively |
|---|
| 406 | // equivalent to removing all child nodes from every item in |
|---|
| 407 | // the list. |
|---|
| 408 | return this.forEach("item.innerHTML='';"); // dojo.NodeList |
|---|
| 409 | // FIXME: should we be checking for and/or disposing of widgets below these nodes? |
|---|
| 410 | }, |
|---|
| 411 | =====*/ |
|---|
| 412 | |
|---|
| 413 | // useful html methods |
|---|
| 414 | coords: adaptAsMap(d.coords), |
|---|
| 415 | |
|---|
| 416 | // FIXME: connectPublisher()? connectRunOnce()? |
|---|
| 417 | |
|---|
| 418 | /* |
|---|
| 419 | destroy: function(){ |
|---|
| 420 | // summary: |
|---|
| 421 | // destroys every item in the list. |
|---|
| 422 | this.forEach(d.destroy); |
|---|
| 423 | // FIXME: should we be checking for and/or disposing of widgets below these nodes? |
|---|
| 424 | }, |
|---|
| 425 | */ |
|---|
| 426 | |
|---|
| 427 | place: function(/*String||Node*/ queryOrNode, /*String*/ position){ |
|---|
| 428 | // summary: |
|---|
| 429 | // places elements of this node list relative to the first element matched |
|---|
| 430 | // by queryOrNode. Returns the original NodeList. See: `dojo.place` |
|---|
| 431 | // queryOrNode: |
|---|
| 432 | // may be a string representing any valid CSS3 selector or a DOM node. |
|---|
| 433 | // In the selector case, only the first matching element will be used |
|---|
| 434 | // for relative positioning. |
|---|
| 435 | // position: |
|---|
| 436 | // can be one of: |
|---|
| 437 | // | * "last" (default) |
|---|
| 438 | // | * "first" |
|---|
| 439 | // | * "before" |
|---|
| 440 | // | * "after" |
|---|
| 441 | // | * "only" |
|---|
| 442 | // | * "replace" |
|---|
| 443 | // or an offset in the childNodes property |
|---|
| 444 | var item = d.query(queryOrNode)[0]; |
|---|
| 445 | return this.forEach(function(node){ d.place(node, item, position); }); // dojo.NodeList |
|---|
| 446 | }, |
|---|
| 447 | |
|---|
| 448 | orphan: function(/*String?*/ simpleFilter){ |
|---|
| 449 | // summary: |
|---|
| 450 | // removes elements in this list that match the simple |
|---|
| 451 | // filter from their parents and returns them as a new |
|---|
| 452 | // NodeList. |
|---|
| 453 | // simpleFilter: |
|---|
| 454 | // single-expression CSS rule. For example, ".thinger" or |
|---|
| 455 | // "#someId[attrName='value']" but not "div > span". In short, |
|---|
| 456 | // anything which does not invoke a descent to evaluate but |
|---|
| 457 | // can instead be used to test a single node is acceptable. |
|---|
| 458 | // returns: |
|---|
| 459 | // `dojo.NodeList` containing the orpahned elements |
|---|
| 460 | return (simpleFilter ? d._filterQueryResult(this, simpleFilter) : this).forEach(orphan); // dojo.NodeList |
|---|
| 461 | }, |
|---|
| 462 | |
|---|
| 463 | adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){ |
|---|
| 464 | // summary: |
|---|
| 465 | // places any/all elements in queryOrListOrNode at a |
|---|
| 466 | // position relative to the first element in this list. |
|---|
| 467 | // Returns a dojo.NodeList of the adopted elements. |
|---|
| 468 | // queryOrListOrNode: |
|---|
| 469 | // a DOM node or a query string or a query result. |
|---|
| 470 | // Represents the nodes to be adopted relative to the |
|---|
| 471 | // first element of this NodeList. |
|---|
| 472 | // position: |
|---|
| 473 | // can be one of: |
|---|
| 474 | // | * "last" (default) |
|---|
| 475 | // | * "first" |
|---|
| 476 | // | * "before" |
|---|
| 477 | // | * "after" |
|---|
| 478 | // | * "only" |
|---|
| 479 | // | * "replace" |
|---|
| 480 | // or an offset in the childNodes property |
|---|
| 481 | return d.query(queryOrListOrNode).place(item[0], position); // dojo.NodeList |
|---|
| 482 | }, |
|---|
| 483 | |
|---|
| 484 | // FIXME: do we need this? |
|---|
| 485 | query: function(/*String*/ queryStr){ |
|---|
| 486 | // summary: |
|---|
| 487 | // Returns a new list whose memebers match the passed query, |
|---|
| 488 | // assuming elements of the current NodeList as the root for |
|---|
| 489 | // each search. |
|---|
| 490 | // example: |
|---|
| 491 | // assume a DOM created by this markup: |
|---|
| 492 | // | <div id="foo"> |
|---|
| 493 | // | <p> |
|---|
| 494 | // | bacon is tasty, <span>dontcha think?</span> |
|---|
| 495 | // | </p> |
|---|
| 496 | // | </div> |
|---|
| 497 | // | <div id="bar"> |
|---|
| 498 | // | <p>great commedians may not be funny <span>in person</span></p> |
|---|
| 499 | // | </div> |
|---|
| 500 | // If we are presented with the following defintion for a NodeList: |
|---|
| 501 | // | var l = new dojo.NodeList(dojo.byId("foo"), dojo.byId("bar")); |
|---|
| 502 | // it's possible to find all span elements under paragraphs |
|---|
| 503 | // contained by these elements with this sub-query: |
|---|
| 504 | // | var spans = l.query("p span"); |
|---|
| 505 | |
|---|
| 506 | // FIXME: probably slow |
|---|
| 507 | if(!queryStr){ return this; } |
|---|
| 508 | var ret = this.map(function(node){ |
|---|
| 509 | // FIXME: why would we ever get undefined here? |
|---|
| 510 | return d.query(queryStr, node).filter(function(subNode){ return subNode !== undefined; }); |
|---|
| 511 | }); |
|---|
| 512 | return tnl(apc.apply([], ret)); // dojo.NodeList |
|---|
| 513 | }, |
|---|
| 514 | |
|---|
| 515 | filter: function(/*String|Function*/ simpleFilter){ |
|---|
| 516 | // summary: |
|---|
| 517 | // "masks" the built-in javascript filter() method (supported |
|---|
| 518 | // in Dojo via `dojo.filter`) to support passing a simple |
|---|
| 519 | // string filter in addition to supporting filtering function |
|---|
| 520 | // objects. |
|---|
| 521 | // simpleFilter: |
|---|
| 522 | // If a string, a single-expression CSS rule. For example, ".thinger" or |
|---|
| 523 | // "#someId[attrName='value']" but not "div > span". In short, |
|---|
| 524 | // anything which does not invoke a descent to evaluate but |
|---|
| 525 | // can instead be used to test a single node is acceptable. |
|---|
| 526 | // example: |
|---|
| 527 | // "regular" JS filter syntax as exposed in dojo.filter: |
|---|
| 528 | // | dojo.query("*").filter(function(item){ |
|---|
| 529 | // | // highlight every paragraph |
|---|
| 530 | // | return (item.nodeName == "p"); |
|---|
| 531 | // | }).style("backgroundColor", "yellow"); |
|---|
| 532 | // example: |
|---|
| 533 | // the same filtering using a CSS selector |
|---|
| 534 | // | dojo.query("*").filter("p").styles("backgroundColor", "yellow"); |
|---|
| 535 | |
|---|
| 536 | var a = arguments, items = this, start = 0; |
|---|
| 537 | if(d.isString(simpleFilter)){ |
|---|
| 538 | items = d._filterQueryResult(this, a[0]); |
|---|
| 539 | if(a.length == 1){ |
|---|
| 540 | // if we only got a string query, pass back the filtered results |
|---|
| 541 | return items; // dojo.NodeList |
|---|
| 542 | } |
|---|
| 543 | // if we got a callback, run it over the filtered items |
|---|
| 544 | start = 1; |
|---|
| 545 | } |
|---|
| 546 | return tnl(d.filter(items, a[start], a[start + 1])); // dojo.NodeList |
|---|
| 547 | }, |
|---|
| 548 | |
|---|
| 549 | /* |
|---|
| 550 | // FIXME: should this be "copyTo" and include parenting info? |
|---|
| 551 | clone: function(){ |
|---|
| 552 | // summary: |
|---|
| 553 | // creates node clones of each element of this list |
|---|
| 554 | // and returns a new list containing the clones |
|---|
| 555 | }, |
|---|
| 556 | */ |
|---|
| 557 | |
|---|
| 558 | addContent: function(/*String|DomNode*/ content, /*String||Integer?*/ position){ |
|---|
| 559 | // summary: |
|---|
| 560 | // add a node or some HTML as a string to every item in the list. |
|---|
| 561 | // Returns the original list. |
|---|
| 562 | // description: |
|---|
| 563 | // a copy of the HTML content is added to each item in the |
|---|
| 564 | // list, with an optional position argument. If no position |
|---|
| 565 | // argument is provided, the content is appended to the end of |
|---|
| 566 | // each item. |
|---|
| 567 | // content: |
|---|
| 568 | // DOM node or HTML in string format to add at position to |
|---|
| 569 | // every item |
|---|
| 570 | // position: |
|---|
| 571 | // can be one of: |
|---|
| 572 | // * "last"||"end" (default) |
|---|
| 573 | // * "first||"start" |
|---|
| 574 | // * "before" |
|---|
| 575 | // * "after" |
|---|
| 576 | // or an offset in the childNodes property |
|---|
| 577 | // example: |
|---|
| 578 | // appends content to the end if the position is ommitted |
|---|
| 579 | // | dojo.query("h3 > p").addContent("hey there!"); |
|---|
| 580 | // example: |
|---|
| 581 | // add something to the front of each element that has a "thinger" property: |
|---|
| 582 | // | dojo.query("[thinger]").addContent("...", "first"); |
|---|
| 583 | // example: |
|---|
| 584 | // adds a header before each element of the list |
|---|
| 585 | // | dojo.query(".note").addContent("<h4>NOTE:</h4>", "before"); |
|---|
| 586 | // example: |
|---|
| 587 | // add a clone of a DOM node to the end of every element in |
|---|
| 588 | // the list, removing it from its existing parent. |
|---|
| 589 | // | dojo.query(".note").addContent(dojo.byId("foo")); |
|---|
| 590 | var c = d.isString(content) ? d._toDom(content, this[0] && this[0].ownerDocument) : content, i, l = this.length - 1; |
|---|
| 591 | for(i = 0; i < l; ++i){ |
|---|
| 592 | d.place(c.cloneNode(true), this[i], position); |
|---|
| 593 | } |
|---|
| 594 | if(l >= 0){ |
|---|
| 595 | d.place(c, this[l], position); |
|---|
| 596 | } |
|---|
| 597 | return this; // dojo.NodeList |
|---|
| 598 | }, |
|---|
| 599 | |
|---|
| 600 | instantiate: function(/*String|Object*/ declaredClass, /*Object?*/ properties){ |
|---|
| 601 | // summary: |
|---|
| 602 | // Create a new instance of a specified class, using the |
|---|
| 603 | // specified properties and each node in the nodeList as a |
|---|
| 604 | // srcNodeRef |
|---|
| 605 | // |
|---|
| 606 | var c = d.isFunction(declaredClass) ? declaredClass : d.getObject(declaredClass); |
|---|
| 607 | properties = properties || {}; |
|---|
| 608 | return this.forEach(function(node){ new c(properties, node); }); // dojo.NodeList |
|---|
| 609 | }, |
|---|
| 610 | |
|---|
| 611 | at: function(/*===== index =====*/){ |
|---|
| 612 | // summary: |
|---|
| 613 | // Returns a new NodeList comprised of items in this NodeList |
|---|
| 614 | // at the given index or indices. |
|---|
| 615 | // index: Integer... |
|---|
| 616 | // One or more 0-based indices of items in the current NodeList. |
|---|
| 617 | // returns: |
|---|
| 618 | // dojo.NodeList |
|---|
| 619 | var t = new dojo.NodeList(); |
|---|
| 620 | d.forEach(arguments, function(i){ if(this[i]){ t.push(this[i]); }}, this); |
|---|
| 621 | return t; // dojo.NodeList |
|---|
| 622 | } |
|---|
| 623 | |
|---|
| 624 | }); |
|---|
| 625 | |
|---|
| 626 | // syntactic sugar for DOM events |
|---|
| 627 | d.forEach([ |
|---|
| 628 | "blur", "focus", "change", "click", "error", "keydown", "keypress", "keyup", "load", "mousedown", |
|---|
| 629 | "mouseenter", "mouseleave", "mousemove", "mouseout", "mouseover", "mouseup", "submit" |
|---|
| 630 | ], function(evt){ |
|---|
| 631 | var _oe = "on"+evt; |
|---|
| 632 | nlp[_oe] = function(a, b){ |
|---|
| 633 | return this.connect(_oe, a, b); |
|---|
| 634 | } |
|---|
| 635 | // FIXME: should these events trigger publishes? |
|---|
| 636 | /* |
|---|
| 637 | return (a ? this.connect(_oe, a, b) : |
|---|
| 638 | this.forEach(function(n){ |
|---|
| 639 | // FIXME: |
|---|
| 640 | // listeners get buried by |
|---|
| 641 | // addEventListener and can't be dug back |
|---|
| 642 | // out to be triggered externally. |
|---|
| 643 | // see: |
|---|
| 644 | // http://developer.mozilla.org/en/docs/DOM:element |
|---|
| 645 | |
|---|
| 646 | console.log(n, evt, _oe); |
|---|
| 647 | |
|---|
| 648 | // FIXME: need synthetic event support! |
|---|
| 649 | var _e = { target: n, faux: true, type: evt }; |
|---|
| 650 | // dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt }); |
|---|
| 651 | try{ n[evt](_e); }catch(e){ console.log(e); } |
|---|
| 652 | try{ n[_oe](_e); }catch(e){ console.log(e); } |
|---|
| 653 | }) |
|---|
| 654 | ); |
|---|
| 655 | } |
|---|
| 656 | */ |
|---|
| 657 | } |
|---|
| 658 | ); |
|---|
| 659 | |
|---|
| 660 | //>>excludeStart("webkitMobile", kwArgs.webkitMobile); |
|---|
| 661 | })(); |
|---|
| 662 | //>>excludeEnd("webkitMobile"); |
|---|