From deb31b3bb4f9f708a3b8522ad66b6fbb70d0b465 Mon Sep 17 00:00:00 2001 From: Julian Seidenberg Date: Thu, 24 Feb 2011 10:03:38 +1300 Subject: [PATCH] API-CHANGE: updated jquery entwine to new version that is compatible with jQuery 1.5 --- thirdparty/jquery-entwine/.piston.yml | 4 +- thirdparty/jquery-entwine/build.sh | 4 +- .../dist/jquery.concrete-dist.js | 1588 +--- .../dist/jquery.entwine-dist.js | 72 +- .../jquery-entwine/spec/SpecRunner.html | 42 + .../jquery-entwine/spec/legacy/spec-dist.html | 30 - .../spec/legacy/spec.concrete.basics.js | 85 - .../spec/legacy/spec.concrete.ctors.js | 68 - .../spec/legacy/spec.concrete.events.js | 112 - .../spec/legacy/spec.concrete.namespaces.js | 246 - .../spec/legacy/spec.concrete.properties.js | 102 - .../spec/legacy/spec.concrete.super.js | 66 - .../jquery-entwine/spec/legacy/spec.html | 39 - thirdparty/jquery-entwine/spec/spec-dist.html | 30 - .../spec/spec.entwine.basics.js | 85 +- .../jquery-entwine/spec/spec.entwine.ctors.js | 92 +- .../spec/spec.entwine.events.js | 132 +- .../spec/spec.entwine.namespaces.js | 147 +- .../spec/spec.entwine.properties.js | 182 +- .../jquery-entwine/spec/spec.entwine.super.js | 152 +- thirdparty/jquery-entwine/spec/spec.html | 38 - .../jquery-entwine/src/jquery.entwine.js | 70 +- .../vendor/jasmine-1.0.1/MIT.LICENSE | 20 + .../vendor/jasmine-1.0.1/jasmine-html.js | 188 + .../vendor/jasmine-1.0.1/jasmine.css | 166 + .../vendor/jasmine-1.0.1/jasmine.js | 2421 +++++ .../jasmine-dom/jasmine-dom-fixtures.js | 175 + .../jasmine-dom/jasmine-dom-matchers.js | 205 + .../jquery-entwine/vendor/jquery-1.3.2.js | 4376 --------- .../jquery-entwine/vendor/jquery-1.5.js | 8176 +++++++++++++++++ 30 files changed, 11882 insertions(+), 7231 deletions(-) mode change 100644 => 120000 thirdparty/jquery-entwine/dist/jquery.concrete-dist.js create mode 100644 thirdparty/jquery-entwine/spec/SpecRunner.html delete mode 100644 thirdparty/jquery-entwine/spec/legacy/spec-dist.html delete mode 100644 thirdparty/jquery-entwine/spec/legacy/spec.concrete.basics.js delete mode 100644 thirdparty/jquery-entwine/spec/legacy/spec.concrete.ctors.js delete mode 100644 thirdparty/jquery-entwine/spec/legacy/spec.concrete.events.js delete mode 100644 thirdparty/jquery-entwine/spec/legacy/spec.concrete.namespaces.js delete mode 100644 thirdparty/jquery-entwine/spec/legacy/spec.concrete.properties.js delete mode 100644 thirdparty/jquery-entwine/spec/legacy/spec.concrete.super.js delete mode 100644 thirdparty/jquery-entwine/spec/legacy/spec.html delete mode 100644 thirdparty/jquery-entwine/spec/spec-dist.html delete mode 100644 thirdparty/jquery-entwine/spec/spec.html create mode 100644 thirdparty/jquery-entwine/vendor/jasmine-1.0.1/MIT.LICENSE create mode 100644 thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine-html.js create mode 100644 thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine.css create mode 100644 thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine.js create mode 100644 thirdparty/jquery-entwine/vendor/jasmine-dom/jasmine-dom-fixtures.js create mode 100644 thirdparty/jquery-entwine/vendor/jasmine-dom/jasmine-dom-matchers.js delete mode 100644 thirdparty/jquery-entwine/vendor/jquery-1.3.2.js create mode 100644 thirdparty/jquery-entwine/vendor/jquery-1.5.js diff --git a/thirdparty/jquery-entwine/.piston.yml b/thirdparty/jquery-entwine/.piston.yml index 35d3f81cc..461035058 100644 --- a/thirdparty/jquery-entwine/.piston.yml +++ b/thirdparty/jquery-entwine/.piston.yml @@ -1,8 +1,8 @@ --- format: 1 handler: - commit: f09e97da777031a67e136945f8732890c84e3e65 + commit: b0b8d4f3417db927eae24510f9a45dfe38bb7d37 branch: master lock: false repository_class: Piston::Git::Repository -repository_url: git://github.com/hafriedlander/jquery.entwine.git +repository_url: https://github.com/hafriedlander/jquery.entwine.git diff --git a/thirdparty/jquery-entwine/build.sh b/thirdparty/jquery-entwine/build.sh index 9321d4b9c..efd44f095 100755 --- a/thirdparty/jquery-entwine/build.sh +++ b/thirdparty/jquery-entwine/build.sh @@ -6,7 +6,7 @@ FILE="dist/jquery.entwine-dist.js" mkdir -p dist rm dist/*.js -echo "/* jQuery.Entwine - Copyright 2009 Hamish Friedlander and SilverStripe. Version $VER. */" > $FILE +echo "/* jQuery.Entwine - Copyright 2009-2011 Hamish Friedlander and SilverStripe. Version $VER. */" > $FILE for x in \ vendor/jquery.selector/jquery.class.js \ @@ -40,4 +40,4 @@ done # git add LICENSE # git commit -m "Update dist to master version $VER" -# git checkout master \ No newline at end of file +# git checkout master diff --git a/thirdparty/jquery-entwine/dist/jquery.concrete-dist.js b/thirdparty/jquery-entwine/dist/jquery.concrete-dist.js deleted file mode 100644 index 7e8822eb7..000000000 --- a/thirdparty/jquery-entwine/dist/jquery.concrete-dist.js +++ /dev/null @@ -1,1587 +0,0 @@ -/* jQuery.Entwine - Copyright 2009 Hamish Friedlander and SilverStripe. Version . */ - -/* vendor/jquery.selector/jquery.class.js */ - -/** - * 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) - */ - -var Base; - -(function(){ - - var marker = {}, fnTest = /xyz/.test(function(){var xyz;}) ? /\b_super\b/ : /.*/; - - // The base Class implementation (does nothing) - Base = function(){}; - - Base.addMethod = function(name, func) { - var parent = this._super && this._super.prototype; - - if (parent && fnTest.test(func)) { - this.prototype[name] = function(){ - var tmp = this._super; - this._super = parent[name]; - try { - var ret = func.apply(this, arguments); - } - finally { - this._super = tmp; - } - return ret; - }; - } - else this.prototype[name] = func; - }; - - Base.addMethods = function(props) { - for (var name in props) { - if (typeof props[name] == 'function') this.addMethod(name, props[name]); - else this.prototype[name] = props[name]; - } - }; - - Base.subclassOf = function(parentkls) { - var kls = this; - while (kls) { - if (kls === parentkls) return true; - kls = kls._super; - } - }; - - // Create a new Class that inherits from this class - Base.extend = function(props) { - - // 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; - } - }; - - // Add the common class variables and methods - Kls.constructor = Kls; - Kls.extend = Base.extend; - Kls.addMethod = Base.addMethod; - Kls.addMethods = Base.addMethods; - Kls.subclassOf = Base.subclassOf; - - Kls._super = this; - - // Attach the parent object to the inheritance chain - Kls.prototype = new this(marker); - Kls.prototype.constructor = Kls; - - // Copy the properties over onto the new prototype - Kls.addMethods(props); - - return Kls; - }; -})();; - - -/* vendor/jquery.selector/jquery.selector.js */ - -(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 m, 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); -; - - -/* vendor/jquery.selector/jquery.selector.specifity.js */ - -(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]; spec[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); -; - - -/* vendor/jquery.selector/jquery.selector.matches.js */ - -/* -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) { - var code = new String(js.join('\n')); // String objects can have properties set. strings can't - code.complex = true; - return code; - }; - - /**** ATTRIBUTE ACCESSORS ****/ - - // Not all attribute names can be used as identifiers, so we encode any non-acceptable characters as hex - var varForAttr = function(attr) { - return '_' + attr.replace(/^[^A-Za-z]|[^A-Za-z0-9]/g, function(m){ return '_0x' + m.charCodeAt(0).toString(16) + '_'; }); - }; - - var getAttr; - - // Good browsers - if (!getAttributeDodgy) { - getAttr = function(attr){ return 'var '+varForAttr(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 '+varForAttr(attr)+' = el.getAttribute("'+ieattr+'",2) || (el.getAttributeNode("'+attr+'")||{}).nodeValue;'; - }; - } - - /**** ATTRIBUTE COMPARITORS ****/ - - var attrchecks = { - '-': '!K', - '=': 'K != "V"', - '!=': 'K == "V"', - '~=': '_WS_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 _WS_'+varForAttr(attr)+' = " "+'+varForAttr(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 (_WS__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, varForAttr(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) { - var l = this.parts.length; - - var expr = this.parts[--l].compile(el); - while (l) { - var 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); - -; - - -/* src/jquery.focusinout.js */ - -(function($){ - - /** - * Add focusin and focusout support to bind and live for browers other than IE. Designed to be usable in a delegated fashion (like $.live) - * Copyright (c) 2007 Jörn Zaefferer - */ - $.support.focusInOut = !!($.browser.msie); - if (!$.support.focusInOut) { - // Emulate focusin and focusout by binding focus and blur in capturing mode - $.each({focus: 'focusin', blur: 'focusout'}, function(original, fix){ - $.event.special[fix] = { - setup: function(){ - if (!this.addEventListener) return false; - this.addEventListener(original, $.event.special[fix].handler, true); - }, - teardown: function(){ - if (!this.removeEventListener) return false; - this.removeEventListener(original, $.event.special[fix].handler, true); - }, - handler: function(e){ - arguments[0] = $.event.fix(e); - arguments[0].type = fix; - return $.event.handle.apply(this, arguments); - } - }; - }); - } - - (function(){ - //IE has some trouble with focusout with select and keyboard navigation - var activeFocus = null; - - $(document) - .bind('focusin', function(e){ - var target = e.realTarget || e.target; - if (activeFocus && activeFocus !== target) { - e.type = 'focusout'; - $(activeFocus).trigger(e); - e.type = 'focusin'; - e.target = target; - } - activeFocus = target; - }) - .bind('focusout', function(e){ - activeFocus = null; - }); - })(); - -})(jQuery);; - - -/* src/jquery.entwine.js */ - -var console; - -(function($) { - - var namespaces = {}; - - $.entwine = function() { - $.fn.entwine.apply(null, arguments); - }; - - /** - * A couple of utility functions for accessing the store outside of this closure, and for making things - * operate in a little more easy-to-test manner - */ - $.extend($.entwine, { - /** - * Get all the namespaces. Useful for introspection? Internal interface of Namespace not guaranteed consistant - */ - namespaces: namespaces, - - /** - * Remove all entwine rules - */ - clear_all_rules: function() { - // Remove proxy functions - for (var k in $.fn) { if ($.fn[k].entwine) delete $.fn[k] ; } - // Remove bound events - TODO: Make this pluggable, so this code can be moved to jquery.entwine.events.js - $(document).unbind('.entwine'); - // Remove namespaces, and start over again - namespaces = $.entwine.namespaces = {}; - }, - - WARN_LEVEL_NONE: 0, - WARN_LEVEL_IMPORTANT: 1, - WARN_LEVEL_BESTPRACTISE: 2, - - /** - * Warning level. Set to a higher level to get warnings dumped to console. - */ - warningLevel: 0, - - /** Utility to optionally display warning messages depending on level */ - warn: function(message, level) { - if (level <= $.entwine.warningLevel && console && console.warn) { - console.warn(message); - if (console.trace) console.trace(); - } - }, - - warn_exception: function(where, /* optional: */ on, e) { - if ($.entwine.WARN_LEVEL_IMPORTANT <= $.entwine.warningLevel && console && console.warn) { - if (arguments.length == 2) { e = on; on = null; } - - if (on) console.warn('Uncaught exception',e,'in',where,'on',on); - else console.warn('Uncaught exception',e,'in',where); - - if (e.stack) console.warn("Stack Trace:\n" + e.stack); - } - } - }); - - - /** Stores a count of definitions, so that we can sort identical selectors by definition order */ - var rulecount = 0; - - var Rule = Base.extend({ - init: function(selector, name) { - this.selector = selector; - this.specifity = selector.specifity(); - this.important = 0; - this.name = name; - this.rulecount = rulecount++; - } - }); - - Rule.compare = function(a, b) { - var as = a.specifity, bs = b.specifity; - - return (a.important - b.important) || - (as[0] - bs[0]) || - (as[1] - bs[1]) || - (as[2] - bs[2]) || - (a.rulecount - b.rulecount) ; - }; - - $.entwine.RuleList = function() { - var list = []; - - list.addRule = function(selector, name){ - var rule = Rule(selector, name); - - list[list.length] = rule; - list.sort(Rule.compare); - - return rule; - }; - - return list; - }; - - var handlers = []; - - /** - * A Namespace holds all the information needed for adding entwine methods to a namespace (including the _null_ namespace) - */ - $.entwine.Namespace = Base.extend({ - init: function(name){ - if (name && !name.match(/^[A-Za-z0-9.]+$/)) $.entwine.warn('Entwine namespace '+name+' is not formatted as period seperated identifiers', $.entwine.WARN_LEVEL_BESTPRACTISE); - name = name || '__base'; - - this.name = name; - this.store = {}; - - namespaces[name] = this; - - if (name == "__base") { - this.injectee = $.fn; - this.$ = $; - } - else { - // We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into - var subfn = function(){}; - this.injectee = subfn.prototype = new $(); - - // And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building - var bound$ = this.$ = function(a) { - // Try the simple way first - var jq = $.fn.init.apply(new subfn(), arguments); - if (jq instanceof subfn) return jq; - - // That didn't return a bound object, so now we need to copy it - var rv = new subfn(); - rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length; - while (i--) rv[i] = jq[i]; - return rv; - }; - this.injectee.pushStack = function(elems, name, selector){ - var ret = bound$(elems); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; - - if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector; - else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")"; - - // Return the newly-formed element set - return ret; - }; - - // Copy static functions through from $ to this.$ so e.g. $.ajax still works - // @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through - $.extend(this.$, $); - - // We override entwine to inject the name of this namespace when defining blocks inside this namespace - var entwine_wrapper = this.injectee.entwine = function(spacename) { - var args = arguments; - - if (!spacename || typeof spacename != 'string') { args = $.makeArray(args); args.unshift(name); } - else if (spacename.charAt(0) != '.') args[0] = name+'.'+spacename; - - return $.fn.entwine.apply(this, args); - }; - - this.$.entwine = function() { - entwine_wrapper.apply(null, arguments); - }; - - for (var i = 0; i < handlers.length; i++) { - var handler = handlers[i], builder; - - // Inject jQuery object method overrides - if (builder = handler.namespaceMethodOverrides) { - var overrides = builder(this); - for (var k in overrides) this.injectee[k] = overrides[k]; - } - - // Inject $.entwine function overrides - if (builder = handler.namespaceStaticOverrides) { - var overrides = builder(this); - for (var k in overrides) this.$.entwine[k] = overrides[k]; - } - } - } - }, - - /** - * Returns a function that does selector matching against the function list for a function name - * Used by proxy for all calls, and by ctorProxy to handle _super calls - * @param {String} name - name of the function as passed in the construction object - * @param {String} funcprop - the property on the Rule object that gives the actual function to call - * @param {function} basefunc - the non-entwine function to use as the catch-all function at the bottom of the stack - */ - one: function(name, funcprop, basefunc) { - var namespace = this; - var funcs = this.store[name]; - - var one = function(el, args, i){ - if (i === undefined) i = funcs.length; - while (i--) { - if (funcs[i].selector.matches(el)) { - var ret, tmp_i = el.i, tmp_f = el.f; - el.i = i; el.f = one; - try { ret = funcs[i][funcprop].apply(namespace.$(el), args); } - finally { el.i = tmp_i; el.f = tmp_f; } - return ret; - } - } - // If we didn't find a entwine-defined function, but there is a non-entwine function to use as a base, try that - if (basefunc) return basefunc.apply(namespace.$(el), args); - }; - - return one; - }, - - /** - * A proxy is a function attached to a callable object (either the base jQuery.fn or a subspace object) which handles - * finding and calling the correct function for each member of the current jQuery context - * @param {String} name - name of the function as passed in the construction object - * @param {function} basefunc - the non-entwine function to use as the catch-all function at the bottom of the stack - */ - build_proxy: function(name, basefunc) { - var one = this.one(name, 'func', basefunc); - - var prxy = function() { - var rv, ctx = $(this); - - var i = ctx.length; - while (i--) rv = one(ctx[i], arguments); - return rv; - }; - - return prxy; - }, - - bind_proxy: function(selector, name, func) { - var rulelist = this.store[name] || (this.store[name] = $.entwine.RuleList()); - - var rule = rulelist.addRule(selector, name); rule.func = func; - - if (!this.injectee.hasOwnProperty(name) || !this.injectee[name].entwine) { - this.injectee[name] = this.build_proxy(name, this.injectee.hasOwnProperty(name) ? this.injectee[name] : null); - this.injectee[name].entwine = true; - } - - if (!this.injectee[name].entwine) { - $.entwine.warn('Warning: Entwine function '+name+' clashes with regular jQuery function - entwine function will not be callable directly on jQuery object', $.entwine.WARN_LEVEL_IMPORTANT); - } - }, - - add: function(selector, data) { - // For every item in the hash, try ever method handler, until one returns true - for (var k in data) { - var v = data[k]; - - for (var i = 0; i < handlers.length; i++) { - if (handlers[i].bind && handlers[i].bind.call(this, selector, k, v)) break; - } - } - }, - - has: function(ctx, name) { - var rulelist = this.store[name]; - if (!rulelist) return false; - - /* We go forward this time, since low specifity is likely to knock out a bunch of elements quickly */ - for (var i = 0 ; i < rulelist.length; i++) { - ctx = ctx.not(rulelist[i].selector); - if (!ctx.length) return true; - } - return false; - } - }); - - /** - * A handler is some javascript code that adds support for some time of key / value pair passed in the hash to the Namespace add method. - * The default handlers provided (and included by default) are event, ctor and properties - */ - $.entwine.Namespace.addHandler = function(handler) { - for (var i = 0; i < handlers.length && handlers[i].order < handler.order; i++) { /* Pass */ } - handlers.splice(i, 0, handler); - }; - - $.entwine.Namespace.addHandler({ - order: 50, - - bind: function(selector, k, v){ - if ($.isFunction(v)) { - this.bind_proxy(selector, k, v); - return true; - } - } - }); - - $.extend($.fn, { - /** - * Main entwine function. Used for new definitions, calling into a namespace (or forcing the base namespace) and entering a using block - * - */ - entwine: function(spacename) { - var i = 0; - /* Don't actually work out selector until we try and define something on it - we might be opening a namespace on an function-traveresed object - which have non-standard selectors like .parents(.foo).slice(0,1) */ - var selector = null; - - /* By default we operator on the base namespace */ - var namespace = namespaces.__base || $.entwine.Namespace(); - - /* If the first argument is a string, then it's the name of a namespace. Look it up */ - if (typeof spacename == 'string') { - if (spacename.charAt('0') == '.') spacename = spacename.substr(1); - if (spacename) namespace = namespaces[spacename] || $.entwine.Namespace(spacename); - i=1; - } - - /* All remaining arguments should either be using blocks or definition hashs */ - while (i < arguments.length) { - var res = arguments[i++]; - - // If it's a function, call it - either it's a using block or it's a namespaced entwine definition - if ($.isFunction(res)) { - if (res.length != 1) $.entwine.warn('Function block inside entwine definition does not take $ argument properly', $.entwine.WARN_LEVEL_IMPORTANT); - res = res.call(namespace.$(this), namespace.$); - } - - // If we have a entwine definition hash, inject it into namespace - if (res) { - if (selector === null) selector = this.selector ? $.selector(this.selector) : false; - - if (selector) namespace.add(selector, res); - else $.entwine.warn('Entwine block given to entwine call without selector. Make sure you call $(selector).entwine when defining blocks', $.entwine.WARN_LEVEL_IMPORTANT); - } - } - - /* Finally, return the jQuery object 'this' refers to, wrapped in the new namespace */ - return namespace.$(this); - }, - - /** - * Calls the next most specific version of the current entwine method - */ - _super: function(){ - var rv, i = this.length; - while (i--) { - var el = this[0]; - rv = el.f(el, arguments, el.i); - } - return rv; - } - }); - -})(jQuery); -; - - -/* src/jquery.entwine.dommaybechanged.js */ - -(function($){ - - /** What to call to run a function 'soon'. Normally setTimeout, but for syncronous mode we override so soon === now */ - var runSoon = window.setTimeout; - - /** The timer handle for the asyncronous matching call */ - var check_id = null; - - /** Fire the change event. Only fires on the document node, so bind to that */ - var triggerEvent = function() { - $(document).triggerHandler('DOMMaybeChanged'); - check_id = null; - }; - - $.extend($.entwine, { - /** - * Make onmatch and onunmatch work in synchronous mode - that is, new elements will be detected immediately after - * the DOM manipulation that made them match. This is only really useful for during testing, since it's pretty slow - * (otherwise we'd make it the default). - */ - synchronous_mode: function() { - if (check_id) clearTimeout(check_id); check_id = null; - runSoon = function(func, delay){ func.call(this); return null; }; - }, - - /** - * Trigger onmatch and onunmatch now - usefull for after DOM manipulation by methods other than through jQuery. - * Called automatically on document.ready - */ - triggerMatching: function() { - matching(); - } - }); - - function registerMutateFunction() { - $.each(arguments, function(i,func){ - var old = $.fn[func]; - $.fn[func] = function() { - var rv = old.apply(this, arguments); - if (!check_id) check_id = runSoon(triggerEvent, 100); - return rv; - }; - }); - } - - function registerSetterGetterFunction() { - $.each(arguments, function(i,func){ - var old = $.fn[func]; - $.fn[func] = function(a, b) { - var rv = old.apply(this, arguments); - if (!check_id && (b !== undefined || typeof a != 'string')) check_id = runSoon(triggerEvent, 100); - return rv; - }; - }); - } - - // Register core DOM manipulation methods - registerMutateFunction('append', 'prepend', 'after', 'before', 'wrap', 'removeAttr', 'addClass', 'removeClass', 'toggleClass', 'empty', 'remove'); - registerSetterGetterFunction('attr'); - - // And on DOM ready, trigger matching once - $(function(){ triggerEvent(); }); - -})(jQuery);; - - -/* src/jquery.entwine.events.js */ - -(function($) { - - /* If we are any browser other than IE or Safari, we don't have to do anything special to handle - * onchange delegation */ - $.support.bubblingChange = !($.browser.msie || $.browser.safari); - - /* Return true if node b is the same as, or is a descendant of, node a */ - if (document.compareDocumentPosition) { - var is_or_contains = function(a, b) { - return a && b && (a == b || !!(a.compareDocumentPosition(b) & 16)); - }; - } - else { - var is_or_contains = function(a, b) { - return a && b && (a == b || (a.contains ? a.contains(b) : true)); - }; - } - - /* Add the methods to handle event binding to the Namespace class */ - $.entwine.Namespace.addMethods({ - build_event_proxy: function(name) { - var one = this.one(name, 'func'); - - var prxy = function(e, data) { - // For events that do not bubble we manually trigger delegation (see delegate_submit below) - // If this event is a manual trigger, the event we actually want to bubble is attached as a property of the passed event - e = e.delegatedEvent || e; - - var el = e.target; - while (el && el.nodeType == 1 && !e.isPropagationStopped()) { - var ret = one(el, arguments); - if (ret !== undefined) e.result = ret; - if (ret === false) { e.preventDefault(); e.stopPropagation(); } - - el = el.parentNode; - } - }; - - return prxy; - }, - - build_mouseenterleave_proxy: function(name) { - var one = this.one(name, 'func'); - - var prxy = function(e) { - var el = e.target; - var rel = e.relatedTarget; - - while (el && el.nodeType == 1 && !e.isPropagationStopped()) { - /* We know el contained target. If it also contains relatedTarget then we didn't mouseenter / leave. What's more, every ancestor will also - contan el and rel, and so we can just stop bubbling */ - if (is_or_contains(el, rel)) break; - - var ret = one(el, arguments); - if (ret !== undefined) e.result = ret; - if (ret === false) { e.preventDefault(); e.stopPropagation(); } - - el = el.parentNode; - } - }; - - return prxy; - }, - - build_change_proxy: function(name) { - var one = this.one(name, 'func'); - - var prxy = function(e) { - var el = e.target; - // If this is a keydown event, only worry about the enter key, since browsers only trigger onchange on enter or focus loss - if (e.type === 'keydown' && e.keyCode !== 13) return; - // Make sure this is event is for an input type we're interested in - if (el.tagName !== 'INPUT' && el.tagName !== 'TEXTAREA' && el.tagName !== 'SELECT') return; - - var $el = $(el), nowVal, oldVal = $el.data('changeVal'); - - // Detect changes on checkboxes & radiobuttons, which have different value logic. We don't use el.value, since el is part - // of a set, and we only want to raise onchange once for a single user action. - if (el.type == 'checkbox' || el.type == 'radio') { - if (!el.disabled && e.type === 'click') { - nowVal = el.checked; - // If radio, we get two changes - the activation, and the deactivation. We only want to fire one change though - if ((el.type === 'checkbox' || nowVal === true) && oldVal !== nowVal) e.type = 'change'; - } - } - // Detect changes on other input types. In this case value is OK. - else { - nowVal = el.value; - if (oldVal !== undefined && oldVal !== nowVal) e.type = 'change'; - } - - // Save the current value for next time - if (nowVal !== undefined) $el.data('changeVal', nowVal); - - // And if we decided that a change happened, do the actual triggering - if (e.type == 'change') { - while (el && el.nodeType == 1 && !e.isPropagationStopped()) { - var ret = one(el, arguments); - if (ret !== undefined) e.result = ret; - if (ret === false) { e.preventDefault(); e.stopPropagation(); } - - el = el.parentNode; - } - } - }; - - return prxy; - }, - - bind_event: function(selector, name, func, event) { - var funcs = this.store[name] || (this.store[name] = $.entwine.RuleList()) ; - var proxies = funcs.proxies || (funcs.proxies = {}); - - var rule = funcs.addRule(selector, name); rule.func = func; - - if (!proxies[name]) { - switch (name) { - case 'onmouseenter': - proxies[name] = this.build_mouseenterleave_proxy(name); - event = 'mouseover'; - break; - case 'onmouseleave': - proxies[name] = this.build_mouseenterleave_proxy(name); - event = 'mouseout'; - break; - case 'onchange': - if (!$.support.bubblingChange) { - proxies[name] = this.build_change_proxy(name); - event = 'click focusin focusout keydown'; - } - break; - case 'onsubmit': - event = 'delegatedSubmit'; - break; - case 'onfocus': - case 'onblur': - $.entwine.warn('Event '+event+' not supported - using focusin / focusout instead', $.entwine.WARN_LEVEL_IMPORTANT); - } - - // If none of the special handlers created a proxy, use the generic proxy - if (!proxies[name]) proxies[name] = this.build_event_proxy(name); - - $(document).bind(event+'.entwine', proxies[name]); - } - } - }); - - $.entwine.Namespace.addHandler({ - order: 40, - - bind: function(selector, k, v){ - var match, event; - if ($.isFunction(v) && (match = k.match(/^on(.*)/))) { - event = match[1]; - this.bind_event(selector, k, v, event); - return true; - } - } - }); - - // Find all forms and bind onsubmit to trigger on the document too. - // This is the only event that can't be grabbed via delegation - - var form_binding_cache = $([]); // A cache for already-handled form elements - var delegate_submit = function(e, data){ - var delegationEvent = $.Event('delegatedSubmit'); delegationEvent.delegatedEvent = e; - return $(document).trigger(delegationEvent, data); - }; - - $(document).bind('DOMMaybeChanged', function(){ - var forms = $('form'); - // Only bind to forms we haven't processed yet - forms.not(form_binding_cache).bind('submit', delegate_submit); - // Then remember the current set of forms - form_binding_cache = forms; - }); - -})(jQuery); - ; - - -/* src/jquery.entwine.ctors.js */ - -(function($) { - - /* Add the methods to handle constructor & destructor binding to the Namespace class */ - $.entwine.Namespace.addMethods({ - bind_condesc: function(selector, name, func) { - var ctors = this.store.ctors || (this.store.ctors = $.entwine.RuleList()) ; - - var rule; - for (var i = 0 ; i < ctors.length; i++) { - if (ctors[i].selector.selector == selector.selector) { - rule = ctors[i]; break; - } - } - if (!rule) { - rule = ctors.addRule(selector, 'ctors'); - } - - rule[name] = func; - - if (!ctors[name+'proxy']) { - var one = this.one('ctors', name); - var namespace = this; - - var proxy = function(els, i, func) { - var j = els.length; - while (j--) { - var el = els[j]; - - var tmp_i = el.i, tmp_f = el.f; - el.i = i; el.f = one; - - try { func.call(namespace.$(el)); } - catch(e) { $.entwine.warn_exception(name, el, e); } - finally { el.i = tmp_i; el.f = tmp_f; } - } - }; - - ctors[name+'proxy'] = proxy; - } - } - }); - - $.entwine.Namespace.addHandler({ - order: 30, - - bind: function(selector, k, v) { - if ($.isFunction(v) && (k == 'onmatch' || k == 'onunmatch')) { - this.bind_condesc(selector, k, v); - return true; - } - } - }); - - /** - * Finds all the elements that now match a different rule (or have been removed) and call onmatch on onunmatch as appropriate - * - * Because this has to scan the DOM, and is therefore fairly slow, this is normally triggered off a short timeout, so that - * a series of DOM manipulations will only trigger this once. - * - * The downside of this is that things like: - * $('#foo').addClass('tabs'); $('#foo').tabFunctionBar(); - * won't work. - */ - $(document).bind('DOMMaybeChanged', function(){ - // For every namespace - for (var k in $.entwine.namespaces) { - // That has constructors or destructors - var ctors = $.entwine.namespaces[k].store.ctors; - if (ctors) { - - // Keep a record of elements that have matched already - var matched = $([]), add, rem, res, rule, sel, ctor, dtor; - // Stepping through each selector from most to least specific - var j = ctors.length; - while (j--) { - // Build some quick-access variables - rule = ctors[j]; - sel = rule.selector.selector; - ctor = rule.onmatch; - dtor = rule.onunmatch; - - // Get the list of elements that match this selector, that haven't yet matched a more specific selector - res = add = $(sel).not(matched); - - // If this selector has a list of elements it matched against last time - if (rule.cache) { - // Find the ones that are extra this time - add = res.not(rule.cache); - if (dtor) { - // Find the ones that are gone this time - rem = rule.cache.not(res); - // And call the destructor on them - if (rem.length) ctors.onunmatchproxy(rem, j, dtor); - } - } - - // Call the constructor on the newly matched ones - if (add.length && ctor) ctors.onmatchproxy(add, j, ctor); - - // Add these matched ones to the list tracking all elements matched so far - matched = matched.add(res); - // And remember this list of matching elements again this selector, so next matching we can find the unmatched ones - ctors[j].cache = res; - } - } - } - }); - - -})(jQuery); -; - - -/* src/jquery.entwine.properties.js */ - -(function($) { - - var entwine_prepend = '__entwine!'; - - var getEntwineData = function(el, namespace, property) { - return el.data(entwine_prepend + namespace + '!' + property); - }; - - var setEntwineData = function(el, namespace, property, value) { - return el.data(entwine_prepend + namespace + '!' + property, value); - }; - - var getEntwineDataAsHash = function(el, namespace) { - var hash = {}; - var id = jQuery.data(el[0]); - - var matchstr = entwine_prepend + namespace + '!'; - var matchlen = matchstr.length; - - var cache = jQuery.cache[id]; - for (var k in cache) { - if (k.substr(0,matchlen) == matchstr) hash[k.substr(matchlen)] = cache[k]; - } - - return hash; - }; - - var setEntwineDataFromHash = function(el, namespace, hash) { - for (var k in hash) setEntwineData(namespace, k, hash[k]); - }; - - var entwineData = function(el, namespace, args) { - switch (args.length) { - case 0: - return getEntwineDataAsHash(el, namespace); - case 1: - if (typeof args[0] == 'string') return getEntwineData(el, namespace, args[0]); - else return setEntwineDataFromHash(el, namespace, args[0]); - default: - return setEntwineData(el, namespace, args[0], args[1]); - } - }; - - $.extend($.fn, { - entwineData: function() { - return entwineData(this, '__base', arguments); - } - }); - - $.entwine.Namespace.addHandler({ - order: 60, - - bind: function(selector, k, v) { - if (k.charAt(0) != k.charAt(0).toUpperCase()) $.entwine.warn('Entwine property '+k+' does not start with a capital letter', $.entwine.WARN_LEVEL_BESTPRACTISE); - - // Create the getters and setters - - var getterName = 'get'+k; - var setterName = 'set'+k; - - this.bind_proxy(selector, getterName, function() { return this.entwineData(k) || v ; }); - this.bind_proxy(selector, setterName, function(v){ return this.entwineData(k, v); }); - - // Get the get and set proxies we just created - - var getter = this.injectee[getterName]; - var setter = this.injectee[setterName]; - - // And bind in the jQuery-style accessor - - this.bind_proxy(selector, k, function(v){ return (arguments.length == 1 ? setter : getter).call(this, v) ; }); - - return true; - }, - - namespaceMethodOverrides: function(namespace){ - return { - entwineData: function() { - return entwineData(this, namespace.name, arguments); - } - }; - } - }); - -})(jQuery); -; - - -/* src/jquery.entwine.legacy.js */ - -(function($) { - - // Adds back concrete methods for backwards compatibility - $.concrete = $.entwine; - $.fn.concrete = $.fn.entwine; - $.fn.concreteData = $.fn.entwineData; - - // Use addHandler to hack in the namespace.$.concrete equivilent to the namespace.$.entwine namespace-injection - $.entwine.Namespace.addHandler({ - order: 100, - bind: function(selector, k, v) { return false; }, - - namespaceMethodOverrides: function(namespace){ - namespace.$.concrete = namespace.$.entwine; - namespace.injectee.concrete = namespace.injectee.entwine; - namespace.injectee.concreteData = namespace.injectee.entwineData; - return {}; - } - }); - -})(jQuery); -; - diff --git a/thirdparty/jquery-entwine/dist/jquery.concrete-dist.js b/thirdparty/jquery-entwine/dist/jquery.concrete-dist.js new file mode 120000 index 000000000..69348f3cd --- /dev/null +++ b/thirdparty/jquery-entwine/dist/jquery.concrete-dist.js @@ -0,0 +1 @@ +jquery.entwine-dist.js \ No newline at end of file diff --git a/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js b/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js index 7e8822eb7..092c4484a 100644 --- a/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js +++ b/thirdparty/jquery-entwine/dist/jquery.entwine-dist.js @@ -1,4 +1,4 @@ -/* jQuery.Entwine - Copyright 2009 Hamish Friedlander and SilverStripe. Version . */ +/* jQuery.Entwine - Copyright 2009-2011 Hamish Friedlander and SilverStripe. Version . */ /* vendor/jquery.selector/jquery.class.js */ @@ -774,7 +774,7 @@ var console; */ clear_all_rules: function() { // Remove proxy functions - for (var k in $.fn) { if ($.fn[k].entwine) delete $.fn[k] ; } + for (var k in $.fn) { if ($.fn[k].isentwinemethod) delete $.fn[k]; } // Remove bound events - TODO: Make this pluggable, so this code can be moved to jquery.entwine.events.js $(document).unbind('.entwine'); // Remove namespaces, and start over again @@ -870,38 +870,48 @@ var console; } else { // We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into - var subfn = function(){}; - this.injectee = subfn.prototype = new $(); - // And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building - var bound$ = this.$ = function(a) { - // Try the simple way first - var jq = $.fn.init.apply(new subfn(), arguments); - if (jq instanceof subfn) return jq; + // jQuery 1.5 already provides a nice way to subclass, so use it + if ($.sub) { + this.$ = $.sub(); + this.injectee = this.$.prototype; + } + // For jQuery < 1.5 we have to do it ourselves + else { + var subfn = function(){}; + this.injectee = subfn.prototype = new $; + + // And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building + var bound$ = this.$ = function(a) { + // Try the simple way first + var jq = $.fn.init.apply(new subfn(), arguments); + if (jq instanceof subfn) return jq; - // That didn't return a bound object, so now we need to copy it - var rv = new subfn(); - rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length; - while (i--) rv[i] = jq[i]; - return rv; - }; - this.injectee.pushStack = function(elems, name, selector){ - var ret = bound$(elems); + // That didn't return a bound object, so now we need to copy it + var rv = new subfn(); + rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length; + while (i--) rv[i] = jq[i]; + return rv; + }; + + this.injectee.pushStack = function(elems, name, selector){ + var ret = bound$(elems); - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; - if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector; - else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")"; + if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector; + else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")"; - // Return the newly-formed element set - return ret; - }; + // Return the newly-formed element set + return ret; + }; - // Copy static functions through from $ to this.$ so e.g. $.ajax still works - // @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through - $.extend(this.$, $); + // Copy static functions through from $ to this.$ so e.g. $.ajax still works + // @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through + $.extend(this.$, $); + } // We override entwine to inject the name of this namespace when defining blocks inside this namespace var entwine_wrapper = this.injectee.entwine = function(spacename) { @@ -989,12 +999,12 @@ var console; var rule = rulelist.addRule(selector, name); rule.func = func; - if (!this.injectee.hasOwnProperty(name) || !this.injectee[name].entwine) { + if (!this.injectee.hasOwnProperty(name) || !this.injectee[name].isentwinemethod) { this.injectee[name] = this.build_proxy(name, this.injectee.hasOwnProperty(name) ? this.injectee[name] : null); - this.injectee[name].entwine = true; + this.injectee[name].isentwinemethod = true; } - if (!this.injectee[name].entwine) { + if (!this.injectee[name].isentwinemethod) { $.entwine.warn('Warning: Entwine function '+name+' clashes with regular jQuery function - entwine function will not be callable directly on jQuery object', $.entwine.WARN_LEVEL_IMPORTANT); } }, diff --git a/thirdparty/jquery-entwine/spec/SpecRunner.html b/thirdparty/jquery-entwine/spec/SpecRunner.html new file mode 100644 index 000000000..2a4d6ddd8 --- /dev/null +++ b/thirdparty/jquery-entwine/spec/SpecRunner.html @@ -0,0 +1,42 @@ + + + + Jasmine Test Runner + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/thirdparty/jquery-entwine/spec/legacy/spec-dist.html b/thirdparty/jquery-entwine/spec/legacy/spec-dist.html deleted file mode 100644 index 9c238603e..000000000 --- a/thirdparty/jquery-entwine/spec/legacy/spec-dist.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - -

