diff --git a/thirdparty/jquery-selector/.gitignore b/thirdparty/jquery-selector/.gitignore deleted file mode 100644 index 60a337fb8..000000000 --- a/thirdparty/jquery-selector/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -vendor/ -test/ \ No newline at end of file diff --git a/thirdparty/jquery-selector/.piston.yml b/thirdparty/jquery-selector/.piston.yml deleted file mode 100644 index 7b5417f99..000000000 --- a/thirdparty/jquery-selector/.piston.yml +++ /dev/null @@ -1,8 +0,0 @@ ---- -format: 1 -handler: - commit: 2d129e2754ba864a5c538c3be3355e24f49f1939 - branch: master -lock: false -repository_url: git://github.com/hafriedlander/jquery.selector.git -repository_class: Piston::Git::Repository diff --git a/thirdparty/jquery-selector/LICENSE b/thirdparty/jquery-selector/LICENSE deleted file mode 100644 index 5a899dce7..000000000 --- a/thirdparty/jquery-selector/LICENSE +++ /dev/null @@ -1,10 +0,0 @@ -Copyright (C) 2009 Hamish Friedlander (hamish@silverstripe.com) and SilverStripe Limited (www.silverstripe.com) -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 Hamish Friedlander nor SilverStripe 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. \ No newline at end of file diff --git a/thirdparty/jquery-selector/README.textile b/thirdparty/jquery-selector/README.textile deleted file mode 100644 index ac3acada4..000000000 --- a/thirdparty/jquery-selector/README.textile +++ /dev/null @@ -1,32 +0,0 @@ -h1. jQuery Selector - -h3. Selector tools and reverse mapping for jQuery - -* Parse and examine the AST for a selector -* Calculate the specifity of a selector -* Determine if a single element matches a selector ($().is equivilent) much faster that jQuery - -h3. Intro - -jQuery has an excellent CSS 3 selector engine built in called Sizzle. However, it's clear focus is on filtering a set of elements down to the set that matches a selector. - -jQuery.concrete has a usage pattern quite different from that optimized for by Sizzle. It reuses a small set of selectors (making a more complicated initial parsing step acceptable) -and checks if a single element matches those selectors. In this case, Sizzle can be quite slow. - -h3. Usage - -Usual usage of jQuery selector: - -var sel = $.selector('#foo'); -sel.matches(element); - -element must be a raw DOM object, not a jQuery element, sequence of elements or anything else - -h3. Compatibility - -jQuery.selector aims to be 100% compatible with Sizzle (except a couple of corner cases, noted below). Sizzle implements most of the CSS 3 spec plus several extensions. - -One set of extensions Sizzle has is a set of pseudo-classes that filter the currently selected set. These pseudo-classes are ':first', ':last', ':even', ':odd', ':eq', ':nth', ':lt', ':gt'. -These pseudo-classes are not supported in jQuery.selector, as they don't make sense when the working set is always a single element. - -jQuery.selector currently passes the jQuery selector unit test suite, with the exception of the psuedo-classes mentioned above diff --git a/thirdparty/jquery-selector/src/jquery.class.js b/thirdparty/jquery-selector/src/jquery.class.js deleted file mode 100644 index 3b08db98e..000000000 --- a/thirdparty/jquery-selector/src/jquery.class.js +++ /dev/null @@ -1,67 +0,0 @@ -/** - * Very basic Class utility. Based on base and jquery.class. - * - * Class definition: var Foo = Base.extend({ init: function(){ Constructor }; method_name: function(){ Method } }); - * - * Inheritance: var Bar = Foo.extend({ method_name: function(){ this._super(); } }); - * - * new-less Constructor: new Foo(arg) <-same as-> Foo(arg) - */ -Base = (function(){ - - var marker = {}, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; - - // The base Class implementation (does nothing) - Base = function(){}; - - Base.addMethod = function(name, func) { - var _super = this._super; - if (_super && fnTest.test(func)) { - this.prototype[name] = function(){ - var tmp = this._super; - this._super = _super[name]; - try { - var ret = func.apply(this, arguments); - } - finally { - this._super = tmp; - } - return ret; - } - } - else this.prototype[name] = func; - } - - // Create a new Class that inherits from this class - Base.extend = function(prop) { - - // The dummy class constructor - var Kls = function() { - if (arguments[0] === marker) return; - - if (this instanceof Kls) { - if (this.init) this.init.apply(this, arguments); - } - else { - var ret = new Kls(marker); if (ret.init) ret.init.apply(ret, arguments); return ret; - } - } - - Kls.constructor = Kls; - Kls.extend = Base.extend; - Kls.addMethod = Base.addMethod; - Kls._super = this.prototype; - - Kls.prototype = new this(marker); - - // Copy the properties over onto the new prototype - for (var name in prop) { - if (typeof prop[name] == 'function') Kls.addMethod(name, prop[name]); - else Kls.prototype[name] = prop; - } - - return Kls; - }; - - return Base; -})(); \ No newline at end of file diff --git a/thirdparty/jquery-selector/src/jquery.selector.js b/thirdparty/jquery-selector/src/jquery.selector.js deleted file mode 100644 index a409672e3..000000000 --- a/thirdparty/jquery-selector/src/jquery.selector.js +++ /dev/null @@ -1,188 +0,0 @@ -(function($){ - - var tokens = { - UNICODE: /\\[0-9a-f]{1,6}(?:\r\n|[ \n\r\t\f])?/, - ESCAPE: /(?:UNICODE)|\\[^\n\r\f0-9a-f]/, - NONASCII: /[^\x00-\x7F]/, - NMSTART: /[_a-z]|(?:NONASCII)|(?:ESCAPE)/, - NMCHAR: /[_a-z0-9-]|(?:NONASCII)|(?:ESCAPE)/, - IDENT: /-?(?:NMSTART)(?:NMCHAR)*/, - - NL: /\n|\r\n|\r|\f/, - - STRING: /(?:STRING1)|(?:STRING2)|(?:STRINGBARE)/, - STRING1: /"(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\"])*"/, - STRING2: /'(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\'])*'/, - STRINGBARE: /(?:(?:ESCAPE)|\\(?:NL)|[^\n\r\f\]])*/, - - FUNCTION: /(?:IDENT)\(\)/, - - INTEGER: /[0-9]+/, - - WITHN: /([-+])?(INTEGER)?(n)\s*(?:([-+])\s*(INTEGER))?/, - WITHOUTN: /([-+])?(INTEGER)/ - } - - var rx = { - not: /:not\(/, - not_end: /\)/, - - tag: /((?:IDENT)|\*)/, - id: /#(IDENT)/, - cls: /\.(IDENT)/, - attr: /\[\s*(IDENT)\s*(?:([^=]?=)\s*(STRING)\s*)?\]/, - pseudo_el: /(?::(first-line|first-letter|before|after))|(?:::((?:FUNCTION)|(?:IDENT)))/, - pseudo_cls_nth: /:nth-child\(\s*(?:(?:WITHN)|(?:WITHOUTN)|(odd|even))\s*\)/, - pseudo_cls: /:(IDENT)/, - - comb: /\s*(\+|~|>)\s*|\s+/, - comma: /\s*,\s*/, - important: /\s+!important\s*$/ - } - - /* Replace placeholders with actual regex, and mark all as case insensitive */ - var token = /[A-Z][A-Z0-9]+/; - for (var k in rx) { - var src = rx[k].source; - while (m = src.match(token)) src = src.replace(m[0], tokens[m[0]].source); - rx[k] = new RegExp(src, 'gi'); - } - - /** - * A string that matches itself against regexii, and keeps track of how much of itself has been matched - */ - var ConsumableString = Base.extend({ - init: function(str) { - this.str = str; - this.pos = 0; - }, - match: function(rx) { - var m; - rx.lastIndex = this.pos; - if ((m = rx.exec(this.str)) && m.index == this.pos ) { - this.pos = rx.lastIndex ? rx.lastIndex : this.str.length ; - return m; - } - return null; - }, - peek: function(rx) { - var m; - rx.lastIndex = this.pos; - if ((m = rx.exec(this.str)) && m.index == this.pos ) return m; - return null; - }, - showpos: function() { - return this.str.slice(0,this.pos)+'' + this.str.slice(this.pos); - }, - done: function() { - return this.pos == this.str.length; - } - }) - - /* A base class that all Selectors inherit off */ - var SelectorBase = Base.extend({}); - - /** - * A class representing a Simple Selector, as per the CSS3 selector spec - */ - var SimpleSelector = SelectorBase.extend({ - init: function() { - this.tag = null; - this.id = null; - this.classes = []; - this.attrs = []; - this.nots = []; - this.pseudo_classes = []; - this.pseudo_els = []; - }, - parse: function(selector) { - var m; - - /* Pull out the initial tag first, if there is one */ - if (m = selector.match(rx.tag)) this.tag = m[1]; - - /* Then for each selection type, try and find a match */ - do { - if (m = selector.match(rx.not)) { - this.nots[this.nots.length] = SelectorsGroup().parse(selector) - if (!(m = selector.match(rx.not_end))) { - throw 'Invalid :not term in selector'; - } - } - else if (m = selector.match(rx.id)) this.id = m[1]; - else if (m = selector.match(rx.cls)) this.classes[this.classes.length] = m[1]; - else if (m = selector.match(rx.attr)) this.attrs[this.attrs.length] = [ m[1], m[2], m[3] ]; - else if (m = selector.match(rx.pseudo_el)) this.pseudo_els[this.pseudo_els.length] = m[1] || m[2]; - else if (m = selector.match(rx.pseudo_cls_nth)) { - if (m[3]) { - var a = parseInt((m[1]||'')+(m[2]||'1')); - var b = parseInt((m[4]||'')+(m[5]||'0')); - } - else { - var a = m[8] ? 2 : 0; - var b = m[8] ? (4-m[8].length) : parseInt((m[6]||'')+m[7]); - } - this.pseudo_classes[this.pseudo_classes.length] = ['nth-child', [a, b]]; - } - else if (m = selector.match(rx.pseudo_cls)) this.pseudo_classes[this.pseudo_classes.length] = [m[1]]; - - } while(m && !selector.done()); - - return this; - } - }) - - /** - * A class representing a Selector, as per the CSS3 selector spec - */ - var Selector = SelectorBase.extend({ - init: function(){ - this.parts = []; - }, - parse: function(cons){ - this.parts[this.parts.length] = SimpleSelector().parse(cons); - - while (!cons.done() && !cons.peek(rx.comma) && (m = cons.match(rx.comb))) { - this.parts[this.parts.length] = m[1] || ' '; - this.parts[this.parts.length] = SimpleSelector().parse(cons); - } - - return this.parts.length == 1 ? this.parts[0] : this; - } - }); - - /** - * A class representing a sequence of selectors, as per the CSS3 selector spec - */ - var SelectorsGroup = SelectorBase.extend({ - init: function(){ - this.parts = []; - }, - parse: function(cons){ - this.parts[this.parts.length] = Selector().parse(cons); - - while (!cons.done() && (m = cons.match(rx.comma))) { - this.parts[this.parts.length] = Selector().parse(cons); - } - - return this.parts.length == 1 ? this.parts[0] : this; - } - }); - - - $.selector = function(s){ - var cons = ConsumableString(s); - var res = SelectorsGroup().parse(cons); - - res.selector = s; - - if (!cons.done()) throw 'Could not parse selector - ' + cons.showpos() ; - else return res; - } - - $.selector.SelectorBase = SelectorBase; - $.selector.SimpleSelector = SimpleSelector; - $.selector.Selector = Selector; - $.selector.SelectorsGroup = SelectorsGroup; - -})(jQuery) diff --git a/thirdparty/jquery-selector/src/jquery.selector.matches.js b/thirdparty/jquery-selector/src/jquery.selector.matches.js deleted file mode 100644 index 3a6a2a2f2..000000000 --- a/thirdparty/jquery-selector/src/jquery.selector.matches.js +++ /dev/null @@ -1,353 +0,0 @@ -/* -This attempts to do the opposite of Sizzle. -Sizzle is good for finding elements for a selector, but not so good for telling if an individual element matches a selector -*/ - -(function($) { - - /**** CAPABILITY TESTS ****/ - var div = document.createElement('div'); - div.innerHTML = '
'; - - // In IE 6-7, getAttribute often does the wrong thing (returns similar to el.attr), so we need to use getAttributeNode on that browser - var getAttributeDodgy = div.firstChild.getAttribute('id') !== 'test'; - - // Does browser support Element.firstElementChild, Element.previousElementSibling, etc. - var hasElementTraversal = div.firstElementChild && div.firstElementChild.tagName == 'FORM'; - - // Does browser support Element.children - var hasChildren = div.children && div.children[0].tagName == 'FORM'; - - var FUNC_IN = /^\s*function\s*\([^)]*\)\s*{/; - var FUNC_OUT = /}\s*$/; - - var funcToString = function(f) { - return (''+f).replace(FUNC_IN,'').replace(FUNC_OUT,''); - } - - // Can we use Function#toString ? - try { - var testFunc = function(){ return 'good' }; - if ((new Function('',funcToString(testFunc)))() != 'good') funcToString = false; - } - catch(e) { funcToString = false; console.log(e.message);/*pass*/ } - - /**** INTRO ****/ - - var GOOD = /GOOD/g; - var BAD = /BAD/g; - - var STARTS_WITH_QUOTES = /^['"]/g; - - var join = function(js) { - return js.join('\n'); - } - - var join_complex = function(js) { - code = new String(js.join('\n')); // String objects can have properties set. strings can't - code.complex = true; - return code; - } - - /**** ATTRIBUTE ACCESSORS ****/ - - var getAttr; - - // Good browsers - if (!getAttributeDodgy) { - getAttr = function(attr){ return 'var _'+attr+' = el.getAttribute("'+attr+'");' ; } - } - // IE 6, 7 - else { - // On IE 6 + 7, getAttribute still has to be called with DOM property mirror name, not attribute name. Map attributes to those names - var getAttrIEMap = { 'class': 'className', 'for': 'htmlFor' }; - - getAttr = function(attr) { - var ieattr = getAttrIEMap[attr] || attr; - return 'var _'+attr+' = el.getAttribute("'+ieattr+'",2) || (el.getAttributeNode("'+attr+'")||{}).nodeValue;'; - } - } - - /**** ATTRIBUTE COMPARITORS ****/ - - var attrchecks = { - '-': '!_K', - '=': '_K != "V"', - '!=': '_K == "V"', - '~=': '__K.indexOf(" V ") == -1', - '^=': '!_K || _K.indexOf("V") != 0', - '*=': '!_K || _K.indexOf("V") == -1', - '$=': '!_K || _K.substr(_K.length-"V".length) != "V"' - } - - /**** STATE TRACKER ****/ - - var State = $.selector.State = Base.extend({ - init: function(){ - this.reset(); - }, - reset: function() { - this.attrs = {}; this.wsattrs = {}; - }, - - prev: function(){ - this.reset(); - if (hasElementTraversal) return 'el = el.previousElementSibling'; - return 'while((el = el.previousSibling) && el.nodeType != 1) {}'; - }, - next: function() { - this.reset(); - if (hasElementTraversal) return 'el = el.nextElementSibling'; - return 'while((el = el.nextSibling) && el.nodeType != 1) {}'; - }, - prevLoop: function(body){ - this.reset(); - if (hasElementTraversal) return join([ 'while(el = el.previousElementSibling){', body]); - return join([ - 'while(el = el.previousSibling){', - 'if (el.nodeType != 1) continue;', - body, - ]); - }, - parent: function() { - this.reset(); - return 'el = el.parentNode;'; - }, - parentLoop: function(body) { - this.reset(); - return join([ - 'while((el = el.parentNode) && el.nodeType == 1){', - body, - '}' - ]); - }, - - uses_attr: function(attr) { - if (this.attrs[attr]) return; - this.attrs[attr] = true; - return getAttr(attr); - }, - uses_wsattr: function(attr) { - if (this.wsattrs[attr]) return; - this.wsattrs[attr] = true; - return join([this.uses_attr(attr), 'var __'+attr+' = " "+_'+attr+'+" ";']); - }, - - save: function(lbl) { - return 'var el'+lbl+' = el;'; - }, - restore: function(lbl) { - this.reset(); - return 'el = el'+lbl+';'; - } - }); - - /**** PSEUDO-CLASS DETAILS ****/ - - var pseudoclschecks = { - 'first-child': join([ - 'var cel = el;', - 'while(cel = cel.previousSibling){ if (cel.nodeType === 1) BAD; }', - ]), - 'last-child': join([ - 'var cel = el;', - 'while(cel = cel.nextSibling){ if (cel.nodeType === 1) BAD; }' - ]), - 'nth-child': function(a,b) { - var get_i = join([ - 'var i = 1, cel = el;', - 'while(cel = cel.previousSibling){', - 'if (cel.nodeType === 1) i++;', - '}', - ]); - - if (a == 0) return join([ - get_i, - 'if (i- '+b+' != 0) BAD;' - ]); - else if (b == 0 && a >= 0) return join([ - get_i, - 'if (i%'+a+' != 0 || i/'+a+' < 0) BAD;' - ]); - else if (b == 0 && a < 0) return join([ - 'BAD;' - ]); - else return join([ - get_i, - 'if ((i- '+b+')%'+a+' != 0 || (i- '+b+')/'+a+' < 0) BAD;' - ]); - } - }; - - // Needs to refence contents of object, so must be injected after definition - pseudoclschecks['only-child'] = join([ - pseudoclschecks['first-child'], - pseudoclschecks['last-child'] - ]); - - /**** SimpleSelector ****/ - - $.selector.SimpleSelector.addMethod('compile', function(el) { - var js = []; - - /* Check against element name */ - if (this.tag && this.tag != '*') { - js[js.length] = 'if (el.tagName != "'+this.tag.toUpperCase()+'") BAD;'; - } - - /* Check against ID */ - if (this.id) { - js[js.length] = el.uses_attr('id'); - js[js.length] = 'if (_id !== "'+this.id+'") BAD;'; - } - - /* Build className checking variable */ - if (this.classes.length) { - js[js.length] = el.uses_wsattr('class'); - - /* Check against class names */ - $.each(this.classes, function(i, cls){ - js[js.length] = 'if (__class.indexOf(" '+cls+' ") == -1) BAD;'; - }) - } - - /* Check against attributes */ - $.each(this.attrs, function(i, attr){ - js[js.length] = (attr[1] == '~=') ? el.uses_wsattr(attr[0]) : el.uses_attr(attr[0]); - var check = attrchecks[ attr[1] || '-' ]; - check = check.replace( /K/g, attr[0]).replace( /V/g, attr[2] && attr[2].match(STARTS_WITH_QUOTES) ? attr[2].slice(1,-1) : attr[2] ); - js[js.length] = 'if ('+check+') BAD;'; - }); - - /* Check against nots */ - $.each(this.nots, function(i, not){ - var lbl = ++lbl_id; - var func = join([ - 'l'+lbl+':{', - not.compile(el).replace(BAD, 'break l'+lbl).replace(GOOD, 'BAD'), - '}' - ]); - - if (!(not instanceof $.selector.SimpleSelector)) func = join([ - el.save(lbl), - func, - el.restore(lbl) - ]) - - js[js.length] = func; - }); - - /* Check against pseudo-classes */ - $.each(this.pseudo_classes, function(i, pscls){ - var check = pseudoclschecks[pscls[0]]; - if (check) { - js[js.length] = ( typeof check == 'function' ? check.apply(this, pscls[1]) : check ); - } - else if (check = $.find.selectors.filters[pscls[0]]) { - if (funcToString) { - js[js.length] = funcToString(check).replace(/elem/g,'el').replace(/return([^;]+);/,'if (!($1)) BAD;'); - } - else { - js[js.length] = 'if (!$.find.selectors.filters.'+pscls[0]+'(el)) BAD;' - } - } - }); - - js[js.length] = 'GOOD'; - - /* Pass */ - return join(js); - }); - - var lbl_id = 0; - /** Turns an compiled fragment into the first part of a combination */ - function as_subexpr(f) { - if (f.complex) - return join([ - 'l'+(++lbl_id)+':{', - f.replace(GOOD, 'break l'+lbl_id), - '}', - ]); - else - return f.replace(GOOD, ''); - } - - var combines = { - ' ': function(el, f1, f2) { - return join_complex([ - f2, - 'while(true){', - el.parent(), - 'if (!el || el.nodeType !== 1) BAD;', - f1.compile(el).replace(BAD, 'continue'), - '}' - ]); - }, - - '>': function(el, f1, f2) { - return join([ - f2, - el.parent(), - 'if (!el || el.nodeType !== 1) BAD;', - f1.compile(el) - ]); - }, - - '~': function(el, f1, f2) { - return join_complex([ - f2, - el.prevLoop(), - f1.compile(el).replace(BAD, 'continue'), - '}', - 'BAD;' - ]); - }, - - '+': function(el, f1, f2) { - return join([ - f2, - el.prev(), - 'if (!el) BAD;', - f1.compile(el) - ]); - } - }; - - $.selector.Selector.addMethod('compile', function(el) { - l = this.parts.length; - - expr = this.parts[--l].compile(el); - while (l) { - combinator = this.parts[--l]; - expr = combines[combinator](el, this.parts[--l], as_subexpr(expr)); - } - - return expr; - }); - - $.selector.SelectorsGroup.addMethod('compile', function(el) { - var expr = [], lbl = ++lbl_id; - - for (var i=0; i < this.parts.length; i++) { - expr[expr.length] = join([ - i == 0 ? el.save(lbl) : el.restore(lbl), - 'l'+lbl+'_'+i+':{', - this.parts[i].compile(el).replace(BAD, 'break l'+lbl+'_'+i), - '}' - ]); - } - - expr[expr.length] = 'BAD;'; - return join(expr); - }); - - $.selector.SelectorBase.addMethod('matches', function(el){ - this.matches = new Function('el', join([ - 'if (!el) return false;', - this.compile(new State()).replace(BAD, 'return false').replace(GOOD, 'return true') - ])); - return this.matches(el); - }); - -})(jQuery); - diff --git a/thirdparty/jquery-selector/src/jquery.selector.specifity.js b/thirdparty/jquery-selector/src/jquery.selector.specifity.js deleted file mode 100644 index f11cb9a33..000000000 --- a/thirdparty/jquery-selector/src/jquery.selector.specifity.js +++ /dev/null @@ -1,42 +0,0 @@ -(function($) { - - $.selector.SimpleSelector.addMethod('specifity', function() { - if (this.spec) return this.spec; - - var spec = [ - this.id ? 1 : 0, - this.classes.length + this.attrs.length + this.pseudo_classes.length, - ((this.tag && this.tag != '*') ? 1 : 0) + this.pseudo_els.length - ]; - $.each(this.nots, function(i,not){ - var ns = not.specifity(); spec[0] += ns[0]; spec[1] += ns[1]; sspec[2] += ns[2]; - }); - - return this.spec = spec; - }) - - $.selector.Selector.addMethod('specifity', function(){ - if (this.spec) return this.spec; - - var spec = [0,0,0]; - $.each(this.parts, function(i,part){ - if (i%2) return; - var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2]; - }); - - return this.spec = spec; - }) - - $.selector.SelectorsGroup.addMethod('specifity', function(){ - if (this.spec) return this.spec; - - var spec = [0,0,0]; - $.each(this.parts, function(i,part){ - var ps = part.specifity(); spec[0] += ps[0]; spec[1] += ps[1]; spec[2] += ps[2]; - }); - - return this.spec = spec; - }) - - -})(jQuery);