public
Description: Prototype JavaScript framework
Homepage: http://prototypejs.org/
Clone URL: git://github.com/sstephenson/prototype.git
Selector.patterns should be represented as an ordered structure. [#315 
state:resolved]
Fri Oct 10 12:19:51 -0700 2008
commit  b065eed3b8d7352b383dd007952ff065f8aca56d
tree    0881dc480e86cf9e1804c7801c40707ae74c1ddc
parent  3e2e8d48b58061a993d1c1323c50c13554027cde
...
 
 
1
2
3
...
1
2
3
4
5
0
@@ -1,3 +1,5 @@
0
+* Selector.patterns should be represented as an ordered structure. (ADO, kangax)
0
+
0
 * Work around an issue with assigning a variable within a "return" statement in V8/Google Chrome. (Chris Lear, Oleg K, Maikel Punie, Andrew Dupont)
0
 
0
 *1.6.0.3* (September 29, 2008)
...
54
55
56
57
 
58
59
60
...
66
67
68
69
70
 
 
 
71
72
73
 
 
74
75
76
...
84
85
86
87
 
88
89
90
...
93
94
95
96
97
98
99
 
 
 
 
 
100
101
102
...
136
137
138
139
 
140
141
142
143
144
 
 
 
145
146
147
148
149
 
 
150
151
152
...
226
227
228
229
 
230
231
232
233
234
235
236
 
 
 
 
237
238
239
...
301
302
303
304
 
305
306
307
308
309
310
 
 
 
 
311
312
313
314
315
316
317
318
319
320
 
 
 
 
 
 
 
321
322
323
...
54
55
56
 
57
58
59
60
...
66
67
68
 
 
69
70
71
72
 
 
73
74
75
76
77
...
85
86
87
 
88
89
90
91
...
94
95
96
 
 
 
 
97
98
99
100
101
102
103
104
...
138
139
140
 
141
142
143
144
 
 
145
146
147
148
149
150
 
 
151
152
153
154
155
...
229
230
231
 
232
233
234
235
236
 
 
 
237
238
239
240
241
242
243
...
305
306
307
 
