PageSourceSearch

https://charlestonfreight.co.ke/Spry-UI-1.7/includes/SpryDOMUtils.js

js charlestonfreight.co.ke collected 2026-10-06 13:16:53 UTC 29,611 bytes, 1,184 lines download raw bytes

1// SpryDOMUtils.js - version 0.13 - Spry Pre-Release 1.7
2//
3// Copyright (c) 2007. Adobe Systems Incorporated.
4// All rights reserved.
5//
6// Redistribution and use in source and binary forms, with or without
7// modification, are permitted provided that the following conditions are met:
8//
9//   * Redistributions of source code must retain the above copyright notice,
10//     this list of conditions and the following disclaimer.
11//   * Redistributions in binary form must reproduce the above copyright notice,
12//     this list of conditions and the following disclaimer in the documentation
13//     and/or other materials provided with the distribution.
14//   * Neither the name of Adobe Systems Incorporated nor the names of its
15//     contributors may be used to endorse or promote products derived from this
16//     software without specific prior written permission.
17//
18// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28// POSSIBILITY OF SUCH DAMAGE.
29
30(function() { // BeginSpryComponent
31
32if (typeof Spry == "undefined") window.Spry = {}; if (!Spry.Utils) Spry.Utils = {};
33
34//////////////////////////////////////////////////////////////////////
35//
36// Define Prototype's $() convenience function, but make sure it is
37// namespaced under Spry so that we avoid collisions with other
38// toolkits.
39//
40//////////////////////////////////////////////////////////////////////
41
42Spry.$ = function(element)
43{
44	if (arguments.length > 1)
45	{
46		for (var i = 0, elements = [], length = arguments.length; i < length; i++)
47			elements.push(Spry.$(arguments[i]));
48		return elements;
49	}
50	if (typeof element == 'string')
51		element = document.getElementById(element);
52	return element;
53};
54
55//////////////////////////////////////////////////////////////////////
56//
57// DOM Utils
58//
59//////////////////////////////////////////////////////////////////////
60
61Spry.Utils.getAttribute = function(ele, name)
62{
63	ele = Spry.$(ele);
64	if (!ele || !name)
65		return null;
66
67	// We need to wrap getAttribute with a try/catch because IE will throw
68	// an exception if you call it with a namespace prefixed attribute name
69	// that doesn't exist.
70
71	try { var value = ele.getAttribute(name); }
72	catch (e) { value == undefined; }
73
74	// XXX: Workaround for Safari 2.x and earlier:
75	//
76	// If value is undefined, the attribute didn't exist. Check to see if this is
77	// a namespace prefixed attribute name. If it is, remove the ':' from the name
78	// and try again. This allows us to support spry attributes of the form
79	// "spry:region" and "spryregion".
80
81	if (value == undefined && name.search(/:/) != -1)
82	{
83		try { var value = ele.getAttribute(name.replace(/:/, "")); }
84		catch (e) { value == undefined; }
85	}
86
87	return value;
88};
89
90Spry.Utils.setAttribute = function(ele, name, value)
91{
92	ele = Spry.$(ele);
93	if (!ele || !name)
94		return;
95
96	// IE doesn't allow you to set the "class" attribute. You
97	// have to set the className property instead.
98
99	if (name == "class")
100		ele.className = value;
101	else
102	{
103		// I'm probably being a bit paranoid, but given the fact that
104		// getAttribute() throws exceptions when dealing with namespace
105		// prefixed attributes, I'm going to wrap this setAttribute()
106		// call with try/catch just in case ...
107
108		try { ele.setAttribute(name, value); } catch(e) {}
109
110		// XXX: Workaround for Safari 2.x and earlier:
111		//
112		// If this is a namespace prefixed attribute, check to make
113		// sure an attribute was created. This is necessary because some
114		// older versions of Safari (2.x and earlier) drop the namespace
115		// prefixes. If the attribute was munged, try removing the ':'
116		// character from the attribute name and setting the attribute
117		// using the resulting name. The idea here is that even if we
118		// remove the ':' character, Spry.Utils.getAttribute() will still
119		// find the attribute.
120
121		if (name.search(/:/) != -1 && ele.getAttribute(name) == undefined)
122			ele.setAttribute(name.replace(/:/, ""), value);
123	}
124};
125
126Spry.Utils.removeAttribute = function(ele, name)
127{
128	ele = Spry.$(ele);
129	if (!ele || !name)
130		return;
131
132	try { ele.removeAttribute(name); } catch(e) {}
133
134	// XXX: Workaround for Safari 2.x and earlier:
135	//
136	// If this is a namespace prefixed attribute, make sure we
137	// also remove any attributes with the same name, but without
138	// the ':' character.
139
140	if (name.search(/:/) != -1)
141		ele.removeAttribute(name.replace(/:/, ""));
142
143	// XXX: Workaround for IE
144	//
145	// IE doesn't allow you to remove the "class" attribute.
146	// It requires you to remove "className" instead, so go
147	// ahead and try to remove that too.
148
149	if (name == "class")
150		ele.removeAttribute("className");
151};
152
153Spry.Utils.addClassName = function(ele, className)
154{
155	ele = Spry.$(ele);
156	if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
157		return;
158	ele.className += (ele.className ? " " : "") + className;
159};
160
161Spry.Utils.removeClassName = function(ele, className)
162{
163	ele = Spry.$(ele);
164	if (Spry.Utils.hasClassName(ele, className))
165		ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
166};
167
168Spry.Utils.toggleClassName = function(ele, className)
169{
170	if (Spry.Utils.hasClassName(ele, className))
171		Spry.Utils.removeClassName(ele, className);
172	else
173		Spry.Utils.addClassName(ele, className);
174};
175
176Spry.Utils.hasClassName = function(ele, className)
177{
178	ele = Spry.$(ele);
179	if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
180		return false;
181	return true;
182};
183
184Spry.Utils.camelizeString = function(str)
185{
186	var cStr = "";
187	var a = str.split("-");
188	for (var i = 0; i < a.length; i++)
189	{
190		var s = a[i];
191		if (s)
192			cStr = cStr ? (cStr + s.charAt(0).toUpperCase() + s.substring(1)) : s;
193	}
194	return cStr;
195};
196
197Spry.Utils.styleStringToObject = function(styleStr)
198{
199	var o = {};
200	if (styleStr)
201	{
202		var pvA = styleStr.split(";");
203		for (var i = 0; i < pvA.length; i++)
204		{
205			var pv = pvA[i];
206			if (pv && pv.indexOf(":") != -1)
207			{
208				var nvA = pv.split(":");
209				var n = nvA[0].replace(/^\s*|\s*$/g, "");			
210				var v = nvA[1].replace(/^\s*|\s*$/g, "");
211				if (n && v)
212					o[Spry.Utils.camelizeString(n)] = v;
213			}
214		}
215	}
216	return o;
217};
218
219Spry.Utils.addEventListener = function(element, eventType, handler, capture)
220{
221	try
222	{
223		if (!Spry.Utils.eventListenerIsBoundToElement(element, eventType, handler, capture))
224		{
225			element = Spry.$(element);
226			handler = Spry.Utils.bindEventListenerToElement(element, eventType, handler, capture);
227			if (element.addEventListener)
228				element.addEventListener(eventType, handler, capture);
229			else if (element.attachEvent)
230				element.attachEvent("on" + eventType, handler);
231		}
232	}
233	catch (e) {}
234};
235
236Spry.Utils.removeEventListener = function(element, eventType, handler, capture)
237{
238	try
239	{
240			element = Spry.$(element);
241			handler = Spry.Utils.unbindEventListenerFromElement(element, eventType, handler, capture);
242			if (element.removeEventListener)
243				element.removeEventListener(eventType, handler, capture);
244			else if (element.detachEvent)
245				element.detachEvent("on" + eventType, handler);
246	}
247	catch (e) {}
248};
249
250Spry.Utils.eventListenerHash = {};
251Spry.Utils.nextEventListenerID = 1;
252
253Spry.Utils.getHashForElementAndHandler = function(element, eventType, handler, capture)
254{
255	var hash = null;
256	element = Spry.$(element);
257	if (element)
258	{
259		if (typeof element.spryEventListenerID == "undefined")
260			element.spryEventListenerID = "e" + (Spry.Utils.nextEventListenerID++);
261		if (typeof handler.spryEventHandlerID == "undefined")
262			handler.spryEventHandlerID = "h" + (Spry.Utils.nextEventListenerID++);	
263		hash = element.spryEventListenerID + "-" + handler.spryEventHandlerID + "-" + eventType + (capture?"-capture":"");
264	}
265	return hash;
266};
267
268Spry.Utils.eventListenerIsBoundToElement = function(element, eventType, handler, capture)
269{
270	element = Spry.$(element);
271	var hash = Spry.Utils.getHashForElementAndHandler(element, eventType, handler, capture);
272	return Spry.Utils.eventListenerHash[hash] != undefined;
273};
274
275Spry.Utils.bindEventListenerToElement = function(element, eventType, handler, capture)
276{
277	element = Spry.$(element);
278	var hash = Spry.Utils.getHashForElementAndHandler(element, eventType, handler, capture);
279	if (Spry.Utils.eventListenerHash[hash])
280		return Spry.Utils.eventListenerHash[hash];
281	return Spry.Utils.eventListenerHash[hash] = function(e)
282	{
283		e = e || window.event;
284
285		if (!e.preventDefault) e.preventDefault = function() { this.returnValue = false; };
286		if (!e.stopPropagation) e.stopPropagation = function() { this.cancelBubble = true; };
287
288		var result = handler.call(element, e);
289		if (result == false)
290		{
291			e.preventDefault();
292			e.stopPropagation();
293		}
294		return result;
295	};
296};
297
298Spry.Utils.unbindEventListenerFromElement = function(element, eventType, handler, capture)
299{
300	element = Spry.$(element);
301	var hash = Spry.Utils.getHashForElementAndHandler(element, eventType, handler, capture);
302	if (Spry.Utils.eventListenerHash[hash])
303	{
304		handler = Spry.Utils.eventListenerHash[hash];
305		Spry.Utils.eventListenerHash[hash] = undefined;
306	}
307	return handler;
308};
309
310Spry.Utils.cancelEvent = function(e)
311{
312	if (e.preventDefault) e.preventDefault();
313	else e.returnValue = false;
314	if (e.stopPropagation) e.stopPropagation();
315	else e.cancelBubble = true;
316
317	return false;
318};
319
320
321Spry.Utils.addLoadListener = function(handler)
322{
323	if (typeof window.addEventListener != 'undefined')
324		window.addEventListener('load', handler, false);
325	else if (typeof document.addEventListener != 'undefined')
326		document.addEventListener('load', handler, false);
327	else if (typeof window.attachEvent != 'undefined')
328		window.attachEvent('onload', handler);
329};
330
331Spry.Utils.isDescendant = function(parent, child)
332{
333	if (parent && child)
334	{
335		child = child.parentNode;
336		while (child)
337		{
338			if (parent == child)
339				return true;
340			child = child.parentNode;
341		}
342	}
343	return false;
344};
345
346Spry.Utils.getAncestor = function(ele, selector)
347{
348	ele = Spry.$(ele);
349	if (ele)
350	{
351		var s = Spry.$$.tokenizeSequence(selector ? selector : "*")[0];
352		var t = s ? s[0] : null;
353		if (t)
354		{
355			var p = ele.parentNode;
356			while (p)
357			{
358				if (t.match(p))
359					return p;
360				p = p.parentNode;
361			}
362		}
363	}
364	return null;
365};
366
367//////////////////////////////////////////////////////////////////////
368//
369// CSS Selector Matching
370//
371//////////////////////////////////////////////////////////////////////
372
373Spry.$$ = function(selectorSequence, rootNode)
374{
375	var matches = [];
376	Spry.$$.addExtensions(matches);
377
378	// If the first argument to $$() is an object, it
379	// is assumed that all args are either a DOM element
380	// or an array of DOM elements, in which case we
381	// simply append all DOM elements to our special
382	// matches array and return immediately.
383
384	if (typeof arguments[0] == "object")
385	{
386		for (var i = 0; i < arguments.length; i++)
387		{
388			if (arguments[i].constructor == Array)
389				matches.push.apply(matches, arguments[i]);
390			else
391				matches.push(arguments[i]);
392		}
393		return matches;
394	}
395
396	if (!rootNode)
397		rootNode = document;
398	else
399		rootNode = Spry.$(rootNode);
400
401	var sequences = Spry.$$.tokenizeSequence(selectorSequence);
402
403	++Spry.$$.queryID;
404
405	var nid = 0;
406	var ns = sequences.length;
407	for (var i = 0; i < ns; i++)
408	{
409		var m = Spry.$$.processTokens(sequences[i], rootNode);
410		var nm = m.length;
411		for (var j = 0; j < nm; j++)
412		{
413			var n = m[j];
414			if (!n.spry$$ID)
415			{
416				n.spry$$ID = ++nid;
417				matches.push(n);
418			}
419		}
420	}
421
422	var nm = matches.length;
423	for (i = 0; i < nm; i++)
424		matches[i].spry$$ID = undefined;
425
426	return matches;
427};
428
429Spry.$$.cache = {};
430Spry.$$.queryID = 0;
431
432Spry.$$.Token = function()
433{
434	this.type = Spry.$$.Token.SELECTOR;
435	this.name = "*";
436	this.id = "";
437	this.classes = [];
438	this.attrs = [];
439
440	this.pseudos = [];
441};
442
443Spry.$$.Token.Attr = function(n, v)
444{
445	this.name = n;
446	this.value = v ? new RegExp(v) : undefined;
447};
448
449Spry.$$.Token.PseudoClass = function(pstr)
450{
451	this.name = pstr.replace(/\(.*/, "");
452	this.arg = pstr.replace(/^[^\(\)]*\(?\s*|\)\s*$/g, "");
453	this.func = Spry.$$.pseudoFuncs[this.name];
454};
455
456Spry.$$.Token.SELECTOR = 0;
457Spry.$$.Token.COMBINATOR = 1;
458
459Spry.$$.Token.prototype.match = function(ele, nameAlreadyMatches)
460{
461	if (this.type == Spry.$$.Token.COMBINATOR)
462		return false;
463	if (!nameAlreadyMatches && this.name != '*' && this.name != ele.nodeName.toLowerCase())
464		return false;
465	if (this.id && this.id != ele.id)
466		return false;
467	var classes = this.classes;
468	var len = classes.length;
469	for (var i = 0; i < len; i++)
470	{
471		if (!ele.className || !classes[i].value.test(ele.className))
472			return false;
473	}
474
475	var attrs = this.attrs;
476	len = attrs.length;
477	for (var i = 0; i < len; i++)
478	{
479		var a = attrs[i];
480		var an = ele.attributes.getNamedItem(a.name);
481		if (!an || (!a.value && an.nodeValue == undefined) || (a.value && !a.value.test(an.nodeValue)))
482			return false;
483	}
484
485	var ps = this.pseudos;
486	var len = ps.length;
487	for (var i = 0; i < len; i++)
488	{
489		var p = ps[i];
490		if (p && p.func && !p.func(p.arg, ele, this))
491			return false;
492	}
493
494	return true;
495};
496
497Spry.$$.Token.prototype.getNodeNameIfTypeMatches = function(ele)
498{
499	var nodeName = ele.nodeName.toLowerCase();
500	if (this.name != '*')
501	{
502		if (this.name != nodeName)
503			return null;
504		return this.name;
505	}
506	return nodeName;
507};
508
509Spry.$$.escapeRegExpCharsRE = /\/|\.|\*|\+|\(|\)|\[|\]|\{|\}|\\|\|/g;
510
511Spry.$$.tokenizeSequence = function(s)
512{
513	var cc = Spry.$$.cache[s];
514	if (cc) return cc;
515
516	// Attribute Selector: /(\[[^\"'~\^\$\*\|\]=]+([~\^\$\*\|]?=\s*('[^']*'|"[^"]*"|[^"'\]]+))?\s*\])/g
517	// Simple Selector:    /((:[^\.#:\s,>~\+\[\]]+\(([^\(\)]+|\([^\(\)]*\))*\))|[\.#:]?[^\.#:\s,>~\+\[\]]+)/g
518	// Combinator:         /(\s*[\s,>~\+]\s*)/g
519
520	var tokenExpr = /(\[[^\"'~\^\$\*\|\]=]+([~\^\$\*\|]?=\s*('[^']*'|"[^"]*"|[^"'\]]+))?\s*\])|((:[^\.#:\s,>~\+\[\]]+\(([^\(\)]+|\([^\(\)]*\))*\))|[\.#:]?[^\.#:\s,>~\+\[\]]+)|(\s*[\s,>~\+]\s*)/g;
521
522	var tkn = new Spry.$$.Token;
523	var sequence = [];
524	sequence.push(tkn);
525	var tokenSequences = [];
526	tokenSequences.push(sequence);
527
528	s = s.replace(/^\s*|\s*$/, "");
529
530	var expMatch = tokenExpr.exec(s);
531	while (expMatch)
532	{
533		var tstr = expMatch[0];
534		var c = tstr.charAt(0);
535		switch (c)
536		{
537			case '.':
538				tkn.classes.push(new Spry.$$.Token.Attr("class", "\\b" + tstr.substr(1) + "\\b"));
539				break;
540			case '#':
541				tkn.id = tstr.substr(1);
542				break;
543			case ':':
544				tkn.pseudos.push(new Spry.$$.Token.PseudoClass(tstr));
545				break;
546			case '[':
547				var attrComps = tstr.match(/\[([^\"'~\^\$\*\|\]=]+)(([~\^\$\*\|]?=)\s*('[^']*'|"[^"]*"|[^"'\]]+))?\s*\]/);
548				var name = attrComps[1];				
549				var matchType = attrComps[3];
550				var val = attrComps[4];
551				if (val)
552				{
553					val = val.replace(/^['"]|['"]$/g, "");
554					val = val.replace(Spry.$$.escapeRegExpCharsRE, '\\$&');
555				}
556
557				var matchStr = undefined;
558
559				switch(matchType)
560				{
561					case "=":
562						matchStr = "^" + val + "$";
563						break;
564					case "^=":
565						matchStr = "^" + val;
566						break;
567					case "$=":
568						matchStr = val + "$";
569						break;
570					case "~=":
571					case "|=":
572						matchStr = "\\b" + val + "\\b";
573						break;
574					case "*=":
575						matchStr = val;
576						break;
577				}
578
579				tkn.attrs.push(new Spry.$$.Token.Attr(name, matchStr));
580				break;
581			default:
582				var combiMatch = tstr.match(/^\s*([\s,~>\+])\s*$/);
583				if (combiMatch)
584				{
585					if (combiMatch[1] == ',')
586					{
587						sequence = new Array;
588						tokenSequences.push(sequence);
589						tkn = new Spry.$$.Token;
590						sequence.push(tkn);
591					}
592					else
593					{
594						tkn = new Spry.$$.Token;
595						tkn.type = Spry.$$.Token.COMBINATOR;
596						tkn.name = combiMatch[1];
597						sequence.push(tkn);
598						tkn = new Spry.$$.Token();
599						sequence.push(tkn);
600					}
601				}
602				else
603					tkn.name = tstr.toLowerCase();
604				break;
605		}
606		expMatch = tokenExpr.exec(s);
607	}
608
609	Spry.$$.cache[s] = tokenSequences;
610
611	return tokenSequences;
612};
613
614Spry.$$.combinatorFuncs = {
615	// Element Descendant
616
617	" ": function(nodes, token)
618	{
619		var uid = ++Spry.$$.uniqueID;
620		var results = [];
621		var nn = nodes.length;
622		for (var i = 0; i < nn; i++)
623		{
624			var n = nodes[i];
625			if (uid != n.spry$$uid)
626			{
627				// n.spry$$uid = uid;
628				var ea = nodes[i].getElementsByTagName(token.name);
629				var ne = ea.length;
630				for (var j = 0; j < ne; j++)
631				{
632					var e = ea[j];
633
634					// If the token matches, add it to our results. We have
635					// to make sure e is an element because IE6 returns the DOCTYPE
636					// tag as a comment when '*' is used in the call to getElementsByTagName().
637
638					if (e.nodeType == 1 /* Node.ELEMENT_NODE */ && token.match(e, true))
639						results.push(e);
640					e.spry$$uid = uid;
641				}
642			}
643		}
644		return results;
645	},
646
647	// Element Child
648
649	">": function(nodes, token)
650	{
651		var results = [];
652		var nn = nodes.length;
653		for (var i = 0; i < nn; i++)
654		{
655			var n = nodes[i].firstChild;
656			while (n)
657			{
658				if (n.nodeType == 1 /* Node.ELEMENT_NODE */ && token.match(n))
659					results.push(n);
660				n = n.nextSibling;
661			}
662		}
663		return results;
664	},
665
666	// Element Immediately Preceded By
667
668	"+": function(nodes, token)
669	{
670		var results = [];
671		var nn = nodes.length;
672		for (var i = 0; i < nn; i++)
673		{
674			var n = nodes[i].nextSibling;
675			while (n && n.nodeType != 1 /* Node.ELEMENT_NODE */)
676				n = n.nextSibling;
677			if (n && token.match(n))
678				results.push(n);
679		}
680		return results;
681	},
682
683	// Element Preceded By
684
685	"~": function(nodes, token)
686	{
687		var uid = ++Spry.$$.uniqueID;
688		var results = [];
689		var nn = nodes.length;
690		for (var i = 0; i < nn; i++)
691		{
692			var n = nodes[i].nextSibling;
693			while (n)
694			{
695				if (n.nodeType == 1 /* Node.ELEMENT_NODE */)
696				{
697					if (uid == n.spry$$uid)
698						break;
699
700					if (token.match(n))
701					{
702						results.push(n);
703						n.spry$$uid = uid;
704					}
705				}
706				n = n.nextSibling;
707			}
708		}
709		return results;
710	}
711};
712
713Spry.$$.uniqueID = 0;
714
715Spry.$$.pseudoFuncs = {
716	":first-child": function(arg, node, token)
717	{
718		var n = node.previousSibling;
719		while (n)
720		{
721			if (n.nodeType == 1) return false; // Node.ELEMENT_NODE
722			n = n.previousSibling;
723		}
724
725		return true;
726	},
727
728	":last-child": function(arg, node, token)
729	{
730		var n = node.nextSibling;
731		while (n)
732		{
733			if (n.nodeType == 1) // Node.ELEMENT_NODE
734				return false;
735			n = n.nextSibling;
736		}
737		return true;
738	},
739
740	":empty": function(arg, node, token)
741	{
742		var n = node.firstChild;
743		while (n)
744		{
745			switch(n.nodeType)
746			{
747				case 1: // Node.ELEMENT_NODE
748				case 3: // Node.TEXT_NODE
749				case 4: // Node.CDATA_NODE
750				case 5: // Node.ENTITY_REFERENCE_NODE
751					return false;
752			}
753			n = n.nextSibling;
754		}
755		return true;
756	},
757
758	":nth-child": function(arg, node, token)
759	{
760		return Spry.$$.nthChild(arg, node, token);
761	},
762
763	":nth-last-child": function(arg, node, token)
764	{
765		return Spry.$$.nthChild(arg, node, token, true);
766	},
767
768	":nth-of-type": function(arg, node, token)
769	{
770		return Spry.$$.nthChild(arg, node, token, false, true);
771	},
772	
773	":nth-last-of-type": function(arg, node, token)
774	{
775		return Spry.$$.nthChild(arg, node, token, true, true);
776	},
777	
778	":first-of-type": function(arg, node, token)
779	{
780		var nodeName = token.getNodeNameIfTypeMatches(node);
781		if (!nodeName) return false;
782
783		var n = node.previousSibling;
784		while (n)
785		{
786			if (n.nodeType == 1 && nodeName == n.nodeName.toLowerCase()) return false; // Node.ELEMENT_NODE
787			n = n.previousSibling;
788		}
789
790		return true;
791	},
792
793	":last-of-type": function(arg, node, token)
794	{
795		var nodeName = token.getNodeNameIfTypeMatches(node);
796		if (!nodeName) return false;
797
798		var n = node.nextSibling;
799		while (n)
800		{
801			if (n.nodeType == 1 && nodeName == n.nodeName.toLowerCase()) // Node.ELEMENT_NODE
802				return false;
803			n = n.nextSibling;
804		}
805		return true;
806	},
807
808	":only-child": function(arg, node, token)
809	{
810		var f = Spry.$$.pseudoFuncs;
811		return f[":first-child"](arg, node, token) && f[":last-child"](arg, node, token);
812	},
813
814	":only-of-type": function(arg, node, token)
815	{
816		var f = Spry.$$.pseudoFuncs;
817		return f[":first-of-type"](arg, node, token) && f[":last-of-type"](arg, node, token);
818	},
819
820	":not": function(arg, node, token)
821	{
822		var s = Spry.$$.tokenizeSequence(arg)[0];
823		var t = s ? s[0] : null;
824		return !t || !t.match(node);
825	},
826
827	":enabled": function(arg, node, token)
828	{
829		return !node.disabled;
830	},
831
832	":disabled": function(arg, node, token)
833	{
834		return node.disabled;
835	},
836
837	":checked": function(arg, node, token)
838	{
839		return node.checked;
840	},
841
842	":root": function(arg, node, token)
843	{
844		return node.parentNode && node.ownerDocument && node.parentNode == node.ownerDocument;
845	}
846};
847
848Spry.$$.nthRegExp = /((-|[0-9]+)?n)?([+-]?[0-9]*)/;
849
850Spry.$$.nthCache = {
851	  "even": { a: 2, b: 0, mode: 1, invalid: false }
852	, "odd":  { a: 2, b: 1, mode: 1, invalid: false }
853	, "2n":   { a: 2, b: 0, mode: 1, invalid: false }
854	, "2n+1": { a: 2, b: 1, mode: 1, invalid: false }
855};
856
857Spry.$$.parseNthChildString = function(str)
858{
859	var o = Spry.$$.nthCache[str];
860	if (!o)
861	{
862		var m = str.match(Spry.$$.nthRegExp);
863		var n = m[1];
864		var a = m[2];
865		var b = m[3];
866
867		if (!a)
868		{
869			// An 'a' value was not specified. Was there an 'n' present?
870			// If so, we treat it as an increment of 1, otherwise we're
871			// in no-repeat mode.
872
873			a = n ? 1 : 0;
874		}
875		else if (a == "-")
876		{
877			// The string is using the "-n" short-hand which is
878			// short for -1.
879
880			a = -1;
881		}
882		else
883		{
884			// An integer repeat value for 'a' was specified. Convert
885			// it into number.
886
887			a = parseInt(a, 10);
888		}
889
890		// If a 'b' value was specified, turn it into a number.
891		// If no 'b' value was specified, default to zero.
892
893		b = b ? parseInt(b, 10) : 0;
894
895		// Figure out the mode:
896		//
897		// -1 - repeat backwards
898		//  0 - no repeat
899		//  1 - repeat forwards
900
901		var mode = (a == 0) ? 0 : ((a > 0) ? 1 : -1);
902		var invalid = false;
903
904		// Fix up 'a' and 'b' for proper repeating.
905
906		if (a > 0 && b < 0)
907		{
908			b = b % a;
909			b = ((b=(b%a)) < 0) ? a + b : b;
910		}
911		else if (a < 0)
912		{
913			if (b < 0)
914				invalid = true;
915			else
916				a = Math.abs(a);
917		}
918
919		o = new Object;
920		o.a = a;
921		o.b = b;
922		o.mode = mode;
923		o.invalid = invalid;
924
925		Spry.$$.nthCache[str] = o;
926	}
927
928	return o;
929};
930
931Spry.$$.nthChild = function(arg, node, token, fromLastSib, matchNodeName)
932{
933	if (matchNodeName)
934	{
935		var nodeName = token.getNodeNameIfTypeMatches(node);
936		if (!nodeName) return false;
937	}
938
939	var o = Spry.$$.parseNthChildString(arg);
940
941	if (o.invalid)
942		return false;
943
944	var qidProp = "spry$$ncQueryID";
945	var posProp = "spry$$ncPos";
946	var countProp = "spry$$ncCount";
947	if (matchNodeName)
948	{
949		qidProp += nodeName;
950		posProp += nodeName;
951		countProp += nodeName;
952	}
953
954	var parent = node.parentNode;
955	if (parent[qidProp] != Spry.$$.queryID)
956	{
957		var pos = 0;
958		parent[qidProp] = Spry.$$.queryID;
959		var c = parent.firstChild;
960		while (c)
961		{
962			if (c.nodeType == 1 && (!matchNodeName || nodeName == c.nodeName.toLowerCase()))
963				c[posProp] = ++pos;
964			c = c.nextSibling;
965		}
966		parent[countProp] = pos;
967	}
968
969	pos = node[posProp];
970	if (fromLastSib)
971		pos = parent[countProp] - pos + 1;
972
973/*
974	var sib = fromLastSib ? "nextSibling" : "previousSibling";
975
976	var pos = 1;
977	var n = node[sib];
978	while (n)
979	{
980		if (n.nodeType == 1 && (!matchNodeName || nodeName == n.nodeName.toLowerCase()))
981		{
982			if (n == node) break;
983			++pos;
984		}
985		n = n[sib];
986	}
987*/
988
989	if (o.mode == 0) // Exact match
990		return pos == o.b;
991	if (o.mode > 0) // Forward Repeat
992		return (pos < o.b) ? false : (!((pos - o.b) % o.a));
993	return (pos > o.b) ? false : (!((o.b - pos) % o.a)); // Backward Repeat
994};
995
996Spry.$$.processTokens = function(tokens, root)
997{
998	var numTokens = tokens.length;
999	var nodeSet = [ root ];
1000	var combiFunc = null;
1001
1002	for (var i = 0; i < numTokens && nodeSet.length > 0; i++)
1003	{
1004		var t = tokens[i];
1005		if (t.type == Spry.$$.Token.SELECTOR)
1006		{
1007			if (combiFunc)
1008			{
1009				nodeSet = combiFunc(nodeSet, t);
1010				combiFunc = null;
1011			}
1012			else
1013				nodeSet = Spry.$$.getMatchingElements(nodeSet, t);
1014		}
1015		else // Spry.$$.Token.COMBINATOR
1016			combiFunc = Spry.$$.combinatorFuncs[t.name];
1017	}
1018	return nodeSet;
1019};
1020
1021Spry.$$.getMatchingElements = function(nodes, token)
1022{
1023	var results = [];
1024	if (token.id)
1025	{
1026		n = nodes[0];
1027		if (n && n.ownerDocument)
1028		{
1029			var e = n.ownerDocument.getElementById(token.id);
1030			if (e)
1031			{
1032				// XXX: We need to make sure that the element
1033				//      we found is actually underneath the root
1034				//      we were given!
1035
1036				if (token.match(e))
1037					results.push(e);
1038			}
1039			return results;
1040		}
1041	}
1042
1043	var nn = nodes.length;
1044	for (var i = 0; i < nn; i++)
1045	{
1046		var n = nodes[i];
1047		// if (token.match(n)) results.push(n);
1048		
1049		var ea = n.getElementsByTagName(token.name);
1050		var ne = ea.length;
1051		for (var j = 0; j < ne; j++)
1052		{
1053			var e = ea[j];
1054
1055			// If the token matches, add it to our results. We have
1056			// to make sure e is an element because IE6 returns the DOCTYPE
1057			// tag as a comment when '*' is used in the call to getElementsByTagName().
1058
1059			if (e.nodeType == 1 /* Node.ELEMENT_NODE */ && token.match(e, true))
1060				results.push(e);
1061		}
1062	}
1063	return results;
1064};
1065
1066/*
1067Spry.$$.dumpSequences = function(sequences)
1068{
1069	Spry.Debug.trace("<hr />Number of Sequences: " + sequences.length);
1070	for (var i = 0; i < sequences.length; i++)
1071	{
1072		var str = "";
1073		var s = sequences[i];
1074		Spry.Debug.trace("<hr />Sequence " + i + " -- Tokens: " + s.length);
1075		for (var j = 0; j < s.length; j++)
1076		{
1077			var t = s[j];
1078			if (t.type == Spry.$$.Token.SELECTOR)
1079			{
1080				str += "  SELECTOR:\n    Name: " + t.name + "\n    ID: " + t.id + "\n    Attrs:\n";
1081				for (var k = 0; k < t.classes.length; k++)
1082					str += "      " + t.classes[k].name + ": " + t.classes[k].value + "\n";
1083				for (var k = 0; k < t.attrs.length; k++)
1084					str += "      " + t.attrs[k].name + ": " + t.attrs[k].value + "\n";
1085				str += "    Pseudos:\n";
1086				for (var k = 0; k < t.pseudos.length; k++)
1087					str += "      " + t.pseudos[k].name + (t.pseudos[k].arg ? "(" + t.pseudos[k].arg + ")" : "") + "\n";
1088			}
1089			else
1090			{
1091				str += "  COMBINATOR:\n    Name: '" + t.name + "'\n"; 
1092			}
1093		}
1094		Spry.Debug.trace("<pre>" + Spry.Utils.encodeEntities(str) + "</pre>");
1095	}
1096};
1097*/
1098
1099Spry.$$.addExtensions = function(a)
1100{
1101	for (var f in Spry.$$.Results)
1102		a[f] = Spry.$$.Results[f];
1103};
1104
1105Spry.$$.Results = {};
1106
1107Spry.$$.Results.forEach = function(func)
1108{
1109	var n = this.length;
1110	for (var i = 0; i < n; i++)
1111		func(this[i]);
1112	return this;
1113};
1114
1115Spry.$$.Results.setAttribute = function(name, value)
1116{
1117	return this.forEach(function(n) { Spry.Utils.setAttribute(n, name, value); });
1118};
1119
1120Spry.$$.Results.removeAttribute = function(name)
1121{
1122	return this.forEach(function(n) { Spry.Utils.removeAttribute(n, name); });
1123};
1124
1125Spry.$$.Results.addClassName = function(className)
1126{
1127	return this.forEach(function(n) { Spry.Utils.addClassName(n, className); });
1128};
1129
1130Spry.$$.Results.removeClassName = function(className)
1131{
1132	return this.forEach(function(n) { Spry.Utils.removeClassName(n, className); });
1133};
1134
1135Spry.$$.Results.toggleClassName = function(className)
1136{
1137	return this.forEach(function(n) { Spry.Utils.toggleClassName(n, className); });
1138};
1139
1140Spry.$$.Results.addEventListener = function(eventType, handler, capture, bindHandler)
1141{
1142	return this.forEach(function(n) { Spry.Utils.addEventListener(n, eventType, handler, capture, bindHandler); });
1143};
1144
1145Spry.$$.Results.removeEventListener = function(eventType, handler, capture)
1146{
1147	return this.forEach(function(n) { Spry.Utils.removeEventListener(n, eventType, handler, capture); });
1148};
1149
1150Spry.$$.Results.setStyle = function(style)
1151{
1152	if (style)
1153	{
1154		style = Spry.Utils.styleStringToObject(style);
1155		this.forEach(function(n)
1156		{
1157			for (var p in style)
1158				try { n.style[p] = style[p]; } catch (e) {}
1159		});
1160	}
1161	return this;
1162};
1163
1164Spry.$$.Results.setProperty = function(prop, value)
1165{
1166	if (prop)
1167	{
1168		if (typeof prop == "string")
1169		{
1170			var p = {};
1171			p[prop] = value;
1172			prop = p;
1173		}
1174
1175		this.forEach(function(n)
1176		{
1177			for (var p in prop)
1178				try { n[p] = prop[p]; } catch (e) {}
1179		});
1180	}
1181	return this;
1182};
1183
1184})(); // EndSpryComponent

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.