New file |
0,0 → 1,467 |
if(!dojo._hasResource["dojo._base.NodeList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. |
dojo._hasResource["dojo._base.NodeList"] = true; |
dojo.provide("dojo._base.NodeList"); |
dojo.require("dojo._base.lang"); |
dojo.require("dojo._base.array"); |
|
(function(){ |
|
var d = dojo; |
|
var tnl = function(arr){ |
arr.constructor = dojo.NodeList; |
dojo._mixin(arr, dojo.NodeList.prototype); |
return arr; |
} |
|
dojo.NodeList = function(){ |
// summary: |
// dojo.NodeList is as subclass of Array which adds syntactic |
// sugar for chaining, common iteration operations, animation, |
// and node manipulation. NodeLists are most often returned as |
// the result of dojo.query() calls. |
// example: |
// create a node list from a node |
// | new dojo.NodeList(dojo.byId("foo")); |
|
return tnl(Array.apply(null, arguments)); |
} |
|
dojo.NodeList._wrap = tnl; |
|
dojo.extend(dojo.NodeList, { |
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods |
|
// FIXME: handle return values for #3244 |
// http://trac.dojotoolkit.org/ticket/3244 |
|
// FIXME: |
// need to wrap or implement: |
// join (perhaps w/ innerHTML/outerHTML overload for toString() of items?) |
// reduce |
// reduceRight |
|
slice: function(/*===== begin, end =====*/){ |
// summary: |
// Returns a new NodeList, maintaining this one in place |
// description: |
// This method behaves exactly like the Array.slice method |
// with the caveat that it returns a dojo.NodeList and not a |
// raw Array. For more details, see: |
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice |
// begin: Integer |
// Can be a positive or negative integer, with positive |
// integers noting the offset to begin at, and negative |
// integers denoting an offset from the end (i.e., to the left |
// of the end) |
// end: Integer? |
// Optional parameter to describe what position relative to |
// the NodeList's zero index to end the slice at. Like begin, |
// can be positive or negative. |
var a = dojo._toArray(arguments); |
return tnl(a.slice.apply(this, a)); |
}, |
|
splice: function(/*===== index, howmany, item =====*/){ |
// summary: |
// Returns a new NodeList, manipulating this NodeList based on |
// the arguments passed, potentially splicing in new elements |
// at an offset, optionally deleting elements |
// description: |
// This method behaves exactly like the Array.splice method |
// with the caveat that it returns a dojo.NodeList and not a |
// raw Array. For more details, see: |
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice |
// index: Integer |
// begin can be a positive or negative integer, with positive |
// integers noting the offset to begin at, and negative |
// integers denoting an offset from the end (i.e., to the left |
// of the end) |
// howmany: Integer? |
// Optional parameter to describe what position relative to |
// the NodeList's zero index to end the slice at. Like begin, |
// can be positive or negative. |
// item: Object...? |
// Any number of optional parameters may be passed in to be |
// spliced into the NodeList |
// returns: |
// dojo.NodeList |
var a = dojo._toArray(arguments); |
return tnl(a.splice.apply(this, a)); |
}, |
|
concat: function(/*===== item =====*/){ |
// summary: |
// Returns a new NodeList comprised of items in this NodeList |
// as well as items passed in as parameters |
// description: |
// This method behaves exactly like the Array.concat method |
// with the caveat that it returns a dojo.NodeList and not a |
// raw Array. For more details, see: |
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat |
// item: Object...? |
// Any number of optional parameters may be passed in to be |
// spliced into the NodeList |
// returns: |
// dojo.NodeList |
var a = dojo._toArray(arguments, 0, [this]); |
return tnl(a.concat.apply([], a)); |
}, |
|
indexOf: function(/*Object*/ value, /*Integer?*/ fromIndex){ |
// summary: |
// see dojo.indexOf(). The primary difference is that the acted-on |
// array is implicitly this NodeList |
// value: |
// The value to search for. |
// fromIndex: |
// The loction to start searching from. Optional. Defaults to 0. |
// description: |
// For more details on the behavior of indexOf, see: |
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf |
// returns: |
// Positive Integer or 0 for a match, -1 of not found. |
return d.indexOf(this, value, fromIndex); // Integer |
}, |
|
lastIndexOf: function(/*===== value, fromIndex =====*/){ |
// summary: |
// see dojo.lastIndexOf(). The primary difference is that the |
// acted-on array is implicitly this NodeList |
// description: |
// For more details on the behavior of lastIndexOf, see: |
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf |
// value: Object |
// The value to search for. |
// fromIndex: Integer? |
// The loction to start searching from. Optional. Defaults to 0. |
// returns: |
// Positive Integer or 0 for a match, -1 of not found. |
return d.lastIndexOf.apply(d, d._toArray(arguments, 0, [this])); // Integer |
}, |
|
every: function(/*Function*/callback, /*Object?*/thisObject){ |
// summary: |
// see dojo.every() and: |
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every |
// Takes the same structure of arguments and returns as |
// dojo.every() with the caveat that the passed array is |
// implicitly this NodeList |
return d.every(this, callback, thisObject); // Boolean |
}, |
|
some: function(/*Function*/callback, /*Object?*/thisObject){ |
// summary: |
// see dojo.some() and: |
// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some |
// Takes the same structure of arguments and returns as |
// dojo.some() with the caveat that the passed array is |
// implicitly this NodeList |
return d.some(this, callback, thisObject); // Boolean |
}, |
|
map: function(/*Function*/ func, /*Function?*/ obj){ |
// summary: |
// see dojo.map(). The primary difference is that the acted-on |
// array is implicitly this NodeList and the return is a |
// dojo.NodeList (a subclass of Array) |
|
return d.map(this, func, obj, d.NodeList); // dojo.NodeList |
}, |
|
forEach: function(callback, thisObj){ |
// summary: |
// see dojo.forEach(). The primary difference is that the acted-on |
// array is implicitly this NodeList |
|
d.forEach(this, callback, thisObj); |
return this; // dojo.NodeList non-standard return to allow easier chaining |
}, |
|
// custom methods |
|
coords: function(){ |
// summary: |
// Returns the box objects all elements in a node list as |
// an Array (*not* a NodeList) |
|
return d.map(this, d.coords); |
}, |
|
style: function(/*===== property, value =====*/){ |
// summary: |
// gets or sets the CSS property for every element in the NodeList |
// property: String |
// the CSS property to get/set, in JavaScript notation |
// ("lineHieght" instead of "line-height") |
// value: String? |
// optional. The value to set the property to |
// return: |
// if no value is passed, the result is an array of strings. |
// If a value is passed, the return is this NodeList |
var aa = d._toArray(arguments, 0, [null]); |
var s = this.map(function(i){ |
aa[0] = i; |
return d.style.apply(d, aa); |
}); |
return (arguments.length > 1) ? this : s; // String||dojo.NodeList |
}, |
|
styles: function(/*===== property, value =====*/){ |
// summary: |
// Deprecated. Use NodeList.style instead. Will be removed in |
// Dojo 1.1. Gets or sets the CSS property for every element |
// in the NodeList |
// property: String |
// the CSS property to get/set, in JavaScript notation |
// ("lineHieght" instead of "line-height") |
// value: String? |
// optional. The value to set the property to |
// return: |
// if no value is passed, the result is an array of strings. |
// If a value is passed, the return is this NodeList |
d.deprecated("NodeList.styles", "use NodeList.style instead", "1.1"); |
return this.style.apply(this, arguments); |
}, |
|
addClass: function(/*String*/ className){ |
// summary: |
// adds the specified class to every node in the list |
// |
this.forEach(function(i){ d.addClass(i, className); }); |
return this; |
}, |
|
removeClass: function(/*String*/ className){ |
this.forEach(function(i){ d.removeClass(i, className); }); |
return this; |
}, |
|
// FIXME: toggleClass()? connectPublisher()? connectRunOnce()? |
|
place: function(/*String||Node*/ queryOrNode, /*String*/ position){ |
// summary: |
// places elements of this node list relative to the first element matched |
// by queryOrNode. Returns the original NodeList. |
// queryOrNode: |
// may be a string representing any valid CSS3 selector or a DOM node. |
// In the selector case, only the first matching element will be used |
// for relative positioning. |
// position: |
// can be one of: |
// "last"||"end" (default) |
// "first||"start" |
// "before" |
// "after" |
// or an offset in the childNodes property |
var item = d.query(queryOrNode)[0]; |
position = position||"last"; |
|
for(var x=0; x<this.length; x++){ |
d.place(this[x], item, position); |
} |
return this; // dojo.NodeList |
}, |
|
connect: function(/*String*/ methodName, /*Object||Function||String*/ objOrFunc, /*String?*/ funcName){ |
// summary: |
// attach event handlers to every item of the NodeList. Uses dojo.connect() |
// so event properties are normalized |
// methodName: |
// the name of the method to attach to. For DOM events, this should be |
// the lower-case name of the event |
// objOrFunc: |
// if 2 arguments are passed (methodName, objOrFunc), objOrFunc should |
// reference a function or be the name of the function in the global |
// namespace to attach. If 3 arguments are provided |
// (methodName, objOrFunc, funcName), objOrFunc must be the scope to |
// locate the bound function in |
// funcName: |
// optional. A string naming the function in objOrFunc to bind to the |
// event. May also be a function reference. |
// example: |
// add an onclick handler to every button on the page |
// | dojo.query("onclick", function(e){ |
// | console.debug("clicked!"); |
// | }); |
// example: |
// attach foo.bar() to every odd div's onmouseover |
// | dojo.query("div:nth-child(odd)").onclick("onmouseover", foo, "bar"); |
this.forEach(function(item){ |
d.connect(item, methodName, objOrFunc, funcName); |
}); |
return this; // dojo.NodeList |
}, |
|
orphan: function(/*String?*/ simpleFilter){ |
// summary: |
// removes elements in this list that match the simple |
// filter from their parents and returns them as a new |
// NodeList. |
// simpleFilter: single-expression CSS filter |
// return: a dojo.NodeList of all of the elements orpahned |
var orphans = (simpleFilter) ? d._filterQueryResult(this, simpleFilter) : this; |
orphans.forEach(function(item){ |
if(item["parentNode"]){ |
item.parentNode.removeChild(item); |
} |
}); |
return orphans; // dojo.NodeList |
}, |
|
adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){ |
// summary: |
// places any/all elements in queryOrListOrNode at a |
// position relative to the first element in this list. |
// Returns a dojo.NodeList of the adopted elements. |
// queryOrListOrNode: |
// a DOM node or a query string or a query result. |
// Represents the nodes to be adopted relative to the |
// first element of this NodeList. |
// position: |
// optional. One of: |
// "last"||"end" (default) |
// "first||"start" |
// "before" |
// "after" |
// or an offset in the childNodes property |
var item = this[0]; |
return d.query(queryOrListOrNode).forEach(function(ai){ d.place(ai, item, (position||"last")); }); // dojo.NodeList |
}, |
|
// FIXME: do we need this? |
query: function(/*String*/ queryStr){ |
// summary: |
// Returns a new, flattened NodeList. Elements of the new list |
// satisfy the passed query but use elements of the |
// current NodeList as query roots. |
|
queryStr = queryStr||""; |
|
// FIXME: probably slow |
var ret = d.NodeList(); |
this.forEach(function(item){ |
d.query(queryStr, item).forEach(function(subItem){ |
if(typeof subItem != "undefined"){ |
ret.push(subItem); |
} |
}); |
}); |
return ret; // dojo.NodeList |
}, |
|
filter: function(/*String*/ simpleQuery){ |
// summary: |
// "masks" the built-in javascript filter() method to support |
// passing a simple string filter in addition to supporting |
// filtering function objects. |
// example: |
// "regular" JS filter syntax as exposed in dojo.filter: |
// | dojo.query("*").filter(function(item){ |
// | // highlight every paragraph |
// | return (item.nodeName == "p"); |
// | }).styles("backgroundColor", "yellow"); |
// example: |
// the same filtering using a CSS selector |
// | dojo.query("*").filter("p").styles("backgroundColor", "yellow"); |
|
var items = this; |
var _a = arguments; |
var r = d.NodeList(); |
var rp = function(t){ |
if(typeof t != "undefined"){ |
r.push(t); |
} |
} |
if(d.isString(simpleQuery)){ |
items = d._filterQueryResult(this, _a[0]); |
if(_a.length == 1){ |
// if we only got a string query, pass back the filtered results |
return items; // dojo.NodeList |
} |
// if we got a callback, run it over the filtered items |
d.forEach(d.filter(items, _a[1], _a[2]), rp); |
return r; // dojo.NodeList |
} |
// handle the (callback, [thisObject]) case |
d.forEach(d.filter(items, _a[0], _a[1]), rp); |
return r; // dojo.NodeList |
|
}, |
|
/* |
// FIXME: should this be "copyTo" and include parenting info? |
clone: function(){ |
// summary: |
// creates node clones of each element of this list |
// and returns a new list containing the clones |
}, |
*/ |
|
addContent: function(/*String*/ content, /*String||Integer?*/ position){ |
// summary: |
// add a node or some HTML as a string to every item in the list. |
// Returns the original list. |
// content: |
// the HTML in string format to add at position to every item |
// position: |
// One of: |
// "last"||"end" (default) |
// "first||"start" |
// "before" |
// "after" |
// or an integer offset in the childNodes property |
var ta = d.doc.createElement("span"); |
if(d.isString(content)){ |
ta.innerHTML = content; |
}else{ |
ta.appendChild(content); |
} |
var ct = ((position == "first")||(position == "after")) ? "lastChild" : "firstChild"; |
this.forEach(function(item){ |
var tn = ta.cloneNode(true); |
while(tn[ct]){ |
d.place(tn[ct], item, position); |
} |
}); |
return this; // dojo.NodeList |
} |
}); |
|
// syntactic sugar for DOM events |
d.forEach([ |
"blur", "click", "keydown", "keypress", "keyup", "mousedown", "mouseenter", |
"mouseleave", "mousemove", "mouseout", "mouseover", "mouseup" |
], function(evt){ |
var _oe = "on"+evt; |
dojo.NodeList.prototype[_oe] = function(a, b){ |
return this.connect(_oe, a, b); |
} |
// FIXME: should these events trigger publishes? |
/* |
return (a ? this.connect(_oe, a, b) : |
this.forEach(function(n){ |
// FIXME: |
// listeners get buried by |
// addEventListener and can't be dug back |
// out to be triggered externally. |
// see: |
// http://developer.mozilla.org/en/docs/DOM:element |
|
console.debug(n, evt, _oe); |
|
// FIXME: need synthetic event support! |
var _e = { target: n, faux: true, type: evt }; |
// dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt }); |
try{ n[evt](_e); }catch(e){ console.debug(e); } |
try{ n[_oe](_e); }catch(e){ console.debug(e); } |
}) |
); |
} |
*/ |
} |
); |
|
})(); |
|
} |