308
309
310
 
 
 
 
311
312
313
314
315
316
 
 
 
 
 
 
 
 
317
318
319
320
321
322
323
324
325
326
0
@@ -54,7 +54,7 @@ var Selector = Class.create({
0
   
0
   compileMatcher: function() {
0
     var e = this.expression, ps = Selector.patterns, h = Selector.handlers, 
0
-        c = Selector.criteria, le, p, m;
0
+        c = Selector.criteria, le, p, m, len = ps.length, name;
0
 
0
     if (Selector._cache[e]) {
0
       this.matcher = Selector._cache[e]; 
0
@@ -66,11 +66,12 @@ var Selector = Class.create({
0
 
0
     while (e && le != e && (/\S/).test(e)) {
0
       le = e;
0
-      for (var i in ps) {
0
-        p = ps[i];
0
+      for (var i=0; i<len; i++) {
0
+        p = ps[i].re;
0
+        name = ps[i].name;
0
         if (m = e.match(p)) {
0
-          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
0
-            new Template(c[i]).evaluate(m));
0
+          this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
0
+            new Template(c[name]).evaluate(m));
0
           e = e.replace(m[0], '');
0
           break;
0
         }
0
@@ -84,7 +85,7 @@ var Selector = Class.create({
0
   
0
   compileXPathMatcher: function() {
0
     var e = this.expression, ps = Selector.patterns,
0
-        x = Selector.xpath, le, m;
0
+        x = Selector.xpath, le, m, len = ps.length, name;
0
 
0
     if (Selector._cache[e]) {
0
       this.xpath = Selector._cache[e]; return;
0
@@ -93,10 +94,11 @@ var Selector = Class.create({
0
     this.matcher = ['.//*'];
0
     while (e && le != e && (/\S/).test(e)) {
0
       le = e;
0
-      for (var i in ps) {
0
-        if (m = e.match(ps[i])) {
0
-          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) : 
0
-            new Template(x[i]).evaluate(m));
0
+      for (var i=0; i<len; i++) {
0
+        name = ps[i].name;
0
+        if (m = e.match(ps[i].re)) {
0
+          this.matcher.push(Object.isFunction(x[name]) ? x[name](m) : 
0
+            new Template(x[name]).evaluate(m));
0
           e = e.replace(m[0], '');
0
           break;
0
         }
0
@@ -136,17 +138,18 @@ var Selector = Class.create({
0
     this.tokens = [];
0
 
0
     var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
0
-    var le, p, m;
0
+    var le, p, m, len = ps.length, name;
0
     
0
     while (e && le !== e && (/\S/).test(e)) {
0
       le = e;
0
-      for (var i in ps) {
0
-        p = ps[i];
0
+      for (var i=0; i<len; i++) {
0
+        p = ps[i].re;
0
+        name = ps[i].name;
0
         if (m = e.match(p)) {
0
           // use the Selector.assertions methods unless the selector
0
           // is too complex.
0
-          if (as[i]) {
0
-            this.tokens.push([i, Object.clone(m)]);
0
+          if (as[name]) {
0
+            this.tokens.push([name, Object.clone(m)]);
0
             e = e.replace(m[0], '');
0
           } else {
0
             // reluctantly do a document-wide search
0
@@ -226,14 +229,15 @@ Object.extend(Selector, {
0
       'enabled':     "[not(@disabled) and (@type!='hidden')]",
0
       'not': function(m) {
0
         var e = m[6], p = Selector.patterns,
0
-            x = Selector.xpath, le, v;
0
+            x = Selector.xpath, le, v, len = p.length, name;
0
             
0
         var exclusion = [];
0
         while (e && le != e && (/\S/).test(e)) {
0
           le = e;
0
-          for (var i in p) {
0
-            if (m = e.match(p[i])) {
0
-              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
0
+          for (var i=0; i<len; i++) {
0
+            name = p[i].name
0
+            if (m = e.match(p[i].re)) {
0
+              v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
0
               exclusion.push("(" + v.substring(1, v.length - 1) + ")");
0
               e = e.replace(m[0], '');
0
               break;
0
@@ -301,23 +305,22 @@ Object.extend(Selector, {
0
     laterSibling: 'c = "laterSibling";'
0
   },
0
 
0
-  patterns: {
0
+  patterns: [
0
     // combinators must be listed first
0
     // (and descendant needs to be last combinator)
0
-    laterSibling: /^\s*~\s*/,
0
-    child:        /^\s*>\s*/,
0
-    adjacent:     /^\s*\+\s*/,
0
-    descendant:   /^\s/,
0
+    { name: 'laterSibling', re: /^\s*~\s*/ },
0
+    { name: 'child',        re: /^\s*>\s*/ },
0
+    { name: 'adjacent',     re: /^\s*\+\s*/ },
0
+    { name: 'descendant',   re: /^\s/ },
0
 
0
     // selectors follow
0
-    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
0
-    id:           /^#([\w\-\*]+)(\b|$)/,
0
-    className:    /^\.([\w\-\*]+)(\b|$)/,
0
-    pseudo:      
0
-/^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/,
0
-    attrPresence: /^\[((?:[\w]+:)?[\w]+)\]/,
0
-    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
0
-  },
0
+    { name: 'tagName',      re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
0
+    { name: 'id',           re: /^#([\w\-\*]+)(\b|$)/ },
0
+    { name: 'className',    re: /^\.([\w\-\*]+)(\b|$)/ },
0
+    { name: 'pseudo',       re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
0
+    { name: 'attrPresence', re: /^\[((?:[\w]+:)?[\w]+)\]/ },
0
+    { name: 'attr',         re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
0
+  ],
0
   
0
   // for Selector.match and Element#match
0
   assertions: {

Comments