Diffstat (limited to 'frontend/gamma/js/MochiKit/Selector.js') (more/less context) (ignore whitespace changes)
-rw-r--r-- | frontend/gamma/js/MochiKit/Selector.js | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/frontend/gamma/js/MochiKit/Selector.js b/frontend/gamma/js/MochiKit/Selector.js index 6aec892..3187fe9 100644 --- a/frontend/gamma/js/MochiKit/Selector.js +++ b/frontend/gamma/js/MochiKit/Selector.js | |||
@@ -1,387 +1,393 @@ | |||
1 | /*** | 1 | /*** |
2 | 2 | ||
3 | MochiKit.Selector 1.5 | 3 | MochiKit.Selector 1.5 |
4 | 4 | ||
5 | See <http://mochikit.com/> for documentation, downloads, license, etc. | 5 | See <http://mochikit.com/> for documentation, downloads, license, etc. |
6 | 6 | ||
7 | (c) 2005 Bob Ippolito and others. All rights Reserved. | 7 | (c) 2005 Bob Ippolito and others. All rights Reserved. |
8 | 8 | ||
9 | ***/ | 9 | ***/ |
10 | 10 | ||
11 | MochiKit.Base._module('Selector', '1.5', ['Base', 'DOM', 'Iter']); | 11 | MochiKit.Base.module(MochiKit, 'Selector', '1.5', ['Base', 'DOM', 'Iter']); |
12 | 12 | ||
13 | MochiKit.Selector.Selector = function (expression) { | 13 | MochiKit.Selector.Selector = function (expression) { |
14 | this.params = {classNames: [], pseudoClassNames: []}; | 14 | this.params = {classNames: [], pseudoClassNames: []}; |
15 | this.expression = expression.toString().replace(/(^\s+|\s+$)/g, ''); | 15 | this.expression = expression.toString().replace(/(^\s+|\s+$)/g, ''); |
16 | this.parseExpression(); | 16 | this.parseExpression(); |
17 | this.compileMatcher(); | 17 | this.compileMatcher(); |
18 | }; | 18 | }; |
19 | 19 | ||
20 | MochiKit.Selector.Selector.prototype = { | 20 | MochiKit.Selector.Selector.prototype = { |
21 | /*** | 21 | /*** |
22 | 22 | ||
23 | Selector class: convenient object to make CSS selections. | 23 | Selector class: convenient object to make CSS selections. |
24 | 24 | ||
25 | ***/ | 25 | ***/ |
26 | __class__: MochiKit.Selector.Selector, | 26 | __class__: MochiKit.Selector.Selector, |
27 | 27 | ||
28 | /** @id MochiKit.Selector.Selector.prototype.parseExpression */ | 28 | /** @id MochiKit.Selector.Selector.prototype.parseExpression */ |
29 | parseExpression: function () { | 29 | parseExpression: function () { |
30 | function abort(message) { | 30 | function abort(message) { |
31 | throw 'Parse error in selector: ' + message; | 31 | throw 'Parse error in selector: ' + message; |
32 | } | 32 | } |
33 | 33 | ||
34 | if (this.expression == '') { | 34 | if (this.expression == '') { |
35 | abort('empty expression'); | 35 | abort('empty expression'); |
36 | } | 36 | } |
37 | 37 | ||
38 | var repr = MochiKit.Base.repr; | 38 | var repr = MochiKit.Base.repr; |
39 | var params = this.params; | 39 | var params = this.params; |
40 | var expr = this.expression; | 40 | var expr = this.expression; |
41 | var match, modifier, clause, rest; | 41 | var match, modifier, clause, rest; |
42 | while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!^$*]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { | 42 | while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!^$*]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) { |
43 | params.attributes = params.attributes || []; | 43 | params.attributes = params.attributes || []; |
44 | params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); | 44 | params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''}); |
45 | expr = match[1]; | 45 | expr = match[1]; |
46 | } | 46 | } |
47 | 47 | ||
48 | if (expr == '*') { | 48 | if (expr == '*') { |
49 | return this.params.wildcard = true; | 49 | return this.params.wildcard = true; |
50 | } | 50 | } |
51 | 51 | ||
52 | while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+(?:\([^)]*\))?)(.*)/i)) { | 52 | while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+(?:\([^)]*\))?)(.*)/i)) { |
53 | modifier = match[1]; | 53 | modifier = match[1]; |
54 | clause = match[2]; | 54 | clause = match[2]; |
55 | rest = match[3]; | 55 | rest = match[3]; |
56 | switch (modifier) { | 56 | switch (modifier) { |
57 | case '#': | 57 | case '#': |
58 | params.id = clause; | 58 | params.id = clause; |
59 | break; | 59 | break; |
60 | case '.': | 60 | case '.': |
61 | params.classNames.push(clause); | 61 | params.classNames.push(clause); |
62 | break; | 62 | break; |
63 | case ':': | 63 | case ':': |
64 | params.pseudoClassNames.push(clause); | 64 | params.pseudoClassNames.push(clause); |
65 | break; | 65 | break; |
66 | case '': | 66 | case '': |
67 | case undefined: | 67 | case undefined: |
68 | params.tagName = clause.toUpperCase(); | 68 | params.tagName = clause.toUpperCase(); |
69 | break; | 69 | break; |
70 | default: | 70 | default: |
71 | abort(repr(expr)); | 71 | abort(repr(expr)); |
72 | } | 72 | } |
73 | expr = rest; | 73 | expr = rest; |
74 | } | 74 | } |
75 | 75 | ||
76 | if (expr.length > 0) { | 76 | if (expr.length > 0) { |
77 | abort(repr(expr)); | 77 | abort(repr(expr)); |
78 | } | 78 | } |
79 | }, | 79 | }, |
80 | 80 | ||
81 | /** @id MochiKit.Selector.Selector.prototype.buildMatchExpression */ | 81 | /** @id MochiKit.Selector.Selector.prototype.buildMatchExpression */ |
82 | buildMatchExpression: function () { | 82 | buildMatchExpression: function () { |
83 | var repr = MochiKit.Base.repr; | 83 | var repr = MochiKit.Base.repr; |
84 | var params = this.params; | 84 | var params = this.params; |
85 | var conditions = []; | 85 | var conditions = []; |
86 | var clause, i; | 86 | var clause, i; |
87 | 87 | ||
88 | function childElements(element) { | 88 | function childElements(element) { |
89 | return "MochiKit.Base.filter(function (node) { return node.nodeType == 1; }, " + element + ".childNodes)"; | 89 | return "MochiKit.Base.filter(function (node) { return node.nodeType == 1; }, " + element + ".childNodes)"; |
90 | } | 90 | } |
91 | 91 | ||
92 | if (params.wildcard) { | 92 | if (params.wildcard) { |
93 | conditions.push('true'); | 93 | conditions.push('true'); |
94 | } | 94 | } |
95 | if (clause = params.id) { | 95 | if (clause = params.id) { |
96 | conditions.push('element.id == ' + repr(clause)); | 96 | conditions.push('element.id == ' + repr(clause)); |
97 | } | 97 | } |
98 | if (clause = params.tagName) { | 98 | if (clause = params.tagName) { |
99 | conditions.push('element.tagName.toUpperCase() == ' + repr(clause)); | 99 | conditions.push('element.tagName.toUpperCase() == ' + repr(clause)); |
100 | } | 100 | } |
101 | if ((clause = params.classNames).length > 0) { | 101 | if ((clause = params.classNames).length > 0) { |
102 | for (i = 0; i < clause.length; i++) { | 102 | for (i = 0; i < clause.length; i++) { |
103 | conditions.push('MochiKit.DOM.hasElementClass(element, ' + repr(clause[i]) + ')'); | 103 | conditions.push('MochiKit.DOM.hasElementClass(element, ' + repr(clause[i]) + ')'); |
104 | } | 104 | } |
105 | } | 105 | } |
106 | if ((clause = params.pseudoClassNames).length > 0) { | 106 | if ((clause = params.pseudoClassNames).length > 0) { |
107 | for (i = 0; i < clause.length; i++) { | 107 | for (i = 0; i < clause.length; i++) { |
108 | var match = clause[i].match(/^([^(]+)(?:\((.*)\))?$/); | 108 | var match = clause[i].match(/^([^(]+)(?:\((.*)\))?$/); |
109 | var pseudoClass = match[1]; | 109 | var pseudoClass = match[1]; |
110 | var pseudoClassArgument = match[2]; | 110 | var pseudoClassArgument = match[2]; |
111 | switch (pseudoClass) { | 111 | switch (pseudoClass) { |
112 | case 'root': | 112 | case 'root': |
113 | conditions.push('element.nodeType == 9 || element === element.ownerDocument.documentElement'); break; | 113 | conditions.push('element.nodeType == 9 || element === element.ownerDocument.documentElement'); break; |
114 | case 'nth-child': | 114 | case 'nth-child': |
115 | case 'nth-last-child': | 115 | case 'nth-last-child': |
116 | case 'nth-of-type': | 116 | case 'nth-of-type': |
117 | case 'nth-last-of-type': | 117 | case 'nth-last-of-type': |
118 | match = pseudoClassArgument.match(/^((?:(\d+)n\+)?(\d+)|odd|even)$/); | 118 | match = pseudoClassArgument.match(/^((?:(\d+)n\+)?(\d+)|odd|even)$/); |
119 | if (!match) { | 119 | if (!match) { |
120 | throw "Invalid argument to pseudo element nth-child: " + pseudoClassArgument; | 120 | throw "Invalid argument to pseudo element nth-child: " + pseudoClassArgument; |
121 | } | 121 | } |
122 | var a, b; | 122 | var a, b; |
123 | if (match[0] == 'odd') { | 123 | if (match[0] == 'odd') { |
124 | a = 2; | 124 | a = 2; |
125 | b = 1; | 125 | b = 1; |
126 | } else if (match[0] == 'even') { | 126 | } else if (match[0] == 'even') { |
127 | a = 2; | 127 | a = 2; |
128 | b = 0; | 128 | b = 0; |
129 | } else { | 129 | } else { |
130 | a = match[2] && parseInt(match) || null; | 130 | a = match[2] && parseInt(match, 10) || null; |
131 | b = parseInt(match[3]); | 131 | b = parseInt(match[3], 10); |
132 | } | 132 | } |
133 | conditions.push('this.nthChild(element,' + a + ',' + b | 133 | conditions.push('this.nthChild(element,' + a + ',' + b |
134 | + ',' + !!pseudoClass.match('^nth-last') // Reverse | 134 | + ',' + !!pseudoClass.match('^nth-last') // Reverse |
135 | + ',' + !!pseudoClass.match('of-type$') // Restrict to same tagName | 135 | + ',' + !!pseudoClass.match('of-type$') // Restrict to same tagName |
136 | + ')'); | 136 | + ')'); |
137 | break; | 137 | break; |
138 | case 'first-child': | 138 | case 'first-child': |
139 | conditions.push('this.nthChild(element, null, 1)'); | 139 | conditions.push('this.nthChild(element, null, 1)'); |
140 | break; | 140 | break; |
141 | case 'last-child': | 141 | case 'last-child': |
142 | conditions.push('this.nthChild(element, null, 1, true)'); | 142 | conditions.push('this.nthChild(element, null, 1, true)'); |
143 | break; | 143 | break; |
144 | case 'first-of-type': | 144 | case 'first-of-type': |
145 | conditions.push('this.nthChild(element, null, 1, false, true)'); | 145 | conditions.push('this.nthChild(element, null, 1, false, true)'); |
146 | break; | 146 | break; |
147 | case 'last-of-type': | 147 | case 'last-of-type': |
148 | conditions.push('this.nthChild(element, null, 1, true, true)'); | 148 | conditions.push('this.nthChild(element, null, 1, true, true)'); |
149 | break; | 149 | break; |
150 | case 'only-child': | 150 | case 'only-child': |
151 | conditions.push(childElements('element.parentNode') + '.length == 1'); | 151 | conditions.push(childElements('element.parentNode') + '.length == 1'); |
152 | break; | 152 | break; |
153 | case 'only-of-type': | 153 | case 'only-of-type': |
154 | conditions.push('MochiKit.Base.filter(function (node) { return node.tagName == element.tagName; }, ' + childElements('element.parentNode') + ').length == 1'); | 154 | conditions.push('MochiKit.Base.filter(function (node) { return node.tagName == element.tagName; }, ' + childElements('element.parentNode') + ').length == 1'); |
155 | break; | 155 | break; |
156 | case 'empty': | 156 | case 'empty': |
157 | conditions.push('element.childNodes.length == 0'); | 157 | conditions.push('element.childNodes.length == 0'); |
158 | break; | 158 | break; |
159 | case 'enabled': | 159 | case 'enabled': |
160 | conditions.push('(this.isUIElement(element) && element.disabled === false)'); | 160 | conditions.push('(this.isUIElement(element) && element.disabled === false)'); |
161 | break; | 161 | break; |
162 | case 'disabled': | 162 | case 'disabled': |
163 | conditions.push('(this.isUIElement(element) && element.disabled === true)'); | 163 | conditions.push('(this.isUIElement(element) && element.disabled === true)'); |
164 | break; | 164 | break; |
165 | case 'checked': | 165 | case 'checked': |
166 | conditions.push('(this.isUIElement(element) && element.checked === true)'); | 166 | conditions.push('(this.isUIElement(element) && element.checked === true)'); |
167 | break; | 167 | break; |
168 | case 'not': | 168 | case 'not': |
169 | var subselector = new MochiKit.Selector.Selector(pseudoClassArgument); | 169 | var subselector = new MochiKit.Selector.Selector(pseudoClassArgument); |
170 | conditions.push('!( ' + subselector.buildMatchExpression() + ')') | 170 | conditions.push('!( ' + subselector.buildMatchExpression() + ')'); |
171 | break; | 171 | break; |
172 | } | 172 | } |
173 | } | 173 | } |
174 | } | 174 | } |
175 | if (clause = params.attributes) { | 175 | if (clause = params.attributes) { |
176 | MochiKit.Base.map(function (attribute) { | 176 | MochiKit.Base.map(function (attribute) { |
177 | var value = 'MochiKit.DOM.getNodeAttribute(element, ' + repr(attribute.name) + ')'; | 177 | var value = 'MochiKit.DOM.getNodeAttribute(element, ' + repr(attribute.name) + ')'; |
178 | var splitValueBy = function (delimiter) { | 178 | var splitValueBy = function (delimiter) { |
179 | return value + '.split(' + repr(delimiter) + ')'; | 179 | return value + '.split(' + repr(delimiter) + ')'; |
180 | } | 180 | }; |
181 | conditions.push(value + ' != null'); | 181 | conditions.push(value + ' != null'); |
182 | switch (attribute.operator) { | 182 | switch (attribute.operator) { |
183 | case '=': | 183 | case '=': |
184 | conditions.push(value + ' == ' + repr(attribute.value)); | 184 | conditions.push(value + ' == ' + repr(attribute.value)); |
185 | break; | 185 | break; |
186 | case '~=': | 186 | case '~=': |
187 | conditions.push('MochiKit.Base.findValue(' + splitValueBy(' ') + ', ' + repr(attribute.value) + ') > -1'); | 187 | conditions.push('MochiKit.Base.findValue(' + splitValueBy(' ') + ', ' + repr(attribute.value) + ') > -1'); |
188 | break; | 188 | break; |
189 | case '^=': | 189 | case '^=': |
190 | conditions.push(value + '.substring(0, ' + attribute.value.length + ') == ' + repr(attribute.value)); | 190 | conditions.push(value + '.substring(0, ' + attribute.value.length + ') == ' + repr(attribute.value)); |
191 | break; | 191 | break; |
192 | case '$=': | 192 | case '$=': |
193 | conditions.push(value + '.substring(' + value + '.length - ' + attribute.value.length + ') == ' + repr(attribute.value)); | 193 | conditions.push(value + '.substring(' + value + '.length - ' + attribute.value.length + ') == ' + repr(attribute.value)); |
194 | break; | 194 | break; |
195 | case '*=': | 195 | case '*=': |
196 | conditions.push(value + '.match(' + repr(attribute.value) + ')'); | 196 | conditions.push(value + '.match(' + repr(attribute.value) + ')'); |
197 | break; | 197 | break; |
198 | case '|=': | 198 | case '|=': |
199 | conditions.push(splitValueBy('-') + '[0].toUpperCase() == ' + repr(attribute.value.toUpperCase())); | 199 | conditions.push(splitValueBy('-') + '[0].toUpperCase() == ' + repr(attribute.value.toUpperCase())); |
200 | break; | 200 | break; |
201 | case '!=': | 201 | case '!=': |
202 | conditions.push(value + ' != ' + repr(attribute.value)); | 202 | conditions.push(value + ' != ' + repr(attribute.value)); |
203 | break; | 203 | break; |
204 | case '': | 204 | case '': |
205 | case undefined: | 205 | case undefined: |
206 | // Condition already added above | 206 | // Condition already added above |
207 | break; | 207 | break; |
208 | default: | 208 | default: |
209 | throw 'Unknown operator ' + attribute.operator + ' in selector'; | 209 | throw 'Unknown operator ' + attribute.operator + ' in selector'; |
210 | } | 210 | } |
211 | }, clause); | 211 | }, clause); |
212 | } | 212 | } |
213 | 213 | ||
214 | return conditions.join(' && '); | 214 | return conditions.join(' && '); |
215 | }, | 215 | }, |
216 | 216 | ||
217 | /** @id MochiKit.Selector.Selector.prototype.compileMatcher */ | 217 | /** @id MochiKit.Selector.Selector.prototype.compileMatcher */ |
218 | compileMatcher: function () { | 218 | compileMatcher: function () { |
219 | var code = 'return (!element.tagName) ? false : ' + | 219 | var code = 'return (!element.tagName) ? false : ' + |
220 | this.buildMatchExpression() + ';'; | 220 | this.buildMatchExpression() + ';'; |
221 | this.match = new Function('element', code); | 221 | this.match = new Function('element', code); |
222 | }, | 222 | }, |
223 | 223 | ||
224 | /** @id MochiKit.Selector.Selector.prototype.nthChild */ | 224 | /** @id MochiKit.Selector.Selector.prototype.nthChild */ |
225 | nthChild: function (element, a, b, reverse, sametag){ | 225 | nthChild: function (element, a, b, reverse, sametag){ |
226 | var siblings = MochiKit.Base.filter(function (node) { | 226 | var siblings = MochiKit.Base.filter(function (node) { |
227 | return node.nodeType == 1; | 227 | return node.nodeType == 1; |
228 | }, element.parentNode.childNodes); | 228 | }, element.parentNode.childNodes); |
229 | if (sametag) { | 229 | if (sametag) { |
230 | siblings = MochiKit.Base.filter(function (node) { | 230 | siblings = MochiKit.Base.filter(function (node) { |
231 | return node.tagName == element.tagName; | 231 | return node.tagName == element.tagName; |
232 | }, siblings); | 232 | }, siblings); |
233 | } | 233 | } |
234 | if (reverse) { | 234 | if (reverse) { |
235 | siblings = MochiKit.Iter.reversed(siblings); | 235 | siblings = MochiKit.Iter.reversed(siblings); |
236 | } | 236 | } |
237 | if (a) { | 237 | if (a) { |
238 | var actualIndex = MochiKit.Base.findIdentical(siblings, element); | 238 | var actualIndex = MochiKit.Base.findIdentical(siblings, element); |
239 | return ((actualIndex + 1 - b) / a) % 1 == 0; | 239 | return ((actualIndex + 1 - b) / a) % 1 == 0; |
240 | } else { | 240 | } else { |
241 | return b == MochiKit.Base.findIdentical(siblings, element) + 1; | 241 | return b == MochiKit.Base.findIdentical(siblings, element) + 1; |
242 | } | 242 | } |
243 | }, | 243 | }, |
244 | 244 | ||
245 | /** @id MochiKit.Selector.Selector.prototype.isUIElement */ | 245 | /** @id MochiKit.Selector.Selector.prototype.isUIElement */ |
246 | isUIElement: function (element) { | 246 | isUIElement: function (element) { |
247 | return MochiKit.Base.findValue(['input', 'button', 'select', 'option', 'textarea', 'object'], | 247 | return MochiKit.Base.findValue(['input', 'button', 'select', 'option', 'textarea', 'object'], |
248 | element.tagName.toLowerCase()) > -1; | 248 | element.tagName.toLowerCase()) > -1; |
249 | }, | 249 | }, |
250 | 250 | ||
251 | /** @id MochiKit.Selector.Selector.prototype.findElements */ | 251 | /** @id MochiKit.Selector.Selector.prototype.findElements */ |
252 | findElements: function (scope, axis) { | 252 | findElements: function (scope, axis) { |
253 | var element; | 253 | var element; |
254 | 254 | ||
255 | if (axis == undefined) { | 255 | if (axis == undefined) { |
256 | axis = ""; | 256 | axis = ""; |
257 | } | 257 | } |
258 | 258 | ||
259 | function inScope(element, scope) { | 259 | function inScope(element, scope) { |
260 | if (axis == "") { | 260 | if (axis == "") { |
261 | return MochiKit.DOM.isChildNode(element, scope); | 261 | return MochiKit.DOM.isChildNode(element, scope); |
262 | } else if (axis == ">") { | 262 | } else if (axis == ">") { |
263 | return element.parentNode === scope; | 263 | return element.parentNode === scope; |
264 | } else if (axis == "+") { | 264 | } else if (axis == "+") { |
265 | return element === nextSiblingElement(scope); | 265 | return element === nextSiblingElement(scope); |
266 | } else if (axis == "~") { | 266 | } else if (axis == "~") { |
267 | var sibling = scope; | 267 | var sibling = scope; |
268 | while (sibling = nextSiblingElement(sibling)) { | 268 | while (sibling = nextSiblingElement(sibling)) { |
269 | if (element === sibling) { | 269 | if (element === sibling) { |
270 | return true; | 270 | return true; |
271 | } | 271 | } |
272 | } | 272 | } |
273 | return false; | 273 | return false; |
274 | } else { | 274 | } else { |
275 | throw "Invalid axis: " + axis; | 275 | throw "Invalid axis: " + axis; |
276 | } | 276 | } |
277 | } | 277 | } |
278 | 278 | ||
279 | if (element = MochiKit.DOM.getElement(this.params.id)) { | 279 | if (element = MochiKit.DOM.getElement(this.params.id)) { |
280 | if (this.match(element)) { | 280 | if (this.match(element)) { |
281 | if (!scope || inScope(element, scope)) { | 281 | if (!scope || inScope(element, scope)) { |
282 | return [element]; | 282 | return [element]; |
283 | } | 283 | } |
284 | } | 284 | } |
285 | } | 285 | } |
286 | 286 | ||
287 | function nextSiblingElement(node) { | 287 | function nextSiblingElement(node) { |
288 | node = node.nextSibling; | 288 | node = node.nextSibling; |
289 | while (node && node.nodeType != 1) { | 289 | while (node && node.nodeType != 1) { |
290 | node = node.nextSibling; | 290 | node = node.nextSibling; |
291 | } | 291 | } |
292 | return node; | 292 | return node; |
293 | } | 293 | } |
294 | 294 | ||
295 | if (axis == "") { | 295 | if (axis == "") { |
296 | scope = (scope || MochiKit.DOM.currentDocument()).getElementsByTagName(this.params.tagName || '*'); | 296 | scope = (scope || MochiKit.DOM.currentDocument()).getElementsByTagName(this.params.tagName || '*'); |
297 | } else if (axis == ">") { | 297 | } else if (axis == ">") { |
298 | if (!scope) { | 298 | if (!scope) { |
299 | throw "> combinator not allowed without preceeding expression"; | 299 | throw "> combinator not allowed without preceeding expression"; |
300 | } | 300 | } |
301 | scope = MochiKit.Base.filter(function (node) { | 301 | scope = MochiKit.Base.filter(function (node) { |
302 | return node.nodeType == 1; | 302 | return node.nodeType == 1; |
303 | }, scope.childNodes); | 303 | }, scope.childNodes); |
304 | } else if (axis == "+") { | 304 | } else if (axis == "+") { |
305 | if (!scope) { | 305 | if (!scope) { |
306 | throw "+ combinator not allowed without preceeding expression"; | 306 | throw "+ combinator not allowed without preceeding expression"; |
307 | } | 307 | } |
308 | scope = nextSiblingElement(scope) && [nextSiblingElement(scope)]; | 308 | scope = nextSiblingElement(scope) && [nextSiblingElement(scope)]; |
309 | } else if (axis == "~") { | 309 | } else if (axis == "~") { |
310 | if (!scope) { | 310 | if (!scope) { |
311 | throw "~ combinator not allowed without preceeding expression"; | 311 | throw "~ combinator not allowed without preceeding expression"; |
312 | } | 312 | } |
313 | var newscope = []; | 313 | var newscope = []; |
314 | while (nextSiblingElement(scope)) { | 314 | while (nextSiblingElement(scope)) { |
315 | scope = nextSiblingElement(scope); | 315 | scope = nextSiblingElement(scope); |
316 | newscope.push(scope); | 316 | newscope.push(scope); |
317 | } | 317 | } |
318 | scope = newscope; | 318 | scope = newscope; |
319 | } | 319 | } |
320 | 320 | ||
321 | if (!scope) { | 321 | if (!scope) { |
322 | return []; | 322 | return []; |
323 | } | 323 | } |
324 | 324 | ||
325 | var results = MochiKit.Base.filter(MochiKit.Base.bind(function (scopeElt) { | 325 | var results = MochiKit.Base.filter(MochiKit.Base.bind(function (scopeElt) { |
326 | return this.match(scopeElt); | 326 | return this.match(scopeElt); |
327 | }, this), scope); | 327 | }, this), scope); |
328 | 328 | ||
329 | return results; | 329 | return results; |
330 | }, | 330 | }, |
331 | 331 | ||
332 | /** @id MochiKit.Selector.Selector.prototype.repr */ | 332 | /** @id MochiKit.Selector.Selector.prototype.repr */ |
333 | repr: function () { | 333 | repr: function () { |
334 | return 'Selector(' + this.expression + ')'; | 334 | return 'Selector(' + this.expression + ')'; |
335 | }, | 335 | }, |
336 | 336 | ||
337 | toString: MochiKit.Base.forwardCall("repr") | 337 | toString: MochiKit.Base.forwardCall("repr") |
338 | }; | 338 | }; |
339 | 339 | ||
340 | MochiKit.Base.update(MochiKit.Selector, { | 340 | MochiKit.Base.update(MochiKit.Selector, { |
341 | 341 | ||
342 | /** @id MochiKit.Selector.findChildElements */ | 342 | /** @id MochiKit.Selector.findChildElements */ |
343 | findChildElements: function (element, expressions) { | 343 | findChildElements: function (element, expressions) { |
344 | element = MochiKit.DOM.getElement(element); | 344 | element = MochiKit.DOM.getElement(element); |
345 | var uniq = function(arr) { | 345 | var uniq = function(arr) { |
346 | var res = []; | 346 | var res = []; |
347 | for (var i = 0; i < arr.length; i++) { | 347 | for (var i = 0; i < arr.length; i++) { |
348 | if (MochiKit.Base.findIdentical(res, arr[i]) < 0) { | 348 | if (MochiKit.Base.findIdentical(res, arr[i]) < 0) { |
349 | res.push(arr[i]); | 349 | res.push(arr[i]); |
350 | } | 350 | } |
351 | } | 351 | } |
352 | return res; | 352 | return res; |
353 | }; | 353 | }; |
354 | return MochiKit.Base.flattenArray(MochiKit.Base.map(function (expression) { | 354 | return MochiKit.Base.flattenArray(MochiKit.Base.map(function (expression) { |
355 | try { | ||
356 | var res = element.querySelectorAll(expression); | ||
357 | return Array.prototype.slice.call(res, 0); | ||
358 | } catch (ignore) { | ||
359 | // No querySelectorAll or extended expression syntax used | ||
360 | } | ||
355 | var nextScope = ""; | 361 | var nextScope = ""; |
356 | var reducer = function (results, expr) { | 362 | var reducer = function (results, expr) { |
357 | var match = expr.match(/^[>+~]$/); | 363 | var match = expr.match(/^[>+~]$/); |
358 | if (match) { | 364 | if (match) { |
359 | nextScope = match[0]; | 365 | nextScope = match[0]; |
360 | return results; | 366 | return results; |
361 | } else { | 367 | } else { |
362 | var selector = new MochiKit.Selector.Selector(expr); | 368 | var selector = new MochiKit.Selector.Selector(expr); |
363 | var elements = MochiKit.Iter.reduce(function (elements, result) { | 369 | var elements = MochiKit.Iter.reduce(function (elements, result) { |
364 | return MochiKit.Base.extend(elements, selector.findElements(result || element, nextScope)); | 370 | return MochiKit.Base.extend(elements, selector.findElements(result || element, nextScope)); |
365 | }, results, []); | 371 | }, results, []); |
366 | nextScope = ""; | 372 | nextScope = ""; |
367 | return elements; | 373 | return elements; |
368 | } | 374 | } |
369 | }; | 375 | }; |
370 | var exprs = expression.replace(/(^\s+|\s+$)/g, '').split(/\s+/); | 376 | var exprs = expression.replace(/(^\s+|\s+$)/g, '').split(/\s+/); |
371 | return uniq(MochiKit.Iter.reduce(reducer, exprs, [null])); | 377 | return uniq(MochiKit.Iter.reduce(reducer, exprs, [null])); |
372 | }, expressions)); | 378 | }, expressions)); |
373 | }, | 379 | }, |
374 | 380 | ||
375 | findDocElements: function () { | 381 | findDocElements: function () { |
376 | return MochiKit.Selector.findChildElements(MochiKit.DOM.currentDocument(), arguments); | 382 | return MochiKit.Selector.findChildElements(MochiKit.DOM.currentDocument(), arguments); |
377 | }, | 383 | }, |
378 | 384 | ||
379 | __new__: function () { | 385 | __new__: function () { |
380 | this.$$ = this.findDocElements; | 386 | this.$$ = this.findDocElements; |
381 | MochiKit.Base.nameFunctions(this); | 387 | MochiKit.Base.nameFunctions(this); |
382 | } | 388 | } |
383 | }); | 389 | }); |
384 | 390 | ||
385 | MochiKit.Selector.__new__(); | 391 | MochiKit.Selector.__new__(); |
386 | 392 | ||
387 | MochiKit.Base._exportSymbols(this, MochiKit.Selector); | 393 | MochiKit.Base._exportSymbols(this, MochiKit.Selector); |