Subversion Repositories Applications.papyrus

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2150 mathias 1
if(!dojo._hasResource["dojo._base.NodeList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
2
dojo._hasResource["dojo._base.NodeList"] = true;
3
dojo.provide("dojo._base.NodeList");
4
dojo.require("dojo._base.lang");
5
dojo.require("dojo._base.array");
6
 
7
(function(){
8
 
9
	var d = dojo;
10
 
11
	var tnl = function(arr){
12
		arr.constructor = dojo.NodeList;
13
		dojo._mixin(arr, dojo.NodeList.prototype);
14
		return arr;
15
	}
16
 
17
	dojo.NodeList = function(){
18
		//	summary:
19
		//		dojo.NodeList is as subclass of Array which adds syntactic
20
		//		sugar for chaining, common iteration operations, animation,
21
		//		and node manipulation. NodeLists are most often returned as
22
		//		the result of dojo.query() calls.
23
		//	example:
24
		//		create a node list from a node
25
		//		|	new dojo.NodeList(dojo.byId("foo"));
26
 
27
		return tnl(Array.apply(null, arguments));
28
	}
29
 
30
	dojo.NodeList._wrap = tnl;
31
 
32
	dojo.extend(dojo.NodeList, {
33
		// http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array#Methods
34
 
35
		// FIXME: handle return values for #3244
36
		//		http://trac.dojotoolkit.org/ticket/3244
37
 
38
		// FIXME:
39
		//		need to wrap or implement:
40
		//			join (perhaps w/ innerHTML/outerHTML overload for toString() of items?)
41
		//			reduce
42
		//			reduceRight
43
 
44
		slice: function(/*===== begin, end =====*/){
45
			// summary:
46
			//		Returns a new NodeList, maintaining this one in place
47
			// description:
48
			//		This method behaves exactly like the Array.slice method
49
			//		with the caveat that it returns a dojo.NodeList and not a
50
			//		raw Array. For more details, see:
51
			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:slice
52
			// begin: Integer
53
			//		Can be a positive or negative integer, with positive
54
			//		integers noting the offset to begin at, and negative
55
			//		integers denoting an offset from the end (i.e., to the left
56
			//		of the end)
57
			// end: Integer?
58
			//		Optional parameter to describe what position relative to
59
			//		the NodeList's zero index to end the slice at. Like begin,
60
			//		can be positive or negative.
61
			var a = dojo._toArray(arguments);
62
			return tnl(a.slice.apply(this, a));
63
		},
64
 
65
		splice: function(/*===== index, howmany, item =====*/){
66
			// summary:
67
			//		Returns a new NodeList, manipulating this NodeList based on
68
			//		the arguments passed, potentially splicing in new elements
69
			//		at an offset, optionally deleting elements
70
			// description:
71
			//		This method behaves exactly like the Array.splice method
72
			//		with the caveat that it returns a dojo.NodeList and not a
73
			//		raw Array. For more details, see:
74
			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:splice
75
			// index: Integer
76
			//		begin can be a positive or negative integer, with positive
77
			//		integers noting the offset to begin at, and negative
78
			//		integers denoting an offset from the end (i.e., to the left
79
			//		of the end)
80
			// howmany: Integer?
81
			//		Optional parameter to describe what position relative to
82
			//		the NodeList's zero index to end the slice at. Like begin,
83
			//		can be positive or negative.
84
			// item: Object...?
85
			//		Any number of optional parameters may be passed in to be
86
			//		spliced into the NodeList
87
			// returns:
88
			//		dojo.NodeList
89
			var a = dojo._toArray(arguments);
90
			return tnl(a.splice.apply(this, a));
91
		},
92
 
93
		concat: function(/*===== item =====*/){
94
			// summary:
95
			//		Returns a new NodeList comprised of items in this NodeList
96
			//		as well as items passed in as parameters
97
			// description:
98
			//		This method behaves exactly like the Array.concat method
99
			//		with the caveat that it returns a dojo.NodeList and not a
100
			//		raw Array. For more details, see:
101
			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:concat
102
			// item: Object...?
103
			//		Any number of optional parameters may be passed in to be
104
			//		spliced into the NodeList
105
			// returns:
106
			//		dojo.NodeList
107
			var a = dojo._toArray(arguments, 0, [this]);
108
			return tnl(a.concat.apply([], a));
109
		},
110
 
111
		indexOf: function(/*Object*/ value, /*Integer?*/ fromIndex){
112
			//	summary:
113
			//		see dojo.indexOf(). The primary difference is that the acted-on
114
			//		array is implicitly this NodeList
115
			// value:
116
			//		The value to search for.
117
			// fromIndex:
118
			//		The loction to start searching from. Optional. Defaults to 0.
119
			//	description:
120
			//		For more details on the behavior of indexOf, see:
121
			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:indexOf
122
			//	returns:
123
			//		Positive Integer or 0 for a match, -1 of not found.
124
			return d.indexOf(this, value, fromIndex); // Integer
125
		},
126
 
127
		lastIndexOf: function(/*===== value, fromIndex =====*/){
128
			// summary:
129
			//		see dojo.lastIndexOf(). The primary difference is that the
130
			//		acted-on array is implicitly this NodeList
131
			//	description:
132
			//		For more details on the behavior of lastIndexOf, see:
133
			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:lastIndexOf
134
			// value: Object
135
			//		The value to search for.
136
			// fromIndex: Integer?
137
			//		The loction to start searching from. Optional. Defaults to 0.
138
			// returns:
139
			//		Positive Integer or 0 for a match, -1 of not found.
140
			return d.lastIndexOf.apply(d, d._toArray(arguments, 0, [this])); // Integer
141
		},
142
 
143
		every: function(/*Function*/callback, /*Object?*/thisObject){
144
			//	summary:
145
			//		see dojo.every() and:
146
			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:every
147
			//		Takes the same structure of arguments and returns as
148
			//		dojo.every() with the caveat that the passed array is
149
			//		implicitly this NodeList
150
			return d.every(this, callback, thisObject); // Boolean
151
		},
152
 
153
		some: function(/*Function*/callback, /*Object?*/thisObject){
154
			//	summary:
155
			//		see dojo.some() and:
156
			//			http://developer.mozilla.org/en/docs/Core_JavaScript_1.5_Reference:Global_Objects:Array:some
157
			//		Takes the same structure of arguments and returns as
158
			//		dojo.some() with the caveat that the passed array is
159
			//		implicitly this NodeList
160
			return d.some(this, callback, thisObject); // Boolean
161
		},
162
 
163
		map: function(/*Function*/ func, /*Function?*/ obj){
164
			//	summary:
165
			//		see dojo.map(). The primary difference is that the acted-on
166
			//		array is implicitly this NodeList and the return is a
167
			//		dojo.NodeList (a subclass of Array)
168
 
169
			return d.map(this, func, obj, d.NodeList); // dojo.NodeList
170
		},
171
 
172
		forEach: function(callback, thisObj){
173
			//	summary:
174
			//		see dojo.forEach(). The primary difference is that the acted-on
175
			//		array is implicitly this NodeList
176
 
177
			d.forEach(this, callback, thisObj);
178
			return this; // dojo.NodeList non-standard return to allow easier chaining
179
		},
180
 
181
		// custom methods
182
 
183
		coords: function(){
184
			//	summary:
185
			// 		Returns the box objects all elements in a node list as
186
			// 		an Array (*not* a NodeList)
187
 
188
			return d.map(this, d.coords);
189
		},
190
 
191
		style: function(/*===== property, value =====*/){
192
			//	summary:
193
			//		gets or sets the CSS property for every element in the NodeList
194
			//	property: String
195
			//		the CSS property to get/set, in JavaScript notation
196
			//		("lineHieght" instead of "line-height")
197
			//	value: String?
198
			//		optional. The value to set the property to
199
			//	return:
200
			//		if no value is passed, the result is an array of strings.
201
			//		If a value is passed, the return is this NodeList
202
			var aa = d._toArray(arguments, 0, [null]);
203
			var s = this.map(function(i){
204
				aa[0] = i;
205
				return d.style.apply(d, aa);
206
			});
207
			return (arguments.length > 1) ? this : s; // String||dojo.NodeList
208
		},
209
 
210
		styles: function(/*===== property, value =====*/){
211
			//	summary:
212
			//		Deprecated. Use NodeList.style instead. Will be removed in
213
			//		Dojo 1.1. Gets or sets the CSS property for every element
214
			//		in the NodeList
215
			//	property: String
216
			//		the CSS property to get/set, in JavaScript notation
217
			//		("lineHieght" instead of "line-height")
218
			//	value: String?
219
			//		optional. The value to set the property to
220
			//	return:
221
			//		if no value is passed, the result is an array of strings.
222
			//		If a value is passed, the return is this NodeList
223
			d.deprecated("NodeList.styles", "use NodeList.style instead", "1.1");
224
			return this.style.apply(this, arguments);
225
		},
226
 
227
		addClass: function(/*String*/ className){
228
			// summary:
229
			//		adds the specified class to every node in the list
230
			//
231
			this.forEach(function(i){ d.addClass(i, className); });
232
			return this;
233
		},
234
 
235
		removeClass: function(/*String*/ className){
236
			this.forEach(function(i){ d.removeClass(i, className); });
237
			return this;
238
		},
239
 
240
		// FIXME: toggleClass()? connectPublisher()? connectRunOnce()?
241
 
242
		place: function(/*String||Node*/ queryOrNode, /*String*/ position){
243
			//	summary:
244
			//		places elements of this node list relative to the first element matched
245
			//		by queryOrNode. Returns the original NodeList.
246
			//	queryOrNode:
247
			//		may be a string representing any valid CSS3 selector or a DOM node.
248
			//		In the selector case, only the first matching element will be used
249
			//		for relative positioning.
250
			//	position:
251
			//		can be one of:
252
			//			"last"||"end" (default)
253
			//			"first||"start"
254
			//			"before"
255
			//			"after"
256
			// 		or an offset in the childNodes property
257
			var item = d.query(queryOrNode)[0];
258
			position = position||"last";
259
 
260
			for(var x=0; x<this.length; x++){
261
				d.place(this[x], item, position);
262
			}
263
			return this; // dojo.NodeList
264
		},
265
 
266
		connect: function(/*String*/ methodName, /*Object||Function||String*/ objOrFunc, /*String?*/ funcName){
267
			//	summary:
268
			//		attach event handlers to every item of the NodeList. Uses dojo.connect()
269
			//		so event properties are normalized
270
			//	methodName:
271
			//		the name of the method to attach to. For DOM events, this should be
272
			//		the lower-case name of the event
273
			//	objOrFunc:
274
			//		if 2 arguments are passed (methodName, objOrFunc), objOrFunc should
275
			//		reference a function or be the name of the function in the global
276
			//		namespace to attach. If 3 arguments are provided
277
			//		(methodName, objOrFunc, funcName), objOrFunc must be the scope to
278
			//		locate the bound function in
279
			//	funcName:
280
			//		optional. A string naming the function in objOrFunc to bind to the
281
			//		event. May also be a function reference.
282
			//	example:
283
			//		add an onclick handler to every button on the page
284
			//		|	dojo.query("onclick", function(e){
285
			//		|		console.debug("clicked!");
286
			//		|	});
287
			// example:
288
			//		attach foo.bar() to every odd div's onmouseover
289
			//		|	dojo.query("div:nth-child(odd)").onclick("onmouseover", foo, "bar");
290
			this.forEach(function(item){
291
				d.connect(item, methodName, objOrFunc, funcName);
292
			});
293
			return this; // dojo.NodeList
294
		},
295
 
296
		orphan: function(/*String?*/ simpleFilter){
297
			//	summary:
298
			//		removes elements in this list that match the simple
299
			//		filter from their parents and returns them as a new
300
			//		NodeList.
301
			//	simpleFilter: single-expression CSS filter
302
			//	return: a dojo.NodeList of all of the elements orpahned
303
			var orphans = (simpleFilter) ? d._filterQueryResult(this, simpleFilter) : this;
304
			orphans.forEach(function(item){
305
				if(item["parentNode"]){
306
					item.parentNode.removeChild(item);
307
				}
308
			});
309
			return orphans; // dojo.NodeList
310
		},
311
 
312
		adopt: function(/*String||Array||DomNode*/ queryOrListOrNode, /*String?*/ position){
313
			//	summary:
314
			//		places any/all elements in queryOrListOrNode at a
315
			//		position relative to the first element in this list.
316
			//		Returns a dojo.NodeList of the adopted elements.
317
			//	queryOrListOrNode:
318
			//		a DOM node or a query string or a query result.
319
			//		Represents the nodes to be adopted relative to the
320
			//		first element of this NodeList.
321
			//	position:
322
			//		optional. One of:
323
			//			"last"||"end" (default)
324
			//			"first||"start"
325
			//			"before"
326
			//			"after"
327
			// 		or an offset in the childNodes property
328
			var item = this[0];
329
			return d.query(queryOrListOrNode).forEach(function(ai){ d.place(ai, item, (position||"last")); }); // dojo.NodeList
330
		},
331
 
332
		// FIXME: do we need this?
333
		query: function(/*String*/ queryStr){
334
			//	summary:
335
			//		Returns a new, flattened NodeList. Elements of the new list
336
			//		satisfy the passed query but use elements of the
337
			//		current NodeList as query roots.
338
 
339
			queryStr = queryStr||"";
340
 
341
			// FIXME: probably slow
342
			var ret = d.NodeList();
343
			this.forEach(function(item){
344
				d.query(queryStr, item).forEach(function(subItem){
345
					if(typeof subItem != "undefined"){
346
						ret.push(subItem);
347
					}
348
				});
349
			});
350
			return ret; // dojo.NodeList
351
		},
352
 
353
		filter: function(/*String*/ simpleQuery){
354
			//	summary:
355
			// 		"masks" the built-in javascript filter() method to support
356
			//		passing a simple string filter in addition to supporting
357
			//		filtering function objects.
358
			//	example:
359
			//		"regular" JS filter syntax as exposed in dojo.filter:
360
			//		|	dojo.query("*").filter(function(item){
361
			//		|		// highlight every paragraph
362
			//		|		return (item.nodeName == "p");
363
			//		|	}).styles("backgroundColor", "yellow");
364
			// example:
365
			//		the same filtering using a CSS selector
366
			//		|	dojo.query("*").filter("p").styles("backgroundColor", "yellow");
367
 
368
			var items = this;
369
			var _a = arguments;
370
			var r = d.NodeList();
371
			var rp = function(t){
372
				if(typeof t != "undefined"){
373
					r.push(t);
374
				}
375
			}
376
			if(d.isString(simpleQuery)){
377
				items = d._filterQueryResult(this, _a[0]);
378
				if(_a.length == 1){
379
					// if we only got a string query, pass back the filtered results
380
					return items; // dojo.NodeList
381
				}
382
				// if we got a callback, run it over the filtered items
383
				d.forEach(d.filter(items, _a[1], _a[2]), rp);
384
				return r; // dojo.NodeList
385
			}
386
			// handle the (callback, [thisObject]) case
387
			d.forEach(d.filter(items, _a[0], _a[1]), rp);
388
			return r; // dojo.NodeList
389
 
390
		},
391
 
392
		/*
393
		// FIXME: should this be "copyTo" and include parenting info?
394
		clone: function(){
395
			// summary:
396
			//		creates node clones of each element of this list
397
			//		and returns a new list containing the clones
398
		},
399
		*/
400
 
401
		addContent: function(/*String*/ content, /*String||Integer?*/ position){
402
			//	summary:
403
			//		add a node or some HTML as a string to every item in the list.
404
			//		Returns the original list.
405
			//	content:
406
			//		the HTML in string format to add at position to every item
407
			//	position:
408
			//		One of:
409
			//			"last"||"end" (default)
410
			//			"first||"start"
411
			//			"before"
412
			//			"after"
413
			//		or an integer offset in the childNodes property
414
			var ta = d.doc.createElement("span");
415
			if(d.isString(content)){
416
				ta.innerHTML = content;
417
			}else{
418
				ta.appendChild(content);
419
			}
420
			var ct = ((position == "first")||(position == "after")) ? "lastChild" : "firstChild";
421
			this.forEach(function(item){
422
				var tn = ta.cloneNode(true);
423
				while(tn[ct]){
424
					d.place(tn[ct], item, position);
425
				}
426
			});
427
			return this; // dojo.NodeList
428
		}
429
	});
430
 
431
	// syntactic sugar for DOM events
432
	d.forEach([
433
		"blur", "click", "keydown", "keypress", "keyup", "mousedown", "mouseenter",
434
		"mouseleave", "mousemove", "mouseout", "mouseover", "mouseup"
435
		], function(evt){
436
			var _oe = "on"+evt;
437
			dojo.NodeList.prototype[_oe] = function(a, b){
438
				return this.connect(_oe, a, b);
439
			}
440
				// FIXME: should these events trigger publishes?
441
				/*
442
				return (a ? this.connect(_oe, a, b) :
443
							this.forEach(function(n){
444
								// FIXME:
445
								//		listeners get buried by
446
								//		addEventListener and can't be dug back
447
								//		out to be triggered externally.
448
								// see:
449
								//		http://developer.mozilla.org/en/docs/DOM:element
450
 
451
								console.debug(n, evt, _oe);
452
 
453
								// FIXME: need synthetic event support!
454
								var _e = { target: n, faux: true, type: evt };
455
								// dojo._event_listener._synthesizeEvent({}, { target: n, faux: true, type: evt });
456
								try{ n[evt](_e); }catch(e){ console.debug(e); }
457
								try{ n[_oe](_e); }catch(e){ console.debug(e); }
458
							})
459
				);
460
			}
461
			*/
462
		}
463
	);
464
 
465
})();
466
 
467
}