selenium-core-runner 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. data/Gemfile +9 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +3 -0
  4. data/Rakefile +30 -0
  5. data/app/controllers/selenium_core_runner/suites_controller.rb +19 -0
  6. data/app/views/selenium_core_runner/suites/index.html.erb +177 -0
  7. data/app/views/selenium_core_runner/suites/show.html.erb +0 -0
  8. data/config/routes.rb +6 -0
  9. data/lib/selenium-core-runner/engine.rb +19 -0
  10. data/lib/selenium-core-runner.rb +3 -0
  11. data/public/selenium-core-runner/Blank.html +7 -0
  12. data/public/selenium-core-runner/InjectedRemoteRunner.html +8 -0
  13. data/public/selenium-core-runner/RemoteRunner.html +101 -0
  14. data/public/selenium-core-runner/SeleniumLog.html +109 -0
  15. data/public/selenium-core-runner/TestPrompt.html +145 -0
  16. data/public/selenium-core-runner/TestRunner-splash.html +55 -0
  17. data/public/selenium-core-runner/TestRunner.hta +177 -0
  18. data/public/selenium-core-runner/TestRunner.html +177 -0
  19. data/public/selenium-core-runner/icons/all.png +0 -0
  20. data/public/selenium-core-runner/icons/continue.png +0 -0
  21. data/public/selenium-core-runner/icons/continue_disabled.png +0 -0
  22. data/public/selenium-core-runner/icons/pause.png +0 -0
  23. data/public/selenium-core-runner/icons/pause_disabled.png +0 -0
  24. data/public/selenium-core-runner/icons/selected.png +0 -0
  25. data/public/selenium-core-runner/icons/step.png +0 -0
  26. data/public/selenium-core-runner/icons/step_disabled.png +0 -0
  27. data/public/selenium-core-runner/iedoc-core.xml +1789 -0
  28. data/public/selenium-core-runner/iedoc.xml +1830 -0
  29. data/public/selenium-core-runner/lib/cssQuery/cssQuery-p.js +6 -0
  30. data/public/selenium-core-runner/lib/cssQuery/src/cssQuery-level2.js +142 -0
  31. data/public/selenium-core-runner/lib/cssQuery/src/cssQuery-level3.js +150 -0
  32. data/public/selenium-core-runner/lib/cssQuery/src/cssQuery-standard.js +53 -0
  33. data/public/selenium-core-runner/lib/cssQuery/src/cssQuery.js +356 -0
  34. data/public/selenium-core-runner/lib/prototype.js +2006 -0
  35. data/public/selenium-core-runner/lib/scriptaculous/builder.js +101 -0
  36. data/public/selenium-core-runner/lib/scriptaculous/controls.js +815 -0
  37. data/public/selenium-core-runner/lib/scriptaculous/dragdrop.js +915 -0
  38. data/public/selenium-core-runner/lib/scriptaculous/effects.js +958 -0
  39. data/public/selenium-core-runner/lib/scriptaculous/scriptaculous.js +47 -0
  40. data/public/selenium-core-runner/lib/scriptaculous/slider.js +283 -0
  41. data/public/selenium-core-runner/lib/scriptaculous/unittest.js +383 -0
  42. data/public/selenium-core-runner/lib/snapsie.js +91 -0
  43. data/public/selenium-core-runner/scripts/find_matching_child.js +69 -0
  44. data/public/selenium-core-runner/scripts/htmlutils.js +1623 -0
  45. data/public/selenium-core-runner/scripts/injection.html +72 -0
  46. data/public/selenium-core-runner/scripts/selenium-api.js +3240 -0
  47. data/public/selenium-core-runner/scripts/selenium-browserbot.js +2333 -0
  48. data/public/selenium-core-runner/scripts/selenium-browserdetect.js +153 -0
  49. data/public/selenium-core-runner/scripts/selenium-commandhandlers.js +379 -0
  50. data/public/selenium-core-runner/scripts/selenium-executionloop.js +175 -0
  51. data/public/selenium-core-runner/scripts/selenium-logging.js +148 -0
  52. data/public/selenium-core-runner/scripts/selenium-remoterunner.js +695 -0
  53. data/public/selenium-core-runner/scripts/selenium-testrunner.js +1362 -0
  54. data/public/selenium-core-runner/scripts/selenium-version.js +5 -0
  55. data/public/selenium-core-runner/scripts/ui-doc.html +803 -0
  56. data/public/selenium-core-runner/scripts/ui-element.js +1627 -0
  57. data/public/selenium-core-runner/scripts/ui-map-sample.js +979 -0
  58. data/public/selenium-core-runner/scripts/user-extensions.js +3 -0
  59. data/public/selenium-core-runner/scripts/user-extensions.js.sample +75 -0
  60. data/public/selenium-core-runner/scripts/xmlextras.js +153 -0
  61. data/public/selenium-core-runner/selenium-logo.png +0 -0
  62. data/public/selenium-core-runner/selenium-test.css +43 -0
  63. data/public/selenium-core-runner/selenium.css +316 -0
  64. data/public/selenium-core-runner/xpath/dom.js +566 -0
  65. data/public/selenium-core-runner/xpath/javascript-xpath-0.1.11.js +2816 -0
  66. data/public/selenium-core-runner/xpath/util.js +549 -0
  67. data/public/selenium-core-runner/xpath/xmltoken.js +149 -0
  68. data/public/selenium-core-runner/xpath/xpath.js +2481 -0
  69. metadata +121 -0
