diff --git a/forms/CalendarDateField.php b/forms/CalendarDateField.php index bb346fdf8..df4687425 100755 --- a/forms/CalendarDateField.php +++ b/forms/CalendarDateField.php @@ -29,12 +29,12 @@ class CalendarDateField extends DateField { // javascript: concrete - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.class.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.specifity.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.matches.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.dat.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.concrete.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.class.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.specifity.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.matches.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.dat.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.concrete.js'); // javascript: custom Requirements::javascript(SAPPHIRE_DIR . '/javascript/CalendarDateField.js'); diff --git a/forms/TabSet.php b/forms/TabSet.php index 6ae705cc0..c43008343 100644 --- a/forms/TabSet.php +++ b/forms/TabSet.php @@ -60,12 +60,12 @@ class TabSet extends CompositeField { Requirements::css(SAPPHIRE_DIR . '/thirdparty/jquery-ui-themes/smoothness/ui.tabs.css'); // concrete - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.class.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.specifity.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.matches.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.dat.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.concrete.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.class.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.specifity.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.matches.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.dat.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.concrete.js'); Requirements::javascript(SAPPHIRE_DIR . '/javascript/TabSet.js'); diff --git a/security/Security.php b/security/Security.php index 3bdd12c80..015c30212 100644 --- a/security/Security.php +++ b/security/Security.php @@ -344,12 +344,12 @@ class Security extends Controller { Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-ui/ui.tabs.js'); // concrete - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.class.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.specifity.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.selector.matches.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.dat.js'); - Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/jquery.concrete.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.class.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.specifity.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-selector/src/jquery.selector.matches.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.dat.js'); + Requirements::javascript(SAPPHIRE_DIR . '/thirdparty/jquery-concrete/src/jquery.concrete.js'); Requirements::css(THIRDPARTY_DIR . '/jquery/themes/smoothness/ui.all.css'); Requirements::css(THIRDPARTY_DIR . '/jquery/themes/smoothness/ui.tabs.css'); diff --git a/tests/forms/UniqueTextFieldTest.php b/tests/forms/UniqueTextFieldTest.php new file mode 100644 index 000000000..e69de29bb diff --git a/thirdparty/jquery-concrete/.gitignore b/thirdparty/jquery-concrete/.gitignore new file mode 100644 index 000000000..eb4065740 --- /dev/null +++ b/thirdparty/jquery-concrete/.gitignore @@ -0,0 +1,2 @@ +vendor/ +spec/ diff --git a/thirdparty/jquery-concrete/.piston.yml b/thirdparty/jquery-concrete/.piston.yml new file mode 100644 index 000000000..b0c8e4c56 --- /dev/null +++ b/thirdparty/jquery-concrete/.piston.yml @@ -0,0 +1,8 @@ +--- +format: 1 +handler: + commit: c857ed5d684031115a2bb369f601c7147a2c69bc + branch: master +lock: false +repository_url: git://github.com/hafriedlander/jquery.concrete.git +repository_class: Piston::Git::Repository diff --git a/thirdparty/jquery-concrete/LICENSE b/thirdparty/jquery-concrete/LICENSE new file mode 100644 index 000000000..5a899dce7 --- /dev/null +++ b/thirdparty/jquery-concrete/LICENSE @@ -0,0 +1,10 @@ +Copyright (C) 2009 Hamish Friedlander (hamish@silverstripe.com) and SilverStripe Limited (www.silverstripe.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of Hamish Friedlander nor SilverStripe nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/thirdparty/jquery-concrete/README.textile b/thirdparty/jquery-concrete/README.textile new file mode 100644 index 000000000..9dc4c5c56 --- /dev/null +++ b/thirdparty/jquery-concrete/README.textile @@ -0,0 +1,267 @@ +h1. Concrete - Support for ConcreteUI programming in jQuery + +A basic desire for jQuery programming is some sort of OO or other organisational method for code. For your consideration, +we provide a library for ConcreteUI style programming. In ConcreteUI you attach behavioral code to DOM objects. Concrete extends this +concept beyond what is provided by other libraries to provide a very easy to use system with class like, ploymorphic, namespaced properties + +h2. Basic use + +h4. First intro + +To attach methods to DOM nodes, call the `concrete` function on a jQuery selector object, passing a hash listing the method names and bodys + +

+  $('div').concrete({
+    foo: function(..){..},
+    bar: function(..){..}
+  });
+
+ +You can then call those methods on any jQuery object. + +

+  $('#a').foo();
+
+ +Any elements in the jQuery selection that match the selector used during definition ('div' in this example) will have foo called with that element +set as this. Any other objects are skipped. The return value will be the return value of foo() for the last matched DOM object in the set + +h4. A proper example + +Given this DOM structure: + +

+  
+    
Internal text
+
+
Nonsense
+ +
+ +And this concrete definition + +

+  $('.internal_text').concrete({
+    foo: function(){ console.log(this.text()); }
+  });
+  $('.attribute_text').concrete({
+    foo: function(){ console.log(this.attr('rel')); }
+  });
+
+ +Then this call + +

+  $('div').foo();
+
+ +Will log this to the console + +

+  Internal text
+  Attribute text  
+
+ +h4. Limitations + +When defining methods, the jQuery object that concrete is called on must be a plain selector, without context. These examples will not work + +

+  $('div', el).concrete(...)
+  $([ela, elb, elc]).concrete(...)
+  $('
').concrete(...) +
+ +h2. Live + +The definitions you provide are not bound to the elements that match at definition time. You can declare behaviour prior to the DOM existing in any +form (i.e. prior to DOMReady) and later calls will function correctly. + +h2. Selector specifity + +When there are two definitions for a particular method on a particular DOM node, the function with the most _specific_ selector is used. +_Specifity_ is calculated as defined by the CSS 2/3 spec. This can be seen as _subclassing_ applied to behaviour. + +Another example. Given this DOM structure + +

+  
+    
Internal text
+
+
Nonsense
+ +
+ +And this concrete definition + +

+  $('div').concrete({
+    foo: function(){ console.log(this.text()); }
+  });
+  $('.attribute_text').concrete({
+    foo: function(){ console.log(this.attr('rel')); }
+  });
+
+ +Then this call + +

+  $('div').foo();
+
+ +Will log this to the console + +

+  Internal text
+  Attribute text
+  Nonsense
+
+ +h2. Events + +If you declare a function with a name starting with 'on', then instead of defining that function, it will be bound to an event of that +name. Just like other functions this binding will be live, and only the most specific definition will be used + +

+  
+    
+  
+    
Background will turn blue when clicked on
+
Will also have blue background when clicked on
+
Will have green text when clicked on. Background color will not change
+ +
+ +h2. Constructors / Destructors + +Declaring a function with the name `onmatch` will create a behavior that is called on each object when it matches. Likewise, `onunmatch` will +be called when an object that did match this selector stops matching it (because it is removed, or because you've changed its properties). + +Note that an onunmatch block must be paired with an onmatch block - an onunmatch without an onmatch _in the same concrete definition block_ is illegal + +Like other functions, only the most specific definition will be used. However, because property changes are not atomic, this may not work as you +expect. + +h2. Namespaces + +To avoid name clashes, to allow multiple bindings to the same event, and to generally seperate a set of functions from other code you can use namespaces + +

+  $('div').concrete('foo.bar', function($){ return {
+      baz: function(){}
+  }});
+
+ +You can then call these functions like this: + +

+  $('div').concrete('foo.bar').baz()
+
+ +Namespaced functions work just like regular functions (`this` is still set to a matching DOM Node). However, specifity is calculated per namespace. +This is particularly useful for events, because given this: + +

+  $('div').concrete({
+    onclick: function(){ this.css({backgroundColor: 'blue'}); }
+  });
+  
+  $('div').concrete('foo', function($){ return {
+      onclick: function(){ this.css({color: 'green'}); }
+  }});
+
+ +Clicking on a div will change the background **and** foreground color. + +This is particularly important when writing reusable code, since otherwise you can't know before hand whether your event handler will be called or not + +Although a namespace can be any string, best practise is to name them with dotted-identifier notation. + +h4. Namespaces and scope (or What the hell's up with that ugly function closure) + +Inside a namespace definition, functions remember the namespace they are in, and calls to other functions will be looked up inside that namespace first. +Where they don't exist, they will be looked up in the base namespace + +

+  $('div').concrete('foo', {
+    bar: function() { this.baz(); this.qux(); }
+    baz: function() { console.log('baz'); }
+  })
+  
+  $('div').concrete({
+    qux: function() { console.log('qux'); }
+  })
+
+ +Will print baz, qux to the console + +Note that 'exists' means that a function is declared in this namespace for _any_ selector, not just a matching one. Given the dom + +

+  
Internal text
+
+ +And the concrete definitions + +

+  $('div').concrete('foo', {
+    bar: function() { this.baz(); }
+  })
+  
+  $('span').concrete('foo' {
+    baz: function() { console.log('a'); }
+  
+  $('div').concrete({
+    baz: function() { console.log('b'); }
+  })
+
+ +Then doing $('div').bar(); will _not_ display b. Even though the span rule could never match a div, because baz is defined for some rule in the foo namespace, the base namespace will never be checked + +h4. Forcing base + +In some situations (such as the last example) you may want to force using the base namespace. In this case you can call concrete without any arguments. For example, if the first definition in the previous example was + +

+  $('div').concrete('foo', {
+    bar: function() { this.concrete().baz(); }
+  })
+
+ +Then b _would_ be output to the console. It is up to the developer to decide when they need to be explicit about using the base namespace + +h4. Using + +Sometimes a block outside of a namespace will need to refer to that namespace repeatedly. By passing a function to the concrete function, you can change the looked-up namespace + +

+  $('div').concrete('foo', {
+    bar: function() { console.log('a'); }
+  })
+  
+  $('div').concrete('foo', function(){
+    this.bar();
+  });
+
+ +This equivilent to /with/ in javascript, and just like /with/, care should be taken to only use this construct in situations that merit it. + + + + + + + + + + + + \ No newline at end of file diff --git a/thirdparty/jquery-concrete/jquery.concrete.js b/thirdparty/jquery-concrete/src/jquery.concrete.js similarity index 85% rename from thirdparty/jquery-concrete/jquery.concrete.js rename to thirdparty/jquery-concrete/src/jquery.concrete.js index 4af33ff21..769eac814 100644 --- a/thirdparty/jquery-concrete/jquery.concrete.js +++ b/thirdparty/jquery-concrete/src/jquery.concrete.js @@ -10,7 +10,10 @@ var console; /** Utility to optionally display warning messages depending on level */ var warn = function(message, level) { - if (level <= $.concrete.warningLevel && console && console.log) console.log(message); + if (level <= $.concrete.warningLevel && console && console.log) { + console.warn(message); + if (console.trace) console.trace(); + } } /** A property definition */ @@ -100,16 +103,28 @@ var console; name = name || '__base'; this.name = name; - this.proxies = {}; this.store = {}; namespaces[name] = this; - var self = this; - this.$ = function() { - var jq = $.apply(window, arguments); - jq.namespace = self; - return jq; + 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(jq){ + this.selector = jq.selector; this.context = jq.context; this.setArray($.makeArray(jq)); + } + this.injectee = subfn.prototype = new $(); + + // And then we provide an overriding $ that returns objects of our new Class + this.$ = function() { + return new subfn($.apply(window, arguments)); + } + // 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.$, $); } }, @@ -148,7 +163,7 @@ var console; var one = this.one(name, 'func'); var prxy = function() { - var rv, ctx = $(this.__context || this); + var rv, ctx = $(this); var i = ctx.length; while (i--) rv = one(ctx[i], arguments); @@ -158,40 +173,23 @@ var console; return prxy; }, - build_jquery_injection: function(name) { - if (!$.fn[name]) { - $.fn[name] = function() { - // Try bound namespace - var namespace = this.namespace; - // If that doesn't exist, or doesn't have function, try root namespace - if (!namespace || !namespace.proxies[name]) namespace = namespaces.__base; - // If that doesn't exist, throw error - if (!namespace.proxies[name]) { - throw new ReferenceError('Concrete function '+name+' not found in ' + (this.namespace ? ('namespace '+this.namespace.name+' or root namespace') : 'root namespace')); - } - - namespace.__context = null; - return namespace.proxies[name].apply(this, arguments); - } - $.fn[name].concrete = true; - } - - if (!$.fn[name].concrete) { - warn('Warning: Concrete function '+name+' clashes with regular jQuery function - concrete function will not be callable directly on jQuery object', $.concrete.WARN_LEVEL_IMPORTANT); - } - }, - bind_proxy: function(selector, name, func) { var funcs = this.store[name] || (this.store[name] = []) ; var rule = funcs[funcs.length] = Rule(selector, name); rule.func = func; funcs.sort(Rule.compare); - if (!this.proxies[name]) this.proxies[name] = this.build_proxy(name); - this.build_jquery_injection(name); + if (!this.injectee.hasOwnProperty(name)) { + this.injectee[name] = this.build_proxy(name); + this.injectee[name].concrete = true; + } + + if (!this.injectee[name].concrete) { + warn('Warning: Concrete function '+name+' clashes with regular jQuery function - concrete function will not be callable directly on jQuery object', $.concrete.WARN_LEVEL_IMPORTANT); + } }, - bind_event: function(selector, name, func) { + bind_event: function(selector, name, func, event) { var funcs = this.store[name] || (this.store[name] = []) ; var rule = funcs[funcs.length] = Rule(selector, name); rule.func = func; @@ -199,7 +197,7 @@ var console; if (!funcs.proxy) { funcs.proxy = this.build_proxy(name); - $(selector.selector).live(match[1], funcs.proxy); + $(selector.selector).live(event, funcs.proxy); } }, @@ -240,22 +238,36 @@ var console; }, add: function(selector, data) { - for (var k in data) { - var v = data[k]; + var k, v, match, event; + + for (k in data) { + v = data[k]; if ($.isFunction(v)) { if (k == 'onmatch' || k == 'onunmatch') { this.bind_condesc(selector, k, v); } else if (match = k.match(/^on(.*)/)) { - this.bind_event(selector, k, v); + event = match[1]; + + if (!$.fn.liveHover && $.concrete.event_needs_extensions[event]) { + warn('Event '+event+' requires live-extensions to function, which does not seem to be present', $.concrete.WARN_LEVEL_IMPORTANT); + } + else if (event == 'submit') { + warn('Event submit not currently supported', $.concrete.WARN_LEVEL_IMPORTANT); + } + else if (event == 'focus' || event == 'blur') { + warn('Event '+event+' not supported - use focusin / focusout instead', $.concrete.WARN_LEVEL_IMPORTANT); + } + + this.bind_event(selector, k, v, event); } else { this.bind_proxy(selector, k, v); } } else { - var g, s; + var g, s, p; if (k.charAt(0) != k.charAt(0).toUpperCase()) warn('Concrete property '+k+' does not start with a capital letter', $.concrete.WARN_LEVEL_BESTPRACTISE); @@ -263,7 +275,7 @@ var console; g = v.getter(); s = v.setter(); } else { - var p = $.property({initial: v}); g = p.getter(); s = p.setter(); + p = $.property({initial: v}); g = p.getter(); s = p.setter(); } g.pname = s.pname = k; @@ -314,8 +326,7 @@ var console; i++ } - namespace.proxies.__context = this; - return namespace.proxies; + return namespace.$(this); } /** @@ -364,7 +375,12 @@ var console; /** * Warning level. Set to a higher level to get warnings dumped to console. */ - warningLevel: 0 + warningLevel: 0, + + /** + * These events need the live-extensions plugin + */ + event_needs_extensions: { mouseenter: true, mouseleave: true, change: true, focusin: true, focusout: true } } var check_id = null; diff --git a/thirdparty/jquery-concrete/jquery.dat.js b/thirdparty/jquery-concrete/src/jquery.dat.js similarity index 100% rename from thirdparty/jquery-concrete/jquery.dat.js rename to thirdparty/jquery-concrete/src/jquery.dat.js diff --git a/thirdparty/jquery-selector/.gitignore b/thirdparty/jquery-selector/.gitignore new file mode 100644 index 000000000..60a337fb8 --- /dev/null +++ b/thirdparty/jquery-selector/.gitignore @@ -0,0 +1,2 @@ +vendor/ +test/ \ No newline at end of file diff --git a/thirdparty/jquery-selector/.piston.yml b/thirdparty/jquery-selector/.piston.yml new file mode 100644 index 000000000..7b5417f99 --- /dev/null +++ b/thirdparty/jquery-selector/.piston.yml @@ -0,0 +1,8 @@ +--- +format: 1 +handler: + commit: 2d129e2754ba864a5c538c3be3355e24f49f1939 + branch: master +lock: false +repository_url: git://github.com/hafriedlander/jquery.selector.git +repository_class: Piston::Git::Repository diff --git a/thirdparty/jquery-selector/LICENSE b/thirdparty/jquery-selector/LICENSE new file mode 100644 index 000000000..5a899dce7 --- /dev/null +++ b/thirdparty/jquery-selector/LICENSE @@ -0,0 +1,10 @@ +Copyright (C) 2009 Hamish Friedlander (hamish@silverstripe.com) and SilverStripe Limited (www.silverstripe.com) +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + * Neither the name of Hamish Friedlander nor SilverStripe nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file diff --git a/thirdparty/jquery-selector/README.textile b/thirdparty/jquery-selector/README.textile new file mode 100644 index 000000000..ac3acada4 --- /dev/null +++ b/thirdparty/jquery-selector/README.textile @@ -0,0 +1,32 @@ +h1. jQuery Selector + +h3. Selector tools and reverse mapping for jQuery + +* Parse and examine the AST for a selector +* Calculate the specifity of a selector +* Determine if a single element matches a selector ($().is equivilent) much faster that jQuery + +h3. Intro + +jQuery has an excellent CSS 3 selector engine built in called Sizzle. However, it's clear focus is on filtering a set of elements down to the set that matches a selector. + +jQuery.concrete has a usage pattern quite different from that optimized for by Sizzle. It reuses a small set of selectors (making a more complicated initial parsing step acceptable) +and checks if a single element matches those selectors. In this case, Sizzle can be quite slow. + +h3. Usage + +Usual usage of jQuery selector: + +var sel = $.selector('#foo'); +sel.matches(element); + +element must be a raw DOM object, not a jQuery element, sequence of elements or anything else + +h3. Compatibility + +jQuery.selector aims to be 100% compatible with Sizzle (except a couple of corner cases, noted below). Sizzle implements most of the CSS 3 spec plus several extensions. + +One set of extensions Sizzle has is a set of pseudo-classes that filter the currently selected set. These pseudo-classes are ':first', ':last', ':even', ':odd', ':eq', ':nth', ':lt', ':gt'. +These pseudo-classes are not supported in jQuery.selector, as they don't make sense when the working set is always a single element. + +jQuery.selector currently passes the jQuery selector unit test suite, with the exception of the psuedo-classes mentioned above diff --git a/thirdparty/jquery-concrete/jquery.class.js b/thirdparty/jquery-selector/src/jquery.class.js similarity index 100% rename from thirdparty/jquery-concrete/jquery.class.js rename to thirdparty/jquery-selector/src/jquery.class.js diff --git a/thirdparty/jquery-concrete/jquery.selector.js b/thirdparty/jquery-selector/src/jquery.selector.js similarity index 100% rename from thirdparty/jquery-concrete/jquery.selector.js rename to thirdparty/jquery-selector/src/jquery.selector.js diff --git a/thirdparty/jquery-concrete/jquery.selector.matches.js b/thirdparty/jquery-selector/src/jquery.selector.matches.js similarity index 100% rename from thirdparty/jquery-concrete/jquery.selector.matches.js rename to thirdparty/jquery-selector/src/jquery.selector.matches.js diff --git a/thirdparty/jquery-concrete/jquery.selector.specifity.js b/thirdparty/jquery-selector/src/jquery.selector.specifity.js similarity index 100% rename from thirdparty/jquery-concrete/jquery.selector.specifity.js rename to thirdparty/jquery-selector/src/jquery.selector.specifity.js