// SpryDOMUtils.js - version 0.6 - Spry Pre-Release 1.6.1
//
// Copyright (c) 2007. Adobe Systems Incorporated.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of Adobe Systems Incorporated nor the names of its
//     contributors may be used to endorse or promote products derived from this
//     software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
var Spry; if (!Spry) Spry = {}; if (!Spry.Utils) Spry.Utils = {};
//////////////////////////////////////////////////////////////////////
//
// Define Prototype's $() convenience function, but make sure it is
// namespaced under Spry so that we avoid collisions with other
// toolkits.
//
//////////////////////////////////////////////////////////////////////
Spry.$ = function(element)
{
if (arguments.length > 1)
{
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
elements.push(Spry.$(arguments[i]));
return elements;
}
if (typeof element == 'string')
element = document.getElementById(element);
return element;
};
//////////////////////////////////////////////////////////////////////
//
// DOM Utils
//
//////////////////////////////////////////////////////////////////////
Spry.Utils.setAttribute = function(ele, name, value)
{
ele = Spry.$(ele);
if (!ele || !name)
return;
// IE doesn't allow you to set the "class" attribute. You
// have to set the className property instead.
if (name == "class")
ele.className = value;
else
ele.setAttribute(name, value);
};
Spry.Utils.removeAttribute = function(ele, name)
{
ele = Spry.$(ele);
if (!ele || !name)
return;
try
{
ele.removeAttribute(name);
// IE doesn't allow you to remove the "class" attribute.
// It requires you to remove "className" instead, so go
// ahead and try to remove that too.
//
// XXX: We should add a check for IE here instead of doing
// it for every browser.
if (name == "class")
ele.removeAttribute("className");
} catch(e) {}
};
Spry.Utils.addClassName = function(ele, className)
{
ele = Spry.$(ele);
if (!ele || !className || (ele.className && ele.className.search(new RegExp("\\b" + className + "\\b")) != -1))
return;
ele.className += (ele.className ? " " : "") + className;
};
Spry.Utils.removeClassName = function(ele, className)
{
ele = Spry.$(ele);
if (Spry.Utils.hasClassName(ele, className))
ele.className = ele.className.replace(new RegExp("\\s*\\b" + className + "\\b", "g"), "");
};
Spry.Utils.toggleClassName = function(ele, className)
{
if (Spry.Utils.hasClassName(ele, className))
Spry.Utils.removeClassName(ele, className);
else
Spry.Utils.addClassName(ele, className);
};
Spry.Utils.hasClassName = function(ele, className)
{
ele = Spry.$(ele);
if (!ele || !className || !ele.className || ele.className.search(new RegExp("\\b" + className + "\\b")) == -1)
return false;
return true;
};
Spry.Utils.camelizeString = function(str)
{
var cStr = "";
var a = str.split("-");
for (var i = 0; i < a.length; i++)
{
var s = a[i];
if (s)
cStr = cStr ? (cStr + s.charAt(0).toUpperCase() + s.substring(1)) : s;
}
return cStr;
};
Spry.Utils.styleStringToObject = function(styleStr)
{
var o = {};
if (styleStr)
{
pvA = styleStr.split(";");
for (var i = 0; i < pvA.length; i++)
{
var pv = pvA[i];
if (pv && pv.indexOf(":") != -1)
{
var nvA = pv.split(":");
var n = nvA[0].replace(/^\s*|\s*$/g, "");
var v = nvA[1].replace(/^\s*|\s*$/g, "");
if (n && v)
o[Spry.Utils.camelizeString(n)] = v;
}
}
}
return o;
};
Spry.Utils.addEventListener = function(element, eventType, handler, capture)
{
try
{
if (!Spry.Utils.eventListenerIsBoundToElement(element, eventType, handler, capture))
{
element = Spry.$(element);
handler = Spry.Utils.bindEventListenerToElement(element, eventType, handler, capture);
if (element.addEventListener)
element.addEventListener(eventType, handler, capture);
else if (element.attachEvent)
element.attachEvent("on" + eventType, handler);
}
}
catch (e) {}
};
Spry.Utils.removeEventListener = function(element, eventType, handler, capture)
{
try
{
element = Spry.$(element);
handler = Spry.Utils.unbindEventListenerFromElement(element, eventType, handler, capture);
if (element.removeEventListener)
element.removeEventListener(eventType, handler, capture);
else if (element.detachEvent)
element.detachEvent("on" + eventType, handler);
}
catch (e) {}
};
Spry.Utils.eventListenerHash = {};
Spry.Utils.nextEventListenerID = 1;
Spry.Utils.getHashForElementAndHandler = function(element, eventType, handler, capture)
{
var hash = null;
element = Spry.$(element);
if (element)
{
if (typeof element.spryEventListenerID == "undefined")
element.spryEventListenerID = "e" + (Spry.Utils.nextEventListenerID++);
if (typeof handler.spryEventHandlerID == "undefined")
handler.spryEventHandlerID = "h" + (Spry.Utils.nextEventListenerID++);
hash = element.spryEventListenerID + "-" + handler.spryEventHandlerID + "-" + eventType + (capture?"-capture":"");
}
return hash;
};
Spry.Utils.eventListenerIsBoundToElement = function(element, eventType, handler, capture)
{
element = Spry.$(element);
var hash = Spry.Utils.getHashForElementAndHandler(element, eventType, handler, capture);
return Spry.Utils.eventListenerHash[hash] != undefined;
};
Spry.Utils.bindEventListenerToElement = function(element, eventType, handler, capture)
{
element = Spry.$(element);
var hash = Spry.Utils.getHashForElementAndHandler(element, eventType, handler, capture);
if (Spry.Utils.eventListenerHash[hash])
return Spry.Utils.eventListenerHash[hash];
return Spry.Utils.eventListenerHash[hash] = function(e)
{
e = e || window.event;
if (!e.preventDefault) e.preventDefault = function() { this.returnValue = false; };
if (!e.stopPropagation) e.stopPropagation = function() { this.cancelBubble = true; };
var result = handler.call(element, e);
if (result == false)
{
e.preventDefault();
e.stopPropagation();
}
return result;
};
};
Spry.Utils.unbindEventListenerFromElement = function(element, eventType, handler, capture)
{
element = Spry.$(element);
var hash = Spry.Utils.getHashForElementAndHandler(element, eventType, handler, capture);
if (Spry.Utils.eventListenerHash[hash])
{
handler = Spry.Utils.eventListenerHash[hash];
Spry.Utils.eventListenerHash[hash] = undefined;
}
return handler;
};
Spry.Utils.addLoadListener = function(handler)
{
if (typeof window.addEventListener != 'undefined')
window.addEventListener('load', handler, false);
else if (typeof document.addEventListener != 'undefined')
document.addEventListener('load', handler, false);
else if (typeof window.attachEvent != 'undefined')
window.attachEvent('onload', handler);
};
Spry.Utils.getAncestor = function(ele, selector)
{
ele = Spry.$(ele);
if (ele)
{
var s = Spry.$$.tokenizeSequence(selector ? selector : "*")[0];
var t = s ? s[0] : null;
if (t)
{
var p = ele.parentNode;
while (p)
{
if (t.match(p))
return p;
p = p.parentNode;
}
}
}
return null;
};
//////////////////////////////////////////////////////////////////////
//
// CSS Selector Matching
//
//////////////////////////////////////////////////////////////////////
Spry.$$ = function(selectorSequence, rootNode)
{
if (!rootNode)
rootNode = document;
else
rootNode = Spry.$(rootNode);
var sequences = Spry.$$.tokenizeSequence(selectorSequence);
var matches = [];
Spry.$$.addExtensions(matches);
++Spry.$$.queryID;
var nid = 0;
var ns = sequences.length;
for (var i = 0; i < ns; i++)
{
var m = Spry.$$.processTokens(sequences[i], rootNode);
var nm = m.length;
for (var j = 0; j < nm; j++)
{
var n = m[j];
if (!n.spry$$ID)
{
n.spry$$ID = ++nid;
matches.push(n);
}
}
}
var nm = matches.length;
for (i = 0; i < nm; i++)
matches[i].spry$$ID = undefined;
return matches;
};
Spry.$$.cache = {};
Spry.$$.queryID = 0;
Spry.$$.Token = function()
{
this.type = Spry.$$.Token.SELECTOR;
this.name = "*";
this.id = "";
this.classes = [];
this.attrs = [];
this.pseudos = [];
};
Spry.$$.Token.Attr = function(n, v)
{
this.name = n;
this.value = v ? new RegExp(v) : undefined;
};
Spry.$$.Token.PseudoClass = function(pstr)
{
this.name = pstr.replace(/\(.*/, "");
this.arg = pstr.replace(/^[^\(\)]*\(?\s*|\)\s*$/g, "");
this.func = Spry.$$.pseudoFuncs[this.name];
};
Spry.$$.Token.SELECTOR = 0;
Spry.$$.Token.COMBINATOR = 1;
Spry.$$.Token.prototype.match = function(ele, nameAlreadyMatches)
{
if (this.type == Spry.$$.Token.COMBINATOR)
return false;
if (!nameAlreadyMatches && this.name != '*' && this.name != ele.nodeName.toLowerCase())
return false;
if (this.id && this.id != ele.id)
return false;
var classes = this.classes;
var len = classes.length;
for (var i = 0; i < len; i++)
{
if (!ele.className || !classes[i].value.test(ele.className))
return false;
}
var attrs = this.attrs;
len = attrs.length;
for (var i = 0; i < len; i++)
{
var a = attrs[i];
var an = ele.attributes.getNamedItem(a.name);
if (!an || (!a.value && an.nodeValue == undefined) || (a.value && !a.value.test(an.nodeValue)))
return false;
}
var ps = this.pseudos;
var len = ps.length;
for (var i = 0; i < len; i++)
{
var p = ps[i];
if (p && p.func && !p.func(p.arg, ele, this))
return false;
}
return true;
};
Spry.$$.Token.prototype.getNodeNameIfTypeMatches = function(ele)
{
var nodeName = ele.nodeName.toLowerCase();
if (this.name != '*')
{
if (this.name != nodeName)
return null;
return this.name;
}
return nodeName;
};
Spry.$$.escapeRegExpCharsRE = /\/|\.|\*|\+|\(|\)|\[|\]|\{|\}|\\|\|/g;
Spry.$$.tokenizeSequence = function(s)
{
var cc = Spry.$$.cache[s];
if (cc) return cc;
// Attribute Selector: /(\[[^\"'~\^\$\*\|\]=]+([~\^\$\*\|]?=\s*('[^']*'|"[^"]*"|[^"'\]]+))?\s*\])/g
// Simple Selector:    /((:[^\.#:\s,>~\+\[\]]+\(([^\(\)]+|\([^\(\)]*\))*\))|[\.#:]?[^\.#:\s,>~\+\[\]]+)/g
// Combinator:         /(\s*[\s,>~\+]\s*)/g
var tokenExpr = /(\[[^\"'~\^\$\*\|\]=]+([~\^\$\*\|]?=\s*('[^']*'|"[^"]*"|[^"'\]]+))?\s*\])|((:[^\.#:\s,>~\+\[\]]+\(([^\(\)]+|\([^\(\)]*\))*\))|[\.#:]?[^\.#:\s,>~\+\[\]]+)|(\s*[\s,>~\+]\s*)/g;
var tkn = new Spry.$$.Token;
var sequence = [];
sequence.push(tkn);
var tokenSequences = [];
tokenSequences.push(sequence);
s = s.replace(/^\s*|\s*$/, "");
var expMatch = tokenExpr.exec(s);
while (expMatch)
{
var tstr = expMatch[0];
var c = tstr.charAt(0);
switch (c)
{
case '.':
tkn.classes.push(new Spry.$$.Token.Attr("class", "\\b" + tstr.substr(1) + "\\b"));
break;
case '#':
tkn.id = tstr.substr(1);
break;
case ':':
tkn.pseudos.push(new Spry.$$.Token.PseudoClass(tstr));
break;
case '[':
var attrComps = tstr.match(/\[([^\"'~\^\$\*\|\]=]+)(([~\^\$\*\|]?=)\s*('[^']*'|"[^"]*"|[^"'\]]+))?\s*\]/);
var name = attrComps[1];
var matchType = attrComps[3];
var val = attrComps[4];
if (val)
{
val = val.replace(/^['"]|['"]$/g, "");
val = val.replace(Spry.$$.escapeRegExpCharsRE, '\\$&');
}
var matchStr = undefined;
switch(matchType)
{
case "=":
matchStr = "^" + val + "$";
break;
case "^=":
matchStr = "^" + val;
break;
case "$=":
matchStr = val + "$";
break;
case "~=":
case "|=":
matchStr = "\\b" + val + "\\b";
break;
case "*=":
matchStr = val;
break;
}
tkn.attrs.push(new Spry.$$.Token.Attr(name, matchStr));
break;
default:
var combiMatch = tstr.match(/^\s*([\s,~>\+])\s*$/);
if (combiMatch)
{
if (combiMatch[1] == ',')
{
sequence = new Array;
tokenSequences.push(sequence);
tkn = new Spry.$$.Token;
sequence.push(tkn);
}
else
{
tkn = new Spry.$$.Token;
tkn.type = Spry.$$.Token.COMBINATOR;
tkn.name = combiMatch[1];
sequence.push(tkn);
tkn = new Spry.$$.Token();
sequence.push(tkn);
}
}
else
tkn.name = tstr.toLowerCase();
break;
}
expMatch = tokenExpr.exec(s);
}
Spry.$$.cache[s] = tokenSequences;
return tokenSequences;
};
Spry.$$.combinatorFuncs = {
// Element Descendant
" ": function(nodes, token)
{
var uid = ++Spry.$$.uniqueID;
var results = [];
var nn = nodes.length;
for (var i = 0; i < nn; i++)
{
var n = nodes[i];
if (uid != n.spry$$uid)
{
// n.spry$$uid = uid;
var ea = nodes[i].getElementsByTagName(token.name);
var ne = ea.length;
for (var j = 0; j < ne; j++)
{
var e = ea[j];
if (token.match(e, true))
results.push(e);
e.spry$$uid = uid;
}
}
}
return results;
},
// Element Child
">": function(nodes, token)
{
var results = [];
var nn = nodes.length;
for (var i = 0; i < nn; i++)
{
var n = nodes[i].firstChild;
while (n)
{
if (n.nodeType == 1 /* Node.ELEMENT_NODE */ && token.match(n))
results.push(n);
n = n.nextSibling;
}
}
return results;
},
// Element Immediately Preceded By
"+": function(nodes, token)
{
var results = [];
var nn = nodes.length;
for (var i = 0; i < nn; i++)
{
var n = nodes[i].nextSibling;
while (n && n.nodeType != 1 /* Node.ELEMENT_NODE */)
n = n.nextSibling;
if (n && token.match(n))
results.push(n);
}
return results;
},
// Element Preceded By
"~": function(nodes, token)
{
var uid = ++Spry.$$.uniqueID;
var results = [];
var nn = nodes.length;
for (var i = 0; i < nn; i++)
{
var n = nodes[i].nextSibling;
while (n)
{
if (n.nodeType == 1 /* Node.ELEMENT_NODE */)
{
if (uid == n.spry$$uid)
break;
if (token.match(n))
{
results.push(n);
n.spry$$uid = uid;
}
}
n = n.nextSibling;
}
}
return results;
}
};
Spry.$$.uniqueID = 0;
Spry.$$.pseudoFuncs = {
":first-child": function(arg, node, token)
{
var n = node.previousSibling;
while (n)
{
if (n.nodeType == 1) return false; // Node.ELEMENT_NODE
n = n.previousSibling;
}
return true;
},
":last-child": function(arg, node, token)
{
var n = node.nextSibling;
while (n)
{
if (n.nodeType == 1) // Node.ELEMENT_NODE
return false;
n = n.nextSibling;
}
return true;
},
":empty": function(arg, node, token)
{
var n = node.firstChild;
while (n)
{
switch(n.nodeType)
{
case 1: // Node.ELEMENT_NODE
case 3: // Node.TEXT_NODE
case 4: // Node.CDATA_NODE
case 5: // Node.ENTITY_REFERENCE_NODE
return false;
}
n = n.nextSibling;
}
return true;
},
":nth-child": function(arg, node, token)
{
return Spry.$$.nthChild(arg, node, token);
},
":nth-last-child": function(arg, node, token)
{
return Spry.$$.nthChild(arg, node, token, true);
},
":nth-of-type": function(arg, node, token)
{
return Spry.$$.nthChild(arg, node, token, false, true);
},
":nth-last-of-type": function(arg, node, token)
{
return Spry.$$.nthChild(arg, node, token, true, true);
},
":first-of-type": function(arg, node, token)
{
var nodeName = token.getNodeNameIfTypeMatches(node);
if (!nodeName) return false;
var n = node.previousSibling;
while (n)
{
if (n.nodeType == 1 && nodeName == n.nodeName.toLowerCase()) return false; // Node.ELEMENT_NODE
n = n.previousSibling;
}
return true;
},
":last-of-type": function(arg, node, token)
{
var nodeName = token.getNodeNameIfTypeMatches(node);
if (!nodeName) return false;
var n = node.nextSibling;
while (n)
{
if (n.nodeType == 1 && nodeName == n.nodeName.toLowerCase()) // Node.ELEMENT_NODE
return false;
n = n.nextSibling;
}
return true;
},
":only-child": function(arg, node, token)
{
var f = Spry.$$.pseudoFuncs;
return f[":first-child"](arg, node, token) && f[":last-child"](arg, node, token);
},
":only-of-type": function(arg, node, token)
{
var f = Spry.$$.pseudoFuncs;
return f[":first-of-type"](arg, node, token) && f[":last-of-type"](arg, node, token);
},
":not": function(arg, node, token)
{
var s = Spry.$$.tokenizeSequence(arg)[0];
var t = s ? s[0] : null;
return !t || !t.match(node);
},
":enabled": function(arg, node, token)
{
return !node.disabled;
},
":disabled": function(arg, node, token)
{
return node.disabled;
},
":checked": function(arg, node, token)
{
return node.checked;
},
":root": function(arg, node, token)
{
return node.parentNode && node.ownerDocument && node.parentNode == node.ownerDocument;
}
};
Spry.$$.nthRegExp = /((-|[0-9]+)?n)?([+-]?[0-9]*)/;
Spry.$$.nthCache = {
"even": { a: 2, b: 0, mode: 1, invalid: false }
, "odd":  { a: 2, b: 1, mode: 1, invalid: false }
, "2n":   { a: 2, b: 0, mode: 1, invalid: false }
, "2n+1": { a: 2, b: 1, mode: 1, invalid: false }
};
Spry.$$.parseNthChildString = function(str)
{
var o = Spry.$$.nthCache[str];
if (!o)
{
var m = str.match(Spry.$$.nthRegExp);
var n = m[1];
var a = m[2];
var b = m[3];
if (!a)
{
// An 'a' value was not specified. Was there an 'n' present?
// If so, we treat it as an increment of 1, otherwise we're
// in no-repeat mode.
a = n ? 1 : 0;
}
else if (a == "-")
{
// The string is using the "-n" short-hand which is
// short for -1.
a = -1;
}
else
{
// An integer repeat value for 'a' was specified. Convert
// it into number.
a = parseInt(a, 10);
}
// If a 'b' value was specified, turn it into a number.
// If no 'b' value was specified, default to zero.
b = b ? parseInt(b, 10) : 0;
// Figure out the mode:
//
// -1 - repeat backwards
//  0 - no repeat
//  1 - repeat forwards
var mode = (a == 0) ? 0 : ((a > 0) ? 1 : -1);
var invalid = false;
// Fix up 'a' and 'b' for proper repeating.
if (a > 0 && b < 0)
{
b = b % a;
b = ((b=(b%a)) < 0) ? a + b : b;
}
else if (a < 0)
{
if (b < 0)
invalid = true;
else
a = Math.abs(a);
}
o = new Object;
o.a = a;
o.b = b;
o.mode = mode;
o.invalid = invalid;
Spry.$$.nthCache[str] = o;
}
return o;
};
Spry.$$.nthChild = function(arg, node, token, fromLastSib, matchNodeName)
{
if (matchNodeName)
{
var nodeName = token.getNodeNameIfTypeMatches(node);
if (!nodeName) return false;
}
var o = Spry.$$.parseNthChildString(arg);
if (o.invalid)
return false;
var qidProp = "spry$$ncQueryID";
var posProp = "spry$$ncPos";
var countProp = "spry$$ncCount";
if (matchNodeName)
{
qidProp += nodeName;
posProp += nodeName;
countProp += nodeName;
}
var parent = node.parentNode;
if (parent[qidProp] != Spry.$$.queryID)
{
var pos = 0;
parent[qidProp] = Spry.$$.queryID;
var c = parent.firstChild;
while (c)
{
if (c.nodeType == 1 && (!matchNodeName || nodeName == c.nodeName.toLowerCase()))
c[posProp] = ++pos;
c = c.nextSibling;
}
parent[countProp] = pos;
}
pos = node[posProp];
if (fromLastSib)
pos = parent[countProp] - pos + 1;
/*
var sib = fromLastSib ? "nextSibling" : "previousSibling";
var pos = 1;
var n = node[sib];
while (n)
{
if (n.nodeType == 1 && (!matchNodeName || nodeName == n.nodeName.toLowerCase()))
{
if (n == node) break;
++pos;
}
n = n[sib];
}
*/
if (o.mode == 0) // Exact match
return pos == o.b;
if (o.mode > 0) // Forward Repeat
return (pos < o.b) ? false : (!((pos - o.b) % o.a));
return (pos > o.b) ? false : (!((o.b - pos) % o.a)); // Backward Repeat
};
Spry.$$.processTokens = function(tokens, root)
{
var numTokens = tokens.length;
var nodeSet = [ root ];
var combiFunc = null;
for (var i = 0; i < numTokens && nodeSet.length > 0; i++)
{
var t = tokens[i];
if (t.type == Spry.$$.Token.SELECTOR)
{
if (combiFunc)
{
nodeSet = combiFunc(nodeSet, t);
combiFunc = null;
}
else
nodeSet = Spry.$$.getMatchingElements(nodeSet, t);
}
else // Spry.$$.Token.COMBINATOR
combiFunc = Spry.$$.combinatorFuncs[t.name];
}
return nodeSet;
};
Spry.$$.getMatchingElements = function(nodes, token)
{
var results = [];
if (token.id)
{
n = nodes[0];
if (n && n.ownerDocument)
{
var e = n.ownerDocument.getElementById(token.id);
if (e)
{
// XXX: We need to make sure that the element
//      we found is actually underneath the root
//      we were given!
if (token.match(e))
results.push(e);
}
return results;
}
}
var nn = nodes.length;
for (var i = 0; i < nn; i++)
{
var n = nodes[i];
// if (token.match(n)) results.push(n);
var ea = n.getElementsByTagName(token.name);
var ne = ea.length;
for (var j = 0; j < ne; j++)
{
var e = ea[j];
if (token.match(e, true))
results.push(e);
}
}
return results;
};
/*
Spry.$$.dumpSequences = function(sequences)
{
Spry.Debug.trace("<hr />Number of Sequences: " + sequences.length);
for (var i = 0; i < sequences.length; i++)
{
var str = "";
var s = sequences[i];
Spry.Debug.trace("<hr />Sequence " + i + " -- Tokens: " + s.length);
for (var j = 0; j < s.length; j++)
{
var t = s[j];
if (t.type == Spry.$$.Token.SELECTOR)
{
str += "  SELECTOR:\n    Name: " + t.name + "\n    ID: " + t.id + "\n    Attrs:\n";
for (var k = 0; k < t.classes.length; k++)
str += "      " + t.classes[k].name + ": " + t.classes[k].value + "\n";
for (var k = 0; k < t.attrs.length; k++)
str += "      " + t.attrs[k].name + ": " + t.attrs[k].value + "\n";
str += "    Pseudos:\n";
for (var k = 0; k < t.pseudos.length; k++)
str += "      " + t.pseudos[k].name + (t.pseudos[k].arg ? "(" + t.pseudos[k].arg + ")" : "") + "\n";
}
else
{
str += "  COMBINATOR:\n    Name: '" + t.name + "'\n";
}
}
Spry.Debug.trace("<pre>" + Spry.Utils.encodeEntities(str) + "</pre>");
}
};
*/
Spry.$$.addExtensions = function(a)
{
for (var f in Spry.$$.Results)
a[f] = Spry.$$.Results[f];
};
Spry.$$.Results = {};
Spry.$$.Results.forEach = function(func)
{
var n = this.length;
for (var i = 0; i < n; i++)
func(this[i]);
return this;
};
Spry.$$.Results.setAttribute = function(name, value)
{
return this.forEach(function(n) { Spry.Utils.setAttribute(n, name, value); });
};
Spry.$$.Results.removeAttribute = function(name)
{
return this.forEach(function(n) { Spry.Utils.removeAttribute(n, name); });
};
Spry.$$.Results.addClassName = function(className)
{
return this.forEach(function(n) { Spry.Utils.addClassName(n, className); });
};
Spry.$$.Results.removeClassName = function(className)
{
return this.forEach(function(n) { Spry.Utils.removeClassName(n, className); });
};
Spry.$$.Results.toggleClassName = function(className)
{
return this.forEach(function(n) { Spry.Utils.toggleClassName(n, className); });
};
Spry.$$.Results.addEventListener = function(eventType, handler, capture, bindHandler)
{
return this.forEach(function(n) { Spry.Utils.addEventListener(n, eventType, handler, capture, bindHandler); });
};
Spry.$$.Results.removeEventListener = function(eventType, handler, capture)
{
return this.forEach(function(n) { Spry.Utils.removeEventListener(n, eventType, handler, capture); });
};
Spry.$$.Results.setStyle = function(style)
{
if (style)
{
style = Spry.Utils.styleStringToObject(style);
this.forEach(function(n)
{
for (var p in style)
try { n.style[p] = style[p]; } catch (e) {}
});
}
return this;
};
Spry.$$.Results.setProperty = function(prop, value)
{
if (prop)
{
if (typeof prop == "string")
{
var p = {};
p[prop] = value;
prop = p;
}
this.forEach(function(n)
{
for (var p in prop)
try { n[p] = prop[p]; } catch (e) {}
});
}
return this;
};

