selenium-core-runner 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
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,2816 @@
1
+ /* JavaScript-XPath 0.1.11
2
+ * (c) 2007 Cybozu Labs, Inc.
3
+ *
4
+ * JavaScript-XPath is freely distributable under the terms of an MIT-style license.
5
+ * For details, see the JavaScript-XPath web site: http://coderepos.org/share/wiki/JavaScript-XPath
6
+ *
7
+ /*--------------------------------------------------------------------------*/
8
+
9
+
10
+
11
+ (function () {
12
+
13
+ var undefined = void(0);
14
+
15
+ var defaultConfig = {
16
+ targetFrame: undefined,
17
+ exportInstaller: false,
18
+ useNative: true,
19
+ useInnerText: true
20
+ };
21
+
22
+ var config;
23
+
24
+ if (window.jsxpath) {
25
+ config = window.jsxpath;
26
+ }
27
+ else {
28
+ var scriptElms = document.getElementsByTagName('script');
29
+ var scriptElm = scriptElms[scriptElms.length - 1];
30
+ var scriptSrc = scriptElm.src;
31
+ config = {};
32
+ var scriptSrcMatchResult = scriptSrc.match(/\?(.*)$/);
33
+ if (scriptSrcMatchResult) {
34
+ var configStrings = scriptSrcMatchResult[1].split('&');
35
+ for (var i = 0, l = configStrings.length; i < l; i ++) {
36
+ var configString = configStrings[i];
37
+ var configStringSplited = configString.split('=');
38
+ var configName = configStringSplited[0];
39
+ var configValue = configStringSplited[1];
40
+ if (configValue == undefined) {
41
+ configValue == true;
42
+ }
43
+ else if (configValue == 'false' || /^-?\d+$/.test(configValue)) {
44
+ configValue = eval(configValue);
45
+ }
46
+ config[configName] = configValue;
47
+ }
48
+ }
49
+ }
50
+
51
+ for (var n in defaultConfig) {
52
+ if (!(n in config)) config[n] = defaultConfig[n];
53
+ }
54
+
55
+ config.hasNative = !!(document.implementation
56
+ && document.implementation.hasFeature
57
+ && document.implementation.hasFeature("XPath", null));
58
+
59
+ if (config.hasNative && config.useNative && !config.exportInstaller) {
60
+ return;
61
+ }
62
+
63
+
64
+
65
+ var BinaryExpr;
66
+ var FilterExpr;
67
+ var FunctionCall;
68
+ var Literal;
69
+ var NameTest;
70
+ var NodeSet;
71
+ var NodeType;
72
+ var NodeUtil;
73
+ var Number;
74
+ var PathExpr;
75
+ var Step;
76
+ var UnaryExpr;
77
+ var UnionExpr;
78
+ var VariableReference;
79
+
80
+ /*
81
+ * object: user agent identifier
82
+ */
83
+ var uai = new function() {
84
+
85
+ var ua = navigator.userAgent;
86
+
87
+ if (RegExp == undefined) {
88
+ if (ua.indexOf("Opera") >= 0) {
89
+ this.opera = true;
90
+ } else if (ua.indexOf("Netscape") >= 0) {
91
+ this.netscape = true;
92
+ } else if (ua.indexOf("Mozilla/") == 0) {
93
+ this.mozilla = true;
94
+ } else {
95
+ this.unknown = true;
96
+ }
97
+
98
+ if (ua.indexOf("Gecko/") >= 0) {
99
+ this.gecko = true;
100
+ }
101
+
102
+ if (ua.indexOf("Win") >= 0) {
103
+ this.windows = true;
104
+ } else if (ua.indexOf("Mac") >= 0) {
105
+ this.mac = true;
106
+ } else if (ua.indexOf("Linux") >= 0) {
107
+ this.linux = true;
108
+ } else if (ua.indexOf("BSD") >= 0) {
109
+ this.bsd = true;
110
+ } else if (ua.indexOf("SunOS") >= 0) {
111
+ this.sunos = true;
112
+ }
113
+ }
114
+ else {
115
+
116
+ /* for Trident/Tasman */
117
+ /*@cc_on
118
+ @if (@_jscript)
119
+ function jscriptVersion() {
120
+ switch (@_jscript_version) {
121
+ case 3.0: return "4.0";
122
+ case 5.0: return "5.0";
123
+ case 5.1: return "5.01";
124
+ case 5.5: return "5.5";
125
+ case 5.6:
126
+ if ("XMLHttpRequest" in window) return "7.0";
127
+ return "6.0";
128
+ case 5.7:
129
+ return "7.0";
130
+ default: return true;
131
+ }
132
+ }
133
+ if (@_win16 || @_win32 || @_win64) {
134
+ this.windows = true;
135
+ this.trident = jscriptVersion();
136
+ } else if (@_mac || navigator.platform.indexOf("Mac") >= 0) {
137
+ // '@_mac' may be 'NaN' even if the platform is Mac,
138
+ // so we check 'navigator.platform', too.
139
+ this.mac = true;
140
+ this.tasman = jscriptVersion();
141
+ }
142
+ if (/MSIE (\d+\.\d+)b?;/.test(ua)) {
143
+ this.ie = RegExp.$1;
144
+ this['ie' + RegExp.$1.charAt(0)] = true;
145
+ }
146
+ @else @*/
147
+
148
+ /* for AppleWebKit */
149
+ if (/AppleWebKit\/(\d+(?:\.\d+)*)/.test(ua)) {
150
+ this.applewebkit = RegExp.$1;
151
+ if (RegExp.$1.charAt(0) == 4) {
152
+ this.applewebkit2 = true;
153
+ }
154
+ else {
155
+ this.applewebkit3 = true;
156
+ }
157
+ }
158
+
159
+ /* for Gecko */
160
+ else if (typeof Components == "object" &&
161
+ (/Gecko\/(\d{8})/.test(ua) ||
162
+ navigator.product == "Gecko" && /^(\d{8})$/.test(navigator.productSub))) {
163
+ this.gecko = RegExp.$1;
164
+ }
165
+
166
+ /*@end @*/
167
+
168
+ if (typeof(opera) == "object" && typeof(opera.version) == "function") {
169
+ this.opera = opera.version();
170
+ this['opera' + this.opera[0] + this.opera[2]] = true;
171
+ } else if (typeof opera == "object"
172
+ && (/Opera[\/ ](\d+\.\d+)/.test(ua))) {
173
+ this.opera = RegExp.$1;
174
+ } else if (this.ie) {
175
+ } else if (/Safari\/(\d+(?:\.\d+)*)/.test(ua)) {
176
+ this.safari = RegExp.$1;
177
+ } else if (/NetFront\/(\d+(?:\.\d+)*)/.test(ua)) {
178
+ this.netfront = RegExp.$1;
179
+ } else if (/Konqueror\/(\d+(?:\.\d+)*)/.test(ua)) {
180
+ this.konqueror = RegExp.$1;
181
+ } else if (ua.indexOf("(compatible;") < 0
182
+ && (/^Mozilla\/(\d+\.\d+)/.test(ua))) {
183
+ this.mozilla = RegExp.$1;
184
+ if (/\([^(]*rv:(\d+(?:\.\d+)*).*?\)/.test(ua))
185
+ this.mozillarv = RegExp.$1;
186
+ if (/Firefox\/(\d+(?:\.\d+)*)/.test(ua)) {
187
+ this.firefox = RegExp.$1;
188
+ } else if (/Netscape\d?\/(\d+(?:\.\d+)*)/.test(ua)) {
189
+ this.netscape = RegExp.$1;
190
+ }
191
+ } else {
192
+ this.unknown = true;
193
+ }
194
+
195
+ if (ua.indexOf("Win 9x 4.90") >= 0) {
196
+ this.windows = "ME";
197
+ } else if (/Win(?:dows)? ?(NT ?(\d+\.\d+)?|\d+|ME|Vista|XP)/.test(ua)) {
198
+ this.windows = RegExp.$1;
199
+ if (RegExp.$2) {
200
+ this.winnt = RegExp.$2;
201
+ } else switch (RegExp.$1) {
202
+ case "2000": this.winnt = "5.0"; break;
203
+ case "XP": this.winnt = "5.1"; break;
204
+ case "Vista": this.winnt = "6.0"; break;
205
+ }
206
+ } else if (ua.indexOf("Mac") >= 0) {
207
+ this.mac = true;
208
+ } else if (ua.indexOf("Linux") >= 0) {
209
+ this.linux = true;
210
+ } else if (/(\w*BSD)/.test(ua)) {
211
+ this.bsd = RegExp.$1;
212
+ } else if (ua.indexOf("SunOS") >= 0) {
213
+ this.sunos = true;
214
+ }
215
+ }
216
+ };
217
+
218
+
219
+ /**
220
+ * pseudo class: Lexer
221
+ */
222
+ var Lexer = function(source) {
223
+ var proto = Lexer.prototype;
224
+ var tokens = source.match(proto.regs.token);
225
+ for (var i = 0, l = tokens.length; i < l; i ++) {
226
+ if (proto.regs.strip.test(tokens[i])) {
227
+ tokens.splice(i, 1);
228
+ }
229
+ }
230
+ for (var n in proto) tokens[n] = proto[n];
231
+ tokens.index = 0;
232
+ return tokens;
233
+ };
234
+
235
+ Lexer.prototype.regs = {
236
+ token: /\$?(?:(?![0-9-])[\w-]+:)?(?![0-9-])[\w-]+|\/\/|\.\.|::|\d+(?:\.\d*)?|\.\d+|"[^"]*"|'[^']*'|[!<>]=|(?![0-9-])[\w-]+:\*|\s+|./g,
237
+ strip: /^\s/
238
+ };
239
+
240
+ Lexer.prototype.peek = function(i) {
241
+ return this[this.index + (i||0)];
242
+ };
243
+ Lexer.prototype.next = function() {
244
+ return this[this.index++];
245
+ };
246
+ Lexer.prototype.back = function() {
247
+ this.index--;
248
+ };
249
+ Lexer.prototype.empty = function() {
250
+ return this.length <= this.index;
251
+ };
252
+
253
+
254
+ /**
255
+ * class: Ctx
256
+ */
257
+ var Ctx = function(node, position, last) {
258
+ this.node = node;
259
+ this.position = position || 1;
260
+ this.last = last || 1;
261
+ };
262
+
263
+
264
+ /**
265
+ * abstract class: BaseExpr
266
+ */
267
+ var BaseExpr = function() {};
268
+
269
+ BaseExpr.prototype.number = function(ctx) {
270
+ var exrs = this.evaluate(ctx);
271
+ if (exrs.isNodeSet) return exrs.number();
272
+ return + exrs;
273
+ };
274
+
275
+ BaseExpr.prototype.string = function(ctx) {
276
+ var exrs = this.evaluate(ctx);
277
+ if (exrs.isNodeSet) return exrs.string();
278
+ return '' + exrs;
279
+ };
280
+
281
+ BaseExpr.prototype.bool = function(ctx) {
282
+ var exrs = this.evaluate(ctx);
283
+ if (exrs.isNodeSet) return exrs.bool();
284
+ return !! exrs;
285
+ };
286
+
287
+
288
+ /**
289
+ * abstract class: BaseExprHasPredicates
290
+ */
291
+ var BaseExprHasPredicates = function() {};
292
+
293
+ BaseExprHasPredicates.parsePredicates = function(lexer, expr) {
294
+ while (lexer.peek() == '[') {
295
+ lexer.next();
296
+ if (lexer.empty()) {
297
+ throw Error('missing predicate expr');
298
+ }
299
+ var predicate = BinaryExpr.parse(lexer);
300
+ expr.predicate(predicate);
301
+ if (lexer.empty()) {
302
+ throw Error('unclosed predicate expr');
303
+ }
304
+ if (lexer.next() != ']') {
305
+ lexer.back();
306
+ throw Error('bad token: ' + lexer.next());
307
+ }
308
+ }
309
+ };
310
+
311
+ BaseExprHasPredicates.prototyps = new BaseExpr();
312
+
313
+ BaseExprHasPredicates.prototype.evaluatePredicates = function(nodeset, start) {
314
+ var predicates, predicate, nodes, node, nodeset, position, reverse;
315
+
316
+ reverse = this.reverse;
317
+ predicates = this.predicates;
318
+
319
+ nodeset.sort();
320
+
321
+ for (var i = start || 0, l0 = predicates.length; i < l0; i ++) {
322
+ predicate = predicates[i];
323
+
324
+ var deleteIndexes = [];
325
+ var nodes = nodeset.list();
326
+
327
+ for (var j = 0, l1 = nodes.length; j < l1; j ++) {
328
+
329
+ position = reverse ? (l1 - j) : (j + 1);
330
+ exrs = predicate.evaluate(new Ctx(nodes[j], position, l1));
331
+
332
+ switch (typeof exrs) {
333
+ case 'number':
334
+ exrs = (position == exrs);
335
+ break;
336
+ case 'string':
337
+ exrs = !!exrs;
338
+ break;
339
+ case 'object':
340
+ exrs = exrs.bool();
341
+ break;
342
+ }
343
+
344
+ if (!exrs) {
345
+ deleteIndexes.push(j);
346
+ }
347
+ }
348
+
349
+ for (var j = deleteIndexes.length - 1, l1 = 0; j >= l1; j --) {
350
+ nodeset.del(deleteIndexes[j]);
351
+ }
352
+
353
+ }
354
+
355
+ return nodeset;
356
+ };
357
+
358
+
359
+ /**
360
+ * class: BinaryExpr
361
+ */
362
+ if (!window.BinaryExpr && window.defaultConfig)
363
+ window.BinaryExpr = null;
364
+
365
+ BinaryExpr = function(op, left, right, datatype) {
366
+ this.op = op;
367
+ this.left = left;
368
+ this.right = right;
369
+
370
+ this.datatype = BinaryExpr.ops[op][2];
371
+
372
+ this.needContextPosition = left.needContextPosition || right.needContextPosition;
373
+ this.needContextNode = left.needContextNode || right.needContextNode;
374
+
375
+ // Optimize [@id="foo"] and [@name="bar"]
376
+ if (this.op == '=') {
377
+ if (!right.needContextNode && !right.needContextPosition &&
378
+ right.datatype != 'nodeset' && right.datatype != 'void' && left.quickAttr) {
379
+ this.quickAttr = true;
380
+ this.attrName = left.attrName;
381
+ this.attrValueExpr = right;
382
+ }
383
+ else if (!left.needContextNode && !left.needContextPosition &&
384
+ left.datatype != 'nodeset' && left.datatype != 'void' && right.quickAttr) {
385
+ this.quickAttr = true;
386
+ this.attrName = right.attrName;
387
+ this.attrValueExpr = left;
388
+ }
389
+ }
390
+ };
391
+
392
+ BinaryExpr.compare = function(op, comp, left, right, ctx) {
393
+ var type, lnodes, rnodes, nodes, nodeset, primitive;
394
+
395
+ left = left.evaluate(ctx);
396
+ right = right.evaluate(ctx);
397
+
398
+ if (left.isNodeSet && right.isNodeSet) {
399
+ lnodes = left.list();
400
+ rnodes = right.list();
401
+ for (var i = 0, l0 = lnodes.length; i < l0; i ++)
402
+ for (var j = 0, l1 = rnodes.length; j < l1; j ++)
403
+ if (comp(NodeUtil.to('string', lnodes[i]), NodeUtil.to('string', rnodes[j])))
404
+ return true;
405
+ return false;
406
+ }
407
+
408
+ if (left.isNodeSet || right.isNodeSet) {
409
+ if (left.isNodeSet)
410
+ nodeset = left, primitive = right;
411
+ else
412
+ nodeset = right, primitive = left;
413
+
414
+ nodes = nodeset.list();
415
+ type = typeof primitive;
416
+ for (var i = 0, l = nodes.length; i < l; i ++) {
417
+ if (comp(NodeUtil.to(type, nodes[i]), primitive))
418
+ return true;
419
+ }
420
+ return false;
421
+ }
422
+
423
+ if (op == '=' || op == '!=') {
424
+ if (typeof left == 'boolean' || typeof right == 'boolean') {
425
+ return comp(!!left, !!right);
426
+ }
427
+ if (typeof left == 'number' || typeof right == 'number') {
428
+ return comp(+left, +right);
429
+ }
430
+ return comp(left, right);
431
+ }
432
+
433
+ return comp(+left, +right);
434
+ };
435
+
436
+
437
+ BinaryExpr.ops = {
438
+ 'div': [6, function(left, right, ctx) {
439
+ return left.number(ctx) / right.number(ctx);
440
+ }, 'number'],
441
+ 'mod': [6, function(left, right, ctx) {
442
+ return left.number(ctx) % right.number(ctx);
443
+ }, 'number'],
444
+ '*': [6, function(left, right, ctx) {
445
+ return left.number(ctx) * right.number(ctx);
446
+ }, 'number'],
447
+ '+': [5, function(left, right, ctx) {
448
+ return left.number(ctx) + right.number(ctx);
449
+ }, 'number'],
450
+ '-': [5, function(left, right, ctx) {
451
+ return left.number(ctx) - right.number(ctx);
452
+ }, 'number'],
453
+ '<': [4, function(left, right, ctx) {
454
+ return BinaryExpr.compare('<',
455
+ function(a, b) { return a < b }, left, right, ctx);
456
+ }, 'boolean'],
457
+ '>': [4, function(left, right, ctx) {
458
+ return BinaryExpr.compare('>',
459
+ function(a, b) { return a > b }, left, right, ctx);
460
+ }, 'boolean'],
461
+ '<=': [4, function(left, right, ctx) {
462
+ return BinaryExpr.compare('<=',
463
+ function(a, b) { return a <= b }, left, right, ctx);
464
+ }, 'boolean'],
465
+ '>=': [4, function(left, right, ctx) {
466
+ return BinaryExpr.compare('>=',
467
+ function(a, b) { return a >= b }, left, right, ctx);
468
+ }, 'boolean'],
469
+ '=': [3, function(left, right, ctx) {
470
+ return BinaryExpr.compare('=',
471
+ function(a, b) { return a == b }, left, right, ctx);
472
+ }, 'boolean'],
473
+ '!=': [3, function(left, right, ctx) {
474
+ return BinaryExpr.compare('!=',
475
+ function(a, b) { return a != b }, left, right, ctx);
476
+ }, 'boolean'],
477
+ 'and': [2, function(left, right, ctx) {
478
+ return left.bool(ctx) && right.bool(ctx);
479
+ }, 'boolean'],
480
+ 'or': [1, function(left, right, ctx) {
481
+ return left.bool(ctx) || right.bool(ctx);
482
+ }, 'boolean']
483
+ };
484
+
485
+
486
+ BinaryExpr.parse = function(lexer) {
487
+ var op, precedence, info, expr, stack = [], index = lexer.index;
488
+
489
+ while (true) {
490
+
491
+ if (lexer.empty()) {
492
+ throw Error('missing right expression');
493
+ }
494
+ expr = UnaryExpr.parse(lexer);
495
+
496
+ op = lexer.next();
497
+ if (!op) {
498
+ break;
499
+ }
500
+
501
+ info = this.ops[op];
502
+ precedence = info && info[0];
503
+ if (!precedence) {
504
+ lexer.back();
505
+ break;
506
+ }
507
+
508
+ while (stack.length && precedence <= this.ops[stack[stack.length-1]][0]) {
509
+ expr = new BinaryExpr(stack.pop(), stack.pop(), expr);
510
+ }
511
+
512
+ stack.push(expr, op);
513
+ }
514
+
515
+ while (stack.length) {
516
+ expr = new BinaryExpr(stack.pop(), stack.pop(), expr);
517
+ }
518
+
519
+ return expr;
520
+ };
521
+
522
+ BinaryExpr.prototype = new BaseExpr();
523
+
524
+ BinaryExpr.prototype.evaluate = function(ctx) {
525
+ return BinaryExpr.ops[this.op][1](this.left, this.right, ctx);
526
+ };
527
+
528
+ BinaryExpr.prototype.show = function(indent) {
529
+ indent = indent || '';
530
+ var t = '';
531
+ t += indent + 'binary: ' + this.op + '\n';
532
+ indent += ' ';
533
+ t += this.left.show(indent);
534
+ t += this.right.show(indent);
535
+ return t;
536
+ };
537
+
538
+
539
+ /**
540
+ * class: UnaryExpr
541
+ */
542
+ if (!window.UnaryExpr && window.defaultConfig)
543
+ window.UnaryExpr = null;
544
+
545
+ UnaryExpr = function(op, expr) {
546
+ this.op = op;
547
+ this.expr = expr;
548
+
549
+ this.needContextPosition = expr.needContextPosition;
550
+ this.needContextNode = expr.needContextNode;
551
+ };
552
+
553
+ UnaryExpr.ops = { '-': 1 };
554
+
555
+ UnaryExpr.parse = function(lexer) {
556
+ var token;
557
+ if (this.ops[lexer.peek()])
558
+ return new UnaryExpr(lexer.next(), UnaryExpr.parse(lexer));
559
+ else
560
+ return UnionExpr.parse(lexer);
561
+ };
562
+
563
+ UnaryExpr.prototype = new BaseExpr();
564
+
565
+ UnaryExpr.prototype.datatype = 'number';
566
+
567
+ UnaryExpr.prototype.evaluate = function(ctx) {
568
+ return - this.expr.number(ctx);
569
+ };
570
+
571
+ UnaryExpr.prototype.show = function(indent) {
572
+ indent = indent || '';
573
+ var t = '';
574
+ t += indent + 'unary: ' + this.op + '\n';
575
+ indent += ' ';
576
+ t += this.expr.show(indent);
577
+ return t;
578
+ };
579
+
580
+
581
+ /**
582
+ * class: UnionExpr
583
+ */
584
+ if (!window.UnionExpr && window.defaultConfig)
585
+ window.UnionExpr = null;
586
+
587
+ UnionExpr = function() {
588
+ this.paths = [];
589
+ };
590
+
591
+ UnionExpr.ops = { '|': 1 };
592
+
593
+
594
+ UnionExpr.parse = function(lexer) {
595
+ var union, expr;
596
+
597
+ expr = PathExpr.parse(lexer);
598
+ if (!this.ops[lexer.peek()])
599
+ return expr;
600
+
601
+ union = new UnionExpr();
602
+ union.path(expr);
603
+
604
+ while (true) {
605
+ if (!this.ops[lexer.next()]) break;
606
+ if (lexer.empty()) {
607
+ throw Error('missing next union location path');
608
+ }
609
+ union.path(PathExpr.parse(lexer));
610
+ }
611
+
612
+
613
+
614
+ lexer.back();
615
+ return union;
616
+ };
617
+
618
+ UnionExpr.prototype = new BaseExpr();
619
+
620
+ UnionExpr.prototype.datatype = 'nodeset';
621
+
622
+ UnionExpr.prototype.evaluate = function(ctx) {
623
+ var paths = this.paths;
624
+ var nodeset = new NodeSet();
625
+ for (var i = 0, l = paths.length; i < l; i ++) {
626
+ var exrs = paths[i].evaluate(ctx);
627
+ if (!exrs.isNodeSet) throw Error('PathExpr must be nodeset');
628
+ nodeset.merge(exrs);
629
+ }
630
+ return nodeset;
631
+ };
632
+
633
+ UnionExpr.prototype.path = function(path) {
634
+ this.paths.push(path);
635
+
636
+ if (path.needContextPosition) {
637
+ this.needContextPosition = true;
638
+ }
639
+ if (path.needContextNode) {
640
+ this.needContextNode = true;
641
+ }
642
+ }
643
+ UnionExpr.prototype.show = function(indent) {
644
+ indent = indent || '';
645
+ var t = '';
646
+ t += indent + 'union:' + '\n';
647
+ indent += ' ';
648
+ for (var i = 0; i < this.paths.length; i ++) {
649
+ t += this.paths[i].show(indent);
650
+ }
651
+ return t;
652
+ };
653
+
654
+
655
+ /**
656
+ * class: PathExpr
657
+ */
658
+ if (!window.PathExpr && window.defaultConfig)
659
+ window.PathExpr = null;
660
+
661
+ PathExpr = function(filter) {
662
+ this.filter = filter;
663
+ this.steps = [];
664
+
665
+ this.datatype = filter.datatype;
666
+
667
+ this.needContextPosition = filter.needContextPosition;
668
+ this.needContextNode = filter.needContextNode;
669
+ };
670
+
671
+ PathExpr.ops = { '//': 1, '/': 1 };
672
+
673
+ PathExpr.parse = function(lexer) {
674
+ var op, expr, path, token;
675
+
676
+ if (this.ops[lexer.peek()]) {
677
+ op = lexer.next();
678
+ token = lexer.peek();
679
+
680
+ if (op == '/' && (lexer.empty() ||
681
+ (token != '.' && token != '..' && token != '@' && token != '*' &&
682
+ !/(?![0-9])[\w]/.test(token)))) {
683
+ return FilterExpr.root();
684
+ }
685
+
686
+ path = new PathExpr(FilterExpr.root()); // RootExpr
687
+
688
+ if (lexer.empty()) {
689
+ throw Error('missing next location step');
690
+ }
691
+ expr = Step.parse(lexer);
692
+ path.step(op, expr);
693
+ }
694
+ else {
695
+ expr = FilterExpr.parse(lexer);
696
+ if (!expr) {
697
+ expr = Step.parse(lexer);
698
+ path = new PathExpr(FilterExpr.context());
699
+ path.step('/', expr);
700
+ }
701
+ else if (!this.ops[lexer.peek()])
702
+ return expr;
703
+ else
704
+ path = new PathExpr(expr);
705
+ }
706
+
707
+ while (true) {
708
+ if (!this.ops[lexer.peek()]) break;
709
+ op = lexer.next();
710
+ if (lexer.empty()) {
711
+ throw Error('missing next location step');
712
+ }
713
+ path.step(op, Step.parse(lexer));
714
+ }
715
+
716
+ return path;
717
+ };
718
+
719
+ PathExpr.prototype = new BaseExpr();
720
+
721
+ PathExpr.prototype.evaluate = function(ctx) {
722
+ var nodeset = this.filter.evaluate(ctx);
723
+ if (!nodeset.isNodeSet) throw Exception('Filter nodeset must be nodeset type');
724
+
725
+ var steps = this.steps;
726
+
727
+ for (var i = 0, l0 = steps.length; i < l0 && nodeset.length; i ++) {
728
+ var step = steps[i][1];
729
+ var reverse = step.reverse;
730
+ var iter = nodeset.iterator(reverse);
731
+ var prevNodeset = nodeset;
732
+ nodeset = null;
733
+ var node, next;
734
+ if (!step.needContextPosition && step.axis == 'following') {
735
+ for (node = iter(); next = iter(); node = next) {
736
+
737
+ // Safari 2 node.contains problem
738
+ if (uai.applewebkit2) {
739
+ var contains = false;
740
+ var ancestor = next;
741
+ do {
742
+ if (ancestor == node) {
743
+ contains = true;
744
+ break;
745
+ }
746
+ } while (ancestor = ancestor.parentNode);
747
+ if (!contains) break;
748
+ }
749
+ else {
750
+ try { if (!node.contains(next)) break }
751
+ catch(e) { if (!(next.compareDocumentPosition(node) & 8)) break }
752
+ }
753
+ }
754
+ nodeset = step.evaluate(new Ctx(node));
755
+ }
756
+ else if (!step.needContextPosition && step.axis == 'preceding') {
757
+ node = iter();
758
+ nodeset = step.evaluate(new Ctx(node));
759
+ }
760
+ else {
761
+ node = iter();
762
+ var j = 0;
763
+ nodeset = step.evaluate(new Ctx(node), false, prevNodeset, j);
764
+ while (node = iter()) {
765
+ j ++;
766
+ nodeset.merge(step.evaluate(new Ctx(node), false, prevNodeset, j));
767
+ }
768
+ }
769
+ }
770
+
771
+ return nodeset;
772
+ };
773
+
774
+ PathExpr.prototype.step = function(op, step) {
775
+ step.op = op;
776
+ this.steps.push([op, step]);
777
+
778
+ this.quickAttr = false;
779
+
780
+ if (this.steps.length == 1) {
781
+ if (op == '/' && step.axis == 'attribute') {
782
+ var test = step.test;
783
+ if (!test.notOnlyElement && test.name != '*') {
784
+ this.quickAttr = true;
785
+ this.attrName = test.name;
786
+ }
787
+ }
788
+ }
789
+ };
790
+
791
+ PathExpr.prototype.show = function(indent) {
792
+ indent = indent || '';
793
+ var t = '';
794
+ t += indent + 'path:' + '\n';
795
+ indent += ' ';
796
+ t += indent + 'filter:' + '\n';
797
+ t += this.filter.show(indent + ' ');
798
+ if (this.steps.length) {
799
+ t += indent + 'steps:' + '\n';
800
+ indent += ' ';
801
+ for (var i = 0; i < this.steps.length; i ++) {
802
+ var step = this.steps[i];
803
+ t += indent + 'operator: ' + step[0] + '\n';
804
+ t += step[1].show(indent);
805
+ }
806
+ }
807
+ return t;
808
+ };
809
+
810
+
811
+ /**
812
+ * class: FilterExpr
813
+ */
814
+ if (!window.FilterExpr && window.defaultConfig)
815
+ window.FilterExpr = null;
816
+
817
+ FilterExpr = function(primary) {
818
+ this.primary = primary;
819
+ this.predicates = [];
820
+
821
+ this.datatype = primary.datatype;
822
+
823
+ this.needContextPosition = primary.needContextPosition;
824
+
825
+ this.needContextNode = primary.needContextNode;
826
+ };
827
+
828
+ FilterExpr.parse = function(lexer) {
829
+ var expr, filter, token, ch;
830
+
831
+ token = lexer.peek();
832
+ ch = token.charAt(0);
833
+
834
+ switch (ch) {
835
+ case '$':
836
+ expr = VariableReference.parse(lexer);
837
+ break;
838
+
839
+ case '(':
840
+ lexer.next();
841
+ expr = BinaryExpr.parse(lexer);
842
+ if (lexer.empty()) {
843
+ throw Error('unclosed "("');
844
+ }
845
+ if (lexer.next() != ')') {
846
+ lexer.back();
847
+ throw Error('bad token: ' + lexer.next());
848
+ }
849
+ break;
850
+
851
+ case '"':
852
+ case "'":
853
+ expr = Literal.parse(lexer);
854
+ break;
855
+
856
+ default:
857
+ if (!isNaN(+token)) {
858
+ expr = Number.parse(lexer);
859
+ }
860
+
861
+ else if (NodeType.types[token]) {
862
+ return null;
863
+ }
864
+
865
+ else if (/(?![0-9])[\w]/.test(ch) && lexer.peek(1) == '(') {
866
+ expr = FunctionCall.parse(lexer);
867
+ }
868
+ else {
869
+ return null;
870
+ }
871
+ break;
872
+ }
873
+
874
+ if (lexer.peek() != '[') return expr;
875
+
876
+ filter = new FilterExpr(expr);
877
+
878
+ BaseExprHasPredicates.parsePredicates(lexer, filter);
879
+
880
+ return filter;
881
+ };
882
+
883
+ FilterExpr.root = function() {
884
+ return new FunctionCall('root-node');
885
+ };
886
+ FilterExpr.context = function() {
887
+ return new FunctionCall('context-node');
888
+ };
889
+
890
+ FilterExpr.prototype = new BaseExprHasPredicates();
891
+
892
+ FilterExpr.prototype.evaluate = function(ctx) {
893
+ var nodeset = this.primary.evaluate(ctx);
894
+ if(!nodeset.isNodeSet) {
895
+ if (this.predicates.length)
896
+ throw Error(
897
+ 'Primary result must be nodeset type ' +
898
+ 'if filter have predicate expression');
899
+ return nodeset;
900
+ }
901
+
902
+ return this.evaluatePredicates(nodeset);
903
+ };
904
+
905
+ FilterExpr.prototype.predicate = function(predicate) {
906
+ this.predicates.push(predicate);
907
+ };
908
+
909
+ FilterExpr.prototype.show = function(indent) {
910
+ indent = indent || '';
911
+ var t = '';
912
+ t += indent + 'filter: ' + '\n';
913
+ indent += ' ';
914
+ t += this.primary.show(indent);
915
+ if (this.predicates.length) {
916
+ t += indent + 'predicates: ' + '\n';
917
+ indent += ' ';
918
+ for (var i = 0; i < this.predicates.length; i ++) {
919
+ t += this.predicates[i].show(indent);
920
+ }
921
+ }
922
+ return t;
923
+ };
924
+
925
+
926
+ if (!window.NodeUtil && window.defaultConfig)
927
+ window.NodeUtil = null;
928
+
929
+ NodeUtil = {
930
+ to: function(valueType, node) {
931
+ var t, type = node.nodeType;
932
+ // Safari2: innerText contains some bugs
933
+ if (type == 1 && config.useInnerText && !uai.applewebkit2) {
934
+ t = node.textContent;
935
+ t = (t == undefined || t == null) ? node.innerText : t;
936
+ t = (t == undefined || t == null) ? '' : t;
937
+ }
938
+ if (typeof t != 'string') {
939
+ /*@cc_on
940
+ if (type == 1 && node.nodeName.toLowerCase() == 'title') {
941
+ t = node.text;
942
+ }
943
+ else
944
+ @*/
945
+ if (type == 9 || type == 1) {
946
+ if (type == 9) {
947
+ node = node.documentElement;
948
+ }
949
+ else {
950
+ node = node.firstChild;
951
+ }
952
+ for (t = '', stack = [], i = 0; node;) {
953
+ do {
954
+ if (node.nodeType != 1) {
955
+ t += node.nodeValue;
956
+ }
957
+ /*@cc_on
958
+ else if (node.nodeName.toLowerCase() == 'title') {
959
+ t += node.text;
960
+ }
961
+ @*/
962
+ stack[i++] = node; // push
963
+ } while (node = node.firstChild);
964
+ while (i && !(node = stack[--i].nextSibling)) {}
965
+ }
966
+ }
967
+ else {
968
+ t = node.nodeValue;
969
+ }
970
+ }
971
+ switch (valueType) {
972
+ case 'number':
973
+ return + t;
974
+ case 'boolean':
975
+ return !! t;
976
+ default:
977
+ return t;
978
+ }
979
+ },
980
+ attrPropMap: {
981
+ name: 'name',
982
+ 'class': 'className',
983
+ dir: 'dir',
984
+ id: 'id',
985
+ name: 'name',
986
+ title: 'title'
987
+ },
988
+ attrMatch: function(node, attrName, attrValue) {
989
+ /*@cc_on @if (@_jscript)
990
+ var propName = NodeUtil.attrPropMap[attrName];
991
+ if (!attrName ||
992
+ attrValue == null && (
993
+ propName && node[propName] ||
994
+ !propName && node.getAttribute && node.getAttribute(attrName, 2)
995
+ ) ||
996
+ attrValue != null && (
997
+ propName && node[propName] == attrValue ||
998
+ !propName && node.getAttribute && node.getAttribute(attrName, 2) == attrValue
999
+ )) {
1000
+ @else @*/
1001
+ if (!attrName ||
1002
+ attrValue == null && node.hasAttribute && node.hasAttribute(attrName) ||
1003
+ attrValue != null && node.getAttribute && node.getAttribute(attrName) == attrValue) {
1004
+ /*@end @*/
1005
+ return true;
1006
+ }
1007
+ else {
1008
+ return false;
1009
+ }
1010
+ },
1011
+ getDescendantNodes: function(test, node, nodeset, attrName, attrValue, prevNodeset, prevIndex) {
1012
+ if (prevNodeset) {
1013
+ prevNodeset.delDescendant(node, prevIndex);
1014
+ }
1015
+ /*@cc_on
1016
+ try {
1017
+ if (!test.notOnlyElement || test.type == 8 || (attrName && test.type == 0)) {
1018
+
1019
+ var all = node.all;
1020
+ if (!all) {
1021
+ return nodeset;
1022
+ }
1023
+
1024
+ var name = test.name;
1025
+ if (test.type == 8) name = '!';
1026
+ else if (test.type == 0) name = '*';
1027
+
1028
+ if (name != '*') {
1029
+ all = all.tags(name);
1030
+ if (!all) {
1031
+ return nodeset;
1032
+ }
1033
+ }
1034
+
1035
+ if (attrName) {
1036
+ var result = []
1037
+ var i = 0;
1038
+ if (attrValue != null && (attrName == 'id' || attrName == 'name')) {
1039
+ all = all[attrValue];
1040
+ if (!all) {
1041
+ return nodeset;
1042
+ }
1043
+ if (!all.length || all.nodeType) {
1044
+ all = [all];
1045
+ }
1046
+ }
1047
+
1048
+ while (node = all[i++]) {
1049
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) result.push(node);
1050
+ }
1051
+
1052
+ all = result;
1053
+ }
1054
+
1055
+ var i = 0;
1056
+ while (node = all[i++]) {
1057
+ if (name != '*' || node.tagName != '!') {
1058
+ nodeset.push(node);
1059
+ }
1060
+ }
1061
+
1062
+ return nodeset;
1063
+ }
1064
+
1065
+ (function (parent) {
1066
+ var g = arguments.callee;
1067
+ var node = parent.firstChild;
1068
+ if (node) {
1069
+ for (; node; node = node.nextSibling) {
1070
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) {
1071
+ if (test.match(node)) nodeset.push(node);
1072
+ }
1073
+ g(node);
1074
+ }
1075
+ }
1076
+ })(node);
1077
+
1078
+ return nodeset;
1079
+ }
1080
+ catch(e) {
1081
+ @*/
1082
+ if (attrValue && attrName == 'id' && node.getElementById) {
1083
+ node = node.getElementById(attrValue);
1084
+ if (node && test.match(node)) {
1085
+ nodeset.push(node);
1086
+ }
1087
+ }
1088
+ else if (attrValue && attrName == 'name' && node.getElementsByName) {
1089
+ var nodes = node.getElementsByName(attrValue);
1090
+ for (var i = 0, l = nodes.length; i < l; i ++) {
1091
+ node = nodes[i];
1092
+ if (uai.opera ? (node.name == attrValue && test.match(node)) : test.match(node)) {
1093
+ nodeset.push(node);
1094
+ }
1095
+ }
1096
+ }
1097
+ else if (attrValue && attrName == 'class' && node.getElementsByClassName) {
1098
+ var nodes = node.getElementsByClassName(attrValue);
1099
+ for (var i = 0, l = nodes.length; i < l; i ++) {
1100
+ node = nodes[i];
1101
+ if (node.className == attrValue && test.match(node)) {
1102
+ nodeset.push(node);
1103
+ }
1104
+ }
1105
+ }
1106
+ else if (test.notOnlyElement) {
1107
+ (function (parent) {
1108
+ var f = arguments.callee;
1109
+ for (var node = parent.firstChild; node; node = node.nextSibling) {
1110
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) {
1111
+ if (test.match(node.nodeType)) nodeset.push(node);
1112
+ }
1113
+ f(node);
1114
+ }
1115
+ })(node);
1116
+ }
1117
+ else {
1118
+ var name = test.name;
1119
+ if (node.getElementsByTagName) {
1120
+ var nodes = node.getElementsByTagName(name);
1121
+ if (nodes) {
1122
+ var i = 0;
1123
+ while (node = nodes[i++]) {
1124
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) nodeset.push(node);
1125
+ }
1126
+ }
1127
+ }
1128
+ }
1129
+ return nodeset;
1130
+ /*@cc_on
1131
+ }
1132
+ @*/
1133
+ },
1134
+
1135
+ getChildNodes: function(test, node, nodeset, attrName, attrValue) {
1136
+
1137
+ /*@cc_on
1138
+ try {
1139
+ var children;
1140
+
1141
+ if ((!test.notOnlyElement || test.type == 8 || (attrName && test.type == 0)) && (children = node.children)) {
1142
+ var name, elm;
1143
+
1144
+ name = test.name;
1145
+ if (test.type == 8) name = '!';
1146
+ else if (test.type == 0) name = '*';
1147
+
1148
+ if (name != '*') {
1149
+ children = children.tags(name);
1150
+ if (!children) {
1151
+ return nodeset;
1152
+ }
1153
+ }
1154
+
1155
+ if (attrName) {
1156
+ var result = []
1157
+ var i = 0;
1158
+ if (attrName == 'id' || attrName == 'name') {
1159
+ children = children[attrValue];
1160
+
1161
+ if (!children) {
1162
+ return nodeset;
1163
+ }
1164
+
1165
+ if (!children.length || children.nodeType) {
1166
+ children = [children];
1167
+ }
1168
+ }
1169
+
1170
+ while (node = children[i++]) {
1171
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) result.push(node);
1172
+ }
1173
+ children = result;
1174
+ }
1175
+
1176
+ var i = 0;
1177
+ while (node = children[i++]) {
1178
+ if (name != '*' || node.tagName != '!') {
1179
+ nodeset.push(node);
1180
+ }
1181
+ }
1182
+
1183
+ return nodeset;
1184
+ }
1185
+
1186
+ for (var i = 0, node = node.firstChild; node; i++, node = node.nextSibling) {
1187
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) {
1188
+ if (test.match(node)) nodeset.push(node);
1189
+ }
1190
+ }
1191
+
1192
+ return nodeset;
1193
+ } catch(e) {
1194
+ @*/
1195
+ for (var node = node.firstChild; node; node = node.nextSibling) {
1196
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) {
1197
+ if (test.match(node)) nodeset.push(node);
1198
+ }
1199
+ }
1200
+ return nodeset;
1201
+ /*@cc_on
1202
+ }
1203
+ @*/
1204
+ }
1205
+ };
1206
+
1207
+ /*@cc_on
1208
+ var AttributeWrapper = function(node, parent, sourceIndex) {
1209
+ this.node = node;
1210
+ this.nodeType = 2;
1211
+ this.nodeValue = node.nodeValue;
1212
+ this.nodeName = node.nodeName;
1213
+ this.parentNode = parent;
1214
+ this.ownerElement = parent;
1215
+ this.parentSourceIndex = sourceIndex;
1216
+ };
1217
+
1218
+ @*/
1219
+
1220
+
1221
+ /**
1222
+ * class: Step
1223
+ */
1224
+ if (!window.Step && window.defaultConfig)
1225
+ window.Step = null;
1226
+
1227
+ Step = function(axis, test) {
1228
+ // TODO check arguments and throw axis error
1229
+ this.axis = axis;
1230
+ this.reverse = Step.axises[axis][0];
1231
+ this.func = Step.axises[axis][1];
1232
+ this.test = test;
1233
+ this.predicates = [];
1234
+ this._quickAttr = Step.axises[axis][2]
1235
+ };
1236
+
1237
+ Step.axises = {
1238
+
1239
+ ancestor: [true, function(test, node, nodeset, _, __, prevNodeset, prevIndex) {
1240
+ while (node = node.parentNode) {
1241
+ if (prevNodeset && node.nodeType == 1) {
1242
+ prevNodeset.reserveDelByNode(node, prevIndex, true);
1243
+ }
1244
+ if (test.match(node)) nodeset.unshift(node);
1245
+ }
1246
+ return nodeset;
1247
+ }],
1248
+
1249
+ 'ancestor-or-self': [true, function(test, node, nodeset, _, __, prevNodeset, prevIndex) {
1250
+ do {
1251
+ if (prevNodeset && node.nodeType == 1) {
1252
+ prevNodeset.reserveDelByNode(node, prevIndex, true);
1253
+ }
1254
+ if (test.match(node)) nodeset.unshift(node);
1255
+ } while (node = node.parentNode)
1256
+ return nodeset;
1257
+ }],
1258
+
1259
+ attribute: [false, function(test, node, nodeset) {
1260
+ var attrs = node.attributes;
1261
+ if (attrs) {
1262
+ /*@cc_on
1263
+ var sourceIndex = node.sourceIndex;
1264
+ @*/
1265
+ if ((test.notOnlyElement && test.type == 0) || test.name == '*') {
1266
+ for (var i = 0, attr; attr = attrs[i]; i ++) {
1267
+ /*@cc_on @if (@_jscript)
1268
+ if (attr.nodeValue) {
1269
+ nodeset.push(new AttributeWrapper(attr, node, sourceIndex));
1270
+ }
1271
+ @else @*/
1272
+ nodeset.push(attr);
1273
+ /*@end @*/
1274
+ }
1275
+ }
1276
+ else {
1277
+ var attr = attrs.getNamedItem(test.name);
1278
+
1279
+ /*@cc_on @if (@_jscript)
1280
+ if (attr && attr.nodeValue) {
1281
+ attr = new AttributeWrapper(attr, node, sourceIndex);;
1282
+ @else @*/
1283
+ if (attr) {
1284
+ /*@end @*/
1285
+ nodeset.push(attr);
1286
+ }
1287
+ }
1288
+ }
1289
+ return nodeset;
1290
+ }],
1291
+
1292
+ child: [false, NodeUtil.getChildNodes, true],
1293
+
1294
+ descendant: [false, NodeUtil.getDescendantNodes, true],
1295
+
1296
+ 'descendant-or-self': [false, function(test, node, nodeset, attrName, attrValue, prevNodeset, prevIndex) {
1297
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) {
1298
+ if (test.match(node)) nodeset.push(node);
1299
+ }
1300
+ return NodeUtil.getDescendantNodes(test, node, nodeset, attrName, attrValue, prevNodeset, prevIndex);
1301
+ }, true],
1302
+
1303
+ following: [false, function(test, node, nodeset, attrName, attrValue) {
1304
+ do {
1305
+ var child = node;
1306
+ while (child = child.nextSibling) {
1307
+ if (NodeUtil.attrMatch(child, attrName, attrValue)) {
1308
+ if (test.match(child)) nodeset.push(child);
1309
+ }
1310
+ nodeset = NodeUtil.getDescendantNodes(test, child, nodeset, attrName, attrValue);
1311
+ }
1312
+ } while (node = node.parentNode);
1313
+ return nodeset;
1314
+ }, true],
1315
+
1316
+ 'following-sibling': [false, function(test, node, nodeset, _, __, prevNodeset, prevIndex) {
1317
+ while (node = node.nextSibling) {
1318
+
1319
+ if (prevNodeset && node.nodeType == 1) {
1320
+ prevNodeset.reserveDelByNode(node, prevIndex);
1321
+ }
1322
+
1323
+ if (test.match(node)) {
1324
+ nodeset.push(node);
1325
+ }
1326
+ }
1327
+ return nodeset;
1328
+ }],
1329
+
1330
+ namespace: [false, function(test, node, nodeset) {
1331
+ // not implemented
1332
+ return nodeset;
1333
+ }],
1334
+
1335
+ parent: [false, function(test, node, nodeset) {
1336
+ if (node.nodeType == 9) {
1337
+ return nodeset;
1338
+ }
1339
+ if (node.nodeType == 2) {
1340
+ nodeset.push(node.ownerElement);
1341
+ return nodeset;
1342
+ }
1343
+ var node = node.parentNode;
1344
+ if (test.match(node)) nodeset.push(node);
1345
+ return nodeset;
1346
+ }],
1347
+
1348
+ preceding: [true, function(test, node, nodeset, attrName, attrValue) {
1349
+ var parents = [];
1350
+ do {
1351
+ parents.unshift(node);
1352
+ } while (node = node.parentNode);
1353
+
1354
+ for (var i = 1, l0 = parents.length; i < l0; i ++) {
1355
+ var siblings = [];
1356
+ node = parents[i];
1357
+ while (node = node.previousSibling) {
1358
+ siblings.unshift(node);
1359
+ }
1360
+
1361
+ for (var j = 0, l1 = siblings.length; j < l1; j ++) {
1362
+ node = siblings[j];
1363
+ if (NodeUtil.attrMatch(node, attrName, attrValue)) {
1364
+ if (test.match(node)) nodeset.push(node);
1365
+ }
1366
+ nodeset = NodeUtil.getDescendantNodes(test, node, nodeset, attrName, attrValue);
1367
+ }
1368
+ }
1369
+ return nodeset;
1370
+ }, true],
1371
+
1372
+ 'preceding-sibling': [true, function(test, node, nodeset, _, __, prevNodeset, prevIndex) {
1373
+ while (node = node.previousSibling) {
1374
+
1375
+ if (prevNodeset && node.nodeType == 1) {
1376
+ prevNodeset.reserveDelByNode(node, prevIndex, true);
1377
+ }
1378
+
1379
+ if (test.match(node)) {
1380
+ nodeset.unshift(node)
1381
+ }
1382
+ }
1383
+ return nodeset;
1384
+ }],
1385
+
1386
+ self: [false, function(test, node, nodeset) {
1387
+ if (test.match(node)) nodeset.push(node);
1388
+ return nodeset;
1389
+ }]
1390
+ };
1391
+
1392
+ Step.parse = function(lexer) {
1393
+ var axis, test, step, token;
1394
+
1395
+ if (lexer.peek() == '.') {
1396
+ step = this.self();
1397
+ lexer.next();
1398
+ }
1399
+ else if (lexer.peek() == '..') {
1400
+ step = this.parent();
1401
+ lexer.next();
1402
+ }
1403
+ else {
1404
+ if (lexer.peek() == '@') {
1405
+ axis = 'attribute';
1406
+ lexer.next();
1407
+ if (lexer.empty()) {
1408
+ throw Error('missing attribute name');
1409
+ }
1410
+ }
1411
+ else {
1412
+ if (lexer.peek(1) == '::') {
1413
+
1414
+ if (!/(?![0-9])[\w]/.test(lexer.peek().charAt(0))) {
1415
+ throw Error('bad token: ' + lexer.next());
1416
+ }
1417
+
1418
+ axis = lexer.next();
1419
+ lexer.next();
1420
+
1421
+ if (!this.axises[axis]) {
1422
+ throw Error('invalid axis: ' + axis);
1423
+ }
1424
+ if (lexer.empty()) {
1425
+ throw Error('missing node name');
1426
+ }
1427
+ }
1428
+ else {
1429
+ axis = 'child';
1430
+ }
1431
+ }
1432
+
1433
+ token = lexer.peek();
1434
+ if (!/(?![0-9])[\w]/.test(token.charAt(0))) {
1435
+ if (token == '*') {
1436
+ test = NameTest.parse(lexer)
1437
+ }
1438
+ else {
1439
+ throw Error('bad token: ' + lexer.next());
1440
+ }
1441
+ }
1442
+ else {
1443
+ if (lexer.peek(1) == '(') {
1444
+ if (!NodeType.types[token]) {
1445
+ throw Error('invalid node type: ' + token);
1446
+ }
1447
+ test = NodeType.parse(lexer)
1448
+ }
1449
+ else {
1450
+ test = NameTest.parse(lexer);
1451
+ }
1452
+ }
1453
+ step = new Step(axis, test);
1454
+ }
1455
+
1456
+ BaseExprHasPredicates.parsePredicates(lexer, step);
1457
+
1458
+ return step;
1459
+ };
1460
+
1461
+ Step.self = function() {
1462
+ return new Step('self', new NodeType('node'));
1463
+ };
1464
+
1465
+ Step.parent = function() {
1466
+ return new Step('parent', new NodeType('node'));
1467
+ };
1468
+
1469
+ Step.prototype = new BaseExprHasPredicates();
1470
+
1471
+ Step.prototype.evaluate = function(ctx, special, prevNodeset, prevIndex) {
1472
+ var node = ctx.node;
1473
+ var reverse = false;
1474
+
1475
+ if (!special && this.op == '//') {
1476
+
1477
+ if (!this.needContextPosition && this.axis == 'child') {
1478
+ if (this.quickAttr) {
1479
+ var attrValue = this.attrValueExpr ? this.attrValueExpr.string(ctx) : null;
1480
+ var nodeset = NodeUtil.getDescendantNodes(this.test, node, new NodeSet(), this.attrName, attrValue, prevNodeset, prevIndex);
1481
+ nodeset = this.evaluatePredicates(nodeset, 1);
1482
+ }
1483
+ else {
1484
+ var nodeset = NodeUtil.getDescendantNodes(this.test, node, new NodeSet(), null, null, prevNodeset, prevIndex);
1485
+ nodeset = this.evaluatePredicates(nodeset);
1486
+ }
1487
+ }
1488
+ else {
1489
+ var step = new Step('descendant-or-self', new NodeType('node'));
1490
+ var nodes = step.evaluate(ctx, false, prevNodeset, prevIndex).list();
1491
+ var nodeset = null;
1492
+ step.op = '/';
1493
+ for (var i = 0, l = nodes.length; i < l; i ++) {
1494
+ if (!nodeset) {
1495
+ nodeset = this.evaluate(new Ctx(nodes[i]), true);
1496
+ }
1497
+ else {
1498
+ nodeset.merge(this.evaluate(new Ctx(nodes[i]), true));
1499
+ }
1500
+ }
1501
+ nodeset = nodeset || new NodeSet();
1502
+ }
1503
+ }
1504
+ else {
1505
+
1506
+ if (this.needContextPosition) {
1507
+ prevNodeset = null;
1508
+ prevIndex = null;
1509
+ }
1510
+
1511
+ if (this.quickAttr) {
1512
+ var attrValue = this.attrValueExpr ? this.attrValueExpr.string(ctx) : null;
1513
+ var nodeset = this.func(this.test, node, new NodeSet(), this.attrName, attrValue, prevNodeset, prevIndex);
1514
+ nodeset = this.evaluatePredicates(nodeset, 1);
1515
+ }
1516
+ else {
1517
+ var nodeset = this.func(this.test, node, new NodeSet(), null, null, prevNodeset, prevIndex);
1518
+ nodeset = this.evaluatePredicates(nodeset);
1519
+ }
1520
+ if (prevNodeset) {
1521
+ prevNodeset.doDel();
1522
+ }
1523
+ }
1524
+ return nodeset;
1525
+ };
1526
+
1527
+ Step.prototype.predicate = function(predicate) {
1528
+ this.predicates.push(predicate);
1529
+
1530
+ if (predicate.needContextPosition ||
1531
+ predicate.datatype == 'number'||
1532
+ predicate.datatype == 'void') {
1533
+ this.needContextPosition = true;
1534
+ }
1535
+
1536
+ if (this._quickAttr && this.predicates.length == 1 && predicate.quickAttr) {
1537
+ var attrName = predicate.attrName;
1538
+ /*@cc_on @if (@_jscript)
1539
+ this.attrName = attrName.toLowerCase();
1540
+ @else @*/
1541
+ this.attrName = attrName;
1542
+ /*@end @*/
1543
+ this.attrValueExpr = predicate.attrValueExpr;
1544
+ this.quickAttr = true;
1545
+ }
1546
+ };
1547
+
1548
+ Step.prototype.show = function(indent) {
1549
+ indent = indent || '';
1550
+ var t = '';
1551
+ t += indent + 'step: ' + '\n';
1552
+ indent += ' ';
1553
+ if (this.axis) t += indent + 'axis: ' + this.axis + '\n';
1554
+ t += this.test.show(indent);
1555
+ if (this.predicates.length) {
1556
+ t += indent + 'predicates: ' + '\n';
1557
+ indent += ' ';
1558
+ for (var i = 0; i < this.predicates.length; i ++) {
1559
+ t += this.predicates[i].show(indent);
1560
+ }
1561
+ }
1562
+ return t;
1563
+ };
1564
+
1565
+
1566
+
1567
+ /**
1568
+ * NodeType
1569
+ */
1570
+ if (!window.NodeType && window.defaultConfig)
1571
+ window.NodeType = null;
1572
+
1573
+ NodeType = function(name, literal) {
1574
+ this.name = name;
1575
+ this.literal = literal;
1576
+
1577
+ switch (name) {
1578
+ case 'comment':
1579
+ this.type = 8;
1580
+ break;
1581
+ case 'text':
1582
+ this.type = 3;
1583
+ break;
1584
+ case 'processing-instruction':
1585
+ this.type = 7;
1586
+ break;
1587
+ case 'node':
1588
+ this.type = 0;
1589
+ break;
1590
+ }
1591
+ };
1592
+
1593
+ NodeType.types = {
1594
+ 'comment':1, 'text':1, 'processing-instruction':1, 'node':1
1595
+ };
1596
+
1597
+ NodeType.parse = function(lexer) {
1598
+ var type, literal, ch;
1599
+ type = lexer.next();
1600
+ lexer.next();
1601
+ if (lexer.empty()) {
1602
+ throw Error('bad nodetype');
1603
+ }
1604
+ ch = lexer.peek().charAt(0);
1605
+ if (ch == '"' || ch == "'") {
1606
+ literal = Literal.parse(lexer);
1607
+ }
1608
+ if (lexer.empty()) {
1609
+ throw Error('bad nodetype');
1610
+ }
1611
+ if (lexer.next() != ')') {
1612
+ lexer.back();
1613
+ throw Error('bad token ' + lexer.next());
1614
+ }
1615
+ return new NodeType(type, literal);
1616
+ };
1617
+
1618
+ NodeType.prototype = new BaseExpr();
1619
+
1620
+ NodeType.prototype.notOnlyElement = true;
1621
+
1622
+ NodeType.prototype.match = function(node) {
1623
+ return !this.type || this.type == node.nodeType;
1624
+ };
1625
+
1626
+ NodeType.prototype.show = function(indent) {
1627
+ indent = indent || '';
1628
+ var t = '';
1629
+ t += indent + 'nodetype: ' + this.type + '\n';
1630
+ if (this.literal) {
1631
+ indent += ' ';
1632
+ t += this.literal.show(indent);
1633
+ }
1634
+ return t;
1635
+ };
1636
+
1637
+
1638
+ /**
1639
+ * NodeType
1640
+ */
1641
+ if (!window.NameTest && window.defaultConfig)
1642
+ window.NameTest = null;
1643
+
1644
+ NameTest = function(name) {
1645
+ this.name = name.toLowerCase();
1646
+ };
1647
+
1648
+ NameTest.parse = function(lexer) {
1649
+ if (lexer.peek() != '*' && lexer.peek(1) == ':' && lexer.peek(2) == '*') {
1650
+ return new NameTest(lexer.next() + lexer.next() + lexer.next());
1651
+ }
1652
+ return new NameTest(lexer.next());
1653
+ };
1654
+
1655
+ NameTest.prototype = new BaseExpr();
1656
+
1657
+ NameTest.prototype.match = function(node) {
1658
+ var type = node.nodeType;
1659
+
1660
+ if (type == 1 || type == 2) {
1661
+ if (this.name == '*' || this.name == node.nodeName.toLowerCase()) {
1662
+ return true;
1663
+ }
1664
+ }
1665
+ return false;
1666
+ };
1667
+
1668
+ NameTest.prototype.show = function(indent) {
1669
+ indent = indent || '';
1670
+ var t = '';
1671
+ t += indent + 'nametest: ' + this.name + '\n';
1672
+ return t;
1673
+ };
1674
+
1675
+
1676
+ /**
1677
+ * class: VariableRefernce
1678
+ */
1679
+ if (!window.VariableReference && window.defaultConfig)
1680
+ window.VariableReference = null;
1681
+
1682
+ VariableReference = function(name) {
1683
+ this.name = name.substring(1);
1684
+ };
1685
+
1686
+
1687
+ VariableReference.parse = function(lexer) {
1688
+ var token = lexer.next();
1689
+ if (token.length < 2) {
1690
+ throw Error('unnamed variable reference');
1691
+ }
1692
+ return new VariableReference(token)
1693
+ };
1694
+
1695
+ VariableReference.prototype = new BaseExpr();
1696
+
1697
+ VariableReference.prototype.datatype = 'void';
1698
+
1699
+ VariableReference.prototype.show = function(indent) {
1700
+ indent = indent || '';
1701
+ var t = '';
1702
+ t += indent + 'variable: ' + this.name + '\n';
1703
+ return t;
1704
+ };
1705
+
1706
+
1707
+ /**
1708
+ * class: Literal
1709
+ */
1710
+ if (!window.Literal && window.defaultConfig)
1711
+ window.Literal = null;
1712
+
1713
+ Literal = function(text) {
1714
+ this.text = text.substring(1, text.length - 1);
1715
+ };
1716
+
1717
+ Literal.parse = function(lexer) {
1718
+ var token = lexer.next();
1719
+ if (token.length < 2) {
1720
+ throw Error('unclosed literal string');
1721
+ }
1722
+ return new Literal(token)
1723
+ };
1724
+
1725
+ Literal.prototype = new BaseExpr();
1726
+
1727
+ Literal.prototype.datatype = 'string';
1728
+
1729
+ Literal.prototype.evaluate = function(ctx) {
1730
+ return this.text;
1731
+ };
1732
+
1733
+ Literal.prototype.show = function(indent) {
1734
+ indent = indent || '';
1735
+ var t = '';
1736
+ t += indent + 'literal: ' + this.text + '\n';
1737
+ return t;
1738
+ };
1739
+
1740
+
1741
+ /**
1742
+ * class: Number
1743
+ */
1744
+ if (!window.Number && window.defaultConfig)
1745
+ window.Number = null;
1746
+
1747
+ Number = function(digit) {
1748
+ this.digit = +digit;
1749
+ };
1750
+
1751
+
1752
+ Number.parse = function(lexer) {
1753
+ return new Number(lexer.next());
1754
+ };
1755
+
1756
+ Number.prototype = new BaseExpr();
1757
+
1758
+ Number.prototype.datatype = 'number';
1759
+
1760
+ Number.prototype.evaluate = function(ctx) {
1761
+ return this.digit;
1762
+ };
1763
+
1764
+ Number.prototype.show = function(indent) {
1765
+ indent = indent || '';
1766
+ var t = '';
1767
+ t += indent + 'number: ' + this.digit + '\n';
1768
+ return t;
1769
+ };
1770
+
1771
+
1772
+ /**
1773
+ * class: FunctionCall
1774
+ */
1775
+ if (!window.FunctionCall && window.defaultConfig)
1776
+ window.FunctionCall = null;
1777
+
1778
+ FunctionCall = function(name) {
1779
+ var info = FunctionCall.funcs[name];
1780
+ if (!info)
1781
+ throw Error(name +' is not a function');
1782
+
1783
+ this.name = name;
1784
+ this.func = info[0];
1785
+ this.args = [];
1786
+
1787
+ this.datatype = info[1];
1788
+
1789
+ if (info[2]) {
1790
+ this.needContextPosition = true;
1791
+ }
1792
+
1793
+ this.needContextNodeInfo = info[3];
1794
+ this.needContextNode = this.needContextNodeInfo[0]
1795
+ };
1796
+
1797
+ FunctionCall.funcs = {
1798
+
1799
+ // Original Function
1800
+ 'context-node': [function() {
1801
+ if (arguments.length != 0) {
1802
+ throw Error('Function context-node expects ()');
1803
+ }
1804
+ var ns;
1805
+ ns = new NodeSet();
1806
+ ns.push(this.node);
1807
+ return ns;
1808
+ }, 'nodeset', false, [true]],
1809
+
1810
+ // Original Function
1811
+ 'root-node': [function() {
1812
+ if (arguments.length != 0) {
1813
+ throw Error('Function root-node expects ()');
1814
+ }
1815
+ var ns, ctxn;
1816
+ ns = new NodeSet();
1817
+ ctxn = this.node;
1818
+ if (ctxn.nodeType == 9)
1819
+ ns.push(ctxn);
1820
+ else
1821
+ ns.push(ctxn.ownerDocument);
1822
+ return ns;
1823
+ }, 'nodeset', false, []],
1824
+
1825
+ last: [function() {
1826
+ if (arguments.length != 0) {
1827
+ throw Error('Function last expects ()');
1828
+ }
1829
+ return this.last;
1830
+ }, 'number', true, []],
1831
+
1832
+ position: [function() {
1833
+ if (arguments.length != 0) {
1834
+ throw Error('Function position expects ()');
1835
+ }
1836
+ return this.position;
1837
+ }, 'number', true, []],
1838
+
1839
+ count: [function(ns) {
1840
+ if (arguments.length != 1 || !(ns = ns.evaluate(this)).isNodeSet) {
1841
+ throw Error('Function count expects (nodeset)');
1842
+ }
1843
+ return ns.length;
1844
+ }, 'number', false, []],
1845
+
1846
+ id: [function(s) {
1847
+ var ids, ns, i, id, elm, ctxn, doc;
1848
+ if (arguments.length != 1) {
1849
+ throw Error('Function id expects (object)');
1850
+ }
1851
+ ctxn = this.node;
1852
+ if (ctxn.nodeType == 9)
1853
+ doc = ctxn;
1854
+ else
1855
+ doc = ctxn.ownerDocument;
1856
+ /*@cc_on
1857
+ all = doc.all;
1858
+ @*/
1859
+ s = s.string(this);
1860
+ ids = s.split(/\s+/);
1861
+ ns = new NodeSet();
1862
+ for (i = 0, l = ids.length; i < l; i ++) {
1863
+ id = ids[i];
1864
+
1865
+ /*@cc_on @if (@_jscript)
1866
+ elm = all[id];
1867
+ if (elm) {
1868
+ if ((!elm.length || elm.nodeType) && id == elm.id) {
1869
+ ns.push(elm)
1870
+ }
1871
+ else if (elm.length) {
1872
+ var elms = elm;
1873
+ for (var j = 0, l0 = elms.length; j < l0; j ++) {
1874
+ var elem = elms[j];
1875
+ if (id == elem.id) {
1876
+ ns.push(elem);
1877
+ break;
1878
+ }
1879
+ }
1880
+ }
1881
+ }
1882
+ @else @*/
1883
+ elm = doc.getElementById(id);
1884
+ if (uai.opera && elm && elm.id != id) {
1885
+ var elms = doc.getElementsByName(id);
1886
+ for (var j = 0, l0 = elms.length; j < l0; j ++) {
1887
+ elm = elms[j];
1888
+ if (elm.id == id) {
1889
+ ns.push(elm);
1890
+ }
1891
+ }
1892
+ }
1893
+ else {
1894
+ if (elm) ns.push(elm)
1895
+ }
1896
+ /*@end @*/
1897
+
1898
+ }
1899
+ ns.isSorted = false;
1900
+ return ns;
1901
+ }, 'nodeset', false, []],
1902
+
1903
+ 'local-name': [function(ns) {
1904
+ var nd;
1905
+ switch (arguments.length) {
1906
+ case 0:
1907
+ nd = this.node;
1908
+ break;
1909
+ case 1:
1910
+ if ((ns = ns.evaluate(this)).isNodeSet) {
1911
+ nd = ns.first();
1912
+ break;
1913
+ }
1914
+ default:
1915
+ throw Error('Function local-name expects (nodeset?)');
1916
+ break;
1917
+ }
1918
+ return '' + nd.nodeName.toLowerCase();
1919
+ }, 'string', false, [true, false]],
1920
+
1921
+ name: [function(ns) {
1922
+ // not implemented
1923
+ return FunctionCall.funcs['local-name'][0].apply(this, arguments);
1924
+ }, 'string', false, [true, false]],
1925
+
1926
+ 'namespace-uri': [function(ns) {
1927
+ // not implemented
1928
+ return '';
1929
+ }, 'string', false, [true, false]],
1930
+
1931
+ string: [function(s) {
1932
+ switch (arguments.length) {
1933
+ case 0:
1934
+ s = NodeUtil.to('string', this.node);
1935
+ break;
1936
+ case 1:
1937
+ s = s.string(this);
1938
+ break;
1939
+ default:
1940
+ throw Error('Function string expects (object?)');
1941
+ break;
1942
+ }
1943
+ return s;
1944
+ }, 'string', false, [true, false]],
1945
+
1946
+ concat: [function(s1, s2) {
1947
+ if (arguments.length < 2) {
1948
+ throw Error('Function concat expects (string, string[, ...])');
1949
+ }
1950
+ for (var t = '', i = 0, l = arguments.length; i < l; i ++) {
1951
+ t += arguments[i].string(this);
1952
+ }
1953
+ return t;
1954
+ }, 'string', false, []],
1955
+
1956
+ 'starts-with': [function(s1, s2) {
1957
+ if (arguments.length != 2) {
1958
+ throw Error('Function starts-with expects (string, string)');
1959
+ }
1960
+ s1 = s1.string(this);
1961
+ s2 = s2.string(this);
1962
+ return s1.indexOf(s2) == 0;
1963
+ }, 'boolean', false, []],
1964
+
1965
+ contains: [function(s1, s2) {
1966
+ if (arguments.length != 2) {
1967
+ throw Error('Function contains expects (string, string)');
1968
+ }
1969
+ s1 = s1.string(this);
1970
+ s2 = s2.string(this);
1971
+ return s1.indexOf(s2) != -1;
1972
+ }, 'boolean', false, []],
1973
+
1974
+ substring: [function(s, n1, n2) {
1975
+ var a1, a2;
1976
+ s = s.string(this);
1977
+ n1 = n1.number(this);
1978
+ switch (arguments.length) {
1979
+ case 2:
1980
+ n2 = s.length - n1 + 1;
1981
+ break;
1982
+ case 3:
1983
+ n2 = n2.number(this);
1984
+ break;
1985
+ default:
1986
+ throw Error('Function substring expects (string, string)');
1987
+ break;
1988
+ }
1989
+ n1 = Math.round(n1);
1990
+ n2 = Math.round(n2);
1991
+ a1 = n1 - 1;
1992
+ a2 = n1 + n2 - 1;
1993
+ if (a2 == Infinity) {
1994
+ return s.substring(a1 < 0 ? 0 : a1);
1995
+ }
1996
+ else {
1997
+ return s.substring(a1 < 0 ? 0 : a1, a2)
1998
+ }
1999
+ }, 'string', false, []],
2000
+
2001
+ 'substring-before': [function(s1, s2) {
2002
+ var n;
2003
+ if (arguments.length != 2) {
2004
+ throw Error('Function substring-before expects (string, string)');
2005
+ }
2006
+ s1 = s1.string(this);
2007
+ s2 = s2.string(this);
2008
+ n = s1.indexOf(s2);
2009
+ if (n == -1) return '';
2010
+ return s1.substring(0, n);
2011
+ }, 'string', false, []],
2012
+
2013
+ 'substring-after': [function(s1, s2) {
2014
+ if (arguments.length != 2) {
2015
+ throw Error('Function substring-after expects (string, string)');
2016
+ }
2017
+ s1 = s1.string(this);
2018
+ s2 = s2.string(this);
2019
+ var n = s1.indexOf(s2);
2020
+ if (n == -1) return '';
2021
+ return s1.substring(n + s2.length);
2022
+ }, 'string', false, []],
2023
+
2024
+ 'string-length': [function(s) {
2025
+ switch (arguments.length) {
2026
+ case 0:
2027
+ s = NodeUtil.to('string', this.node);
2028
+ break;
2029
+ case 1:
2030
+ s = s.string(this);
2031
+ break;
2032
+ default:
2033
+ throw Error('Function string-length expects (string?)');
2034
+ break;
2035
+ }
2036
+ return s.length;
2037
+ }, 'number', false, [true, false]],
2038
+
2039
+ 'normalize-space': [function(s) {
2040
+ switch (arguments.length) {
2041
+ case 0:
2042
+ s = NodeUtil.to('string', this.node);
2043
+ break;
2044
+ case 1:
2045
+ s = s.string(this);
2046
+ break;
2047
+ default:
2048
+ throw Error('Function normalize-space expects (string?)');
2049
+ break;
2050
+ }
2051
+ return s.replace(/\s+/g, ' ').replace(/^ /, '').replace(/ $/, '');
2052
+ }, 'string', false, [true, false]],
2053
+
2054
+ translate: [function(s1, s2, s3) {
2055
+ if (arguments.length != 3) {
2056
+ throw Error('Function translate expects (string, string, string)');
2057
+ }
2058
+ s1 = s1.string(this);
2059
+ s2 = s2.string(this);
2060
+ s3 = s3.string(this);
2061
+
2062
+ var map = [];
2063
+ for (var i = 0, l = s2.length; i < l; i ++) {
2064
+ var ch = s2.charAt(i);
2065
+ if (!map[ch]) map[ch] = s3.charAt(i) || '';
2066
+ }
2067
+ for (var t = '', i = 0, l = s1.length; i < l; i ++) {
2068
+ var ch = s1.charAt(i);
2069
+ var replace = map[ch]
2070
+ t += (replace != undefined) ? replace : ch;
2071
+ }
2072
+ return t;
2073
+ }, 'string', false, []],
2074
+
2075
+ 'boolean': [function(b) {
2076
+ if (arguments.length != 1) {
2077
+ throw Error('Function boolean expects (object)');
2078
+ }
2079
+ return b.bool(this)
2080
+ }, 'boolean', false, []],
2081
+
2082
+ not: [function(b) {
2083
+ if (arguments.length != 1) {
2084
+ throw Error('Function not expects (object)');
2085
+ }
2086
+ return !b.bool(this)
2087
+ }, 'boolean', false, []],
2088
+
2089
+ 'true': [function() {
2090
+ if (arguments.length != 0) {
2091
+ throw Error('Function true expects ()');
2092
+ }
2093
+ return true;
2094
+ }, 'boolean', false, []],
2095
+
2096
+ 'false': [function() {
2097
+ if (arguments.length != 0) {
2098
+ throw Error('Function false expects ()');
2099
+ }
2100
+ return false;
2101
+ }, 'boolean', false, []],
2102
+
2103
+ lang: [function(s) {
2104
+ // not implemented
2105
+ return false;
2106
+ }, 'boolean', false, []],
2107
+
2108
+ number: [function(n) {
2109
+ switch (arguments.length) {
2110
+ case 0:
2111
+ n = NodeUtil.to('number', this.node);
2112
+ break;
2113
+ case 1:
2114
+ n = n.number(this);
2115
+ break;
2116
+ default:
2117
+ throw Error('Function number expects (object?)');
2118
+ break;
2119
+ }
2120
+ return n;
2121
+ }, 'number', false, [true, false]],
2122
+
2123
+ sum: [function(ns) {
2124
+ var nodes, n, i, l;
2125
+ if (arguments.length != 1 || !(ns = ns.evaluate(this)).isNodeSet) {
2126
+ throw Error('Function sum expects (nodeset)');
2127
+ }
2128
+ nodes = ns.list();
2129
+ n = 0;
2130
+ for (i = 0, l = nodes.length; i < l; i ++) {
2131
+ n += NodeUtil.to('number', nodes[i]);
2132
+ }
2133
+ return n;
2134
+ }, 'number', false, []],
2135
+
2136
+ floor: [function(n) {
2137
+ if (arguments.length != 1) {
2138
+ throw Error('Function floor expects (number)');
2139
+ }
2140
+ n = n.number(this);
2141
+ return Math.floor(n);
2142
+ }, 'number', false, []],
2143
+
2144
+ ceiling: [function(n) {
2145
+ if (arguments.length != 1) {
2146
+ throw Error('Function ceiling expects (number)');
2147
+ }
2148
+ n = n.number(this);
2149
+ return Math.ceil(n);
2150
+ }, 'number', false, []],
2151
+
2152
+ round: [function(n) {
2153
+ if (arguments.length != 1) {
2154
+ throw Error('Function round expects (number)');
2155
+ }
2156
+ n = n.number(this);
2157
+ return Math.round(n);
2158
+ }, 'number', false, []]
2159
+ };
2160
+
2161
+ FunctionCall.parse = function(lexer) {
2162
+ var expr, func = new FunctionCall(lexer.next());
2163
+ lexer.next();
2164
+ while (lexer.peek() != ')') {
2165
+ if (lexer.empty()) {
2166
+ throw Error('missing function argument list');
2167
+ }
2168
+ expr = BinaryExpr.parse(lexer);
2169
+ func.arg(expr);
2170
+ if (lexer.peek() != ',') break;
2171
+ lexer.next();
2172
+ }
2173
+ if (lexer.empty()) {
2174
+ throw Error('unclosed function argument list');
2175
+ }
2176
+ if (lexer.next() != ')') {
2177
+ lexer.back();
2178
+ throw Error('bad token: ' + lexer.next());
2179
+ }
2180
+ return func
2181
+ };
2182
+
2183
+ FunctionCall.prototype = new BaseExpr();
2184
+
2185
+ FunctionCall.prototype.evaluate = function (ctx) {
2186
+ return this.func.apply(ctx, this.args);
2187
+ };
2188
+
2189
+ FunctionCall.prototype.arg = function(arg) {
2190
+ this.args.push(arg);
2191
+
2192
+ if (arg.needContextPosition) {
2193
+ this.needContextPosition = true;
2194
+ }
2195
+
2196
+ var args = this.args;
2197
+ if (arg.needContextNode) {
2198
+ args.needContexNode = true;
2199
+ }
2200
+ this.needContextNode = args.needContextNode ||
2201
+ this.needContextNodeInfo[args.length];
2202
+ };
2203
+
2204
+ FunctionCall.prototype.show = function(indent) {
2205
+ indent = indent || '';
2206
+ var t = '';
2207
+ t += indent + 'function: ' + this.name + '\n';
2208
+ indent += ' ';
2209
+
2210
+ if (this.args.length) {
2211
+ t += indent + 'arguments: ' + '\n';
2212
+ indent += ' ';
2213
+ for (var i = 0; i < this.args.length; i ++) {
2214
+ t += this.args[i].show(indent);
2215
+ }
2216
+ }
2217
+
2218
+ return t;
2219
+ };
2220
+
2221
+
2222
+ /*@cc_on @if (@_jscript)
2223
+ var NodeWrapper = function(node, sourceIndex, subIndex, attributeName) {
2224
+ this.node = node;
2225
+ this.nodeType = node.nodeType;
2226
+ this.sourceIndex = sourceIndex;
2227
+ this.subIndex = subIndex;
2228
+ this.attributeName = attributeName || '';
2229
+ this.order = String.fromCharCode(sourceIndex) + String.fromCharCode(subIndex) + attributeName;
2230
+ };
2231
+
2232
+ NodeWrapper.prototype.toString = function() {
2233
+ return this.order;
2234
+ };
2235
+ @else @*/
2236
+ var NodeID = {
2237
+ uuid: 1,
2238
+ get: function(node) {
2239
+ return node.__jsxpath_id__ || (node.__jsxpath_id__ = this.uuid++);
2240
+ }
2241
+ };
2242
+ /*@end @*/
2243
+
2244
+ if (!window.NodeSet && window.defaultConfig)
2245
+ window.NodeSet = null;
2246
+
2247
+ NodeSet = function() {
2248
+ this.length = 0;
2249
+ this.nodes = [];
2250
+ this.seen = {};
2251
+ this.idIndexMap = null;
2252
+ this.reserveDels = [];
2253
+ };
2254
+
2255
+ NodeSet.prototype.isNodeSet = true;
2256
+ NodeSet.prototype.isSorted = true;
2257
+
2258
+ /*@_cc_on
2259
+ NodeSet.prototype.shortcut = true;
2260
+ @*/
2261
+
2262
+ NodeSet.prototype.merge = function(nodeset) {
2263
+ this.isSorted = false;
2264
+ if (nodeset.only) {
2265
+ return this.push(nodeset.only);
2266
+ }
2267
+
2268
+ if (this.only){
2269
+ var only = this.only;
2270
+ delete this.only;
2271
+ this.push(only);
2272
+ this.length --;
2273
+ }
2274
+
2275
+ var nodes = nodeset.nodes;
2276
+ for (var i = 0, l = nodes.length; i < l; i ++) {
2277
+ this._add(nodes[i]);
2278
+ }
2279
+ };
2280
+
2281
+ NodeSet.prototype.sort = function() {
2282
+ if (this.only) return;
2283
+ if (this.sortOff) return;
2284
+
2285
+ if (!this.isSorted) {
2286
+ this.isSorted = true;
2287
+ this.idIndexMap = null;
2288
+
2289
+ /*@cc_on
2290
+ if (this.shortcut) {
2291
+ this.nodes.sort();
2292
+ }
2293
+ else {
2294
+ this.nodes.sort(function(a, b) {
2295
+ var result;
2296
+ result = a.sourceIndex - b.sourceIndex;
2297
+ if (result == 0)
2298
+ return a.subIndex - a.subIndex;
2299
+ else
2300
+ return result;
2301
+ });
2302
+ }
2303
+ return;
2304
+ @*/
2305
+ var nodes = this.nodes;
2306
+ nodes.sort(function(a, b) {
2307
+ if (a == b) return 0;
2308
+
2309
+ if (a.compareDocumentPosition) {
2310
+ var result = a.compareDocumentPosition(b);
2311
+ if (result & 2) return 1;
2312
+ if (result & 4) return -1;
2313
+ return 0;
2314
+ }
2315
+ else {
2316
+ var node1 = a, node2 = b, ancestor1 = a, ancestor2 = b, deep1 = 0, deep2 = 0;
2317
+
2318
+ while(ancestor1 = ancestor1.parentNode) deep1 ++;
2319
+ while(ancestor2 = ancestor2.parentNode) deep2 ++;
2320
+
2321
+ // same deep
2322
+ if (deep1 > deep2) {
2323
+ while (deep1-- != deep2) node1 = node1.parentNode;
2324
+ if (node1 == node2) return 1;
2325
+ }
2326
+ else if (deep2 > deep1) {
2327
+ while (deep2-- != deep1) node2 = node2.parentNode;
2328
+ if (node1 == node2) return -1;
2329
+ }
2330
+
2331
+ while ((ancestor1 = node1.parentNode) != (ancestor2 = node2.parentNode)) {
2332
+ node1 = ancestor1;
2333
+ node2 = ancestor2;
2334
+ }
2335
+
2336
+ // node1 is node2's sibling
2337
+ while (node1 = node1.nextSibling) if (node1 == node2) return -1;
2338
+
2339
+ return 1;
2340
+ }
2341
+ });
2342
+ }
2343
+ };
2344
+
2345
+
2346
+ /*@cc_on @if (@_jscript)
2347
+ NodeSet.prototype.sourceOffset = 1;
2348
+ NodeSet.prototype.subOffset = 2;
2349
+ NodeSet.prototype.createWrapper = function(node) {
2350
+ var parent, child, attributes, attributesLength, sourceIndex, subIndex, attributeName;
2351
+
2352
+ sourceIndex = node.sourceIndex;
2353
+
2354
+ if (typeof sourceIndex != 'number') {
2355
+ type = node.nodeType;
2356
+ switch (type) {
2357
+ case 2:
2358
+ parent = node.parentNode;
2359
+ sourceIndex = node.parentSourceIndex;
2360
+ subIndex = -1;
2361
+ attributeName = node.nodeName;
2362
+ break;
2363
+ case 9:
2364
+ subIndex = -2;
2365
+ sourceIndex = -1;
2366
+ break;
2367
+ default:
2368
+ child = node;
2369
+ subIndex = 0;
2370
+ do {
2371
+ subIndex ++;
2372
+ sourceIndex = child.sourceIndex;
2373
+ if (sourceIndex) {
2374
+ parent = child;
2375
+ child = child.lastChild;
2376
+ if (!child) {
2377
+ child = parent;
2378
+ break;
2379
+ }
2380
+ subIndex ++;
2381
+ }
2382
+ } while (child = child.previousSibling);
2383
+ if (!sourceIndex) {
2384
+ sourceIndex = node.parentNode.sourceIndex;
2385
+ }
2386
+ break;
2387
+ }
2388
+ }
2389
+ else {
2390
+ subIndex = -2;
2391
+ }
2392
+
2393
+ sourceIndex += this.sourceOffset;
2394
+ subIndex += this.subOffset;
2395
+
2396
+ return new NodeWrapper(node, sourceIndex, subIndex, attributeName);
2397
+ };
2398
+
2399
+ NodeSet.prototype.reserveDelBySourceIndexAndSubIndex = function(sourceIndex, subIndex, offset, reverse) {
2400
+ var map = this.createIdIndexMap();
2401
+ var index;
2402
+ if ((map = map[sourceIndex]) && (index = map[subIndex])) {
2403
+ if (reverse && (this.length - offset - 1) > index || !reverse && offset < index) {
2404
+ var obj = {
2405
+ value: index,
2406
+ order: String.fromCharCode(index),
2407
+ toString: function() { return this.order },
2408
+ valueOf: function() { return this.value }
2409
+ };
2410
+ this.reserveDels.push(obj);
2411
+ }
2412
+ }
2413
+ };
2414
+ @else @*/
2415
+ NodeSet.prototype.reserveDelByNodeID = function(id, offset, reverse) {
2416
+ var map = this.createIdIndexMap();
2417
+ var index;
2418
+ if (index = map[id]) {
2419
+ if (reverse && (this.length - offset - 1) > index || !reverse && offset < index) {
2420
+ var obj = {
2421
+ value: index,
2422
+ order: String.fromCharCode(index),
2423
+ toString: function() { return this.order },
2424
+ valueOf: function() { return this.value }
2425
+ };
2426
+ this.reserveDels.push(obj);
2427
+ }
2428
+ }
2429
+ };
2430
+ /*@end @*/
2431
+
2432
+ NodeSet.prototype.reserveDelByNode = function(node, offset, reverse) {
2433
+ /*@cc_on @if (@_jscript)
2434
+ node = this.createWrapper(node);
2435
+ this.reserveDelBySourceIndexAndSubIndex(node.sourceIndex, node.subIndex, offset, reverse);
2436
+ @else @*/
2437
+ this.reserveDelByNodeID(NodeID.get(node), offset, reverse);
2438
+ /*@end @*/
2439
+ };
2440
+
2441
+ NodeSet.prototype.doDel = function() {
2442
+ if (!this.reserveDels.length) return;
2443
+
2444
+ if (this.length < 0x10000) {
2445
+ var dels = this.reserveDels.sort(function(a, b) { return b - a });
2446
+ }
2447
+ else {
2448
+ var dels = this.reserveDels.sort(function(a, b) { return b - a });
2449
+ }
2450
+ for (var i = 0, l = dels.length; i < l; i ++) {
2451
+ this.del(dels[i]);
2452
+ }
2453
+ this.reserveDels = [];
2454
+ this.idIndexMap = null;
2455
+ };
2456
+
2457
+ NodeSet.prototype.createIdIndexMap = function() {
2458
+ if (this.idIndexMap) {
2459
+ return this.idIndexMap;
2460
+ }
2461
+ else {
2462
+ var map = this.idIndexMap = {};
2463
+ var nodes = this.nodes;
2464
+ for (var i = 0, l = nodes.length; i < l; i ++) {
2465
+ var node = nodes[i];
2466
+ /*@cc_on @if (@_jscript)
2467
+ var sourceIndex = node.sourceIndex;
2468
+ var subIndex = node.subIndex;
2469
+ if (!map[sourceIndex]) map[sourceIndex] = {};
2470
+ map[sourceIndex][subIndex] = i;
2471
+ @else @*/
2472
+ var id = NodeID.get(node);
2473
+ map[id] = i;
2474
+ /*@end @*/
2475
+ }
2476
+ return map;
2477
+ }
2478
+ };
2479
+
2480
+ NodeSet.prototype.del = function(index) {
2481
+ this.length --;
2482
+ if (this.only) {
2483
+ delete this.only;
2484
+ }
2485
+ else {
2486
+ var node = this.nodes.splice(index, 1)[0];
2487
+
2488
+ if (this._first == node) {
2489
+ delete this._first;
2490
+ delete this._firstSourceIndex;
2491
+ delete this._firstSubIndex;
2492
+ }
2493
+
2494
+ /*@cc_on @if (@_jscript)
2495
+ delete this.seen[node.sourceIndex][node.subIndex];
2496
+ @else @*/
2497
+ delete this.seen[NodeID.get(node)];
2498
+ /*@end @*/
2499
+ }
2500
+ };
2501
+
2502
+
2503
+ NodeSet.prototype.delDescendant = function(elm, offset) {
2504
+ if (this.only) return;
2505
+ var nodeType = elm.nodeType;
2506
+ if (nodeType != 1 && nodeType != 9) return;
2507
+ if (uai.applewebkit2) return;
2508
+
2509
+ // element || document
2510
+ if (!elm.contains) {
2511
+ if (nodeType == 1) {
2512
+ var _elm = elm;
2513
+ elm = {
2514
+ contains: function(node) {
2515
+ return node.compareDocumentPosition(_elm) & 8;
2516
+ }
2517
+ };
2518
+ }
2519
+ else {
2520
+ // document
2521
+ elm = {
2522
+ contains: function() {
2523
+ return true;
2524
+ }
2525
+ };
2526
+ }
2527
+ }
2528
+
2529
+ var nodes = this.nodes;
2530
+ for (var i = offset + 1; i < nodes.length; i ++) {
2531
+
2532
+ /*@cc_on @if (@_jscript)
2533
+ if (nodes[i].node.nodeType == 1 && elm.contains(nodes[i].node)) {
2534
+ @else @*/
2535
+ if (elm.contains(nodes[i])) {
2536
+ /*@end @*/
2537
+ this.del(i);
2538
+ i --;
2539
+ }
2540
+ }
2541
+ };
2542
+
2543
+ NodeSet.prototype._add = function(node, reverse) {
2544
+
2545
+ /*@cc_on @if (@_jscript)
2546
+
2547
+ var first, firstSourceIndex, firstSubIndex, sourceIndex, subIndex, attributeName;
2548
+
2549
+ sourceIndex = node.sourceIndex;
2550
+ subIndex = node.subIndex;
2551
+ attributeName = node.attributeName;
2552
+ seen = this.seen;
2553
+
2554
+ seen = seen[sourceIndex] || (seen[sourceIndex] = {});
2555
+
2556
+ if (node.nodeType == 2) {
2557
+ seen = seen[subIndex] || (seen[subIndex] = {});
2558
+ if (seen[attributeName]) {
2559
+ return true;
2560
+ }
2561
+ seen[attributeName] = true;
2562
+ }
2563
+ else {
2564
+ if (seen[subIndex]) {
2565
+ return true;
2566
+ }
2567
+ seen[subIndex] = true;
2568
+ }
2569
+
2570
+ if (sourceIndex >= 0x10000 || subIndex >= 0x10000) {
2571
+ this.shortcut = false;
2572
+ }
2573
+
2574
+ // if this._first is undefined and this.nodes is not empty
2575
+ // then first node shortcut is disabled.
2576
+ if (this._first || this.nodes.length == 0) {
2577
+ first = this._first;
2578
+ firstSourceIndex = this._firstSourceIndex;
2579
+ firstSubIndex = this._firstSubIndex;
2580
+ if (!first || firstSourceIndex > sourceIndex || (firstSourceIndex == sourceIndex && firstSubIndex > subIndex)) {
2581
+ this._first = node;
2582
+ this._firstSourceIndex = sourceIndex;
2583
+ this._firstSubIndex = subIndex
2584
+ }
2585
+ }
2586
+
2587
+ @else @*/
2588
+
2589
+ var seen = this.seen;
2590
+ var id = NodeID.get(node);
2591
+ if (seen[id]) return true;
2592
+ seen[id] = true;
2593
+
2594
+ /*@end @*/
2595
+
2596
+ this.length++;
2597
+ if (reverse)
2598
+ this.nodes.unshift(node);
2599
+ else
2600
+ this.nodes.push(node);
2601
+ };
2602
+
2603
+
2604
+ NodeSet.prototype.unshift = function(node) {
2605
+ if (!this.length) {
2606
+ this.length ++;
2607
+ this.only = node;
2608
+ return
2609
+ }
2610
+ if (this.only){
2611
+ var only = this.only;
2612
+ delete this.only;
2613
+ this.unshift(only);
2614
+ this.length --;
2615
+ }
2616
+ /*@cc_on
2617
+ node = this.createWrapper(node);
2618
+ @*/
2619
+ return this._add(node, true);
2620
+ };
2621
+
2622
+
2623
+ NodeSet.prototype.push = function(node) {
2624
+ if (!this.length) {
2625
+ this.length ++;
2626
+ this.only = node;
2627
+ return;
2628
+ }
2629
+ if (this.only) {
2630
+ var only = this.only;
2631
+ delete this.only;
2632
+ this.push(only);
2633
+ this.length --;
2634
+ }
2635
+ /*@cc_on
2636
+ node = this.createWrapper(node);
2637
+ @*/
2638
+ return this._add(node);
2639
+ };
2640
+
2641
+ NodeSet.prototype.first = function() {
2642
+ if (this.only) return this.only;
2643
+ /*@cc_on
2644
+ if (this._first) return this._first.node;
2645
+ if (this.nodes.length > 1) this.sort();
2646
+ var node = this.nodes[0];
2647
+ return node ? node.node : undefined;
2648
+ @*/
2649
+ if (this.nodes.length > 1) this.sort();
2650
+ return this.nodes[0];
2651
+ };
2652
+
2653
+ NodeSet.prototype.list = function() {
2654
+ if (this.only) return [this.only];
2655
+ this.sort();
2656
+ /*@cc_on
2657
+ var i, l, nodes, results;
2658
+ nodes = this.nodes;
2659
+ results = [];
2660
+ for (i = 0, l = nodes.length; i < l; i ++) {
2661
+ results.push(nodes[i].node);
2662
+ }
2663
+ return results;
2664
+ @*/
2665
+ return this.nodes;
2666
+ };
2667
+
2668
+ NodeSet.prototype.string = function() {
2669
+ var node = this.only || this.first();
2670
+ return node ? NodeUtil.to('string', node) : '';
2671
+ };
2672
+
2673
+ NodeSet.prototype.bool = function() {
2674
+ return !! (this.length || this.only);
2675
+ };
2676
+
2677
+ NodeSet.prototype.number = function() {
2678
+ return + this.string();
2679
+ };
2680
+
2681
+ NodeSet.prototype.iterator = function(reverse) {
2682
+ this.sort();
2683
+ var nodeset = this;
2684
+
2685
+ if (!reverse) {
2686
+ var count = 0;
2687
+ return function() {
2688
+ if (nodeset.only && count++ == 0) return nodeset.only;
2689
+ /*@cc_on @if(@_jscript)
2690
+ var wrapper = nodeset.nodes[count++];
2691
+ if (wrapper) return wrapper.node;
2692
+ return undefined;
2693
+ @else @*/
2694
+ return nodeset.nodes[count++];
2695
+ /*@end @*/
2696
+ };
2697
+ }
2698
+ else {
2699
+ var count = 0;
2700
+ return function() {
2701
+ var index = nodeset.length - (count++) - 1;
2702
+ if (nodeset.only && index == 0) return nodeset.only;
2703
+ /*@cc_on @if(@_jscript)
2704
+ var wrapper = nodeset.nodes[index];
2705
+ if (wrapper) return wrapper.node;
2706
+ return undefined;
2707
+ @else @*/
2708
+ return nodeset.nodes[index];
2709
+ /*@end @*/
2710
+ };
2711
+ }
2712
+ };
2713
+
2714
+
2715
+ var install = function(win) {
2716
+
2717
+ win = win || this;
2718
+ var doc = win.document;
2719
+ var undefined = win.undefined;
2720
+
2721
+ win.XPathExpression = function(expr) {
2722
+ if (!expr.length) {
2723
+ throw win.Error('no expression');
2724
+ }
2725
+ var lexer = this.lexer = Lexer(expr);
2726
+ if (lexer.empty()) {
2727
+ throw win.Error('no expression');
2728
+ }
2729
+ this.expr = BinaryExpr.parse(lexer);
2730
+ if (!lexer.empty()) {
2731
+ throw win.Error('bad token: ' + lexer.next());
2732
+ }
2733
+ };
2734
+
2735
+ win.XPathExpression.prototype.evaluate = function(node, type) {
2736
+ return new win.XPathResult(this.expr.evaluate(new Ctx(node)), type);
2737
+ };
2738
+
2739
+ win.XPathResult = function (value, type) {
2740
+ if (type == 0) {
2741
+ switch (typeof value) {
2742
+ case 'object': type ++; // 4
2743
+ case 'boolean': type ++; // 3
2744
+ case 'string': type ++; // 2
2745
+ case 'number': type ++; // 1
2746
+ }
2747
+ }
2748
+
2749
+ this.resultType = type;
2750
+
2751
+ switch (type) {
2752
+ case 1:
2753
+ this.numberValue = value.isNodeSet ? value.number() : +value;
2754
+ return;
2755
+ case 2:
2756
+ this.stringValue = value.isNodeSet ? value.string() : '' + value;
2757
+ return;
2758
+ case 3:
2759
+ this.booleanValue = value.isNodeSet ? value.bool() : !! value;
2760
+ return;
2761
+ case 4: case 5: case 6: case 7:
2762
+ this.nodes = value.list();
2763
+ this.snapshotLength = value.length;
2764
+ this.index = 0;
2765
+ this.invalidIteratorState = false;
2766
+ break;
2767
+ case 8: case 9:
2768
+ this.singleNodeValue = value.first();
2769
+ return;
2770
+ }
2771
+ };
2772
+
2773
+ win.XPathResult.prototype.iterateNext = function() { return this.nodes[this.index++] };
2774
+ win.XPathResult.prototype.snapshotItem = function(i) { return this.nodes[i] };
2775
+
2776
+ win.XPathResult.ANY_TYPE = 0;
2777
+ win.XPathResult.NUMBER_TYPE = 1;
2778
+ win.XPathResult.STRING_TYPE = 2;
2779
+ win.XPathResult.BOOLEAN_TYPE = 3;
2780
+ win.XPathResult.UNORDERED_NODE_ITERATOR_TYPE = 4;
2781
+ win.XPathResult.ORDERED_NODE_ITERATOR_TYPE = 5;
2782
+ win.XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE = 6;
2783
+ win.XPathResult.ORDERED_NODE_SNAPSHOT_TYPE = 7;
2784
+ win.XPathResult.ANY_UNORDERED_NODE_TYPE = 8;
2785
+ win.XPathResult.FIRST_ORDERED_NODE_TYPE = 9;
2786
+
2787
+
2788
+ doc.createExpression = function(expr) {
2789
+ return new win.XPathExpression(expr, null);
2790
+ };
2791
+
2792
+ doc.evaluate = function(expr, context, _, type) {
2793
+ return doc.createExpression(expr, null).evaluate(context, type);
2794
+ };
2795
+ };
2796
+
2797
+ var win;
2798
+
2799
+ if (config.targetFrame) {
2800
+ var frame = document.getElementById(config.targetFrame);
2801
+ if (frame) win = frame.contentWindow;
2802
+ }
2803
+
2804
+ if (config.exportInstaller) {
2805
+ window.install = install;
2806
+ }
2807
+
2808
+ if (!config.hasNative || !config.useNative) {
2809
+ install(win || window);
2810
+ }
2811
+
2812
+
2813
+ })();
2814
+
2815
+ // Thanks for reading this source code. We love JavaScript.
2816
+