@@ -0,0 +1,549 @@
1
+ // Copyright 2005 Google
2
+ //
3
+ // Author: Steffen Meschkat <mesch@google.com>
4
+ //
5
+ // Miscellaneous utility and placeholder functions.
6
+
7
+ // Dummy implmentation for the logging functions. Replace by something
8
+ // useful when you want to debug.
9
+ function xpathLog(msg) {};
10
+ function xsltLog(msg) {};
11
+ function xsltLogXml(msg) {};
12
+
13
+ var ajaxsltIsIE6 = navigator.appVersion.match(/MSIE 6.0/);
14
+
15
+ // Throws an exception if false.
16
+ function assert(b) {
17
+ if (!b) {
18
+ throw "Assertion failed";
19
+ }
20
+ }
21
+
22
+ // Splits a string s at all occurrences of character c. This is like
23
+ // the split() method of the string object, but IE omits empty
24
+ // strings, which violates the invariant (s.split(x).join(x) == s).
25
+ function stringSplit(s, c) {
26
+ var a = s.indexOf(c);
27
+ if (a == -1) {
28
+ return [ s ];
29
+ }
30
+ var parts = [];
31
+ parts.push(s.substr(0,a));
32
+ while (a != -1) {
33
+ var a1 = s.indexOf(c, a + 1);
34
+ if (a1 != -1) {
35
+ parts.push(s.substr(a + 1, a1 - a - 1));
36
+ } else {
37
+ parts.push(s.substr(a + 1));
38
+ }
39
+ a = a1;
40
+ }
41
+ return parts;
42
+ }
43
+
44
+ // The following function does what document.importNode(node, true)
45
+ // would do for us here; however that method is broken in Safari/1.3,
46
+ // so we have to emulate it.
47
+ function xmlImportNode(doc, node) {
48
+ if (node.nodeType == DOM_TEXT_NODE) {
49
+ return domCreateTextNode(doc, node.nodeValue);
50
+
51
+ } else if (node.nodeType == DOM_CDATA_SECTION_NODE) {
52
+ return domCreateCDATASection(doc, node.nodeValue);
53
+
54
+ } else if (node.nodeType == DOM_ELEMENT_NODE) {
55
+ var newNode = domCreateElement(doc, node.nodeName);
56
+ for (var i = 0; i < node.attributes.length; ++i) {
57
+ var an = node.attributes[i];
58
+ var name = an.nodeName;
59
+ var value = an.nodeValue;
60
+ domSetAttribute(newNode, name, value);
61
+ }
62
+
63
+ for (var c = node.firstChild; c; c = c.nextSibling) {
64
+ var cn = arguments.callee(doc, c);
65
+ domAppendChild(newNode, cn);
66
+ }
67
+
68
+ return newNode;
69
+
70
+ } else {
71
+ return domCreateComment(doc, node.nodeName);
72
+ }
73
+ }
74
+
75
+ // A set data structure. It can also be used as a map (i.e. the keys
76
+ // can have values other than 1), but we don't call it map because it
77
+ // would be ambiguous in this context. Also, the map is iterable, so
78
+ // we can use it to replace for-in loops over core javascript Objects.
79
+ // For-in iteration breaks when Object.prototype is modified, which
80
+ // some clients of the maps API do.
81
+ //
82
+ // NOTE(mesch): The set keys by the string value of its element, NOT
83
+ // by the typed value. In particular, objects can't be used as keys.
84
+ //
85
+ // @constructor
86
+ function Set() {
87
+ this.keys = [];
88
+ }
89
+
90
+ Set.prototype.size = function() {
91
+ return this.keys.length;
92
+ }
93
+
94
+ // Adds the entry to the set, ignoring if it is present.
95
+ Set.prototype.add = function(key, opt_value) {
96
+ var value = opt_value || 1;
97
+ if (!this.contains(key)) {
98
+ this[':' + key] = value;
99
+ this.keys.push(key);
100
+ }
101
+ }
102
+
103
+ // Sets the entry in the set, adding if it is not yet present.
104
+ Set.prototype.set = function(key, opt_value) {
105
+ var value = opt_value || 1;
106
+ if (!this.contains(key)) {
107
+ this[':' + key] = value;
108
+ this.keys.push(key);
109
+ } else {
110
+ this[':' + key] = value;
111
+ }
112
+ }
113
+
114
+ // Increments the key's value by 1. This works around the fact that
115
+ // numbers are always passed by value, never by reference, so that we
116
+ // can't increment the value returned by get(), or the iterator
117
+ // argument. Sets the key's value to 1 if it doesn't exist yet.
118
+ Set.prototype.inc = function(key) {
119
+ if (!this.contains(key)) {
120
+ this[':' + key] = 1;
121
+ this.keys.push(key);
122
+ } else {
123
+ this[':' + key]++;
124
+ }
125
+ }
126
+
127
+ Set.prototype.get = function(key) {
128
+ if (this.contains(key)) {
129
+ return this[':' + key];
130
+ } else {
131
+ var undefined;
132
+ return undefined;
133
+ }
134
+ }
135
+
136
+ // Removes the entry from the set.
137
+ Set.prototype.remove = function(key) {
138
+ if (this.contains(key)) {
139
+ delete this[':' + key];
140
+ removeFromArray(this.keys, key, true);
141
+ }
142
+ }
143
+
144
+ // Tests if an entry is in the set.
145
+ Set.prototype.contains = function(entry) {
146
+ return typeof this[':' + entry] != 'undefined';
147
+ }
148
+
149
+ // Gets a list of values in the set.
150
+ Set.prototype.items = function() {
151
+ var list = [];
152
+ for (var i = 0; i < this.keys.length; ++i) {
153
+ var k = this.keys[i];
154
+ var v = this[':' + k];
155
+ list.push(v);
156
+ }
157
+ return list;
158
+ }
159
+
160
+
161
+ // Invokes function f for every key value pair in the set as a method
162
+ // of the set.
163
+ Set.prototype.map = function(f) {
164
+ for (var i = 0; i < this.keys.length; ++i) {
165
+ var k = this.keys[i];
166
+ f.call(this, k, this[':' + k]);
167
+ }
168
+ }
169
+
170
+ Set.prototype.clear = function() {
171
+ for (var i = 0; i < this.keys.length; ++i) {
172
+ delete this[':' + this.keys[i]];
173
+ }
174
+ this.keys.length = 0;
175
+ }
176
+
177
+
178
+ // Applies the given function to each element of the array, preserving
179
+ // this, and passing the index.
180
+ function mapExec(array, func) {
181
+ for (var i = 0; i < array.length; ++i) {
182
+ func.call(this, array[i], i);
183
+ }
184
+ }
185
+
186
+ // Returns an array that contains the return value of the given
187
+ // function applied to every element of the input array.
188
+ function mapExpr(array, func) {
189
+ var ret = [];
190
+ for (var i = 0; i < array.length; ++i) {
191
+ ret.push(func(array[i]));
192
+ }
193
+ return ret;
194
+ };
195
+
196
+ // Reverses the given array in place.
197
+ function reverseInplace(array) {
198
+ for (var i = 0; i < array.length / 2; ++i) {
199
+ var h = array[i];
200
+ var ii = array.length - i - 1;
201
+ array[i] = array[ii];
202
+ array[ii] = h;
203
+ }
204
+ }
205
+
206
+ // Removes value from array. Returns the number of instances of value
207
+ // that were removed from array.
208
+ function removeFromArray(array, value, opt_notype) {
209
+ var shift = 0;
210
+ for (var i = 0; i < array.length; ++i) {
211
+ if (array[i] === value || (opt_notype && array[i] == value)) {
212
+ array.splice(i--, 1);
213
+ shift++;
214
+ }
215
+ }
216
+ return shift;
217
+ }
218
+
219
+ // Shallow-copies an array to the end of another array
220
+ // Basically Array.concat, but works with other non-array collections
221
+ function copyArray(dst, src) {
222
+ if (!src) return;
223
+ var dstLength = dst.length;
224
+ for (var i = src.length - 1; i >= 0; --i) {
225
+ dst[i+dstLength] = src[i];
226
+ }
227
+ }
228
+
229
+ /**
230
+ * This is an optimization for copying attribute lists in IE. IE includes many
231
+ * extraneous properties in its DOM attribute lists, which take require
232
+ * significant extra processing when evaluating attribute steps. With this
233
+ * function, we ignore any such attributes that has an empty string value.
234
+ */
235
+ function copyArrayIgnoringAttributesWithoutValue(dst, src)
236
+ {
237
+ if (!src) return;
238
+ for (var i = src.length - 1; i >= 0; --i) {
239
+ // this test will pass so long as the attribute has a non-empty string
240
+ // value, even if that value is "false", "0", "undefined", etc.
241
+ if (src[i].nodeValue) {
242
+ dst.push(src[i]);
243
+ }
244
+ }
245
+ }
246
+
247
+ // Returns the text value of a node; for nodes without children this
248
+ // is the nodeValue, for nodes with children this is the concatenation
249
+ // of the value of all children. Browser-specific optimizations are used by
250
+ // default; they can be disabled by passing "true" in as the second parameter.
251
+ function xmlValue(node, disallowBrowserSpecificOptimization) {
252
+ if (!node) {
253
+ return '';
254
+ }
255
+
256
+ var ret = '';
257
+ if (node.nodeType == DOM_TEXT_NODE ||
258
+ node.nodeType == DOM_CDATA_SECTION_NODE) {
259
+ ret += node.nodeValue;
260
+
261
+ } else if (node.nodeType == DOM_ATTRIBUTE_NODE) {
262
+ if (ajaxsltIsIE6) {
263
+ ret += xmlValueIE6Hack(node);
264
+ } else {
265
+ ret += node.nodeValue;
266
+ }
267
+ } else if (node.nodeType == DOM_ELEMENT_NODE ||
268
+ node.nodeType == DOM_DOCUMENT_NODE ||
269
+ node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
270
+ if (!disallowBrowserSpecificOptimization) {
271
+ // IE, Safari, Opera, and friends
272
+ var innerText = node.innerText;
273
+ if (innerText != undefined) {
274
+ return innerText;
275
+ }
276
+ // Firefox
277
+ var textContent = node.textContent;
278
+ if (textContent != undefined) {
279
+ return textContent;
280
+ }
281
+ }
282
+ // pobrecito!
283
+ var len = node.childNodes.length;
284
+ for (var i = 0; i < len; ++i) {
285
+ ret += arguments.callee(node.childNodes[i]);
286
+ }
287
+ }
288
+ return ret;
289
+ }
290
+
291
+ function xmlValueIE6Hack(node) {
292
+ // Issue 19, IE6 mangles href attribute when it's a javascript: url
293
+ var nodeName = node.nodeName;
294
+ var nodeValue = node.nodeValue;
295
+ if (nodeName.length != 4) return nodeValue;
296
+ if (!/^href$/i.test(nodeName)) return nodeValue;
297
+ if (!/^javascript:/.test(nodeValue)) return nodeValue;
298
+ return unescape(nodeValue);
299
+ }
300
+
301
+ // Returns the representation of a node as XML text.
302
+ function xmlText(node, opt_cdata) {
303
+ var buf = [];
304
+ xmlTextR(node, buf, opt_cdata);
305
+ return buf.join('');
306
+ }
307
+
308
+ function xmlTextR(node, buf, cdata) {
309
+ if (node.nodeType == DOM_TEXT_NODE) {
310
+ buf.push(xmlEscapeText(node.nodeValue));
311
+
312
+ } else if (node.nodeType == DOM_CDATA_SECTION_NODE) {
313
+ if (cdata) {
314
+ buf.push(node.nodeValue);
315
+ } else {
316
+ buf.push('<![CDATA[' + node.nodeValue + ']]>');
317
+ }
318
+
319
+ } else if (node.nodeType == DOM_COMMENT_NODE) {
320
+ buf.push('<!--' + node.nodeValue + '-->');
321
+
322
+ } else if (node.nodeType == DOM_ELEMENT_NODE) {
323
+ buf.push('<' + xmlFullNodeName(node));
324
+ for (var i = 0; i < node.attributes.length; ++i) {
325
+ var a = node.attributes[i];
326
+ if (a && a.nodeName && a.nodeValue) {
327
+ buf.push(' ' + xmlFullNodeName(a) + '="' +
328
+ xmlEscapeAttr(a.nodeValue) + '"');
329
+ }
330
+ }
331
+
332
+ if (node.childNodes.length == 0) {
333
+ buf.push('/>');
334
+ } else {
335
+ buf.push('>');
336
+ for (var i = 0; i < node.childNodes.length; ++i) {
337
+ arguments.callee(node.childNodes[i], buf, cdata);
338
+ }
339
+ buf.push('</' + xmlFullNodeName(node) + '>');
340
+ }
341
+
342
+ } else if (node.nodeType == DOM_DOCUMENT_NODE ||
343
+ node.nodeType == DOM_DOCUMENT_FRAGMENT_NODE) {
344
+ for (var i = 0; i < node.childNodes.length; ++i) {
345
+ arguments.callee(node.childNodes[i], buf, cdata);
346
+ }
347
+ }
348
+ }
349
+
350
+ function xmlFullNodeName(n) {
351
+ if (n.prefix && n.nodeName.indexOf(n.prefix + ':') != 0) {
352
+ return n.prefix + ':' + n.nodeName;
353
+ } else {
354
+ return n.nodeName;
355
+ }
356
+ }
357
+
358
+ // Escape XML special markup chracters: tag delimiter < > and entity
359
+ // reference start delimiter &. The escaped string can be used in XML
360
+ // text portions (i.e. between tags).
361
+ function xmlEscapeText(s) {
362
+ return ('' + s).replace(/&/g, '&amp;').replace(/</g, '&lt;').
363
+ replace(/>/g, '&gt;');
364
+ }
365
+
366
+ // Escape XML special markup characters: tag delimiter < > entity
367
+ // reference start delimiter & and quotes ". The escaped string can be
368
+ // used in double quoted XML attribute value portions (i.e. in
369
+ // attributes within start tags).
370
+ function xmlEscapeAttr(s) {
371
+ return xmlEscapeText(s).replace(/\"/g, '&quot;');
372
+ }
373
+
374
+ // Escape markup in XML text, but don't touch entity references. The
375
+ // escaped string can be used as XML text (i.e. between tags).
376
+ function xmlEscapeTags(s) {
377
+ return s.replace(/</g, '&lt;').replace(/>/g, '&gt;');
378
+ }
379
+
380
+ /**
381
+ * Wrapper function to access the owner document uniformly for document
382
+ * and other nodes: for the document node, the owner document is the
383
+ * node itself, for all others it's the ownerDocument property.
384
+ *
385
+ * @param {Node} node
386
+ * @return {Document}
387
+ */
388
+ function xmlOwnerDocument(node) {
389
+ if (node.nodeType == DOM_DOCUMENT_NODE) {
390
+ return node;
391
+ } else {
392
+ return node.ownerDocument;
393
+ }
394
+ }
395
+
396
+ // Wrapper around DOM methods so we can condense their invocations.
397
+ function domGetAttribute(node, name) {
398
+ return node.getAttribute(name);
399
+ }
400
+
401
+ function domSetAttribute(node, name, value) {
402
+ return node.setAttribute(name, value);
403
+ }
404
+
405
+ function domRemoveAttribute(node, name) {
406
+ return node.removeAttribute(name);
407
+ }
408
+
409
+ function domAppendChild(node, child) {
410
+ return node.appendChild(child);
411
+ }
412
+
413
+ function domRemoveChild(node, child) {
414
+ return node.removeChild(child);
415
+ }
416
+
417
+ function domReplaceChild(node, newChild, oldChild) {
418
+ return node.replaceChild(newChild, oldChild);
419
+ }
420
+
421
+ function domInsertBefore(node, newChild, oldChild) {
422
+ return node.insertBefore(newChild, oldChild);
423
+ }
424
+
425
+ function domRemoveNode(node) {
426
+ return domRemoveChild(node.parentNode, node);
427
+ }
428
+
429
+ function domCreateTextNode(doc, text) {
430
+ return doc.createTextNode(text);
431
+ }
432
+
433
+ function domCreateElement(doc, name) {
434
+ return doc.createElement(name);
435
+ }
436
+
437
+ function domCreateAttribute(doc, name) {
438
+ return doc.createAttribute(name);
439
+ }
440
+
441
+ function domCreateCDATASection(doc, data) {
442
+ return doc.createCDATASection(data);
443
+ }
444
+
445
+ function domCreateComment(doc, text) {
446
+ return doc.createComment(text);
447
+ }
448
+
449
+ function domCreateDocumentFragment(doc) {
450
+ return doc.createDocumentFragment();
451
+ }
452
+
453
+ function domGetElementById(doc, id) {
454
+ return doc.getElementById(id);
455
+ }
456
+
457
+ // Same for window methods.
458
+ function windowSetInterval(win, fun, time) {
459
+ return win.setInterval(fun, time);
460
+ }
461
+
462
+ function windowClearInterval(win, id) {
463
+ return win.clearInterval(id);
464
+ }
465
+
466
+ /**
467
+ * Escape the special regular expression characters when the regular expression
468
+ * is specified as a string.
469
+ *
470
+ * Based on: http://simonwillison.net/2006/Jan/20/escape/
471
+ */
472
+ RegExp.escape = (function() {
473
+ var specials = [
474
+ '/', '.', '*', '+', '?', '|', '^', '$',
475
+ '(', ')', '[', ']', '{', '}', '\\'
476
+ ];
477
+
478
+ var sRE = new RegExp(
479
+ '(\\' + specials.join('|\\') + ')', 'g'
480
+ );
481
+
482
+ return function(text) {
483
+ return text.replace(sRE, '\\$1');
484
+ }
485
+ })();
486
+
487
+ /**
488
+ * Determines whether a predicate expression contains a "positional selector".
489
+ * A positional selector filters nodes from the nodelist input based on their
490
+ * position within that list. When such selectors are encountered, the
491
+ * evaluation of the predicate cannot be depth-first, because the positional
492
+ * selector may be based on the result of evaluating predicates that precede
493
+ * it.
494
+ */
495
+ function predicateExprHasPositionalSelector(expr, isRecursiveCall) {
496
+ if (!expr) {
497
+ return false;
498
+ }
499
+ if (!isRecursiveCall && exprReturnsNumberValue(expr)) {
500
+ // this is a "proximity position"-based predicate
501
+ return true;
502
+ }
503
+ if (expr instanceof FunctionCallExpr) {
504
+ var value = expr.name.value;
505
+ return (value == 'last' || value == 'position');
506
+ }
507
+ if (expr instanceof BinaryExpr) {
508
+ return (
509
+ predicateExprHasPositionalSelector(expr.expr1, true) ||
510
+ predicateExprHasPositionalSelector(expr.expr2, true));
511
+ }
512
+ return false;
513
+ }
514
+
515
+ function exprReturnsNumberValue(expr) {
516
+ if (expr instanceof FunctionCallExpr) {
517
+ var isMember = {
518
+ last: true
519
+ , position: true
520
+ , count: true
521
+ , 'string-length': true
522
+ , number: true
523
+ , sum: true
524
+ , floor: true
525
+ , ceiling: true
526
+ , round: true
527
+ };
528
+ return isMember[expr.name.value];
529
+ }
530
+ else if (expr instanceof UnaryMinusExpr) {
531
+ return true;
532
+ }
533
+ else if (expr instanceof BinaryExpr) {
534
+ var isMember = {
535
+ '+': true
536
+ , '-': true
537
+ , '*': true
538
+ , mod: true
539
+ , div: true
540
+ };
541
+ return isMember[expr.op.value];
542
+ }
543
+ else if (expr instanceof NumberExpr) {
544
+ return true;
545
+ }
546
+ return false;
547
+ }
548
+
549
+
@@ -0,0 +1,149 @@
1
+ // Copyright 2006 Google Inc.
2
+ // All Rights Reserved
3
+ //
4
+ // Defines regular expression patterns to extract XML tokens from string.
5
+ // See <http://www.w3.org/TR/REC-xml/#sec-common-syn>,
6
+ // <http://www.w3.org/TR/xml11/#sec-common-syn> and
7
+ // <http://www.w3.org/TR/REC-xml-names/#NT-NCName> for the specifications.
8
+ //
9
+ // Author: Junji Takagi <jtakagi@google.com>
10
+
11
+ // Detect whether RegExp supports Unicode characters or not.
12
+
13
+ var REGEXP_UNICODE = function() {
14
+ var tests = [' ', '\u0120', -1, // Konquerer 3.4.0 fails here.
15
+ '!', '\u0120', -1,
16
+ '\u0120', '\u0120', 0,
17
+ '\u0121', '\u0120', -1,
18
+ '\u0121', '\u0120|\u0121', 0,
19
+ '\u0122', '\u0120|\u0121', -1,
20
+ '\u0120', '[\u0120]', 0, // Safari 2.0.3 fails here.
21
+ '\u0121', '[\u0120]', -1,
22
+ '\u0121', '[\u0120\u0121]', 0, // Safari 2.0.3 fails here.
23
+ '\u0122', '[\u0120\u0121]', -1,
24
+ '\u0121', '[\u0120-\u0121]', 0, // Safari 2.0.3 fails here.
25
+ '\u0122', '[\u0120-\u0121]', -1];
26
+ for (var i = 0; i < tests.length; i += 3) {
27
+ if (tests[i].search(new RegExp(tests[i + 1])) != tests[i + 2]) {
28
+ return false;
29
+ }
30
+ }
31
+ return true;
32
+ }();
33
+
34
+ // Common tokens in XML 1.0 and XML 1.1.
35
+
36
+ var XML_S = '[ \t\r\n]+';
37
+ var XML_EQ = '(' + XML_S + ')?=(' + XML_S + ')?';
38
+ var XML_CHAR_REF = '&#[0-9]+;|&#x[0-9a-fA-F]+;';
39
+
40
+ // XML 1.0 tokens.
41
+
42
+ var XML10_VERSION_INFO = XML_S + 'version' + XML_EQ + '("1\\.0"|' + "'1\\.0')";
43
+ var XML10_BASE_CHAR = (REGEXP_UNICODE) ?
44
+ '\u0041-\u005a\u0061-\u007a\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u00ff' +
45
+ '\u0100-\u0131\u0134-\u013e\u0141-\u0148\u014a-\u017e\u0180-\u01c3' +
46
+ '\u01cd-\u01f0\u01f4-\u01f5\u01fa-\u0217\u0250-\u02a8\u02bb-\u02c1\u0386' +
47
+ '\u0388-\u038a\u038c\u038e-\u03a1\u03a3-\u03ce\u03d0-\u03d6\u03da\u03dc' +
48
+ '\u03de\u03e0\u03e2-\u03f3\u0401-\u040c\u040e-\u044f\u0451-\u045c' +
49
+ '\u045e-\u0481\u0490-\u04c4\u04c7-\u04c8\u04cb-\u04cc\u04d0-\u04eb' +
50
+ '\u04ee-\u04f5\u04f8-\u04f9\u0531-\u0556\u0559\u0561-\u0586\u05d0-\u05ea' +
51
+ '\u05f0-\u05f2\u0621-\u063a\u0641-\u064a\u0671-\u06b7\u06ba-\u06be' +
52
+ '\u06c0-\u06ce\u06d0-\u06d3\u06d5\u06e5-\u06e6\u0905-\u0939\u093d' +
53
+ '\u0958-\u0961\u0985-\u098c\u098f-\u0990\u0993-\u09a8\u09aa-\u09b0\u09b2' +
54
+ '\u09b6-\u09b9\u09dc-\u09dd\u09df-\u09e1\u09f0-\u09f1\u0a05-\u0a0a' +
55
+ '\u0a0f-\u0a10\u0a13-\u0a28\u0a2a-\u0a30\u0a32-\u0a33\u0a35-\u0a36' +
56
+ '\u0a38-\u0a39\u0a59-\u0a5c\u0a5e\u0a72-\u0a74\u0a85-\u0a8b\u0a8d' +
57
+ '\u0a8f-\u0a91\u0a93-\u0aa8\u0aaa-\u0ab0\u0ab2-\u0ab3\u0ab5-\u0ab9' +
58
+ '\u0abd\u0ae0\u0b05-\u0b0c\u0b0f-\u0b10\u0b13-\u0b28\u0b2a-\u0b30' +
59
+ '\u0b32-\u0b33\u0b36-\u0b39\u0b3d\u0b5c-\u0b5d\u0b5f-\u0b61\u0b85-\u0b8a' +
60
+ '\u0b8e-\u0b90\u0b92-\u0b95\u0b99-\u0b9a\u0b9c\u0b9e-\u0b9f\u0ba3-\u0ba4' +
61
+ '\u0ba8-\u0baa\u0bae-\u0bb5\u0bb7-\u0bb9\u0c05-\u0c0c\u0c0e-\u0c10' +
62
+ '\u0c12-\u0c28\u0c2a-\u0c33\u0c35-\u0c39\u0c60-\u0c61\u0c85-\u0c8c' +
63
+ '\u0c8e-\u0c90\u0c92-\u0ca8\u0caa-\u0cb3\u0cb5-\u0cb9\u0cde\u0ce0-\u0ce1' +
64
+ '\u0d05-\u0d0c\u0d0e-\u0d10\u0d12-\u0d28\u0d2a-\u0d39\u0d60-\u0d61' +
65
+ '\u0e01-\u0e2e\u0e30\u0e32-\u0e33\u0e40-\u0e45\u0e81-\u0e82\u0e84' +
66
+ '\u0e87-\u0e88\u0e8a\u0e8d\u0e94-\u0e97\u0e99-\u0e9f\u0ea1-\u0ea3\u0ea5' +
67
+ '\u0ea7\u0eaa-\u0eab\u0ead-\u0eae\u0eb0\u0eb2-\u0eb3\u0ebd\u0ec0-\u0ec4' +
68
+ '\u0f40-\u0f47\u0f49-\u0f69\u10a0-\u10c5\u10d0-\u10f6\u1100\u1102-\u1103' +
69
+ '\u1105-\u1107\u1109\u110b-\u110c\u110e-\u1112\u113c\u113e\u1140\u114c' +
70
+ '\u114e\u1150\u1154-\u1155\u1159\u115f-\u1161\u1163\u1165\u1167\u1169' +
71
+ '\u116d-\u116e\u1172-\u1173\u1175\u119e\u11a8\u11ab\u11ae-\u11af' +
72
+ '\u11b7-\u11b8\u11ba\u11bc-\u11c2\u11eb\u11f0\u11f9\u1e00-\u1e9b' +
73
+ '\u1ea0-\u1ef9\u1f00-\u1f15\u1f18-\u1f1d\u1f20-\u1f45\u1f48-\u1f4d' +
74
+ '\u1f50-\u1f57\u1f59\u1f5b\u1f5d\u1f5f-\u1f7d\u1f80-\u1fb4\u1fb6-\u1fbc' +
75
+ '\u1fbe\u1fc2-\u1fc4\u1fc6-\u1fcc\u1fd0-\u1fd3\u1fd6-\u1fdb\u1fe0-\u1fec' +
76
+ '\u1ff2-\u1ff4\u1ff6-\u1ffc\u2126\u212a-\u212b\u212e\u2180-\u2182' +
77
+ '\u3041-\u3094\u30a1-\u30fa\u3105-\u312c\uac00-\ud7a3' :
78
+ 'A-Za-z';
79
+ var XML10_IDEOGRAPHIC = (REGEXP_UNICODE) ?
80
+ '\u4e00-\u9fa5\u3007\u3021-\u3029' :
81
+ '';
82
+ var XML10_COMBINING_CHAR = (REGEXP_UNICODE) ?
83
+ '\u0300-\u0345\u0360-\u0361\u0483-\u0486\u0591-\u05a1\u05a3-\u05b9' +
84
+ '\u05bb-\u05bd\u05bf\u05c1-\u05c2\u05c4\u064b-\u0652\u0670\u06d6-\u06dc' +
85
+ '\u06dd-\u06df\u06e0-\u06e4\u06e7-\u06e8\u06ea-\u06ed\u0901-\u0903\u093c' +
86
+ '\u093e-\u094c\u094d\u0951-\u0954\u0962-\u0963\u0981-\u0983\u09bc\u09be' +
87
+ '\u09bf\u09c0-\u09c4\u09c7-\u09c8\u09cb-\u09cd\u09d7\u09e2-\u09e3\u0a02' +
88
+ '\u0a3c\u0a3e\u0a3f\u0a40-\u0a42\u0a47-\u0a48\u0a4b-\u0a4d\u0a70-\u0a71' +
89
+ '\u0a81-\u0a83\u0abc\u0abe-\u0ac5\u0ac7-\u0ac9\u0acb-\u0acd\u0b01-\u0b03' +
90
+ '\u0b3c\u0b3e-\u0b43\u0b47-\u0b48\u0b4b-\u0b4d\u0b56-\u0b57\u0b82-\u0b83' +
91
+ '\u0bbe-\u0bc2\u0bc6-\u0bc8\u0bca-\u0bcd\u0bd7\u0c01-\u0c03\u0c3e-\u0c44' +
92
+ '\u0c46-\u0c48\u0c4a-\u0c4d\u0c55-\u0c56\u0c82-\u0c83\u0cbe-\u0cc4' +
93
+ '\u0cc6-\u0cc8\u0cca-\u0ccd\u0cd5-\u0cd6\u0d02-\u0d03\u0d3e-\u0d43' +
94
+ '\u0d46-\u0d48\u0d4a-\u0d4d\u0d57\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1' +
95
+ '\u0eb4-\u0eb9\u0ebb-\u0ebc\u0ec8-\u0ecd\u0f18-\u0f19\u0f35\u0f37\u0f39' +
96
+ '\u0f3e\u0f3f\u0f71-\u0f84\u0f86-\u0f8b\u0f90-\u0f95\u0f97\u0f99-\u0fad' +
97
+ '\u0fb1-\u0fb7\u0fb9\u20d0-\u20dc\u20e1\u302a-\u302f\u3099\u309a' :
98
+ '';
99
+ var XML10_DIGIT = (REGEXP_UNICODE) ?
100
+ '\u0030-\u0039\u0660-\u0669\u06f0-\u06f9\u0966-\u096f\u09e6-\u09ef' +
101
+ '\u0a66-\u0a6f\u0ae6-\u0aef\u0b66-\u0b6f\u0be7-\u0bef\u0c66-\u0c6f' +
102
+ '\u0ce6-\u0cef\u0d66-\u0d6f\u0e50-\u0e59\u0ed0-\u0ed9\u0f20-\u0f29' :
103
+ '0-9';
104
+ var XML10_EXTENDER = (REGEXP_UNICODE) ?
105
+ '\u00b7\u02d0\u02d1\u0387\u0640\u0e46\u0ec6\u3005\u3031-\u3035' +
106
+ '\u309d-\u309e\u30fc-\u30fe' :
107
+ '';
108
+ var XML10_LETTER = XML10_BASE_CHAR + XML10_IDEOGRAPHIC;
109
+ var XML10_NAME_CHAR = XML10_LETTER + XML10_DIGIT + '\\._:' +
110
+ XML10_COMBINING_CHAR + XML10_EXTENDER + '-';
111
+ var XML10_NAME = '[' + XML10_LETTER + '_:][' + XML10_NAME_CHAR + ']*';
112
+
113
+ var XML10_ENTITY_REF = '&' + XML10_NAME + ';';
114
+ var XML10_REFERENCE = XML10_ENTITY_REF + '|' + XML_CHAR_REF;
115
+ var XML10_ATT_VALUE = '"(([^<&"]|' + XML10_REFERENCE + ')*)"|' +
116
+ "'(([^<&']|" + XML10_REFERENCE + ")*)'";
117
+ var XML10_ATTRIBUTE =
118
+ '(' + XML10_NAME + ')' + XML_EQ + '(' + XML10_ATT_VALUE + ')';
119
+
120
+ // XML 1.1 tokens.
121
+ // TODO(jtakagi): NameStartChar also includes \u10000-\ueffff.
122
+ // ECMAScript Language Specifiction defines UnicodeEscapeSequence as
123
+ // "\u HexDigit HexDigit HexDigit HexDigit" and we may need to use
124
+ // surrogate pairs, but any browser doesn't support surrogate paris in
125
+ // character classes of regular expression, so avoid including them for now.
126
+
127
+ var XML11_VERSION_INFO = XML_S + 'version' + XML_EQ + '("1\\.1"|' + "'1\\.1')";
128
+ var XML11_NAME_START_CHAR = (REGEXP_UNICODE) ?
129
+ ':A-Z_a-z\u00c0-\u00d6\u00d8-\u00f6\u00f8-\u02ff\u0370-\u037d' +
130
+ '\u037f-\u1fff\u200c-\u200d\u2070-\u218f\u2c00-\u2fef\u3001-\ud7ff' +
131
+ '\uf900-\ufdcf\ufdf0-\ufffd' :
132
+ ':A-Z_a-z';
133
+ var XML11_NAME_CHAR = XML11_NAME_START_CHAR +
134
+ ((REGEXP_UNICODE) ? '\\.0-9\u00b7\u0300-\u036f\u203f-\u2040-' : '\\.0-9-');
135
+ var XML11_NAME = '[' + XML11_NAME_START_CHAR + '][' + XML11_NAME_CHAR + ']*';
136
+
137
+ var XML11_ENTITY_REF = '&' + XML11_NAME + ';';
138
+ var XML11_REFERENCE = XML11_ENTITY_REF + '|' + XML_CHAR_REF;
139
+ var XML11_ATT_VALUE = '"(([^<&"]|' + XML11_REFERENCE + ')*)"|' +
140
+ "'(([^<&']|" + XML11_REFERENCE + ")*)'";
141
+ var XML11_ATTRIBUTE =
142
+ '(' + XML11_NAME + ')' + XML_EQ + '(' + XML11_ATT_VALUE + ')';
143
+
144
+ // XML Namespace tokens.
145
+ // Used in XML parser and XPath parser.
146
+
147
+ var XML_NC_NAME_CHAR = XML10_LETTER + XML10_DIGIT + '\\._' +
148
+ XML10_COMBINING_CHAR + XML10_EXTENDER + '-';
149
+ var XML_NC_NAME = '[' + XML10_LETTER + '_][' + XML_NC_NAME_CHAR + ']*';