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,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
+