JSpec

-
-
- - \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.basics.js b/thirdparty/jquery-entwine/spec/legacy/spec.concrete.basics.js deleted file mode 100644 index 7b0c23a1f..000000000 --- a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.basics.js +++ /dev/null @@ -1,85 +0,0 @@ - -describe 'Concrete' - describe 'Basics' - before - $.concrete.warningLevel = $.concrete.WARN_LEVEL_BESTPRACTISE; - $('body').append('
'); - end - after - $('#dom_test').remove(); - end - - before_each - $.concrete.clear_all_rules(); - $('#dom_test').html('
'); - end - - it 'can attach and call a base function' - $('#a').concrete({ - foo: function(){return this.attr('id');} - }); - $('.a').foo().should.equal 'a' - end - - it 'can attach and call a base function on a selector using a data attribute selection' - $('[data-fieldtype=foo]').concrete({ - foo: function(){return this.attr('id');} - }); - $('.a').foo().should.equal 'a' - end - - it 'can attach and call several base functions' - $('#a').concrete({ - foo: function(){return 'foo_' + this.attr('id');}, - bar: function(){return 'bar_' + this.attr('id');} - }); - $('.a').foo().should.equal 'foo_a' - $('.a').bar().should.equal 'bar_a' - end - - it 'can attach and call a namespaced function' - $.concrete('bar', function($){ - $('#a').concrete({ - foo: function(){return this.attr('id');} - }); - }); - $('.a').concrete('bar').foo().should.equal 'a' - end - - it 'can attach and call a nested namespaced function' - $.concrete('qux.baz.bar', function($){ - $('#a').concrete({ - foo: function(){return this.attr('id');} - }); - }); - $('.a').concrete('qux.baz.bar').foo().should.equal 'a' - end - - it 'can call two functions on two elements' - var res = [] - $('#a').concrete({ - foo: function(){res.push(this.attr('id'));} - }); - $('#b.c').concrete({ - foo: function(){res.push(this.attr('id'));} - }); - $('#dom_test div').foo(); - res.should.eql ['b', 'a'] - end - - it 'can call two namespaced functions on two elements' - var res = [] - $.concrete('bar', function($){ - $('#a').concrete({ - foo: function(){res.push(this.attr('id'));} - }); - $('#b.c').concrete({ - foo: function(){res.push(this.attr('id'));} - }); - }); - $('#dom_test div').concrete('bar').foo(); - res.should.eql ['b', 'a'] - end - - end -end diff --git a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.ctors.js b/thirdparty/jquery-entwine/spec/legacy/spec.concrete.ctors.js deleted file mode 100644 index d0025318b..000000000 --- a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.ctors.js +++ /dev/null @@ -1,68 +0,0 @@ -describe 'Concrete' - describe 'Ctors' - - before - $('body').append('
') - end - - after - $('#dom_test').remove() - end - - before_each - $.concrete.synchronous_mode(); - $.concrete.clear_all_rules() - $('#dom_test').html('
') - end - - it 'calls onmatch when new element created' - var a = false; - $('#b').concrete({onmatch: function(){a = true;} }); - a.should.be_false - $('#a').after('
'); - a.should.be_true - end - - it 'calls onunmatch when new element deleted' - var a = 0; - $('#b').concrete({onmatch: function(){a = 1;}, onunmatch: function(){a = 2;} }); - a.should.equal 0 - $('#a').after('
'); - a.should.equal 1 - $('#b').remove(); - a.should.equal 2 - end - - it 'calls onmatch when ruleset matches after class added' - var a = 0; - $('#a.foo').concrete({onmatch: function(){a = 1;} }); - a.should.equal 0 - $('#a').addClass('foo'); - a.should.equal 1 - end - - it 'calls onmatch in both direct and namespaced onmatch, does not call less specific onmatch' - var a = 0, b=0, c=0, d=0; - $('.foo').concrete({onmatch: function(){a = 1;}}) - $('.foo').concrete('bar', function($){return{onmatch: function(){b = 1;}}}) - $('#a.foo').concrete({onmatch: function(){c = 1;}}) - $('#a.foo').concrete('bar', function($){return{onmatch: function(){d = 1}}}) - [a, b, c, d].should.eql [0, 0, 0, 0] - $('#a').addClass('foo'); - [a, b, c, d].should.eql [0, 0, 1, 1] - end - - it 'calls onmatch in both direct and namespaced onmatch, super works as expected' - var a = 0, b=0, c=0, d=0; - $('.foo').concrete({onmatch: function(){a += 1;}}) - $('.foo').concrete('bar', function($){return{onmatch: function(){b += 1;}}}) - $('#a.foo').concrete({onmatch: function(){this._super(); c = 1; this._super();}}) - $('#a.foo').concrete('bar', function($){return{onmatch: function(){this._super(); d = 1; this._super();}}}) - [a, b, c, d].should.eql [0, 0, 0, 0] - $('#a').addClass('foo'); - [a, b, c, d].should.eql [2, 2, 1, 1] - end - - - end -end \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.events.js b/thirdparty/jquery-entwine/spec/legacy/spec.concrete.events.js deleted file mode 100644 index 2a90f8d46..000000000 --- a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.events.js +++ /dev/null @@ -1,112 +0,0 @@ -describe 'Concrete' - describe 'Events' - - before - $('body').append('
') - end - - after - $('#dom_test').remove() - end - - before_each - $.concrete.synchronous_mode(); - $.concrete.clear_all_rules() - $('#dom_test').html('
') - end - - it 'calls onfoo when foo triggered' - var a = 0; - $('#a').concrete({onfoo: function(){a = 1;} }); - a.should.equal 0 - $('#a').trigger('foo'); - a.should.equal 1 - end - - it 'only calls most specific onfoo when foo triggered' - var a = 0, b = 0; - $('#a.a').concrete({onfoo: function(){a = 1;} }); - $('#a').concrete({onfoo: function(){b = 1;} }); - a.should.equal 0 - b.should.equal 0 - $('#a').trigger('foo'); - a.should.equal 1 - b.should.equal 0 - end - - it 'calls namespaced onfoo when foo triggered' - var a = 0; - $('#a').concrete('bar', function($){return{onfoo: function(){a = 1;} }}); - a.should.equal 0 - $('#a').trigger('foo'); - a.should.equal 1 - end - - it 'calls most specific namespaced onfoo and most specific non-namespaced onfoo when foo triggered' - var a = 0, b = 0, c = 0, d = 0; - $('#a.a').concrete({onfoo: function(){a = 1;} }); - $('#a').concrete({onfoo: function(){b = 1;} }); - $('#a.a').concrete('bar', function($){return{onfoo: function(){c = 1;} }}); - $('#a').concrete('bar', function($){return{onfoo: function(){d = 1;} }}); - [a, b, c, d].should.eql [0, 0, 0, 0] - - $('#a').trigger('foo'); - [a, b, c, d].should.eql [1, 0, 1, 0] - end - - it 'calls up correctly on _super' - var a = 0, b = 0; - $('#a').concrete({onfoo: function(){a += 1;} }); - $('#a.a').concrete({onfoo: function(){this._super(); b += 1; this._super();} }); - - [a, b].should.eql [0, 0] - $('#a').trigger('foo') - [a, b].should.eql [2, 1] - end - - it 'passes event object' - var event; - $('#a').concrete({onfoo: function(e){event = e;} }); - $('#a').trigger('foo'); - event.should.have_prop 'type', 'foo' - $(event.target).should.have_attr 'id', 'a' - end - - it 'delegates submit events to forms' - var a = 0; - $('
').appendTo('#dom_test'); - - $('.foo').concrete({onsubmit: function(e, d){a = 1;} }); - - a.should.eql 0 - $('.foo').trigger('submit'); - a.should.eql 1 - end - - describe 'can pass event data' - it 'on custom events' - var data; - $('#a').concrete({onfoo: function(e, d){data = d;} }); - $('#a').trigger('foo', {cheese: 'burger'}); - data.cheese.should.eql 'burger' - end - - it 'on normal events' - var data; - $('#a').concrete({onclick: function(e, d){data = d;} }); - $('#a').trigger('click', {finger: 'left'}); - data.finger.should.eql 'left' - end - - it 'on submit' - var data; - - $('').appendTo('#dom_test'); - $('.foo').concrete({onsubmit: function(e, d){data = d; return false;} }) - - $('.foo').trigger('submit', {cheese: 'burger'}); - data.cheese.should.eql 'burger' - end - end - end -end \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.namespaces.js b/thirdparty/jquery-entwine/spec/legacy/spec.concrete.namespaces.js deleted file mode 100644 index 5f99bad51..000000000 --- a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.namespaces.js +++ /dev/null @@ -1,246 +0,0 @@ - -describe 'Concrete' - describe 'Namespaces' - before - $('body').append('
') - end - after - $('#dom_test').remove() - end - - before_each - $.concrete.synchronous_mode(); - $.concrete.clear_all_rules() - $('#dom_test').html('
') - end - - it 'namespaced functions work (single definition mode)' - $('#a').concrete('bar', function($){return{ - bar: function(){return 'a';} - }}) - $('#a').concrete('bar').bar().should.equal 'a' - end - - it 'namespaced functions work (block definition mode)' - $.concrete('zap', function($){ - $('#a').concrete({ - bar: function(){return 'a';} - }) - }); - $('#a').concrete('zap').bar().should.equal 'a' - end - - it 'double-namespaced functions work (block definition mode)' - $.concrete('zap', function($){ - $.concrete('pow', function($){ - $('#a').concrete({ - bar: function(){return 'a';} - }) - }) - }) - $('#a').concrete('zap.pow').bar().should.equal 'a' - end - - it 'revert to base namespacing work (block definition mode)' - $.concrete('zap', function($){ - $.concrete('.pow', function($){ - $('#a').concrete({ - bar: function(){return 'a';} - }) - }) - }) - $('#a').concrete('pow').bar().should.equal 'a' - end - - it 'internal to namespace, will look up functions in namespace before in base' - var res = [] - $('#a').concrete({ - foo: function(){res.push(1);}, - bar: function(){res.push(2); this.foo();} - }) - $('#a').concrete('bar', function($){return{ - foo: function(){res.push(3);}, - bar: function(){res.push(4); $(this).foo();} - }}) - - $('#dom_test div').bar(); - res.should.eql [2, 1] - $('#dom_test div').concrete('bar').bar(); - res.should.eql [2, 1, 4, 3] - end - - it 'internal to namespace, will look up functions in namespace before in base, even in closure' - var res = [] - $('#a').concrete({ - foo: function(){res.push(1);}, - bar: function(){res.push(2); this.foo();} - }) - $('#a').concrete('bar', function($){return{ - foo: function(){res.push(3);}, - bar: function(){res.push(4); $('#a').each(function(){ $(this).foo(); })} - }}) - - $('#dom_test div').bar(); - res.should.eql [2, 1] - $('#dom_test div').concrete('bar').bar(); - res.should.eql [2, 1, 4, 3] - end - - it 'internal to namespace, will look up functions in namespace before in base, even in onmatch' - var res = [] - $('#a').concrete({ - foo: function(){res.push(1);}, - bar: function(){res.push(2); this.foo();} - }) - $('#a').concrete('bar', function($){return{ - foo: function(){res.push(3);} - }}) - $('#a.d').concrete('bar', function($){return{ - onmatch: function(){res.push(4); this.foo();} - }}) - - $('#dom_test div').bar(); - res.should.eql [2, 1] - - $('#a').addClass('d'); - res.should.eql [2, 1, 4, 3] - end - - it 'internal to namespace, will look up functions in base when not present in namespace' - var res = [] - $('#a').concrete({ - foo: function(){res.push(1);} - }) - $('#a').concrete('bar', function($){return{ - bar: function(){res.push(2); this.foo();} - }}) - $('#dom_test div').concrete('bar').bar(); - res.should.eql [2, 1] - end - - it 'internal to namespace, will not look up functions in base if present in namespace, even when not applicable to selector' - var res = [] - $('#a').concrete('bar', function($){return{ - foo: function(){this.bar();} - }}) - $('#a').concrete({ - bar: function(){res.push(1);} - }) - $('span').concrete('bar', function($){return{ - bar: function(){res.push(2);} - }}) - - $('#a').concrete('bar').foo() - res.should.eql [] - end - - it 'internal to namespace, can be directed to base namespace' - var res = [] - $('#a').concrete({ - foo: function(){res.push(1);}, - bar: function(){res.push(2); this.foo();} - }) - $('#a').concrete('bar', function($){return{ - foo: function(){res.push(3);}, - bar: function(){res.push(4); this.foo(); this.concrete('.').foo();} - }}) - $('#dom_test div').bar(); - res.should.eql [2, 1] - $('#dom_test div').concrete('bar').bar(); - res.should.eql [2, 1, 4, 3, 1] - end - - it 'internal to namespace, will look up functions in namespace called the same as a regular jQuery base function' - var res = [] - $('#a').concrete('bar', function($){return{ - load: function(){res.push(1);}, - bar: function(){res.push(2); this.load();} - }}) - $('#dom_test div').concrete('bar').bar(); - res.should.eql [2, 1] - end - - it 'internal to namespace, can be directed to regular jQuery base function' - var res = [] - $.fn.testy = function(){ res.push(1); } - $('#a').concrete('bar', function($){return{ - testy: function(){res.push(3);}, - bar: function(){res.push(2); this.concrete('.').testy();} - }}) - $('#dom_test div').concrete('bar').bar(); - res.should.eql [2, 1] - end - - it 'internal to namespace, can be directed to sub namespace' - var res = [] - $.concrete('zap', function($){ - $('#a').concrete({ - foo: function(){ res.push(1); this.concrete('pow').bar(); } - }) - - $.concrete('pow', function($){ - $('#a').concrete({ - bar: function(){ res.push(2); } - }) - }) - }) - $('#dom_test div').concrete('zap').foo(); - res.should.eql [1, 2] - end - - it 'internal to namespace, can be directed to unrelated namespace' - var res = [] - $.concrete('zap', function($){ - $('#a').concrete({ - foo: function(){ res.push(1); this.concrete('.pow').bar(); } - }) - - $.concrete('pow', function($){ - $('#a').concrete({ - bar: function(){ res.push(2); } - }) - }) - }) - $.concrete('pow', function($){ - $('#a').concrete({ - bar: function(){ res.push(3); } - }) - }) - - $('#dom_test div').concrete('zap').foo(); - res.should.eql [1, 3] - end - - it 'a function passed out of a namespace will remember its namespace' - var res = [] - var func = function(func) { - func.call($('#a, #b')); - } - $('#a, #b').concrete('bar', function($){return{ - zap: function(){res.push($(this).attr('id'));}, - bar: function(){res.push(2); func(this.zap);} - }}) - $('#dom_test #a').concrete('bar').bar(); - res.should.eql [2, 'b', 'a'] - end - - it 'using block functions' - var res = [] - $('#a').concrete({ - foo: function(){res.push(1);} - }) - $('#a').concrete('bar', function($){return{ - foo: function(){res.push(3);} - }}) - - $('#dom_test div').foo(); - res.should.eql [1] - - $('#dom_test div').concrete('bar', function($){ - $(this).foo(); - }) - res.should.eql [1, 3] - end - - end -end diff --git a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.properties.js b/thirdparty/jquery-entwine/spec/legacy/spec.concrete.properties.js deleted file mode 100644 index 978ae2694..000000000 --- a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.properties.js +++ /dev/null @@ -1,102 +0,0 @@ - -describe 'Concrete' - describe 'Properties' - before - $('body').append('
') - end - after - $('#dom_test').remove() - end - - before_each - $.concrete.clear_all_rules() - $('#dom_test').html('
') - end - - it 'can define and get a basic property' - $('#a').concrete({ - Foo: null - }); - $('.a').getFoo().should.be_null - end - - it 'can define and set a basic property' - $('#a').concrete({ - Foo: null - }); - $('.a').setFoo(1); - $('.a').getFoo().should.equal 1 - end - - it 'can define a default value' - $('#a').concrete({ - Foo: 1 - }); - $('.a').getFoo().should.equal 1 - end - - it 'should manage proprties in namespaces without clashing' - $('#a').concrete({ - Foo: 1 - }); - - $.concrete('test', function($){ - $('#a').concrete({ - Foo: 2 - }); - }); - - $('.a').getFoo().should.equal 1 - $('.a').concrete('test').getFoo().should.equal 2 - - $('.a').setFoo(4); - $('.a').concrete('test').setFoo(8); - - $('.a').getFoo().should.equal 4 - $('.a').concrete('test').getFoo().should.equal 8 - end - - it 'should manage directly setting proprties in namespaces without clashing' - $('#a').concrete({ - Foo: null - }); - - $.concrete('test', function($){ - $('#a').concrete({ - Foo: null - }); - }); - - $('.a').concreteData('Foo', 4); - $('.a').concrete('test').concreteData('Foo', 8); - - $('.a').concreteData('Foo').should.equal 4 - $('.a').concrete('test').concreteData('Foo').should.equal 8 - end - - describe 'jQuery style accessors' - it 'can define and get a basic property' - $('#a').concrete({ - Foo: null - }); - $('.a').Foo().should.be_null - end - - it 'can define and set a basic property' - $('#a').concrete({ - Foo: null - }); - $('.a').Foo(1); - $('.a').Foo().should.equal 1 - end - - it 'can define a default value' - $('#a').concrete({ - Foo: 1 - }); - $('.a').Foo().should.equal 1 - end - end - - end -end diff --git a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.super.js b/thirdparty/jquery-entwine/spec/legacy/spec.concrete.super.js deleted file mode 100644 index 83212242b..000000000 --- a/thirdparty/jquery-entwine/spec/legacy/spec.concrete.super.js +++ /dev/null @@ -1,66 +0,0 @@ - -describe 'Concrete' - describe 'Super' - before - $('body').append('
') - end - after - $('#dom_test').remove() - end - - before_each - $.concrete.clear_all_rules() - $('#dom_test').html('
Foo
Bar
') - end - - it 'can call the super function' - var a = 1; - $('#a').concrete({ - foo: function(){a *= 2;} - }); - $('#a.a').concrete({ - foo: function(){a += 2; this._super();} - }); - $('#a').foo(); - a.should.equal 6 - end - - it 'super to a non-existant class should be ignored' - var a = 1; - $('#a').concrete({ - foo: function(){a *= 2; this._super();} - }); - $('#a.a').concrete({ - foo: function(){a += 2; this._super();} - }); - $('#a').foo(); - a.should.equal 6 - end - - it 'can call super from two different functions without screwing up what super points to' - var list = []; - $('#a').concrete({ - foo: function(){ list.push('foo'); this.bar(); }, - bar: function(){ list.push('bar'); } - }); - $('#a.a').concrete({ - foo: function(){ list.push('foo2'); this._super(); list.push('foo2'); this._super(); }, - bar: function(){ list.push('bar2'); this._super(); } - }); - $('#a').foo(); - list.should.eql [ 'foo2', 'foo', 'bar2', 'bar', 'foo2', 'foo', 'bar2', 'bar' ] - end - - it 'can override (and call via super) a non-concrete jquery function' - var a = 1 - $('#a').concrete({ - text: function(){ a = this._super(); } - }); - - $('#a').text(); - a.should.equal 'Foo' - - $('#b').text().should.equal 'Bar' - end - end -end diff --git a/thirdparty/jquery-entwine/spec/legacy/spec.html b/thirdparty/jquery-entwine/spec/legacy/spec.html deleted file mode 100644 index 891b68d52..000000000 --- a/thirdparty/jquery-entwine/spec/legacy/spec.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - -

JSpec

-
-
- - \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/spec-dist.html b/thirdparty/jquery-entwine/spec/spec-dist.html deleted file mode 100644 index e093d77d9..000000000 --- a/thirdparty/jquery-entwine/spec/spec-dist.html +++ /dev/null @@ -1,30 +0,0 @@ - - - - - - - - - - - - - -

JSpec

-
-
- - \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/spec.entwine.basics.js b/thirdparty/jquery-entwine/spec/spec.entwine.basics.js index 204db1d85..f59b3bcd4 100644 --- a/thirdparty/jquery-entwine/spec/spec.entwine.basics.js +++ b/thirdparty/jquery-entwine/spec/spec.entwine.basics.js @@ -1,61 +1,63 @@ - -describe 'Entwine' - describe 'Basics' - before - $.entwine.warningLevel = $.entwine.WARN_LEVEL_BESTPRACTISE; - $('body').append('
'); - end - after - $('#dom_test').remove(); - end +describe( 'Entwine', function() { - before_each + beforeEach(function() { + $.entwine.warningLevel = $.entwine.WARN_LEVEL_BESTPRACTISE; + $('body').append('
'); + }); + + afterEach(function() { + $('#dom_test').remove(); + }); + + describe( 'Basics', function() { + + beforeEach(function() { $.entwine.clear_all_rules(); $('#dom_test').html('
'); - end + }); - it 'can attach and call a base function' + it( 'can attach and call a base function', function() { $('#a').entwine({ foo: function(){return this.attr('id');} }); - $('.a').foo().should.equal 'a' - end + expect($('.a').foo()).toEqual('a'); + }); - it 'can attach and call a base function on a selector using a data attribute selection' + it( 'can attach and call a base function on a selector using a data attribute selection', function() { $('[data-fieldtype=foo]').entwine({ foo: function(){return this.attr('id');} }); - $('.a').foo().should.equal 'a' - end - - it 'can attach and call several base functions' + expect($('.a').foo()).toEqual('a') ; + }); + + it( 'can attach and call several base functions', function() { $('#a').entwine({ foo: function(){return 'foo_' + this.attr('id');}, bar: function(){return 'bar_' + this.attr('id');} }); - $('.a').foo().should.equal 'foo_a' - $('.a').bar().should.equal 'bar_a' - end - - it 'can attach and call a namespaced function' + expect($('.a').foo()).toEqual( 'foo_a'); + expect($('.a').bar()).toEqual( 'bar_a'); + }); + + it( 'can attach and call a namespaced function', function() { $.entwine('bar', function($){ $('#a').entwine({ foo: function(){return this.attr('id');} }); }); - $('.a').entwine('bar').foo().should.equal 'a' - end - - it 'can attach and call a nested namespaced function' + expect($('.a').entwine('bar').foo()).toEqual( 'a'); + }); + + it( 'can attach and call a nested namespaced function', function() { $.entwine('qux.baz.bar', function($){ $('#a').entwine({ foo: function(){return this.attr('id');} }); }); - $('.a').entwine('qux.baz.bar').foo().should.equal 'a' - end - - it 'can call two functions on two elements' + expect($('.a').entwine('qux.baz.bar').foo()).toEqual( 'a'); + }); + + it( 'can call two functions on two elements', function() { var res = [] $('#a').entwine({ foo: function(){res.push(this.attr('id'));} @@ -64,10 +66,10 @@ describe 'Entwine' foo: function(){res.push(this.attr('id'));} }); $('#dom_test div').foo(); - res.should.eql ['b', 'a'] - end - - it 'can call two namespaced functions on two elements' + expect(res).toEqual( ['b', 'a']); + }); + + it( 'can call two namespaced functions on two elements', function() { var res = [] $.entwine('bar', function($){ $('#a').entwine({ @@ -78,8 +80,7 @@ describe 'Entwine' }); }); $('#dom_test div').entwine('bar').foo(); - res.should.eql ['b', 'a'] - end - - end -end + expect(res).toEqual( ['b', 'a']); + }); + }); +}); \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/spec.entwine.ctors.js b/thirdparty/jquery-entwine/spec/spec.entwine.ctors.js index 9abe98ad5..9128ddcee 100644 --- a/thirdparty/jquery-entwine/spec/spec.entwine.ctors.js +++ b/thirdparty/jquery-entwine/spec/spec.entwine.ctors.js @@ -1,68 +1,68 @@ -describe 'Entwine' - describe 'Ctors' - - before - $('body').append('
') - end +describe( 'Entwine', function() { - after - $('#dom_test').remove() - end - - before_each + beforeEach(function() { + $('body').append('
') + }); + + afterEach(function() { + $('#dom_test').remove() + }); + + describe( 'Ctors', function() { + + beforeEach(function() { $.entwine.synchronous_mode(); $.entwine.clear_all_rules() $('#dom_test').html('
') - end - - it 'calls onmatch when new element created' + }); + + it( 'calls onmatch when new element created', function() { var a = false; $('#b').entwine({onmatch: function(){a = true;} }); - a.should.be_false + expect(a).toBeFalsy(); $('#a').after('
'); - a.should.be_true - end - - it 'calls onunmatch when new element deleted' + expect(a).toBeTruthy(); + }); + + it( 'calls onunmatch when new element deleted', function() { var a = 0; $('#b').entwine({onmatch: function(){a = 1;}, onunmatch: function(){a = 2;} }); - a.should.equal 0 + expect(a).toEqual( 0); $('#a').after('
'); - a.should.equal 1 + expect(a).toEqual( 1); $('#b').remove(); - a.should.equal 2 - end - - it 'calls onmatch when ruleset matches after class added' + expect(a).toEqual( 2); + }); + + it( 'calls onmatch when ruleset matches after class added', function() { var a = 0; $('#a.foo').entwine({onmatch: function(){a = 1;} }); - a.should.equal 0 + expect(a).toEqual(0); $('#a').addClass('foo'); - a.should.equal 1 - end - - it 'calls onmatch in both direct and namespaced onmatch, does not call less specific onmatch' + expect(a).toEqual( 1); + }); + + it( 'calls onmatch in both direct and namespaced onmatch, does not call less specific onmatch', function() { var a = 0, b=0, c=0, d=0; $('.foo').entwine({onmatch: function(){a = 1;}}) - $('.foo').entwine('bar', function($){return{onmatch: function(){b = 1;}}}) + $('.foo').entwine('bar', function($){return{onmatch: function(){b = 1;}}}) $('#a.foo').entwine({onmatch: function(){c = 1;}}) - $('#a.foo').entwine('bar', function($){return{onmatch: function(){d = 1}}}) - [a, b, c, d].should.eql [0, 0, 0, 0] + $('#a.foo').entwine('bar', function($){return{onmatch: function(){d = 1}}}) + expect([a, b, c, d]).toEqual( [0, 0, 0, 0]); $('#a').addClass('foo'); - [a, b, c, d].should.eql [0, 0, 1, 1] - end - - it 'calls onmatch in both direct and namespaced onmatch, super works as expected' + expect([a, b, c, d]).toEqual( [0, 0, 1, 1]); + }); + + it( 'calls onmatch in both direct and namespaced onmatch, super works as expected', function() { var a = 0, b=0, c=0, d=0; $('.foo').entwine({onmatch: function(){a += 1;}}) - $('.foo').entwine('bar', function($){return{onmatch: function(){b += 1;}}}) + $('.foo').entwine('bar', function($){return{onmatch: function(){b += 1;}}}) $('#a.foo').entwine({onmatch: function(){this._super(); c = 1; this._super();}}) - $('#a.foo').entwine('bar', function($){return{onmatch: function(){this._super(); d = 1; this._super();}}}) - [a, b, c, d].should.eql [0, 0, 0, 0] + $('#a.foo').entwine('bar', function($){return{onmatch: function(){this._super(); d = 1; this._super();}}}) + expect([a, b, c, d]).toEqual( [0, 0, 0, 0]); $('#a').addClass('foo'); - [a, b, c, d].should.eql [2, 2, 1, 1] - end - - - end -end \ No newline at end of file + expect([a, b, c, d]).toEqual( [2, 2, 1, 1]); + }); + + }); +}); \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/spec.entwine.events.js b/thirdparty/jquery-entwine/spec/spec.entwine.events.js index 4d3cbbd0b..fa044ad95 100644 --- a/thirdparty/jquery-entwine/spec/spec.entwine.events.js +++ b/thirdparty/jquery-entwine/spec/spec.entwine.events.js @@ -1,112 +1,116 @@ -describe 'Entwine' - describe 'Events' +describe( 'Entwine', function() { - before - $('body').append('
') - end - - after - $('#dom_test').remove() - end - - before_each + beforeEach(function() { + $('body').append('
') + }); + + afterEach(function() { + $('#dom_test').remove() + }); + + describe( 'Events', function() { + + beforeEach(function() { $.entwine.synchronous_mode(); $.entwine.clear_all_rules() $('#dom_test').html('
') - end - - it 'calls onfoo when foo triggered' + }); + + it( 'calls onfoo when foo triggered', function() { var a = 0; $('#a').entwine({onfoo: function(){a = 1;} }); - a.should.equal 0 + expect(a).toEqual(0); $('#a').trigger('foo'); - a.should.equal 1 - end - - it 'only calls most specific onfoo when foo triggered' + expect(a).toEqual( 1); + }); + + it( 'only calls most specific onfoo when foo triggered', function() { var a = 0, b = 0; $('#a.a').entwine({onfoo: function(){a = 1;} }); $('#a').entwine({onfoo: function(){b = 1;} }); - a.should.equal 0 - b.should.equal 0 + expect(a).toEqual( 0); + expect(b).toEqual( 0); $('#a').trigger('foo'); - a.should.equal 1 - b.should.equal 0 - end - - it 'calls namespaced onfoo when foo triggered' + expect(a).toEqual( 1); + expect(b).toEqual( 0); + }); + + it( 'calls namespaced onfoo when foo triggered', function() { var a = 0; $('#a').entwine('bar', function($){return{onfoo: function(){a = 1;} }}); - a.should.equal 0 + expect(a).toEqual( 0); $('#a').trigger('foo'); - a.should.equal 1 - end - - it 'calls most specific namespaced onfoo and most specific non-namespaced onfoo when foo triggered' + expect(a).toEqual( 1); + }); + + it( 'calls most specific namespaced onfoo and most specific non-namespaced onfoo when foo triggered', function() { var a = 0, b = 0, c = 0, d = 0; $('#a.a').entwine({onfoo: function(){a = 1;} }); $('#a').entwine({onfoo: function(){b = 1;} }); $('#a.a').entwine('bar', function($){return{onfoo: function(){c = 1;} }}); $('#a').entwine('bar', function($){return{onfoo: function(){d = 1;} }}); - [a, b, c, d].should.eql [0, 0, 0, 0] + expect([a, b, c, d]).toEqual( [0, 0, 0, 0] ); $('#a').trigger('foo'); - [a, b, c, d].should.eql [1, 0, 1, 0] - end - - it 'calls up correctly on _super' + expect([a, b, c, d]).toEqual( [1, 0, 1, 0]); + }); + + it( 'calls up correctly on _super', function() { var a = 0, b = 0; $('#a').entwine({onfoo: function(){a += 1;} }); $('#a.a').entwine({onfoo: function(){this._super(); b += 1; this._super();} }); - [a, b].should.eql [0, 0] + expect([a, b]).toEqual( [0, 0]); $('#a').trigger('foo') - [a, b].should.eql [2, 1] - end - - it 'passes event object' + expect([a, b]).toEqual( [2, 1]); + }); + + it( 'passes event object', function() { var event; $('#a').entwine({onfoo: function(e){event = e;} }); $('#a').trigger('foo'); - event.should.have_prop 'type', 'foo' - $(event.target).should.have_attr 'id', 'a' - end - - it 'delegates submit events to forms' + expect(event.type).toBeDefined(); + expect(event.type).toEqual('foo'); + expect(event.target).toHaveAttr( 'id', 'a'); + }); + + it( 'delegates submit events to forms', function() { var a = 0; $('').appendTo('#dom_test'); $('.foo').entwine({onsubmit: function(e, d){a = 1;} }); - a.should.eql 0 + expect(a).toEqual( 0); $('.foo').trigger('submit'); - a.should.eql 1 - end - - describe 'can pass event data' - it 'on custom events' + expect(a).toEqual( 1); + }); + + describe( 'can pass event data', function() { + it( 'on custom events', function() { var data; $('#a').entwine({onfoo: function(e, d){data = d;} }); $('#a').trigger('foo', {cheese: 'burger'}); - data.cheese.should.eql 'burger' - end + expect(data.cheese).toEqual( 'burger'); + }); - it 'on normal events' + it( 'on normal events', function() { var data; $('#a').entwine({onclick: function(e, d){data = d;} }); $('#a').trigger('click', {finger: 'left'}); - data.finger.should.eql 'left' - end - - it 'on submit' + expect(data.finger).toEqual( 'left'); + }); + + it( 'on submit', function() { var data; $('').appendTo('#dom_test'); $('.foo').entwine({onsubmit: function(e, d){data = d; return false;} }) $('.foo').trigger('submit', {cheese: 'burger'}); - data.cheese.should.eql 'burger' - end - end - end -end \ No newline at end of file + expect(data.cheese).toEqual( 'burger'); + }); + }); + + }); + +}); \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/spec.entwine.namespaces.js b/thirdparty/jquery-entwine/spec/spec.entwine.namespaces.js index a4895d309..14be77e96 100644 --- a/thirdparty/jquery-entwine/spec/spec.entwine.namespaces.js +++ b/thirdparty/jquery-entwine/spec/spec.entwine.namespaces.js @@ -1,36 +1,38 @@ - -describe 'Entwine' - describe 'Namespaces' - before - $('body').append('
') - end - after - $('#dom_test').remove() - end +describe( 'Entwine', function() { - before_each + beforeEach(function() { + $('body').append('
') + }); + + afterEach(function() { + $('#dom_test').remove() + }); + + describe( 'Namespaces', function() { + + beforeEach(function() { $.entwine.synchronous_mode(); $.entwine.clear_all_rules() $('#dom_test').html('
') - end - - it 'namespaced functions work (single definition mode)' + }); + + it( 'namespaced functions work (single definition mode)', function() { $('#a').entwine('bar', function($){return{ bar: function(){return 'a';} }}) - $('#a').entwine('bar').bar().should.equal 'a' - end + expect($('#a').entwine('bar').bar()).toEqual( 'a'); + }); - it 'namespaced functions work (block definition mode)' + it( 'namespaced functions work (block definition mode)', function() { $.entwine('zap', function($){ $('#a').entwine({ bar: function(){return 'a';} }) }); - $('#a').entwine('zap').bar().should.equal 'a' - end - - it 'double-namespaced functions work (block definition mode)' + expect($('#a').entwine('zap').bar()).toEqual( 'a'); + }); + + it( 'double-namespaced functions work (block definition mode)', function() { $.entwine('zap', function($){ $.entwine('pow', function($){ $('#a').entwine({ @@ -38,10 +40,10 @@ describe 'Entwine' }) }) }) - $('#a').entwine('zap.pow').bar().should.equal 'a' - end + expect($('#a').entwine('zap.pow').bar()).toEqual( 'a'); + }) - it 'revert to base namespacing work (block definition mode)' + it( 'revert to base namespacing work (block definition mode)', function() { $.entwine('zap', function($){ $.entwine('.pow', function($){ $('#a').entwine({ @@ -49,10 +51,10 @@ describe 'Entwine' }) }) }) - $('#a').entwine('pow').bar().should.equal 'a' - end + expect($('#a').entwine('pow').bar()).toEqual( 'a'); + }); - it 'internal to namespace, will look up functions in namespace before in base' + it( 'internal to namespace, will look up functions in namespace before in base', function() { var res = [] $('#a').entwine({ foo: function(){res.push(1);}, @@ -64,12 +66,12 @@ describe 'Entwine' }}) $('#dom_test div').bar(); - res.should.eql [2, 1] + expect(res).toEqual( [2, 1]); $('#dom_test div').entwine('bar').bar(); - res.should.eql [2, 1, 4, 3] - end - - it 'internal to namespace, will look up functions in namespace before in base, even in closure' + expect(res).toEqual( [2, 1, 4, 3]); + }); + + it( 'internal to namespace, will look up functions in namespace before in base, even in closure', function() { var res = [] $('#a').entwine({ foo: function(){res.push(1);}, @@ -81,12 +83,12 @@ describe 'Entwine' }}) $('#dom_test div').bar(); - res.should.eql [2, 1] + expect(res).toEqual( [2, 1]); $('#dom_test div').entwine('bar').bar(); - res.should.eql [2, 1, 4, 3] - end - - it 'internal to namespace, will look up functions in namespace before in base, even in onmatch' + expect(res).toEqual( [2, 1, 4, 3]); + }); + + it( 'internal to namespace, will look up functions in namespace before in base, even in onmatch', function() { var res = [] $('#a').entwine({ foo: function(){res.push(1);}, @@ -100,13 +102,13 @@ describe 'Entwine' }}) $('#dom_test div').bar(); - res.should.eql [2, 1] + expect(res).toEqual( [2, 1]); $('#a').addClass('d'); - res.should.eql [2, 1, 4, 3] - end - - it 'internal to namespace, will look up functions in base when not present in namespace' + expect(res).toEqual( [2, 1, 4, 3]); + }); + + it( 'internal to namespace, will look up functions in base when not present in namespace', function() { var res = [] $('#a').entwine({ foo: function(){res.push(1);} @@ -115,10 +117,10 @@ describe 'Entwine' bar: function(){res.push(2); this.foo();} }}) $('#dom_test div').entwine('bar').bar(); - res.should.eql [2, 1] - end + expect(res).toEqual( [2, 1]); + }); - it 'internal to namespace, will not look up functions in base if present in namespace, even when not applicable to selector' + it( 'internal to namespace, will not look up functions in base if present in namespace, even when not applicable to selector', function() { var res = [] $('#a').entwine('bar', function($){return{ foo: function(){this.bar();} @@ -131,10 +133,10 @@ describe 'Entwine' }}) $('#a').entwine('bar').foo() - res.should.eql [] - end + expect(res).toEqual( []); + }); - it 'internal to namespace, can be directed to base namespace' + it( 'internal to namespace, can be directed to base namespace', function() { var res = [] $('#a').entwine({ foo: function(){res.push(1);}, @@ -145,22 +147,22 @@ describe 'Entwine' bar: function(){res.push(4); this.foo(); this.entwine('.').foo();} }}) $('#dom_test div').bar(); - res.should.eql [2, 1] + expect(res).toEqual( [2, 1]); $('#dom_test div').entwine('bar').bar(); - res.should.eql [2, 1, 4, 3, 1] - end + expect(res).toEqual( [2, 1, 4, 3, 1]); + }); - it 'internal to namespace, will look up functions in namespace called the same as a regular jQuery base function' + it( 'internal to namespace, will look up functions in namespace called the same as a regular jQuery base function', function() { var res = [] $('#a').entwine('bar', function($){return{ load: function(){res.push(1);}, bar: function(){res.push(2); this.load();} }}) $('#dom_test div').entwine('bar').bar(); - res.should.eql [2, 1] - end + expect(res).toEqual( [2, 1]); + }); - it 'internal to namespace, can be directed to regular jQuery base function' + it( 'internal to namespace, can be directed to regular jQuery base function', function() { var res = [] $.fn.testy = function(){ res.push(1); } $('#a').entwine('bar', function($){return{ @@ -168,10 +170,10 @@ describe 'Entwine' bar: function(){res.push(2); this.entwine('.').testy();} }}) $('#dom_test div').entwine('bar').bar(); - res.should.eql [2, 1] - end - - it 'internal to namespace, can be directed to sub namespace' + expect(res).toEqual( [2, 1]); + }); + + it( 'internal to namespace, can be directed to sub namespace', function() { var res = [] $.entwine('zap', function($){ $('#a').entwine({ @@ -185,10 +187,10 @@ describe 'Entwine' }) }) $('#dom_test div').entwine('zap').foo(); - res.should.eql [1, 2] - end + expect(res).toEqual( [1, 2]); + }); - it 'internal to namespace, can be directed to unrelated namespace' + it( 'internal to namespace, can be directed to unrelated namespace', function() { var res = [] $.entwine('zap', function($){ $('#a').entwine({ @@ -208,10 +210,10 @@ describe 'Entwine' }) $('#dom_test div').entwine('zap').foo(); - res.should.eql [1, 3] - end + expect(res).toEqual( [1, 3]); + }); - it 'a function passed out of a namespace will remember its namespace' + it( 'a function passed out of a namespace will remember its namespace', function() { var res = [] var func = function(func) { func.call($('#a, #b')); @@ -221,10 +223,10 @@ describe 'Entwine' bar: function(){res.push(2); func(this.zap);} }}) $('#dom_test #a').entwine('bar').bar(); - res.should.eql [2, 'b', 'a'] - end + expect(res).toEqual( [2, 'b', 'a']); + }); - it 'using block functions' + it( 'using block functions', function() { var res = [] $('#a').entwine({ foo: function(){res.push(1);} @@ -234,13 +236,14 @@ describe 'Entwine' }}) $('#dom_test div').foo(); - res.should.eql [1] + expect(res).toEqual( [1]); $('#dom_test div').entwine('bar', function($){ $(this).foo(); }) - res.should.eql [1, 3] - end + expect(res).toEqual( [1, 3]); + }); - end -end + }); + +}); \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/spec.entwine.properties.js b/thirdparty/jquery-entwine/spec/spec.entwine.properties.js index 4312d7f03..a8b9089dd 100644 --- a/thirdparty/jquery-entwine/spec/spec.entwine.properties.js +++ b/thirdparty/jquery-entwine/spec/spec.entwine.properties.js @@ -1,102 +1,88 @@ - -describe 'Entwine' - describe 'Properties' - before - $('body').append('
') - end - after - $('#dom_test').remove() - end - - before_each - $.entwine.clear_all_rules() - $('#dom_test').html('
') - end - - it 'can define and get a basic property' - $('#a').entwine({ - Foo: null - }); - $('.a').getFoo().should.be_null - end - - it 'can define and set a basic property' - $('#a').entwine({ - Foo: null - }); - $('.a').setFoo(1); - $('.a').getFoo().should.equal 1 - end - - it 'can define a default value' - $('#a').entwine({ - Foo: 1 - }); - $('.a').getFoo().should.equal 1 - end - - it 'should manage proprties in namespaces without clashing' - $('#a').entwine({ - Foo: 1 - }); - - $.entwine('test', function($){ - $('#a').entwine({ - Foo: 2 - }); - }); - - $('.a').getFoo().should.equal 1 - $('.a').entwine('test').getFoo().should.equal 2 - - $('.a').setFoo(4); - $('.a').entwine('test').setFoo(8); - - $('.a').getFoo().should.equal 4 - $('.a').entwine('test').getFoo().should.equal 8 - end - - it 'should manage directly setting proprties in namespaces without clashing' - $('#a').entwine({ - Foo: null - }); - - $.entwine('test', function($){ - $('#a').entwine({ - Foo: null - }); - }); - - $('.a').entwineData('Foo', 4); - $('.a').entwine('test').entwineData('Foo', 8); - - $('.a').entwineData('Foo').should.equal 4 - $('.a').entwine('test').entwineData('Foo').should.equal 8 - end +describe('Entwine', function() { - describe 'jQuery style accessors' - it 'can define and get a basic property' - $('#a').entwine({ - Foo: null + beforeEach(function() { + $('body').append('
') + }); + afterEach(function() { + $('#dom_test').remove() + }); + + describe('Properties', function() { + + beforeEach(function() { + $.entwine.clear_all_rules(); + $('#dom_test').html('
'); }); - $('.a').Foo().should.be_null - end - - it 'can define and set a basic property' - $('#a').entwine({ - Foo: null + + it('can define and get a basic property', function() { + $('#a').entwine({ + Foo: null + }); + expect($('.a').getFoo()).toBeNull(); }); - $('.a').Foo(1); - $('.a').Foo().should.equal 1 - end - - it 'can define a default value' - $('#a').entwine({ - Foo: 1 + it('can define and set a basic property', function() { + $('#a').entwine({ + Foo: null + }); + $('.a').setFoo(1); + expect($('.a').getFoo()).toEqual(1) }); - $('.a').Foo().should.equal 1 - end - end - - end -end + it('can define a default value', function() { + $('#a').entwine({ + Foo: 1 + }); + expect($('.a').getFoo()).toEqual(1); + }); + it('should manage proprties in namespaces without clashing', function() { + $('#a').entwine({ + Foo: 1 + }); + $.entwine('test', function($) { + $('#a').entwine({ + Foo: 2 + }); + }); + expect($('.a').getFoo()).toEqual(1); + expect($('.a').entwine('test').getFoo()).toEqual(2) + $('.a').setFoo(4); + $('.a').entwine('test').setFoo(8); + expect($('.a').getFoo()).toEqual(4) + expect($('.a').entwine('test').getFoo()).toEqual(8) + }); + it('should manage directly setting proprties in namespaces without clashing', function() { + $('#a').entwine({ + Foo: null + }); + $.entwine('test', function($) { + $('#a').entwine({ + Foo: null + }); + }); + $('.a').entwineData('Foo', 4); + $('.a').entwine('test').entwineData('Foo', 8); + expect($('.a').entwineData('Foo')).toEqual(4) ; + expect($('.a').entwine('test').entwineData('Foo')).toEqual(8); + }); + describe('jQuery style accessors', function() { + it('can define and get a basic property', function() { + $('#a').entwine({ + Foo: null + }); + expect($('.a').Foo()).toBeNull(); + }); + it('can define and set a basic property', function() { + $('#a').entwine({ + Foo: null + }); + $('.a').Foo(1); + expect($('.a').Foo()).toEqual(1) + }); + it('can define a default value', function() { + $('#a').entwine({ + Foo: 1 + }); + expect($('.a').Foo()).toEqual(1) + }); + }); + }); +}); \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/spec.entwine.super.js b/thirdparty/jquery-entwine/spec/spec.entwine.super.js index 13ff15117..e4f522a44 100644 --- a/thirdparty/jquery-entwine/spec/spec.entwine.super.js +++ b/thirdparty/jquery-entwine/spec/spec.entwine.super.js @@ -1,66 +1,88 @@ - -describe 'Entwine' - describe 'Super' - before - $('body').append('
') - end - after - $('#dom_test').remove() - end +describe('Entwine', function() { - before_each - $.entwine.clear_all_rules() - $('#dom_test').html('
Foo
Bar
') - end - - it 'can call the super function' - var a = 1; - $('#a').entwine({ - foo: function(){a *= 2;} - }); - $('#a.a').entwine({ - foo: function(){a += 2; this._super();} - }); - $('#a').foo(); - a.should.equal 6 - end - - it 'super to a non-existant class should be ignored' - var a = 1; - $('#a').entwine({ - foo: function(){a *= 2; this._super();} - }); - $('#a.a').entwine({ - foo: function(){a += 2; this._super();} - }); - $('#a').foo(); - a.should.equal 6 - end - - it 'can call super from two different functions without screwing up what super points to' - var list = []; - $('#a').entwine({ - foo: function(){ list.push('foo'); this.bar(); }, - bar: function(){ list.push('bar'); } - }); - $('#a.a').entwine({ - foo: function(){ list.push('foo2'); this._super(); list.push('foo2'); this._super(); }, - bar: function(){ list.push('bar2'); this._super(); } - }); - $('#a').foo(); - list.should.eql [ 'foo2', 'foo', 'bar2', 'bar', 'foo2', 'foo', 'bar2', 'bar' ] - end - - it 'can override (and call via super) a non-entwine jquery function' - var a = 1 - $('#a').entwine({ - text: function(){ a = this._super(); } - }); - - $('#a').text(); - a.should.equal 'Foo' - - $('#b').text().should.equal 'Bar' - end - end -end + beforeEach(function() { + $('body').append('
') + }); + afterEach(function() { + $('#dom_test').remove() + }); + + describe('Super', function() { + + beforeEach(function() { + $.entwine.clear_all_rules() + $('#dom_test').html('
Foo
Bar
') + }); + + it('can call the super function', function() { + var a = 1; + $('#a').entwine({ + foo: function() { + a *= 2; + } + }); + $('#a.a').entwine({ + foo: function() { + a += 2; + this._super(); + } + }); + $('#a').foo(); + expect(a).toEqual(6) + }); + it('super to a non-existant class should be ignored', function() { + var a = 1; + $('#a').entwine({ + foo: function() { + a *= 2; + this._super(); + } + }); + $('#a.a').entwine({ + foo: function() { + a += 2; + this._super(); + } + }); + $('#a').foo(); + expect(a).toEqual(6) + }); + it('can call super from two different functions without screwing up what super points to', function() { + var list = []; + $('#a').entwine({ + foo: function() { + list.push('foo'); + this.bar(); + }, + bar: function() { + list.push('bar'); + } + }); + $('#a.a').entwine({ + foo: function() { + list.push('foo2'); + this._super(); + list.push('foo2'); + this._super(); + }, + bar: function() { + list.push('bar2'); + this._super(); + } + }); + $('#a').foo(); + expect(list).toEqual(['foo2', 'foo', 'bar2', 'bar', 'foo2', 'foo', 'bar2', 'bar']) + }); + it('can override (and call via super) a non-entwine jquery function', function() { + var a = 1 + $('#a').entwine({ + text: function() { + a = this._super(); + } + }); + $('#a').text(); + expect(a).toEqual('Foo') + expect($('#b').text()).toEqual('Bar') + }); + }); +}); \ No newline at end of file diff --git a/thirdparty/jquery-entwine/spec/spec.html b/thirdparty/jquery-entwine/spec/spec.html deleted file mode 100644 index f23102eaf..000000000 --- a/thirdparty/jquery-entwine/spec/spec.html +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - -

JSpec

-
-
- - \ No newline at end of file diff --git a/thirdparty/jquery-entwine/src/jquery.entwine.js b/thirdparty/jquery-entwine/src/jquery.entwine.js index 742cf5884..93118e62b 100644 --- a/thirdparty/jquery-entwine/src/jquery.entwine.js +++ b/thirdparty/jquery-entwine/src/jquery.entwine.js @@ -23,7 +23,7 @@ var console; */ clear_all_rules: function() { // Remove proxy functions - for (var k in $.fn) { if ($.fn[k].entwine) delete $.fn[k] ; } + for (var k in $.fn) { if ($.fn[k].isentwinemethod) delete $.fn[k]; } // Remove bound events - TODO: Make this pluggable, so this code can be moved to jquery.entwine.events.js $(document).unbind('.entwine'); // Remove namespaces, and start over again @@ -119,38 +119,48 @@ var console; } else { // We're in a namespace, so we build a Class that subclasses the jQuery Object Class to inject namespace functions into - var subfn = function(){}; - this.injectee = subfn.prototype = new $(); - // And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building - var bound$ = this.$ = function(a) { - // Try the simple way first - var jq = $.fn.init.apply(new subfn(), arguments); - if (jq instanceof subfn) return jq; + // jQuery 1.5 already provides a nice way to subclass, so use it + if ($.sub) { + this.$ = $.sub(); + this.injectee = this.$.prototype; + } + // For jQuery < 1.5 we have to do it ourselves + else { + var subfn = function(){}; + this.injectee = subfn.prototype = new $; + + // And then we provide an overriding $ that returns objects of our new Class, and an overriding pushStack to catch further selection building + var bound$ = this.$ = function(a) { + // Try the simple way first + var jq = $.fn.init.apply(new subfn(), arguments); + if (jq instanceof subfn) return jq; - // That didn't return a bound object, so now we need to copy it - var rv = new subfn(); - rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length; - while (i--) rv[i] = jq[i]; - return rv; - }; - this.injectee.pushStack = function(elems, name, selector){ - var ret = bound$(elems); + // That didn't return a bound object, so now we need to copy it + var rv = new subfn(); + rv.selector = jq.selector; rv.context = jq.context; var i = rv.length = jq.length; + while (i--) rv[i] = jq[i]; + return rv; + }; + + this.injectee.pushStack = function(elems, name, selector){ + var ret = bound$(elems); - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - ret.context = this.context; + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; - if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector; - else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")"; + if ( name === "find" ) ret.selector = this.selector + (this.selector ? " " : "") + selector; + else if ( name ) ret.selector = this.selector + "." + name + "(" + selector + ")"; - // Return the newly-formed element set - return ret; - }; + // Return the newly-formed element set + return ret; + }; - // Copy static functions through from $ to this.$ so e.g. $.ajax still works - // @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through - $.extend(this.$, $); + // Copy static functions through from $ to this.$ so e.g. $.ajax still works + // @bug, @cantfix: Any class functions added to $ after this call won't get mirrored through + $.extend(this.$, $); + } // We override entwine to inject the name of this namespace when defining blocks inside this namespace var entwine_wrapper = this.injectee.entwine = function(spacename) { @@ -238,12 +248,12 @@ var console; var rule = rulelist.addRule(selector, name); rule.func = func; - if (!this.injectee.hasOwnProperty(name) || !this.injectee[name].entwine) { + if (!this.injectee.hasOwnProperty(name) || !this.injectee[name].isentwinemethod) { this.injectee[name] = this.build_proxy(name, this.injectee.hasOwnProperty(name) ? this.injectee[name] : null); - this.injectee[name].entwine = true; + this.injectee[name].isentwinemethod = true; } - if (!this.injectee[name].entwine) { + if (!this.injectee[name].isentwinemethod) { $.entwine.warn('Warning: Entwine function '+name+' clashes with regular jQuery function - entwine function will not be callable directly on jQuery object', $.entwine.WARN_LEVEL_IMPORTANT); } }, diff --git a/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/MIT.LICENSE b/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/MIT.LICENSE new file mode 100644 index 000000000..1eb9b49e7 --- /dev/null +++ b/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/MIT.LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2008-2010 Pivotal Labs + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine-html.js b/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine-html.js new file mode 100644 index 000000000..81402b9c1 --- /dev/null +++ b/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine-html.js @@ -0,0 +1,188 @@ +jasmine.TrivialReporter = function(doc) { + this.document = doc || document; + this.suiteDivs = {}; + this.logRunningSpecs = false; +}; + +jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { + var el = document.createElement(type); + + for (var i = 2; i < arguments.length; i++) { + var child = arguments[i]; + + if (typeof child === 'string') { + el.appendChild(document.createTextNode(child)); + } else { + if (child) { el.appendChild(child); } + } + } + + for (var attr in attrs) { + if (attr == "className") { + el[attr] = attrs[attr]; + } else { + el.setAttribute(attr, attrs[attr]); + } + } + + return el; +}; + +jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { + var showPassed, showSkipped; + + this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' }, + this.createDom('div', { className: 'banner' }, + this.createDom('div', { className: 'logo' }, + this.createDom('a', { href: 'http://pivotal.github.com/jasmine/', target: "_blank" }, "Jasmine"), + this.createDom('span', { className: 'version' }, runner.env.versionString())), + this.createDom('div', { className: 'options' }, + "Show ", + showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), + this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), + showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), + this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") + ) + ), + + this.runnerDiv = this.createDom('div', { className: 'runner running' }, + this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), + this.runnerMessageSpan = this.createDom('span', {}, "Running..."), + this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) + ); + + this.document.body.appendChild(this.outerDiv); + + var suites = runner.suites(); + for (var i = 0; i < suites.length; i++) { + var suite = suites[i]; + var suiteDiv = this.createDom('div', { className: 'suite' }, + this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), + this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); + this.suiteDivs[suite.id] = suiteDiv; + var parentDiv = this.outerDiv; + if (suite.parentSuite) { + parentDiv = this.suiteDivs[suite.parentSuite.id]; + } + parentDiv.appendChild(suiteDiv); + } + + this.startedAt = new Date(); + + var self = this; + showPassed.onclick = function(evt) { + if (showPassed.checked) { + self.outerDiv.className += ' show-passed'; + } else { + self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); + } + }; + + showSkipped.onclick = function(evt) { + if (showSkipped.checked) { + self.outerDiv.className += ' show-skipped'; + } else { + self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); + } + }; +}; + +jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { + var results = runner.results(); + var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; + this.runnerDiv.setAttribute("class", className); + //do it twice for IE + this.runnerDiv.setAttribute("className", className); + var specs = runner.specs(); + var specCount = 0; + for (var i = 0; i < specs.length; i++) { + if (this.specFilter(specs[i])) { + specCount++; + } + } + var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); + message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; + this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); + + this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); +}; + +jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { + var results = suite.results(); + var status = results.passed() ? 'passed' : 'failed'; + if (results.totalCount == 0) { // todo: change this to check results.skipped + status = 'skipped'; + } + this.suiteDivs[suite.id].className += " " + status; +}; + +jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { + if (this.logRunningSpecs) { + this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); + } +}; + +jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { + var results = spec.results(); + var status = results.passed() ? 'passed' : 'failed'; + if (results.skipped) { + status = 'skipped'; + } + var specDiv = this.createDom('div', { className: 'spec ' + status }, + this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), + this.createDom('a', { + className: 'description', + href: '?spec=' + encodeURIComponent(spec.getFullName()), + title: spec.getFullName() + }, spec.description)); + + + var resultItems = results.getItems(); + var messagesDiv = this.createDom('div', { className: 'messages' }); + for (var i = 0; i < resultItems.length; i++) { + var result = resultItems[i]; + + if (result.type == 'log') { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); + } else if (result.type == 'expect' && result.passed && !result.passed()) { + messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); + + if (result.trace.stack) { + messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); + } + } + } + + if (messagesDiv.childNodes.length > 0) { + specDiv.appendChild(messagesDiv); + } + + this.suiteDivs[spec.suite.id].appendChild(specDiv); +}; + +jasmine.TrivialReporter.prototype.log = function() { + var console = jasmine.getGlobal().console; + if (console && console.log) { + if (console.log.apply) { + console.log.apply(console, arguments); + } else { + console.log(arguments); // ie fix: console.log.apply doesn't exist on ie + } + } +}; + +jasmine.TrivialReporter.prototype.getLocation = function() { + return this.document.location; +}; + +jasmine.TrivialReporter.prototype.specFilter = function(spec) { + var paramMap = {}; + var params = this.getLocation().search.substring(1).split('&'); + for (var i = 0; i < params.length; i++) { + var p = params[i].split('='); + paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); + } + + if (!paramMap["spec"]) return true; + return spec.getFullName().indexOf(paramMap["spec"]) == 0; +}; diff --git a/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine.css b/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine.css new file mode 100644 index 000000000..6583fe7c6 --- /dev/null +++ b/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine.css @@ -0,0 +1,166 @@ +body { + font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; +} + + +.jasmine_reporter a:visited, .jasmine_reporter a { + color: #303; +} + +.jasmine_reporter a:hover, .jasmine_reporter a:active { + color: blue; +} + +.run_spec { + float:right; + padding-right: 5px; + font-size: .8em; + text-decoration: none; +} + +.jasmine_reporter { + margin: 0 5px; +} + +.banner { + color: #303; + background-color: #fef; + padding: 5px; +} + +.logo { + float: left; + font-size: 1.1em; + padding-left: 5px; +} + +.logo .version { + font-size: .6em; + padding-left: 1em; +} + +.runner.running { + background-color: yellow; +} + + +.options { + text-align: right; + font-size: .8em; +} + + + + +.suite { + border: 1px outset gray; + margin: 5px 0; + padding-left: 1em; +} + +.suite .suite { + margin: 5px; +} + +.suite.passed { + background-color: #dfd; +} + +.suite.failed { + background-color: #fdd; +} + +.spec { + margin: 5px; + padding-left: 1em; + clear: both; +} + +.spec.failed, .spec.passed, .spec.skipped { + padding-bottom: 5px; + border: 1px solid gray; +} + +.spec.failed { + background-color: #fbb; + border-color: red; +} + +.spec.passed { + background-color: #bfb; + border-color: green; +} + +.spec.skipped { + background-color: #bbb; +} + +.messages { + border-left: 1px dashed gray; + padding-left: 1em; + padding-right: 1em; +} + +.passed { + background-color: #cfc; + display: none; +} + +.failed { + background-color: #fbb; +} + +.skipped { + color: #777; + background-color: #eee; + display: none; +} + + +/*.resultMessage {*/ + /*white-space: pre;*/ +/*}*/ + +.resultMessage span.result { + display: block; + line-height: 2em; + color: black; +} + +.resultMessage .mismatch { + color: black; +} + +.stackTrace { + white-space: pre; + font-size: .8em; + margin-left: 10px; + max-height: 5em; + overflow: auto; + border: 1px inset red; + padding: 1em; + background: #eef; +} + +.finished-at { + padding-left: 1em; + font-size: .6em; +} + +.show-passed .passed, +.show-skipped .skipped { + display: block; +} + + +#jasmine_content { + position:fixed; + right: 100%; +} + +.runner { + border: 1px solid gray; + display: block; + margin: 5px 0; + padding: 2px 0 2px 10px; +} diff --git a/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine.js b/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine.js new file mode 100644 index 000000000..964f99ed5 --- /dev/null +++ b/thirdparty/jquery-entwine/vendor/jasmine-1.0.1/jasmine.js @@ -0,0 +1,2421 @@ +/** + * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. + * + * @namespace + */ +var jasmine = {}; + +/** + * @private + */ +jasmine.unimplementedMethod_ = function() { + throw new Error("unimplemented method"); +}; + +/** + * Use jasmine.undefined instead of undefined, since undefined is just + * a plain old variable and may be redefined by somebody else. + * + * @private + */ +jasmine.undefined = jasmine.___undefined___; + +/** + * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. + * + */ +jasmine.DEFAULT_UPDATE_INTERVAL = 250; + +/** + * Default timeout interval in milliseconds for waitsFor() blocks. + */ +jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + +jasmine.getGlobal = function() { + function getGlobal() { + return this; + } + + return getGlobal(); +}; + +/** + * Allows for bound functions to be compared. Internal use only. + * + * @ignore + * @private + * @param base {Object} bound 'this' for the function + * @param name {Function} function to find + */ +jasmine.bindOriginal_ = function(base, name) { + var original = base[name]; + if (original.apply) { + return function() { + return original.apply(base, arguments); + }; + } else { + // IE support + return jasmine.getGlobal()[name]; + } +}; + +jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); +jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); +jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); +jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); + +jasmine.MessageResult = function(values) { + this.type = 'log'; + this.values = values; + this.trace = new Error(); // todo: test better +}; + +jasmine.MessageResult.prototype.toString = function() { + var text = ""; + for(var i = 0; i < this.values.length; i++) { + if (i > 0) text += " "; + if (jasmine.isString_(this.values[i])) { + text += this.values[i]; + } else { + text += jasmine.pp(this.values[i]); + } + } + return text; +}; + +jasmine.ExpectationResult = function(params) { + this.type = 'expect'; + this.matcherName = params.matcherName; + this.passed_ = params.passed; + this.expected = params.expected; + this.actual = params.actual; + + this.message = this.passed_ ? 'Passed.' : params.message; + this.trace = this.passed_ ? '' : new Error(this.message); +}; + +jasmine.ExpectationResult.prototype.toString = function () { + return this.message; +}; + +jasmine.ExpectationResult.prototype.passed = function () { + return this.passed_; +}; + +/** + * Getter for the Jasmine environment. Ensures one gets created + */ +jasmine.getEnv = function() { + return jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isArray_ = function(value) { + return jasmine.isA_("Array", value); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isString_ = function(value) { + return jasmine.isA_("String", value); +}; + +/** + * @ignore + * @private + * @param value + * @returns {Boolean} + */ +jasmine.isNumber_ = function(value) { + return jasmine.isA_("Number", value); +}; + +/** + * @ignore + * @private + * @param {String} typeName + * @param value + * @returns {Boolean} + */ +jasmine.isA_ = function(typeName, value) { + return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; +}; + +/** + * Pretty printer for expecations. Takes any object and turns it into a human-readable string. + * + * @param value {Object} an object to be outputted + * @returns {String} + */ +jasmine.pp = function(value) { + var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); + stringPrettyPrinter.format(value); + return stringPrettyPrinter.string; +}; + +/** + * Returns true if the object is a DOM Node. + * + * @param {Object} obj object to check + * @returns {Boolean} + */ +jasmine.isDomNode = function(obj) { + return obj['nodeType'] > 0; +}; + +/** + * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. + * + * @example + * // don't care about which function is passed in, as long as it's a function + * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); + * + * @param {Class} clazz + * @returns matchable object of the type clazz + */ +jasmine.any = function(clazz) { + return new jasmine.Matchers.Any(clazz); +}; + +/** + * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. + * + * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine + * expectation syntax. Spies can be checked if they were called or not and what the calling params were. + * + * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). + * + * Spies are torn down at the end of every spec. + * + * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. + * + * @example + * // a stub + * var myStub = jasmine.createSpy('myStub'); // can be used anywhere + * + * // spy example + * var foo = { + * not: function(bool) { return !bool; } + * } + * + * // actual foo.not will not be called, execution stops + * spyOn(foo, 'not'); + + // foo.not spied upon, execution will continue to implementation + * spyOn(foo, 'not').andCallThrough(); + * + * // fake example + * var foo = { + * not: function(bool) { return !bool; } + * } + * + * // foo.not(val) will return val + * spyOn(foo, 'not').andCallFake(function(value) {return value;}); + * + * // mock example + * foo.not(7 == 7); + * expect(foo.not).toHaveBeenCalled(); + * expect(foo.not).toHaveBeenCalledWith(true); + * + * @constructor + * @see spyOn, jasmine.createSpy, jasmine.createSpyObj + * @param {String} name + */ +jasmine.Spy = function(name) { + /** + * The name of the spy, if provided. + */ + this.identity = name || 'unknown'; + /** + * Is this Object a spy? + */ + this.isSpy = true; + /** + * The actual function this spy stubs. + */ + this.plan = function() { + }; + /** + * Tracking of the most recent call to the spy. + * @example + * var mySpy = jasmine.createSpy('foo'); + * mySpy(1, 2); + * mySpy.mostRecentCall.args = [1, 2]; + */ + this.mostRecentCall = {}; + + /** + * Holds arguments for each call to the spy, indexed by call count + * @example + * var mySpy = jasmine.createSpy('foo'); + * mySpy(1, 2); + * mySpy(7, 8); + * mySpy.mostRecentCall.args = [7, 8]; + * mySpy.argsForCall[0] = [1, 2]; + * mySpy.argsForCall[1] = [7, 8]; + */ + this.argsForCall = []; + this.calls = []; +}; + +/** + * Tells a spy to call through to the actual implemenatation. + * + * @example + * var foo = { + * bar: function() { // do some stuff } + * } + * + * // defining a spy on an existing property: foo.bar + * spyOn(foo, 'bar').andCallThrough(); + */ +jasmine.Spy.prototype.andCallThrough = function() { + this.plan = this.originalValue; + return this; +}; + +/** + * For setting the return value of a spy. + * + * @example + * // defining a spy from scratch: foo() returns 'baz' + * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); + * + * // defining a spy on an existing property: foo.bar() returns 'baz' + * spyOn(foo, 'bar').andReturn('baz'); + * + * @param {Object} value + */ +jasmine.Spy.prototype.andReturn = function(value) { + this.plan = function() { + return value; + }; + return this; +}; + +/** + * For throwing an exception when a spy is called. + * + * @example + * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' + * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); + * + * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' + * spyOn(foo, 'bar').andThrow('baz'); + * + * @param {String} exceptionMsg + */ +jasmine.Spy.prototype.andThrow = function(exceptionMsg) { + this.plan = function() { + throw exceptionMsg; + }; + return this; +}; + +/** + * Calls an alternate implementation when a spy is called. + * + * @example + * var baz = function() { + * // do some stuff, return something + * } + * // defining a spy from scratch: foo() calls the function baz + * var foo = jasmine.createSpy('spy on foo').andCall(baz); + * + * // defining a spy on an existing property: foo.bar() calls an anonymnous function + * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); + * + * @param {Function} fakeFunc + */ +jasmine.Spy.prototype.andCallFake = function(fakeFunc) { + this.plan = fakeFunc; + return this; +}; + +/** + * Resets all of a spy's the tracking variables so that it can be used again. + * + * @example + * spyOn(foo, 'bar'); + * + * foo.bar(); + * + * expect(foo.bar.callCount).toEqual(1); + * + * foo.bar.reset(); + * + * expect(foo.bar.callCount).toEqual(0); + */ +jasmine.Spy.prototype.reset = function() { + this.wasCalled = false; + this.callCount = 0; + this.argsForCall = []; + this.calls = []; + this.mostRecentCall = {}; +}; + +jasmine.createSpy = function(name) { + + var spyObj = function() { + spyObj.wasCalled = true; + spyObj.callCount++; + var args = jasmine.util.argsToArray(arguments); + spyObj.mostRecentCall.object = this; + spyObj.mostRecentCall.args = args; + spyObj.argsForCall.push(args); + spyObj.calls.push({object: this, args: args}); + return spyObj.plan.apply(this, arguments); + }; + + var spy = new jasmine.Spy(name); + + for (var prop in spy) { + spyObj[prop] = spy[prop]; + } + + spyObj.reset(); + + return spyObj; +}; + +/** + * Determines whether an object is a spy. + * + * @param {jasmine.Spy|Object} putativeSpy + * @returns {Boolean} + */ +jasmine.isSpy = function(putativeSpy) { + return putativeSpy && putativeSpy.isSpy; +}; + +/** + * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something + * large in one call. + * + * @param {String} baseName name of spy class + * @param {Array} methodNames array of names of methods to make spies + */ +jasmine.createSpyObj = function(baseName, methodNames) { + if (!jasmine.isArray_(methodNames) || methodNames.length == 0) { + throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); + } + var obj = {}; + for (var i = 0; i < methodNames.length; i++) { + obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); + } + return obj; +}; + +/** + * All parameters are pretty-printed and concatenated together, then written to the current spec's output. + * + * Be careful not to leave calls to jasmine.log in production code. + */ +jasmine.log = function() { + var spec = jasmine.getEnv().currentSpec; + spec.log.apply(spec, arguments); +}; + +/** + * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. + * + * @example + * // spy example + * var foo = { + * not: function(bool) { return !bool; } + * } + * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops + * + * @see jasmine.createSpy + * @param obj + * @param methodName + * @returns a Jasmine spy that can be chained with all spy methods + */ +var spyOn = function(obj, methodName) { + return jasmine.getEnv().currentSpec.spyOn(obj, methodName); +}; + +/** + * Creates a Jasmine spec that will be added to the current suite. + * + * // TODO: pending tests + * + * @example + * it('should be true', function() { + * expect(true).toEqual(true); + * }); + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var it = function(desc, func) { + return jasmine.getEnv().it(desc, func); +}; + +/** + * Creates a disabled Jasmine spec. + * + * A convenience method that allows existing specs to be disabled temporarily during development. + * + * @param {String} desc description of this specification + * @param {Function} func defines the preconditions and expectations of the spec + */ +var xit = function(desc, func) { + return jasmine.getEnv().xit(desc, func); +}; + +/** + * Starts a chain for a Jasmine expectation. + * + * It is passed an Object that is the actual value and should chain to one of the many + * jasmine.Matchers functions. + * + * @param {Object} actual Actual value to test against and expected value + */ +var expect = function(actual) { + return jasmine.getEnv().currentSpec.expect(actual); +}; + +/** + * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. + * + * @param {Function} func Function that defines part of a jasmine spec. + */ +var runs = function(func) { + jasmine.getEnv().currentSpec.runs(func); +}; + +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ +var waits = function(timeout) { + jasmine.getEnv().currentSpec.waits(timeout); +}; + +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); +}; + +/** + * A function that is called before each spec in a suite. + * + * Used for spec setup, including validating assumptions. + * + * @param {Function} beforeEachFunction + */ +var beforeEach = function(beforeEachFunction) { + jasmine.getEnv().beforeEach(beforeEachFunction); +}; + +/** + * A function that is called after each spec in a suite. + * + * Used for restoring any state that is hijacked during spec execution. + * + * @param {Function} afterEachFunction + */ +var afterEach = function(afterEachFunction) { + jasmine.getEnv().afterEach(afterEachFunction); +}; + +/** + * Defines a suite of specifications. + * + * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared + * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization + * of setup in some tests. + * + * @example + * // TODO: a simple suite + * + * // TODO: a simple suite with a nested describe block + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var describe = function(description, specDefinitions) { + return jasmine.getEnv().describe(description, specDefinitions); +}; + +/** + * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. + * + * @param {String} description A string, usually the class under test. + * @param {Function} specDefinitions function that defines several specs. + */ +var xdescribe = function(description, specDefinitions) { + return jasmine.getEnv().xdescribe(description, specDefinitions); +}; + + +// Provide the XMLHttpRequest class for IE 5.x-6.x: +jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { + try { + return new ActiveXObject("Msxml2.XMLHTTP.6.0"); + } catch(e) { + } + try { + return new ActiveXObject("Msxml2.XMLHTTP.3.0"); + } catch(e) { + } + try { + return new ActiveXObject("Msxml2.XMLHTTP"); + } catch(e) { + } + try { + return new ActiveXObject("Microsoft.XMLHTTP"); + } catch(e) { + } + throw new Error("This browser does not support XMLHttpRequest."); +} : XMLHttpRequest; +/** + * @namespace + */ +jasmine.util = {}; + +/** + * Declare that a child class inherit it's prototype from the parent class. + * + * @private + * @param {Function} childClass + * @param {Function} parentClass + */ +jasmine.util.inherit = function(childClass, parentClass) { + /** + * @private + */ + var subclass = function() { + }; + subclass.prototype = parentClass.prototype; + childClass.prototype = new subclass; +}; + +jasmine.util.formatException = function(e) { + var lineNumber; + if (e.line) { + lineNumber = e.line; + } + else if (e.lineNumber) { + lineNumber = e.lineNumber; + } + + var file; + + if (e.sourceURL) { + file = e.sourceURL; + } + else if (e.fileName) { + file = e.fileName; + } + + var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); + + if (file && lineNumber) { + message += ' in ' + file + ' (line ' + lineNumber + ')'; + } + + return message; +}; + +jasmine.util.htmlEscape = function(str) { + if (!str) return str; + return str.replace(/&/g, '&') + .replace(//g, '>'); +}; + +jasmine.util.argsToArray = function(args) { + var arrayOfArgs = []; + for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); + return arrayOfArgs; +}; + +jasmine.util.extend = function(destination, source) { + for (var property in source) destination[property] = source[property]; + return destination; +}; + +/** + * Environment for Jasmine + * + * @constructor + */ +jasmine.Env = function() { + this.currentSpec = null; + this.currentSuite = null; + this.currentRunner_ = new jasmine.Runner(this); + + this.reporter = new jasmine.MultiReporter(); + + this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; + this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; + this.lastUpdate = 0; + this.specFilter = function() { + return true; + }; + + this.nextSpecId_ = 0; + this.nextSuiteId_ = 0; + this.equalityTesters_ = []; + + // wrap matchers + this.matchersClass = function() { + jasmine.Matchers.apply(this, arguments); + }; + jasmine.util.inherit(this.matchersClass, jasmine.Matchers); + + jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); +}; + + +jasmine.Env.prototype.setTimeout = jasmine.setTimeout; +jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; +jasmine.Env.prototype.setInterval = jasmine.setInterval; +jasmine.Env.prototype.clearInterval = jasmine.clearInterval; + +/** + * @returns an object containing jasmine version build info, if set. + */ +jasmine.Env.prototype.version = function () { + if (jasmine.version_) { + return jasmine.version_; + } else { + throw new Error('Version not set'); + } +}; + +/** + * @returns string containing jasmine version build info, if set. + */ +jasmine.Env.prototype.versionString = function() { + if (jasmine.version_) { + var version = this.version(); + return version.major + "." + version.minor + "." + version.build + " revision " + version.revision; + } else { + return "version unknown"; + } +}; + +/** + * @returns a sequential integer starting at 0 + */ +jasmine.Env.prototype.nextSpecId = function () { + return this.nextSpecId_++; +}; + +/** + * @returns a sequential integer starting at 0 + */ +jasmine.Env.prototype.nextSuiteId = function () { + return this.nextSuiteId_++; +}; + +/** + * Register a reporter to receive status updates from Jasmine. + * @param {jasmine.Reporter} reporter An object which will receive status updates. + */ +jasmine.Env.prototype.addReporter = function(reporter) { + this.reporter.addReporter(reporter); +}; + +jasmine.Env.prototype.execute = function() { + this.currentRunner_.execute(); +}; + +jasmine.Env.prototype.describe = function(description, specDefinitions) { + var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); + + var parentSuite = this.currentSuite; + if (parentSuite) { + parentSuite.add(suite); + } else { + this.currentRunner_.add(suite); + } + + this.currentSuite = suite; + + var declarationError = null; + try { + specDefinitions.call(suite); + } catch(e) { + declarationError = e; + } + + this.currentSuite = parentSuite; + + if (declarationError) { + this.it("encountered a declaration exception", function() { + throw declarationError; + }); + } + + return suite; +}; + +jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { + if (this.currentSuite) { + this.currentSuite.beforeEach(beforeEachFunction); + } else { + this.currentRunner_.beforeEach(beforeEachFunction); + } +}; + +jasmine.Env.prototype.currentRunner = function () { + return this.currentRunner_; +}; + +jasmine.Env.prototype.afterEach = function(afterEachFunction) { + if (this.currentSuite) { + this.currentSuite.afterEach(afterEachFunction); + } else { + this.currentRunner_.afterEach(afterEachFunction); + } + +}; + +jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { + return { + execute: function() { + } + }; +}; + +jasmine.Env.prototype.it = function(description, func) { + var spec = new jasmine.Spec(this, this.currentSuite, description); + this.currentSuite.add(spec); + this.currentSpec = spec; + + if (func) { + spec.runs(func); + } + + return spec; +}; + +jasmine.Env.prototype.xit = function(desc, func) { + return { + id: this.nextSpecId(), + runs: function() { + } + }; +}; + +jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { + if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { + return true; + } + + a.__Jasmine_been_here_before__ = b; + b.__Jasmine_been_here_before__ = a; + + var hasKey = function(obj, keyName) { + return obj != null && obj[keyName] !== jasmine.undefined; + }; + + for (var property in b) { + if (!hasKey(a, property) && hasKey(b, property)) { + mismatchKeys.push("expected has key '" + property + "', but missing from actual."); + } + } + for (property in a) { + if (!hasKey(b, property) && hasKey(a, property)) { + mismatchKeys.push("expected missing key '" + property + "', but present in actual."); + } + } + for (property in b) { + if (property == '__Jasmine_been_here_before__') continue; + if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { + mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); + } + } + + if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { + mismatchValues.push("arrays were not the same length"); + } + + delete a.__Jasmine_been_here_before__; + delete b.__Jasmine_been_here_before__; + return (mismatchKeys.length == 0 && mismatchValues.length == 0); +}; + +jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { + mismatchKeys = mismatchKeys || []; + mismatchValues = mismatchValues || []; + + for (var i = 0; i < this.equalityTesters_.length; i++) { + var equalityTester = this.equalityTesters_[i]; + var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); + if (result !== jasmine.undefined) return result; + } + + if (a === b) return true; + + if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { + return (a == jasmine.undefined && b == jasmine.undefined); + } + + if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { + return a === b; + } + + if (a instanceof Date && b instanceof Date) { + return a.getTime() == b.getTime(); + } + + if (a instanceof jasmine.Matchers.Any) { + return a.matches(b); + } + + if (b instanceof jasmine.Matchers.Any) { + return b.matches(a); + } + + if (jasmine.isString_(a) && jasmine.isString_(b)) { + return (a == b); + } + + if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { + return (a == b); + } + + if (typeof a === "object" && typeof b === "object") { + return this.compareObjects_(a, b, mismatchKeys, mismatchValues); + } + + //Straight check + return (a === b); +}; + +jasmine.Env.prototype.contains_ = function(haystack, needle) { + if (jasmine.isArray_(haystack)) { + for (var i = 0; i < haystack.length; i++) { + if (this.equals_(haystack[i], needle)) return true; + } + return false; + } + return haystack.indexOf(needle) >= 0; +}; + +jasmine.Env.prototype.addEqualityTester = function(equalityTester) { + this.equalityTesters_.push(equalityTester); +}; +/** No-op base class for Jasmine reporters. + * + * @constructor + */ +jasmine.Reporter = function() { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportRunnerResults = function(runner) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSuiteResults = function(suite) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecStarting = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.reportSpecResults = function(spec) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.Reporter.prototype.log = function(str) { +}; + +/** + * Blocks are functions with executable code that make up a spec. + * + * @constructor + * @param {jasmine.Env} env + * @param {Function} func + * @param {jasmine.Spec} spec + */ +jasmine.Block = function(env, func, spec) { + this.env = env; + this.func = func; + this.spec = spec; +}; + +jasmine.Block.prototype.execute = function(onComplete) { + try { + this.func.apply(this.spec); + } catch (e) { + this.spec.fail(e); + } + onComplete(); +}; +/** JavaScript API reporter. + * + * @constructor + */ +jasmine.JsApiReporter = function() { + this.started = false; + this.finished = false; + this.suites_ = []; + this.results_ = {}; +}; + +jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { + this.started = true; + var suites = runner.topLevelSuites(); + for (var i = 0; i < suites.length; i++) { + var suite = suites[i]; + this.suites_.push(this.summarize_(suite)); + } +}; + +jasmine.JsApiReporter.prototype.suites = function() { + return this.suites_; +}; + +jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { + var isSuite = suiteOrSpec instanceof jasmine.Suite; + var summary = { + id: suiteOrSpec.id, + name: suiteOrSpec.description, + type: isSuite ? 'suite' : 'spec', + children: [] + }; + + if (isSuite) { + var children = suiteOrSpec.children(); + for (var i = 0; i < children.length; i++) { + summary.children.push(this.summarize_(children[i])); + } + } + return summary; +}; + +jasmine.JsApiReporter.prototype.results = function() { + return this.results_; +}; + +jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { + return this.results_[specId]; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { + this.finished = true; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { + this.results_[spec.id] = { + messages: spec.results().getItems(), + result: spec.results().failedCount > 0 ? "failed" : "passed" + }; +}; + +//noinspection JSUnusedLocalSymbols +jasmine.JsApiReporter.prototype.log = function(str) { +}; + +jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ + var results = {}; + for (var i = 0; i < specIds.length; i++) { + var specId = specIds[i]; + results[specId] = this.summarizeResult_(this.results_[specId]); + } + return results; +}; + +jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ + var summaryMessages = []; + var messagesLength = result.messages.length; + for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { + var resultMessage = result.messages[messageIndex]; + summaryMessages.push({ + text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, + passed: resultMessage.passed ? resultMessage.passed() : true, + type: resultMessage.type, + message: resultMessage.message, + trace: { + stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined + } + }); + } + + return { + result : result.result, + messages : summaryMessages + }; +}; + +/** + * @constructor + * @param {jasmine.Env} env + * @param actual + * @param {jasmine.Spec} spec + */ +jasmine.Matchers = function(env, actual, spec, opt_isNot) { + this.env = env; + this.actual = actual; + this.spec = spec; + this.isNot = opt_isNot || false; + this.reportWasCalled_ = false; +}; + +// todo: @deprecated as of Jasmine 0.11, remove soon [xw] +jasmine.Matchers.pp = function(str) { + throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); +}; + +// todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] +jasmine.Matchers.prototype.report = function(result, failing_message, details) { + throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); +}; + +jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { + for (var methodName in prototype) { + if (methodName == 'report') continue; + var orig = prototype[methodName]; + matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); + } +}; + +jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { + return function() { + var matcherArgs = jasmine.util.argsToArray(arguments); + var result = matcherFunction.apply(this, arguments); + + if (this.isNot) { + result = !result; + } + + if (this.reportWasCalled_) return result; + + var message; + if (!result) { + if (this.message) { + message = this.message.apply(this, arguments); + if (jasmine.isArray_(message)) { + message = message[this.isNot ? 1 : 0]; + } + } else { + var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); + message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; + if (matcherArgs.length > 0) { + for (var i = 0; i < matcherArgs.length; i++) { + if (i > 0) message += ","; + message += " " + jasmine.pp(matcherArgs[i]); + } + } + message += "."; + } + } + var expectationResult = new jasmine.ExpectationResult({ + matcherName: matcherName, + passed: result, + expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], + actual: this.actual, + message: message + }); + this.spec.addMatcherResult(expectationResult); + return jasmine.undefined; + }; +}; + + + + +/** + * toBe: compares the actual to the expected using === + * @param expected + */ +jasmine.Matchers.prototype.toBe = function(expected) { + return this.actual === expected; +}; + +/** + * toNotBe: compares the actual to the expected using !== + * @param expected + * @deprecated as of 1.0. Use not.toBe() instead. + */ +jasmine.Matchers.prototype.toNotBe = function(expected) { + return this.actual !== expected; +}; + +/** + * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. + * + * @param expected + */ +jasmine.Matchers.prototype.toEqual = function(expected) { + return this.env.equals_(this.actual, expected); +}; + +/** + * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual + * @param expected + * @deprecated as of 1.0. Use not.toNotEqual() instead. + */ +jasmine.Matchers.prototype.toNotEqual = function(expected) { + return !this.env.equals_(this.actual, expected); +}; + +/** + * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes + * a pattern or a String. + * + * @param expected + */ +jasmine.Matchers.prototype.toMatch = function(expected) { + return new RegExp(expected).test(this.actual); +}; + +/** + * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch + * @param expected + * @deprecated as of 1.0. Use not.toMatch() instead. + */ +jasmine.Matchers.prototype.toNotMatch = function(expected) { + return !(new RegExp(expected).test(this.actual)); +}; + +/** + * Matcher that compares the actual to jasmine.undefined. + */ +jasmine.Matchers.prototype.toBeDefined = function() { + return (this.actual !== jasmine.undefined); +}; + +/** + * Matcher that compares the actual to jasmine.undefined. + */ +jasmine.Matchers.prototype.toBeUndefined = function() { + return (this.actual === jasmine.undefined); +}; + +/** + * Matcher that compares the actual to null. + */ +jasmine.Matchers.prototype.toBeNull = function() { + return (this.actual === null); +}; + +/** + * Matcher that boolean not-nots the actual. + */ +jasmine.Matchers.prototype.toBeTruthy = function() { + return !!this.actual; +}; + + +/** + * Matcher that boolean nots the actual. + */ +jasmine.Matchers.prototype.toBeFalsy = function() { + return !this.actual; +}; + + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was called. + */ +jasmine.Matchers.prototype.toHaveBeenCalled = function() { + if (arguments.length > 0) { + throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); + } + + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy " + this.actual.identity + " to have been called.", + "Expected spy " + this.actual.identity + " not to have been called." + ]; + }; + + return this.actual.wasCalled; +}; + +/** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ +jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was not called. + * + * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead + */ +jasmine.Matchers.prototype.wasNotCalled = function() { + if (arguments.length > 0) { + throw new Error('wasNotCalled does not take arguments'); + } + + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy " + this.actual.identity + " to not have been called.", + "Expected spy " + this.actual.identity + " to have been called." + ]; + }; + + return !this.actual.wasCalled; +}; + +/** + * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. + * + * @example + * + */ +jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { + var expectedArgs = jasmine.util.argsToArray(arguments); + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + this.message = function() { + if (this.actual.callCount == 0) { + // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] + return [ + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was." + ]; + } else { + return [ + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) + ]; + } + }; + + return this.env.contains_(this.actual.argsForCall, expectedArgs); +}; + +/** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; + +/** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ +jasmine.Matchers.prototype.wasNotCalledWith = function() { + var expectedArgs = jasmine.util.argsToArray(arguments); + if (!jasmine.isSpy(this.actual)) { + throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); + } + + this.message = function() { + return [ + "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", + "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" + ] + }; + + return !this.env.contains_(this.actual.argsForCall, expectedArgs); +}; + +/** + * Matcher that checks that the expected item is an element in the actual Array. + * + * @param {Object} expected + */ +jasmine.Matchers.prototype.toContain = function(expected) { + return this.env.contains_(this.actual, expected); +}; + +/** + * Matcher that checks that the expected item is NOT an element in the actual Array. + * + * @param {Object} expected + * @deprecated as of 1.0. Use not.toNotContain() instead. + */ +jasmine.Matchers.prototype.toNotContain = function(expected) { + return !this.env.contains_(this.actual, expected); +}; + +jasmine.Matchers.prototype.toBeLessThan = function(expected) { + return this.actual < expected; +}; + +jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { + return this.actual > expected; +}; + +/** + * Matcher that checks that the expected exception was thrown by the actual. + * + * @param {String} expected + */ +jasmine.Matchers.prototype.toThrow = function(expected) { + var result = false; + var exception; + if (typeof this.actual != 'function') { + throw new Error('Actual is not a function'); + } + try { + this.actual(); + } catch (e) { + exception = e; + } + if (exception) { + result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); + } + + var not = this.isNot ? "not " : ""; + + this.message = function() { + if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { + return ["Expected function " + not + "to throw", expected ? expected.message || expected : " an exception", ", but it threw", exception.message || exception].join(' '); + } else { + return "Expected function to throw an exception."; + } + }; + + return result; +}; + +jasmine.Matchers.Any = function(expectedClass) { + this.expectedClass = expectedClass; +}; + +jasmine.Matchers.Any.prototype.matches = function(other) { + if (this.expectedClass == String) { + return typeof other == 'string' || other instanceof String; + } + + if (this.expectedClass == Number) { + return typeof other == 'number' || other instanceof Number; + } + + if (this.expectedClass == Function) { + return typeof other == 'function' || other instanceof Function; + } + + if (this.expectedClass == Object) { + return typeof other == 'object'; + } + + return other instanceof this.expectedClass; +}; + +jasmine.Matchers.Any.prototype.toString = function() { + return ''; +}; + +/** + * @constructor + */ +jasmine.MultiReporter = function() { + this.subReporters_ = []; +}; +jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); + +jasmine.MultiReporter.prototype.addReporter = function(reporter) { + this.subReporters_.push(reporter); +}; + +(function() { + var functionNames = [ + "reportRunnerStarting", + "reportRunnerResults", + "reportSuiteResults", + "reportSpecStarting", + "reportSpecResults", + "log" + ]; + for (var i = 0; i < functionNames.length; i++) { + var functionName = functionNames[i]; + jasmine.MultiReporter.prototype[functionName] = (function(functionName) { + return function() { + for (var j = 0; j < this.subReporters_.length; j++) { + var subReporter = this.subReporters_[j]; + if (subReporter[functionName]) { + subReporter[functionName].apply(subReporter, arguments); + } + } + }; + })(functionName); + } +})(); +/** + * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults + * + * @constructor + */ +jasmine.NestedResults = function() { + /** + * The total count of results + */ + this.totalCount = 0; + /** + * Number of passed results + */ + this.passedCount = 0; + /** + * Number of failed results + */ + this.failedCount = 0; + /** + * Was this suite/spec skipped? + */ + this.skipped = false; + /** + * @ignore + */ + this.items_ = []; +}; + +/** + * Roll up the result counts. + * + * @param result + */ +jasmine.NestedResults.prototype.rollupCounts = function(result) { + this.totalCount += result.totalCount; + this.passedCount += result.passedCount; + this.failedCount += result.failedCount; +}; + +/** + * Adds a log message. + * @param values Array of message parts which will be concatenated later. + */ +jasmine.NestedResults.prototype.log = function(values) { + this.items_.push(new jasmine.MessageResult(values)); +}; + +/** + * Getter for the results: message & results. + */ +jasmine.NestedResults.prototype.getItems = function() { + return this.items_; +}; + +/** + * Adds a result, tracking counts (total, passed, & failed) + * @param {jasmine.ExpectationResult|jasmine.NestedResults} result + */ +jasmine.NestedResults.prototype.addResult = function(result) { + if (result.type != 'log') { + if (result.items_) { + this.rollupCounts(result); + } else { + this.totalCount++; + if (result.passed()) { + this.passedCount++; + } else { + this.failedCount++; + } + } + } + this.items_.push(result); +}; + +/** + * @returns {Boolean} True if everything below passed + */ +jasmine.NestedResults.prototype.passed = function() { + return this.passedCount === this.totalCount; +}; +/** + * Base class for pretty printing for expectation results. + */ +jasmine.PrettyPrinter = function() { + this.ppNestLevel_ = 0; +}; + +/** + * Formats a value in a nice, human-readable string. + * + * @param value + */ +jasmine.PrettyPrinter.prototype.format = function(value) { + if (this.ppNestLevel_ > 40) { + throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); + } + + this.ppNestLevel_++; + try { + if (value === jasmine.undefined) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === jasmine.getGlobal()) { + this.emitScalar(''); + } else if (value instanceof jasmine.Matchers.Any) { + this.emitScalar(value.toString()); + } else if (typeof value === 'string') { + this.emitString(value); + } else if (jasmine.isSpy(value)) { + this.emitScalar("spy on " + value.identity); + } else if (value instanceof RegExp) { + this.emitScalar(value.toString()); + } else if (typeof value === 'function') { + this.emitScalar('Function'); + } else if (typeof value.nodeType === 'number') { + this.emitScalar('HTMLNode'); + } else if (value instanceof Date) { + this.emitScalar('Date(' + value + ')'); + } else if (value.__Jasmine_been_here_before__) { + this.emitScalar(''); + } else if (jasmine.isArray_(value) || typeof value == 'object') { + value.__Jasmine_been_here_before__ = true; + if (jasmine.isArray_(value)) { + this.emitArray(value); + } else { + this.emitObject(value); + } + delete value.__Jasmine_been_here_before__; + } else { + this.emitScalar(value.toString()); + } + } finally { + this.ppNestLevel_--; + } +}; + +jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { + for (var property in obj) { + if (property == '__Jasmine_been_here_before__') continue; + fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) != null) : false); + } +}; + +jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; +jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; + +jasmine.StringPrettyPrinter = function() { + jasmine.PrettyPrinter.call(this); + + this.string = ''; +}; +jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); + +jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { + this.append(value); +}; + +jasmine.StringPrettyPrinter.prototype.emitString = function(value) { + this.append("'" + value + "'"); +}; + +jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { + this.append('[ '); + for (var i = 0; i < array.length; i++) { + if (i > 0) { + this.append(', '); + } + this.format(array[i]); + } + this.append(' ]'); +}; + +jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { + var self = this; + this.append('{ '); + var first = true; + + this.iterateObject(obj, function(property, isGetter) { + if (first) { + first = false; + } else { + self.append(', '); + } + + self.append(property); + self.append(' : '); + if (isGetter) { + self.append(''); + } else { + self.format(obj[property]); + } + }); + + this.append(' }'); +}; + +jasmine.StringPrettyPrinter.prototype.append = function(value) { + this.string += value; +}; +jasmine.Queue = function(env) { + this.env = env; + this.blocks = []; + this.running = false; + this.index = 0; + this.offset = 0; + this.abort = false; +}; + +jasmine.Queue.prototype.addBefore = function(block) { + this.blocks.unshift(block); +}; + +jasmine.Queue.prototype.add = function(block) { + this.blocks.push(block); +}; + +jasmine.Queue.prototype.insertNext = function(block) { + this.blocks.splice((this.index + this.offset + 1), 0, block); + this.offset++; +}; + +jasmine.Queue.prototype.start = function(onComplete) { + this.running = true; + this.onComplete = onComplete; + this.next_(); +}; + +jasmine.Queue.prototype.isRunning = function() { + return this.running; +}; + +jasmine.Queue.LOOP_DONT_RECURSE = true; + +jasmine.Queue.prototype.next_ = function() { + var self = this; + var goAgain = true; + + while (goAgain) { + goAgain = false; + + if (self.index < self.blocks.length && !this.abort) { + var calledSynchronously = true; + var completedSynchronously = false; + + var onComplete = function () { + if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { + completedSynchronously = true; + return; + } + + if (self.blocks[self.index].abort) { + self.abort = true; + } + + self.offset = 0; + self.index++; + + var now = new Date().getTime(); + if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { + self.env.lastUpdate = now; + self.env.setTimeout(function() { + self.next_(); + }, 0); + } else { + if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { + goAgain = true; + } else { + self.next_(); + } + } + }; + self.blocks[self.index].execute(onComplete); + + calledSynchronously = false; + if (completedSynchronously) { + onComplete(); + } + + } else { + self.running = false; + if (self.onComplete) { + self.onComplete(); + } + } + } +}; + +jasmine.Queue.prototype.results = function() { + var results = new jasmine.NestedResults(); + for (var i = 0; i < this.blocks.length; i++) { + if (this.blocks[i].results) { + results.addResult(this.blocks[i].results()); + } + } + return results; +}; + + +/** + * Runner + * + * @constructor + * @param {jasmine.Env} env + */ +jasmine.Runner = function(env) { + var self = this; + self.env = env; + self.queue = new jasmine.Queue(env); + self.before_ = []; + self.after_ = []; + self.suites_ = []; +}; + +jasmine.Runner.prototype.execute = function() { + var self = this; + if (self.env.reporter.reportRunnerStarting) { + self.env.reporter.reportRunnerStarting(this); + } + self.queue.start(function () { + self.finishCallback(); + }); +}; + +jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.before_.splice(0,0,beforeEachFunction); +}; + +jasmine.Runner.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.after_.splice(0,0,afterEachFunction); +}; + + +jasmine.Runner.prototype.finishCallback = function() { + this.env.reporter.reportRunnerResults(this); +}; + +jasmine.Runner.prototype.addSuite = function(suite) { + this.suites_.push(suite); +}; + +jasmine.Runner.prototype.add = function(block) { + if (block instanceof jasmine.Suite) { + this.addSuite(block); + } + this.queue.add(block); +}; + +jasmine.Runner.prototype.specs = function () { + var suites = this.suites(); + var specs = []; + for (var i = 0; i < suites.length; i++) { + specs = specs.concat(suites[i].specs()); + } + return specs; +}; + +jasmine.Runner.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Runner.prototype.topLevelSuites = function() { + var topLevelSuites = []; + for (var i = 0; i < this.suites_.length; i++) { + if (!this.suites_[i].parentSuite) { + topLevelSuites.push(this.suites_[i]); + } + } + return topLevelSuites; +}; + +jasmine.Runner.prototype.results = function() { + return this.queue.results(); +}; +/** + * Internal representation of a Jasmine specification, or test. + * + * @constructor + * @param {jasmine.Env} env + * @param {jasmine.Suite} suite + * @param {String} description + */ +jasmine.Spec = function(env, suite, description) { + if (!env) { + throw new Error('jasmine.Env() required'); + } + if (!suite) { + throw new Error('jasmine.Suite() required'); + } + var spec = this; + spec.id = env.nextSpecId ? env.nextSpecId() : null; + spec.env = env; + spec.suite = suite; + spec.description = description; + spec.queue = new jasmine.Queue(env); + + spec.afterCallbacks = []; + spec.spies_ = []; + + spec.results_ = new jasmine.NestedResults(); + spec.results_.description = description; + spec.matchersClass = null; +}; + +jasmine.Spec.prototype.getFullName = function() { + return this.suite.getFullName() + ' ' + this.description + '.'; +}; + + +jasmine.Spec.prototype.results = function() { + return this.results_; +}; + +/** + * All parameters are pretty-printed and concatenated together, then written to the spec's output. + * + * Be careful not to leave calls to jasmine.log in production code. + */ +jasmine.Spec.prototype.log = function() { + return this.results_.log(arguments); +}; + +jasmine.Spec.prototype.runs = function (func) { + var block = new jasmine.Block(this.env, func, this); + this.addToQueue(block); + return this; +}; + +jasmine.Spec.prototype.addToQueue = function (block) { + if (this.queue.isRunning()) { + this.queue.insertNext(block); + } else { + this.queue.add(block); + } +}; + +/** + * @param {jasmine.ExpectationResult} result + */ +jasmine.Spec.prototype.addMatcherResult = function(result) { + this.results_.addResult(result); +}; + +jasmine.Spec.prototype.expect = function(actual) { + var positive = new (this.getMatchersClass_())(this.env, actual, this); + positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); + return positive; +}; + +/** + * Waits a fixed time period before moving to the next block. + * + * @deprecated Use waitsFor() instead + * @param {Number} timeout milliseconds to wait + */ +jasmine.Spec.prototype.waits = function(timeout) { + var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); + this.addToQueue(waitsFunc); + return this; +}; + +/** + * Waits for the latchFunction to return true before proceeding to the next block. + * + * @param {Function} latchFunction + * @param {String} optional_timeoutMessage + * @param {Number} optional_timeout + */ +jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { + var latchFunction_ = null; + var optional_timeoutMessage_ = null; + var optional_timeout_ = null; + + for (var i = 0; i < arguments.length; i++) { + var arg = arguments[i]; + switch (typeof arg) { + case 'function': + latchFunction_ = arg; + break; + case 'string': + optional_timeoutMessage_ = arg; + break; + case 'number': + optional_timeout_ = arg; + break; + } + } + + var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); + this.addToQueue(waitsForFunc); + return this; +}; + +jasmine.Spec.prototype.fail = function (e) { + var expectationResult = new jasmine.ExpectationResult({ + passed: false, + message: e ? jasmine.util.formatException(e) : 'Exception' + }); + this.results_.addResult(expectationResult); +}; + +jasmine.Spec.prototype.getMatchersClass_ = function() { + return this.matchersClass || this.env.matchersClass; +}; + +jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { + var parent = this.getMatchersClass_(); + var newMatchersClass = function() { + parent.apply(this, arguments); + }; + jasmine.util.inherit(newMatchersClass, parent); + jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); + this.matchersClass = newMatchersClass; +}; + +jasmine.Spec.prototype.finishCallback = function() { + this.env.reporter.reportSpecResults(this); +}; + +jasmine.Spec.prototype.finish = function(onComplete) { + this.removeAllSpies(); + this.finishCallback(); + if (onComplete) { + onComplete(); + } +}; + +jasmine.Spec.prototype.after = function(doAfter) { + if (this.queue.isRunning()) { + this.queue.add(new jasmine.Block(this.env, doAfter, this)); + } else { + this.afterCallbacks.unshift(doAfter); + } +}; + +jasmine.Spec.prototype.execute = function(onComplete) { + var spec = this; + if (!spec.env.specFilter(spec)) { + spec.results_.skipped = true; + spec.finish(onComplete); + return; + } + + this.env.reporter.reportSpecStarting(this); + + spec.env.currentSpec = spec; + + spec.addBeforesAndAftersToQueue(); + + spec.queue.start(function () { + spec.finish(onComplete); + }); +}; + +jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { + var runner = this.env.currentRunner(); + var i; + + for (var suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); + } + } + for (i = 0; i < runner.before_.length; i++) { + this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); + } + for (i = 0; i < this.afterCallbacks.length; i++) { + this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this)); + } + for (suite = this.suite; suite; suite = suite.parentSuite) { + for (i = 0; i < suite.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, suite.after_[i], this)); + } + } + for (i = 0; i < runner.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); + } +}; + +jasmine.Spec.prototype.explodes = function() { + throw 'explodes function should not have been called'; +}; + +jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { + if (obj == jasmine.undefined) { + throw "spyOn could not find an object to spy upon for " + methodName + "()"; + } + + if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { + throw methodName + '() method does not exist'; + } + + if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { + throw new Error(methodName + ' has already been spied upon'); + } + + var spyObj = jasmine.createSpy(methodName); + + this.spies_.push(spyObj); + spyObj.baseObj = obj; + spyObj.methodName = methodName; + spyObj.originalValue = obj[methodName]; + + obj[methodName] = spyObj; + + return spyObj; +}; + +jasmine.Spec.prototype.removeAllSpies = function() { + for (var i = 0; i < this.spies_.length; i++) { + var spy = this.spies_[i]; + spy.baseObj[spy.methodName] = spy.originalValue; + } + this.spies_ = []; +}; + +/** + * Internal representation of a Jasmine suite. + * + * @constructor + * @param {jasmine.Env} env + * @param {String} description + * @param {Function} specDefinitions + * @param {jasmine.Suite} parentSuite + */ +jasmine.Suite = function(env, description, specDefinitions, parentSuite) { + var self = this; + self.id = env.nextSuiteId ? env.nextSuiteId() : null; + self.description = description; + self.queue = new jasmine.Queue(env); + self.parentSuite = parentSuite; + self.env = env; + self.before_ = []; + self.after_ = []; + self.children_ = []; + self.suites_ = []; + self.specs_ = []; +}; + +jasmine.Suite.prototype.getFullName = function() { + var fullName = this.description; + for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { + fullName = parentSuite.description + ' ' + fullName; + } + return fullName; +}; + +jasmine.Suite.prototype.finish = function(onComplete) { + this.env.reporter.reportSuiteResults(this); + this.finished = true; + if (typeof(onComplete) == 'function') { + onComplete(); + } +}; + +jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { + beforeEachFunction.typeName = 'beforeEach'; + this.before_.unshift(beforeEachFunction); +}; + +jasmine.Suite.prototype.afterEach = function(afterEachFunction) { + afterEachFunction.typeName = 'afterEach'; + this.after_.unshift(afterEachFunction); +}; + +jasmine.Suite.prototype.results = function() { + return this.queue.results(); +}; + +jasmine.Suite.prototype.add = function(suiteOrSpec) { + this.children_.push(suiteOrSpec); + if (suiteOrSpec instanceof jasmine.Suite) { + this.suites_.push(suiteOrSpec); + this.env.currentRunner().addSuite(suiteOrSpec); + } else { + this.specs_.push(suiteOrSpec); + } + this.queue.add(suiteOrSpec); +}; + +jasmine.Suite.prototype.specs = function() { + return this.specs_; +}; + +jasmine.Suite.prototype.suites = function() { + return this.suites_; +}; + +jasmine.Suite.prototype.children = function() { + return this.children_; +}; + +jasmine.Suite.prototype.execute = function(onComplete) { + var self = this; + this.queue.start(function () { + self.finish(onComplete); + }); +}; +jasmine.WaitsBlock = function(env, timeout, spec) { + this.timeout = timeout; + jasmine.Block.call(this, env, null, spec); +}; + +jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); + +jasmine.WaitsBlock.prototype.execute = function (onComplete) { + this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); + this.env.setTimeout(function () { + onComplete(); + }, this.timeout); +}; +/** + * A block which waits for some condition to become true, with timeout. + * + * @constructor + * @extends jasmine.Block + * @param {jasmine.Env} env The Jasmine environment. + * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. + * @param {Function} latchFunction A function which returns true when the desired condition has been met. + * @param {String} message The message to display if the desired condition hasn't been met within the given time period. + * @param {jasmine.Spec} spec The Jasmine spec. + */ +jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { + this.timeout = timeout || env.defaultTimeoutInterval; + this.latchFunction = latchFunction; + this.message = message; + this.totalTimeSpentWaitingForLatch = 0; + jasmine.Block.call(this, env, null, spec); +}; +jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); + +jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; + +jasmine.WaitsForBlock.prototype.execute = function(onComplete) { + this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); + var latchFunctionResult; + try { + latchFunctionResult = this.latchFunction.apply(this.spec); + } catch (e) { + this.spec.fail(e); + onComplete(); + return; + } + + if (latchFunctionResult) { + onComplete(); + } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { + var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); + this.spec.fail({ + name: 'timeout', + message: message + }); + + this.abort = true; + onComplete(); + } else { + this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; + var self = this; + this.env.setTimeout(function() { + self.execute(onComplete); + }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); + } +}; +// Mock setTimeout, clearTimeout +// Contributed by Pivotal Computer Systems, www.pivotalsf.com + +jasmine.FakeTimer = function() { + this.reset(); + + var self = this; + self.setTimeout = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); + return self.timeoutsMade; + }; + + self.setInterval = function(funcToCall, millis) { + self.timeoutsMade++; + self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); + return self.timeoutsMade; + }; + + self.clearTimeout = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + + self.clearInterval = function(timeoutKey) { + self.scheduledFunctions[timeoutKey] = jasmine.undefined; + }; + +}; + +jasmine.FakeTimer.prototype.reset = function() { + this.timeoutsMade = 0; + this.scheduledFunctions = {}; + this.nowMillis = 0; +}; + +jasmine.FakeTimer.prototype.tick = function(millis) { + var oldMillis = this.nowMillis; + var newMillis = oldMillis + millis; + this.runFunctionsWithinRange(oldMillis, newMillis); + this.nowMillis = newMillis; +}; + +jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { + var scheduledFunc; + var funcsToRun = []; + for (var timeoutKey in this.scheduledFunctions) { + scheduledFunc = this.scheduledFunctions[timeoutKey]; + if (scheduledFunc != jasmine.undefined && + scheduledFunc.runAtMillis >= oldMillis && + scheduledFunc.runAtMillis <= nowMillis) { + funcsToRun.push(scheduledFunc); + this.scheduledFunctions[timeoutKey] = jasmine.undefined; + } + } + + if (funcsToRun.length > 0) { + funcsToRun.sort(function(a, b) { + return a.runAtMillis - b.runAtMillis; + }); + for (var i = 0; i < funcsToRun.length; ++i) { + try { + var funcToRun = funcsToRun[i]; + this.nowMillis = funcToRun.runAtMillis; + funcToRun.funcToCall(); + if (funcToRun.recurring) { + this.scheduleFunction(funcToRun.timeoutKey, + funcToRun.funcToCall, + funcToRun.millis, + true); + } + } catch(e) { + } + } + this.runFunctionsWithinRange(oldMillis, nowMillis); + } +}; + +jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { + this.scheduledFunctions[timeoutKey] = { + runAtMillis: this.nowMillis + millis, + funcToCall: funcToCall, + recurring: recurring, + timeoutKey: timeoutKey, + millis: millis + }; +}; + +/** + * @namespace + */ +jasmine.Clock = { + defaultFakeTimer: new jasmine.FakeTimer(), + + reset: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.reset(); + }, + + tick: function(millis) { + jasmine.Clock.assertInstalled(); + jasmine.Clock.defaultFakeTimer.tick(millis); + }, + + runFunctionsWithinRange: function(oldMillis, nowMillis) { + jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); + }, + + scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { + jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); + }, + + useMock: function() { + if (!jasmine.Clock.isInstalled()) { + var spec = jasmine.getEnv().currentSpec; + spec.after(jasmine.Clock.uninstallMock); + + jasmine.Clock.installMock(); + } + }, + + installMock: function() { + jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; + }, + + uninstallMock: function() { + jasmine.Clock.assertInstalled(); + jasmine.Clock.installed = jasmine.Clock.real; + }, + + real: { + setTimeout: jasmine.getGlobal().setTimeout, + clearTimeout: jasmine.getGlobal().clearTimeout, + setInterval: jasmine.getGlobal().setInterval, + clearInterval: jasmine.getGlobal().clearInterval + }, + + assertInstalled: function() { + if (!jasmine.Clock.isInstalled()) { + throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); + } + }, + + isInstalled: function() { + return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; + }, + + installed: null +}; +jasmine.Clock.installed = jasmine.Clock.real; + +//else for IE support +jasmine.getGlobal().setTimeout = function(funcToCall, millis) { + if (jasmine.Clock.installed.setTimeout.apply) { + return jasmine.Clock.installed.setTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.setTimeout(funcToCall, millis); + } +}; + +jasmine.getGlobal().setInterval = function(funcToCall, millis) { + if (jasmine.Clock.installed.setInterval.apply) { + return jasmine.Clock.installed.setInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.setInterval(funcToCall, millis); + } +}; + +jasmine.getGlobal().clearTimeout = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearTimeout.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearTimeout(timeoutKey); + } +}; + +jasmine.getGlobal().clearInterval = function(timeoutKey) { + if (jasmine.Clock.installed.clearTimeout.apply) { + return jasmine.Clock.installed.clearInterval.apply(this, arguments); + } else { + return jasmine.Clock.installed.clearInterval(timeoutKey); + } +}; + + +jasmine.version_= { + "major": 1, + "minor": 0, + "build": 1, + "revision": 1286311016 +}; diff --git a/thirdparty/jquery-entwine/vendor/jasmine-dom/jasmine-dom-fixtures.js b/thirdparty/jquery-entwine/vendor/jasmine-dom/jasmine-dom-fixtures.js new file mode 100644 index 000000000..950055878 --- /dev/null +++ b/thirdparty/jquery-entwine/vendor/jasmine-dom/jasmine-dom-fixtures.js @@ -0,0 +1,175 @@ +/*jsl:declare jasmine*/ +function readFixtures() +{ + return jasmine.getFixtures()._proxyCallTo('read', arguments); +} + +function loadFixtures() +{ + jasmine.getFixtures()._proxyCallTo('load', arguments); +} + +function setFixtures(html) +{ + jasmine.getFixtures().set(html); +} + +function sandbox(attributes) +{ + return jasmine.getFixtures().sandbox(attributes); +} + + +jasmine.getFixtures = function() +{ + return jasmine._currentFixtures = jasmine._currentFixtures || new jasmine.Fixtures(); +} + +jasmine.Fixtures = function() +{ + this.containerId = 'jasmine-fixtures'; + this._fixturesCache = {}; +} + +jasmine.Fixtures.XHR= window.XMLHttpRequest || (function(){ + var progIdCandidates= ['Msxml2.XMLHTTP.4.0', 'Microsoft.XMLHTTP', 'Msxml2.XMLHTTP']; + var len= progIdCandidates.length; + + var progId; + var xhr; + + function ConstructXhr() + { + return new window.ActiveXObject(ConstructXhr.progId); + } + + while (len--) + { + try + { + progId= progIdCandidates[len]; + xhr= new window.ActiveXObject(progId); + // ActiveXObject constructor throws an exception + // if the component isn't available. + xhr= null; + ConstructXhr.progId= progId; + return ConstructXhr; + } + catch (e) + { + // Ignore the error + } + } + throw new Error('No XMLHttpRequest implementation found'); +})(); + +jasmine.Fixtures.prototype= { + + set: function(html) + { + this.cleanUp(); + this._createContainer(html); + }, + + load: function() + { + this.cleanUp(); + this._createContainer(this.read.apply(this, arguments)); + }, + + read: function() + { + var htmlChunks = []; + + var fixtureUrls = arguments; + for (var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) + htmlChunks.push(this._getFixtureHtml(fixtureUrls[urlIndex])); + + return htmlChunks.join(''); + }, + + clearCache: function() + { + this._fixturesCache = {}; + }, + + cleanUp: function() + { + var container= document.getElementById(this.containerId); + if (container) + container.parentNode.removeChild(container); + }, + + sandbox: function(attributes) + { + var attributesToSet = attributes || {}; + var sandbox= document.createElement('div'); + sandbox.id= 'sandbox'; + + if ("string"===typeof(attributes)) + { + sandbox.innerHTML= attributes; + if (1===sandbox.childNodes.length && 1===sandbox.firstChild.nodeType) + { + sandbox= sandbox.firstChild; + if (!sandbox.id) + sandbox.id= 'sandbox'; + } + return sandbox; + } + + for (var attr in attributesToSet) + sandbox.setAttribute(attr, attributesToSet[attr]); + + return sandbox; + }, + + _createContainer: function(html) + { + var container = document.createElement('div'); + container.id= this.containerId; + + if (html && html.nodeType===1) + container.appendChild(html); + else + container.innerHTML= html; + + document.body.appendChild(container); + }, + + _getFixtureHtml: function(url) + { + if (void(0)===this._fixturesCache[url]) + this._loadFixtureIntoCache(url); + return this._fixturesCache[url]; + }, + + _loadFixtureIntoCache: function(url) + { + var self= this; + var xhr= new jasmine.Fixtures.XHR(); + xhr.open('GET', url, true); + + xhr.onreadystatechange= function() + { + if (4!==xhr.readyState) + return; + var status= xhr.status; + var succeeded= 0===status || (status>=200 && status<300) || 304==status; + + if (!succeeded) + throw new Error('Failed to load resource: status=' + status + ' url=' + url); + + self._fixturesCache[url]= xhr.responseText; + xhr.onreadystatechange= null; + xhr= null; + } + xhr.send(null); + }, + + _proxyCallTo: function(methodName, passedArguments) + { + return this[methodName].apply(this, passedArguments); + } + +}; \ No newline at end of file diff --git a/thirdparty/jquery-entwine/vendor/jasmine-dom/jasmine-dom-matchers.js b/thirdparty/jquery-entwine/vendor/jasmine-dom/jasmine-dom-matchers.js new file mode 100644 index 000000000..4c6dcdfb6 --- /dev/null +++ b/thirdparty/jquery-entwine/vendor/jasmine-dom/jasmine-dom-matchers.js @@ -0,0 +1,205 @@ +/*jsl:declare jasmine*/ +/*jsl:declare Sizzle*/ +/*jsl:declare Prototype*/ +/*jsl:declare jQuery*/ + +jasmine.DOM = {}; + +jasmine.DOM.browserTagCaseIndependentHtml = function(html) +{ + var div= document.createElement('div'); + div.innerHTML= html; + return div.innerHTML; +} + +jasmine.DOM.elementToString = function(element) +{ + var div= document.createElement('div'); + div.appendChild(element.cloneNode(true)); + return div.innerHTML; +} + +jasmine.DOM.trim= function(string) +{ + var str= string.replace(/^\s+/, ''); + for (var i = str.length - 1; i > 0; --i) + if (/\S/.test(str.charAt(i))) + { + str = str.substring(0, i + 1); + break; + } + return str; +} + +jasmine.DOM.slice= function(arrayLike, startIndex) +{ + return [].slice.call(arrayLike, startIndex||0); +} + +jasmine.DOM.uniqueId= 1; +jasmine.DOM.assignId= function(element) +{ + return element.id || (element.id=('jasmine_id_' + jasmine.DOM.uniqueId++)); +}; + +/** + jasmine.DOM.queryAll(selector[, scope]) -> array + */ +jasmine.DOM.queryAll= (function(){ + if ('undefined'!==typeof(Sizzle)) + return Sizzle; + if ('undefined'!==typeof(Prototype)) + return function(selector, node) + { + return Element.getElementsBySelector(node||document, selector); + }; + if ('undefined'!==typeof(jQuery)) + return function(selector, node) + { + var result= jQuery(selector, node); + var nodes= []; + var len= result.length; + + for (var i=0; i 0; + } + }; + + function comparePropertyValues(actualValue, expectedValue) + { + if (void(0) === expectedValue) + return void(0) !== actualValue; + return actualValue == expectedValue; + } + + function bindMatcher(methodName) + { + var originalMatcher = jasmine.Matchers.prototype[methodName]; + + jasmine.DOM.matchers[methodName] = function() + { + // If the actual value is a DOM node... + if (this.actual && this.actual.nodeType) + { + var result = matchers[methodName].apply(this, arguments); + this.actual = jasmine.DOM.elementToString(this.actual); + return result; + } + + if (originalMatcher) + return originalMatcher.apply(this, arguments); + + return false; + } + + } + + for (var methodName in matchers) + bindMatcher(methodName); + +})(); + +beforeEach(function() { + this.addMatchers(jasmine.DOM.matchers); +}); + +afterEach(function() { + jasmine.getFixtures().cleanUp(); +}); diff --git a/thirdparty/jquery-entwine/vendor/jquery-1.3.2.js b/thirdparty/jquery-entwine/vendor/jquery-1.3.2.js deleted file mode 100644 index 926357433..000000000 --- a/thirdparty/jquery-entwine/vendor/jquery-1.3.2.js +++ /dev/null @@ -1,4376 +0,0 @@ -/*! - * jQuery JavaScript Library v1.3.2 - * http://jquery.com/ - * - * Copyright (c) 2009 John Resig - * Dual licensed under the MIT and GPL licenses. - * http://docs.jquery.com/License - * - * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) - * Revision: 6246 - */ -(function(){ - -var - // Will speed up references to window, and allows munging its name. - window = this, - // Will speed up references to undefined, and allows munging its name. - undefined, - // Map over jQuery in case of overwrite - _jQuery = window.jQuery, - // Map over the $ in case of overwrite - _$ = window.$, - - jQuery = window.jQuery = window.$ = function( selector, context ) { - // The jQuery object is actually just the init constructor 'enhanced' - return new jQuery.fn.init( selector, context ); - }, - - // A simple way to check for HTML strings or ID strings - // (both of which we optimize for) - quickExpr = /^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/, - // Is it a simple selector - isSimple = /^.[^:#\[\.,]*$/; - -jQuery.fn = jQuery.prototype = { - init: function( selector, context ) { - // Make sure that a selection was provided - selector = selector || document; - - // Handle $(DOMElement) - if ( selector.nodeType ) { - this[0] = selector; - this.length = 1; - this.context = selector; - return this; - } - // Handle HTML strings - if ( typeof selector === "string" ) { - // Are we dealing with HTML string or an ID? - var match = quickExpr.exec( selector ); - - // Verify a match, and that no context was specified for #id - if ( match && (match[1] || !context) ) { - - // HANDLE: $(html) -> $(array) - if ( match[1] ) - selector = jQuery.clean( [ match[1] ], context ); - - // HANDLE: $("#id") - else { - var elem = document.getElementById( match[3] ); - - // Handle the case where IE and Opera return items - // by name instead of ID - if ( elem && elem.id != match[3] ) - return jQuery().find( selector ); - - // Otherwise, we inject the element directly into the jQuery object - var ret = jQuery( elem || [] ); - ret.context = document; - ret.selector = selector; - return ret; - } - - // HANDLE: $(expr, [context]) - // (which is just equivalent to: $(content).find(expr) - } else - return jQuery( context ).find( selector ); - - // HANDLE: $(function) - // Shortcut for document ready - } else if ( jQuery.isFunction( selector ) ) - return jQuery( document ).ready( selector ); - - // Make sure that old selector state is passed along - if ( selector.selector && selector.context ) { - this.selector = selector.selector; - this.context = selector.context; - } - - return this.setArray(jQuery.isArray( selector ) ? - selector : - jQuery.makeArray(selector)); - }, - - // Start with an empty selector - selector: "", - - // The current version of jQuery being used - jquery: "1.3.2", - - // The number of elements contained in the matched element set - size: function() { - return this.length; - }, - - // Get the Nth element in the matched element set OR - // Get the whole matched element set as a clean array - get: function( num ) { - return num === undefined ? - - // Return a 'clean' array - Array.prototype.slice.call( this ) : - - // Return just the object - this[ num ]; - }, - - // Take an array of elements and push it onto the stack - // (returning the new matched element set) - pushStack: function( elems, name, selector ) { - // Build a new jQuery matched element set - var ret = jQuery( elems ); - - // Add the old object onto the stack (as a reference) - ret.prevObject = this; - - ret.context = this.context; - - if ( name === "find" ) - ret.selector = this.selector + (this.selector ? " " : "") + selector; - else if ( name ) - ret.selector = this.selector + "." + name + "(" + selector + ")"; - - // Return the newly-formed element set - return ret; - }, - - // Force the current matched set of elements to become - // the specified array of elements (destroying the stack in the process) - // You should use pushStack() in order to do this, but maintain the stack - setArray: function( elems ) { - // Resetting the length to 0, then using the native Array push - // is a super-fast way to populate an object with array-like properties - this.length = 0; - Array.prototype.push.apply( this, elems ); - - return this; - }, - - // Execute a callback for every element in the matched set. - // (You can seed the arguments with an array of args, but this is - // only used internally.) - each: function( callback, args ) { - return jQuery.each( this, callback, args ); - }, - - // Determine the position of an element within - // the matched set of elements - index: function( elem ) { - // Locate the position of the desired element - return jQuery.inArray( - // If it receives a jQuery object, the first element is used - elem && elem.jquery ? elem[0] : elem - , this ); - }, - - attr: function( name, value, type ) { - var options = name; - - // Look for the case where we're accessing a style value - if ( typeof name === "string" ) - if ( value === undefined ) - return this[0] && jQuery[ type || "attr" ]( this[0], name ); - - else { - options = {}; - options[ name ] = value; - } - - // Check to see if we're setting style values - return this.each(function(i){ - // Set all the styles - for ( name in options ) - jQuery.attr( - type ? - this.style : - this, - name, jQuery.prop( this, options[ name ], type, i, name ) - ); - }); - }, - - css: function( key, value ) { - // ignore negative width and height values - if ( (key == 'width' || key == 'height') && parseFloat(value) < 0 ) - value = undefined; - return this.attr( key, value, "curCSS" ); - }, - - text: function( text ) { - if ( typeof text !== "object" && text != null ) - return this.empty().append( (this[0] && this[0].ownerDocument || document).createTextNode( text ) ); - - var ret = ""; - - jQuery.each( text || this, function(){ - jQuery.each( this.childNodes, function(){ - if ( this.nodeType != 8 ) - ret += this.nodeType != 1 ? - this.nodeValue : - jQuery.fn.text( [ this ] ); - }); - }); - - return ret; - }, - - wrapAll: function( html ) { - if ( this[0] ) { - // The elements to wrap the target around - var wrap = jQuery( html, this[0].ownerDocument ).clone(); - - if ( this[0].parentNode ) - wrap.insertBefore( this[0] ); - - wrap.map(function(){ - var elem = this; - - while ( elem.firstChild ) - elem = elem.firstChild; - - return elem; - }).append(this); - } - - return this; - }, - - wrapInner: function( html ) { - return this.each(function(){ - jQuery( this ).contents().wrapAll( html ); - }); - }, - - wrap: function( html ) { - return this.each(function(){ - jQuery( this ).wrapAll( html ); - }); - }, - - append: function() { - return this.domManip(arguments, true, function(elem){ - if (this.nodeType == 1) - this.appendChild( elem ); - }); - }, - - prepend: function() { - return this.domManip(arguments, true, function(elem){ - if (this.nodeType == 1) - this.insertBefore( elem, this.firstChild ); - }); - }, - - before: function() { - return this.domManip(arguments, false, function(elem){ - this.parentNode.insertBefore( elem, this ); - }); - }, - - after: function() { - return this.domManip(arguments, false, function(elem){ - this.parentNode.insertBefore( elem, this.nextSibling ); - }); - }, - - end: function() { - return this.prevObject || jQuery( [] ); - }, - - // For internal use only. - // Behaves like an Array's method, not like a jQuery method. - push: [].push, - sort: [].sort, - splice: [].splice, - - find: function( selector ) { - if ( this.length === 1 ) { - var ret = this.pushStack( [], "find", selector ); - ret.length = 0; - jQuery.find( selector, this[0], ret ); - return ret; - } else { - return this.pushStack( jQuery.unique(jQuery.map(this, function(elem){ - return jQuery.find( selector, elem ); - })), "find", selector ); - } - }, - - clone: function( events ) { - // Do the clone - var ret = this.map(function(){ - if ( !jQuery.support.noCloneEvent && !jQuery.isXMLDoc(this) ) { - // IE copies events bound via attachEvent when - // using cloneNode. Calling detachEvent on the - // clone will also remove the events from the orignal - // In order to get around this, we use innerHTML. - // Unfortunately, this means some modifications to - // attributes in IE that are actually only stored - // as properties will not be copied (such as the - // the name attribute on an input). - var html = this.outerHTML; - if ( !html ) { - var div = this.ownerDocument.createElement("div"); - div.appendChild( this.cloneNode(true) ); - html = div.innerHTML; - } - - return jQuery.clean([html.replace(/ jQuery\d+="(?:\d+|null)"/g, "").replace(/^\s*/, "")])[0]; - } else - return this.cloneNode(true); - }); - - // Copy the events from the original to the clone - if ( events === true ) { - var orig = this.find("*").andSelf(), i = 0; - - ret.find("*").andSelf().each(function(){ - if ( this.nodeName !== orig[i].nodeName ) - return; - - var events = jQuery.data( orig[i], "events" ); - - for ( var type in events ) { - for ( var handler in events[ type ] ) { - jQuery.event.add( this, type, events[ type ][ handler ], events[ type ][ handler ].data ); - } - } - - i++; - }); - } - - // Return the cloned set - return ret; - }, - - filter: function( selector ) { - return this.pushStack( - jQuery.isFunction( selector ) && - jQuery.grep(this, function(elem, i){ - return selector.call( elem, i ); - }) || - - jQuery.multiFilter( selector, jQuery.grep(this, function(elem){ - return elem.nodeType === 1; - }) ), "filter", selector ); - }, - - closest: function( selector ) { - var pos = jQuery.expr.match.POS.test( selector ) ? jQuery(selector) : null, - closer = 0; - - return this.map(function(){ - var cur = this; - while ( cur && cur.ownerDocument ) { - if ( pos ? pos.index(cur) > -1 : jQuery(cur).is(selector) ) { - jQuery.data(cur, "closest", closer); - return cur; - } - cur = cur.parentNode; - closer++; - } - }); - }, - - not: function( selector ) { - if ( typeof selector === "string" ) - // test special case where just one selector is passed in - if ( isSimple.test( selector ) ) - return this.pushStack( jQuery.multiFilter( selector, this, true ), "not", selector ); - else - selector = jQuery.multiFilter( selector, this ); - - var isArrayLike = selector.length && selector[selector.length - 1] !== undefined && !selector.nodeType; - return this.filter(function() { - return isArrayLike ? jQuery.inArray( this, selector ) < 0 : this != selector; - }); - }, - - add: function( selector ) { - return this.pushStack( jQuery.unique( jQuery.merge( - this.get(), - typeof selector === "string" ? - jQuery( selector ) : - jQuery.makeArray( selector ) - ))); - }, - - is: function( selector ) { - return !!selector && jQuery.multiFilter( selector, this ).length > 0; - }, - - hasClass: function( selector ) { - return !!selector && this.is( "." + selector ); - }, - - val: function( value ) { - if ( value === undefined ) { - var elem = this[0]; - - if ( elem ) { - if( jQuery.nodeName( elem, 'option' ) ) - return (elem.attributes.value || {}).specified ? elem.value : elem.text; - - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type == "select-one"; - - // Nothing was selected - if ( index < 0 ) - return null; - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - if ( option.selected ) { - // Get the specifc value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if ( one ) - return value; - - // Multi-Selects return an array - values.push( value ); - } - } - - return values; - } - - // Everything else, we just grab the value - return (elem.value || "").replace(/\r/g, ""); - - } - - return undefined; - } - - if ( typeof value === "number" ) - value += ''; - - return this.each(function(){ - if ( this.nodeType != 1 ) - return; - - if ( jQuery.isArray(value) && /radio|checkbox/.test( this.type ) ) - this.checked = (jQuery.inArray(this.value, value) >= 0 || - jQuery.inArray(this.name, value) >= 0); - - else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(value); - - jQuery( "option", this ).each(function(){ - this.selected = (jQuery.inArray( this.value, values ) >= 0 || - jQuery.inArray( this.text, values ) >= 0); - }); - - if ( !values.length ) - this.selectedIndex = -1; - - } else - this.value = value; - }); - }, - - html: function( value ) { - return value === undefined ? - (this[0] ? - this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g, "") : - null) : - this.empty().append( value ); - }, - - replaceWith: function( value ) { - return this.after( value ).remove(); - }, - - eq: function( i ) { - return this.slice( i, +i + 1 ); - }, - - slice: function() { - return this.pushStack( Array.prototype.slice.apply( this, arguments ), - "slice", Array.prototype.slice.call(arguments).join(",") ); - }, - - map: function( callback ) { - return this.pushStack( jQuery.map(this, function(elem, i){ - return callback.call( elem, i, elem ); - })); - }, - - andSelf: function() { - return this.add( this.prevObject ); - }, - - domManip: function( args, table, callback ) { - if ( this[0] ) { - var fragment = (this[0].ownerDocument || this[0]).createDocumentFragment(), - scripts = jQuery.clean( args, (this[0].ownerDocument || this[0]), fragment ), - first = fragment.firstChild; - - if ( first ) - for ( var i = 0, l = this.length; i < l; i++ ) - callback.call( root(this[i], first), this.length > 1 || i > 0 ? - fragment.cloneNode(true) : fragment ); - - if ( scripts ) - jQuery.each( scripts, evalScript ); - } - - return this; - - function root( elem, cur ) { - return table && jQuery.nodeName(elem, "table") && jQuery.nodeName(cur, "tr") ? - (elem.getElementsByTagName("tbody")[0] || - elem.appendChild(elem.ownerDocument.createElement("tbody"))) : - elem; - } - } -}; - -// Give the init function the jQuery prototype for later instantiation -jQuery.fn.init.prototype = jQuery.fn; - -function evalScript( i, elem ) { - if ( elem.src ) - jQuery.ajax({ - url: elem.src, - async: false, - dataType: "script" - }); - - else - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); - - if ( elem.parentNode ) - elem.parentNode.removeChild( elem ); -} - -function now(){ - return +new Date; -} - -jQuery.extend = jQuery.fn.extend = function() { - // copy reference to target object - var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options; - - // Handle a deep copy situation - if ( typeof target === "boolean" ) { - deep = target; - target = arguments[1] || {}; - // skip the boolean and the target - i = 2; - } - - // Handle case when target is a string or something (possible in deep copy) - if ( typeof target !== "object" && !jQuery.isFunction(target) ) - target = {}; - - // extend jQuery itself if only one argument is passed - if ( length == i ) { - target = this; - --i; - } - - for ( ; i < length; i++ ) - // Only deal with non-null/undefined values - if ( (options = arguments[ i ]) != null ) - // Extend the base object - for ( var name in options ) { - var src = target[ name ], copy = options[ name ]; - - // Prevent never-ending loop - if ( target === copy ) - continue; - - // Recurse if we're merging object values - if ( deep && copy && typeof copy === "object" && !copy.nodeType ) - target[ name ] = jQuery.extend( deep, - // Never move original objects, clone them - src || ( copy.length != null ? [ ] : { } ) - , copy ); - - // Don't bring in undefined values - else if ( copy !== undefined ) - target[ name ] = copy; - - } - - // Return the modified object - return target; -}; - -// exclude the following css properties to add px -var exclude = /z-?index|font-?weight|opacity|zoom|line-?height/i, - // cache defaultView - defaultView = document.defaultView || {}, - toString = Object.prototype.toString; - -jQuery.extend({ - noConflict: function( deep ) { - window.$ = _$; - - if ( deep ) - window.jQuery = _jQuery; - - return jQuery; - }, - - // See test/unit/core.js for details concerning isFunction. - // Since version 1.3, DOM methods and functions like alert - // aren't supported. They return false on IE (#2968). - isFunction: function( obj ) { - return toString.call(obj) === "[object Function]"; - }, - - isArray: function( obj ) { - return toString.call(obj) === "[object Array]"; - }, - - // check if an element is in a (or is an) XML document - isXMLDoc: function( elem ) { - return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" || - !!elem.ownerDocument && jQuery.isXMLDoc( elem.ownerDocument ); - }, - - // Evalulates a script in a global context - globalEval: function( data ) { - if ( data && /\S/.test(data) ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.getElementsByTagName("head")[0] || document.documentElement, - script = document.createElement("script"); - - script.type = "text/javascript"; - if ( jQuery.support.scriptEval ) - script.appendChild( document.createTextNode( data ) ); - else - script.text = data; - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); - } - }, - - nodeName: function( elem, name ) { - return elem.nodeName && elem.nodeName.toUpperCase() == name.toUpperCase(); - }, - - // args is for internal usage only - each: function( object, callback, args ) { - var name, i = 0, length = object.length; - - if ( args ) { - if ( length === undefined ) { - for ( name in object ) - if ( callback.apply( object[ name ], args ) === false ) - break; - } else - for ( ; i < length; ) - if ( callback.apply( object[ i++ ], args ) === false ) - break; - - // A special, fast, case for the most common use of each - } else { - if ( length === undefined ) { - for ( name in object ) - if ( callback.call( object[ name ], name, object[ name ] ) === false ) - break; - } else - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ){} - } - - return object; - }, - - prop: function( elem, value, type, i, name ) { - // Handle executable functions - if ( jQuery.isFunction( value ) ) - value = value.call( elem, i ); - - // Handle passing in a number to a CSS property - return typeof value === "number" && type == "curCSS" && !exclude.test( name ) ? - value + "px" : - value; - }, - - className: { - // internal only, use addClass("class") - add: function( elem, classNames ) { - jQuery.each((classNames || "").split(/\s+/), function(i, className){ - if ( elem.nodeType == 1 && !jQuery.className.has( elem.className, className ) ) - elem.className += (elem.className ? " " : "") + className; - }); - }, - - // internal only, use removeClass("class") - remove: function( elem, classNames ) { - if (elem.nodeType == 1) - elem.className = classNames !== undefined ? - jQuery.grep(elem.className.split(/\s+/), function(className){ - return !jQuery.className.has( classNames, className ); - }).join(" ") : - ""; - }, - - // internal only, use hasClass("class") - has: function( elem, className ) { - return elem && jQuery.inArray( className, (elem.className || elem).toString().split(/\s+/) ) > -1; - } - }, - - // A method for quickly swapping in/out CSS properties to get correct calculations - swap: function( elem, options, callback ) { - var old = {}; - // Remember the old values, and insert the new ones - for ( var name in options ) { - old[ name ] = elem.style[ name ]; - elem.style[ name ] = options[ name ]; - } - - callback.call( elem ); - - // Revert the old values - for ( var name in options ) - elem.style[ name ] = old[ name ]; - }, - - css: function( elem, name, force, extra ) { - if ( name == "width" || name == "height" ) { - var val, props = { position: "absolute", visibility: "hidden", display:"block" }, which = name == "width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ]; - - function getWH() { - val = name == "width" ? elem.offsetWidth : elem.offsetHeight; - - if ( extra === "border" ) - return; - - jQuery.each( which, function() { - if ( !extra ) - val -= parseFloat(jQuery.curCSS( elem, "padding" + this, true)) || 0; - if ( extra === "margin" ) - val += parseFloat(jQuery.curCSS( elem, "margin" + this, true)) || 0; - else - val -= parseFloat(jQuery.curCSS( elem, "border" + this + "Width", true)) || 0; - }); - } - - if ( elem.offsetWidth !== 0 ) - getWH(); - else - jQuery.swap( elem, props, getWH ); - - return Math.max(0, Math.round(val)); - } - - return jQuery.curCSS( elem, name, force ); - }, - - curCSS: function( elem, name, force ) { - var ret, style = elem.style; - - // We need to handle opacity special in IE - if ( name == "opacity" && !jQuery.support.opacity ) { - ret = jQuery.attr( style, "opacity" ); - - return ret == "" ? - "1" : - ret; - } - - // Make sure we're using the right name for getting the float value - if ( name.match( /float/i ) ) - name = styleFloat; - - if ( !force && style && style[ name ] ) - ret = style[ name ]; - - else if ( defaultView.getComputedStyle ) { - - // Only "float" is needed here - if ( name.match( /float/i ) ) - name = "float"; - - name = name.replace( /([A-Z])/g, "-$1" ).toLowerCase(); - - var computedStyle = defaultView.getComputedStyle( elem, null ); - - if ( computedStyle ) - ret = computedStyle.getPropertyValue( name ); - - // We should always get a number back from opacity - if ( name == "opacity" && ret == "" ) - ret = "1"; - - } else if ( elem.currentStyle ) { - var camelCase = name.replace(/\-(\w)/g, function(all, letter){ - return letter.toUpperCase(); - }); - - ret = elem.currentStyle[ name ] || elem.currentStyle[ camelCase ]; - - // From the awesome hack by Dean Edwards - // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 - - // If we're not dealing with a regular pixel number - // but a number that has a weird ending, we need to convert it to pixels - if ( !/^\d+(px)?$/i.test( ret ) && /^\d/.test( ret ) ) { - // Remember the original values - var left = style.left, rsLeft = elem.runtimeStyle.left; - - // Put in the new values to get a computed value out - elem.runtimeStyle.left = elem.currentStyle.left; - style.left = ret || 0; - ret = style.pixelLeft + "px"; - - // Revert the changed values - style.left = left; - elem.runtimeStyle.left = rsLeft; - } - } - - return ret; - }, - - clean: function( elems, context, fragment ) { - context = context || document; - - // !context.createElement fails in IE with an error but returns typeof 'object' - if ( typeof context.createElement === "undefined" ) - context = context.ownerDocument || context[0] && context[0].ownerDocument || document; - - // If a single string is passed in and it's a single tag - // just do a createElement and skip the rest - if ( !fragment && elems.length === 1 && typeof elems[0] === "string" ) { - var match = /^<(\w+)\s*\/?>$/.exec(elems[0]); - if ( match ) - return [ context.createElement( match[1] ) ]; - } - - var ret = [], scripts = [], div = context.createElement("div"); - - jQuery.each(elems, function(i, elem){ - if ( typeof elem === "number" ) - elem += ''; - - if ( !elem ) - return; - - // Convert html string into DOM nodes - if ( typeof elem === "string" ) { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(/(<(\w+)[^>]*?)\/>/g, function(all, front, tag){ - return tag.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i) ? - all : - front + ">"; - }); - - // Trim whitespace, otherwise indexOf won't work as expected - var tags = elem.replace(/^\s+/, "").substring(0, 10).toLowerCase(); - - var wrap = - // option or optgroup - !tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - tags.match(/^<(thead|tbody|tfoot|colg|cap)/) && - [ 1, "", "
" ] || - - !tags.indexOf("", "" ] || - - // matched above - (!tags.indexOf("", "" ] || - - !tags.indexOf("", "" ] || - - // IE can't serialize and