From 3c08118ca6c13d8e14745faaee1e9042b3b4d06c Mon Sep 17 00:00:00 2001
From: Slawomir Jaranowski
Date: Sat, 5 Sep 2020 13:15:58 +0200
Subject: [PATCH] update dependency after merge from master
---
node_modules/@actions/core/LICENSE.md | 9 +
node_modules/@actions/core/README.md | 3 +-
node_modules/@actions/core/lib/command.d.ts | 9 +-
node_modules/@actions/core/lib/command.js | 18 +-
node_modules/@actions/core/lib/command.js.map | 2 +-
node_modules/@actions/core/lib/core.d.ts | 28 +-
node_modules/@actions/core/lib/core.js | 31 +-
node_modules/@actions/core/lib/core.js.map | 2 +-
node_modules/@actions/core/package.json | 74 +-
node_modules/xpath/.npmignore | 1 -
node_modules/xpath/LICENSE | 22 +
node_modules/xpath/docs/XPathEvaluator.md | 12 +-
node_modules/xpath/docs/function resolvers.md | 30 +-
node_modules/xpath/package.json | 67 +-
node_modules/xpath/test.js | 2024 ++--
node_modules/xpath/xpath.d.ts | 8 +-
node_modules/xpath/xpath.js | 9197 +++++++++--------
17 files changed, 5814 insertions(+), 5723 deletions(-)
create mode 100644 node_modules/@actions/core/LICENSE.md
delete mode 100644 node_modules/xpath/.npmignore
create mode 100644 node_modules/xpath/LICENSE
diff --git a/node_modules/@actions/core/LICENSE.md b/node_modules/@actions/core/LICENSE.md
new file mode 100644
index 00000000..dbae2edb
--- /dev/null
+++ b/node_modules/@actions/core/LICENSE.md
@@ -0,0 +1,9 @@
+The MIT License (MIT)
+
+Copyright 2019 GitHub
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
diff --git a/node_modules/@actions/core/README.md b/node_modules/@actions/core/README.md
index 5ad27eed..95428cf3 100644
--- a/node_modules/@actions/core/README.md
+++ b/node_modules/@actions/core/README.md
@@ -89,6 +89,7 @@ try {
}
// Do stuff
+ core.info('Output to the actions build log')
}
catch (err) {
core.error(`Error ${err}, action may still succeed though`);
@@ -143,4 +144,4 @@ const core = require('@actions/core');
var pid = core.getState("pidToKill");
process.kill(pid);
-```
\ No newline at end of file
+```
diff --git a/node_modules/@actions/core/lib/command.d.ts b/node_modules/@actions/core/lib/command.d.ts
index 51b8f116..94d5e449 100644
--- a/node_modules/@actions/core/lib/command.d.ts
+++ b/node_modules/@actions/core/lib/command.d.ts
@@ -1,5 +1,5 @@
interface CommandProperties {
- [key: string]: string;
+ [key: string]: any;
}
/**
* Commands
@@ -11,6 +11,11 @@ interface CommandProperties {
* ::warning::This is the message
* ::set-env name=MY_VAR::some value
*/
-export declare function issueCommand(command: string, properties: CommandProperties, message: string): void;
+export declare function issueCommand(command: string, properties: CommandProperties, message: any): void;
export declare function issue(name: string, message?: string): void;
+/**
+ * Sanitizes an input into a string so it can be passed into issueCommand safely
+ * @param input input to sanitize into a string
+ */
+export declare function toCommandValue(input: any): string;
export {};
diff --git a/node_modules/@actions/core/lib/command.js b/node_modules/@actions/core/lib/command.js
index eeef233e..af28d2b1 100644
--- a/node_modules/@actions/core/lib/command.js
+++ b/node_modules/@actions/core/lib/command.js
@@ -61,14 +61,28 @@ class Command {
return cmdStr;
}
}
+/**
+ * Sanitizes an input into a string so it can be passed into issueCommand safely
+ * @param input input to sanitize into a string
+ */
+function toCommandValue(input) {
+ if (input === null || input === undefined) {
+ return '';
+ }
+ else if (typeof input === 'string' || input instanceof String) {
+ return input;
+ }
+ return JSON.stringify(input);
+}
+exports.toCommandValue = toCommandValue;
function escapeData(s) {
- return (s || '')
+ return toCommandValue(s)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A');
}
function escapeProperty(s) {
- return (s || '')
+ return toCommandValue(s)
.replace(/%/g, '%25')
.replace(/\r/g, '%0D')
.replace(/\n/g, '%0A')
diff --git a/node_modules/@actions/core/lib/command.js.map b/node_modules/@actions/core/lib/command.js.map
index 00a9861e..ae755652 100644
--- a/node_modules/@actions/core/lib/command.js.map
+++ b/node_modules/@actions/core/lib/command.js.map
@@ -1 +1 @@
-{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAwB;AAQxB;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAC1B,OAAe,EACf,UAA6B,EAC7B,OAAe;IAEf,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAC/C,CAAC;AAPD,oCAOC;AAED,SAAgB,KAAK,CAAC,IAAY,EAAE,UAAkB,EAAE;IACtD,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACjC,CAAC;AAFD,sBAEC;AAED,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,OAAO;IAKX,YAAY,OAAe,EAAE,UAA6B,EAAE,OAAe;QACzE,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,GAAG,iBAAiB,CAAA;SAC5B;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,QAAQ;QACN,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC9D,MAAM,IAAI,GAAG,CAAA;YACb,IAAI,KAAK,GAAG,IAAI,CAAA;YAChB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE;gBACjC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;oBACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,GAAG,EAAE;wBACP,IAAI,KAAK,EAAE;4BACT,KAAK,GAAG,KAAK,CAAA;yBACd;6BAAM;4BACL,MAAM,IAAI,GAAG,CAAA;yBACd;wBAED,MAAM,IAAI,GAAG,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAA;qBAC1C;iBACF;aACF;SACF;QAED,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;QACpD,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED,SAAS,UAAU,CAAC,CAAS;IAC3B,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SACb,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,CAAS;IAC/B,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;SACb,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzB,CAAC"}
\ No newline at end of file
+{"version":3,"file":"command.js","sourceRoot":"","sources":["../src/command.ts"],"names":[],"mappings":";;;;;;;;;AAAA,uCAAwB;AAWxB;;;;;;;;;GASG;AACH,SAAgB,YAAY,CAC1B,OAAe,EACf,UAA6B,EAC7B,OAAY;IAEZ,MAAM,GAAG,GAAG,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,OAAO,CAAC,CAAA;IACrD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AAC/C,CAAC;AAPD,oCAOC;AAED,SAAgB,KAAK,CAAC,IAAY,EAAE,UAAkB,EAAE;IACtD,YAAY,CAAC,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACjC,CAAC;AAFD,sBAEC;AAED,MAAM,UAAU,GAAG,IAAI,CAAA;AAEvB,MAAM,OAAO;IAKX,YAAY,OAAe,EAAE,UAA6B,EAAE,OAAe;QACzE,IAAI,CAAC,OAAO,EAAE;YACZ,OAAO,GAAG,iBAAiB,CAAA;SAC5B;QAED,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;QACtB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAA;QAC5B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;IAED,QAAQ;QACN,IAAI,MAAM,GAAG,UAAU,GAAG,IAAI,CAAC,OAAO,CAAA;QAEtC,IAAI,IAAI,CAAC,UAAU,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE;YAC9D,MAAM,IAAI,GAAG,CAAA;YACb,IAAI,KAAK,GAAG,IAAI,CAAA;YAChB,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,UAAU,EAAE;gBACjC,IAAI,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE;oBACvC,MAAM,GAAG,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;oBAChC,IAAI,GAAG,EAAE;wBACP,IAAI,KAAK,EAAE;4BACT,KAAK,GAAG,KAAK,CAAA;yBACd;6BAAM;4BACL,MAAM,IAAI,GAAG,CAAA;yBACd;wBAED,MAAM,IAAI,GAAG,GAAG,IAAI,cAAc,CAAC,GAAG,CAAC,EAAE,CAAA;qBAC1C;iBACF;aACF;SACF;QAED,MAAM,IAAI,GAAG,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAA;QACpD,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAED;;;GAGG;AACH,SAAgB,cAAc,CAAC,KAAU;IACvC,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS,EAAE;QACzC,OAAO,EAAE,CAAA;KACV;SAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,YAAY,MAAM,EAAE;QAC/D,OAAO,KAAe,CAAA;KACvB;IACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAA;AAC9B,CAAC;AAPD,wCAOC;AAED,SAAS,UAAU,CAAC,CAAM;IACxB,OAAO,cAAc,CAAC,CAAC,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;AAC1B,CAAC;AAED,SAAS,cAAc,CAAC,CAAM;IAC5B,OAAO,cAAc,CAAC,CAAC,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;SACrB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC;SACpB,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,CAAA;AACzB,CAAC"}
\ No newline at end of file
diff --git a/node_modules/@actions/core/lib/core.d.ts b/node_modules/@actions/core/lib/core.d.ts
index 8fcc31ba..8bb5093c 100644
--- a/node_modules/@actions/core/lib/core.d.ts
+++ b/node_modules/@actions/core/lib/core.d.ts
@@ -21,9 +21,9 @@ export declare enum ExitCode {
/**
* Sets env variable for this action and future actions in the job
* @param name the name of the variable to set
- * @param val the value of the variable
+ * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
*/
-export declare function exportVariable(name: string, val: string): void;
+export declare function exportVariable(name: string, val: any): void;
/**
* Registers a secret which will get masked from logs
* @param secret value of the secret
@@ -46,15 +46,21 @@ export declare function getInput(name: string, options?: InputOptions): string;
* Sets the value of an output.
*
* @param name name of the output to set
- * @param value value to store
+ * @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
-export declare function setOutput(name: string, value: string): void;
+export declare function setOutput(name: string, value: any): void;
+/**
+ * Enables or disables the echoing of commands into stdout for the rest of the step.
+ * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
+ *
+ */
+export declare function setCommandEcho(enabled: boolean): void;
/**
* Sets the action status to failed.
* When the action exits it will be with an exit code of 1
* @param message add error issue message
*/
-export declare function setFailed(message: string): void;
+export declare function setFailed(message: string | Error): void;
/**
* Gets whether Actions Step Debug is on or not
*/
@@ -66,14 +72,14 @@ export declare function isDebug(): boolean;
export declare function debug(message: string): void;
/**
* Adds an error issue
- * @param message error issue message
+ * @param message error issue message. Errors will be converted to string via toString()
*/
-export declare function error(message: string): void;
+export declare function error(message: string | Error): void;
/**
* Adds an warning issue
- * @param message warning issue message
+ * @param message warning issue message. Errors will be converted to string via toString()
*/
-export declare function warning(message: string): void;
+export declare function warning(message: string | Error): void;
/**
* Writes info to log with console.log.
* @param message info message
@@ -104,9 +110,9 @@ export declare function group(name: string, fn: () => Promise): Promise
* Saves state for current action, the state can only be retrieved by this action's post job execution.
*
* @param name name of the state to store
- * @param value value to store
+ * @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
-export declare function saveState(name: string, value: string): void;
+export declare function saveState(name: string, value: any): void;
/**
* Gets the value of an state set by this action's main execution.
*
diff --git a/node_modules/@actions/core/lib/core.js b/node_modules/@actions/core/lib/core.js
index b7ec8ab4..c838f4e2 100644
--- a/node_modules/@actions/core/lib/core.js
+++ b/node_modules/@actions/core/lib/core.js
@@ -39,11 +39,13 @@ var ExitCode;
/**
* Sets env variable for this action and future actions in the job
* @param name the name of the variable to set
- * @param val the value of the variable
+ * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify
*/
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
function exportVariable(name, val) {
- process.env[name] = val;
- command_1.issueCommand('set-env', { name }, val);
+ const convertedVal = command_1.toCommandValue(val);
+ process.env[name] = convertedVal;
+ command_1.issueCommand('set-env', { name }, convertedVal);
}
exports.exportVariable = exportVariable;
/**
@@ -82,12 +84,22 @@ exports.getInput = getInput;
* Sets the value of an output.
*
* @param name name of the output to set
- * @param value value to store
+ * @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setOutput(name, value) {
command_1.issueCommand('set-output', { name }, value);
}
exports.setOutput = setOutput;
+/**
+ * Enables or disables the echoing of commands into stdout for the rest of the step.
+ * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set.
+ *
+ */
+function setCommandEcho(enabled) {
+ command_1.issue('echo', enabled ? 'on' : 'off');
+}
+exports.setCommandEcho = setCommandEcho;
//-----------------------------------------------------------------------
// Results
//-----------------------------------------------------------------------
@@ -121,18 +133,18 @@ function debug(message) {
exports.debug = debug;
/**
* Adds an error issue
- * @param message error issue message
+ * @param message error issue message. Errors will be converted to string via toString()
*/
function error(message) {
- command_1.issue('error', message);
+ command_1.issue('error', message instanceof Error ? message.toString() : message);
}
exports.error = error;
/**
* Adds an warning issue
- * @param message warning issue message
+ * @param message warning issue message. Errors will be converted to string via toString()
*/
function warning(message) {
- command_1.issue('warning', message);
+ command_1.issue('warning', message instanceof Error ? message.toString() : message);
}
exports.warning = warning;
/**
@@ -190,8 +202,9 @@ exports.group = group;
* Saves state for current action, the state can only be retrieved by this action's post job execution.
*
* @param name name of the state to store
- * @param value value to store
+ * @param value value to store. Non-string values will be converted to a string via JSON.stringify
*/
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
function saveState(name, value) {
command_1.issueCommand('save-state', { name }, value);
}
diff --git a/node_modules/@actions/core/lib/core.js.map b/node_modules/@actions/core/lib/core.js.map
index fb93bd38..68e9f313 100644
--- a/node_modules/@actions/core/lib/core.js.map
+++ b/node_modules/@actions/core/lib/core.js.map
@@ -1 +1 @@
-{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,uCAA6C;AAE7C,uCAAwB;AACxB,2CAA4B;AAU5B;;GAEG;AACH,IAAY,QAUX;AAVD,WAAY,QAAQ;IAClB;;OAEG;IACH,6CAAW,CAAA;IAEX;;OAEG;IACH,6CAAW,CAAA;AACb,CAAC,EAVW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAUnB;AAED,yEAAyE;AACzE,YAAY;AACZ,yEAAyE;AAEzE;;;;GAIG;AACH,SAAgB,cAAc,CAAC,IAAY,EAAE,GAAW;IACtD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAA;IACvB,sBAAY,CAAC,SAAS,EAAE,EAAC,IAAI,EAAC,EAAE,GAAG,CAAC,CAAA;AACtC,CAAC;AAHD,wCAGC;AAED;;;GAGG;AACH,SAAgB,SAAS,CAAC,MAAc;IACtC,sBAAY,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;AACtC,CAAC;AAFD,8BAEC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,SAAiB;IACvC,sBAAY,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,CAAC,CAAA;IACvC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAA;AAC7E,CAAC;AAHD,0BAGC;AAED;;;;;;GAMG;AACH,SAAgB,QAAQ,CAAC,IAAY,EAAE,OAAsB;IAC3D,MAAM,GAAG,GACP,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;IACrE,IAAI,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE;QACvC,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAA;KAC5D;IAED,OAAO,GAAG,CAAC,IAAI,EAAE,CAAA;AACnB,CAAC;AARD,4BAQC;AAED;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,sBAAY,CAAC,YAAY,EAAE,EAAC,IAAI,EAAC,EAAE,KAAK,CAAC,CAAA;AAC3C,CAAC;AAFD,8BAEC;AAED,yEAAyE;AACzE,UAAU;AACV,yEAAyE;AAEzE;;;;GAIG;AACH,SAAgB,SAAS,CAAC,OAAe;IACvC,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAA;IACnC,KAAK,CAAC,OAAO,CAAC,CAAA;AAChB,CAAC;AAHD,8BAGC;AAED,yEAAyE;AACzE,mBAAmB;AACnB,yEAAyE;AAEzE;;GAEG;AACH,SAAgB,OAAO;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,GAAG,CAAA;AAC5C,CAAC;AAFD,0BAEC;AAED;;;GAGG;AACH,SAAgB,KAAK,CAAC,OAAe;IACnC,sBAAY,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACpC,CAAC;AAFD,sBAEC;AAED;;;GAGG;AACH,SAAgB,KAAK,CAAC,OAAe;IACnC,eAAK,CAAC,OAAO,EAAE,OAAO,CAAC,CAAA;AACzB,CAAC;AAFD,sBAEC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,OAAe;IACrC,eAAK,CAAC,SAAS,EAAE,OAAO,CAAC,CAAA;AAC3B,CAAC;AAFD,0BAEC;AAED;;;GAGG;AACH,SAAgB,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AACxC,CAAC;AAFD,oBAEC;AAED;;;;;;GAMG;AACH,SAAgB,UAAU,CAAC,IAAY;IACrC,eAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AACtB,CAAC;AAFD,gCAEC;AAED;;GAEG;AACH,SAAgB,QAAQ;IACtB,eAAK,CAAC,UAAU,CAAC,CAAA;AACnB,CAAC;AAFD,4BAEC;AAED;;;;;;;GAOG;AACH,SAAsB,KAAK,CAAI,IAAY,EAAE,EAAoB;;QAC/D,UAAU,CAAC,IAAI,CAAC,CAAA;QAEhB,IAAI,MAAS,CAAA;QAEb,IAAI;YACF,MAAM,GAAG,MAAM,EAAE,EAAE,CAAA;SACpB;gBAAS;YACR,QAAQ,EAAE,CAAA;SACX;QAED,OAAO,MAAM,CAAA;IACf,CAAC;CAAA;AAZD,sBAYC;AAED,yEAAyE;AACzE,uBAAuB;AACvB,yEAAyE;AAEzE;;;;;GAKG;AACH,SAAgB,SAAS,CAAC,IAAY,EAAE,KAAa;IACnD,sBAAY,CAAC,YAAY,EAAE,EAAC,IAAI,EAAC,EAAE,KAAK,CAAC,CAAA;AAC3C,CAAC;AAFD,8BAEC;AAED;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,IAAY;IACnC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;AAC3C,CAAC;AAFD,4BAEC"}
\ No newline at end of file
+{"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAAA,uCAA6D;AAE7D,uCAAwB;AACxB,2CAA4B;AAU5B;;GAEG;AACH,IAAY,QAUX;AAVD,WAAY,QAAQ;IAClB;;OAEG;IACH,6CAAW,CAAA;IAEX;;OAEG;IACH,6CAAW,CAAA;AACb,CAAC,EAVW,QAAQ,GAAR,gBAAQ,KAAR,gBAAQ,QAUnB;AAED,yEAAyE;AACzE,YAAY;AACZ,yEAAyE;AAEzE;;;;GAIG;AACH,8DAA8D;AAC9D,SAAgB,cAAc,CAAC,IAAY,EAAE,GAAQ;IACnD,MAAM,YAAY,GAAG,wBAAc,CAAC,GAAG,CAAC,CAAA;IACxC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,YAAY,CAAA;IAChC,sBAAY,CAAC,SAAS,EAAE,EAAC,IAAI,EAAC,EAAE,YAAY,CAAC,CAAA;AAC/C,CAAC;AAJD,wCAIC;AAED;;;GAGG;AACH,SAAgB,SAAS,CAAC,MAAc;IACtC,sBAAY,CAAC,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,CAAA;AACtC,CAAC;AAFD,8BAEC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,SAAiB;IACvC,sBAAY,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,CAAC,CAAA;IACvC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,GAAG,SAAS,GAAG,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAA;AAC7E,CAAC;AAHD,0BAGC;AAED;;;;;;GAMG;AACH,SAAgB,QAAQ,CAAC,IAAY,EAAE,OAAsB;IAC3D,MAAM,GAAG,GACP,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,IAAI,EAAE,CAAA;IACrE,IAAI,OAAO,IAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,GAAG,EAAE;QACvC,MAAM,IAAI,KAAK,CAAC,oCAAoC,IAAI,EAAE,CAAC,CAAA;KAC5D;IAED,OAAO,GAAG,CAAC,IAAI,EAAE,CAAA;AACnB,CAAC;AARD,4BAQC;AAED;;;;;GAKG;AACH,8DAA8D;AAC9D,SAAgB,SAAS,CAAC,IAAY,EAAE,KAAU;IAChD,sBAAY,CAAC,YAAY,EAAE,EAAC,IAAI,EAAC,EAAE,KAAK,CAAC,CAAA;AAC3C,CAAC;AAFD,8BAEC;AAED;;;;GAIG;AACH,SAAgB,cAAc,CAAC,OAAgB;IAC7C,eAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAA;AACvC,CAAC;AAFD,wCAEC;AAED,yEAAyE;AACzE,UAAU;AACV,yEAAyE;AAEzE;;;;GAIG;AACH,SAAgB,SAAS,CAAC,OAAuB;IAC/C,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC,OAAO,CAAA;IAEnC,KAAK,CAAC,OAAO,CAAC,CAAA;AAChB,CAAC;AAJD,8BAIC;AAED,yEAAyE;AACzE,mBAAmB;AACnB,yEAAyE;AAEzE;;GAEG;AACH,SAAgB,OAAO;IACrB,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,KAAK,GAAG,CAAA;AAC5C,CAAC;AAFD,0BAEC;AAED;;;GAGG;AACH,SAAgB,KAAK,CAAC,OAAe;IACnC,sBAAY,CAAC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAA;AACpC,CAAC;AAFD,sBAEC;AAED;;;GAGG;AACH,SAAgB,KAAK,CAAC,OAAuB;IAC3C,eAAK,CAAC,OAAO,EAAE,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;AACzE,CAAC;AAFD,sBAEC;AAED;;;GAGG;AACH,SAAgB,OAAO,CAAC,OAAuB;IAC7C,eAAK,CAAC,SAAS,EAAE,OAAO,YAAY,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;AAC3E,CAAC;AAFD,0BAEC;AAED;;;GAGG;AACH,SAAgB,IAAI,CAAC,OAAe;IAClC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;AACxC,CAAC;AAFD,oBAEC;AAED;;;;;;GAMG;AACH,SAAgB,UAAU,CAAC,IAAY;IACrC,eAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;AACtB,CAAC;AAFD,gCAEC;AAED;;GAEG;AACH,SAAgB,QAAQ;IACtB,eAAK,CAAC,UAAU,CAAC,CAAA;AACnB,CAAC;AAFD,4BAEC;AAED;;;;;;;GAOG;AACH,SAAsB,KAAK,CAAI,IAAY,EAAE,EAAoB;;QAC/D,UAAU,CAAC,IAAI,CAAC,CAAA;QAEhB,IAAI,MAAS,CAAA;QAEb,IAAI;YACF,MAAM,GAAG,MAAM,EAAE,EAAE,CAAA;SACpB;gBAAS;YACR,QAAQ,EAAE,CAAA;SACX;QAED,OAAO,MAAM,CAAA;IACf,CAAC;CAAA;AAZD,sBAYC;AAED,yEAAyE;AACzE,uBAAuB;AACvB,yEAAyE;AAEzE;;;;;GAKG;AACH,8DAA8D;AAC9D,SAAgB,SAAS,CAAC,IAAY,EAAE,KAAU;IAChD,sBAAY,CAAC,YAAY,EAAE,EAAC,IAAI,EAAC,EAAE,KAAK,CAAC,CAAA;AAC3C,CAAC;AAFD,8BAEC;AAED;;;;;GAKG;AACH,SAAgB,QAAQ,CAAC,IAAY;IACnC,OAAO,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,IAAI,EAAE,CAAA;AAC3C,CAAC;AAFD,4BAEC"}
\ No newline at end of file
diff --git a/node_modules/@actions/core/package.json b/node_modules/@actions/core/package.json
index 951dd7bd..f57fe1b5 100644
--- a/node_modules/@actions/core/package.json
+++ b/node_modules/@actions/core/package.json
@@ -1,23 +1,57 @@
{
- "name": "@actions/core",
- "version": "1.2.3",
- "description": "Actions core lib",
- "keywords": [
- "github",
- "actions",
- "core"
+ "_args": [
+ [
+ "@actions/core@1.2.5",
+ "."
+ ]
],
- "homepage": "https://github.com/actions/toolkit/tree/master/packages/core",
- "license": "MIT",
- "main": "lib/core.js",
- "types": "lib/core.d.ts",
+ "_from": "@actions/core@1.2.5",
+ "_id": "@actions/core@1.2.5",
+ "_inBundle": false,
+ "_integrity": "sha512-mwpoNjHSWWh0IiALdDEQi3tru124JKn0yVNziIBzTME8QRv7thwoghVuT1jBRjFvdtoHsqD58IRHy1nf86paRg==",
+ "_location": "/@actions/core",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "version",
+ "registry": true,
+ "raw": "@actions/core@1.2.5",
+ "name": "@actions/core",
+ "escapedName": "@actions%2fcore",
+ "scope": "@actions",
+ "rawSpec": "1.2.5",
+ "saveSpec": null,
+ "fetchSpec": "1.2.5"
+ },
+ "_requiredBy": [
+ "/"
+ ],
+ "_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.5.tgz",
+ "_spec": "1.2.5",
+ "_where": ".",
+ "bugs": {
+ "url": "https://github.com/actions/toolkit/issues"
+ },
+ "description": "Actions core lib",
+ "devDependencies": {
+ "@types/node": "^12.0.2"
+ },
"directories": {
"lib": "lib",
"test": "__tests__"
},
"files": [
- "lib"
+ "lib",
+ "!.DS_Store"
],
+ "homepage": "https://github.com/actions/toolkit/tree/main/packages/core",
+ "keywords": [
+ "github",
+ "actions",
+ "core"
+ ],
+ "license": "MIT",
+ "main": "lib/core.js",
+ "name": "@actions/core",
"publishConfig": {
"access": "public"
},
@@ -27,18 +61,10 @@
"directory": "packages/core"
},
"scripts": {
- "audit-moderate": "npm install && npm audit --audit-level=moderate",
+ "audit-moderate": "npm install && npm audit --json --audit-level=moderate > audit.json",
"test": "echo \"Error: run tests from root\" && exit 1",
"tsc": "tsc"
},
- "bugs": {
- "url": "https://github.com/actions/toolkit/issues"
- },
- "devDependencies": {
- "@types/node": "^12.0.2"
- }
-
-,"_resolved": "https://registry.npmjs.org/@actions/core/-/core-1.2.3.tgz"
-,"_integrity": "sha512-Wp4xnyokakM45Uuj4WLUxdsa8fJjKVl1fDTsPbTEcTcuu0Nb26IPQbOtjmnfaCPGcaoPOOqId8H9NapZ8gii4w=="
-,"_from": "@actions/core@1.2.3"
-}
\ No newline at end of file
+ "types": "lib/core.d.ts",
+ "version": "1.2.5"
+}
diff --git a/node_modules/xpath/.npmignore b/node_modules/xpath/.npmignore
deleted file mode 100644
index c2658d7d..00000000
--- a/node_modules/xpath/.npmignore
+++ /dev/null
@@ -1 +0,0 @@
-node_modules/
diff --git a/node_modules/xpath/LICENSE b/node_modules/xpath/LICENSE
new file mode 100644
index 00000000..e9a0bae4
--- /dev/null
+++ b/node_modules/xpath/LICENSE
@@ -0,0 +1,22 @@
+MIT License
+
+Copyright (c) 2018 Cameron McCormack
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/node_modules/xpath/docs/XPathEvaluator.md b/node_modules/xpath/docs/XPathEvaluator.md
index 471cfecd..fe0999bf 100644
--- a/node_modules/xpath/docs/XPathEvaluator.md
+++ b/node_modules/xpath/docs/XPathEvaluator.md
@@ -2,15 +2,15 @@
The `xpath.parse()` method returns an `XPathEvaluator`, which contains the following methods.
-Each of these methods takes an optional `options` object, which can contain any of the following properties:
+Each of these methods takes an optional `options` object, which can contain any of the following properties. See the links for each item for further details:
-`namespaces` - a namespace resolver. See the [documentation page](namespace%20resolvers.md) for details.
+- `namespaces` - a [namespace resolver](namespace%20resolvers.md)
-`variables` - a variable resolver. See the [documentation page](variable%20resolvers.md) for details.
+- `variables` - a [variable resolver](variable%20resolvers.md)
-`functions` - a function resolver. See the [documentation page](function%20resolvers.md) for details.
+- `functions` - a [function resolver](function%20resolvers.md)
-`node` - the context node for evaluating the expression
+- `node` - the context node for evaluating the expression
Example usage:
@@ -56,7 +56,7 @@ This is only valid for expressions that evaluate to a node set.
`select1([options])`
-Evaluates the XPath expression and the first node in the resulting node set, in document order. Returns `undefined`
+Evaluates the XPath expression and the first node in the resulting node set, in document order. Returns `undefined` if the resulting node set is empty.
This is only valid for expressions that evaluate to a node set.
diff --git a/node_modules/xpath/docs/function resolvers.md b/node_modules/xpath/docs/function resolvers.md
index 918af9fe..ad369a67 100644
--- a/node_modules/xpath/docs/function resolvers.md
+++ b/node_modules/xpath/docs/function resolvers.md
@@ -31,11 +31,11 @@ Example usage:
```js
var evaluator = xpath.parse('squareRoot(10)');
var aboutPi = evaluator.evaluateNumber({
- functions: {
- 'squareRoot': function (c, value) {
- return Math.sqrt(value.numberValue());
- }
- }
+ functions: {
+ 'squareRoot': function (c, value) {
+ return Math.sqrt(value.numberValue());
+ }
+ }
});
```
@@ -49,13 +49,13 @@ Example usage:
```js
var evaluator = xpath.parse('math:squareRoot(10)');
var aboutPi = evaluator.evaluateNumber({
- functions: function (name, namespace) {
+ functions: function (name, namespace) {
if (name === 'squareRoot' && namespace === 'http://sample.org/math/') {
- return function (c, value) {
- return Math.sqrt(value.numberValue());
- };
+ return function (c, value) {
+ return Math.sqrt(value.numberValue());
+ };
}
- },
+ },
namespaces: {
math: 'http://sample.org/math/'
}
@@ -72,14 +72,14 @@ Example usage:
```js
var evaluator = xpath.parse('math:squareRoot(10)');
var aboutPi = evaluator.evaluateNumber({
- functions: {
+ functions: {
getFunction: function (name, namespace) {
if (name === 'squareRoot' && namespace === 'http://sample.org/math/') {
- return function (c, value) {
- return Math.sqrt(value.numberValue());
- };
+ return function (c, value) {
+ return Math.sqrt(value.numberValue());
+ };
}
- }
+ }
},
namespaces: {
math: 'http://sample.org/math/'
diff --git a/node_modules/xpath/package.json b/node_modules/xpath/package.json
index 8d908148..f59895f1 100644
--- a/node_modules/xpath/package.json
+++ b/node_modules/xpath/package.json
@@ -1,13 +1,38 @@
{
- "name": "xpath",
- "version": "0.0.27",
- "description": "DOM 3 XPath implemention and helper for node.js.",
- "engines": {
- "node": ">=0.6.0"
+ "_args": [
+ [
+ "xpath@0.0.29",
+ "."
+ ]
+ ],
+ "_from": "xpath@0.0.29",
+ "_id": "xpath@0.0.29",
+ "_inBundle": false,
+ "_integrity": "sha512-W6vSxu0tmHCW01EwDXx45/BAAl8lBJjcRB6eSswMuycOVbUkYskG3W1LtCxcesVel/RaNe/pxtd3FWLiqHGweA==",
+ "_location": "/xpath",
+ "_phantomChildren": {},
+ "_requested": {
+ "type": "version",
+ "registry": true,
+ "raw": "xpath@0.0.29",
+ "name": "xpath",
+ "escapedName": "xpath",
+ "rawSpec": "0.0.29",
+ "saveSpec": null,
+ "fetchSpec": "0.0.29"
},
+ "_requiredBy": [
+ "/"
+ ],
+ "_resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.29.tgz",
+ "_spec": "0.0.29",
+ "_where": ".",
"author": {
"name": "Cameron McCormack"
},
+ "bugs": {
+ "url": "https://github.com/goto100/xpath/issues"
+ },
"contributors": [
{
"name": "goto100"
@@ -17,26 +42,28 @@
}
],
"dependencies": {},
+ "description": "DOM 3 XPath implemention and helper for node.js.",
"devDependencies": {
- "nodeunit": ">=0.6.4",
"xmldom": "^0.1.19"
},
- "typings": "./xpath.d.ts",
- "scripts": {
- "test": "./node_modules/.bin/nodeunit test.js"
+ "engines": {
+ "node": ">=0.6.0"
},
- "repository": {
- "type": "git",
- "url": "https://github.com/goto100/xpath.git"
- },
- "main": "./xpath.js",
+ "homepage": "https://github.com/goto100/xpath#readme",
"keywords": [
"xpath",
"xml"
],
- "license": "MIT"
-
-,"_resolved": "https://registry.npmjs.org/xpath/-/xpath-0.0.27.tgz"
-,"_integrity": "sha512-fg03WRxtkCV6ohClePNAECYsmpKKTv5L8y/X3Dn1hQrec3POx2jHZ/0P2qQ6HvsrU1BmeqXcof3NGGueG6LxwQ=="
-,"_from": "xpath@0.0.27"
-}
\ No newline at end of file
+ "license": "MIT",
+ "main": "./xpath.js",
+ "name": "xpath",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/goto100/xpath.git"
+ },
+ "scripts": {
+ "test": "mocha"
+ },
+ "typings": "./xpath.d.ts",
+ "version": "0.0.29"
+}
diff --git a/node_modules/xpath/test.js b/node_modules/xpath/test.js
index b7f81a48..c99fd506 100644
--- a/node_modules/xpath/test.js
+++ b/node_modules/xpath/test.js
@@ -1,1092 +1,1022 @@
-var xpath = require('./xpath.js')
-, dom = require('xmldom').DOMParser
-, assert = require('assert');
+const xpath = require('./xpath.js');
+const dom = require('xmldom').DOMParser;
+const assert = require('assert');
var xhtmlNs = 'http://www.w3.org/1999/xhtml';
-module.exports = {
- 'api': function(test) {
- assert.ok(xpath.evaluate, 'evaluate api ok.');
- assert.ok(xpath.select, 'select api ok.');
- assert.ok(xpath.parse, 'parse api ok.');
- test.done();
- },
-
- 'evaluate': function(test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
- var nodes = xpath.evaluate('//title', doc, null, xpath.XPathResult.ANY_TYPE, null).nodes;
- assert.equal('title', nodes[0].localName);
- assert.equal('Harry Potter', nodes[0].firstChild.data);
- assert.equal('Harry Potter', nodes[0].toString());
- test.done();
- },
-
- 'select': function(test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
- var nodes = xpath.select('//title', doc);
- assert.equal('title', nodes[0].localName);
- assert.equal('Harry Potter', nodes[0].firstChild.data);
- assert.equal('Harry Potter', nodes[0].toString());
-
- var nodes2 = xpath.select('//node()', doc);
- assert.equal(7, nodes2.length);
-
- var pis = xpath.select("/processing-instruction('series')", doc);
- assert.equal(2, pis.length);
- assert.equal('books="7"', pis[1].data);
-
- test.done();
- },
-
- 'select single node': function(test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
-
- assert.equal('title', xpath.select('//title[1]', doc)[0].localName);
-
- test.done();
- },
-
- 'select text node': function (test) {
- var xml = 'HarryPotter';
- var doc = new dom().parseFromString(xml);
-
- assert.deepEqual('book', xpath.select('local-name(/book)', doc));
- assert.deepEqual('Harry,Potter', xpath.select('//title/text()', doc).toString());
-
- test.done();
- },
-
- 'select number value': function(test) {
- var xml = 'HarryPotter';
- var doc = new dom().parseFromString(xml);
-
- assert.deepEqual(2, xpath.select('count(//title)', doc));
-
- test.done();
- },
-
- 'select xpath with namespaces': function (test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
-
- var nodes = xpath.select('//*[local-name(.)="title" and namespace-uri(.)="myns"]', doc);
- assert.equal('title', nodes[0].localName);
- assert.equal('myns', nodes[0].namespaceURI) ;
-
- var nodes2 = xpath.select('/*/title', doc);
-
- assert.equal(0, nodes2.length);
-
- test.done();
- },
-
- 'select xpath with namespaces, using a resolver': function (test) {
- var xml = 'NarniaHarry PotterJKR';
- var doc = new dom().parseFromString(xml);
-
- var resolver = {
- mappings: {
- 'testns': 'http://example.com/test'
- },
- lookupNamespaceURI: function(prefix) {
- return this.mappings[prefix];
- }
- }
-
- var nodes = xpath.selectWithResolver('//testns:title/text()', doc, resolver);
- assert.equal('Harry Potter', xpath.selectWithResolver('//testns:title/text()', doc, resolver)[0].nodeValue);
- assert.equal('JKR', xpath.selectWithResolver('//testns:field[@testns:type="author"]/text()', doc, resolver)[0].nodeValue);
-
- var nodes2 = xpath.selectWithResolver('/*/testns:*', doc, resolver);
-
- assert.equal(2, nodes2.length);
-
- test.done();
- },
-
- 'select xpath with default namespace, using a resolver': function (test) {
- var xml = 'Harry PotterJKR';
- var doc = new dom().parseFromString(xml);
-
- var resolver = {
- mappings: {
- 'testns': 'http://example.com/test'
- },
- lookupNamespaceURI: function(prefix) {
- return this.mappings[prefix];
- }
- }
-
- var nodes = xpath.selectWithResolver('//testns:title/text()', doc, resolver);
- assert.equal('Harry Potter', xpath.selectWithResolver('//testns:title/text()', doc, resolver)[0].nodeValue);
- assert.equal('JKR', xpath.selectWithResolver('//testns:field[@type="author"]/text()', doc, resolver)[0].nodeValue);
-
- test.done();
- },
-
- 'select xpath with namespaces, prefixes different in xml and xpath, using a resolver': function (test) {
- var xml = 'Harry PotterJKR';
- var doc = new dom().parseFromString(xml);
-
- var resolver = {
- mappings: {
- 'ns': 'http://example.com/test'
- },
- lookupNamespaceURI: function(prefix) {
- return this.mappings[prefix];
- }
- }
-
- var nodes = xpath.selectWithResolver('//ns:title/text()', doc, resolver);
- assert.equal('Harry Potter', xpath.selectWithResolver('//ns:title/text()', doc, resolver)[0].nodeValue);
- assert.equal('JKR', xpath.selectWithResolver('//ns:field[@ns:type="author"]/text()', doc, resolver)[0].nodeValue);
-
- test.done();
- },
-
- 'select xpath with namespaces, using namespace mappings': function (test) {
- var xml = 'Harry PotterJKR';
- var doc = new dom().parseFromString(xml);
- var select = xpath.useNamespaces({'testns': 'http://example.com/test'});
-
- assert.equal('Harry Potter', select('//testns:title/text()', doc)[0].nodeValue);
- assert.equal('JKR', select('//testns:field[@testns:type="author"]/text()', doc)[0].nodeValue);
-
- test.done();
- },
-
-
- 'select attribute': function (test) {
- var xml = '';
- var doc = new dom().parseFromString(xml);
-
- var author = xpath.select1('/author/@name', doc).value;
- assert.equal('J. K. Rowling', author);
-
- test.done();
- }
-
- ,'select with multiple predicates': function (test) {
- var xml = '';
- var doc = new dom().parseFromString(xml);
-
- var characters = xpath.select('/*/character[@sex = "M"][@age > 40]/@name', doc);
-
- assert.equal(1, characters.length);
- assert.equal('Snape', characters[0].textContent);
-
- test.done();
- }
-
- // https://github.com/goto100/xpath/issues/37
- ,'select multiple attributes': function (test) {
- var xml = '';
- var doc = new dom().parseFromString(xml);
-
- var authors = xpath.select('/authors/author/@name', doc);
- assert.equal(2, authors.length);
- assert.equal('J. K. Rowling', authors[0].value);
-
- // https://github.com/goto100/xpath/issues/41
- doc = new dom().parseFromString('');
- var nodes = xpath.select("/chapters/chapter/@v", doc);
- var values = nodes.map(function(n) { return n.value; });
-
- assert.equal(3, values.length);
- assert.equal("1", values[0]);
- assert.equal("2", values[1]);
- assert.equal("3", values[2]);
-
- test.done();
- }
-
- ,'XPathException acts like Error': function (test) {
- try {
- xpath.evaluate('1', null, null, null);
- assert.fail(null, null, 'evaluate() should throw exception');
- } catch (e) {
- assert.ok('code' in e, 'must have a code');
- assert.ok('stack' in e, 'must have a stack');
- }
-
- test.done();
- },
-
- 'string() with no arguments': function (test) {
- var doc = new dom().parseFromString('Harry Potter');
-
- var rootElement = xpath.select1('/book', doc);
- assert.ok(rootElement, 'rootElement is null');
-
- assert.equal('Harry Potter', xpath.select1('string()', doc));
-
- test.done();
- },
-
- 'string value of document fragment': function (test) {
- var doc = new dom().parseFromString('');
- var docFragment = doc.createDocumentFragment();
-
- var el = doc.createElement("book");
- docFragment.appendChild(el);
-
- var testValue = "Harry Potter";
-
- el.appendChild(doc.createTextNode(testValue));
-
- assert.equal(testValue, xpath.select1("string()", docFragment));
-
- test.done();
- },
-
- 'compare string of a number with a number': function (test) {
- assert.ok(xpath.select1('"000" = 0'), '000');
- assert.ok(xpath.select1('"45.0" = 45'), '45');
-
- test.done();
- },
-
- 'string(boolean) is a string': function (test) {
- assert.equal('string', typeof xpath.select1('string(true())'));
- assert.equal('string', typeof xpath.select1('string(false())'));
- assert.equal('string', typeof xpath.select1('string(1 = 2)'));
- assert.ok(xpath.select1('"true" = string(true())'), '"true" = string(true())');
-
- test.done();
- },
-
- 'string should downcast to boolean': function (test) {
- assert.equal(false, xpath.select1('"false" = false()'), '"false" = false()');
- assert.equal(true, xpath.select1('"a" = true()'), '"a" = true()');
- assert.equal(true, xpath.select1('"" = false()'), '"" = false()');
-
- test.done();
- },
-
- 'string(number) is a string': function (test) {
- assert.equal('string', typeof xpath.select1('string(45)'));
- assert.ok(xpath.select1('"45" = string(45)'), '"45" = string(45)');
-
- test.done();
- },
-
- 'correct string to number conversion': function (test) {
- assert.equal(45.2, xpath.select1('number("45.200")'));
- assert.equal(55.0, xpath.select1('number("000055")'));
- assert.equal(65.0, xpath.select1('number(" 65 ")'));
-
- assert.equal(true, xpath.select1('"" != 0'), '"" != 0');
- assert.equal(false, xpath.select1('"" = 0'), '"" = 0');
- assert.equal(false, xpath.select1('0 = ""'), '0 = ""');
- assert.equal(false, xpath.select1('0 = " "'), '0 = " "');
-
- assert.ok(Number.isNaN(xpath.select('number("")')), 'number("")');
- assert.ok(Number.isNaN(xpath.select('number("45.8g")')), 'number("45.8g")');
- assert.ok(Number.isNaN(xpath.select('number("2e9")')), 'number("2e9")');
- assert.ok(Number.isNaN(xpath.select('number("+33")')), 'number("+33")');
-
- test.done();
- }
-
- ,'correct number to string conversion': function (test) {
- assert.equal('0.0000000000000000000000005250000000000001', xpath.parse('0.525 div 1000000 div 1000000 div 1000000 div 1000000').evaluateString());
- assert.equal('525000000000000000000000', xpath.parse('0.525 * 1000000 * 1000000 * 1000000 * 1000000').evaluateString());
-
- test.done();
- }
-
- ,'local-name() and name() of processing instruction': function (test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
- var expectedName = 'book-record';
- var localName = xpath.select('local-name(/processing-instruction())', doc);
- var name = xpath.select('name(/processing-instruction())', doc);
-
- assert.deepEqual(expectedName, localName, 'local-name() - "' + expectedName + '" !== "' + localName + '"');
- assert.deepEqual(expectedName, name, 'name() - "' + expectedName + '" !== "' + name + '"');
-
- test.done();
- },
-
- 'evaluate substring-after': function (test) {
- var xml = 'Hermione';
- var doc = new dom().parseFromString(xml);
-
- var part = xpath.select('substring-after(/classmate, "Her")', doc);
- assert.deepEqual('mione', part);
-
- test.done();
- }
-
- ,'parsed expression with no options': function (test) {
- var parsed = xpath.parse('5 + 7');
-
- assert.equal(typeof parsed, "object", "parse() should return an object");
- assert.equal(typeof parsed.evaluate, "function", "parsed.evaluate should be a function");
- assert.equal(typeof parsed.evaluateNumber, "function", "parsed.evaluateNumber should be a function");
-
- assert.equal(parsed.evaluateNumber(), 12);
-
- // evaluating twice should yield the same result
- assert.equal(parsed.evaluateNumber(), 12);
-
- test.done();
- }
-
- ,'select1() on parsed expression': function (test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
- var parsed = xpath.parse('/*/title');
-
- assert.equal(typeof parsed, 'object', 'parse() should return an object');
-
- assert.equal(typeof parsed.select1, 'function', 'parsed.select1 should be a function');
-
- var single = parsed.select1({ node: doc });
-
- assert.equal('title', single.localName);
- assert.equal('Harry Potter', single.firstChild.data);
- assert.equal('Harry Potter', single.toString());
-
- test.done();
- }
-
- ,'select() on parsed expression': function (test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
- var parsed = xpath.parse('/*/title');
-
- assert.equal(typeof parsed, 'object', 'parse() should return an object');
-
- assert.equal(typeof parsed.select, 'function', 'parsed.select should be a function');
-
- var nodes = parsed.select({ node: doc });
-
- assert.ok(nodes, 'parsed.select() should return a value');
- assert.equal(1, nodes.length);
- assert.equal('title', nodes[0].localName);
- assert.equal('Harry Potter', nodes[0].firstChild.data);
- assert.equal('Harry Potter', nodes[0].toString());
-
- test.done();
- }
-
- ,'evaluateString(), and evaluateNumber() on parsed expression with node': function (test) {
- var xml = 'Harry Potter7';
- var doc = new dom().parseFromString(xml);
- var parsed = xpath.parse('/*/numVolumes');
-
- assert.equal(typeof parsed, 'object', 'parse() should return an object');
-
- assert.equal(typeof parsed.evaluateString, 'function', 'parsed.evaluateString should be a function');
- assert.equal('7', parsed.evaluateString({ node: doc }));
-
- assert.equal(typeof parsed.evaluateBoolean, 'function', 'parsed.evaluateBoolean should be a function');
- assert.equal(true, parsed.evaluateBoolean({ node: doc }));
-
- assert.equal(typeof parsed.evaluateNumber, 'function', 'parsed.evaluateNumber should be a function');
- assert.equal(7, parsed.evaluateNumber({ node: doc }));
-
- test.done();
- }
-
- ,'evaluateBoolean() on parsed empty node set and boolean expressions': function (test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
- var context = { node: doc };
-
- function evaluate(path) {
- return xpath.parse(path).evaluateBoolean({ node: doc });
- }
-
- assert.equal(false, evaluate('/*/myrtle'), 'boolean value of empty node set should be false');
-
- assert.equal(true, evaluate('not(/*/myrtle)'), 'not() of empty nodeset should be true');
-
- assert.equal(true, evaluate('/*/title'), 'boolean value of non-empty nodeset should be true');
-
- assert.equal(true, evaluate('/*/title = "Harry Potter"'), 'title equals Harry Potter');
-
- assert.equal(false, evaluate('/*/title != "Harry Potter"'), 'title != Harry Potter should be false');
-
- assert.equal(false, evaluate('/*/title = "Percy Jackson"'), 'title should not equal Percy Jackson');
-
- test.done();
- }
-
- ,'namespaces with parsed expression': function (test) {
- var xml = '' +
- 'QuirrellFluffy' +
- 'MyrtleTom Riddle' +
- '';
- var doc = new dom().parseFromString(xml);
-
- var expr = xpath.parse('/characters/c:character');
- var countExpr = xpath.parse('count(/characters/c:character)');
- var csns = 'http://chamber-secrets.com';
-
- function resolve(prefix) {
- if (prefix === 'c') {
- return csns;
- }
- }
-
- function testContext(context, description) {
- try {
- var value = expr.evaluateString(context);
- var count = countExpr.evaluateNumber(context);
-
- assert.equal('Myrtle', value, description + ' - string value - ' + value);
- assert.equal(2, count, description + ' map - count - ' + count);
- } catch(e) {
- e.message = description + ': ' + (e.message || '');
- throw e;
- }
- }
-
- testContext({
- node: doc,
- namespaces: {
- c: csns
- }
- }, 'Namespace map');
-
- testContext({
- node: doc,
- namespaces: resolve
- }, 'Namespace function');
-
- testContext({
- node: doc,
- namespaces: {
- getNamespace: resolve
- }
- }, 'Namespace object');
-
- test.done();
- }
-
- ,'custom functions': function (test) {
- var xml = 'Harry Potter';
- var doc = new dom().parseFromString(xml);
-
- var parsed = xpath.parse('concat(double(/*/title), " is cool")');
-
- function doubleString(context, value) {
- assert.equal(2, arguments.length);
- var str = value.stringValue();
- return str + str;
- }
-
- function functions(name, namespace) {
- if(name === 'double') {
- return doubleString;
- }
- return null;
- }
-
- function testContext(context, description) {
- try{
- var actual = parsed.evaluateString(context);
- var expected = 'Harry PotterHarry Potter is cool';
- assert.equal(expected, actual, description + ' - ' + expected + ' != ' + actual);
- } catch (e) {
- e.message = description + ": " + (e.message || '');
- throw e;
- }
- }
-
- testContext({
- node: doc,
- functions: functions
- }, 'Functions function');
-
- testContext({
- node: doc,
- functions: {
- getFunction: functions
- }
- }, 'Functions object');
-
- testContext({
- node: doc,
- functions: {
- double: doubleString
- }
- }, 'Functions map');
-
- test.done();
- }
-
- ,'custom function namespaces': function (test) {
- var xml = 'Harry PotterRonHermioneNeville';
- var doc = new dom().parseFromString(xml);
-
- var parsed = xpath.parse('concat(hp:double(/*/title), " is 2 cool ", hp:square(2), " school")');
- var hpns = 'http://harry-potter.com';
-
- var namespaces = {
- hp: hpns
- };
-
- var context = {
- node: doc,
- namespaces: {
- hp: hpns
- },
- functions: function (name, namespace) {
- if (namespace === hpns) {
- switch (name) {
- case "double":
- return function (context, value) {
- assert.equal(2, arguments.length);
- var str = value.stringValue();
- return str + str;
- };
- case "square":
- return function (context, value) {
- var num = value.numberValue();
- return num * num;
- };
-
- case "xor":
- return function (context, l, r) {
- assert.equal(3, arguments.length);
- var lbool = l.booleanValue();
- var rbool = r.booleanValue();
- return (lbool || rbool) && !(lbool && rbool);
- };
-
- case "second":
- return function (context, nodes) {
- var nodesArr = nodes.toArray();
- var second = nodesArr[1];
- return second ? [second] : [];
- };
- }
- }
- return null;
- }
- };
-
- assert.equal('Harry PotterHarry Potter is 2 cool 4 school', parsed.evaluateString(context));
-
- assert.equal(false, xpath.parse('hp:xor(false(), false())').evaluateBoolean(context));
- assert.equal(true, xpath.parse('hp:xor(false(), true())').evaluateBoolean(context));
- assert.equal(true, xpath.parse('hp:xor(true(), false())').evaluateBoolean(context));
- assert.equal(false, xpath.parse('hp:xor(true(), true())').evaluateBoolean(context));
-
- assert.equal('Hermione', xpath.parse('hp:second(/*/friend)').evaluateString(context));
- assert.equal(1, xpath.parse('count(hp:second(/*/friend))').evaluateNumber(context));
- assert.equal(0, xpath.parse('count(hp:second(/*/friendz))').evaluateNumber(context));
-
- test.done();
- }
-
- ,'xpath variables': function (test) {
- var xml = 'Harry Potter7';
- var doc = new dom().parseFromString(xml);
-
- var variables = {
- title: 'Harry Potter',
- notTitle: 'Percy Jackson',
- houses: 4
- };
-
- function variableFunction(name) {
- return variables[name];
- }
-
- function testContext(context, description) {
- try{
- assert.equal(true, xpath.parse('$title = /*/title').evaluateBoolean(context));
- assert.equal(false, xpath.parse('$notTitle = /*/title').evaluateBoolean(context));
- assert.equal(11, xpath.parse('$houses + /*/volumes').evaluateNumber(context));
- } catch (e) {
- e.message = description + ": " + (e.message || '');
- throw e;
- }
- }
-
- testContext({
- node: doc,
- variables: variableFunction
- }, 'Variables function');
-
- testContext({
- node: doc,
- variables: {
- getVariable: variableFunction
- }
- }, 'Variables object');
-
- testContext({
- node: doc,
- variables: variables
- }, 'Variables map');
-
- test.done();
- }
-
- ,'xpath variable namespaces': function (test) {
- var xml = 'Harry Potter7';
- var doc = new dom().parseFromString(xml);
- var hpns = 'http://harry-potter.com';
-
- var context = {
- node: doc,
- namespaces: {
- hp: hpns
- },
- variables: function(name, namespace) {
- if (namespace === hpns) {
- switch (name) {
- case 'title': return 'Harry Potter';
- case 'houses': return 4;
- case 'false': return false;
- case 'falseStr': return 'false';
- }
- } else if (namespace === '') {
- switch (name) {
- case 'title': return 'World';
- }
- }
-
- return null;
- }
- };
-
- assert.equal(true, xpath.parse('$hp:title = /*/title').evaluateBoolean(context));
- assert.equal(false, xpath.parse('$title = /*/title').evaluateBoolean(context));
- assert.equal('World', xpath.parse('$title').evaluateString(context));
- assert.equal(false, xpath.parse('$hp:false').evaluateBoolean(context));
- assert.notEqual(false, xpath.parse('$hp:falseStr').evaluateBoolean(context));
- assert.throws(function () {
- xpath.parse('$hp:hello').evaluateString(context);
- }, function (err) {
- return err.message === 'Undeclared variable: $hp:hello';
+describe('xpath', () => {
+ describe('api', () => {
+ it('should contain the correct methods', () => {
+ assert.ok(xpath.evaluate, 'evaluate api ok.');
+ assert.ok(xpath.select, 'select api ok.');
+ assert.ok(xpath.parse, 'parse api ok.');
});
-
- test.done();
- }
- ,"detect unterminated string literals": function (test) {
- function testUnterminated(path) {
- assert.throws(function () {
- xpath.evaluate('"hello');
- }, function (err) {
- return err.message.indexOf('Unterminated') !== -1;
- });
- }
-
- testUnterminated('"Hello');
- testUnterminated("'Hello");
- testUnterminated('self::text() = "\""');
- testUnterminated('"\""');
+ it('should support .evaluate()', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
+ var nodes = xpath.evaluate('//title', doc, null, xpath.XPathResult.ANY_TYPE, null).nodes;
- test.done();
- }
-
- ,"string value for CDATA sections": function (test) {
- var xml = "Ron ",
- doc = new dom().parseFromString(xml),
- person1 = xpath.parse("/people/person").evaluateString({ node: doc }),
- person2 = xpath.parse("/people/person/text()").evaluateString({ node: doc }),
- person3 = xpath.select("string(/people/person/text())", doc);
- person4 = xpath.parse("/people/person[2]").evaluateString({ node: doc });
-
- assert.equal(person1, 'Harry Potter');
- assert.equal(person2, 'Harry Potter');
- assert.equal(person3, 'Harry Potter');
- assert.equal(person4, 'Ron Weasley');
-
- test.done();
- }
-
- ,"string value of various node types": function (test) {
- var xml = "Harry Potter",
- doc = new dom().parseFromString(xml),
- allText = xpath.parse('.').evaluateString({ node: doc }),
- ns = xpath.parse('*/namespace::*[name() = "hp"]').evaluateString({ node: doc }),
- title = xpath.parse('*/title').evaluateString({ node: doc }),
- child = xpath.parse('*/*').evaluateString({ node: doc }),
- titleLang = xpath.parse('*/*/@lang').evaluateString({ node: doc }),
- pi = xpath.parse('*/processing-instruction()').evaluateString({ node: doc }),
- comment = xpath.parse('*/comment()').evaluateString({ node: doc });
-
- assert.equal(allText, "Harry Potter & the Philosopher's StoneHarry Potter");
- assert.equal(ns, 'http://harry');
- assert.equal(title, "Harry Potter & the Philosopher's Stone");
- assert.equal(child, "Harry Potter & the Philosopher's Stone");
- assert.equal(titleLang, 'en');
- assert.equal(pi.trim(), "name='J.K. Rowling'");
- assert.equal(comment, ' This describes the Harry Potter Book ');
-
- test.done();
- }
-
- ,"exposes custom types": function (test) {
- assert.ok(xpath.XPath, "xpath.XPath");
- assert.ok(xpath.XPathParser, "xpath.XPathParser");
- assert.ok(xpath.XPathResult, "xpath.XPathResult");
-
- assert.ok(xpath.Step, "xpath.Step");
- assert.ok(xpath.NodeTest, "xpath.NodeTest");
- assert.ok(xpath.BarOperation, "xpath.BarOperation");
-
- assert.ok(xpath.NamespaceResolver, "xpath.NamespaceResolver");
- assert.ok(xpath.FunctionResolver, "xpath.FunctionResolver");
- assert.ok(xpath.VariableResolver, "xpath.VariableResolver");
-
- assert.ok(xpath.Utilities, "xpath.Utilities");
-
- assert.ok(xpath.XPathContext, "xpath.XPathContext");
- assert.ok(xpath.XNodeSet, "xpath.XNodeSet");
- assert.ok(xpath.XBoolean, "xpath.XBoolean");
- assert.ok(xpath.XString, "xpath.XString");
- assert.ok(xpath.XNumber, "xpath.XNumber");
-
- test.done();
- }
-
- ,"work with nodes created using DOM1 createElement()": function (test) {
- var doc = new dom().parseFromString('');
-
- doc.documentElement.appendChild(doc.createElement('characters'));
-
- assert.ok(xpath.select1('/book/characters', doc));
-
- assert.equal(xpath.select1('local-name(/book/characters)', doc), 'characters');
-
- test.done();
- }
-
- ,"preceding:: axis works on document fragments": function (test) {
- var doc = new dom().parseFromString(''),
- df = doc.createDocumentFragment(),
- root = doc.createElement('book');
-
- df.appendChild(root);
-
- for (var i = 0; i < 10; i += 1) {
- root.appendChild(doc.createElement('chapter'));
- }
-
- var chapter = xpath.select1("book/chapter[5]", df);
-
- assert.ok(chapter, 'chapter');
-
- assert.equal(xpath.select("count(preceding::chapter)", chapter), 4);
-
- test.done();
- }
-
- ,"node set sorted and unsorted arrays": function (test) {
- var doc = new dom().parseFromString('HarryRonHermione'),
- path = xpath.parse("/*/*[3] | /*/*[2] | /*/*[1]")
- nset = path.evaluateNodeSet({ node: doc }),
- sorted = nset.toArray(),
- unsorted = nset.toUnsortedArray();
-
- assert.equal(sorted.length, 3);
- assert.equal(unsorted.length, 3);
-
- assert.equal(sorted[0].textContent, 'Harry');
- assert.equal(sorted[1].textContent, 'Ron');
- assert.equal(sorted[2].textContent, 'Hermione');
-
- assert.notEqual(sorted[0], unsorted[0], "first nodeset element equal");
-
- test.done();
- }
-
- ,'meaningful error for invalid function': function(test) {
- var path = xpath.parse('invalidFunc()');
-
- assert.throws(function () {
- path.evaluateString();
- }, function (err) {
- return err.message.indexOf('invalidFunc') !== -1;
+ assert.equal('title', nodes[0].localName);
+ assert.equal('Harry Potter', nodes[0].firstChild.data);
+ assert.equal('Harry Potter', nodes[0].toString());
});
-
- var path2 = xpath.parse('funcs:invalidFunc()');
-
- assert.throws(function () {
- path2.evaluateString({
+
+ it('should support .select()', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
+ var nodes = xpath.select('//title', doc);
+ assert.equal('title', nodes[0].localName);
+ assert.equal('Harry Potter', nodes[0].firstChild.data);
+ assert.equal('Harry Potter', nodes[0].toString());
+
+ var nodes2 = xpath.select('//node()', doc);
+ assert.equal(7, nodes2.length);
+
+ var pis = xpath.select("/processing-instruction('series')", doc);
+ assert.equal(2, pis.length);
+ assert.equal('books="7"', pis[1].data);
+ });
+ });
+
+ describe('parsing', () => {
+ it('should detect unterminated string literals', () => {
+ function testUnterminated(path) {
+ assert.throws(function () {
+ xpath.evaluate('"hello');
+ }, function (err) {
+ return err.message.indexOf('Unterminated') !== -1;
+ });
+ }
+
+ testUnterminated('"Hello');
+ testUnterminated("'Hello");
+ testUnterminated('self::text() = "\""');
+ testUnterminated('"\""');
+ });
+ });
+
+ describe('.select()', () => {
+ it('should select single nodes', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
+
+ assert.equal('title', xpath.select('//title[1]', doc)[0].localName);
+ });
+
+ it('should select text nodes', () => {
+ var xml = 'HarryPotter';
+ var doc = new dom().parseFromString(xml);
+
+ assert.deepEqual('book', xpath.select('local-name(/book)', doc));
+ assert.deepEqual('Harry,Potter', xpath.select('//title/text()', doc).toString());
+ });
+
+ it('should select number values', () => {
+ var xml = 'HarryPotter';
+ var doc = new dom().parseFromString(xml);
+
+ assert.deepEqual(2, xpath.select('count(//title)', doc));
+ });
+
+ it('should select with namespaces', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
+
+ var nodes = xpath.select('//*[local-name(.)="title" and namespace-uri(.)="myns"]', doc);
+ assert.equal('title', nodes[0].localName);
+ assert.equal('myns', nodes[0].namespaceURI);
+
+ var nodes2 = xpath.select('/*/title', doc);
+
+ assert.equal(0, nodes2.length);
+ });
+
+ it('should select with namespaces, using a resolver', () => {
+ var xml = 'NarniaHarry PotterJKR';
+ var doc = new dom().parseFromString(xml);
+
+ var resolver = {
+ mappings: {
+ 'testns': 'http://example.com/test'
+ },
+ lookupNamespaceURI: function (prefix) {
+ return this.mappings[prefix];
+ }
+ };
+
+ var nodes = xpath.selectWithResolver('//testns:title/text()', doc, resolver);
+ assert.equal('Harry Potter', nodes[0].nodeValue);
+
+ assert.equal('JKR', xpath.selectWithResolver('//testns:field[@testns:type="author"]/text()', doc, resolver)[0].nodeValue);
+
+ var nodes2 = xpath.selectWithResolver('/*/testns:*', doc, resolver);
+
+ assert.equal(2, nodes2.length);
+ });
+
+ it('should select from xml with a default namespace, using a resolver', () => {
+ var xml = 'Harry PotterJKR';
+ var doc = new dom().parseFromString(xml);
+
+ var resolver = {
+ mappings: {
+ 'testns': 'http://example.com/test'
+ },
+ lookupNamespaceURI: function (prefix) {
+ return this.mappings[prefix];
+ }
+ }
+
+ var nodes = xpath.selectWithResolver('//testns:title/text()', doc, resolver);
+ assert.equal('Harry Potter', xpath.selectWithResolver('//testns:title/text()', doc, resolver)[0].nodeValue);
+ assert.equal('JKR', xpath.selectWithResolver('//testns:field[@type="author"]/text()', doc, resolver)[0].nodeValue);
+ });
+
+ it('should select with namespaces, prefixes different in xml and xpath, using a resolver', () => {
+ var xml = 'Harry PotterJKR';
+ var doc = new dom().parseFromString(xml);
+
+ var resolver = {
+ mappings: {
+ 'ns': 'http://example.com/test'
+ },
+ lookupNamespaceURI: function (prefix) {
+ return this.mappings[prefix];
+ }
+ }
+
+ var nodes = xpath.selectWithResolver('//ns:title/text()', doc, resolver);
+ assert.equal('Harry Potter', nodes[0].nodeValue);
+
+ assert.equal('JKR', xpath.selectWithResolver('//ns:field[@ns:type="author"]/text()', doc, resolver)[0].nodeValue);
+ });
+
+ it('should select with namespaces, using namespace mappings', () => {
+ var xml = 'Harry PotterJKR';
+ var doc = new dom().parseFromString(xml);
+ var select = xpath.useNamespaces({ 'testns': 'http://example.com/test' });
+
+ assert.equal('Harry Potter', select('//testns:title/text()', doc)[0].nodeValue);
+ assert.equal('JKR', select('//testns:field[@testns:type="author"]/text()', doc)[0].nodeValue);
+ });
+
+ it('should select attributes', () => {
+ var xml = '';
+ var doc = new dom().parseFromString(xml);
+
+ var author = xpath.select1('/author/@name', doc).value;
+ assert.equal('J. K. Rowling', author);
+ });
+ });
+
+ describe('selection', () => {
+ it('should select with multiple predicates', () => {
+ var xml = '';
+ var doc = new dom().parseFromString(xml);
+
+ var characters = xpath.select('/*/character[@sex = "M"][@age > 40]/@name', doc);
+
+ assert.equal(1, characters.length);
+ assert.equal('Snape', characters[0].textContent);
+ });
+
+ // https://github.com/goto100/xpath/issues/37
+ it('should select multiple attributes', () => {
+ var xml = '';
+ var doc = new dom().parseFromString(xml);
+
+ var authors = xpath.select('/authors/author/@name', doc);
+ assert.equal(2, authors.length);
+ assert.equal('J. K. Rowling', authors[0].value);
+
+ // https://github.com/goto100/xpath/issues/41
+ doc = new dom().parseFromString('');
+ var nodes = xpath.select("/chapters/chapter/@v", doc);
+ var values = nodes.map(function (n) { return n.value; });
+
+ assert.equal(3, values.length);
+ assert.equal("1", values[0]);
+ assert.equal("2", values[1]);
+ assert.equal("3", values[2]);
+ });
+
+ it('should compare string values of numbers with numbers', () => {
+ assert.ok(xpath.select1('"000" = 0'), '000');
+ assert.ok(xpath.select1('"45.0" = 45'), '45');
+ });
+
+ it('should correctly compare strings with booleans', () => {
+ // string should downcast to boolean
+ assert.equal(false, xpath.select1('"false" = false()'), '"false" = false()');
+ assert.equal(true, xpath.select1('"a" = true()'), '"a" = true()');
+ assert.equal(true, xpath.select1('"" = false()'), '"" = false()');
+ });
+
+ it('should evaluate local-name() and name() on processing instructions', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
+ var expectedName = 'book-record';
+ var localName = xpath.select('local-name(/processing-instruction())', doc);
+ var name = xpath.select('name(/processing-instruction())', doc);
+
+ assert.deepEqual(expectedName, localName, 'local-name() - "' + expectedName + '" !== "' + localName + '"');
+ assert.deepEqual(expectedName, name, 'name() - "' + expectedName + '" !== "' + name + '"');
+ });
+
+ it('should support substring-after()', () => {
+ var xml = 'Hermione';
+ var doc = new dom().parseFromString(xml);
+
+ var part = xpath.select('substring-after(/classmate, "Her")', doc);
+ assert.deepEqual('mione', part);
+ });
+
+ it('should support preceding:: on document fragments', () => {
+ var doc = new dom().parseFromString(''),
+ df = doc.createDocumentFragment(),
+ root = doc.createElement('book');
+
+ df.appendChild(root);
+
+ for (var i = 0; i < 10; i += 1) {
+ root.appendChild(doc.createElement('chapter'));
+ }
+
+ var chapter = xpath.select1("book/chapter[5]", df);
+
+ assert.ok(chapter, 'chapter');
+
+ assert.equal(xpath.select("count(preceding::chapter)", chapter), 4);
+ });
+
+ it('should allow getting sorted and unsorted arrays from nodesets', () => {
+ const doc = new dom().parseFromString('HarryRonHermione');
+ const path = xpath.parse("/*/*[3] | /*/*[2] | /*/*[1]");
+ const nset = path.evaluateNodeSet({ node: doc });
+ const sorted = nset.toArray();
+ const unsorted = nset.toUnsortedArray();
+
+ assert.equal(sorted.length, 3);
+ assert.equal(unsorted.length, 3);
+
+ assert.equal(sorted[0].textContent, 'Harry');
+ assert.equal(sorted[1].textContent, 'Ron');
+ assert.equal(sorted[2].textContent, 'Hermione');
+
+ assert.notEqual(sorted[0], unsorted[0], "first nodeset element equal");
+ });
+
+ it('should compare nodesets to nodesets (=)', () => {
+ var xml = '' +
+ 'HarryHermione' +
+ 'DracoCrabbe' +
+ 'LunaCho' +
+ '' +
+ 'HermioneLuna';
+
+ var doc = new dom().parseFromString(xml);
+ var houses = xpath.parse('/school/houses/house[student = /school/honorStudents/student]').select({ node: doc });
+
+ assert.equal(houses.length, 2);
+
+ var houseNames = houses.map(function (node) { return node.getAttribute('name'); }).sort();
+
+ assert.equal(houseNames[0], 'Gryffindor');
+ assert.equal(houseNames[1], 'Ravenclaw');
+ });
+
+ it('should compare nodesets to nodesets (>=)', () => {
+ var xml = '' +
+ 'HarryHermione' +
+ 'GoyleCrabbe' +
+ 'LunaCho' +
+ '' +
+ 'DADACharms' +
+ '';
+
+ var doc = new dom().parseFromString(xml);
+ var houses = xpath.parse('/school/houses/house[student/@level >= /school/courses/course/@minLevel]').select({ node: doc });
+
+ assert.equal(houses.length, 2);
+
+ var houseNames = houses.map(function (node) { return node.getAttribute('name'); }).sort();
+
+ assert.equal(houseNames[0], 'Gryffindor');
+ assert.equal(houseNames[1], 'Ravenclaw');
+ });
+
+ it('should support various inequality expressions on nodesets', () => {
+ var xml = "";
+ var doc = new dom().parseFromString(xml);
+
+ var options = { node: doc, variables: { theNumber: 3, theString: '3', theBoolean: true } };
+
+ var numberPaths = [
+ '/books/book[$theNumber <= @num]',
+ '/books/book[$theNumber < @num]',
+ '/books/book[$theNumber >= @num]',
+ '/books/book[$theNumber > @num]'
+ ];
+
+ var stringPaths = [
+ '/books/book[$theString <= @num]',
+ '/books/book[$theString < @num]',
+ '/books/book[$theString >= @num]',
+ '/books/book[$theString > @num]'
+ ];
+
+ var booleanPaths = [
+ '/books/book[$theBoolean <= @num]',
+ '/books/book[$theBoolean < @num]',
+ '/books/book[$theBoolean >= @num]',
+ '/books/book[$theBoolean > @num]'
+ ];
+
+ var lhsPaths = [
+ '/books/book[@num <= $theNumber]',
+ '/books/book[@num < $theNumber]'
+ ];
+
+ function countNodes(paths) {
+ return paths
+ .map(xpath.parse)
+ .map(function (path) { return path.select(options) })
+ .map(function (arr) { return arr.length; });
+ }
+
+ assert.deepEqual(countNodes(numberPaths), [5, 4, 3, 2], 'numbers');
+ assert.deepEqual(countNodes(stringPaths), [5, 4, 3, 2], 'strings');
+ assert.deepEqual(countNodes(booleanPaths), [7, 6, 1, 0], 'numbers');
+ assert.deepEqual(countNodes(lhsPaths), [3, 2], 'lhs');
+ });
+
+ it('should correctly evaluate context position', () => {
+ var doc = new dom().parseFromString("The boy who livedThe vanishing glassThe worst birthdayDobby's warningThe burrow");
+
+ var chapters = xpath.parse('/books/book/chapter[2]').select({ node: doc });
+
+ assert.equal(2, chapters.length);
+ assert.equal('The vanishing glass', chapters[0].textContent);
+ assert.equal("Dobby's warning", chapters[1].textContent);
+
+ var lastChapters = xpath.parse('/books/book/chapter[last()]').select({ node: doc });
+
+ assert.equal(2, lastChapters.length);
+ assert.equal('The vanishing glass', lastChapters[0].textContent);
+ assert.equal("The burrow", lastChapters[1].textContent);
+
+ var secondChapter = xpath.parse('(/books/book/chapter)[2]').select({ node: doc });
+
+ assert.equal(1, secondChapter.length);
+ assert.equal('The vanishing glass', chapters[0].textContent);
+
+ var lastChapter = xpath.parse('(/books/book/chapter)[last()]').select({ node: doc });
+
+ assert.equal(1, lastChapter.length);
+ assert.equal("The burrow", lastChapter[0].textContent);
+ });
+ });
+
+ describe('string()', () => {
+ it('should work with no arguments', () => {
+ var doc = new dom().parseFromString('Harry Potter');
+
+ var rootElement = xpath.select1('/book', doc);
+ assert.ok(rootElement, 'rootElement is null');
+
+ assert.equal('Harry Potter', xpath.select1('string()', doc));
+ });
+
+ it('should work on document fragments', () => {
+ var doc = new dom().parseFromString('');
+ var docFragment = doc.createDocumentFragment();
+
+ var el = doc.createElement("book");
+ docFragment.appendChild(el);
+
+ var testValue = "Harry Potter";
+
+ el.appendChild(doc.createTextNode(testValue));
+
+ assert.equal(testValue, xpath.select1("string()", docFragment));
+ });
+
+ it('should work correctly on boolean values', () => {
+ assert.equal('string', typeof xpath.select1('string(true())'));
+ assert.equal('string', typeof xpath.select1('string(false())'));
+ assert.equal('string', typeof xpath.select1('string(1 = 2)'));
+ assert.ok(xpath.select1('"true" = string(true())'), '"true" = string(true())');
+ });
+
+ it('should work correctly on numbers', () => {
+ assert.equal('string', typeof xpath.select1('string(45)'));
+ assert.ok(xpath.select1('"45" = string(45)'), '"45" = string(45)');
+ });
+ });
+
+ describe('type conversion', () => {
+ it('should convert strings to numbers correctly', () => {
+ assert.equal(45.2, xpath.select1('number("45.200")'));
+ assert.equal(55.0, xpath.select1('number("000055")'));
+ assert.equal(65.0, xpath.select1('number(" 65 ")'));
+
+ assert.equal(true, xpath.select1('"" != 0'), '"" != 0');
+ assert.equal(false, xpath.select1('"" = 0'), '"" = 0');
+ assert.equal(false, xpath.select1('0 = ""'), '0 = ""');
+ assert.equal(false, xpath.select1('0 = " "'), '0 = " "');
+
+ assert.ok(Number.isNaN(xpath.select('number("")')), 'number("")');
+ assert.ok(Number.isNaN(xpath.select('number("45.8g")')), 'number("45.8g")');
+ assert.ok(Number.isNaN(xpath.select('number("2e9")')), 'number("2e9")');
+ assert.ok(Number.isNaN(xpath.select('number("+33")')), 'number("+33")');
+ });
+
+ it('should convert numbers to strings correctly', () => {
+ assert.equal('0.0000000000000000000000005250000000000001', xpath.parse('0.525 div 1000000 div 1000000 div 1000000 div 1000000').evaluateString());
+ assert.equal('525000000000000000000000', xpath.parse('0.525 * 1000000 * 1000000 * 1000000 * 1000000').evaluateString());
+ });
+
+ it('should provide correct string value for cdata sections', () => {
+ const xml = "Ron ";
+ const doc = new dom().parseFromString(xml);
+
+ const person1 = xpath.parse("/people/person").evaluateString({ node: doc });
+ const person2 = xpath.parse("/people/person/text()").evaluateString({ node: doc });
+ const person3 = xpath.select("string(/people/person/text())", doc);
+ const person4 = xpath.parse("/people/person[2]").evaluateString({ node: doc });
+
+ assert.equal(person1, 'Harry Potter');
+ assert.equal(person2, 'Harry Potter');
+ assert.equal(person3, 'Harry Potter');
+ assert.equal(person4, 'Ron Weasley');
+ });
+
+ it('should convert various node types to string values', () => {
+ var xml = "Harry Potter",
+ doc = new dom().parseFromString(xml),
+ allText = xpath.parse('.').evaluateString({ node: doc }),
+ ns = xpath.parse('*/namespace::*[name() = "hp"]').evaluateString({ node: doc }),
+ title = xpath.parse('*/title').evaluateString({ node: doc }),
+ child = xpath.parse('*/*').evaluateString({ node: doc }),
+ titleLang = xpath.parse('*/*/@lang').evaluateString({ node: doc }),
+ pi = xpath.parse('*/processing-instruction()').evaluateString({ node: doc }),
+ comment = xpath.parse('*/comment()').evaluateString({ node: doc });
+
+ assert.equal(allText, "Harry Potter & the Philosopher's StoneHarry Potter");
+ assert.equal(ns, 'http://harry');
+ assert.equal(title, "Harry Potter & the Philosopher's Stone");
+ assert.equal(child, "Harry Potter & the Philosopher's Stone");
+ assert.equal(titleLang, 'en');
+ assert.equal(pi.trim(), "name='J.K. Rowling'");
+ assert.equal(comment, ' This describes the Harry Potter Book ');
+ });
+
+ it('should convert booleans to numbers correctly', () => {
+ var num = xpath.parse('"a" = "b"').evaluateNumber();
+
+ assert.equal(num, 0);
+
+ var str = xpath.select('substring("expelliarmus", 1, "a" = "a")');
+
+ assert.equal(str, 'e');
+ });
+ });
+
+ describe('parsed expressions', () => {
+ it('should work with no options', () => {
+ var parsed = xpath.parse('5 + 7');
+
+ assert.equal(typeof parsed, "object", "parse() should return an object");
+ assert.equal(typeof parsed.evaluate, "function", "parsed.evaluate should be a function");
+ assert.equal(typeof parsed.evaluateNumber, "function", "parsed.evaluateNumber should be a function");
+
+ assert.equal(parsed.evaluateNumber(), 12);
+
+ // evaluating twice should yield the same result
+ assert.equal(parsed.evaluateNumber(), 12);
+ });
+
+ it('should support select1()', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
+ var parsed = xpath.parse('/*/title');
+
+ assert.equal(typeof parsed, 'object', 'parse() should return an object');
+
+ assert.equal(typeof parsed.select1, 'function', 'parsed.select1 should be a function');
+
+ var single = parsed.select1({ node: doc });
+
+ assert.equal('title', single.localName);
+ assert.equal('Harry Potter', single.firstChild.data);
+ assert.equal('Harry Potter', single.toString());
+ });
+
+ it('should support select()', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
+ var parsed = xpath.parse('/*/title');
+
+ assert.equal(typeof parsed, 'object', 'parse() should return an object');
+
+ assert.equal(typeof parsed.select, 'function', 'parsed.select should be a function');
+
+ var nodes = parsed.select({ node: doc });
+
+ assert.ok(nodes, 'parsed.select() should return a value');
+ assert.equal(1, nodes.length);
+ assert.equal('title', nodes[0].localName);
+ assert.equal('Harry Potter', nodes[0].firstChild.data);
+ assert.equal('Harry Potter', nodes[0].toString());
+ });
+
+ it('should support .evaluateString() and .evaluateNumber()', () => {
+ var xml = 'Harry Potter7';
+ var doc = new dom().parseFromString(xml);
+ var parsed = xpath.parse('/*/numVolumes');
+
+ assert.equal(typeof parsed, 'object', 'parse() should return an object');
+
+ assert.equal(typeof parsed.evaluateString, 'function', 'parsed.evaluateString should be a function');
+ assert.equal('7', parsed.evaluateString({ node: doc }));
+
+ assert.equal(typeof parsed.evaluateBoolean, 'function', 'parsed.evaluateBoolean should be a function');
+ assert.equal(true, parsed.evaluateBoolean({ node: doc }));
+
+ assert.equal(typeof parsed.evaluateNumber, 'function', 'parsed.evaluateNumber should be a function');
+ assert.equal(7, parsed.evaluateNumber({ node: doc }));
+ });
+
+ it('should support .evaluateBoolean()', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
+ var context = { node: doc };
+
+ function evaluate(path) {
+ return xpath.parse(path).evaluateBoolean(context);
+ }
+
+ assert.equal(false, evaluate('/*/myrtle'), 'boolean value of empty node set should be false');
+
+ assert.equal(true, evaluate('not(/*/myrtle)'), 'not() of empty nodeset should be true');
+
+ assert.equal(true, evaluate('/*/title'), 'boolean value of non-empty nodeset should be true');
+
+ assert.equal(true, evaluate('/*/title = "Harry Potter"'), 'title equals Harry Potter');
+
+ assert.equal(false, evaluate('/*/title != "Harry Potter"'), 'title != Harry Potter should be false');
+
+ assert.equal(false, evaluate('/*/title = "Percy Jackson"'), 'title should not equal Percy Jackson');
+ });
+
+ it('should support namespaces', () => {
+ var xml = '' +
+ 'QuirrellFluffy' +
+ 'MyrtleTom Riddle' +
+ '';
+ var doc = new dom().parseFromString(xml);
+
+ var expr = xpath.parse('/characters/c:character');
+ var countExpr = xpath.parse('count(/characters/c:character)');
+ var csns = 'http://chamber-secrets.com';
+
+ function resolve(prefix) {
+ if (prefix === 'c') {
+ return csns;
+ }
+ }
+
+ function testContext(context, description) {
+ try {
+ var value = expr.evaluateString(context);
+ var count = countExpr.evaluateNumber(context);
+
+ assert.equal('Myrtle', value, description + ' - string value - ' + value);
+ assert.equal(2, count, description + ' map - count - ' + count);
+ } catch (e) {
+ e.message = description + ': ' + (e.message || '');
+ throw e;
+ }
+ }
+
+ testContext({
+ node: doc,
namespaces: {
- funcs: 'myfunctions'
+ c: csns
}
- });
- }, function (err) {
- return err.message.indexOf('invalidFunc') !== -1;
+ }, 'Namespace map');
+
+ testContext({
+ node: doc,
+ namespaces: resolve
+ }, 'Namespace function');
+
+ testContext({
+ node: doc,
+ namespaces: {
+ getNamespace: resolve
+ }
+ }, 'Namespace object');
});
- test.done();
- }
-
- // https://github.com/goto100/xpath/issues/32
- ,'supports contains() function on attributes': function (test) {
- var doc = new dom().parseFromString(""),
- andTheBooks = xpath.select("/books/book[contains(@title, ' ')]", doc),
- secretBooks = xpath.select("/books/book[contains(@title, 'Secrets')]", doc);
-
- assert.equal(andTheBooks.length, 2);
- assert.equal(secretBooks.length, 1);
-
- test.done();
- }
-
- ,'compare multiple nodes to multiple nodes (equals)': function (test) {
- var xml = '' +
- 'HarryHermione' +
- 'DracoCrabbe' +
- 'LunaCho' +
- '' +
- 'HermioneLuna';
+ it('should support custom functions', () => {
+ var xml = 'Harry Potter';
+ var doc = new dom().parseFromString(xml);
- var doc = new dom().parseFromString(xml);
- var houses = xpath.parse('/school/houses/house[student = /school/honorStudents/student]').select({ node: doc });
+ var parsed = xpath.parse('concat(double(/*/title), " is cool")');
- assert.equal(houses.length, 2);
+ function doubleString(context, value) {
+ assert.equal(2, arguments.length);
+ var str = value.stringValue();
+ return str + str;
+ }
- var houseNames = houses.map(function (node) { return node.getAttribute('name'); }).sort();
+ function functions(name, namespace) {
+ if (name === 'double') {
+ return doubleString;
+ }
+ return null;
+ }
- assert.equal(houseNames[0], 'Gryffindor');
- assert.equal(houseNames[1], 'Ravenclaw');
-
- test.done();
- }
+ function testContext(context, description) {
+ try {
+ var actual = parsed.evaluateString(context);
+ var expected = 'Harry PotterHarry Potter is cool';
+ assert.equal(expected, actual, description + ' - ' + expected + ' != ' + actual);
+ } catch (e) {
+ e.message = description + ": " + (e.message || '');
+ throw e;
+ }
+ }
- ,'compare multiple nodes to multiple nodes (gte)': function (test) {
- var xml = '' +
- 'HarryHermione' +
- 'GoyleCrabbe' +
- 'LunaCho' +
- '' +
- 'DADACharms' +
- '';
+ testContext({
+ node: doc,
+ functions: functions
+ }, 'Functions function');
- var doc = new dom().parseFromString(xml);
- var houses = xpath.parse('/school/houses/house[student/@level >= /school/courses/course/@minLevel]').select({ node: doc });
+ testContext({
+ node: doc,
+ functions: {
+ getFunction: functions
+ }
+ }, 'Functions object');
- assert.equal(houses.length, 2);
+ testContext({
+ node: doc,
+ functions: {
+ double: doubleString
+ }
+ }, 'Functions map');
+ });
- var houseNames = houses.map(function (node) { return node.getAttribute('name'); }).sort();
+ it('should support custom functions in namespaces', () => {
+ var xml = 'Harry PotterRonHermioneNeville';
+ var doc = new dom().parseFromString(xml);
- assert.equal(houseNames[0], 'Gryffindor');
- assert.equal(houseNames[1], 'Ravenclaw');
-
- test.done();
- }
+ var parsed = xpath.parse('concat(hp:double(/*/title), " is 2 cool ", hp:square(2), " school")');
+ var hpns = 'http://harry-potter.com';
- ,'inequality comparisons with nodesets': function (test) {
- var xml = "";
- var doc = new dom().parseFromString(xml);
+ var namespaces = {
+ hp: hpns
+ };
- var options = { node: doc, variables: { theNumber: 3, theString: '3', theBoolean: true }};
+ var context = {
+ node: doc,
+ namespaces: {
+ hp: hpns
+ },
+ functions: function (name, namespace) {
+ if (namespace === hpns) {
+ switch (name) {
+ case "double":
+ return function (context, value) {
+ assert.equal(2, arguments.length);
+ var str = value.stringValue();
+ return str + str;
+ };
+ case "square":
+ return function (context, value) {
+ var num = value.numberValue();
+ return num * num;
+ };
- var numberPaths = [
- '/books/book[$theNumber <= @num]',
- '/books/book[$theNumber < @num]',
- '/books/book[$theNumber >= @num]',
- '/books/book[$theNumber > @num]'
- ];
+ case "xor":
+ return function (context, l, r) {
+ assert.equal(3, arguments.length);
+ var lbool = l.booleanValue();
+ var rbool = r.booleanValue();
+ return (lbool || rbool) && !(lbool && rbool);
+ };
- var stringPaths = [
- '/books/book[$theString <= @num]',
- '/books/book[$theString < @num]',
- '/books/book[$theString >= @num]',
- '/books/book[$theString > @num]'
- ];
+ case "second":
+ return function (context, nodes) {
+ var nodesArr = nodes.toArray();
+ var second = nodesArr[1];
+ return second ? [second] : [];
+ };
+ }
+ }
+ return null;
+ }
+ };
- var booleanPaths = [
- '/books/book[$theBoolean <= @num]',
- '/books/book[$theBoolean < @num]',
- '/books/book[$theBoolean >= @num]',
- '/books/book[$theBoolean > @num]'
- ];
+ assert.equal('Harry PotterHarry Potter is 2 cool 4 school', parsed.evaluateString(context));
- var lhsPaths = [
- '/books/book[@num <= $theNumber]',
- '/books/book[@num < $theNumber]'
- ];
+ assert.equal(false, xpath.parse('hp:xor(false(), false())').evaluateBoolean(context));
+ assert.equal(true, xpath.parse('hp:xor(false(), true())').evaluateBoolean(context));
+ assert.equal(true, xpath.parse('hp:xor(true(), false())').evaluateBoolean(context));
+ assert.equal(false, xpath.parse('hp:xor(true(), true())').evaluateBoolean(context));
- function countNodes(paths){
- return paths
- .map(xpath.parse)
- .map(function (path) { return path.select(options) })
- .map(function (arr) { return arr.length; });
- }
-
- assert.deepEqual(countNodes(numberPaths), [5, 4, 3, 2], 'numbers');
- assert.deepEqual(countNodes(stringPaths), [5, 4, 3, 2], 'strings');
- assert.deepEqual(countNodes(booleanPaths), [7, 6, 1, 0], 'numbers');
- assert.deepEqual(countNodes(lhsPaths), [3, 2], 'lhs');
-
- test.done();
- }
+ assert.equal('Hermione', xpath.parse('hp:second(/*/friend)').evaluateString(context));
+ assert.equal(1, xpath.parse('count(hp:second(/*/friend))').evaluateNumber(context));
+ assert.equal(0, xpath.parse('count(hp:second(/*/friendz))').evaluateNumber(context));
+ });
- ,'error when evaluating boolean as number': function (test) {
- var num = xpath.parse('"a" = "b"').evaluateNumber();
-
- assert.equal(num, 0);
-
- var str = xpath.select('substring("expelliarmus", 1, "a" = "a")');
-
- assert.equal(str, 'e');
-
- test.done();
- }
-
- ,'string values of parsed expressions': function (test) {
- var parser = new xpath.XPathParser();
+ it('should support xpath variables', () => {
+ var xml = 'Harry Potter7';
+ var doc = new dom().parseFromString(xml);
- var simpleStep = parser.parse('my:book');
+ var variables = {
+ title: 'Harry Potter',
+ notTitle: 'Percy Jackson',
+ houses: 4
+ };
- assert.equal(simpleStep.toString(), 'child::my:book');
+ function variableFunction(name) {
+ return variables[name];
+ }
- var precedingSib = parser.parse('preceding-sibling::my:chapter');
+ function testContext(context, description) {
+ try {
+ assert.equal(true, xpath.parse('$title = /*/title').evaluateBoolean(context));
+ assert.equal(false, xpath.parse('$notTitle = /*/title').evaluateBoolean(context));
+ assert.equal(11, xpath.parse('$houses + /*/volumes').evaluateNumber(context));
+ } catch (e) {
+ e.message = description + ": " + (e.message || '');
+ throw e;
+ }
+ }
- assert.equal(precedingSib.toString(), 'preceding-sibling::my:chapter');
+ testContext({
+ node: doc,
+ variables: variableFunction
+ }, 'Variables function');
- var withPredicates = parser.parse('book[number > 3][contains(title, "and the")]');
+ testContext({
+ node: doc,
+ variables: {
+ getVariable: variableFunction
+ }
+ }, 'Variables object');
- assert.equal(withPredicates.toString(), "child::book[(child::number > 3)][contains(child::title, 'and the')]");
+ testContext({
+ node: doc,
+ variables: variables
+ }, 'Variables map');
- var parenthesisWithPredicate = parser.parse('(/books/book/chapter)[7]');
-
- assert.equal(parenthesisWithPredicate.toString(), '(/child::books/child::book/child::chapter)[7]');
+ });
- var charactersOver20 = parser.parse('heroes[age > 20] | villains[age > 20]');
-
- assert.equal(charactersOver20.toString(), 'child::heroes[(child::age > 20)] | child::villains[(child::age > 20)]');
-
- test.done();
- }
-
- ,'context position should work correctly': function (test) {
- var doc = new dom().parseFromString("The boy who livedThe vanishing glassThe worst birthdayDobby's warningThe burrow");
-
- var chapters = xpath.parse('/books/book/chapter[2]').select({ node: doc });
-
- assert.equal(2, chapters.length);
- assert.equal('The vanishing glass', chapters[0].textContent);
- assert.equal("Dobby's warning", chapters[1].textContent);
+ it('should support variables with namespaces', () => {
+ var xml = 'Harry Potter7';
+ var doc = new dom().parseFromString(xml);
+ var hpns = 'http://harry-potter.com';
- var lastChapters = xpath.parse('/books/book/chapter[last()]').select({ node: doc });
-
- assert.equal(2, lastChapters.length);
- assert.equal('The vanishing glass', lastChapters[0].textContent);
- assert.equal("The burrow", lastChapters[1].textContent);
+ var context = {
+ node: doc,
+ namespaces: {
+ hp: hpns
+ },
+ variables: function (name, namespace) {
+ if (namespace === hpns) {
+ switch (name) {
+ case 'title': return 'Harry Potter';
+ case 'houses': return 4;
+ case 'false': return false;
+ case 'falseStr': return 'false';
+ }
+ } else if (namespace === '') {
+ switch (name) {
+ case 'title': return 'World';
+ }
+ }
- var secondChapter = xpath.parse('(/books/book/chapter)[2]').select({ node: doc });
-
- assert.equal(1, secondChapter.length);
- assert.equal('The vanishing glass', chapters[0].textContent);
+ return null;
+ }
+ };
- var lastChapter = xpath.parse('(/books/book/chapter)[last()]').select({ node: doc });
-
- assert.equal(1, lastChapter.length);
- assert.equal("The burrow", lastChapter[0].textContent);
+ assert.equal(true, xpath.parse('$hp:title = /*/title').evaluateBoolean(context));
+ assert.equal(false, xpath.parse('$title = /*/title').evaluateBoolean(context));
+ assert.equal('World', xpath.parse('$title').evaluateString(context));
+ assert.equal(false, xpath.parse('$hp:false').evaluateBoolean(context));
+ assert.notEqual(false, xpath.parse('$hp:falseStr').evaluateBoolean(context));
+ assert.throws(function () {
+ xpath.parse('$hp:hello').evaluateString(context);
+ }, function (err) {
+ return err.message === 'Undeclared variable: $hp:hello';
+ });
+ });
-
- test.done();
- }
-
- ,'should allow null namespaces for null prefixes': function (test) {
- var markup = 'Hi Ron!
Hi Draco!
Hi Hermione!
';
- var docHtml = new dom().parseFromString(markup, 'text/html');
-
- var noPrefixPath = xpath.parse('/html/body/p[2]');
-
- var greetings1 = noPrefixPath.select({ node: docHtml, allowAnyNamespaceForNoPrefix: false });
-
- assert.equal(0, greetings1.length);
-
- var allowAnyNamespaceOptions = { node: docHtml, allowAnyNamespaceForNoPrefix: true };
-
- // if allowAnyNamespaceForNoPrefix specified, allow using prefix-less node tests to match nodes with no prefix
- var greetings2 = noPrefixPath.select(allowAnyNamespaceOptions);
-
- assert.equal(1, greetings2.length);
- assert.equal('Hi Hermione!', greetings2[0].textContent);
+ it('should support .toString()', () => {
+ var parser = new xpath.XPathParser();
- var allGreetings = xpath.parse('/html/body/p').select(allowAnyNamespaceOptions);
-
- assert.equal(2, allGreetings.length);
-
- var nsm = { html: xhtmlNs, other: 'http://www.example.com/other' };
-
- var prefixPath = xpath.parse('/html:html/body/html:p');
- var optionsWithNamespaces = { node: docHtml, allowAnyNamespaceForNoPrefix: true, namespaces: nsm };
-
- // if the path uses prefixes, they have to match
- var greetings3 = prefixPath.select(optionsWithNamespaces);
-
- assert.equal(2, greetings3.length);
-
- var badPrefixPath = xpath.parse('/html:html/other:body/html:p');
-
- var greetings4 = badPrefixPath.select(optionsWithNamespaces);
-
- test.done();
- }
-
- ,'support isHtml option' : function (test){
- var markup = 'Hi Ron!
Hi Draco!Hi Hermione!
';
- var docHtml = new dom().parseFromString(markup, 'text/html');
-
- var ns = { h: xhtmlNs };
-
- // allow matching on unprefixed nodes
- var greetings1 = xpath.parse('/html/body/p').select({ node: docHtml, isHtml: true });
-
- assert.equal(2, greetings1.length);
-
- // allow case insensitive match
- var greetings2 = xpath.parse('/h:html/h:bOdY/h:p').select({ node: docHtml, namespaces: ns, isHtml: true });
-
- assert.equal(2, greetings2.length);
-
- // non-html mode: allow select if case and namespaces match
- var greetings3 = xpath.parse('/h:html/h:body/h:p').select({ node: docHtml, namespaces: ns });
+ var simpleStep = parser.parse('my:book');
- assert.equal(2, greetings3.length);
-
- // non-html mode: require namespaces
- var greetings4 = xpath.parse('/html/body/p').select({ node: docHtml, namespaces: ns });
+ assert.equal(simpleStep.toString(), 'child::my:book');
- assert.equal(0, greetings4.length);
-
- // non-html mode: require case to match
- var greetings5 = xpath.parse('/h:html/h:bOdY/h:p').select({ node: docHtml, namespaces: ns });
+ var precedingSib = parser.parse('preceding-sibling::my:chapter');
- assert.equal(0, greetings5.length);
-
- test.done();
- }
-
- ,"builtin functions": function (test) {
- var translated = xpath.parse('translate("hello", "lhho", "yHb")').evaluateString();
-
- assert.equal('Heyy', translated);
-
- var characters = new dom().parseFromString('HarryRonHermione');
-
- var firstTwo = xpath.parse('/characters/character[position() <= 2]').select({ node: characters });
-
- assert.equal(2, firstTwo.length);
- assert.equal('Harry', firstTwo[0].textContent);
- assert.equal('Ron', firstTwo[1].textContent);
+ assert.equal(precedingSib.toString(), 'preceding-sibling::my:chapter');
- var last = xpath.parse('/characters/character[last()]').select({ node: characters });
-
- assert.equal(1, last.length);
- assert.equal('Hermione', last[0].textContent);
-
- test.done();
- }
-}
+ var withPredicates = parser.parse('book[number > 3][contains(title, "and the")]');
+
+ assert.equal(withPredicates.toString(), "child::book[(child::number > 3)][contains(child::title, 'and the')]");
+
+ var parenthesisWithPredicate = parser.parse('(/books/book/chapter)[7]');
+
+ assert.equal(parenthesisWithPredicate.toString(), '(/child::books/child::book/child::chapter)[7]');
+
+ var charactersOver20 = parser.parse('heroes[age > 20] | villains[age > 20]');
+
+ assert.equal(charactersOver20.toString(), 'child::heroes[(child::age > 20)] | child::villains[(child::age > 20)]');
+ });
+ });
+
+ describe('html-mode support', () => {
+ it('should allow null namespaces for nodes with no prefix', () => {
+ var markup = `
+
+
+ Hi Ron!
+ Hi Draco!
+ Hi Hermione!
+
+ `;
+
+ var docHtml = new dom().parseFromString(markup, 'text/html');
+
+ var noPrefixPath = xpath.parse('/html/body/p[2]');
+
+ var greetings1 = noPrefixPath.select({ node: docHtml, allowAnyNamespaceForNoPrefix: false });
+
+ assert.equal(0, greetings1.length);
+
+ var allowAnyNamespaceOptions = { node: docHtml, allowAnyNamespaceForNoPrefix: true };
+
+ // if allowAnyNamespaceForNoPrefix specified, allow using prefix-less node tests to match nodes with no prefix
+ var greetings2 = noPrefixPath.select(allowAnyNamespaceOptions);
+
+ assert.equal(1, greetings2.length);
+ assert.equal('Hi Hermione!', greetings2[0].textContent);
+
+ var allGreetings = xpath.parse('/html/body/p').select(allowAnyNamespaceOptions);
+
+ assert.equal(2, allGreetings.length);
+
+ var nsm = { html: xhtmlNs, other: 'http://www.example.com/other' };
+
+ var prefixPath = xpath.parse('/html:html/body/html:p');
+ var optionsWithNamespaces = { node: docHtml, allowAnyNamespaceForNoPrefix: true, namespaces: nsm };
+
+ // if the path uses prefixes, they have to match
+ var greetings3 = prefixPath.select(optionsWithNamespaces);
+
+ assert.equal(2, greetings3.length);
+
+ var badPrefixPath = xpath.parse('/html:html/other:body/html:p');
+
+ var greetings4 = badPrefixPath.select(optionsWithNamespaces);
+
+ assert.strictEqual(0, greetings4.length);
+ });
+
+ it('should support the isHtml option', () => {
+ var markup = 'Hi Ron!
Hi Draco!Hi Hermione!
';
+ var docHtml = new dom().parseFromString(markup, 'text/html');
+
+ var ns = { h: xhtmlNs };
+
+ // allow matching on unprefixed nodes
+ var greetings1 = xpath.parse('/html/body/p').select({ node: docHtml, isHtml: true });
+
+ assert.equal(2, greetings1.length);
+
+ // allow case insensitive match
+ var greetings2 = xpath.parse('/h:html/h:bOdY/h:p').select({ node: docHtml, namespaces: ns, isHtml: true });
+
+ assert.equal(2, greetings2.length);
+
+ // non-html mode: allow select if case and namespaces match
+ var greetings3 = xpath.parse('/h:html/h:body/h:p').select({ node: docHtml, namespaces: ns });
+
+ assert.equal(2, greetings3.length);
+
+ // non-html mode: require namespaces
+ var greetings4 = xpath.parse('/html/body/p').select({ node: docHtml, namespaces: ns });
+
+ assert.equal(0, greetings4.length);
+
+ // non-html mode: require case to match
+ var greetings5 = xpath.parse('/h:html/h:bOdY/h:p').select({ node: docHtml, namespaces: ns });
+
+ assert.equal(0, greetings5.length);
+ });
+ });
+
+ describe('functions', () => {
+ it('should provide a meaningful error for invalid functions', () => {
+ var path = xpath.parse('invalidFunc()');
+
+ assert.throws(function () {
+ path.evaluateString();
+ }, function (err) {
+ return err.message.indexOf('invalidFunc') !== -1;
+ });
+
+ var path2 = xpath.parse('funcs:invalidFunc()');
+
+ assert.throws(function () {
+ path2.evaluateString({
+ namespaces: {
+ funcs: 'myfunctions'
+ }
+ });
+ }, function (err) {
+ return err.message.indexOf('invalidFunc') !== -1;
+ });
+ });
+
+ // https://github.com/goto100/xpath/issues/32
+ it('should support the contains() function on attributes', () => {
+ var doc = new dom().parseFromString(""),
+ andTheBooks = xpath.select("/books/book[contains(@title, ' ')]", doc),
+ secretBooks = xpath.select("/books/book[contains(@title, 'Secrets')]", doc);
+
+ assert.equal(andTheBooks.length, 2);
+ assert.equal(secretBooks.length, 1);
+ });
+
+ it('should support builtin functions', () => {
+ var translated = xpath.parse('translate("hello", "lhho", "yHb")').evaluateString();
+
+ assert.equal('Heyy', translated);
+
+ var characters = new dom().parseFromString('HarryRonHermione');
+
+ var firstTwo = xpath.parse('/characters/character[position() <= 2]').select({ node: characters });
+
+ assert.equal(2, firstTwo.length);
+ assert.equal('Harry', firstTwo[0].textContent);
+ assert.equal('Ron', firstTwo[1].textContent);
+
+ var last = xpath.parse('/characters/character[last()]').select({ node: characters });
+
+ assert.equal(1, last.length);
+ assert.equal('Hermione', last[0].textContent);
+ });
+ });
+
+ describe('miscellaneous', () => {
+ it('should create XPathExceptions that act like Errors', () => {
+ try {
+ xpath.evaluate('1', null, null, null);
+ assert.fail(null, null, 'evaluate() should throw exception');
+ } catch (e) {
+ assert.ok('code' in e, 'must have a code');
+ assert.ok('stack' in e, 'must have a stack');
+ }
+ });
+
+ it('should expose custom types', () => {
+ assert.ok(xpath.XPath, "xpath.XPath");
+ assert.ok(xpath.XPathParser, "xpath.XPathParser");
+ assert.ok(xpath.XPathResult, "xpath.XPathResult");
+
+ assert.ok(xpath.Step, "xpath.Step");
+ assert.ok(xpath.NodeTest, "xpath.NodeTest");
+ assert.ok(xpath.BarOperation, "xpath.BarOperation");
+
+ assert.ok(xpath.NamespaceResolver, "xpath.NamespaceResolver");
+ assert.ok(xpath.FunctionResolver, "xpath.FunctionResolver");
+ assert.ok(xpath.VariableResolver, "xpath.VariableResolver");
+
+ assert.ok(xpath.Utilities, "xpath.Utilities");
+
+ assert.ok(xpath.XPathContext, "xpath.XPathContext");
+ assert.ok(xpath.XNodeSet, "xpath.XNodeSet");
+ assert.ok(xpath.XBoolean, "xpath.XBoolean");
+ assert.ok(xpath.XString, "xpath.XString");
+ assert.ok(xpath.XNumber, "xpath.XNumber");
+ });
+
+ it('should work with nodes created using DOM1 createElement()', () => {
+ var doc = new dom().parseFromString('');
+
+ doc.documentElement.appendChild(doc.createElement('characters'));
+
+ assert.ok(xpath.select1('/book/characters', doc));
+
+ assert.equal(xpath.select1('local-name(/book/characters)', doc), 'characters');
+ });
+ });
+});
\ No newline at end of file
diff --git a/node_modules/xpath/xpath.d.ts b/node_modules/xpath/xpath.d.ts
index ac95996d..d774463f 100644
--- a/node_modules/xpath/xpath.d.ts
+++ b/node_modules/xpath/xpath.d.ts
@@ -1,9 +1,11 @@
+///
+
type SelectedValue = Node | Attr | string | number | boolean;
interface XPathSelect {
(expression: string, node?: Node): Array;
- (expression: string, node: Node, single: true): SelectedValue;
+ (expression: string, node: Node, single: true): SelectedValue | undefined;
}
export var select: XPathSelect;
-export function select1(expression: string, node?: Node): SelectedValue;
-export function evaluate(expression: string, contextNode: Node, resolver: XPathNSResolver, type: number, result: XPathResult): XPathResult;
+export function select1(expression: string, node?: Node): SelectedValue | undefined;
+export function evaluate(expression: string, contextNode: Node, resolver: XPathNSResolver | null, type: number, result: XPathResult | null): XPathResult;
export function useNamespaces(namespaceMap: { [name: string]: string }): XPathSelect;
diff --git a/node_modules/xpath/xpath.js b/node_modules/xpath/xpath.js
index 02732c02..babd1298 100644
--- a/node_modules/xpath/xpath.js
+++ b/node_modules/xpath/xpath.js
@@ -14,7 +14,7 @@
* Revision 19: November 29, 2005
* Nodesets now store their nodes in a height balanced tree, increasing
* performance for the common case of selecting nodes in document order,
- * thanks to Sé–Žastien Cramatte .
+ * thanks to Sébastien Cramatte .
* AVL tree code adapted from Raimund Neumann .
*
* Revision 18: October 27, 2005
@@ -26,7 +26,7 @@
* Revision 17: October 25, 2005
* Some core XPath function fixes and a patch to avoid crashing certain
* versions of MSXML in PathExpr.prototype.getOwnerElement, thanks to
- * Sé–Žastien Cramatte .
+ * Sébastien Cramatte .
*
* Revision 16: September 22, 2005
* Workarounds for some IE 5.5 deficiencies.
@@ -98,4667 +98,4704 @@
// non-node wrapper
var xpath = (typeof exports === 'undefined') ? {} : exports;
-(function(exports) {
-"use strict";
+(function (exports) {
+ "use strict";
-// functional helpers
-function curry( func ) {
- var slice = Array.prototype.slice,
- totalargs = func.length,
- partial = function( args, fn ) {
- return function( ) {
- return fn.apply( this, args.concat( slice.call( arguments ) ) );
- }
- },
- fn = function( ) {
- var args = slice.call( arguments );
- return ( args.length < totalargs ) ?
- partial( args, fn ) :
- func.apply( this, slice.apply( arguments, [ 0, totalargs ] ) );
- };
- return fn;
-}
+ // functional helpers
+ function curry(func) {
+ var slice = Array.prototype.slice,
+ totalargs = func.length,
+ partial = function (args, fn) {
+ return function () {
+ return fn.apply(this, args.concat(slice.call(arguments)));
+ }
+ },
+ fn = function () {
+ var args = slice.call(arguments);
+ return (args.length < totalargs) ?
+ partial(args, fn) :
+ func.apply(this, slice.apply(arguments, [0, totalargs]));
+ };
+ return fn;
+ }
-var forEach = curry(function (f, xs) {
- for (var i = 0; i < xs.length; i += 1) {
- f(xs[i], i, xs);
- }
-});
-
-var reduce = curry(function (f, seed, xs) {
- var acc = seed;
-
- forEach(function (x, i) { acc = f(acc, x, i); }, xs);
-
- return acc;
-});
-
-var map = curry(function (f, xs) {
- var mapped = new Array(xs.length);
-
- forEach(function (x, i) { mapped[i] = f(x); }, xs);
-
- return mapped;
-});
-
-var filter = curry(function (f, xs) {
- var filtered = [];
-
- forEach(function (x, i) { if(f(x, i)) { filtered.push(x); } }, xs);
-
- return filtered;
-});
-
-function compose() {
- if (arguments.length === 0) { throw new Error('compose requires at least one argument'); }
-
- var funcs = Array.prototype.slice.call(arguments).reverse();
-
- var f0 = funcs[0];
- var fRem = funcs.slice(1);
-
- return function () {
- return reduce(function (acc, next) {
- return next(acc);
- }, f0.apply(null, arguments), fRem);
+ var forEach = function (f, xs) {
+ for (var i = 0; i < xs.length; i += 1) {
+ f(xs[i], i, xs);
+ }
};
-}
-var includes = curry(function (values, value) {
- for (var i = 0; i < values.length; i += 1) {
- if (values[i] === value){
- return true;
- }
- }
-
- return false;
-});
+ var reduce = function (f, seed, xs) {
+ var acc = seed;
-function always(value) { return function () { return value ;} }
+ forEach(function (x, i) { acc = f(acc, x, i); }, xs);
-var prop = curry(function (name, obj) { return obj[name]; });
+ return acc;
+ };
-function toString (x) { return x.toString(); }
-var join = curry(function (s, xs) { return xs.join(s); });
-var wrap = curry(function (pref, suf, str) { return pref + str + suf; });
+ var map = function (f, xs) {
+ var mapped = new Array(xs.length);
-function assign(target) { // .length of function is 2
- var to = Object(target);
+ forEach(function (x, i) { mapped[i] = f(x); }, xs);
- for (var index = 1; index < arguments.length; index++) {
- var nextSource = arguments[index];
+ return mapped;
+ };
- if (nextSource != null) { // Skip over if undefined or null
- for (var nextKey in nextSource) {
- // Avoid bugs when hasOwnProperty is shadowed
- if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
- to[nextKey] = nextSource[nextKey];
+ var filter = function (f, xs) {
+ var filtered = [];
+
+ forEach(function (x, i) { if (f(x, i)) { filtered.push(x); } }, xs);
+
+ return filtered;
+ };
+
+ var includes = function (values, value) {
+ for (var i = 0; i < values.length; i += 1) {
+ if (values[i] === value) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ function always(value) { return function () { return value; } }
+
+ function toString(x) { return x.toString(); }
+ var join = function (s, xs) { return xs.join(s); };
+ var wrap = function (pref, suf, str) { return pref + str + suf; };
+
+ var prototypeConcat = Array.prototype.concat;
+
+ function flatten(arr) {
+ return prototypeConcat.apply([], arr);
+ }
+
+ function assign(target, varArgs) { // .length of function is 2
+ var to = Object(target);
+
+ for (var index = 1; index < arguments.length; index++) {
+ var nextSource = arguments[index];
+
+ if (nextSource != null) { // Skip over if undefined or null
+ for (var nextKey in nextSource) {
+ // Avoid bugs when hasOwnProperty is shadowed
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
+ to[nextKey] = nextSource[nextKey];
+ }
}
}
}
+
+ return to;
}
- return to;
-}
+ // XPathParser ///////////////////////////////////////////////////////////////
-// XPathParser ///////////////////////////////////////////////////////////////
+ XPathParser.prototype = new Object();
+ XPathParser.prototype.constructor = XPathParser;
+ XPathParser.superclass = Object.prototype;
-XPathParser.prototype = new Object();
-XPathParser.prototype.constructor = XPathParser;
-XPathParser.superclass = Object.prototype;
+ function XPathParser() {
+ this.init();
+ }
-function XPathParser() {
- this.init();
-}
+ XPathParser.prototype.init = function () {
+ this.reduceActions = [];
-XPathParser.prototype.init = function() {
- this.reduceActions = [];
-
- this.reduceActions[3] = function(rhs) {
- return new OrOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[5] = function(rhs) {
- return new AndOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[7] = function(rhs) {
- return new EqualsOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[8] = function(rhs) {
- return new NotEqualOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[10] = function(rhs) {
- return new LessThanOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[11] = function(rhs) {
- return new GreaterThanOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[12] = function(rhs) {
- return new LessThanOrEqualOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[13] = function(rhs) {
- return new GreaterThanOrEqualOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[15] = function(rhs) {
- return new PlusOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[16] = function(rhs) {
- return new MinusOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[18] = function(rhs) {
- return new MultiplyOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[19] = function(rhs) {
- return new DivOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[20] = function(rhs) {
- return new ModOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[22] = function(rhs) {
- return new UnaryMinusOperation(rhs[1]);
- };
- this.reduceActions[24] = function(rhs) {
- return new BarOperation(rhs[0], rhs[2]);
- };
- this.reduceActions[25] = function(rhs) {
- return new PathExpr(undefined, undefined, rhs[0]);
- };
- this.reduceActions[27] = function(rhs) {
- rhs[0].locationPath = rhs[2];
- return rhs[0];
- };
- this.reduceActions[28] = function(rhs) {
- rhs[0].locationPath = rhs[2];
- rhs[0].locationPath.steps.unshift(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
- return rhs[0];
- };
- this.reduceActions[29] = function(rhs) {
- return new PathExpr(rhs[0], [], undefined);
- };
- this.reduceActions[30] = function(rhs) {
- if (Utilities.instance_of(rhs[0], PathExpr)) {
- if (rhs[0].filterPredicates == undefined) {
- rhs[0].filterPredicates = [];
- }
- rhs[0].filterPredicates.push(rhs[1]);
- return rhs[0];
- } else {
- return new PathExpr(rhs[0], [rhs[1]], undefined);
- }
- };
- this.reduceActions[32] = function(rhs) {
- return rhs[1];
- };
- this.reduceActions[33] = function(rhs) {
- return new XString(rhs[0]);
- };
- this.reduceActions[34] = function(rhs) {
- return new XNumber(rhs[0]);
- };
- this.reduceActions[36] = function(rhs) {
- return new FunctionCall(rhs[0], []);
- };
- this.reduceActions[37] = function(rhs) {
- return new FunctionCall(rhs[0], rhs[2]);
- };
- this.reduceActions[38] = function(rhs) {
- return [ rhs[0] ];
- };
- this.reduceActions[39] = function(rhs) {
- rhs[2].unshift(rhs[0]);
- return rhs[2];
- };
- this.reduceActions[43] = function(rhs) {
- return new LocationPath(true, []);
- };
- this.reduceActions[44] = function(rhs) {
- rhs[1].absolute = true;
- return rhs[1];
- };
- this.reduceActions[46] = function(rhs) {
- return new LocationPath(false, [ rhs[0] ]);
- };
- this.reduceActions[47] = function(rhs) {
- rhs[0].steps.push(rhs[2]);
- return rhs[0];
- };
- this.reduceActions[49] = function(rhs) {
- return new Step(rhs[0], rhs[1], []);
- };
- this.reduceActions[50] = function(rhs) {
- return new Step(Step.CHILD, rhs[0], []);
- };
- this.reduceActions[51] = function(rhs) {
- return new Step(rhs[0], rhs[1], rhs[2]);
- };
- this.reduceActions[52] = function(rhs) {
- return new Step(Step.CHILD, rhs[0], rhs[1]);
- };
- this.reduceActions[54] = function(rhs) {
- return [ rhs[0] ];
- };
- this.reduceActions[55] = function(rhs) {
- rhs[1].unshift(rhs[0]);
- return rhs[1];
- };
- this.reduceActions[56] = function(rhs) {
- if (rhs[0] == "ancestor") {
- return Step.ANCESTOR;
- } else if (rhs[0] == "ancestor-or-self") {
- return Step.ANCESTORORSELF;
- } else if (rhs[0] == "attribute") {
- return Step.ATTRIBUTE;
- } else if (rhs[0] == "child") {
- return Step.CHILD;
- } else if (rhs[0] == "descendant") {
- return Step.DESCENDANT;
- } else if (rhs[0] == "descendant-or-self") {
- return Step.DESCENDANTORSELF;
- } else if (rhs[0] == "following") {
- return Step.FOLLOWING;
- } else if (rhs[0] == "following-sibling") {
- return Step.FOLLOWINGSIBLING;
- } else if (rhs[0] == "namespace") {
- return Step.NAMESPACE;
- } else if (rhs[0] == "parent") {
- return Step.PARENT;
- } else if (rhs[0] == "preceding") {
- return Step.PRECEDING;
- } else if (rhs[0] == "preceding-sibling") {
- return Step.PRECEDINGSIBLING;
- } else if (rhs[0] == "self") {
- return Step.SELF;
- }
- return -1;
- };
- this.reduceActions[57] = function(rhs) {
- return Step.ATTRIBUTE;
- };
- this.reduceActions[59] = function(rhs) {
- if (rhs[0] == "comment") {
- return NodeTest.commentTest;
- } else if (rhs[0] == "text") {
- return NodeTest.textTest;
- } else if (rhs[0] == "processing-instruction") {
- return NodeTest.anyPiTest;
- } else if (rhs[0] == "node") {
- return NodeTest.nodeTest;
- }
- return new NodeTest(-1, undefined);
- };
- this.reduceActions[60] = function(rhs) {
- return new NodeTest.PITest(rhs[2]);
- };
- this.reduceActions[61] = function(rhs) {
- return rhs[1];
- };
- this.reduceActions[63] = function(rhs) {
- rhs[1].absolute = true;
- rhs[1].steps.unshift(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
- return rhs[1];
- };
- this.reduceActions[64] = function(rhs) {
- rhs[0].steps.push(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
- rhs[0].steps.push(rhs[2]);
- return rhs[0];
- };
- this.reduceActions[65] = function(rhs) {
- return new Step(Step.SELF, NodeTest.nodeTest, []);
- };
- this.reduceActions[66] = function(rhs) {
- return new Step(Step.PARENT, NodeTest.nodeTest, []);
- };
- this.reduceActions[67] = function(rhs) {
- return new VariableReference(rhs[1]);
- };
- this.reduceActions[68] = function(rhs) {
- return NodeTest.nameTestAny;
- };
- this.reduceActions[69] = function(rhs) {
- return new NodeTest.NameTestPrefixAny(rhs[0].split(':')[0]);
- };
- this.reduceActions[70] = function(rhs) {
- return new NodeTest.NameTestQName(rhs[0]);
- };
-};
-
-XPathParser.actionTable = [
- " s s sssssssss s ss s ss",
- " s ",
- "r rrrrrrrrr rrrrrrr rr r ",
- " rrrrr ",
- " s s sssssssss s ss s ss",
- "rs rrrrrrrr s sssssrrrrrr rrs rs ",
- " s s sssssssss s ss s ss",
- " s ",
- " s ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- " s ",
- " s ",
- " s s sssss s s ",
- "r rrrrrrrrr rrrrrrr rr r ",
- "a ",
- "r s rr r ",
- "r sr rr r ",
- "r s rr s rr r ",
- "r rssrr rss rr r ",
- "r rrrrr rrrss rr r ",
- "r rrrrrsss rrrrr rr r ",
- "r rrrrrrrr rrrrr rr r ",
- "r rrrrrrrr rrrrrs rr r ",
- "r rrrrrrrr rrrrrr rr r ",
- "r rrrrrrrr rrrrrr rr r ",
- "r srrrrrrrr rrrrrrs rr sr ",
- "r srrrrrrrr rrrrrrs rr r ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrr rrrrrr rr r ",
- "r rrrrrrrr rrrrrr rr r ",
- "r rrrrrrrrr rrrrrrr rr r ",
- "r rrrrrrrrr rrrrrrr rr r ",
- " sssss ",
- "r rrrrrrrrr rrrrrrr rr sr ",
- "r rrrrrrrrr rrrrrrr rr r ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- " s ",
- "r srrrrrrrr rrrrrrs rr r ",
- "r rrrrrrrr rrrrr rr r ",
- " s ",
- " s ",
- " rrrrr ",
- " s s sssssssss s sss s ss",
- "r srrrrrrrr rrrrrrs rr r ",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssssssss ss s ss",
- " s s sssssssss s ss s ss",
- " s s sssss s s ",
- " s s sssss s s ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- " s s sssss s s ",
- " s s sssss s s ",
- "r rrrrrrrrr rrrrrrr rr sr ",
- "r rrrrrrrrr rrrrrrr rr sr ",
- "r rrrrrrrrr rrrrrrr rr r ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- " s ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- " rr ",
- " s ",
- " rs ",
- "r sr rr r ",
- "r s rr s rr r ",
- "r rssrr rss rr r ",
- "r rssrr rss rr r ",
- "r rrrrr rrrss rr r ",
- "r rrrrr rrrss rr r ",
- "r rrrrr rrrss rr r ",
- "r rrrrr rrrss rr r ",
- "r rrrrrsss rrrrr rr r ",
- "r rrrrrsss rrrrr rr r ",
- "r rrrrrrrr rrrrr rr r ",
- "r rrrrrrrr rrrrr rr r ",
- "r rrrrrrrr rrrrr rr r ",
- "r rrrrrrrr rrrrrr rr r ",
- " r ",
- " s ",
- "r srrrrrrrr rrrrrrs rr r ",
- "r srrrrrrrr rrrrrrs rr r ",
- "r rrrrrrrrr rrrrrrr rr r ",
- "r rrrrrrrrr rrrrrrr rr r ",
- "r rrrrrrrrr rrrrrrr rr r ",
- "r rrrrrrrrr rrrrrrr rr r ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- "r rrrrrrrrr rrrrrrr rr rr ",
- " s s sssssssss s ss s ss",
- "r rrrrrrrrr rrrrrrr rr rr ",
- " r "
-];
-
-XPathParser.actionTableNumber = [
- " 1 0 /.-,+*)(' & %$ # \"!",
- " J ",
- "a aaaaaaaaa aaaaaaa aa a ",
- " YYYYY ",
- " 1 0 /.-,+*)(' & %$ # \"!",
- "K1 KKKKKKKK . +*)('KKKKKK KK# K\" ",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " N ",
- " O ",
- "e eeeeeeeee eeeeeee ee ee ",
- "f fffffffff fffffff ff ff ",
- "d ddddddddd ddddddd dd dd ",
- "B BBBBBBBBB BBBBBBB BB BB ",
- "A AAAAAAAAA AAAAAAA AA AA ",
- " P ",
- " Q ",
- " 1 . +*)(' # \" ",
- "b bbbbbbbbb bbbbbbb bb b ",
- " ",
- "! S !! ! ",
- "\" T\" \"\" \" ",
- "$ V $$ U $$ $ ",
- "& &ZY&& &XW && & ",
- ") ))))) )))\\[ )) ) ",
- ". ....._^] ..... .. . ",
- "1 11111111 11111 11 1 ",
- "5 55555555 55555` 55 5 ",
- "7 77777777 777777 77 7 ",
- "9 99999999 999999 99 9 ",
- ": c:::::::: ::::::b :: a: ",
- "I fIIIIIIII IIIIIIe II I ",
- "= ========= ======= == == ",
- "? ????????? ??????? ?? ?? ",
- "C CCCCCCCCC CCCCCCC CC CC ",
- "J JJJJJJJJ JJJJJJ JJ J ",
- "M MMMMMMMM MMMMMM MM M ",
- "N NNNNNNNNN NNNNNNN NN N ",
- "P PPPPPPPPP PPPPPPP PP P ",
- " +*)(' ",
- "R RRRRRRRRR RRRRRRR RR aR ",
- "U UUUUUUUUU UUUUUUU UU U ",
- "Z ZZZZZZZZZ ZZZZZZZ ZZ ZZ ",
- "c ccccccccc ccccccc cc cc ",
- " j ",
- "L fLLLLLLLL LLLLLLe LL L ",
- "6 66666666 66666 66 6 ",
- " k ",
- " l ",
- " XXXXX ",
- " 1 0 /.-,+*)(' & %$m # \"!",
- "_ f________ ______e __ _ ",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 0 /.-,+*)(' %$ # \"!",
- " 1 0 /.-,+*)(' & %$ # \"!",
- " 1 . +*)(' # \" ",
- " 1 . +*)(' # \" ",
- "> >>>>>>>>> >>>>>>> >> >> ",
- " 1 . +*)(' # \" ",
- " 1 . +*)(' # \" ",
- "Q QQQQQQQQQ QQQQQQQ QQ aQ ",
- "V VVVVVVVVV VVVVVVV VV aV ",
- "T TTTTTTTTT TTTTTTT TT T ",
- "@ @@@@@@@@@ @@@@@@@ @@ @@ ",
- " \x87 ",
- "[ [[[[[[[[[ [[[[[[[ [[ [[ ",
- "D DDDDDDDDD DDDDDDD DD DD ",
- " HH ",
- " \x88 ",
- " F\x89 ",
- "# T# ## # ",
- "% V %% U %% % ",
- "' 'ZY'' 'XW '' ' ",
- "( (ZY(( (XW (( ( ",
- "+ +++++ +++\\[ ++ + ",
- "* ***** ***\\[ ** * ",
- "- ----- ---\\[ -- - ",
- ", ,,,,, ,,,\\[ ,, , ",
- "0 00000_^] 00000 00 0 ",
- "/ /////_^] ///// // / ",
- "2 22222222 22222 22 2 ",
- "3 33333333 33333 33 3 ",
- "4 44444444 44444 44 4 ",
- "8 88888888 888888 88 8 ",
- " ^ ",
- " \x8a ",
- "; f;;;;;;;; ;;;;;;e ;; ; ",
- "< f<<<<<<<< <<<<<?@ AB CDEFGH IJ ",
- " ",
- " ",
- " ",
- "L456789:;<=>?@ AB CDEFGH IJ ",
- " M EFGH IJ ",
- " N;<=>?@ AB CDEFGH IJ ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " S EFGH IJ ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " e ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " h J ",
- " i j ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- "o456789:;<=>?@ ABpqCDEFGH IJ ",
- " ",
- " r6789:;<=>?@ AB CDEFGH IJ ",
- " s789:;<=>?@ AB CDEFGH IJ ",
- " t89:;<=>?@ AB CDEFGH IJ ",
- " u89:;<=>?@ AB CDEFGH IJ ",
- " v9:;<=>?@ AB CDEFGH IJ ",
- " w9:;<=>?@ AB CDEFGH IJ ",
- " x9:;<=>?@ AB CDEFGH IJ ",
- " y9:;<=>?@ AB CDEFGH IJ ",
- " z:;<=>?@ AB CDEFGH IJ ",
- " {:;<=>?@ AB CDEFGH IJ ",
- " |;<=>?@ AB CDEFGH IJ ",
- " };<=>?@ AB CDEFGH IJ ",
- " ~;<=>?@ AB CDEFGH IJ ",
- " \x7f=>?@ AB CDEFGH IJ ",
- "\x80456789:;<=>?@ AB CDEFGH IJ\x81",
- " \x82 EFGH IJ ",
- " \x83 EFGH IJ ",
- " ",
- " \x84 GH IJ ",
- " \x85 GH IJ ",
- " i \x86 ",
- " i \x87 ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- " ",
- "o456789:;<=>?@ AB\x8cqCDEFGH IJ ",
- " ",
- " "
-];
-
-XPathParser.productions = [
- [1, 1, 2],
- [2, 1, 3],
- [3, 1, 4],
- [3, 3, 3, -9, 4],
- [4, 1, 5],
- [4, 3, 4, -8, 5],
- [5, 1, 6],
- [5, 3, 5, -22, 6],
- [5, 3, 5, -5, 6],
- [6, 1, 7],
- [6, 3, 6, -23, 7],
- [6, 3, 6, -24, 7],
- [6, 3, 6, -6, 7],
- [6, 3, 6, -7, 7],
- [7, 1, 8],
- [7, 3, 7, -25, 8],
- [7, 3, 7, -26, 8],
- [8, 1, 9],
- [8, 3, 8, -12, 9],
- [8, 3, 8, -11, 9],
- [8, 3, 8, -10, 9],
- [9, 1, 10],
- [9, 2, -26, 9],
- [10, 1, 11],
- [10, 3, 10, -27, 11],
- [11, 1, 12],
- [11, 1, 13],
- [11, 3, 13, -28, 14],
- [11, 3, 13, -4, 14],
- [13, 1, 15],
- [13, 2, 13, 16],
- [15, 1, 17],
- [15, 3, -29, 2, -30],
- [15, 1, -15],
- [15, 1, -16],
- [15, 1, 18],
- [18, 3, -13, -29, -30],
- [18, 4, -13, -29, 19, -30],
- [19, 1, 20],
- [19, 3, 20, -31, 19],
- [20, 1, 2],
- [12, 1, 14],
- [12, 1, 21],
- [21, 1, -28],
- [21, 2, -28, 14],
- [21, 1, 22],
- [14, 1, 23],
- [14, 3, 14, -28, 23],
- [14, 1, 24],
- [23, 2, 25, 26],
- [23, 1, 26],
- [23, 3, 25, 26, 27],
- [23, 2, 26, 27],
- [23, 1, 28],
- [27, 1, 16],
- [27, 2, 16, 27],
- [25, 2, -14, -3],
- [25, 1, -32],
- [26, 1, 29],
- [26, 3, -20, -29, -30],
- [26, 4, -21, -29, -15, -30],
- [16, 3, -33, 30, -34],
- [30, 1, 2],
- [22, 2, -4, 14],
- [24, 3, 14, -4, 23],
- [28, 1, -35],
- [28, 1, -2],
- [17, 2, -36, -18],
- [29, 1, -17],
- [29, 1, -19],
- [29, 1, -18]
-];
-
-XPathParser.DOUBLEDOT = 2;
-XPathParser.DOUBLECOLON = 3;
-XPathParser.DOUBLESLASH = 4;
-XPathParser.NOTEQUAL = 5;
-XPathParser.LESSTHANOREQUAL = 6;
-XPathParser.GREATERTHANOREQUAL = 7;
-XPathParser.AND = 8;
-XPathParser.OR = 9;
-XPathParser.MOD = 10;
-XPathParser.DIV = 11;
-XPathParser.MULTIPLYOPERATOR = 12;
-XPathParser.FUNCTIONNAME = 13;
-XPathParser.AXISNAME = 14;
-XPathParser.LITERAL = 15;
-XPathParser.NUMBER = 16;
-XPathParser.ASTERISKNAMETEST = 17;
-XPathParser.QNAME = 18;
-XPathParser.NCNAMECOLONASTERISK = 19;
-XPathParser.NODETYPE = 20;
-XPathParser.PROCESSINGINSTRUCTIONWITHLITERAL = 21;
-XPathParser.EQUALS = 22;
-XPathParser.LESSTHAN = 23;
-XPathParser.GREATERTHAN = 24;
-XPathParser.PLUS = 25;
-XPathParser.MINUS = 26;
-XPathParser.BAR = 27;
-XPathParser.SLASH = 28;
-XPathParser.LEFTPARENTHESIS = 29;
-XPathParser.RIGHTPARENTHESIS = 30;
-XPathParser.COMMA = 31;
-XPathParser.AT = 32;
-XPathParser.LEFTBRACKET = 33;
-XPathParser.RIGHTBRACKET = 34;
-XPathParser.DOT = 35;
-XPathParser.DOLLAR = 36;
-
-XPathParser.prototype.tokenize = function(s1) {
- var types = [];
- var values = [];
- var s = s1 + '\0';
-
- var pos = 0;
- var c = s.charAt(pos++);
- while (1) {
- while (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
- c = s.charAt(pos++);
- }
- if (c == '\0' || pos >= s.length) {
- break;
- }
-
- if (c == '(') {
- types.push(XPathParser.LEFTPARENTHESIS);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == ')') {
- types.push(XPathParser.RIGHTPARENTHESIS);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == '[') {
- types.push(XPathParser.LEFTBRACKET);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == ']') {
- types.push(XPathParser.RIGHTBRACKET);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == '@') {
- types.push(XPathParser.AT);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == ',') {
- types.push(XPathParser.COMMA);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == '|') {
- types.push(XPathParser.BAR);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == '+') {
- types.push(XPathParser.PLUS);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == '-') {
- types.push(XPathParser.MINUS);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == '=') {
- types.push(XPathParser.EQUALS);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- if (c == '$') {
- types.push(XPathParser.DOLLAR);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
-
- if (c == '.') {
- c = s.charAt(pos++);
- if (c == '.') {
- types.push(XPathParser.DOUBLEDOT);
- values.push("..");
- c = s.charAt(pos++);
- continue;
- }
- if (c >= '0' && c <= '9') {
- var number = "." + c;
- c = s.charAt(pos++);
- while (c >= '0' && c <= '9') {
- number += c;
- c = s.charAt(pos++);
- }
- types.push(XPathParser.NUMBER);
- values.push(number);
- continue;
- }
- types.push(XPathParser.DOT);
- values.push('.');
- continue;
- }
-
- if (c == '\'' || c == '"') {
- var delimiter = c;
- var literal = "";
- while (pos < s.length && (c = s.charAt(pos)) !== delimiter) {
- literal += c;
- pos += 1;
- }
- if (c !== delimiter) {
- throw XPathException.fromMessage("Unterminated string literal: " + delimiter + literal);
+ this.reduceActions[3] = function (rhs) {
+ return new OrOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[5] = function (rhs) {
+ return new AndOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[7] = function (rhs) {
+ return new EqualsOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[8] = function (rhs) {
+ return new NotEqualOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[10] = function (rhs) {
+ return new LessThanOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[11] = function (rhs) {
+ return new GreaterThanOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[12] = function (rhs) {
+ return new LessThanOrEqualOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[13] = function (rhs) {
+ return new GreaterThanOrEqualOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[15] = function (rhs) {
+ return new PlusOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[16] = function (rhs) {
+ return new MinusOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[18] = function (rhs) {
+ return new MultiplyOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[19] = function (rhs) {
+ return new DivOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[20] = function (rhs) {
+ return new ModOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[22] = function (rhs) {
+ return new UnaryMinusOperation(rhs[1]);
+ };
+ this.reduceActions[24] = function (rhs) {
+ return new BarOperation(rhs[0], rhs[2]);
+ };
+ this.reduceActions[25] = function (rhs) {
+ return new PathExpr(undefined, undefined, rhs[0]);
+ };
+ this.reduceActions[27] = function (rhs) {
+ rhs[0].locationPath = rhs[2];
+ return rhs[0];
+ };
+ this.reduceActions[28] = function (rhs) {
+ rhs[0].locationPath = rhs[2];
+ rhs[0].locationPath.steps.unshift(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
+ return rhs[0];
+ };
+ this.reduceActions[29] = function (rhs) {
+ return new PathExpr(rhs[0], [], undefined);
+ };
+ this.reduceActions[30] = function (rhs) {
+ if (Utilities.instance_of(rhs[0], PathExpr)) {
+ if (rhs[0].filterPredicates == undefined) {
+ rhs[0].filterPredicates = [];
+ }
+ rhs[0].filterPredicates.push(rhs[1]);
+ return rhs[0];
+ } else {
+ return new PathExpr(rhs[0], [rhs[1]], undefined);
+ }
+ };
+ this.reduceActions[32] = function (rhs) {
+ return rhs[1];
+ };
+ this.reduceActions[33] = function (rhs) {
+ return new XString(rhs[0]);
+ };
+ this.reduceActions[34] = function (rhs) {
+ return new XNumber(rhs[0]);
+ };
+ this.reduceActions[36] = function (rhs) {
+ return new FunctionCall(rhs[0], []);
+ };
+ this.reduceActions[37] = function (rhs) {
+ return new FunctionCall(rhs[0], rhs[2]);
+ };
+ this.reduceActions[38] = function (rhs) {
+ return [rhs[0]];
+ };
+ this.reduceActions[39] = function (rhs) {
+ rhs[2].unshift(rhs[0]);
+ return rhs[2];
+ };
+ this.reduceActions[43] = function (rhs) {
+ return new LocationPath(true, []);
+ };
+ this.reduceActions[44] = function (rhs) {
+ rhs[1].absolute = true;
+ return rhs[1];
+ };
+ this.reduceActions[46] = function (rhs) {
+ return new LocationPath(false, [rhs[0]]);
+ };
+ this.reduceActions[47] = function (rhs) {
+ rhs[0].steps.push(rhs[2]);
+ return rhs[0];
+ };
+ this.reduceActions[49] = function (rhs) {
+ return new Step(rhs[0], rhs[1], []);
+ };
+ this.reduceActions[50] = function (rhs) {
+ return new Step(Step.CHILD, rhs[0], []);
+ };
+ this.reduceActions[51] = function (rhs) {
+ return new Step(rhs[0], rhs[1], rhs[2]);
+ };
+ this.reduceActions[52] = function (rhs) {
+ return new Step(Step.CHILD, rhs[0], rhs[1]);
+ };
+ this.reduceActions[54] = function (rhs) {
+ return [rhs[0]];
+ };
+ this.reduceActions[55] = function (rhs) {
+ rhs[1].unshift(rhs[0]);
+ return rhs[1];
+ };
+ this.reduceActions[56] = function (rhs) {
+ if (rhs[0] == "ancestor") {
+ return Step.ANCESTOR;
+ } else if (rhs[0] == "ancestor-or-self") {
+ return Step.ANCESTORORSELF;
+ } else if (rhs[0] == "attribute") {
+ return Step.ATTRIBUTE;
+ } else if (rhs[0] == "child") {
+ return Step.CHILD;
+ } else if (rhs[0] == "descendant") {
+ return Step.DESCENDANT;
+ } else if (rhs[0] == "descendant-or-self") {
+ return Step.DESCENDANTORSELF;
+ } else if (rhs[0] == "following") {
+ return Step.FOLLOWING;
+ } else if (rhs[0] == "following-sibling") {
+ return Step.FOLLOWINGSIBLING;
+ } else if (rhs[0] == "namespace") {
+ return Step.NAMESPACE;
+ } else if (rhs[0] == "parent") {
+ return Step.PARENT;
+ } else if (rhs[0] == "preceding") {
+ return Step.PRECEDING;
+ } else if (rhs[0] == "preceding-sibling") {
+ return Step.PRECEDINGSIBLING;
+ } else if (rhs[0] == "self") {
+ return Step.SELF;
}
- pos += 1;
- types.push(XPathParser.LITERAL);
- values.push(literal);
- c = s.charAt(pos++);
- continue;
- }
-
- if (c >= '0' && c <= '9') {
- var number = c;
- c = s.charAt(pos++);
- while (c >= '0' && c <= '9') {
- number += c;
- c = s.charAt(pos++);
- }
- if (c == '.') {
- if (s.charAt(pos) >= '0' && s.charAt(pos) <= '9') {
- number += c;
- number += s.charAt(pos++);
- c = s.charAt(pos++);
- while (c >= '0' && c <= '9') {
- number += c;
- c = s.charAt(pos++);
- }
- }
- }
- types.push(XPathParser.NUMBER);
- values.push(number);
- continue;
- }
-
- if (c == '*') {
- if (types.length > 0) {
- var last = types[types.length - 1];
- if (last != XPathParser.AT
- && last != XPathParser.DOUBLECOLON
- && last != XPathParser.LEFTPARENTHESIS
- && last != XPathParser.LEFTBRACKET
- && last != XPathParser.AND
- && last != XPathParser.OR
- && last != XPathParser.MOD
- && last != XPathParser.DIV
- && last != XPathParser.MULTIPLYOPERATOR
- && last != XPathParser.SLASH
- && last != XPathParser.DOUBLESLASH
- && last != XPathParser.BAR
- && last != XPathParser.PLUS
- && last != XPathParser.MINUS
- && last != XPathParser.EQUALS
- && last != XPathParser.NOTEQUAL
- && last != XPathParser.LESSTHAN
- && last != XPathParser.LESSTHANOREQUAL
- && last != XPathParser.GREATERTHAN
- && last != XPathParser.GREATERTHANOREQUAL) {
- types.push(XPathParser.MULTIPLYOPERATOR);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
- }
- types.push(XPathParser.ASTERISKNAMETEST);
- values.push(c);
- c = s.charAt(pos++);
- continue;
- }
-
- if (c == ':') {
- if (s.charAt(pos) == ':') {
- types.push(XPathParser.DOUBLECOLON);
- values.push("::");
- pos++;
- c = s.charAt(pos++);
- continue;
- }
- }
-
- if (c == '/') {
- c = s.charAt(pos++);
- if (c == '/') {
- types.push(XPathParser.DOUBLESLASH);
- values.push("//");
- c = s.charAt(pos++);
- continue;
- }
- types.push(XPathParser.SLASH);
- values.push('/');
- continue;
- }
-
- if (c == '!') {
- if (s.charAt(pos) == '=') {
- types.push(XPathParser.NOTEQUAL);
- values.push("!=");
- pos++;
- c = s.charAt(pos++);
- continue;
- }
- }
-
- if (c == '<') {
- if (s.charAt(pos) == '=') {
- types.push(XPathParser.LESSTHANOREQUAL);
- values.push("<=");
- pos++;
- c = s.charAt(pos++);
- continue;
- }
- types.push(XPathParser.LESSTHAN);
- values.push('<');
- c = s.charAt(pos++);
- continue;
- }
-
- if (c == '>') {
- if (s.charAt(pos) == '=') {
- types.push(XPathParser.GREATERTHANOREQUAL);
- values.push(">=");
- pos++;
- c = s.charAt(pos++);
- continue;
- }
- types.push(XPathParser.GREATERTHAN);
- values.push('>');
- c = s.charAt(pos++);
- continue;
- }
-
- if (c == '_' || Utilities.isLetter(c.charCodeAt(0))) {
- var name = c;
- c = s.charAt(pos++);
- while (Utilities.isNCNameChar(c.charCodeAt(0))) {
- name += c;
- c = s.charAt(pos++);
- }
- if (types.length > 0) {
- var last = types[types.length - 1];
- if (last != XPathParser.AT
- && last != XPathParser.DOUBLECOLON
- && last != XPathParser.LEFTPARENTHESIS
- && last != XPathParser.LEFTBRACKET
- && last != XPathParser.AND
- && last != XPathParser.OR
- && last != XPathParser.MOD
- && last != XPathParser.DIV
- && last != XPathParser.MULTIPLYOPERATOR
- && last != XPathParser.SLASH
- && last != XPathParser.DOUBLESLASH
- && last != XPathParser.BAR
- && last != XPathParser.PLUS
- && last != XPathParser.MINUS
- && last != XPathParser.EQUALS
- && last != XPathParser.NOTEQUAL
- && last != XPathParser.LESSTHAN
- && last != XPathParser.LESSTHANOREQUAL
- && last != XPathParser.GREATERTHAN
- && last != XPathParser.GREATERTHANOREQUAL) {
- if (name == "and") {
- types.push(XPathParser.AND);
- values.push(name);
- continue;
- }
- if (name == "or") {
- types.push(XPathParser.OR);
- values.push(name);
- continue;
- }
- if (name == "mod") {
- types.push(XPathParser.MOD);
- values.push(name);
- continue;
- }
- if (name == "div") {
- types.push(XPathParser.DIV);
- values.push(name);
- continue;
- }
- }
- }
- if (c == ':') {
- if (s.charAt(pos) == '*') {
- types.push(XPathParser.NCNAMECOLONASTERISK);
- values.push(name + ":*");
- pos++;
- c = s.charAt(pos++);
- continue;
- }
- if (s.charAt(pos) == '_' || Utilities.isLetter(s.charCodeAt(pos))) {
- name += ':';
- c = s.charAt(pos++);
- while (Utilities.isNCNameChar(c.charCodeAt(0))) {
- name += c;
- c = s.charAt(pos++);
- }
- if (c == '(') {
- types.push(XPathParser.FUNCTIONNAME);
- values.push(name);
- continue;
- }
- types.push(XPathParser.QNAME);
- values.push(name);
- continue;
- }
- if (s.charAt(pos) == ':') {
- types.push(XPathParser.AXISNAME);
- values.push(name);
- continue;
- }
- }
- if (c == '(') {
- if (name == "comment" || name == "text" || name == "node") {
- types.push(XPathParser.NODETYPE);
- values.push(name);
- continue;
- }
- if (name == "processing-instruction") {
- if (s.charAt(pos) == ')') {
- types.push(XPathParser.NODETYPE);
- } else {
- types.push(XPathParser.PROCESSINGINSTRUCTIONWITHLITERAL);
- }
- values.push(name);
- continue;
- }
- types.push(XPathParser.FUNCTIONNAME);
- values.push(name);
- continue;
- }
- types.push(XPathParser.QNAME);
- values.push(name);
- continue;
- }
-
- throw new Error("Unexpected character " + c);
- }
- types.push(1);
- values.push("[EOF]");
- return [types, values];
-};
-
-XPathParser.SHIFT = 's';
-XPathParser.REDUCE = 'r';
-XPathParser.ACCEPT = 'a';
-
-XPathParser.prototype.parse = function(s) {
- var types;
- var values;
- var res = this.tokenize(s);
- if (res == undefined) {
- return undefined;
- }
- types = res[0];
- values = res[1];
- var tokenPos = 0;
- var state = [];
- var tokenType = [];
- var tokenValue = [];
- var s;
- var a;
- var t;
-
- state.push(0);
- tokenType.push(1);
- tokenValue.push("_S");
-
- a = types[tokenPos];
- t = values[tokenPos++];
- while (1) {
- s = state[state.length - 1];
- switch (XPathParser.actionTable[s].charAt(a - 1)) {
- case XPathParser.SHIFT:
- tokenType.push(-a);
- tokenValue.push(t);
- state.push(XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32);
- a = types[tokenPos];
- t = values[tokenPos++];
- break;
- case XPathParser.REDUCE:
- var num = XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][1];
- var rhs = [];
- for (var i = 0; i < num; i++) {
- tokenType.pop();
- rhs.unshift(tokenValue.pop());
- state.pop();
- }
- var s_ = state[state.length - 1];
- tokenType.push(XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][0]);
- if (this.reduceActions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32] == undefined) {
- tokenValue.push(rhs[0]);
- } else {
- tokenValue.push(this.reduceActions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32](rhs));
- }
- state.push(XPathParser.gotoTable[s_].charCodeAt(XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][0] - 2) - 33);
- break;
- case XPathParser.ACCEPT:
- return new XPath(tokenValue.pop());
- default:
- throw new Error("XPath parse error");
- }
- }
-};
-
-// XPath /////////////////////////////////////////////////////////////////////
-
-XPath.prototype = new Object();
-XPath.prototype.constructor = XPath;
-XPath.superclass = Object.prototype;
-
-function XPath(e) {
- this.expression = e;
-}
-
-XPath.prototype.toString = function() {
- return this.expression.toString();
-};
-
-function setIfUnset(obj, prop, value) {
- if (!(prop in obj)) {
- obj[prop] = value;
- }
-}
-
-XPath.prototype.evaluate = function(c) {
- c.contextNode = c.expressionContextNode;
- c.contextSize = 1;
- c.contextPosition = 1;
-
- // [2017-11-25] Removed usage of .implementation.hasFeature() since it does
- // not reliably detect HTML DOMs (always returns false in xmldom and true in browsers)
- if (c.isHtml) {
- setIfUnset(c, 'caseInsensitive', true);
- setIfUnset(c, 'allowAnyNamespaceForNoPrefix', true);
- }
-
- setIfUnset(c, 'caseInsensitive', false);
-
- return this.expression.evaluate(c);
-};
-
-XPath.XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
-XPath.XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
-
-// Expression ////////////////////////////////////////////////////////////////
-
-Expression.prototype = new Object();
-Expression.prototype.constructor = Expression;
-Expression.superclass = Object.prototype;
-
-function Expression() {
-}
-
-Expression.prototype.init = function() {
-};
-
-Expression.prototype.toString = function() {
- return "";
-};
-
-Expression.prototype.evaluate = function(c) {
- throw new Error("Could not evaluate expression.");
-};
-
-// UnaryOperation ////////////////////////////////////////////////////////////
-
-UnaryOperation.prototype = new Expression();
-UnaryOperation.prototype.constructor = UnaryOperation;
-UnaryOperation.superclass = Expression.prototype;
-
-function UnaryOperation(rhs) {
- if (arguments.length > 0) {
- this.init(rhs);
- }
-}
-
-UnaryOperation.prototype.init = function(rhs) {
- this.rhs = rhs;
-};
-
-// UnaryMinusOperation ///////////////////////////////////////////////////////
-
-UnaryMinusOperation.prototype = new UnaryOperation();
-UnaryMinusOperation.prototype.constructor = UnaryMinusOperation;
-UnaryMinusOperation.superclass = UnaryOperation.prototype;
-
-function UnaryMinusOperation(rhs) {
- if (arguments.length > 0) {
- this.init(rhs);
- }
-}
-
-UnaryMinusOperation.prototype.init = function(rhs) {
- UnaryMinusOperation.superclass.init.call(this, rhs);
-};
-
-UnaryMinusOperation.prototype.evaluate = function(c) {
- return this.rhs.evaluate(c).number().negate();
-};
-
-UnaryMinusOperation.prototype.toString = function() {
- return "-" + this.rhs.toString();
-};
-
-// BinaryOperation ///////////////////////////////////////////////////////////
-
-BinaryOperation.prototype = new Expression();
-BinaryOperation.prototype.constructor = BinaryOperation;
-BinaryOperation.superclass = Expression.prototype;
-
-function BinaryOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-BinaryOperation.prototype.init = function(lhs, rhs) {
- this.lhs = lhs;
- this.rhs = rhs;
-};
-
-// OrOperation ///////////////////////////////////////////////////////////////
-
-OrOperation.prototype = new BinaryOperation();
-OrOperation.prototype.constructor = OrOperation;
-OrOperation.superclass = BinaryOperation.prototype;
-
-function OrOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-OrOperation.prototype.init = function(lhs, rhs) {
- OrOperation.superclass.init.call(this, lhs, rhs);
-};
-
-OrOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " or " + this.rhs.toString() + ")";
-};
-
-OrOperation.prototype.evaluate = function(c) {
- var b = this.lhs.evaluate(c).bool();
- if (b.booleanValue()) {
- return b;
- }
- return this.rhs.evaluate(c).bool();
-};
-
-// AndOperation //////////////////////////////////////////////////////////////
-
-AndOperation.prototype = new BinaryOperation();
-AndOperation.prototype.constructor = AndOperation;
-AndOperation.superclass = BinaryOperation.prototype;
-
-function AndOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-AndOperation.prototype.init = function(lhs, rhs) {
- AndOperation.superclass.init.call(this, lhs, rhs);
-};
-
-AndOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " and " + this.rhs.toString() + ")";
-};
-
-AndOperation.prototype.evaluate = function(c) {
- var b = this.lhs.evaluate(c).bool();
- if (!b.booleanValue()) {
- return b;
- }
- return this.rhs.evaluate(c).bool();
-};
-
-// EqualsOperation ///////////////////////////////////////////////////////////
-
-EqualsOperation.prototype = new BinaryOperation();
-EqualsOperation.prototype.constructor = EqualsOperation;
-EqualsOperation.superclass = BinaryOperation.prototype;
-
-function EqualsOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-EqualsOperation.prototype.init = function(lhs, rhs) {
- EqualsOperation.superclass.init.call(this, lhs, rhs);
-};
-
-EqualsOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " = " + this.rhs.toString() + ")";
-};
-
-EqualsOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).equals(this.rhs.evaluate(c));
-};
-
-// NotEqualOperation /////////////////////////////////////////////////////////
-
-NotEqualOperation.prototype = new BinaryOperation();
-NotEqualOperation.prototype.constructor = NotEqualOperation;
-NotEqualOperation.superclass = BinaryOperation.prototype;
-
-function NotEqualOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-NotEqualOperation.prototype.init = function(lhs, rhs) {
- NotEqualOperation.superclass.init.call(this, lhs, rhs);
-};
-
-NotEqualOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " != " + this.rhs.toString() + ")";
-};
-
-NotEqualOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).notequal(this.rhs.evaluate(c));
-};
-
-// LessThanOperation /////////////////////////////////////////////////////////
-
-LessThanOperation.prototype = new BinaryOperation();
-LessThanOperation.prototype.constructor = LessThanOperation;
-LessThanOperation.superclass = BinaryOperation.prototype;
-
-function LessThanOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-LessThanOperation.prototype.init = function(lhs, rhs) {
- LessThanOperation.superclass.init.call(this, lhs, rhs);
-};
-
-LessThanOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).lessthan(this.rhs.evaluate(c));
-};
-
-LessThanOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " < " + this.rhs.toString() + ")";
-};
-
-// GreaterThanOperation //////////////////////////////////////////////////////
-
-GreaterThanOperation.prototype = new BinaryOperation();
-GreaterThanOperation.prototype.constructor = GreaterThanOperation;
-GreaterThanOperation.superclass = BinaryOperation.prototype;
-
-function GreaterThanOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-GreaterThanOperation.prototype.init = function(lhs, rhs) {
- GreaterThanOperation.superclass.init.call(this, lhs, rhs);
-};
-
-GreaterThanOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).greaterthan(this.rhs.evaluate(c));
-};
-
-GreaterThanOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " > " + this.rhs.toString() + ")";
-};
-
-// LessThanOrEqualOperation //////////////////////////////////////////////////
-
-LessThanOrEqualOperation.prototype = new BinaryOperation();
-LessThanOrEqualOperation.prototype.constructor = LessThanOrEqualOperation;
-LessThanOrEqualOperation.superclass = BinaryOperation.prototype;
-
-function LessThanOrEqualOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-LessThanOrEqualOperation.prototype.init = function(lhs, rhs) {
- LessThanOrEqualOperation.superclass.init.call(this, lhs, rhs);
-};
-
-LessThanOrEqualOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).lessthanorequal(this.rhs.evaluate(c));
-};
-
-LessThanOrEqualOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " <= " + this.rhs.toString() + ")";
-};
-
-// GreaterThanOrEqualOperation ///////////////////////////////////////////////
-
-GreaterThanOrEqualOperation.prototype = new BinaryOperation();
-GreaterThanOrEqualOperation.prototype.constructor = GreaterThanOrEqualOperation;
-GreaterThanOrEqualOperation.superclass = BinaryOperation.prototype;
-
-function GreaterThanOrEqualOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-GreaterThanOrEqualOperation.prototype.init = function(lhs, rhs) {
- GreaterThanOrEqualOperation.superclass.init.call(this, lhs, rhs);
-};
-
-GreaterThanOrEqualOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).greaterthanorequal(this.rhs.evaluate(c));
-};
-
-GreaterThanOrEqualOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " >= " + this.rhs.toString() + ")";
-};
-
-// PlusOperation /////////////////////////////////////////////////////////////
-
-PlusOperation.prototype = new BinaryOperation();
-PlusOperation.prototype.constructor = PlusOperation;
-PlusOperation.superclass = BinaryOperation.prototype;
-
-function PlusOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-PlusOperation.prototype.init = function(lhs, rhs) {
- PlusOperation.superclass.init.call(this, lhs, rhs);
-};
-
-PlusOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).number().plus(this.rhs.evaluate(c).number());
-};
-
-PlusOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " + " + this.rhs.toString() + ")";
-};
-
-// MinusOperation ////////////////////////////////////////////////////////////
-
-MinusOperation.prototype = new BinaryOperation();
-MinusOperation.prototype.constructor = MinusOperation;
-MinusOperation.superclass = BinaryOperation.prototype;
-
-function MinusOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-MinusOperation.prototype.init = function(lhs, rhs) {
- MinusOperation.superclass.init.call(this, lhs, rhs);
-};
-
-MinusOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).number().minus(this.rhs.evaluate(c).number());
-};
-
-MinusOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " - " + this.rhs.toString() + ")";
-};
-
-// MultiplyOperation /////////////////////////////////////////////////////////
-
-MultiplyOperation.prototype = new BinaryOperation();
-MultiplyOperation.prototype.constructor = MultiplyOperation;
-MultiplyOperation.superclass = BinaryOperation.prototype;
-
-function MultiplyOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-MultiplyOperation.prototype.init = function(lhs, rhs) {
- MultiplyOperation.superclass.init.call(this, lhs, rhs);
-};
-
-MultiplyOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).number().multiply(this.rhs.evaluate(c).number());
-};
-
-MultiplyOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " * " + this.rhs.toString() + ")";
-};
-
-// DivOperation //////////////////////////////////////////////////////////////
-
-DivOperation.prototype = new BinaryOperation();
-DivOperation.prototype.constructor = DivOperation;
-DivOperation.superclass = BinaryOperation.prototype;
-
-function DivOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-DivOperation.prototype.init = function(lhs, rhs) {
- DivOperation.superclass.init.call(this, lhs, rhs);
-};
-
-DivOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).number().div(this.rhs.evaluate(c).number());
-};
-
-DivOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " div " + this.rhs.toString() + ")";
-};
-
-// ModOperation //////////////////////////////////////////////////////////////
-
-ModOperation.prototype = new BinaryOperation();
-ModOperation.prototype.constructor = ModOperation;
-ModOperation.superclass = BinaryOperation.prototype;
-
-function ModOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-ModOperation.prototype.init = function(lhs, rhs) {
- ModOperation.superclass.init.call(this, lhs, rhs);
-};
-
-ModOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).number().mod(this.rhs.evaluate(c).number());
-};
-
-ModOperation.prototype.toString = function() {
- return "(" + this.lhs.toString() + " mod " + this.rhs.toString() + ")";
-};
-
-// BarOperation //////////////////////////////////////////////////////////////
-
-BarOperation.prototype = new BinaryOperation();
-BarOperation.prototype.constructor = BarOperation;
-BarOperation.superclass = BinaryOperation.prototype;
-
-function BarOperation(lhs, rhs) {
- if (arguments.length > 0) {
- this.init(lhs, rhs);
- }
-}
-
-BarOperation.prototype.init = function(lhs, rhs) {
- BarOperation.superclass.init.call(this, lhs, rhs);
-};
-
-BarOperation.prototype.evaluate = function(c) {
- return this.lhs.evaluate(c).nodeset().union(this.rhs.evaluate(c).nodeset());
-};
-
-BarOperation.prototype.toString = function() {
- return map(toString, [this.lhs, this.rhs]).join(' | ');
-};
-
-// PathExpr //////////////////////////////////////////////////////////////////
-
-PathExpr.prototype = new Expression();
-PathExpr.prototype.constructor = PathExpr;
-PathExpr.superclass = Expression.prototype;
-
-function PathExpr(filter, filterPreds, locpath) {
- if (arguments.length > 0) {
- this.init(filter, filterPreds, locpath);
- }
-}
-
-PathExpr.prototype.init = function(filter, filterPreds, locpath) {
- PathExpr.superclass.init.call(this);
- this.filter = filter;
- this.filterPredicates = filterPreds;
- this.locationPath = locpath;
-};
-
-/**
- * Returns the topmost node of the tree containing node
- */
-function findRoot(node) {
- while (node && node.parentNode) {
- node = node.parentNode;
- }
-
- return node;
-}
-
-PathExpr.applyPredicates = function (predicates, c, nodes) {
- return reduce(function (inNodes, pred) {
- var ctx = c.extend({ contextSize: inNodes.length });
-
- return filter(function (node, i) {
- return PathExpr.predicateMatches(pred, ctx.extend({ contextNode: node, contextPosition: i + 1 }));
- }, inNodes);
- }, nodes, predicates);
-};
-
-PathExpr.getRoot = function (xpc, nodes) {
- var firstNode = nodes[0];
-
- if (firstNode.nodeType === 9 /*Node.DOCUMENT_NODE*/) {
- return firstNode;
- }
-
- if (xpc.virtualRoot) {
- return xpc.virtualRoot;
- }
-
- var ownerDoc = firstNode.ownerDocument;
-
- if (ownerDoc) {
- return ownerDoc;
- }
-
- // IE 5.5 doesn't have ownerDocument?
- var n = firstNode;
- while (n.parentNode != null) {
- n = n.parentNode;
- }
- return n;
-}
-
-PathExpr.applyStep = function (step, xpc, node) {
- var self = this;
- var newNodes = [];
- xpc.contextNode = node;
-
- switch (step.axis) {
- case Step.ANCESTOR:
- // look at all the ancestor nodes
- if (xpc.contextNode === xpc.virtualRoot) {
- break;
- }
- var m;
- if (xpc.contextNode.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
- m = PathExpr.getOwnerElement(xpc.contextNode);
- } else {
- m = xpc.contextNode.parentNode;
- }
- while (m != null) {
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- if (m === xpc.virtualRoot) {
- break;
- }
- m = m.parentNode;
- }
- break;
-
- case Step.ANCESTORORSELF:
- // look at all the ancestor nodes and the current node
- for (var m = xpc.contextNode; m != null; m = m.nodeType == 2 /*Node.ATTRIBUTE_NODE*/ ? PathExpr.getOwnerElement(m) : m.parentNode) {
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- if (m === xpc.virtualRoot) {
- break;
- }
- }
- break;
-
- case Step.ATTRIBUTE:
- // look at the attributes
- var nnm = xpc.contextNode.attributes;
- if (nnm != null) {
- for (var k = 0; k < nnm.length; k++) {
- var m = nnm.item(k);
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- }
- }
- break;
-
- case Step.CHILD:
- // look at all child elements
- for (var m = xpc.contextNode.firstChild; m != null; m = m.nextSibling) {
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- }
- break;
-
- case Step.DESCENDANT:
- // look at all descendant nodes
- var st = [ xpc.contextNode.firstChild ];
- while (st.length > 0) {
- for (var m = st.pop(); m != null; ) {
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- if (m.firstChild != null) {
- st.push(m.nextSibling);
- m = m.firstChild;
- } else {
- m = m.nextSibling;
- }
- }
- }
- break;
-
- case Step.DESCENDANTORSELF:
- // look at self
- if (step.nodeTest.matches(xpc.contextNode, xpc)) {
- newNodes.push(xpc.contextNode);
- }
- // look at all descendant nodes
- var st = [ xpc.contextNode.firstChild ];
- while (st.length > 0) {
- for (var m = st.pop(); m != null; ) {
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- if (m.firstChild != null) {
- st.push(m.nextSibling);
- m = m.firstChild;
- } else {
- m = m.nextSibling;
- }
- }
- }
- break;
-
- case Step.FOLLOWING:
- if (xpc.contextNode === xpc.virtualRoot) {
- break;
- }
- var st = [];
- if (xpc.contextNode.firstChild != null) {
- st.unshift(xpc.contextNode.firstChild);
- } else {
- st.unshift(xpc.contextNode.nextSibling);
- }
- for (var m = xpc.contextNode.parentNode; m != null && m.nodeType != 9 /*Node.DOCUMENT_NODE*/ && m !== xpc.virtualRoot; m = m.parentNode) {
- st.unshift(m.nextSibling);
- }
- do {
- for (var m = st.pop(); m != null; ) {
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- if (m.firstChild != null) {
- st.push(m.nextSibling);
- m = m.firstChild;
- } else {
- m = m.nextSibling;
- }
- }
- } while (st.length > 0);
- break;
-
- case Step.FOLLOWINGSIBLING:
- if (xpc.contextNode === xpc.virtualRoot) {
- break;
- }
- for (var m = xpc.contextNode.nextSibling; m != null; m = m.nextSibling) {
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- }
- break;
-
- case Step.NAMESPACE:
- var n = {};
- if (xpc.contextNode.nodeType == 1 /*Node.ELEMENT_NODE*/) {
- n["xml"] = XPath.XML_NAMESPACE_URI;
- n["xmlns"] = XPath.XMLNS_NAMESPACE_URI;
- for (var m = xpc.contextNode; m != null && m.nodeType == 1 /*Node.ELEMENT_NODE*/; m = m.parentNode) {
- for (var k = 0; k < m.attributes.length; k++) {
- var attr = m.attributes.item(k);
- var nm = String(attr.name);
- if (nm == "xmlns") {
- if (n[""] == undefined) {
- n[""] = attr.value;
- }
- } else if (nm.length > 6 && nm.substring(0, 6) == "xmlns:") {
- var pre = nm.substring(6, nm.length);
- if (n[pre] == undefined) {
- n[pre] = attr.value;
- }
- }
- }
- }
- for (var pre in n) {
- var nsn = new XPathNamespace(pre, n[pre], xpc.contextNode);
- if (step.nodeTest.matches(nsn, xpc)) {
- newNodes.push(nsn);
- }
- }
- }
- break;
-
- case Step.PARENT:
- m = null;
- if (xpc.contextNode !== xpc.virtualRoot) {
- if (xpc.contextNode.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
- m = PathExpr.getOwnerElement(xpc.contextNode);
- } else {
- m = xpc.contextNode.parentNode;
- }
- }
- if (m != null && step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- break;
-
- case Step.PRECEDING:
- var st;
- if (xpc.virtualRoot != null) {
- st = [ xpc.virtualRoot ];
- } else {
- // cannot rely on .ownerDocument because the node may be in a document fragment
- st = [findRoot(xpc.contextNode)];
- }
- outer: while (st.length > 0) {
- for (var m = st.pop(); m != null; ) {
- if (m == xpc.contextNode) {
- break outer;
- }
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.unshift(m);
- }
- if (m.firstChild != null) {
- st.push(m.nextSibling);
- m = m.firstChild;
- } else {
- m = m.nextSibling;
- }
- }
- }
- break;
-
- case Step.PRECEDINGSIBLING:
- if (xpc.contextNode === xpc.virtualRoot) {
- break;
- }
- for (var m = xpc.contextNode.previousSibling; m != null; m = m.previousSibling) {
- if (step.nodeTest.matches(m, xpc)) {
- newNodes.push(m);
- }
- }
- break;
-
- case Step.SELF:
- if (step.nodeTest.matches(xpc.contextNode, xpc)) {
- newNodes.push(xpc.contextNode);
- }
- break;
-
- default:
- }
-
- return newNodes;
-};
-
-PathExpr.applySteps = function (steps, xpc, nodes) {
- return reduce(function (inNodes, step) {
- return [].concat.apply([], map(function (node) {
- return PathExpr.applyPredicates(step.predicates, xpc, PathExpr.applyStep(step, xpc, node));
- }, inNodes));
- }, nodes, steps);
-}
-
-PathExpr.prototype.applyFilter = function(c, xpc) {
- if (!this.filter) {
- return { nodes: [ c.contextNode ] };
- }
-
- var ns = this.filter.evaluate(c);
-
- if (!Utilities.instance_of(ns, XNodeSet)) {
- if (this.filterPredicates != null && this.filterPredicates.length > 0 || this.locationPath != null) {
- throw new Error("Path expression filter must evaluate to a nodeset if predicates or location path are used");
- }
-
- return { nonNodes: ns };
- }
-
- return {
- nodes: PathExpr.applyPredicates(this.filterPredicates || [], xpc, ns.toUnsortedArray())
- };
-};
-
-PathExpr.applyLocationPath = function (locationPath, xpc, nodes) {
- if (!locationPath) {
- return nodes;
- }
-
- var startNodes = locationPath.absolute ? [ PathExpr.getRoot(xpc, nodes) ] : nodes;
-
- return PathExpr.applySteps(locationPath.steps, xpc, startNodes);
-};
-
-PathExpr.prototype.evaluate = function(c) {
- var xpc = assign(new XPathContext(), c);
-
- var filterResult = this.applyFilter(c, xpc);
-
- if ('nonNodes' in filterResult) {
- return filterResult.nonNodes;
- }
-
- var ns = new XNodeSet();
- ns.addArray(PathExpr.applyLocationPath(this.locationPath, xpc, filterResult.nodes));
- return ns;
-};
-
-PathExpr.predicateMatches = function(pred, c) {
- var res = pred.evaluate(c);
-
- return Utilities.instance_of(res, XNumber)
- ? c.contextPosition == res.numberValue()
- : res.booleanValue();
-};
-
-PathExpr.predicateString = compose(wrap('[', ']'), toString);
-PathExpr.predicatesString = compose(join(''), map(PathExpr.predicateString));
-
-PathExpr.prototype.toString = function() {
- if (this.filter != undefined) {
- var filterStr = toString(this.filter);
-
- if (Utilities.instance_of(this.filter, XString)) {
- return wrap("'", "'", filterStr);
- }
- if (this.filterPredicates != undefined && this.filterPredicates.length) {
- return wrap('(', ')', filterStr) +
- PathExpr.predicatesString(this.filterPredicates);
- }
- if (this.locationPath != undefined) {
- return filterStr +
- (this.locationPath.absolute ? '' : '/') +
- toString(this.locationPath);
- }
-
- return filterStr;
- }
-
- return toString(this.locationPath);
-};
-
-PathExpr.getOwnerElement = function(n) {
- // DOM 2 has ownerElement
- if (n.ownerElement) {
- return n.ownerElement;
- }
- // DOM 1 Internet Explorer can use selectSingleNode (ironically)
- try {
- if (n.selectSingleNode) {
- return n.selectSingleNode("..");
- }
- } catch (e) {
- }
- // Other DOM 1 implementations must use this egregious search
- var doc = n.nodeType == 9 /*Node.DOCUMENT_NODE*/
- ? n
- : n.ownerDocument;
- var elts = doc.getElementsByTagName("*");
- for (var i = 0; i < elts.length; i++) {
- var elt = elts.item(i);
- var nnm = elt.attributes;
- for (var j = 0; j < nnm.length; j++) {
- var an = nnm.item(j);
- if (an === n) {
- return elt;
- }
- }
- }
- return null;
-};
-
-// LocationPath //////////////////////////////////////////////////////////////
-
-LocationPath.prototype = new Object();
-LocationPath.prototype.constructor = LocationPath;
-LocationPath.superclass = Object.prototype;
-
-function LocationPath(abs, steps) {
- if (arguments.length > 0) {
- this.init(abs, steps);
- }
-}
-
-LocationPath.prototype.init = function(abs, steps) {
- this.absolute = abs;
- this.steps = steps;
-};
-
-LocationPath.prototype.toString = function() {
- return (
- (this.absolute ? '/' : '') +
- map(toString, this.steps).join('/')
- );
-};
-
-// Step //////////////////////////////////////////////////////////////////////
-
-Step.prototype = new Object();
-Step.prototype.constructor = Step;
-Step.superclass = Object.prototype;
-
-function Step(axis, nodetest, preds) {
- if (arguments.length > 0) {
- this.init(axis, nodetest, preds);
- }
-}
-
-Step.prototype.init = function(axis, nodetest, preds) {
- this.axis = axis;
- this.nodeTest = nodetest;
- this.predicates = preds;
-};
-
-Step.prototype.toString = function() {
- return Step.STEPNAMES[this.axis] +
- "::" +
- this.nodeTest.toString() +
- PathExpr.predicatesString(this.predicates);
-};
-
-
-Step.ANCESTOR = 0;
-Step.ANCESTORORSELF = 1;
-Step.ATTRIBUTE = 2;
-Step.CHILD = 3;
-Step.DESCENDANT = 4;
-Step.DESCENDANTORSELF = 5;
-Step.FOLLOWING = 6;
-Step.FOLLOWINGSIBLING = 7;
-Step.NAMESPACE = 8;
-Step.PARENT = 9;
-Step.PRECEDING = 10;
-Step.PRECEDINGSIBLING = 11;
-Step.SELF = 12;
-
-Step.STEPNAMES = reduce(function (acc, x) { return acc[x[0]] = x[1], acc; }, {}, [
- [Step.ANCESTOR, 'ancestor'],
- [Step.ANCESTORORSELF, 'ancestor-or-self'],
- [Step.ATTRIBUTE, 'attribute'],
- [Step.CHILD, 'child'],
- [Step.DESCENDANT, 'descendant'],
- [Step.DESCENDANTORSELF, 'descendant-or-self'],
- [Step.FOLLOWING, 'following'],
- [Step.FOLLOWINGSIBLING, 'following-sibling'],
- [Step.NAMESPACE, 'namespace'],
- [Step.PARENT, 'parent'],
- [Step.PRECEDING, 'preceding'],
- [Step.PRECEDINGSIBLING, 'preceding-sibling'],
- [Step.SELF, 'self']
- ]);
-
-// NodeTest //////////////////////////////////////////////////////////////////
-
-NodeTest.prototype = new Object();
-NodeTest.prototype.constructor = NodeTest;
-NodeTest.superclass = Object.prototype;
-
-function NodeTest(type, value) {
- if (arguments.length > 0) {
- this.init(type, value);
- }
-}
-
-NodeTest.prototype.init = function(type, value) {
- this.type = type;
- this.value = value;
-};
-
-NodeTest.prototype.toString = function() {
- return "";
-};
-
-NodeTest.prototype.matches = function (n, xpc) {
- console.warn('unknown node test type');
-};
-
-NodeTest.NAMETESTANY = 0;
-NodeTest.NAMETESTPREFIXANY = 1;
-NodeTest.NAMETESTQNAME = 2;
-NodeTest.COMMENT = 3;
-NodeTest.TEXT = 4;
-NodeTest.PI = 5;
-NodeTest.NODE = 6;
-
-NodeTest.isNodeType = function (types){
- return compose(includes(types), prop('nodeType'));
-};
-
-NodeTest.makeNodeTestType = function (type, members, ctor) {
- var newType = ctor || function () {};
-
- newType.prototype = new NodeTest(members.type);
- newType.prototype.constructor = type;
-
- for (var key in members) {
- newType.prototype[key] = members[key];
- }
-
- return newType;
-};
-// create invariant node test for certain node types
-NodeTest.makeNodeTypeTest = function (type, nodeTypes, stringVal) {
- return new (NodeTest.makeNodeTestType(type, {
- matches: NodeTest.isNodeType(nodeTypes),
- toString: always(stringVal)
- }))();
-};
-
-NodeTest.hasPrefix = function (node) {
- return node.prefix || (node.nodeName || node.tagName).indexOf(':') !== -1;
-};
-
-NodeTest.isElementOrAttribute = NodeTest.isNodeType([1, 2]);
-NodeTest.nameSpaceMatches = function (prefix, xpc, n) {
- var nNamespace = (n.namespaceURI || '');
-
- if (!prefix) {
- return !nNamespace || (xpc.allowAnyNamespaceForNoPrefix && !NodeTest.hasPrefix(n));
- }
-
- var ns = xpc.namespaceResolver.getNamespace(prefix, xpc.expressionContextNode);
-
- if (ns == null) {
- throw new Error("Cannot resolve QName " + prefix);
- }
-
- return ns === nNamespace;
-};
-NodeTest.localNameMatches = function (localName, xpc, n) {
- var nLocalName = (n.localName || n.nodeName);
-
- return xpc.caseInsensitive
- ? localName.toLowerCase() === nLocalName.toLowerCase()
- : localName === nLocalName;
-};
-
-NodeTest.NameTestPrefixAny = NodeTest.makeNodeTestType(NodeTest.NAMETESTPREFIXANY, {
- matches: function (n, xpc){
- return NodeTest.isElementOrAttribute(n) &&
- NodeTest.nameSpaceMatches(this.prefix, xpc, n);
- },
- toString: function () {
- return this.prefix + ":*";
- }
-}, function (prefix) { this.prefix = prefix; });
-
-NodeTest.NameTestQName = NodeTest.makeNodeTestType(NodeTest.NAMETESTQNAME, {
- matches: function (n, xpc) {
- return NodeTest.isNodeType([1, 2, XPathNamespace.XPATH_NAMESPACE_NODE])(n) &&
- NodeTest.nameSpaceMatches(this.prefix, xpc, n) &&
- NodeTest.localNameMatches(this.localName, xpc, n);
- },
- toString: function () {
- return this.name;
- }
-}, function (name) {
- var nameParts = name.split(':');
-
- this.name = name;
- this.prefix = nameParts.length > 1 ? nameParts[0] : null;
- this.localName = nameParts[nameParts.length > 1 ? 1 : 0];
-});
-
-NodeTest.PITest = NodeTest.makeNodeTestType(NodeTest.PI, {
- matches: function (n, xpc) {
- return NodeTest.isNodeType([7])(n) && (n.target || n.nodeName) === this.name;
- },
- toString: function () {
- return wrap('processing-instruction("', '")', this.name);
- }
-}, function (name) { this.name = name; })
-
-// singletons
-
-// elements, attributes, namespaces
-NodeTest.nameTestAny = NodeTest.makeNodeTypeTest(NodeTest.NAMETESTANY, [1, 2, XPathNamespace.XPATH_NAMESPACE_NODE], '*');
-// text, cdata
-NodeTest.textTest = NodeTest.makeNodeTypeTest(NodeTest.TEXT, [3, 4], 'text()');
-NodeTest.commentTest = NodeTest.makeNodeTypeTest(NodeTest.COMMENT, [8], 'comment()');
-// elements, attributes, text, cdata, PIs, comments, document nodes
-NodeTest.nodeTest = NodeTest.makeNodeTypeTest(NodeTest.NODE, [1, 2, 3, 4, 7, 8, 9], 'node()');
-NodeTest.anyPiTest = NodeTest.makeNodeTypeTest(NodeTest.PI, [7], 'processing-instruction()');
-
-// VariableReference /////////////////////////////////////////////////////////
-
-VariableReference.prototype = new Expression();
-VariableReference.prototype.constructor = VariableReference;
-VariableReference.superclass = Expression.prototype;
-
-function VariableReference(v) {
- if (arguments.length > 0) {
- this.init(v);
- }
-}
-
-VariableReference.prototype.init = function(v) {
- this.variable = v;
-};
-
-VariableReference.prototype.toString = function() {
- return "$" + this.variable;
-};
-
-VariableReference.prototype.evaluate = function(c) {
- var parts = Utilities.resolveQName(this.variable, c.namespaceResolver, c.contextNode, false);
-
- if (parts[0] == null) {
- throw new Error("Cannot resolve QName " + fn);
- }
- var result = c.variableResolver.getVariable(parts[1], parts[0]);
- if (!result) {
- throw XPathException.fromMessage("Undeclared variable: " + this.toString());
- }
- return result;
-};
-
-// FunctionCall //////////////////////////////////////////////////////////////
-
-FunctionCall.prototype = new Expression();
-FunctionCall.prototype.constructor = FunctionCall;
-FunctionCall.superclass = Expression.prototype;
-
-function FunctionCall(fn, args) {
- if (arguments.length > 0) {
- this.init(fn, args);
- }
-}
-
-FunctionCall.prototype.init = function(fn, args) {
- this.functionName = fn;
- this.arguments = args;
-};
-
-FunctionCall.prototype.toString = function() {
- var s = this.functionName + "(";
- for (var i = 0; i < this.arguments.length; i++) {
- if (i > 0) {
- s += ", ";
- }
- s += this.arguments[i].toString();
- }
- return s + ")";
-};
-
-FunctionCall.prototype.evaluate = function(c) {
- var f = FunctionResolver.getFunctionFromContext(this.functionName, c);
-
- if (!f) {
- throw new Error("Unknown function " + this.functionName);
- }
-
- var a = [c].concat(this.arguments);
- return f.apply(c.functionResolver.thisArg, a);
-};
-
-// Operators /////////////////////////////////////////////////////////////////
-
-var Operators = new Object();
-
-Operators.equals = function(l, r) {
- return l.equals(r);
-};
-
-Operators.notequal = function(l, r) {
- return l.notequal(r);
-};
-
-Operators.lessthan = function(l, r) {
- return l.lessthan(r);
-};
-
-Operators.greaterthan = function(l, r) {
- return l.greaterthan(r);
-};
-
-Operators.lessthanorequal = function(l, r) {
- return l.lessthanorequal(r);
-};
-
-Operators.greaterthanorequal = function(l, r) {
- return l.greaterthanorequal(r);
-};
-
-// XString ///////////////////////////////////////////////////////////////////
-
-XString.prototype = new Expression();
-XString.prototype.constructor = XString;
-XString.superclass = Expression.prototype;
-
-function XString(s) {
- if (arguments.length > 0) {
- this.init(s);
- }
-}
-
-XString.prototype.init = function(s) {
- this.str = String(s);
-};
-
-XString.prototype.toString = function() {
- return this.str;
-};
-
-XString.prototype.evaluate = function(c) {
- return this;
-};
-
-XString.prototype.string = function() {
- return this;
-};
-
-XString.prototype.number = function() {
- return new XNumber(this.str);
-};
-
-XString.prototype.bool = function() {
- return new XBoolean(this.str);
-};
-
-XString.prototype.nodeset = function() {
- throw new Error("Cannot convert string to nodeset");
-};
-
-XString.prototype.stringValue = function() {
- return this.str;
-};
-
-XString.prototype.numberValue = function() {
- return this.number().numberValue();
-};
-
-XString.prototype.booleanValue = function() {
- return this.bool().booleanValue();
-};
-
-XString.prototype.equals = function(r) {
- if (Utilities.instance_of(r, XBoolean)) {
- return this.bool().equals(r);
- }
- if (Utilities.instance_of(r, XNumber)) {
- return this.number().equals(r);
- }
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithString(this, Operators.equals);
- }
- return new XBoolean(this.str == r.str);
-};
-
-XString.prototype.notequal = function(r) {
- if (Utilities.instance_of(r, XBoolean)) {
- return this.bool().notequal(r);
- }
- if (Utilities.instance_of(r, XNumber)) {
- return this.number().notequal(r);
- }
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithString(this, Operators.notequal);
- }
- return new XBoolean(this.str != r.str);
-};
-
-XString.prototype.lessthan = function(r) {
- return this.number().lessthan(r);
-};
-
-XString.prototype.greaterthan = function(r) {
- return this.number().greaterthan(r);
-};
-
-XString.prototype.lessthanorequal = function(r) {
- return this.number().lessthanorequal(r);
-};
-
-XString.prototype.greaterthanorequal = function(r) {
- return this.number().greaterthanorequal(r);
-};
-
-// XNumber ///////////////////////////////////////////////////////////////////
-
-XNumber.prototype = new Expression();
-XNumber.prototype.constructor = XNumber;
-XNumber.superclass = Expression.prototype;
-
-function XNumber(n) {
- if (arguments.length > 0) {
- this.init(n);
- }
-}
-
-XNumber.prototype.init = function(n) {
- this.num = typeof n === "string" ? this.parse(n) : Number(n);
-};
-
-XNumber.prototype.numberFormat = /^\s*-?[0-9]*\.?[0-9]+\s*$/;
-
-XNumber.prototype.parse = function(s) {
- // XPath representation of numbers is more restrictive than what Number() or parseFloat() allow
- return this.numberFormat.test(s) ? parseFloat(s) : Number.NaN;
-};
-
-function padSmallNumber(numberStr) {
- var parts = numberStr.split('e-');
- var base = parts[0].replace('.', '');
- var exponent = Number(parts[1]);
-
- for (var i = 0; i < exponent - 1; i += 1) {
- base = '0' + base;
- }
-
- return '0.' + base;
-}
-
-function padLargeNumber(numberStr) {
- var parts = numberStr.split('e');
- var base = parts[0].replace('.', '');
- var exponent = Number(parts[1]);
- var zerosToAppend = exponent + 1 - base.length;
-
- for (var i = 0; i < zerosToAppend; i += 1){
- base += '0';
- }
-
- return base;
-}
-
-XNumber.prototype.toString = function() {
- var strValue = this.num.toString();
-
- if (strValue.indexOf('e-') !== -1) {
- return padSmallNumber(strValue);
- }
-
- if (strValue.indexOf('e') !== -1) {
- return padLargeNumber(strValue);
- }
-
- return strValue;
-};
-
-XNumber.prototype.evaluate = function(c) {
- return this;
-};
-
-XNumber.prototype.string = function() {
-
-
- return new XString(this.toString());
-};
-
-XNumber.prototype.number = function() {
- return this;
-};
-
-XNumber.prototype.bool = function() {
- return new XBoolean(this.num);
-};
-
-XNumber.prototype.nodeset = function() {
- throw new Error("Cannot convert number to nodeset");
-};
-
-XNumber.prototype.stringValue = function() {
- return this.string().stringValue();
-};
-
-XNumber.prototype.numberValue = function() {
- return this.num;
-};
-
-XNumber.prototype.booleanValue = function() {
- return this.bool().booleanValue();
-};
-
-XNumber.prototype.negate = function() {
- return new XNumber(-this.num);
-};
-
-XNumber.prototype.equals = function(r) {
- if (Utilities.instance_of(r, XBoolean)) {
- return this.bool().equals(r);
- }
- if (Utilities.instance_of(r, XString)) {
- return this.equals(r.number());
- }
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithNumber(this, Operators.equals);
- }
- return new XBoolean(this.num == r.num);
-};
-
-XNumber.prototype.notequal = function(r) {
- if (Utilities.instance_of(r, XBoolean)) {
- return this.bool().notequal(r);
- }
- if (Utilities.instance_of(r, XString)) {
- return this.notequal(r.number());
- }
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithNumber(this, Operators.notequal);
- }
- return new XBoolean(this.num != r.num);
-};
-
-XNumber.prototype.lessthan = function(r) {
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithNumber(this, Operators.greaterthan);
- }
- if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
- return this.lessthan(r.number());
- }
- return new XBoolean(this.num < r.num);
-};
-
-XNumber.prototype.greaterthan = function(r) {
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithNumber(this, Operators.lessthan);
- }
- if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
- return this.greaterthan(r.number());
- }
- return new XBoolean(this.num > r.num);
-};
-
-XNumber.prototype.lessthanorequal = function(r) {
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithNumber(this, Operators.greaterthanorequal);
- }
- if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
- return this.lessthanorequal(r.number());
- }
- return new XBoolean(this.num <= r.num);
-};
-
-XNumber.prototype.greaterthanorequal = function(r) {
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithNumber(this, Operators.lessthanorequal);
- }
- if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
- return this.greaterthanorequal(r.number());
- }
- return new XBoolean(this.num >= r.num);
-};
-
-XNumber.prototype.plus = function(r) {
- return new XNumber(this.num + r.num);
-};
-
-XNumber.prototype.minus = function(r) {
- return new XNumber(this.num - r.num);
-};
-
-XNumber.prototype.multiply = function(r) {
- return new XNumber(this.num * r.num);
-};
-
-XNumber.prototype.div = function(r) {
- return new XNumber(this.num / r.num);
-};
-
-XNumber.prototype.mod = function(r) {
- return new XNumber(this.num % r.num);
-};
-
-// XBoolean //////////////////////////////////////////////////////////////////
-
-XBoolean.prototype = new Expression();
-XBoolean.prototype.constructor = XBoolean;
-XBoolean.superclass = Expression.prototype;
-
-function XBoolean(b) {
- if (arguments.length > 0) {
- this.init(b);
- }
-}
-
-XBoolean.prototype.init = function(b) {
- this.b = Boolean(b);
-};
-
-XBoolean.prototype.toString = function() {
- return this.b.toString();
-};
-
-XBoolean.prototype.evaluate = function(c) {
- return this;
-};
-
-XBoolean.prototype.string = function() {
- return new XString(this.b);
-};
-
-XBoolean.prototype.number = function() {
- return new XNumber(this.b);
-};
-
-XBoolean.prototype.bool = function() {
- return this;
-};
-
-XBoolean.prototype.nodeset = function() {
- throw new Error("Cannot convert boolean to nodeset");
-};
-
-XBoolean.prototype.stringValue = function() {
- return this.string().stringValue();
-};
-
-XBoolean.prototype.numberValue = function() {
- return this.number().numberValue();
-};
-
-XBoolean.prototype.booleanValue = function() {
- return this.b;
-};
-
-XBoolean.prototype.not = function() {
- return new XBoolean(!this.b);
-};
-
-XBoolean.prototype.equals = function(r) {
- if (Utilities.instance_of(r, XString) || Utilities.instance_of(r, XNumber)) {
- return this.equals(r.bool());
- }
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithBoolean(this, Operators.equals);
- }
- return new XBoolean(this.b == r.b);
-};
-
-XBoolean.prototype.notequal = function(r) {
- if (Utilities.instance_of(r, XString) || Utilities.instance_of(r, XNumber)) {
- return this.notequal(r.bool());
- }
- if (Utilities.instance_of(r, XNodeSet)) {
- return r.compareWithBoolean(this, Operators.notequal);
- }
- return new XBoolean(this.b != r.b);
-};
-
-XBoolean.prototype.lessthan = function(r) {
- return this.number().lessthan(r);
-};
-
-XBoolean.prototype.greaterthan = function(r) {
- return this.number().greaterthan(r);
-};
-
-XBoolean.prototype.lessthanorequal = function(r) {
- return this.number().lessthanorequal(r);
-};
-
-XBoolean.prototype.greaterthanorequal = function(r) {
- return this.number().greaterthanorequal(r);
-};
-
-XBoolean.true_ = new XBoolean(true);
-XBoolean.false_ = new XBoolean(false);
-
-// AVLTree ///////////////////////////////////////////////////////////////////
-
-AVLTree.prototype = new Object();
-AVLTree.prototype.constructor = AVLTree;
-AVLTree.superclass = Object.prototype;
-
-function AVLTree(n) {
- this.init(n);
-}
-
-AVLTree.prototype.init = function(n) {
- this.left = null;
- this.right = null;
- this.node = n;
- this.depth = 1;
-};
-
-AVLTree.prototype.balance = function() {
- var ldepth = this.left == null ? 0 : this.left.depth;
- var rdepth = this.right == null ? 0 : this.right.depth;
-
- if (ldepth > rdepth + 1) {
- // LR or LL rotation
- var lldepth = this.left.left == null ? 0 : this.left.left.depth;
- var lrdepth = this.left.right == null ? 0 : this.left.right.depth;
-
- if (lldepth < lrdepth) {
- // LR rotation consists of a RR rotation of the left child
- this.left.rotateRR();
- // plus a LL rotation of this node, which happens anyway
- }
- this.rotateLL();
- } else if (ldepth + 1 < rdepth) {
- // RR or RL rorarion
- var rrdepth = this.right.right == null ? 0 : this.right.right.depth;
- var rldepth = this.right.left == null ? 0 : this.right.left.depth;
-
- if (rldepth > rrdepth) {
- // RR rotation consists of a LL rotation of the right child
- this.right.rotateLL();
- // plus a RR rotation of this node, which happens anyway
- }
- this.rotateRR();
- }
-};
-
-AVLTree.prototype.rotateLL = function() {
- // the left side is too long => rotate from the left (_not_ leftwards)
- var nodeBefore = this.node;
- var rightBefore = this.right;
- this.node = this.left.node;
- this.right = this.left;
- this.left = this.left.left;
- this.right.left = this.right.right;
- this.right.right = rightBefore;
- this.right.node = nodeBefore;
- this.right.updateInNewLocation();
- this.updateInNewLocation();
-};
-
-AVLTree.prototype.rotateRR = function() {
- // the right side is too long => rotate from the right (_not_ rightwards)
- var nodeBefore = this.node;
- var leftBefore = this.left;
- this.node = this.right.node;
- this.left = this.right;
- this.right = this.right.right;
- this.left.right = this.left.left;
- this.left.left = leftBefore;
- this.left.node = nodeBefore;
- this.left.updateInNewLocation();
- this.updateInNewLocation();
-};
-
-AVLTree.prototype.updateInNewLocation = function() {
- this.getDepthFromChildren();
-};
-
-AVLTree.prototype.getDepthFromChildren = function() {
- this.depth = this.node == null ? 0 : 1;
- if (this.left != null) {
- this.depth = this.left.depth + 1;
- }
- if (this.right != null && this.depth <= this.right.depth) {
- this.depth = this.right.depth + 1;
- }
-};
-
-function nodeOrder(n1, n2) {
- if (n1 === n2) {
- return 0;
- }
-
- if (n1.compareDocumentPosition) {
- var cpos = n1.compareDocumentPosition(n2);
-
- if (cpos & 0x01) {
- // not in the same document; return an arbitrary result (is there a better way to do this)
- return 1;
- }
- if (cpos & 0x0A) {
- // n2 precedes or contains n1
- return 1;
- }
- if (cpos & 0x14) {
- // n2 follows or is contained by n1
return -1;
+ };
+ this.reduceActions[57] = function (rhs) {
+ return Step.ATTRIBUTE;
+ };
+ this.reduceActions[59] = function (rhs) {
+ if (rhs[0] == "comment") {
+ return NodeTest.commentTest;
+ } else if (rhs[0] == "text") {
+ return NodeTest.textTest;
+ } else if (rhs[0] == "processing-instruction") {
+ return NodeTest.anyPiTest;
+ } else if (rhs[0] == "node") {
+ return NodeTest.nodeTest;
+ }
+ return new NodeTest(-1, undefined);
+ };
+ this.reduceActions[60] = function (rhs) {
+ return new NodeTest.PITest(rhs[2]);
+ };
+ this.reduceActions[61] = function (rhs) {
+ return rhs[1];
+ };
+ this.reduceActions[63] = function (rhs) {
+ rhs[1].absolute = true;
+ rhs[1].steps.unshift(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
+ return rhs[1];
+ };
+ this.reduceActions[64] = function (rhs) {
+ rhs[0].steps.push(new Step(Step.DESCENDANTORSELF, NodeTest.nodeTest, []));
+ rhs[0].steps.push(rhs[2]);
+ return rhs[0];
+ };
+ this.reduceActions[65] = function (rhs) {
+ return new Step(Step.SELF, NodeTest.nodeTest, []);
+ };
+ this.reduceActions[66] = function (rhs) {
+ return new Step(Step.PARENT, NodeTest.nodeTest, []);
+ };
+ this.reduceActions[67] = function (rhs) {
+ return new VariableReference(rhs[1]);
+ };
+ this.reduceActions[68] = function (rhs) {
+ return NodeTest.nameTestAny;
+ };
+ this.reduceActions[69] = function (rhs) {
+ return new NodeTest.NameTestPrefixAny(rhs[0].split(':')[0]);
+ };
+ this.reduceActions[70] = function (rhs) {
+ return new NodeTest.NameTestQName(rhs[0]);
+ };
+ };
+
+ XPathParser.actionTable = [
+ " s s sssssssss s ss s ss",
+ " s ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ " rrrrr ",
+ " s s sssssssss s ss s ss",
+ "rs rrrrrrrr s sssssrrrrrr rrs rs ",
+ " s s sssssssss s ss s ss",
+ " s ",
+ " s ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ " s ",
+ " s ",
+ " s s sssss s s ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ "a ",
+ "r s rr r ",
+ "r sr rr r ",
+ "r s rr s rr r ",
+ "r rssrr rss rr r ",
+ "r rrrrr rrrss rr r ",
+ "r rrrrrsss rrrrr rr r ",
+ "r rrrrrrrr rrrrr rr r ",
+ "r rrrrrrrr rrrrrs rr r ",
+ "r rrrrrrrr rrrrrr rr r ",
+ "r rrrrrrrr rrrrrr rr r ",
+ "r srrrrrrrr rrrrrrs rr sr ",
+ "r srrrrrrrr rrrrrrs rr r ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrr rrrrrr rr r ",
+ "r rrrrrrrr rrrrrr rr r ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ " sssss ",
+ "r rrrrrrrrr rrrrrrr rr sr ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ " s ",
+ "r srrrrrrrr rrrrrrs rr r ",
+ "r rrrrrrrr rrrrr rr r ",
+ " s ",
+ " s ",
+ " rrrrr ",
+ " s s sssssssss s sss s ss",
+ "r srrrrrrrr rrrrrrs rr r ",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssssssss ss s ss",
+ " s s sssssssss s ss s ss",
+ " s s sssss s s ",
+ " s s sssss s s ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ " s s sssss s s ",
+ " s s sssss s s ",
+ "r rrrrrrrrr rrrrrrr rr sr ",
+ "r rrrrrrrrr rrrrrrr rr sr ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ " s ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ " rr ",
+ " s ",
+ " rs ",
+ "r sr rr r ",
+ "r s rr s rr r ",
+ "r rssrr rss rr r ",
+ "r rssrr rss rr r ",
+ "r rrrrr rrrss rr r ",
+ "r rrrrr rrrss rr r ",
+ "r rrrrr rrrss rr r ",
+ "r rrrrr rrrss rr r ",
+ "r rrrrrsss rrrrr rr r ",
+ "r rrrrrsss rrrrr rr r ",
+ "r rrrrrrrr rrrrr rr r ",
+ "r rrrrrrrr rrrrr rr r ",
+ "r rrrrrrrr rrrrr rr r ",
+ "r rrrrrrrr rrrrrr rr r ",
+ " r ",
+ " s ",
+ "r srrrrrrrr rrrrrrs rr r ",
+ "r srrrrrrrr rrrrrrs rr r ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ "r rrrrrrrrr rrrrrrr rr r ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ " s s sssssssss s ss s ss",
+ "r rrrrrrrrr rrrrrrr rr rr ",
+ " r "
+ ];
+
+ XPathParser.actionTableNumber = [
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " J ",
+ "a aaaaaaaaa aaaaaaa aa a ",
+ " YYYYY ",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ "K1 KKKKKKKK . +*)('KKKKKK KK# K\" ",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " N ",
+ " O ",
+ "e eeeeeeeee eeeeeee ee ee ",
+ "f fffffffff fffffff ff ff ",
+ "d ddddddddd ddddddd dd dd ",
+ "B BBBBBBBBB BBBBBBB BB BB ",
+ "A AAAAAAAAA AAAAAAA AA AA ",
+ " P ",
+ " Q ",
+ " 1 . +*)(' # \" ",
+ "b bbbbbbbbb bbbbbbb bb b ",
+ " ",
+ "! S !! ! ",
+ "\" T\" \"\" \" ",
+ "$ V $$ U $$ $ ",
+ "& &ZY&& &XW && & ",
+ ") ))))) )))\\[ )) ) ",
+ ". ....._^] ..... .. . ",
+ "1 11111111 11111 11 1 ",
+ "5 55555555 55555` 55 5 ",
+ "7 77777777 777777 77 7 ",
+ "9 99999999 999999 99 9 ",
+ ": c:::::::: ::::::b :: a: ",
+ "I fIIIIIIII IIIIIIe II I ",
+ "= ========= ======= == == ",
+ "? ????????? ??????? ?? ?? ",
+ "C CCCCCCCCC CCCCCCC CC CC ",
+ "J JJJJJJJJ JJJJJJ JJ J ",
+ "M MMMMMMMM MMMMMM MM M ",
+ "N NNNNNNNNN NNNNNNN NN N ",
+ "P PPPPPPPPP PPPPPPP PP P ",
+ " +*)(' ",
+ "R RRRRRRRRR RRRRRRR RR aR ",
+ "U UUUUUUUUU UUUUUUU UU U ",
+ "Z ZZZZZZZZZ ZZZZZZZ ZZ ZZ ",
+ "c ccccccccc ccccccc cc cc ",
+ " j ",
+ "L fLLLLLLLL LLLLLLe LL L ",
+ "6 66666666 66666 66 6 ",
+ " k ",
+ " l ",
+ " XXXXX ",
+ " 1 0 /.-,+*)(' & %$m # \"!",
+ "_ f________ ______e __ _ ",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 0 /.-,+*)(' %$ # \"!",
+ " 1 0 /.-,+*)(' & %$ # \"!",
+ " 1 . +*)(' # \" ",
+ " 1 . +*)(' # \" ",
+ "> >>>>>>>>> >>>>>>> >> >> ",
+ " 1 . +*)(' # \" ",
+ " 1 . +*)(' # \" ",
+ "Q QQQQQQQQQ QQQQQQQ QQ aQ ",
+ "V VVVVVVVVV VVVVVVV VV aV ",
+ "T TTTTTTTTT TTTTTTT TT T ",
+ "@ @@@@@@@@@ @@@@@@@ @@ @@ ",
+ " \x87 ",
+ "[ [[[[[[[[[ [[[[[[[ [[ [[ ",
+ "D DDDDDDDDD DDDDDDD DD DD ",
+ " HH ",
+ " \x88 ",
+ " F\x89 ",
+ "# T# ## # ",
+ "% V %% U %% % ",
+ "' 'ZY'' 'XW '' ' ",
+ "( (ZY(( (XW (( ( ",
+ "+ +++++ +++\\[ ++ + ",
+ "* ***** ***\\[ ** * ",
+ "- ----- ---\\[ -- - ",
+ ", ,,,,, ,,,\\[ ,, , ",
+ "0 00000_^] 00000 00 0 ",
+ "/ /////_^] ///// // / ",
+ "2 22222222 22222 22 2 ",
+ "3 33333333 33333 33 3 ",
+ "4 44444444 44444 44 4 ",
+ "8 88888888 888888 88 8 ",
+ " ^ ",
+ " \x8a ",
+ "; f;;;;;;;; ;;;;;;e ;; ; ",
+ "< f<<<<<<<< <<<<<?@ AB CDEFGH IJ ",
+ " ",
+ " ",
+ " ",
+ "L456789:;<=>?@ AB CDEFGH IJ ",
+ " M EFGH IJ ",
+ " N;<=>?@ AB CDEFGH IJ ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " S EFGH IJ ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " e ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " h J ",
+ " i j ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "o456789:;<=>?@ ABpqCDEFGH IJ ",
+ " ",
+ " r6789:;<=>?@ AB CDEFGH IJ ",
+ " s789:;<=>?@ AB CDEFGH IJ ",
+ " t89:;<=>?@ AB CDEFGH IJ ",
+ " u89:;<=>?@ AB CDEFGH IJ ",
+ " v9:;<=>?@ AB CDEFGH IJ ",
+ " w9:;<=>?@ AB CDEFGH IJ ",
+ " x9:;<=>?@ AB CDEFGH IJ ",
+ " y9:;<=>?@ AB CDEFGH IJ ",
+ " z:;<=>?@ AB CDEFGH IJ ",
+ " {:;<=>?@ AB CDEFGH IJ ",
+ " |;<=>?@ AB CDEFGH IJ ",
+ " };<=>?@ AB CDEFGH IJ ",
+ " ~;<=>?@ AB CDEFGH IJ ",
+ " \x7f=>?@ AB CDEFGH IJ ",
+ "\x80456789:;<=>?@ AB CDEFGH IJ\x81",
+ " \x82 EFGH IJ ",
+ " \x83 EFGH IJ ",
+ " ",
+ " \x84 GH IJ ",
+ " \x85 GH IJ ",
+ " i \x86 ",
+ " i \x87 ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "o456789:;<=>?@ AB\x8cqCDEFGH IJ ",
+ " ",
+ " "
+ ];
+
+ XPathParser.productions = [
+ [1, 1, 2],
+ [2, 1, 3],
+ [3, 1, 4],
+ [3, 3, 3, -9, 4],
+ [4, 1, 5],
+ [4, 3, 4, -8, 5],
+ [5, 1, 6],
+ [5, 3, 5, -22, 6],
+ [5, 3, 5, -5, 6],
+ [6, 1, 7],
+ [6, 3, 6, -23, 7],
+ [6, 3, 6, -24, 7],
+ [6, 3, 6, -6, 7],
+ [6, 3, 6, -7, 7],
+ [7, 1, 8],
+ [7, 3, 7, -25, 8],
+ [7, 3, 7, -26, 8],
+ [8, 1, 9],
+ [8, 3, 8, -12, 9],
+ [8, 3, 8, -11, 9],
+ [8, 3, 8, -10, 9],
+ [9, 1, 10],
+ [9, 2, -26, 9],
+ [10, 1, 11],
+ [10, 3, 10, -27, 11],
+ [11, 1, 12],
+ [11, 1, 13],
+ [11, 3, 13, -28, 14],
+ [11, 3, 13, -4, 14],
+ [13, 1, 15],
+ [13, 2, 13, 16],
+ [15, 1, 17],
+ [15, 3, -29, 2, -30],
+ [15, 1, -15],
+ [15, 1, -16],
+ [15, 1, 18],
+ [18, 3, -13, -29, -30],
+ [18, 4, -13, -29, 19, -30],
+ [19, 1, 20],
+ [19, 3, 20, -31, 19],
+ [20, 1, 2],
+ [12, 1, 14],
+ [12, 1, 21],
+ [21, 1, -28],
+ [21, 2, -28, 14],
+ [21, 1, 22],
+ [14, 1, 23],
+ [14, 3, 14, -28, 23],
+ [14, 1, 24],
+ [23, 2, 25, 26],
+ [23, 1, 26],
+ [23, 3, 25, 26, 27],
+ [23, 2, 26, 27],
+ [23, 1, 28],
+ [27, 1, 16],
+ [27, 2, 16, 27],
+ [25, 2, -14, -3],
+ [25, 1, -32],
+ [26, 1, 29],
+ [26, 3, -20, -29, -30],
+ [26, 4, -21, -29, -15, -30],
+ [16, 3, -33, 30, -34],
+ [30, 1, 2],
+ [22, 2, -4, 14],
+ [24, 3, 14, -4, 23],
+ [28, 1, -35],
+ [28, 1, -2],
+ [17, 2, -36, -18],
+ [29, 1, -17],
+ [29, 1, -19],
+ [29, 1, -18]
+ ];
+
+ XPathParser.DOUBLEDOT = 2;
+ XPathParser.DOUBLECOLON = 3;
+ XPathParser.DOUBLESLASH = 4;
+ XPathParser.NOTEQUAL = 5;
+ XPathParser.LESSTHANOREQUAL = 6;
+ XPathParser.GREATERTHANOREQUAL = 7;
+ XPathParser.AND = 8;
+ XPathParser.OR = 9;
+ XPathParser.MOD = 10;
+ XPathParser.DIV = 11;
+ XPathParser.MULTIPLYOPERATOR = 12;
+ XPathParser.FUNCTIONNAME = 13;
+ XPathParser.AXISNAME = 14;
+ XPathParser.LITERAL = 15;
+ XPathParser.NUMBER = 16;
+ XPathParser.ASTERISKNAMETEST = 17;
+ XPathParser.QNAME = 18;
+ XPathParser.NCNAMECOLONASTERISK = 19;
+ XPathParser.NODETYPE = 20;
+ XPathParser.PROCESSINGINSTRUCTIONWITHLITERAL = 21;
+ XPathParser.EQUALS = 22;
+ XPathParser.LESSTHAN = 23;
+ XPathParser.GREATERTHAN = 24;
+ XPathParser.PLUS = 25;
+ XPathParser.MINUS = 26;
+ XPathParser.BAR = 27;
+ XPathParser.SLASH = 28;
+ XPathParser.LEFTPARENTHESIS = 29;
+ XPathParser.RIGHTPARENTHESIS = 30;
+ XPathParser.COMMA = 31;
+ XPathParser.AT = 32;
+ XPathParser.LEFTBRACKET = 33;
+ XPathParser.RIGHTBRACKET = 34;
+ XPathParser.DOT = 35;
+ XPathParser.DOLLAR = 36;
+
+ XPathParser.prototype.tokenize = function (s1) {
+ var types = [];
+ var values = [];
+ var s = s1 + '\0';
+
+ var pos = 0;
+ var c = s.charAt(pos++);
+ while (1) {
+ while (c == ' ' || c == '\t' || c == '\r' || c == '\n') {
+ c = s.charAt(pos++);
+ }
+ if (c == '\0' || pos >= s.length) {
+ break;
+ }
+
+ if (c == '(') {
+ types.push(XPathParser.LEFTPARENTHESIS);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == ')') {
+ types.push(XPathParser.RIGHTPARENTHESIS);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == '[') {
+ types.push(XPathParser.LEFTBRACKET);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == ']') {
+ types.push(XPathParser.RIGHTBRACKET);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == '@') {
+ types.push(XPathParser.AT);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == ',') {
+ types.push(XPathParser.COMMA);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == '|') {
+ types.push(XPathParser.BAR);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == '+') {
+ types.push(XPathParser.PLUS);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == '-') {
+ types.push(XPathParser.MINUS);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == '=') {
+ types.push(XPathParser.EQUALS);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c == '$') {
+ types.push(XPathParser.DOLLAR);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+
+ if (c == '.') {
+ c = s.charAt(pos++);
+ if (c == '.') {
+ types.push(XPathParser.DOUBLEDOT);
+ values.push("..");
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (c >= '0' && c <= '9') {
+ var number = "." + c;
+ c = s.charAt(pos++);
+ while (c >= '0' && c <= '9') {
+ number += c;
+ c = s.charAt(pos++);
+ }
+ types.push(XPathParser.NUMBER);
+ values.push(number);
+ continue;
+ }
+ types.push(XPathParser.DOT);
+ values.push('.');
+ continue;
+ }
+
+ if (c == '\'' || c == '"') {
+ var delimiter = c;
+ var literal = "";
+ while (pos < s.length && (c = s.charAt(pos)) !== delimiter) {
+ literal += c;
+ pos += 1;
+ }
+ if (c !== delimiter) {
+ throw XPathException.fromMessage("Unterminated string literal: " + delimiter + literal);
+ }
+ pos += 1;
+ types.push(XPathParser.LITERAL);
+ values.push(literal);
+ c = s.charAt(pos++);
+ continue;
+ }
+
+ if (c >= '0' && c <= '9') {
+ var number = c;
+ c = s.charAt(pos++);
+ while (c >= '0' && c <= '9') {
+ number += c;
+ c = s.charAt(pos++);
+ }
+ if (c == '.') {
+ if (s.charAt(pos) >= '0' && s.charAt(pos) <= '9') {
+ number += c;
+ number += s.charAt(pos++);
+ c = s.charAt(pos++);
+ while (c >= '0' && c <= '9') {
+ number += c;
+ c = s.charAt(pos++);
+ }
+ }
+ }
+ types.push(XPathParser.NUMBER);
+ values.push(number);
+ continue;
+ }
+
+ if (c == '*') {
+ if (types.length > 0) {
+ var last = types[types.length - 1];
+ if (last != XPathParser.AT
+ && last != XPathParser.DOUBLECOLON
+ && last != XPathParser.LEFTPARENTHESIS
+ && last != XPathParser.LEFTBRACKET
+ && last != XPathParser.AND
+ && last != XPathParser.OR
+ && last != XPathParser.MOD
+ && last != XPathParser.DIV
+ && last != XPathParser.MULTIPLYOPERATOR
+ && last != XPathParser.SLASH
+ && last != XPathParser.DOUBLESLASH
+ && last != XPathParser.BAR
+ && last != XPathParser.PLUS
+ && last != XPathParser.MINUS
+ && last != XPathParser.EQUALS
+ && last != XPathParser.NOTEQUAL
+ && last != XPathParser.LESSTHAN
+ && last != XPathParser.LESSTHANOREQUAL
+ && last != XPathParser.GREATERTHAN
+ && last != XPathParser.GREATERTHANOREQUAL) {
+ types.push(XPathParser.MULTIPLYOPERATOR);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+ }
+ types.push(XPathParser.ASTERISKNAMETEST);
+ values.push(c);
+ c = s.charAt(pos++);
+ continue;
+ }
+
+ if (c == ':') {
+ if (s.charAt(pos) == ':') {
+ types.push(XPathParser.DOUBLECOLON);
+ values.push("::");
+ pos++;
+ c = s.charAt(pos++);
+ continue;
+ }
+ }
+
+ if (c == '/') {
+ c = s.charAt(pos++);
+ if (c == '/') {
+ types.push(XPathParser.DOUBLESLASH);
+ values.push("//");
+ c = s.charAt(pos++);
+ continue;
+ }
+ types.push(XPathParser.SLASH);
+ values.push('/');
+ continue;
+ }
+
+ if (c == '!') {
+ if (s.charAt(pos) == '=') {
+ types.push(XPathParser.NOTEQUAL);
+ values.push("!=");
+ pos++;
+ c = s.charAt(pos++);
+ continue;
+ }
+ }
+
+ if (c == '<') {
+ if (s.charAt(pos) == '=') {
+ types.push(XPathParser.LESSTHANOREQUAL);
+ values.push("<=");
+ pos++;
+ c = s.charAt(pos++);
+ continue;
+ }
+ types.push(XPathParser.LESSTHAN);
+ values.push('<');
+ c = s.charAt(pos++);
+ continue;
+ }
+
+ if (c == '>') {
+ if (s.charAt(pos) == '=') {
+ types.push(XPathParser.GREATERTHANOREQUAL);
+ values.push(">=");
+ pos++;
+ c = s.charAt(pos++);
+ continue;
+ }
+ types.push(XPathParser.GREATERTHAN);
+ values.push('>');
+ c = s.charAt(pos++);
+ continue;
+ }
+
+ if (c == '_' || Utilities.isLetter(c.charCodeAt(0))) {
+ var name = c;
+ c = s.charAt(pos++);
+ while (Utilities.isNCNameChar(c.charCodeAt(0))) {
+ name += c;
+ c = s.charAt(pos++);
+ }
+ if (types.length > 0) {
+ var last = types[types.length - 1];
+ if (last != XPathParser.AT
+ && last != XPathParser.DOUBLECOLON
+ && last != XPathParser.LEFTPARENTHESIS
+ && last != XPathParser.LEFTBRACKET
+ && last != XPathParser.AND
+ && last != XPathParser.OR
+ && last != XPathParser.MOD
+ && last != XPathParser.DIV
+ && last != XPathParser.MULTIPLYOPERATOR
+ && last != XPathParser.SLASH
+ && last != XPathParser.DOUBLESLASH
+ && last != XPathParser.BAR
+ && last != XPathParser.PLUS
+ && last != XPathParser.MINUS
+ && last != XPathParser.EQUALS
+ && last != XPathParser.NOTEQUAL
+ && last != XPathParser.LESSTHAN
+ && last != XPathParser.LESSTHANOREQUAL
+ && last != XPathParser.GREATERTHAN
+ && last != XPathParser.GREATERTHANOREQUAL) {
+ if (name == "and") {
+ types.push(XPathParser.AND);
+ values.push(name);
+ continue;
+ }
+ if (name == "or") {
+ types.push(XPathParser.OR);
+ values.push(name);
+ continue;
+ }
+ if (name == "mod") {
+ types.push(XPathParser.MOD);
+ values.push(name);
+ continue;
+ }
+ if (name == "div") {
+ types.push(XPathParser.DIV);
+ values.push(name);
+ continue;
+ }
+ }
+ }
+ if (c == ':') {
+ if (s.charAt(pos) == '*') {
+ types.push(XPathParser.NCNAMECOLONASTERISK);
+ values.push(name + ":*");
+ pos++;
+ c = s.charAt(pos++);
+ continue;
+ }
+ if (s.charAt(pos) == '_' || Utilities.isLetter(s.charCodeAt(pos))) {
+ name += ':';
+ c = s.charAt(pos++);
+ while (Utilities.isNCNameChar(c.charCodeAt(0))) {
+ name += c;
+ c = s.charAt(pos++);
+ }
+ if (c == '(') {
+ types.push(XPathParser.FUNCTIONNAME);
+ values.push(name);
+ continue;
+ }
+ types.push(XPathParser.QNAME);
+ values.push(name);
+ continue;
+ }
+ if (s.charAt(pos) == ':') {
+ types.push(XPathParser.AXISNAME);
+ values.push(name);
+ continue;
+ }
+ }
+ if (c == '(') {
+ if (name == "comment" || name == "text" || name == "node") {
+ types.push(XPathParser.NODETYPE);
+ values.push(name);
+ continue;
+ }
+ if (name == "processing-instruction") {
+ if (s.charAt(pos) == ')') {
+ types.push(XPathParser.NODETYPE);
+ } else {
+ types.push(XPathParser.PROCESSINGINSTRUCTIONWITHLITERAL);
+ }
+ values.push(name);
+ continue;
+ }
+ types.push(XPathParser.FUNCTIONNAME);
+ values.push(name);
+ continue;
+ }
+ types.push(XPathParser.QNAME);
+ values.push(name);
+ continue;
+ }
+
+ throw new Error("Unexpected character " + c);
+ }
+ types.push(1);
+ values.push("[EOF]");
+ return [types, values];
+ };
+
+ XPathParser.SHIFT = 's';
+ XPathParser.REDUCE = 'r';
+ XPathParser.ACCEPT = 'a';
+
+ XPathParser.prototype.parse = function (s) {
+ var types;
+ var values;
+ var res = this.tokenize(s);
+ if (res == undefined) {
+ return undefined;
+ }
+ types = res[0];
+ values = res[1];
+ var tokenPos = 0;
+ var state = [];
+ var tokenType = [];
+ var tokenValue = [];
+ var s;
+ var a;
+ var t;
+
+ state.push(0);
+ tokenType.push(1);
+ tokenValue.push("_S");
+
+ a = types[tokenPos];
+ t = values[tokenPos++];
+ while (1) {
+ s = state[state.length - 1];
+ switch (XPathParser.actionTable[s].charAt(a - 1)) {
+ case XPathParser.SHIFT:
+ tokenType.push(-a);
+ tokenValue.push(t);
+ state.push(XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32);
+ a = types[tokenPos];
+ t = values[tokenPos++];
+ break;
+ case XPathParser.REDUCE:
+ var num = XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][1];
+ var rhs = [];
+ for (var i = 0; i < num; i++) {
+ tokenType.pop();
+ rhs.unshift(tokenValue.pop());
+ state.pop();
+ }
+ var s_ = state[state.length - 1];
+ tokenType.push(XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][0]);
+ if (this.reduceActions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32] == undefined) {
+ tokenValue.push(rhs[0]);
+ } else {
+ tokenValue.push(this.reduceActions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32](rhs));
+ }
+ state.push(XPathParser.gotoTable[s_].charCodeAt(XPathParser.productions[XPathParser.actionTableNumber[s].charCodeAt(a - 1) - 32][0] - 2) - 33);
+ break;
+ case XPathParser.ACCEPT:
+ return new XPath(tokenValue.pop());
+ default:
+ throw new Error("XPath parse error");
+ }
+ }
+ };
+
+ // XPath /////////////////////////////////////////////////////////////////////
+
+ XPath.prototype = new Object();
+ XPath.prototype.constructor = XPath;
+ XPath.superclass = Object.prototype;
+
+ function XPath(e) {
+ this.expression = e;
+ }
+
+ XPath.prototype.toString = function () {
+ return this.expression.toString();
+ };
+
+ function setIfUnset(obj, prop, value) {
+ if (!(prop in obj)) {
+ obj[prop] = value;
+ }
+ }
+
+ XPath.prototype.evaluate = function (c) {
+ c.contextNode = c.expressionContextNode;
+ c.contextSize = 1;
+ c.contextPosition = 1;
+
+ // [2017-11-25] Removed usage of .implementation.hasFeature() since it does
+ // not reliably detect HTML DOMs (always returns false in xmldom and true in browsers)
+ if (c.isHtml) {
+ setIfUnset(c, 'caseInsensitive', true);
+ setIfUnset(c, 'allowAnyNamespaceForNoPrefix', true);
}
- return 0;
- }
+ setIfUnset(c, 'caseInsensitive', false);
- var d1 = 0,
- d2 = 0;
- for (var m1 = n1; m1 != null; m1 = m1.parentNode || m1.ownerElement) {
- d1++;
- }
- for (var m2 = n2; m2 != null; m2 = m2.parentNode || m2.ownerElement) {
- d2++;
- }
+ return this.expression.evaluate(c);
+ };
- // step up to same depth
- if (d1 > d2) {
- while (d1 > d2) {
- n1 = n1.parentNode || n1.ownerElement;
- d1--;
- }
- if (n1 === n2) {
- return 1;
- }
- } else if (d2 > d1) {
- while (d2 > d1) {
- n2 = n2.parentNode || n2.ownerElement;
- d2--;
- }
- if (n1 === n2) {
- return -1;
- }
- }
+ XPath.XML_NAMESPACE_URI = "http://www.w3.org/XML/1998/namespace";
+ XPath.XMLNS_NAMESPACE_URI = "http://www.w3.org/2000/xmlns/";
- var n1Par = n1.parentNode || n1.ownerElement,
- n2Par = n2.parentNode || n2.ownerElement;
+ // Expression ////////////////////////////////////////////////////////////////
- // find common parent
- while (n1Par !== n2Par) {
- n1 = n1Par;
- n2 = n2Par;
- n1Par = n1.parentNode || n1.ownerElement;
- n2Par = n2.parentNode || n2.ownerElement;
- }
-
- var n1isAttr = Utilities.isAttribute(n1);
- var n2isAttr = Utilities.isAttribute(n2);
-
- if (n1isAttr && !n2isAttr) {
- return -1;
+ Expression.prototype = new Object();
+ Expression.prototype.constructor = Expression;
+ Expression.superclass = Object.prototype;
+
+ function Expression() {
}
- if (!n1isAttr && n2isAttr) {
- return 1;
+
+ Expression.prototype.init = function () {
+ };
+
+ Expression.prototype.toString = function () {
+ return "";
+ };
+
+ Expression.prototype.evaluate = function (c) {
+ throw new Error("Could not evaluate expression.");
+ };
+
+ // UnaryOperation ////////////////////////////////////////////////////////////
+
+ UnaryOperation.prototype = new Expression();
+ UnaryOperation.prototype.constructor = UnaryOperation;
+ UnaryOperation.superclass = Expression.prototype;
+
+ function UnaryOperation(rhs) {
+ if (arguments.length > 0) {
+ this.init(rhs);
+ }
}
-
- if(n1Par) {
- var cn = n1isAttr ? n1Par.attributes : n1Par.childNodes,
- len = cn.length;
- for (var i = 0; i < len; i += 1) {
- var n = cn[i];
- if (n === n1) {
- return -1;
+
+ UnaryOperation.prototype.init = function (rhs) {
+ this.rhs = rhs;
+ };
+
+ // UnaryMinusOperation ///////////////////////////////////////////////////////
+
+ UnaryMinusOperation.prototype = new UnaryOperation();
+ UnaryMinusOperation.prototype.constructor = UnaryMinusOperation;
+ UnaryMinusOperation.superclass = UnaryOperation.prototype;
+
+ function UnaryMinusOperation(rhs) {
+ if (arguments.length > 0) {
+ this.init(rhs);
+ }
+ }
+
+ UnaryMinusOperation.prototype.init = function (rhs) {
+ UnaryMinusOperation.superclass.init.call(this, rhs);
+ };
+
+ UnaryMinusOperation.prototype.evaluate = function (c) {
+ return this.rhs.evaluate(c).number().negate();
+ };
+
+ UnaryMinusOperation.prototype.toString = function () {
+ return "-" + this.rhs.toString();
+ };
+
+ // BinaryOperation ///////////////////////////////////////////////////////////
+
+ BinaryOperation.prototype = new Expression();
+ BinaryOperation.prototype.constructor = BinaryOperation;
+ BinaryOperation.superclass = Expression.prototype;
+
+ function BinaryOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ BinaryOperation.prototype.init = function (lhs, rhs) {
+ this.lhs = lhs;
+ this.rhs = rhs;
+ };
+
+ // OrOperation ///////////////////////////////////////////////////////////////
+
+ OrOperation.prototype = new BinaryOperation();
+ OrOperation.prototype.constructor = OrOperation;
+ OrOperation.superclass = BinaryOperation.prototype;
+
+ function OrOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ OrOperation.prototype.init = function (lhs, rhs) {
+ OrOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ OrOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " or " + this.rhs.toString() + ")";
+ };
+
+ OrOperation.prototype.evaluate = function (c) {
+ var b = this.lhs.evaluate(c).bool();
+ if (b.booleanValue()) {
+ return b;
+ }
+ return this.rhs.evaluate(c).bool();
+ };
+
+ // AndOperation //////////////////////////////////////////////////////////////
+
+ AndOperation.prototype = new BinaryOperation();
+ AndOperation.prototype.constructor = AndOperation;
+ AndOperation.superclass = BinaryOperation.prototype;
+
+ function AndOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ AndOperation.prototype.init = function (lhs, rhs) {
+ AndOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ AndOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " and " + this.rhs.toString() + ")";
+ };
+
+ AndOperation.prototype.evaluate = function (c) {
+ var b = this.lhs.evaluate(c).bool();
+ if (!b.booleanValue()) {
+ return b;
+ }
+ return this.rhs.evaluate(c).bool();
+ };
+
+ // EqualsOperation ///////////////////////////////////////////////////////////
+
+ EqualsOperation.prototype = new BinaryOperation();
+ EqualsOperation.prototype.constructor = EqualsOperation;
+ EqualsOperation.superclass = BinaryOperation.prototype;
+
+ function EqualsOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ EqualsOperation.prototype.init = function (lhs, rhs) {
+ EqualsOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ EqualsOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " = " + this.rhs.toString() + ")";
+ };
+
+ EqualsOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).equals(this.rhs.evaluate(c));
+ };
+
+ // NotEqualOperation /////////////////////////////////////////////////////////
+
+ NotEqualOperation.prototype = new BinaryOperation();
+ NotEqualOperation.prototype.constructor = NotEqualOperation;
+ NotEqualOperation.superclass = BinaryOperation.prototype;
+
+ function NotEqualOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ NotEqualOperation.prototype.init = function (lhs, rhs) {
+ NotEqualOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ NotEqualOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " != " + this.rhs.toString() + ")";
+ };
+
+ NotEqualOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).notequal(this.rhs.evaluate(c));
+ };
+
+ // LessThanOperation /////////////////////////////////////////////////////////
+
+ LessThanOperation.prototype = new BinaryOperation();
+ LessThanOperation.prototype.constructor = LessThanOperation;
+ LessThanOperation.superclass = BinaryOperation.prototype;
+
+ function LessThanOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ LessThanOperation.prototype.init = function (lhs, rhs) {
+ LessThanOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ LessThanOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).lessthan(this.rhs.evaluate(c));
+ };
+
+ LessThanOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " < " + this.rhs.toString() + ")";
+ };
+
+ // GreaterThanOperation //////////////////////////////////////////////////////
+
+ GreaterThanOperation.prototype = new BinaryOperation();
+ GreaterThanOperation.prototype.constructor = GreaterThanOperation;
+ GreaterThanOperation.superclass = BinaryOperation.prototype;
+
+ function GreaterThanOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ GreaterThanOperation.prototype.init = function (lhs, rhs) {
+ GreaterThanOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ GreaterThanOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).greaterthan(this.rhs.evaluate(c));
+ };
+
+ GreaterThanOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " > " + this.rhs.toString() + ")";
+ };
+
+ // LessThanOrEqualOperation //////////////////////////////////////////////////
+
+ LessThanOrEqualOperation.prototype = new BinaryOperation();
+ LessThanOrEqualOperation.prototype.constructor = LessThanOrEqualOperation;
+ LessThanOrEqualOperation.superclass = BinaryOperation.prototype;
+
+ function LessThanOrEqualOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ LessThanOrEqualOperation.prototype.init = function (lhs, rhs) {
+ LessThanOrEqualOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ LessThanOrEqualOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).lessthanorequal(this.rhs.evaluate(c));
+ };
+
+ LessThanOrEqualOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " <= " + this.rhs.toString() + ")";
+ };
+
+ // GreaterThanOrEqualOperation ///////////////////////////////////////////////
+
+ GreaterThanOrEqualOperation.prototype = new BinaryOperation();
+ GreaterThanOrEqualOperation.prototype.constructor = GreaterThanOrEqualOperation;
+ GreaterThanOrEqualOperation.superclass = BinaryOperation.prototype;
+
+ function GreaterThanOrEqualOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ GreaterThanOrEqualOperation.prototype.init = function (lhs, rhs) {
+ GreaterThanOrEqualOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ GreaterThanOrEqualOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).greaterthanorequal(this.rhs.evaluate(c));
+ };
+
+ GreaterThanOrEqualOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " >= " + this.rhs.toString() + ")";
+ };
+
+ // PlusOperation /////////////////////////////////////////////////////////////
+
+ PlusOperation.prototype = new BinaryOperation();
+ PlusOperation.prototype.constructor = PlusOperation;
+ PlusOperation.superclass = BinaryOperation.prototype;
+
+ function PlusOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ PlusOperation.prototype.init = function (lhs, rhs) {
+ PlusOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ PlusOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).number().plus(this.rhs.evaluate(c).number());
+ };
+
+ PlusOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " + " + this.rhs.toString() + ")";
+ };
+
+ // MinusOperation ////////////////////////////////////////////////////////////
+
+ MinusOperation.prototype = new BinaryOperation();
+ MinusOperation.prototype.constructor = MinusOperation;
+ MinusOperation.superclass = BinaryOperation.prototype;
+
+ function MinusOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ MinusOperation.prototype.init = function (lhs, rhs) {
+ MinusOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ MinusOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).number().minus(this.rhs.evaluate(c).number());
+ };
+
+ MinusOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " - " + this.rhs.toString() + ")";
+ };
+
+ // MultiplyOperation /////////////////////////////////////////////////////////
+
+ MultiplyOperation.prototype = new BinaryOperation();
+ MultiplyOperation.prototype.constructor = MultiplyOperation;
+ MultiplyOperation.superclass = BinaryOperation.prototype;
+
+ function MultiplyOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ MultiplyOperation.prototype.init = function (lhs, rhs) {
+ MultiplyOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ MultiplyOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).number().multiply(this.rhs.evaluate(c).number());
+ };
+
+ MultiplyOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " * " + this.rhs.toString() + ")";
+ };
+
+ // DivOperation //////////////////////////////////////////////////////////////
+
+ DivOperation.prototype = new BinaryOperation();
+ DivOperation.prototype.constructor = DivOperation;
+ DivOperation.superclass = BinaryOperation.prototype;
+
+ function DivOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ DivOperation.prototype.init = function (lhs, rhs) {
+ DivOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ DivOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).number().div(this.rhs.evaluate(c).number());
+ };
+
+ DivOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " div " + this.rhs.toString() + ")";
+ };
+
+ // ModOperation //////////////////////////////////////////////////////////////
+
+ ModOperation.prototype = new BinaryOperation();
+ ModOperation.prototype.constructor = ModOperation;
+ ModOperation.superclass = BinaryOperation.prototype;
+
+ function ModOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ ModOperation.prototype.init = function (lhs, rhs) {
+ ModOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ ModOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).number().mod(this.rhs.evaluate(c).number());
+ };
+
+ ModOperation.prototype.toString = function () {
+ return "(" + this.lhs.toString() + " mod " + this.rhs.toString() + ")";
+ };
+
+ // BarOperation //////////////////////////////////////////////////////////////
+
+ BarOperation.prototype = new BinaryOperation();
+ BarOperation.prototype.constructor = BarOperation;
+ BarOperation.superclass = BinaryOperation.prototype;
+
+ function BarOperation(lhs, rhs) {
+ if (arguments.length > 0) {
+ this.init(lhs, rhs);
+ }
+ }
+
+ BarOperation.prototype.init = function (lhs, rhs) {
+ BarOperation.superclass.init.call(this, lhs, rhs);
+ };
+
+ BarOperation.prototype.evaluate = function (c) {
+ return this.lhs.evaluate(c).nodeset().union(this.rhs.evaluate(c).nodeset());
+ };
+
+ BarOperation.prototype.toString = function () {
+ return map(toString, [this.lhs, this.rhs]).join(' | ');
+ };
+
+ // PathExpr //////////////////////////////////////////////////////////////////
+
+ PathExpr.prototype = new Expression();
+ PathExpr.prototype.constructor = PathExpr;
+ PathExpr.superclass = Expression.prototype;
+
+ function PathExpr(filter, filterPreds, locpath) {
+ if (arguments.length > 0) {
+ this.init(filter, filterPreds, locpath);
+ }
+ }
+
+ PathExpr.prototype.init = function (filter, filterPreds, locpath) {
+ PathExpr.superclass.init.call(this);
+ this.filter = filter;
+ this.filterPredicates = filterPreds;
+ this.locationPath = locpath;
+ };
+
+ /**
+ * Returns the topmost node of the tree containing node
+ */
+ function findRoot(node) {
+ while (node && node.parentNode) {
+ node = node.parentNode;
+ }
+
+ return node;
+ }
+
+ PathExpr.applyPredicates = function (predicates, c, nodes) {
+ if (predicates.length === 0) {
+ return nodes;
+ }
+
+ var ctx = c.extend({});
+
+ return reduce(
+ function (inNodes, pred) {
+ ctx.contextSize = inNodes.length;
+
+ return filter(
+ function (node, i) {
+ ctx.contextNode = node;
+ ctx.contextPosition = i + 1;
+
+ return PathExpr.predicateMatches(pred, ctx);
+ },
+ inNodes
+ );
+ },
+ nodes,
+ predicates
+ );
+ };
+
+ PathExpr.getRoot = function (xpc, nodes) {
+ var firstNode = nodes[0];
+
+ if (firstNode.nodeType === 9 /*Node.DOCUMENT_NODE*/) {
+ return firstNode;
+ }
+
+ if (xpc.virtualRoot) {
+ return xpc.virtualRoot;
+ }
+
+ var ownerDoc = firstNode.ownerDocument;
+
+ if (ownerDoc) {
+ return ownerDoc;
+ }
+
+ // IE 5.5 doesn't have ownerDocument?
+ var n = firstNode;
+ while (n.parentNode != null) {
+ n = n.parentNode;
+ }
+ return n;
+ }
+
+ PathExpr.applyStep = function (step, xpc, node) {
+ var self = this;
+ var newNodes = [];
+ xpc.contextNode = node;
+
+ switch (step.axis) {
+ case Step.ANCESTOR:
+ // look at all the ancestor nodes
+ if (xpc.contextNode === xpc.virtualRoot) {
+ break;
+ }
+ var m;
+ if (xpc.contextNode.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
+ m = PathExpr.getOwnerElement(xpc.contextNode);
+ } else {
+ m = xpc.contextNode.parentNode;
+ }
+ while (m != null) {
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ if (m === xpc.virtualRoot) {
+ break;
+ }
+ m = m.parentNode;
+ }
+ break;
+
+ case Step.ANCESTORORSELF:
+ // look at all the ancestor nodes and the current node
+ for (var m = xpc.contextNode; m != null; m = m.nodeType == 2 /*Node.ATTRIBUTE_NODE*/ ? PathExpr.getOwnerElement(m) : m.parentNode) {
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ if (m === xpc.virtualRoot) {
+ break;
+ }
+ }
+ break;
+
+ case Step.ATTRIBUTE:
+ // look at the attributes
+ var nnm = xpc.contextNode.attributes;
+ if (nnm != null) {
+ for (var k = 0; k < nnm.length; k++) {
+ var m = nnm.item(k);
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ }
+ }
+ break;
+
+ case Step.CHILD:
+ // look at all child elements
+ for (var m = xpc.contextNode.firstChild; m != null; m = m.nextSibling) {
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ }
+ break;
+
+ case Step.DESCENDANT:
+ // look at all descendant nodes
+ var st = [xpc.contextNode.firstChild];
+ while (st.length > 0) {
+ for (var m = st.pop(); m != null;) {
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ if (m.firstChild != null) {
+ st.push(m.nextSibling);
+ m = m.firstChild;
+ } else {
+ m = m.nextSibling;
+ }
+ }
+ }
+ break;
+
+ case Step.DESCENDANTORSELF:
+ // look at self
+ if (step.nodeTest.matches(xpc.contextNode, xpc)) {
+ newNodes.push(xpc.contextNode);
+ }
+ // look at all descendant nodes
+ var st = [xpc.contextNode.firstChild];
+ while (st.length > 0) {
+ for (var m = st.pop(); m != null;) {
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ if (m.firstChild != null) {
+ st.push(m.nextSibling);
+ m = m.firstChild;
+ } else {
+ m = m.nextSibling;
+ }
+ }
+ }
+ break;
+
+ case Step.FOLLOWING:
+ if (xpc.contextNode === xpc.virtualRoot) {
+ break;
+ }
+ var st = [];
+ if (xpc.contextNode.firstChild != null) {
+ st.unshift(xpc.contextNode.firstChild);
+ } else {
+ st.unshift(xpc.contextNode.nextSibling);
+ }
+ for (var m = xpc.contextNode.parentNode; m != null && m.nodeType != 9 /*Node.DOCUMENT_NODE*/ && m !== xpc.virtualRoot; m = m.parentNode) {
+ st.unshift(m.nextSibling);
+ }
+ do {
+ for (var m = st.pop(); m != null;) {
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ if (m.firstChild != null) {
+ st.push(m.nextSibling);
+ m = m.firstChild;
+ } else {
+ m = m.nextSibling;
+ }
+ }
+ } while (st.length > 0);
+ break;
+
+ case Step.FOLLOWINGSIBLING:
+ if (xpc.contextNode === xpc.virtualRoot) {
+ break;
+ }
+ for (var m = xpc.contextNode.nextSibling; m != null; m = m.nextSibling) {
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ }
+ break;
+
+ case Step.NAMESPACE:
+ var n = {};
+ if (xpc.contextNode.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ n["xml"] = XPath.XML_NAMESPACE_URI;
+ n["xmlns"] = XPath.XMLNS_NAMESPACE_URI;
+ for (var m = xpc.contextNode; m != null && m.nodeType == 1 /*Node.ELEMENT_NODE*/; m = m.parentNode) {
+ for (var k = 0; k < m.attributes.length; k++) {
+ var attr = m.attributes.item(k);
+ var nm = String(attr.name);
+ if (nm == "xmlns") {
+ if (n[""] == undefined) {
+ n[""] = attr.value;
+ }
+ } else if (nm.length > 6 && nm.substring(0, 6) == "xmlns:") {
+ var pre = nm.substring(6, nm.length);
+ if (n[pre] == undefined) {
+ n[pre] = attr.value;
+ }
+ }
+ }
+ }
+ for (var pre in n) {
+ var nsn = new XPathNamespace(pre, n[pre], xpc.contextNode);
+ if (step.nodeTest.matches(nsn, xpc)) {
+ newNodes.push(nsn);
+ }
+ }
+ }
+ break;
+
+ case Step.PARENT:
+ m = null;
+ if (xpc.contextNode !== xpc.virtualRoot) {
+ if (xpc.contextNode.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
+ m = PathExpr.getOwnerElement(xpc.contextNode);
+ } else {
+ m = xpc.contextNode.parentNode;
+ }
+ }
+ if (m != null && step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ break;
+
+ case Step.PRECEDING:
+ var st;
+ if (xpc.virtualRoot != null) {
+ st = [xpc.virtualRoot];
+ } else {
+ // cannot rely on .ownerDocument because the node may be in a document fragment
+ st = [findRoot(xpc.contextNode)];
+ }
+ outer: while (st.length > 0) {
+ for (var m = st.pop(); m != null;) {
+ if (m == xpc.contextNode) {
+ break outer;
+ }
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.unshift(m);
+ }
+ if (m.firstChild != null) {
+ st.push(m.nextSibling);
+ m = m.firstChild;
+ } else {
+ m = m.nextSibling;
+ }
+ }
+ }
+ break;
+
+ case Step.PRECEDINGSIBLING:
+ if (xpc.contextNode === xpc.virtualRoot) {
+ break;
+ }
+ for (var m = xpc.contextNode.previousSibling; m != null; m = m.previousSibling) {
+ if (step.nodeTest.matches(m, xpc)) {
+ newNodes.push(m);
+ }
+ }
+ break;
+
+ case Step.SELF:
+ if (step.nodeTest.matches(xpc.contextNode, xpc)) {
+ newNodes.push(xpc.contextNode);
+ }
+ break;
+
+ default:
+ }
+
+ return newNodes;
+ };
+
+ function applyStepWithPredicates(step, xpc, node) {
+ return PathExpr.applyPredicates(
+ step.predicates,
+ xpc,
+ PathExpr.applyStep(step, xpc, node)
+ );
+ }
+
+ function applyStepToNodes(context, nodes, step) {
+ return flatten(
+ map(
+ applyStepWithPredicates.bind(null, step, context),
+ nodes
+ )
+ );
+ }
+
+ PathExpr.applySteps = function (steps, xpc, nodes) {
+ return reduce(
+ applyStepToNodes.bind(null, xpc),
+ nodes,
+ steps
+ );
+ }
+
+ PathExpr.prototype.applyFilter = function (c, xpc) {
+ if (!this.filter) {
+ return { nodes: [c.contextNode] };
+ }
+
+ var ns = this.filter.evaluate(c);
+
+ if (!Utilities.instance_of(ns, XNodeSet)) {
+ if (this.filterPredicates != null && this.filterPredicates.length > 0 || this.locationPath != null) {
+ throw new Error("Path expression filter must evaluate to a nodeset if predicates or location path are used");
}
- if (n === n2) {
+
+ return { nonNodes: ns };
+ }
+
+ return {
+ nodes: PathExpr.applyPredicates(this.filterPredicates || [], xpc, ns.toUnsortedArray())
+ };
+ };
+
+ PathExpr.applyLocationPath = function (locationPath, xpc, nodes) {
+ if (!locationPath) {
+ return nodes;
+ }
+
+ var startNodes = locationPath.absolute ? [PathExpr.getRoot(xpc, nodes)] : nodes;
+
+ return PathExpr.applySteps(locationPath.steps, xpc, startNodes);
+ };
+
+ PathExpr.prototype.evaluate = function (c) {
+ var xpc = assign(new XPathContext(), c);
+
+ var filterResult = this.applyFilter(c, xpc);
+
+ if ('nonNodes' in filterResult) {
+ return filterResult.nonNodes;
+ }
+
+ var ns = new XNodeSet();
+ ns.addArray(PathExpr.applyLocationPath(this.locationPath, xpc, filterResult.nodes));
+ return ns;
+ };
+
+ PathExpr.predicateMatches = function (pred, c) {
+ var res = pred.evaluate(c);
+
+ return Utilities.instance_of(res, XNumber)
+ ? c.contextPosition === res.numberValue()
+ : res.booleanValue();
+ };
+
+ PathExpr.predicateString = function (predicate) {
+ return wrap('[', ']', predicate.toString());
+ }
+
+ PathExpr.predicatesString = function (predicates) {
+ return join(
+ '',
+ map(PathExpr.predicateString, predicates)
+ );
+ }
+
+ PathExpr.prototype.toString = function () {
+ if (this.filter != undefined) {
+ var filterStr = toString(this.filter);
+
+ if (Utilities.instance_of(this.filter, XString)) {
+ return wrap("'", "'", filterStr);
+ }
+ if (this.filterPredicates != undefined && this.filterPredicates.length) {
+ return wrap('(', ')', filterStr) +
+ PathExpr.predicatesString(this.filterPredicates);
+ }
+ if (this.locationPath != undefined) {
+ return filterStr +
+ (this.locationPath.absolute ? '' : '/') +
+ toString(this.locationPath);
+ }
+
+ return filterStr;
+ }
+
+ return toString(this.locationPath);
+ };
+
+ PathExpr.getOwnerElement = function (n) {
+ // DOM 2 has ownerElement
+ if (n.ownerElement) {
+ return n.ownerElement;
+ }
+ // DOM 1 Internet Explorer can use selectSingleNode (ironically)
+ try {
+ if (n.selectSingleNode) {
+ return n.selectSingleNode("..");
+ }
+ } catch (e) {
+ }
+ // Other DOM 1 implementations must use this egregious search
+ var doc = n.nodeType == 9 /*Node.DOCUMENT_NODE*/
+ ? n
+ : n.ownerDocument;
+ var elts = doc.getElementsByTagName("*");
+ for (var i = 0; i < elts.length; i++) {
+ var elt = elts.item(i);
+ var nnm = elt.attributes;
+ for (var j = 0; j < nnm.length; j++) {
+ var an = nnm.item(j);
+ if (an === n) {
+ return elt;
+ }
+ }
+ }
+ return null;
+ };
+
+ // LocationPath //////////////////////////////////////////////////////////////
+
+ LocationPath.prototype = new Object();
+ LocationPath.prototype.constructor = LocationPath;
+ LocationPath.superclass = Object.prototype;
+
+ function LocationPath(abs, steps) {
+ if (arguments.length > 0) {
+ this.init(abs, steps);
+ }
+ }
+
+ LocationPath.prototype.init = function (abs, steps) {
+ this.absolute = abs;
+ this.steps = steps;
+ };
+
+ LocationPath.prototype.toString = function () {
+ return (
+ (this.absolute ? '/' : '') +
+ map(toString, this.steps).join('/')
+ );
+ };
+
+ // Step //////////////////////////////////////////////////////////////////////
+
+ Step.prototype = new Object();
+ Step.prototype.constructor = Step;
+ Step.superclass = Object.prototype;
+
+ function Step(axis, nodetest, preds) {
+ if (arguments.length > 0) {
+ this.init(axis, nodetest, preds);
+ }
+ }
+
+ Step.prototype.init = function (axis, nodetest, preds) {
+ this.axis = axis;
+ this.nodeTest = nodetest;
+ this.predicates = preds;
+ };
+
+ Step.prototype.toString = function () {
+ return Step.STEPNAMES[this.axis] +
+ "::" +
+ this.nodeTest.toString() +
+ PathExpr.predicatesString(this.predicates);
+ };
+
+
+ Step.ANCESTOR = 0;
+ Step.ANCESTORORSELF = 1;
+ Step.ATTRIBUTE = 2;
+ Step.CHILD = 3;
+ Step.DESCENDANT = 4;
+ Step.DESCENDANTORSELF = 5;
+ Step.FOLLOWING = 6;
+ Step.FOLLOWINGSIBLING = 7;
+ Step.NAMESPACE = 8;
+ Step.PARENT = 9;
+ Step.PRECEDING = 10;
+ Step.PRECEDINGSIBLING = 11;
+ Step.SELF = 12;
+
+ Step.STEPNAMES = reduce(function (acc, x) { return acc[x[0]] = x[1], acc; }, {}, [
+ [Step.ANCESTOR, 'ancestor'],
+ [Step.ANCESTORORSELF, 'ancestor-or-self'],
+ [Step.ATTRIBUTE, 'attribute'],
+ [Step.CHILD, 'child'],
+ [Step.DESCENDANT, 'descendant'],
+ [Step.DESCENDANTORSELF, 'descendant-or-self'],
+ [Step.FOLLOWING, 'following'],
+ [Step.FOLLOWINGSIBLING, 'following-sibling'],
+ [Step.NAMESPACE, 'namespace'],
+ [Step.PARENT, 'parent'],
+ [Step.PRECEDING, 'preceding'],
+ [Step.PRECEDINGSIBLING, 'preceding-sibling'],
+ [Step.SELF, 'self']
+ ]);
+
+ // NodeTest //////////////////////////////////////////////////////////////////
+
+ NodeTest.prototype = new Object();
+ NodeTest.prototype.constructor = NodeTest;
+ NodeTest.superclass = Object.prototype;
+
+ function NodeTest(type, value) {
+ if (arguments.length > 0) {
+ this.init(type, value);
+ }
+ }
+
+ NodeTest.prototype.init = function (type, value) {
+ this.type = type;
+ this.value = value;
+ };
+
+ NodeTest.prototype.toString = function () {
+ return "";
+ };
+
+ NodeTest.prototype.matches = function (n, xpc) {
+ console.warn('unknown node test type');
+ };
+
+ NodeTest.NAMETESTANY = 0;
+ NodeTest.NAMETESTPREFIXANY = 1;
+ NodeTest.NAMETESTQNAME = 2;
+ NodeTest.COMMENT = 3;
+ NodeTest.TEXT = 4;
+ NodeTest.PI = 5;
+ NodeTest.NODE = 6;
+
+ NodeTest.isNodeType = function (types) {
+ return function (node) {
+ return includes(types, node.nodeType);
+ };
+ };
+
+ NodeTest.makeNodeTestType = function (type, members, ctor) {
+ var newType = ctor || function () { };
+
+ newType.prototype = new NodeTest(members.type);
+ newType.prototype.constructor = type;
+
+ for (var key in members) {
+ newType.prototype[key] = members[key];
+ }
+
+ return newType;
+ };
+ // create invariant node test for certain node types
+ NodeTest.makeNodeTypeTest = function (type, nodeTypes, stringVal) {
+ return new (NodeTest.makeNodeTestType(type, {
+ matches: NodeTest.isNodeType(nodeTypes),
+ toString: always(stringVal)
+ }))();
+ };
+
+ NodeTest.hasPrefix = function (node) {
+ return node.prefix || (node.nodeName || node.tagName).indexOf(':') !== -1;
+ };
+
+ NodeTest.isElementOrAttribute = NodeTest.isNodeType([1, 2]);
+ NodeTest.nameSpaceMatches = function (prefix, xpc, n) {
+ var nNamespace = (n.namespaceURI || '');
+
+ if (!prefix) {
+ return !nNamespace || (xpc.allowAnyNamespaceForNoPrefix && !NodeTest.hasPrefix(n));
+ }
+
+ var ns = xpc.namespaceResolver.getNamespace(prefix, xpc.expressionContextNode);
+
+ if (ns == null) {
+ throw new Error("Cannot resolve QName " + prefix);
+ }
+
+ return ns === nNamespace;
+ };
+ NodeTest.localNameMatches = function (localName, xpc, n) {
+ var nLocalName = (n.localName || n.nodeName);
+
+ return xpc.caseInsensitive
+ ? localName.toLowerCase() === nLocalName.toLowerCase()
+ : localName === nLocalName;
+ };
+
+ NodeTest.NameTestPrefixAny = NodeTest.makeNodeTestType(NodeTest.NAMETESTPREFIXANY, {
+ matches: function (n, xpc) {
+ return NodeTest.isElementOrAttribute(n) &&
+ NodeTest.nameSpaceMatches(this.prefix, xpc, n);
+ },
+ toString: function () {
+ return this.prefix + ":*";
+ }
+ }, function (prefix) { this.prefix = prefix; });
+
+ NodeTest.NameTestQName = NodeTest.makeNodeTestType(NodeTest.NAMETESTQNAME, {
+ matches: function (n, xpc) {
+ return NodeTest.isNodeType([1, 2, XPathNamespace.XPATH_NAMESPACE_NODE])(n) &&
+ NodeTest.nameSpaceMatches(this.prefix, xpc, n) &&
+ NodeTest.localNameMatches(this.localName, xpc, n);
+ },
+ toString: function () {
+ return this.name;
+ }
+ }, function (name) {
+ var nameParts = name.split(':');
+
+ this.name = name;
+ this.prefix = nameParts.length > 1 ? nameParts[0] : null;
+ this.localName = nameParts[nameParts.length > 1 ? 1 : 0];
+ });
+
+ NodeTest.PITest = NodeTest.makeNodeTestType(NodeTest.PI, {
+ matches: function (n, xpc) {
+ return NodeTest.isNodeType([7])(n) && (n.target || n.nodeName) === this.name;
+ },
+ toString: function () {
+ return wrap('processing-instruction("', '")', this.name);
+ }
+ }, function (name) { this.name = name; })
+
+ // singletons
+
+ // elements, attributes, namespaces
+ NodeTest.nameTestAny = NodeTest.makeNodeTypeTest(NodeTest.NAMETESTANY, [1, 2, XPathNamespace.XPATH_NAMESPACE_NODE], '*');
+ // text, cdata
+ NodeTest.textTest = NodeTest.makeNodeTypeTest(NodeTest.TEXT, [3, 4], 'text()');
+ NodeTest.commentTest = NodeTest.makeNodeTypeTest(NodeTest.COMMENT, [8], 'comment()');
+ // elements, attributes, text, cdata, PIs, comments, document nodes
+ NodeTest.nodeTest = NodeTest.makeNodeTypeTest(NodeTest.NODE, [1, 2, 3, 4, 7, 8, 9], 'node()');
+ NodeTest.anyPiTest = NodeTest.makeNodeTypeTest(NodeTest.PI, [7], 'processing-instruction()');
+
+ // VariableReference /////////////////////////////////////////////////////////
+
+ VariableReference.prototype = new Expression();
+ VariableReference.prototype.constructor = VariableReference;
+ VariableReference.superclass = Expression.prototype;
+
+ function VariableReference(v) {
+ if (arguments.length > 0) {
+ this.init(v);
+ }
+ }
+
+ VariableReference.prototype.init = function (v) {
+ this.variable = v;
+ };
+
+ VariableReference.prototype.toString = function () {
+ return "$" + this.variable;
+ };
+
+ VariableReference.prototype.evaluate = function (c) {
+ var parts = Utilities.resolveQName(this.variable, c.namespaceResolver, c.contextNode, false);
+
+ if (parts[0] == null) {
+ throw new Error("Cannot resolve QName " + fn);
+ }
+ var result = c.variableResolver.getVariable(parts[1], parts[0]);
+ if (!result) {
+ throw XPathException.fromMessage("Undeclared variable: " + this.toString());
+ }
+ return result;
+ };
+
+ // FunctionCall //////////////////////////////////////////////////////////////
+
+ FunctionCall.prototype = new Expression();
+ FunctionCall.prototype.constructor = FunctionCall;
+ FunctionCall.superclass = Expression.prototype;
+
+ function FunctionCall(fn, args) {
+ if (arguments.length > 0) {
+ this.init(fn, args);
+ }
+ }
+
+ FunctionCall.prototype.init = function (fn, args) {
+ this.functionName = fn;
+ this.arguments = args;
+ };
+
+ FunctionCall.prototype.toString = function () {
+ var s = this.functionName + "(";
+ for (var i = 0; i < this.arguments.length; i++) {
+ if (i > 0) {
+ s += ", ";
+ }
+ s += this.arguments[i].toString();
+ }
+ return s + ")";
+ };
+
+ FunctionCall.prototype.evaluate = function (c) {
+ var f = FunctionResolver.getFunctionFromContext(this.functionName, c);
+
+ if (!f) {
+ throw new Error("Unknown function " + this.functionName);
+ }
+
+ var a = [c].concat(this.arguments);
+ return f.apply(c.functionResolver.thisArg, a);
+ };
+
+ // Operators /////////////////////////////////////////////////////////////////
+
+ var Operators = new Object();
+
+ Operators.equals = function (l, r) {
+ return l.equals(r);
+ };
+
+ Operators.notequal = function (l, r) {
+ return l.notequal(r);
+ };
+
+ Operators.lessthan = function (l, r) {
+ return l.lessthan(r);
+ };
+
+ Operators.greaterthan = function (l, r) {
+ return l.greaterthan(r);
+ };
+
+ Operators.lessthanorequal = function (l, r) {
+ return l.lessthanorequal(r);
+ };
+
+ Operators.greaterthanorequal = function (l, r) {
+ return l.greaterthanorequal(r);
+ };
+
+ // XString ///////////////////////////////////////////////////////////////////
+
+ XString.prototype = new Expression();
+ XString.prototype.constructor = XString;
+ XString.superclass = Expression.prototype;
+
+ function XString(s) {
+ if (arguments.length > 0) {
+ this.init(s);
+ }
+ }
+
+ XString.prototype.init = function (s) {
+ this.str = String(s);
+ };
+
+ XString.prototype.toString = function () {
+ return this.str;
+ };
+
+ XString.prototype.evaluate = function (c) {
+ return this;
+ };
+
+ XString.prototype.string = function () {
+ return this;
+ };
+
+ XString.prototype.number = function () {
+ return new XNumber(this.str);
+ };
+
+ XString.prototype.bool = function () {
+ return new XBoolean(this.str);
+ };
+
+ XString.prototype.nodeset = function () {
+ throw new Error("Cannot convert string to nodeset");
+ };
+
+ XString.prototype.stringValue = function () {
+ return this.str;
+ };
+
+ XString.prototype.numberValue = function () {
+ return this.number().numberValue();
+ };
+
+ XString.prototype.booleanValue = function () {
+ return this.bool().booleanValue();
+ };
+
+ XString.prototype.equals = function (r) {
+ if (Utilities.instance_of(r, XBoolean)) {
+ return this.bool().equals(r);
+ }
+ if (Utilities.instance_of(r, XNumber)) {
+ return this.number().equals(r);
+ }
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithString(this, Operators.equals);
+ }
+ return new XBoolean(this.str == r.str);
+ };
+
+ XString.prototype.notequal = function (r) {
+ if (Utilities.instance_of(r, XBoolean)) {
+ return this.bool().notequal(r);
+ }
+ if (Utilities.instance_of(r, XNumber)) {
+ return this.number().notequal(r);
+ }
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithString(this, Operators.notequal);
+ }
+ return new XBoolean(this.str != r.str);
+ };
+
+ XString.prototype.lessthan = function (r) {
+ return this.number().lessthan(r);
+ };
+
+ XString.prototype.greaterthan = function (r) {
+ return this.number().greaterthan(r);
+ };
+
+ XString.prototype.lessthanorequal = function (r) {
+ return this.number().lessthanorequal(r);
+ };
+
+ XString.prototype.greaterthanorequal = function (r) {
+ return this.number().greaterthanorequal(r);
+ };
+
+ // XNumber ///////////////////////////////////////////////////////////////////
+
+ XNumber.prototype = new Expression();
+ XNumber.prototype.constructor = XNumber;
+ XNumber.superclass = Expression.prototype;
+
+ function XNumber(n) {
+ if (arguments.length > 0) {
+ this.init(n);
+ }
+ }
+
+ XNumber.prototype.init = function (n) {
+ this.num = typeof n === "string" ? this.parse(n) : Number(n);
+ };
+
+ XNumber.prototype.numberFormat = /^\s*-?[0-9]*\.?[0-9]+\s*$/;
+
+ XNumber.prototype.parse = function (s) {
+ // XPath representation of numbers is more restrictive than what Number() or parseFloat() allow
+ return this.numberFormat.test(s) ? parseFloat(s) : Number.NaN;
+ };
+
+ function padSmallNumber(numberStr) {
+ var parts = numberStr.split('e-');
+ var base = parts[0].replace('.', '');
+ var exponent = Number(parts[1]);
+
+ for (var i = 0; i < exponent - 1; i += 1) {
+ base = '0' + base;
+ }
+
+ return '0.' + base;
+ }
+
+ function padLargeNumber(numberStr) {
+ var parts = numberStr.split('e');
+ var base = parts[0].replace('.', '');
+ var exponent = Number(parts[1]);
+ var zerosToAppend = exponent + 1 - base.length;
+
+ for (var i = 0; i < zerosToAppend; i += 1) {
+ base += '0';
+ }
+
+ return base;
+ }
+
+ XNumber.prototype.toString = function () {
+ var strValue = this.num.toString();
+
+ if (strValue.indexOf('e-') !== -1) {
+ return padSmallNumber(strValue);
+ }
+
+ if (strValue.indexOf('e') !== -1) {
+ return padLargeNumber(strValue);
+ }
+
+ return strValue;
+ };
+
+ XNumber.prototype.evaluate = function (c) {
+ return this;
+ };
+
+ XNumber.prototype.string = function () {
+
+
+ return new XString(this.toString());
+ };
+
+ XNumber.prototype.number = function () {
+ return this;
+ };
+
+ XNumber.prototype.bool = function () {
+ return new XBoolean(this.num);
+ };
+
+ XNumber.prototype.nodeset = function () {
+ throw new Error("Cannot convert number to nodeset");
+ };
+
+ XNumber.prototype.stringValue = function () {
+ return this.string().stringValue();
+ };
+
+ XNumber.prototype.numberValue = function () {
+ return this.num;
+ };
+
+ XNumber.prototype.booleanValue = function () {
+ return this.bool().booleanValue();
+ };
+
+ XNumber.prototype.negate = function () {
+ return new XNumber(-this.num);
+ };
+
+ XNumber.prototype.equals = function (r) {
+ if (Utilities.instance_of(r, XBoolean)) {
+ return this.bool().equals(r);
+ }
+ if (Utilities.instance_of(r, XString)) {
+ return this.equals(r.number());
+ }
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithNumber(this, Operators.equals);
+ }
+ return new XBoolean(this.num == r.num);
+ };
+
+ XNumber.prototype.notequal = function (r) {
+ if (Utilities.instance_of(r, XBoolean)) {
+ return this.bool().notequal(r);
+ }
+ if (Utilities.instance_of(r, XString)) {
+ return this.notequal(r.number());
+ }
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithNumber(this, Operators.notequal);
+ }
+ return new XBoolean(this.num != r.num);
+ };
+
+ XNumber.prototype.lessthan = function (r) {
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithNumber(this, Operators.greaterthan);
+ }
+ if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
+ return this.lessthan(r.number());
+ }
+ return new XBoolean(this.num < r.num);
+ };
+
+ XNumber.prototype.greaterthan = function (r) {
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithNumber(this, Operators.lessthan);
+ }
+ if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
+ return this.greaterthan(r.number());
+ }
+ return new XBoolean(this.num > r.num);
+ };
+
+ XNumber.prototype.lessthanorequal = function (r) {
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithNumber(this, Operators.greaterthanorequal);
+ }
+ if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
+ return this.lessthanorequal(r.number());
+ }
+ return new XBoolean(this.num <= r.num);
+ };
+
+ XNumber.prototype.greaterthanorequal = function (r) {
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithNumber(this, Operators.lessthanorequal);
+ }
+ if (Utilities.instance_of(r, XBoolean) || Utilities.instance_of(r, XString)) {
+ return this.greaterthanorequal(r.number());
+ }
+ return new XBoolean(this.num >= r.num);
+ };
+
+ XNumber.prototype.plus = function (r) {
+ return new XNumber(this.num + r.num);
+ };
+
+ XNumber.prototype.minus = function (r) {
+ return new XNumber(this.num - r.num);
+ };
+
+ XNumber.prototype.multiply = function (r) {
+ return new XNumber(this.num * r.num);
+ };
+
+ XNumber.prototype.div = function (r) {
+ return new XNumber(this.num / r.num);
+ };
+
+ XNumber.prototype.mod = function (r) {
+ return new XNumber(this.num % r.num);
+ };
+
+ // XBoolean //////////////////////////////////////////////////////////////////
+
+ XBoolean.prototype = new Expression();
+ XBoolean.prototype.constructor = XBoolean;
+ XBoolean.superclass = Expression.prototype;
+
+ function XBoolean(b) {
+ if (arguments.length > 0) {
+ this.init(b);
+ }
+ }
+
+ XBoolean.prototype.init = function (b) {
+ this.b = Boolean(b);
+ };
+
+ XBoolean.prototype.toString = function () {
+ return this.b.toString();
+ };
+
+ XBoolean.prototype.evaluate = function (c) {
+ return this;
+ };
+
+ XBoolean.prototype.string = function () {
+ return new XString(this.b);
+ };
+
+ XBoolean.prototype.number = function () {
+ return new XNumber(this.b);
+ };
+
+ XBoolean.prototype.bool = function () {
+ return this;
+ };
+
+ XBoolean.prototype.nodeset = function () {
+ throw new Error("Cannot convert boolean to nodeset");
+ };
+
+ XBoolean.prototype.stringValue = function () {
+ return this.string().stringValue();
+ };
+
+ XBoolean.prototype.numberValue = function () {
+ return this.number().numberValue();
+ };
+
+ XBoolean.prototype.booleanValue = function () {
+ return this.b;
+ };
+
+ XBoolean.prototype.not = function () {
+ return new XBoolean(!this.b);
+ };
+
+ XBoolean.prototype.equals = function (r) {
+ if (Utilities.instance_of(r, XString) || Utilities.instance_of(r, XNumber)) {
+ return this.equals(r.bool());
+ }
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithBoolean(this, Operators.equals);
+ }
+ return new XBoolean(this.b == r.b);
+ };
+
+ XBoolean.prototype.notequal = function (r) {
+ if (Utilities.instance_of(r, XString) || Utilities.instance_of(r, XNumber)) {
+ return this.notequal(r.bool());
+ }
+ if (Utilities.instance_of(r, XNodeSet)) {
+ return r.compareWithBoolean(this, Operators.notequal);
+ }
+ return new XBoolean(this.b != r.b);
+ };
+
+ XBoolean.prototype.lessthan = function (r) {
+ return this.number().lessthan(r);
+ };
+
+ XBoolean.prototype.greaterthan = function (r) {
+ return this.number().greaterthan(r);
+ };
+
+ XBoolean.prototype.lessthanorequal = function (r) {
+ return this.number().lessthanorequal(r);
+ };
+
+ XBoolean.prototype.greaterthanorequal = function (r) {
+ return this.number().greaterthanorequal(r);
+ };
+
+ XBoolean.true_ = new XBoolean(true);
+ XBoolean.false_ = new XBoolean(false);
+
+ // AVLTree ///////////////////////////////////////////////////////////////////
+
+ AVLTree.prototype = new Object();
+ AVLTree.prototype.constructor = AVLTree;
+ AVLTree.superclass = Object.prototype;
+
+ function AVLTree(n) {
+ this.init(n);
+ }
+
+ AVLTree.prototype.init = function (n) {
+ this.left = null;
+ this.right = null;
+ this.node = n;
+ this.depth = 1;
+ };
+
+ AVLTree.prototype.balance = function () {
+ var ldepth = this.left == null ? 0 : this.left.depth;
+ var rdepth = this.right == null ? 0 : this.right.depth;
+
+ if (ldepth > rdepth + 1) {
+ // LR or LL rotation
+ var lldepth = this.left.left == null ? 0 : this.left.left.depth;
+ var lrdepth = this.left.right == null ? 0 : this.left.right.depth;
+
+ if (lldepth < lrdepth) {
+ // LR rotation consists of a RR rotation of the left child
+ this.left.rotateRR();
+ // plus a LL rotation of this node, which happens anyway
+ }
+ this.rotateLL();
+ } else if (ldepth + 1 < rdepth) {
+ // RR or RL rorarion
+ var rrdepth = this.right.right == null ? 0 : this.right.right.depth;
+ var rldepth = this.right.left == null ? 0 : this.right.left.depth;
+
+ if (rldepth > rrdepth) {
+ // RR rotation consists of a LL rotation of the right child
+ this.right.rotateLL();
+ // plus a RR rotation of this node, which happens anyway
+ }
+ this.rotateRR();
+ }
+ };
+
+ AVLTree.prototype.rotateLL = function () {
+ // the left side is too long => rotate from the left (_not_ leftwards)
+ var nodeBefore = this.node;
+ var rightBefore = this.right;
+ this.node = this.left.node;
+ this.right = this.left;
+ this.left = this.left.left;
+ this.right.left = this.right.right;
+ this.right.right = rightBefore;
+ this.right.node = nodeBefore;
+ this.right.updateInNewLocation();
+ this.updateInNewLocation();
+ };
+
+ AVLTree.prototype.rotateRR = function () {
+ // the right side is too long => rotate from the right (_not_ rightwards)
+ var nodeBefore = this.node;
+ var leftBefore = this.left;
+ this.node = this.right.node;
+ this.left = this.right;
+ this.right = this.right.right;
+ this.left.right = this.left.left;
+ this.left.left = leftBefore;
+ this.left.node = nodeBefore;
+ this.left.updateInNewLocation();
+ this.updateInNewLocation();
+ };
+
+ AVLTree.prototype.updateInNewLocation = function () {
+ this.getDepthFromChildren();
+ };
+
+ AVLTree.prototype.getDepthFromChildren = function () {
+ this.depth = this.node == null ? 0 : 1;
+ if (this.left != null) {
+ this.depth = this.left.depth + 1;
+ }
+ if (this.right != null && this.depth <= this.right.depth) {
+ this.depth = this.right.depth + 1;
+ }
+ };
+
+ function nodeOrder(n1, n2) {
+ if (n1 === n2) {
+ return 0;
+ }
+
+ if (n1.compareDocumentPosition) {
+ var cpos = n1.compareDocumentPosition(n2);
+
+ if (cpos & 0x01) {
+ // not in the same document; return an arbitrary result (is there a better way to do this)
return 1;
}
+ if (cpos & 0x0A) {
+ // n2 precedes or contains n1
+ return 1;
+ }
+ if (cpos & 0x14) {
+ // n2 follows or is contained by n1
+ return -1;
+ }
+
+ return 0;
}
- }
-
- throw new Error('Unexpected: could not determine node order');
-}
-AVLTree.prototype.add = function(n) {
- if (n === this.node) {
- return false;
- }
+ var d1 = 0,
+ d2 = 0;
+ for (var m1 = n1; m1 != null; m1 = m1.parentNode || m1.ownerElement) {
+ d1++;
+ }
+ for (var m2 = n2; m2 != null; m2 = m2.parentNode || m2.ownerElement) {
+ d2++;
+ }
- var o = nodeOrder(n, this.node);
-
- var ret = false;
- if (o == -1) {
- if (this.left == null) {
- this.left = new AVLTree(n);
- ret = true;
- } else {
- ret = this.left.add(n);
- if (ret) {
- this.balance();
+ // step up to same depth
+ if (d1 > d2) {
+ while (d1 > d2) {
+ n1 = n1.parentNode || n1.ownerElement;
+ d1--;
+ }
+ if (n1 === n2) {
+ return 1;
+ }
+ } else if (d2 > d1) {
+ while (d2 > d1) {
+ n2 = n2.parentNode || n2.ownerElement;
+ d2--;
+ }
+ if (n1 === n2) {
+ return -1;
}
}
- } else if (o == 1) {
- if (this.right == null) {
- this.right = new AVLTree(n);
- ret = true;
- } else {
- ret = this.right.add(n);
- if (ret) {
- this.balance();
- }
- }
- }
- if (ret) {
- this.getDepthFromChildren();
- }
- return ret;
-};
+ var n1Par = n1.parentNode || n1.ownerElement,
+ n2Par = n2.parentNode || n2.ownerElement;
-// XNodeSet //////////////////////////////////////////////////////////////////
-
-XNodeSet.prototype = new Expression();
-XNodeSet.prototype.constructor = XNodeSet;
-XNodeSet.superclass = Expression.prototype;
-
-function XNodeSet() {
- this.init();
-}
-
-XNodeSet.prototype.init = function() {
- this.tree = null;
- this.nodes = [];
- this.size = 0;
-};
-
-XNodeSet.prototype.toString = function() {
- var p = this.first();
- if (p == null) {
- return "";
- }
- return this.stringForNode(p);
-};
-
-XNodeSet.prototype.evaluate = function(c) {
- return this;
-};
-
-XNodeSet.prototype.string = function() {
- return new XString(this.toString());
-};
-
-XNodeSet.prototype.stringValue = function() {
- return this.toString();
-};
-
-XNodeSet.prototype.number = function() {
- return new XNumber(this.string());
-};
-
-XNodeSet.prototype.numberValue = function() {
- return Number(this.string());
-};
-
-XNodeSet.prototype.bool = function() {
- return new XBoolean(this.booleanValue());
-};
-
-XNodeSet.prototype.booleanValue = function() {
- return !!this.size;
-};
-
-XNodeSet.prototype.nodeset = function() {
- return this;
-};
-
-XNodeSet.prototype.stringForNode = function(n) {
- if (n.nodeType == 9 /*Node.DOCUMENT_NODE*/ ||
- n.nodeType == 1 /*Node.ELEMENT_NODE */ ||
- n.nodeType === 11 /*Node.DOCUMENT_FRAGMENT*/) {
- return this.stringForContainerNode(n);
- }
- if (n.nodeType === 2 /* Node.ATTRIBUTE_NODE */) {
- return n.value || n.nodeValue;
- }
- if (n.isNamespaceNode) {
- return n.namespace;
- }
- return n.nodeValue;
-};
-
-XNodeSet.prototype.stringForContainerNode = function(n) {
- var s = "";
- for (var n2 = n.firstChild; n2 != null; n2 = n2.nextSibling) {
- var nt = n2.nodeType;
- // Element, Text, CDATA, Document, Document Fragment
- if (nt === 1 || nt === 3 || nt === 4 || nt === 9 || nt === 11) {
- s += this.stringForNode(n2);
- }
- }
- return s;
-};
-
-XNodeSet.prototype.buildTree = function () {
- if (!this.tree && this.nodes.length) {
- this.tree = new AVLTree(this.nodes[0]);
- for (var i = 1; i < this.nodes.length; i += 1) {
- this.tree.add(this.nodes[i]);
- }
- }
-
- return this.tree;
-};
-
-XNodeSet.prototype.first = function() {
- var p = this.buildTree();
- if (p == null) {
- return null;
- }
- while (p.left != null) {
- p = p.left;
- }
- return p.node;
-};
-
-XNodeSet.prototype.add = function(n) {
- for (var i = 0; i < this.nodes.length; i += 1) {
- if (n === this.nodes[i]) {
- return;
- }
- }
-
- this.tree = null;
- this.nodes.push(n);
- this.size += 1;
-};
-
-XNodeSet.prototype.addArray = function(ns) {
- var self = this;
-
- forEach(function (x) { self.add(x); }, ns);
-};
-
-/**
- * Returns an array of the node set's contents in document order
- */
-XNodeSet.prototype.toArray = function() {
- var a = [];
- this.toArrayRec(this.buildTree(), a);
- return a;
-};
-
-XNodeSet.prototype.toArrayRec = function(t, a) {
- if (t != null) {
- this.toArrayRec(t.left, a);
- a.push(t.node);
- this.toArrayRec(t.right, a);
- }
-};
-
-/**
- * Returns an array of the node set's contents in arbitrary order
- */
-XNodeSet.prototype.toUnsortedArray = function () {
- return this.nodes.slice();
-};
-
-XNodeSet.prototype.compareWithString = function(r, o) {
- var a = this.toUnsortedArray();
- for (var i = 0; i < a.length; i++) {
- var n = a[i];
- var l = new XString(this.stringForNode(n));
- var res = o(l, r);
- if (res.booleanValue()) {
- return res;
- }
- }
- return new XBoolean(false);
-};
-
-XNodeSet.prototype.compareWithNumber = function(r, o) {
- var a = this.toUnsortedArray();
- for (var i = 0; i < a.length; i++) {
- var n = a[i];
- var l = new XNumber(this.stringForNode(n));
- var res = o(l, r);
- if (res.booleanValue()) {
- return res;
- }
- }
- return new XBoolean(false);
-};
-
-XNodeSet.prototype.compareWithBoolean = function(r, o) {
- return o(this.bool(), r);
-};
-
-XNodeSet.prototype.compareWithNodeSet = function(r, o) {
- var arr = this.toUnsortedArray();
- var oInvert = function (lop, rop) { return o(rop, lop); };
-
- for (var i = 0; i < arr.length; i++) {
- var l = new XString(this.stringForNode(arr[i]));
-
- var res = r.compareWithString(l, oInvert);
- if (res.booleanValue()) {
- return res;
- }
- }
-
- return new XBoolean(false);
-};
-
-XNodeSet.compareWith = curry(function (o, r) {
- if (Utilities.instance_of(r, XString)) {
- return this.compareWithString(r, o);
- }
- if (Utilities.instance_of(r, XNumber)) {
- return this.compareWithNumber(r, o);
- }
- if (Utilities.instance_of(r, XBoolean)) {
- return this.compareWithBoolean(r, o);
- }
- return this.compareWithNodeSet(r, o);
-});
-
-XNodeSet.prototype.equals = XNodeSet.compareWith(Operators.equals);
-XNodeSet.prototype.notequal = XNodeSet.compareWith(Operators.notequal);
-XNodeSet.prototype.lessthan = XNodeSet.compareWith(Operators.lessthan);
-XNodeSet.prototype.greaterthan = XNodeSet.compareWith(Operators.greaterthan);
-XNodeSet.prototype.lessthanorequal = XNodeSet.compareWith(Operators.lessthanorequal);
-XNodeSet.prototype.greaterthanorequal = XNodeSet.compareWith(Operators.greaterthanorequal);
-
-XNodeSet.prototype.union = function(r) {
- var ns = new XNodeSet();
- ns.addArray(this.toUnsortedArray());
- ns.addArray(r.toUnsortedArray());
- return ns;
-};
-
-// XPathNamespace ////////////////////////////////////////////////////////////
-
-XPathNamespace.prototype = new Object();
-XPathNamespace.prototype.constructor = XPathNamespace;
-XPathNamespace.superclass = Object.prototype;
-
-function XPathNamespace(pre, ns, p) {
- this.isXPathNamespace = true;
- this.ownerDocument = p.ownerDocument;
- this.nodeName = "#namespace";
- this.prefix = pre;
- this.localName = pre;
- this.namespaceURI = ns;
- this.nodeValue = ns;
- this.ownerElement = p;
- this.nodeType = XPathNamespace.XPATH_NAMESPACE_NODE;
-}
-
-XPathNamespace.prototype.toString = function() {
- return "{ \"" + this.prefix + "\", \"" + this.namespaceURI + "\" }";
-};
-
-// XPathContext //////////////////////////////////////////////////////////////
-
-XPathContext.prototype = new Object();
-XPathContext.prototype.constructor = XPathContext;
-XPathContext.superclass = Object.prototype;
-
-function XPathContext(vr, nr, fr) {
- this.variableResolver = vr != null ? vr : new VariableResolver();
- this.namespaceResolver = nr != null ? nr : new NamespaceResolver();
- this.functionResolver = fr != null ? fr : new FunctionResolver();
-}
-
-XPathContext.prototype.extend = function (newProps) {
- return assign(new XPathContext(), this, newProps);
-};
-
-// VariableResolver //////////////////////////////////////////////////////////
-
-VariableResolver.prototype = new Object();
-VariableResolver.prototype.constructor = VariableResolver;
-VariableResolver.superclass = Object.prototype;
-
-function VariableResolver() {
-}
-
-VariableResolver.prototype.getVariable = function(ln, ns) {
- return null;
-};
-
-// FunctionResolver //////////////////////////////////////////////////////////
-
-FunctionResolver.prototype = new Object();
-FunctionResolver.prototype.constructor = FunctionResolver;
-FunctionResolver.superclass = Object.prototype;
-
-function FunctionResolver(thisArg) {
- this.thisArg = thisArg != null ? thisArg : Functions;
- this.functions = new Object();
- this.addStandardFunctions();
-}
-
-FunctionResolver.prototype.addStandardFunctions = function() {
- this.functions["{}last"] = Functions.last;
- this.functions["{}position"] = Functions.position;
- this.functions["{}count"] = Functions.count;
- this.functions["{}id"] = Functions.id;
- this.functions["{}local-name"] = Functions.localName;
- this.functions["{}namespace-uri"] = Functions.namespaceURI;
- this.functions["{}name"] = Functions.name;
- this.functions["{}string"] = Functions.string;
- this.functions["{}concat"] = Functions.concat;
- this.functions["{}starts-with"] = Functions.startsWith;
- this.functions["{}contains"] = Functions.contains;
- this.functions["{}substring-before"] = Functions.substringBefore;
- this.functions["{}substring-after"] = Functions.substringAfter;
- this.functions["{}substring"] = Functions.substring;
- this.functions["{}string-length"] = Functions.stringLength;
- this.functions["{}normalize-space"] = Functions.normalizeSpace;
- this.functions["{}translate"] = Functions.translate;
- this.functions["{}boolean"] = Functions.boolean_;
- this.functions["{}not"] = Functions.not;
- this.functions["{}true"] = Functions.true_;
- this.functions["{}false"] = Functions.false_;
- this.functions["{}lang"] = Functions.lang;
- this.functions["{}number"] = Functions.number;
- this.functions["{}sum"] = Functions.sum;
- this.functions["{}floor"] = Functions.floor;
- this.functions["{}ceiling"] = Functions.ceiling;
- this.functions["{}round"] = Functions.round;
-};
-
-FunctionResolver.prototype.addFunction = function(ns, ln, f) {
- this.functions["{" + ns + "}" + ln] = f;
-};
-
-FunctionResolver.getFunctionFromContext = function(qName, context) {
- var parts = Utilities.resolveQName(qName, context.namespaceResolver, context.contextNode, false);
-
- if (parts[0] === null) {
- throw new Error("Cannot resolve QName " + name);
- }
-
- return context.functionResolver.getFunction(parts[1], parts[0]);
-};
-
-FunctionResolver.prototype.getFunction = function(localName, namespace) {
- return this.functions["{" + namespace + "}" + localName];
-};
-
-// NamespaceResolver /////////////////////////////////////////////////////////
-
-NamespaceResolver.prototype = new Object();
-NamespaceResolver.prototype.constructor = NamespaceResolver;
-NamespaceResolver.superclass = Object.prototype;
-
-function NamespaceResolver() {
-}
-
-NamespaceResolver.prototype.getNamespace = function(prefix, n) {
- if (prefix == "xml") {
- return XPath.XML_NAMESPACE_URI;
- } else if (prefix == "xmlns") {
- return XPath.XMLNS_NAMESPACE_URI;
- }
- if (n.nodeType == 9 /*Node.DOCUMENT_NODE*/) {
- n = n.documentElement;
- } else if (n.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
- n = PathExpr.getOwnerElement(n);
- } else if (n.nodeType != 1 /*Node.ELEMENT_NODE*/) {
- n = n.parentNode;
- }
- while (n != null && n.nodeType == 1 /*Node.ELEMENT_NODE*/) {
- var nnm = n.attributes;
- for (var i = 0; i < nnm.length; i++) {
- var a = nnm.item(i);
- var aname = a.name || a.nodeName;
- if ((aname === "xmlns" && prefix === "")
- || aname === "xmlns:" + prefix) {
- return String(a.value || a.nodeValue);
- }
- }
- n = n.parentNode;
- }
- return null;
-};
-
-// Functions /////////////////////////////////////////////////////////////////
-
-var Functions = new Object();
-
-Functions.last = function(c) {
- if (arguments.length != 1) {
- throw new Error("Function last expects ()");
- }
-
- return new XNumber(c.contextSize);
-};
-
-Functions.position = function(c) {
- if (arguments.length != 1) {
- throw new Error("Function position expects ()");
- }
-
- return new XNumber(c.contextPosition);
-};
-
-Functions.count = function() {
- var c = arguments[0];
- var ns;
- if (arguments.length != 2 || !Utilities.instance_of(ns = arguments[1].evaluate(c), XNodeSet)) {
- throw new Error("Function count expects (node-set)");
- }
- return new XNumber(ns.size);
-};
-
-Functions.id = function() {
- var c = arguments[0];
- var id;
- if (arguments.length != 2) {
- throw new Error("Function id expects (object)");
- }
- id = arguments[1].evaluate(c);
- if (Utilities.instance_of(id, XNodeSet)) {
- id = id.toArray().join(" ");
- } else {
- id = id.stringValue();
- }
- var ids = id.split(/[\x0d\x0a\x09\x20]+/);
- var count = 0;
- var ns = new XNodeSet();
- var doc = c.contextNode.nodeType == 9 /*Node.DOCUMENT_NODE*/
- ? c.contextNode
- : c.contextNode.ownerDocument;
- for (var i = 0; i < ids.length; i++) {
- var n;
- if (doc.getElementById) {
- n = doc.getElementById(ids[i]);
- } else {
- n = Utilities.getElementById(doc, ids[i]);
- }
- if (n != null) {
- ns.add(n);
- count++;
- }
- }
- return ns;
-};
-
-Functions.localName = function(c, eNode) {
- var n;
-
- if (arguments.length == 1) {
- n = c.contextNode;
- } else if (arguments.length == 2) {
- n = eNode.evaluate(c).first();
- } else {
- throw new Error("Function local-name expects (node-set?)");
- }
-
- if (n == null) {
- return new XString("");
- }
-
- return new XString(n.localName || // standard elements and attributes
- n.baseName || // IE
- n.target || // processing instructions
- n.nodeName || // DOM1 elements
- ""); // fallback
-};
-
-Functions.namespaceURI = function() {
- var c = arguments[0];
- var n;
- if (arguments.length == 1) {
- n = c.contextNode;
- } else if (arguments.length == 2) {
- n = arguments[1].evaluate(c).first();
- } else {
- throw new Error("Function namespace-uri expects (node-set?)");
- }
- if (n == null) {
- return new XString("");
- }
- return new XString(n.namespaceURI);
-};
-
-Functions.name = function() {
- var c = arguments[0];
- var n;
- if (arguments.length == 1) {
- n = c.contextNode;
- } else if (arguments.length == 2) {
- n = arguments[1].evaluate(c).first();
- } else {
- throw new Error("Function name expects (node-set?)");
- }
- if (n == null) {
- return new XString("");
- }
- if (n.nodeType == 1 /*Node.ELEMENT_NODE*/) {
- return new XString(n.nodeName);
- } else if (n.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
- return new XString(n.name || n.nodeName);
- } else if (n.nodeType === 7 /*Node.PROCESSING_INSTRUCTION_NODE*/) {
- return new XString(n.target || n.nodeName);
- } else if (n.localName == null) {
- return new XString("");
- } else {
- return new XString(n.localName);
- }
-};
-
-Functions.string = function() {
- var c = arguments[0];
- if (arguments.length == 1) {
- return new XString(XNodeSet.prototype.stringForNode(c.contextNode));
- } else if (arguments.length == 2) {
- return arguments[1].evaluate(c).string();
- }
- throw new Error("Function string expects (object?)");
-};
-
-Functions.concat = function(c) {
- if (arguments.length < 3) {
- throw new Error("Function concat expects (string, string[, string]*)");
- }
- var s = "";
- for (var i = 1; i < arguments.length; i++) {
- s += arguments[i].evaluate(c).stringValue();
- }
- return new XString(s);
-};
-
-Functions.startsWith = function() {
- var c = arguments[0];
- if (arguments.length != 3) {
- throw new Error("Function startsWith expects (string, string)");
- }
- var s1 = arguments[1].evaluate(c).stringValue();
- var s2 = arguments[2].evaluate(c).stringValue();
- return new XBoolean(s1.substring(0, s2.length) == s2);
-};
-
-Functions.contains = function() {
- var c = arguments[0];
- if (arguments.length != 3) {
- throw new Error("Function contains expects (string, string)");
- }
- var s1 = arguments[1].evaluate(c).stringValue();
- var s2 = arguments[2].evaluate(c).stringValue();
- return new XBoolean(s1.indexOf(s2) !== -1);
-};
-
-Functions.substringBefore = function() {
- var c = arguments[0];
- if (arguments.length != 3) {
- throw new Error("Function substring-before expects (string, string)");
- }
- var s1 = arguments[1].evaluate(c).stringValue();
- var s2 = arguments[2].evaluate(c).stringValue();
- return new XString(s1.substring(0, s1.indexOf(s2)));
-};
-
-Functions.substringAfter = function() {
- var c = arguments[0];
- if (arguments.length != 3) {
- throw new Error("Function substring-after expects (string, string)");
- }
- var s1 = arguments[1].evaluate(c).stringValue();
- var s2 = arguments[2].evaluate(c).stringValue();
- if (s2.length == 0) {
- return new XString(s1);
- }
- var i = s1.indexOf(s2);
- if (i == -1) {
- return new XString("");
- }
- return new XString(s1.substring(i + s2.length));
-};
-
-Functions.substring = function() {
- var c = arguments[0];
- if (!(arguments.length == 3 || arguments.length == 4)) {
- throw new Error("Function substring expects (string, number, number?)");
- }
- var s = arguments[1].evaluate(c).stringValue();
- var n1 = Math.round(arguments[2].evaluate(c).numberValue()) - 1;
- var n2 = arguments.length == 4 ? n1 + Math.round(arguments[3].evaluate(c).numberValue()) : undefined;
- return new XString(s.substring(n1, n2));
-};
-
-Functions.stringLength = function() {
- var c = arguments[0];
- var s;
- if (arguments.length == 1) {
- s = XNodeSet.prototype.stringForNode(c.contextNode);
- } else if (arguments.length == 2) {
- s = arguments[1].evaluate(c).stringValue();
- } else {
- throw new Error("Function string-length expects (string?)");
- }
- return new XNumber(s.length);
-};
-
-Functions.normalizeSpace = function() {
- var c = arguments[0];
- var s;
- if (arguments.length == 1) {
- s = XNodeSet.prototype.stringForNode(c.contextNode);
- } else if (arguments.length == 2) {
- s = arguments[1].evaluate(c).stringValue();
- } else {
- throw new Error("Function normalize-space expects (string?)");
- }
- var i = 0;
- var j = s.length - 1;
- while (Utilities.isSpace(s.charCodeAt(j))) {
- j--;
- }
- var t = "";
- while (i <= j && Utilities.isSpace(s.charCodeAt(i))) {
- i++;
- }
- while (i <= j) {
- if (Utilities.isSpace(s.charCodeAt(i))) {
- t += " ";
- while (i <= j && Utilities.isSpace(s.charCodeAt(i))) {
- i++;
- }
- } else {
- t += s.charAt(i);
- i++;
- }
- }
- return new XString(t);
-};
-
-Functions.translate = function(c, eValue, eFrom, eTo) {
- if (arguments.length != 4) {
- throw new Error("Function translate expects (string, string, string)");
- }
-
- var value = eValue.evaluate(c).stringValue();
- var from = eFrom.evaluate(c).stringValue();
- var to = eTo.evaluate(c).stringValue();
-
- var cMap = reduce(function (acc, ch, i) {
- if (!(ch in acc)) {
- acc[ch] = i > to.length ? '' : to[i];
- }
- return acc;
- }, {}, from);
-
- var t = join('', map(function (ch) {
- return ch in cMap ? cMap[ch] : ch;
- }, value));
-
- return new XString(t);
-};
-
-Functions.boolean_ = function() {
- var c = arguments[0];
- if (arguments.length != 2) {
- throw new Error("Function boolean expects (object)");
- }
- return arguments[1].evaluate(c).bool();
-};
-
-Functions.not = function(c, eValue) {
- if (arguments.length != 2) {
- throw new Error("Function not expects (object)");
- }
- return eValue.evaluate(c).bool().not();
-};
-
-Functions.true_ = function() {
- if (arguments.length != 1) {
- throw new Error("Function true expects ()");
- }
- return XBoolean.true_;
-};
-
-Functions.false_ = function() {
- if (arguments.length != 1) {
- throw new Error("Function false expects ()");
- }
- return XBoolean.false_;
-};
-
-Functions.lang = function() {
- var c = arguments[0];
- if (arguments.length != 2) {
- throw new Error("Function lang expects (string)");
- }
- var lang;
- for (var n = c.contextNode; n != null && n.nodeType != 9 /*Node.DOCUMENT_NODE*/; n = n.parentNode) {
- var a = n.getAttributeNS(XPath.XML_NAMESPACE_URI, "lang");
- if (a != null) {
- lang = String(a);
- break;
- }
- }
- if (lang == null) {
- return XBoolean.false_;
- }
- var s = arguments[1].evaluate(c).stringValue();
- return new XBoolean(lang.substring(0, s.length) == s
- && (lang.length == s.length || lang.charAt(s.length) == '-'));
-};
-
-Functions.number = function() {
- var c = arguments[0];
- if (!(arguments.length == 1 || arguments.length == 2)) {
- throw new Error("Function number expects (object?)");
- }
- if (arguments.length == 1) {
- return new XNumber(XNodeSet.prototype.stringForNode(c.contextNode));
- }
- return arguments[1].evaluate(c).number();
-};
-
-Functions.sum = function() {
- var c = arguments[0];
- var ns;
- if (arguments.length != 2 || !Utilities.instance_of((ns = arguments[1].evaluate(c)), XNodeSet)) {
- throw new Error("Function sum expects (node-set)");
- }
- ns = ns.toUnsortedArray();
- var n = 0;
- for (var i = 0; i < ns.length; i++) {
- n += new XNumber(XNodeSet.prototype.stringForNode(ns[i])).numberValue();
- }
- return new XNumber(n);
-};
-
-Functions.floor = function() {
- var c = arguments[0];
- if (arguments.length != 2) {
- throw new Error("Function floor expects (number)");
- }
- return new XNumber(Math.floor(arguments[1].evaluate(c).numberValue()));
-};
-
-Functions.ceiling = function() {
- var c = arguments[0];
- if (arguments.length != 2) {
- throw new Error("Function ceiling expects (number)");
- }
- return new XNumber(Math.ceil(arguments[1].evaluate(c).numberValue()));
-};
-
-Functions.round = function() {
- var c = arguments[0];
- if (arguments.length != 2) {
- throw new Error("Function round expects (number)");
- }
- return new XNumber(Math.round(arguments[1].evaluate(c).numberValue()));
-};
-
-// Utilities /////////////////////////////////////////////////////////////////
-
-var Utilities = new Object();
-
-Utilities.isAttribute = function (val) {
- return val && (val.nodeType === 2 || val.ownerElement);
-}
-
-Utilities.splitQName = function(qn) {
- var i = qn.indexOf(":");
- if (i == -1) {
- return [ null, qn ];
- }
- return [ qn.substring(0, i), qn.substring(i + 1) ];
-};
-
-Utilities.resolveQName = function(qn, nr, n, useDefault) {
- var parts = Utilities.splitQName(qn);
- if (parts[0] != null) {
- parts[0] = nr.getNamespace(parts[0], n);
- } else {
- if (useDefault) {
- parts[0] = nr.getNamespace("", n);
- if (parts[0] == null) {
- parts[0] = "";
- }
- } else {
- parts[0] = "";
- }
- }
- return parts;
-};
-
-Utilities.isSpace = function(c) {
- return c == 0x9 || c == 0xd || c == 0xa || c == 0x20;
-};
-
-Utilities.isLetter = function(c) {
- return c >= 0x0041 && c <= 0x005A ||
- c >= 0x0061 && c <= 0x007A ||
- c >= 0x00C0 && c <= 0x00D6 ||
- c >= 0x00D8 && c <= 0x00F6 ||
- c >= 0x00F8 && c <= 0x00FF ||
- c >= 0x0100 && c <= 0x0131 ||
- c >= 0x0134 && c <= 0x013E ||
- c >= 0x0141 && c <= 0x0148 ||
- c >= 0x014A && c <= 0x017E ||
- c >= 0x0180 && c <= 0x01C3 ||
- c >= 0x01CD && c <= 0x01F0 ||
- c >= 0x01F4 && c <= 0x01F5 ||
- c >= 0x01FA && c <= 0x0217 ||
- c >= 0x0250 && c <= 0x02A8 ||
- c >= 0x02BB && c <= 0x02C1 ||
- c == 0x0386 ||
- c >= 0x0388 && c <= 0x038A ||
- c == 0x038C ||
- c >= 0x038E && c <= 0x03A1 ||
- c >= 0x03A3 && c <= 0x03CE ||
- c >= 0x03D0 && c <= 0x03D6 ||
- c == 0x03DA ||
- c == 0x03DC ||
- c == 0x03DE ||
- c == 0x03E0 ||
- c >= 0x03E2 && c <= 0x03F3 ||
- c >= 0x0401 && c <= 0x040C ||
- c >= 0x040E && c <= 0x044F ||
- c >= 0x0451 && c <= 0x045C ||
- c >= 0x045E && c <= 0x0481 ||
- c >= 0x0490 && c <= 0x04C4 ||
- c >= 0x04C7 && c <= 0x04C8 ||
- c >= 0x04CB && c <= 0x04CC ||
- c >= 0x04D0 && c <= 0x04EB ||
- c >= 0x04EE && c <= 0x04F5 ||
- c >= 0x04F8 && c <= 0x04F9 ||
- c >= 0x0531 && c <= 0x0556 ||
- c == 0x0559 ||
- c >= 0x0561 && c <= 0x0586 ||
- c >= 0x05D0 && c <= 0x05EA ||
- c >= 0x05F0 && c <= 0x05F2 ||
- c >= 0x0621 && c <= 0x063A ||
- c >= 0x0641 && c <= 0x064A ||
- c >= 0x0671 && c <= 0x06B7 ||
- c >= 0x06BA && c <= 0x06BE ||
- c >= 0x06C0 && c <= 0x06CE ||
- c >= 0x06D0 && c <= 0x06D3 ||
- c == 0x06D5 ||
- c >= 0x06E5 && c <= 0x06E6 ||
- c >= 0x0905 && c <= 0x0939 ||
- c == 0x093D ||
- c >= 0x0958 && c <= 0x0961 ||
- c >= 0x0985 && c <= 0x098C ||
- c >= 0x098F && c <= 0x0990 ||
- c >= 0x0993 && c <= 0x09A8 ||
- c >= 0x09AA && c <= 0x09B0 ||
- c == 0x09B2 ||
- c >= 0x09B6 && c <= 0x09B9 ||
- c >= 0x09DC && c <= 0x09DD ||
- c >= 0x09DF && c <= 0x09E1 ||
- c >= 0x09F0 && c <= 0x09F1 ||
- c >= 0x0A05 && c <= 0x0A0A ||
- c >= 0x0A0F && c <= 0x0A10 ||
- c >= 0x0A13 && c <= 0x0A28 ||
- c >= 0x0A2A && c <= 0x0A30 ||
- c >= 0x0A32 && c <= 0x0A33 ||
- c >= 0x0A35 && c <= 0x0A36 ||
- c >= 0x0A38 && c <= 0x0A39 ||
- c >= 0x0A59 && c <= 0x0A5C ||
- c == 0x0A5E ||
- c >= 0x0A72 && c <= 0x0A74 ||
- c >= 0x0A85 && c <= 0x0A8B ||
- c == 0x0A8D ||
- c >= 0x0A8F && c <= 0x0A91 ||
- c >= 0x0A93 && c <= 0x0AA8 ||
- c >= 0x0AAA && c <= 0x0AB0 ||
- c >= 0x0AB2 && c <= 0x0AB3 ||
- c >= 0x0AB5 && c <= 0x0AB9 ||
- c == 0x0ABD ||
- c == 0x0AE0 ||
- c >= 0x0B05 && c <= 0x0B0C ||
- c >= 0x0B0F && c <= 0x0B10 ||
- c >= 0x0B13 && c <= 0x0B28 ||
- c >= 0x0B2A && c <= 0x0B30 ||
- c >= 0x0B32 && c <= 0x0B33 ||
- c >= 0x0B36 && c <= 0x0B39 ||
- c == 0x0B3D ||
- c >= 0x0B5C && c <= 0x0B5D ||
- c >= 0x0B5F && c <= 0x0B61 ||
- c >= 0x0B85 && c <= 0x0B8A ||
- c >= 0x0B8E && c <= 0x0B90 ||
- c >= 0x0B92 && c <= 0x0B95 ||
- c >= 0x0B99 && c <= 0x0B9A ||
- c == 0x0B9C ||
- c >= 0x0B9E && c <= 0x0B9F ||
- c >= 0x0BA3 && c <= 0x0BA4 ||
- c >= 0x0BA8 && c <= 0x0BAA ||
- c >= 0x0BAE && c <= 0x0BB5 ||
- c >= 0x0BB7 && c <= 0x0BB9 ||
- c >= 0x0C05 && c <= 0x0C0C ||
- c >= 0x0C0E && c <= 0x0C10 ||
- c >= 0x0C12 && c <= 0x0C28 ||
- c >= 0x0C2A && c <= 0x0C33 ||
- c >= 0x0C35 && c <= 0x0C39 ||
- c >= 0x0C60 && c <= 0x0C61 ||
- c >= 0x0C85 && c <= 0x0C8C ||
- c >= 0x0C8E && c <= 0x0C90 ||
- c >= 0x0C92 && c <= 0x0CA8 ||
- c >= 0x0CAA && c <= 0x0CB3 ||
- c >= 0x0CB5 && c <= 0x0CB9 ||
- c == 0x0CDE ||
- c >= 0x0CE0 && c <= 0x0CE1 ||
- c >= 0x0D05 && c <= 0x0D0C ||
- c >= 0x0D0E && c <= 0x0D10 ||
- c >= 0x0D12 && c <= 0x0D28 ||
- c >= 0x0D2A && c <= 0x0D39 ||
- c >= 0x0D60 && c <= 0x0D61 ||
- c >= 0x0E01 && c <= 0x0E2E ||
- c == 0x0E30 ||
- c >= 0x0E32 && c <= 0x0E33 ||
- c >= 0x0E40 && c <= 0x0E45 ||
- c >= 0x0E81 && c <= 0x0E82 ||
- c == 0x0E84 ||
- c >= 0x0E87 && c <= 0x0E88 ||
- c == 0x0E8A ||
- c == 0x0E8D ||
- c >= 0x0E94 && c <= 0x0E97 ||
- c >= 0x0E99 && c <= 0x0E9F ||
- c >= 0x0EA1 && c <= 0x0EA3 ||
- c == 0x0EA5 ||
- c == 0x0EA7 ||
- c >= 0x0EAA && c <= 0x0EAB ||
- c >= 0x0EAD && c <= 0x0EAE ||
- c == 0x0EB0 ||
- c >= 0x0EB2 && c <= 0x0EB3 ||
- c == 0x0EBD ||
- c >= 0x0EC0 && c <= 0x0EC4 ||
- c >= 0x0F40 && c <= 0x0F47 ||
- c >= 0x0F49 && c <= 0x0F69 ||
- c >= 0x10A0 && c <= 0x10C5 ||
- c >= 0x10D0 && c <= 0x10F6 ||
- c == 0x1100 ||
- c >= 0x1102 && c <= 0x1103 ||
- c >= 0x1105 && c <= 0x1107 ||
- c == 0x1109 ||
- c >= 0x110B && c <= 0x110C ||
- c >= 0x110E && c <= 0x1112 ||
- c == 0x113C ||
- c == 0x113E ||
- c == 0x1140 ||
- c == 0x114C ||
- c == 0x114E ||
- c == 0x1150 ||
- c >= 0x1154 && c <= 0x1155 ||
- c == 0x1159 ||
- c >= 0x115F && c <= 0x1161 ||
- c == 0x1163 ||
- c == 0x1165 ||
- c == 0x1167 ||
- c == 0x1169 ||
- c >= 0x116D && c <= 0x116E ||
- c >= 0x1172 && c <= 0x1173 ||
- c == 0x1175 ||
- c == 0x119E ||
- c == 0x11A8 ||
- c == 0x11AB ||
- c >= 0x11AE && c <= 0x11AF ||
- c >= 0x11B7 && c <= 0x11B8 ||
- c == 0x11BA ||
- c >= 0x11BC && c <= 0x11C2 ||
- c == 0x11EB ||
- c == 0x11F0 ||
- c == 0x11F9 ||
- c >= 0x1E00 && c <= 0x1E9B ||
- c >= 0x1EA0 && c <= 0x1EF9 ||
- c >= 0x1F00 && c <= 0x1F15 ||
- c >= 0x1F18 && c <= 0x1F1D ||
- c >= 0x1F20 && c <= 0x1F45 ||
- c >= 0x1F48 && c <= 0x1F4D ||
- c >= 0x1F50 && c <= 0x1F57 ||
- c == 0x1F59 ||
- c == 0x1F5B ||
- c == 0x1F5D ||
- c >= 0x1F5F && c <= 0x1F7D ||
- c >= 0x1F80 && c <= 0x1FB4 ||
- c >= 0x1FB6 && c <= 0x1FBC ||
- c == 0x1FBE ||
- c >= 0x1FC2 && c <= 0x1FC4 ||
- c >= 0x1FC6 && c <= 0x1FCC ||
- c >= 0x1FD0 && c <= 0x1FD3 ||
- c >= 0x1FD6 && c <= 0x1FDB ||
- c >= 0x1FE0 && c <= 0x1FEC ||
- c >= 0x1FF2 && c <= 0x1FF4 ||
- c >= 0x1FF6 && c <= 0x1FFC ||
- c == 0x2126 ||
- c >= 0x212A && c <= 0x212B ||
- c == 0x212E ||
- c >= 0x2180 && c <= 0x2182 ||
- c >= 0x3041 && c <= 0x3094 ||
- c >= 0x30A1 && c <= 0x30FA ||
- c >= 0x3105 && c <= 0x312C ||
- c >= 0xAC00 && c <= 0xD7A3 ||
- c >= 0x4E00 && c <= 0x9FA5 ||
- c == 0x3007 ||
- c >= 0x3021 && c <= 0x3029;
-};
-
-Utilities.isNCNameChar = function(c) {
- return c >= 0x0030 && c <= 0x0039
- || c >= 0x0660 && c <= 0x0669
- || c >= 0x06F0 && c <= 0x06F9
- || c >= 0x0966 && c <= 0x096F
- || c >= 0x09E6 && c <= 0x09EF
- || c >= 0x0A66 && c <= 0x0A6F
- || c >= 0x0AE6 && c <= 0x0AEF
- || c >= 0x0B66 && c <= 0x0B6F
- || c >= 0x0BE7 && c <= 0x0BEF
- || c >= 0x0C66 && c <= 0x0C6F
- || c >= 0x0CE6 && c <= 0x0CEF
- || c >= 0x0D66 && c <= 0x0D6F
- || c >= 0x0E50 && c <= 0x0E59
- || c >= 0x0ED0 && c <= 0x0ED9
- || c >= 0x0F20 && c <= 0x0F29
- || c == 0x002E
- || c == 0x002D
- || c == 0x005F
- || Utilities.isLetter(c)
- || c >= 0x0300 && c <= 0x0345
- || c >= 0x0360 && c <= 0x0361
- || c >= 0x0483 && c <= 0x0486
- || c >= 0x0591 && c <= 0x05A1
- || c >= 0x05A3 && c <= 0x05B9
- || c >= 0x05BB && c <= 0x05BD
- || c == 0x05BF
- || c >= 0x05C1 && c <= 0x05C2
- || c == 0x05C4
- || c >= 0x064B && c <= 0x0652
- || c == 0x0670
- || c >= 0x06D6 && c <= 0x06DC
- || c >= 0x06DD && c <= 0x06DF
- || c >= 0x06E0 && c <= 0x06E4
- || c >= 0x06E7 && c <= 0x06E8
- || c >= 0x06EA && c <= 0x06ED
- || c >= 0x0901 && c <= 0x0903
- || c == 0x093C
- || c >= 0x093E && c <= 0x094C
- || c == 0x094D
- || c >= 0x0951 && c <= 0x0954
- || c >= 0x0962 && c <= 0x0963
- || c >= 0x0981 && c <= 0x0983
- || c == 0x09BC
- || c == 0x09BE
- || c == 0x09BF
- || c >= 0x09C0 && c <= 0x09C4
- || c >= 0x09C7 && c <= 0x09C8
- || c >= 0x09CB && c <= 0x09CD
- || c == 0x09D7
- || c >= 0x09E2 && c <= 0x09E3
- || c == 0x0A02
- || c == 0x0A3C
- || c == 0x0A3E
- || c == 0x0A3F
- || c >= 0x0A40 && c <= 0x0A42
- || c >= 0x0A47 && c <= 0x0A48
- || c >= 0x0A4B && c <= 0x0A4D
- || c >= 0x0A70 && c <= 0x0A71
- || c >= 0x0A81 && c <= 0x0A83
- || c == 0x0ABC
- || c >= 0x0ABE && c <= 0x0AC5
- || c >= 0x0AC7 && c <= 0x0AC9
- || c >= 0x0ACB && c <= 0x0ACD
- || c >= 0x0B01 && c <= 0x0B03
- || c == 0x0B3C
- || c >= 0x0B3E && c <= 0x0B43
- || c >= 0x0B47 && c <= 0x0B48
- || c >= 0x0B4B && c <= 0x0B4D
- || c >= 0x0B56 && c <= 0x0B57
- || c >= 0x0B82 && c <= 0x0B83
- || c >= 0x0BBE && c <= 0x0BC2
- || c >= 0x0BC6 && c <= 0x0BC8
- || c >= 0x0BCA && c <= 0x0BCD
- || c == 0x0BD7
- || c >= 0x0C01 && c <= 0x0C03
- || c >= 0x0C3E && c <= 0x0C44
- || c >= 0x0C46 && c <= 0x0C48
- || c >= 0x0C4A && c <= 0x0C4D
- || c >= 0x0C55 && c <= 0x0C56
- || c >= 0x0C82 && c <= 0x0C83
- || c >= 0x0CBE && c <= 0x0CC4
- || c >= 0x0CC6 && c <= 0x0CC8
- || c >= 0x0CCA && c <= 0x0CCD
- || c >= 0x0CD5 && c <= 0x0CD6
- || c >= 0x0D02 && c <= 0x0D03
- || c >= 0x0D3E && c <= 0x0D43
- || c >= 0x0D46 && c <= 0x0D48
- || c >= 0x0D4A && c <= 0x0D4D
- || c == 0x0D57
- || c == 0x0E31
- || c >= 0x0E34 && c <= 0x0E3A
- || c >= 0x0E47 && c <= 0x0E4E
- || c == 0x0EB1
- || c >= 0x0EB4 && c <= 0x0EB9
- || c >= 0x0EBB && c <= 0x0EBC
- || c >= 0x0EC8 && c <= 0x0ECD
- || c >= 0x0F18 && c <= 0x0F19
- || c == 0x0F35
- || c == 0x0F37
- || c == 0x0F39
- || c == 0x0F3E
- || c == 0x0F3F
- || c >= 0x0F71 && c <= 0x0F84
- || c >= 0x0F86 && c <= 0x0F8B
- || c >= 0x0F90 && c <= 0x0F95
- || c == 0x0F97
- || c >= 0x0F99 && c <= 0x0FAD
- || c >= 0x0FB1 && c <= 0x0FB7
- || c == 0x0FB9
- || c >= 0x20D0 && c <= 0x20DC
- || c == 0x20E1
- || c >= 0x302A && c <= 0x302F
- || c == 0x3099
- || c == 0x309A
- || c == 0x00B7
- || c == 0x02D0
- || c == 0x02D1
- || c == 0x0387
- || c == 0x0640
- || c == 0x0E46
- || c == 0x0EC6
- || c == 0x3005
- || c >= 0x3031 && c <= 0x3035
- || c >= 0x309D && c <= 0x309E
- || c >= 0x30FC && c <= 0x30FE;
-};
-
-Utilities.coalesceText = function(n) {
- for (var m = n.firstChild; m != null; m = m.nextSibling) {
- if (m.nodeType == 3 /*Node.TEXT_NODE*/ || m.nodeType == 4 /*Node.CDATA_SECTION_NODE*/) {
- var s = m.nodeValue;
- var first = m;
- m = m.nextSibling;
- while (m != null && (m.nodeType == 3 /*Node.TEXT_NODE*/ || m.nodeType == 4 /*Node.CDATA_SECTION_NODE*/)) {
- s += m.nodeValue;
- var del = m;
- m = m.nextSibling;
- del.parentNode.removeChild(del);
- }
- if (first.nodeType == 4 /*Node.CDATA_SECTION_NODE*/) {
- var p = first.parentNode;
- if (first.nextSibling == null) {
- p.removeChild(first);
- p.appendChild(p.ownerDocument.createTextNode(s));
- } else {
- var next = first.nextSibling;
- p.removeChild(first);
- p.insertBefore(p.ownerDocument.createTextNode(s), next);
- }
- } else {
- first.nodeValue = s;
- }
- if (m == null) {
- break;
- }
- } else if (m.nodeType == 1 /*Node.ELEMENT_NODE*/) {
- Utilities.coalesceText(m);
- }
- }
-};
-
-Utilities.instance_of = function(o, c) {
- while (o != null) {
- if (o.constructor === c) {
- return true;
- }
- if (o === Object) {
- return false;
- }
- o = o.constructor.superclass;
- }
- return false;
-};
-
-Utilities.getElementById = function(n, id) {
- // Note that this does not check the DTD to check for actual
- // attributes of type ID, so this may be a bit wrong.
- if (n.nodeType == 1 /*Node.ELEMENT_NODE*/) {
- if (n.getAttribute("id") == id
- || n.getAttributeNS(null, "id") == id) {
- return n;
- }
- }
- for (var m = n.firstChild; m != null; m = m.nextSibling) {
- var res = Utilities.getElementById(m, id);
- if (res != null) {
- return res;
- }
- }
- return null;
-};
-
-// XPathException ////////////////////////////////////////////////////////////
-
-var XPathException = (function () {
- function getMessage(code, exception) {
- var msg = exception ? ": " + exception.toString() : "";
- switch (code) {
- case XPathException.INVALID_EXPRESSION_ERR:
- return "Invalid expression" + msg;
- case XPathException.TYPE_ERR:
- return "Type error" + msg;
- }
- return null;
- }
-
- function XPathException(code, error, message) {
- var err = Error.call(this, getMessage(code, error) || message);
-
- err.code = code;
- err.exception = error;
-
- return err;
- }
-
- XPathException.prototype = Object.create(Error.prototype);
- XPathException.prototype.constructor = XPathException;
- XPathException.superclass = Error;
-
- XPathException.prototype.toString = function() {
- return this.message;
- };
-
- XPathException.fromMessage = function(message, error) {
- return new XPathException(null, error, message);
- };
-
- XPathException.INVALID_EXPRESSION_ERR = 51;
- XPathException.TYPE_ERR = 52;
-
- return XPathException;
-})();
-
-// XPathExpression ///////////////////////////////////////////////////////////
-
-XPathExpression.prototype = {};
-XPathExpression.prototype.constructor = XPathExpression;
-XPathExpression.superclass = Object.prototype;
-
-function XPathExpression(e, r, p) {
- this.xpath = p.parse(e);
- this.context = new XPathContext();
- this.context.namespaceResolver = new XPathNSResolverWrapper(r);
-}
-
-XPathExpression.getOwnerDocument = function (n) {
- return n.nodeType === 9 /*Node.DOCUMENT_NODE*/ ? n : n.ownerDocument;
-}
-
-XPathExpression.detectHtmlDom = function (n) {
- if (!n) { return false; }
-
- var doc = XPathExpression.getOwnerDocument(n);
-
- try {
- return doc.implementation.hasFeature("HTML", "2.0");
- } catch (e) {
- return true;
- }
-}
-
-XPathExpression.prototype.evaluate = function(n, t, res) {
- this.context.expressionContextNode = n;
- // backward compatibility - no reliable way to detect whether the DOM is HTML, but
- // this library has been using this method up until now, so we will continue to use it
- // ONLY when using an XPathExpression
- this.context.caseInsensitive = XPathExpression.detectHtmlDom(n);
-
- var result = this.xpath.evaluate(this.context);
- return new XPathResult(result, t);
-}
-
-// XPathNSResolverWrapper ////////////////////////////////////////////////////
-
-XPathNSResolverWrapper.prototype = {};
-XPathNSResolverWrapper.prototype.constructor = XPathNSResolverWrapper;
-XPathNSResolverWrapper.superclass = Object.prototype;
-
-function XPathNSResolverWrapper(r) {
- this.xpathNSResolver = r;
-}
-
-XPathNSResolverWrapper.prototype.getNamespace = function(prefix, n) {
- if (this.xpathNSResolver == null) {
- return null;
- }
- return this.xpathNSResolver.lookupNamespaceURI(prefix);
-};
-
-// NodeXPathNSResolver ///////////////////////////////////////////////////////
-
-NodeXPathNSResolver.prototype = {};
-NodeXPathNSResolver.prototype.constructor = NodeXPathNSResolver;
-NodeXPathNSResolver.superclass = Object.prototype;
-
-function NodeXPathNSResolver(n) {
- this.node = n;
- this.namespaceResolver = new NamespaceResolver();
-}
-
-NodeXPathNSResolver.prototype.lookupNamespaceURI = function(prefix) {
- return this.namespaceResolver.getNamespace(prefix, this.node);
-};
-
-// XPathResult ///////////////////////////////////////////////////////////////
-
-XPathResult.prototype = {};
-XPathResult.prototype.constructor = XPathResult;
-XPathResult.superclass = Object.prototype;
-
-function XPathResult(v, t) {
- if (t == XPathResult.ANY_TYPE) {
- if (v.constructor === XString) {
- t = XPathResult.STRING_TYPE;
- } else if (v.constructor === XNumber) {
- t = XPathResult.NUMBER_TYPE;
- } else if (v.constructor === XBoolean) {
- t = XPathResult.BOOLEAN_TYPE;
- } else if (v.constructor === XNodeSet) {
- t = XPathResult.UNORDERED_NODE_ITERATOR_TYPE;
- }
- }
- this.resultType = t;
- switch (t) {
- case XPathResult.NUMBER_TYPE:
- this.numberValue = v.numberValue();
- return;
- case XPathResult.STRING_TYPE:
- this.stringValue = v.stringValue();
- return;
- case XPathResult.BOOLEAN_TYPE:
- this.booleanValue = v.booleanValue();
- return;
- case XPathResult.ANY_UNORDERED_NODE_TYPE:
- case XPathResult.FIRST_ORDERED_NODE_TYPE:
- if (v.constructor === XNodeSet) {
- this.singleNodeValue = v.first();
- return;
- }
- break;
- case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
- case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
- if (v.constructor === XNodeSet) {
- this.invalidIteratorState = false;
- this.nodes = v.toArray();
- this.iteratorIndex = 0;
- return;
- }
- break;
- case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
- case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
- if (v.constructor === XNodeSet) {
- this.nodes = v.toArray();
- this.snapshotLength = this.nodes.length;
- return;
- }
- break;
- }
- throw new XPathException(XPathException.TYPE_ERR);
-};
-
-XPathResult.prototype.iterateNext = function() {
- if (this.resultType != XPathResult.UNORDERED_NODE_ITERATOR_TYPE
- && this.resultType != XPathResult.ORDERED_NODE_ITERATOR_TYPE) {
- throw new XPathException(XPathException.TYPE_ERR);
- }
- return this.nodes[this.iteratorIndex++];
-};
-
-XPathResult.prototype.snapshotItem = function(i) {
- if (this.resultType != XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE
- && this.resultType != XPathResult.ORDERED_NODE_SNAPSHOT_TYPE) {
- throw new XPathException(XPathException.TYPE_ERR);
- }
- return this.nodes[i];
-};
-
-XPathResult.ANY_TYPE = 0;
-XPathResult.NUMBER_TYPE = 1;
-XPathResult.STRING_TYPE = 2;
-XPathResult.BOOLEAN_TYPE = 3;
-XPathResult.UNORDERED_NODE_ITERATOR_TYPE = 4;
-XPathResult.ORDERED_NODE_ITERATOR_TYPE = 5;
-XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE = 6;
-XPathResult.ORDERED_NODE_SNAPSHOT_TYPE = 7;
-XPathResult.ANY_UNORDERED_NODE_TYPE = 8;
-XPathResult.FIRST_ORDERED_NODE_TYPE = 9;
-
-// DOM 3 XPath support ///////////////////////////////////////////////////////
-
-function installDOM3XPathSupport(doc, p) {
- doc.createExpression = function(e, r) {
- try {
- return new XPathExpression(e, r, p);
- } catch (e) {
- throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, e);
- }
- };
- doc.createNSResolver = function(n) {
- return new NodeXPathNSResolver(n);
- };
- doc.evaluate = function(e, cn, r, t, res) {
- if (t < 0 || t > 9) {
- throw { code: 0, toString: function() { return "Request type not supported"; } };
- }
- return doc.createExpression(e, r, p).evaluate(cn, t, res);
- };
-};
-
-// ---------------------------------------------------------------------------
-
-// Install DOM 3 XPath support for the current document.
-try {
- var shouldInstall = true;
- try {
- if (document.implementation
- && document.implementation.hasFeature
- && document.implementation.hasFeature("XPath", null)) {
- shouldInstall = false;
- }
- } catch (e) {
- }
- if (shouldInstall) {
- installDOM3XPathSupport(document, new XPathParser());
- }
-} catch (e) {
-}
-
-// ---------------------------------------------------------------------------
-// exports for node.js
-
-installDOM3XPathSupport(exports, new XPathParser());
-
-(function() {
- var parser = new XPathParser();
-
- var defaultNSResolver = new NamespaceResolver();
- var defaultFunctionResolver = new FunctionResolver();
- var defaultVariableResolver = new VariableResolver();
-
- function makeNSResolverFromFunction(func) {
- return {
- getNamespace: function (prefix, node) {
- var ns = func(prefix, node);
-
- return ns || defaultNSResolver.getNamespace(prefix, node);
- }
- };
- }
-
- function makeNSResolverFromObject(obj) {
- return makeNSResolverFromFunction(obj.getNamespace.bind(obj));
- }
-
- function makeNSResolverFromMap(map) {
- return makeNSResolverFromFunction(function (prefix) {
- return map[prefix];
- });
- }
-
- function makeNSResolver(resolver) {
- if (resolver && typeof resolver.getNamespace === "function") {
- return makeNSResolverFromObject(resolver);
+ // find common parent
+ while (n1Par !== n2Par) {
+ n1 = n1Par;
+ n2 = n2Par;
+ n1Par = n1.parentNode || n1.ownerElement;
+ n2Par = n2.parentNode || n2.ownerElement;
}
- if (typeof resolver === "function") {
- return makeNSResolverFromFunction(resolver);
+ var n1isAttr = Utilities.isAttribute(n1);
+ var n2isAttr = Utilities.isAttribute(n2);
+
+ if (n1isAttr && !n2isAttr) {
+ return -1;
+ }
+ if (!n1isAttr && n2isAttr) {
+ return 1;
}
- // assume prefix -> uri mapping
- if (typeof resolver === "object") {
- return makeNSResolverFromMap(resolver);
- }
-
- return defaultNSResolver;
- }
-
- /** Converts native JavaScript types to their XPath library equivalent */
- function convertValue(value) {
- if (value === null ||
- typeof value === "undefined" ||
- value instanceof XString ||
- value instanceof XBoolean ||
- value instanceof XNumber ||
- value instanceof XNodeSet) {
- return value;
- }
-
- switch (typeof value) {
- case "string": return new XString(value);
- case "boolean": return new XBoolean(value);
- case "number": return new XNumber(value);
- }
-
- // assume node(s)
- var ns = new XNodeSet();
- ns.addArray([].concat(value));
- return ns;
- }
-
- function makeEvaluator(func) {
- return function (context) {
- var args = Array.prototype.slice.call(arguments, 1).map(function (arg) {
- return arg.evaluate(context);
- });
- var result = func.apply(this, [].concat(context, args));
- return convertValue(result);
- };
- }
-
- function makeFunctionResolverFromFunction(func) {
- return {
- getFunction: function (name, namespace) {
- var found = func(name, namespace);
- if (found) {
- return makeEvaluator(found);
+ if (n1Par) {
+ var cn = n1isAttr ? n1Par.attributes : n1Par.childNodes,
+ len = cn.length;
+ for (var i = 0; i < len; i += 1) {
+ var n = cn[i];
+ if (n === n1) {
+ return -1;
}
- return defaultFunctionResolver.getFunction(name, namespace);
+ if (n === n2) {
+ return 1;
+ }
+ }
+ }
+
+ throw new Error('Unexpected: could not determine node order');
+ }
+
+ AVLTree.prototype.add = function (n) {
+ if (n === this.node) {
+ return false;
+ }
+
+ var o = nodeOrder(n, this.node);
+
+ var ret = false;
+ if (o == -1) {
+ if (this.left == null) {
+ this.left = new AVLTree(n);
+ ret = true;
+ } else {
+ ret = this.left.add(n);
+ if (ret) {
+ this.balance();
+ }
+ }
+ } else if (o == 1) {
+ if (this.right == null) {
+ this.right = new AVLTree(n);
+ ret = true;
+ } else {
+ ret = this.right.add(n);
+ if (ret) {
+ this.balance();
+ }
+ }
+ }
+
+ if (ret) {
+ this.getDepthFromChildren();
+ }
+ return ret;
+ };
+
+ // XNodeSet //////////////////////////////////////////////////////////////////
+
+ XNodeSet.prototype = new Expression();
+ XNodeSet.prototype.constructor = XNodeSet;
+ XNodeSet.superclass = Expression.prototype;
+
+ function XNodeSet() {
+ this.init();
+ }
+
+ XNodeSet.prototype.init = function () {
+ this.tree = null;
+ this.nodes = [];
+ this.size = 0;
+ };
+
+ XNodeSet.prototype.toString = function () {
+ var p = this.first();
+ if (p == null) {
+ return "";
+ }
+ return this.stringForNode(p);
+ };
+
+ XNodeSet.prototype.evaluate = function (c) {
+ return this;
+ };
+
+ XNodeSet.prototype.string = function () {
+ return new XString(this.toString());
+ };
+
+ XNodeSet.prototype.stringValue = function () {
+ return this.toString();
+ };
+
+ XNodeSet.prototype.number = function () {
+ return new XNumber(this.string());
+ };
+
+ XNodeSet.prototype.numberValue = function () {
+ return Number(this.string());
+ };
+
+ XNodeSet.prototype.bool = function () {
+ return new XBoolean(this.booleanValue());
+ };
+
+ XNodeSet.prototype.booleanValue = function () {
+ return !!this.size;
+ };
+
+ XNodeSet.prototype.nodeset = function () {
+ return this;
+ };
+
+ XNodeSet.prototype.stringForNode = function (n) {
+ if (n.nodeType == 9 /*Node.DOCUMENT_NODE*/ ||
+ n.nodeType == 1 /*Node.ELEMENT_NODE */ ||
+ n.nodeType === 11 /*Node.DOCUMENT_FRAGMENT*/) {
+ return this.stringForContainerNode(n);
+ }
+ if (n.nodeType === 2 /* Node.ATTRIBUTE_NODE */) {
+ return n.value || n.nodeValue;
+ }
+ if (n.isNamespaceNode) {
+ return n.namespace;
+ }
+ return n.nodeValue;
+ };
+
+ XNodeSet.prototype.stringForContainerNode = function (n) {
+ var s = "";
+ for (var n2 = n.firstChild; n2 != null; n2 = n2.nextSibling) {
+ var nt = n2.nodeType;
+ // Element, Text, CDATA, Document, Document Fragment
+ if (nt === 1 || nt === 3 || nt === 4 || nt === 9 || nt === 11) {
+ s += this.stringForNode(n2);
+ }
+ }
+ return s;
+ };
+
+ XNodeSet.prototype.buildTree = function () {
+ if (!this.tree && this.nodes.length) {
+ this.tree = new AVLTree(this.nodes[0]);
+ for (var i = 1; i < this.nodes.length; i += 1) {
+ this.tree.add(this.nodes[i]);
+ }
+ }
+
+ return this.tree;
+ };
+
+ XNodeSet.prototype.first = function () {
+ var p = this.buildTree();
+ if (p == null) {
+ return null;
+ }
+ while (p.left != null) {
+ p = p.left;
+ }
+ return p.node;
+ };
+
+ XNodeSet.prototype.add = function (n) {
+ for (var i = 0; i < this.nodes.length; i += 1) {
+ if (n === this.nodes[i]) {
+ return;
+ }
+ }
+
+ this.tree = null;
+ this.nodes.push(n);
+ this.size += 1;
+ };
+
+ XNodeSet.prototype.addArray = function (ns) {
+ var self = this;
+
+ forEach(function (x) { self.add(x); }, ns);
+ };
+
+ /**
+ * Returns an array of the node set's contents in document order
+ */
+ XNodeSet.prototype.toArray = function () {
+ var a = [];
+ this.toArrayRec(this.buildTree(), a);
+ return a;
+ };
+
+ XNodeSet.prototype.toArrayRec = function (t, a) {
+ if (t != null) {
+ this.toArrayRec(t.left, a);
+ a.push(t.node);
+ this.toArrayRec(t.right, a);
+ }
+ };
+
+ /**
+ * Returns an array of the node set's contents in arbitrary order
+ */
+ XNodeSet.prototype.toUnsortedArray = function () {
+ return this.nodes.slice();
+ };
+
+ XNodeSet.prototype.compareWithString = function (r, o) {
+ var a = this.toUnsortedArray();
+ for (var i = 0; i < a.length; i++) {
+ var n = a[i];
+ var l = new XString(this.stringForNode(n));
+ var res = o(l, r);
+ if (res.booleanValue()) {
+ return res;
+ }
+ }
+ return new XBoolean(false);
+ };
+
+ XNodeSet.prototype.compareWithNumber = function (r, o) {
+ var a = this.toUnsortedArray();
+ for (var i = 0; i < a.length; i++) {
+ var n = a[i];
+ var l = new XNumber(this.stringForNode(n));
+ var res = o(l, r);
+ if (res.booleanValue()) {
+ return res;
+ }
+ }
+ return new XBoolean(false);
+ };
+
+ XNodeSet.prototype.compareWithBoolean = function (r, o) {
+ return o(this.bool(), r);
+ };
+
+ XNodeSet.prototype.compareWithNodeSet = function (r, o) {
+ var arr = this.toUnsortedArray();
+ var oInvert = function (lop, rop) { return o(rop, lop); };
+
+ for (var i = 0; i < arr.length; i++) {
+ var l = new XString(this.stringForNode(arr[i]));
+
+ var res = r.compareWithString(l, oInvert);
+ if (res.booleanValue()) {
+ return res;
+ }
+ }
+
+ return new XBoolean(false);
+ };
+
+ XNodeSet.compareWith = curry(function (o, r) {
+ if (Utilities.instance_of(r, XString)) {
+ return this.compareWithString(r, o);
+ }
+ if (Utilities.instance_of(r, XNumber)) {
+ return this.compareWithNumber(r, o);
+ }
+ if (Utilities.instance_of(r, XBoolean)) {
+ return this.compareWithBoolean(r, o);
+ }
+ return this.compareWithNodeSet(r, o);
+ });
+
+ XNodeSet.prototype.equals = XNodeSet.compareWith(Operators.equals);
+ XNodeSet.prototype.notequal = XNodeSet.compareWith(Operators.notequal);
+ XNodeSet.prototype.lessthan = XNodeSet.compareWith(Operators.lessthan);
+ XNodeSet.prototype.greaterthan = XNodeSet.compareWith(Operators.greaterthan);
+ XNodeSet.prototype.lessthanorequal = XNodeSet.compareWith(Operators.lessthanorequal);
+ XNodeSet.prototype.greaterthanorequal = XNodeSet.compareWith(Operators.greaterthanorequal);
+
+ XNodeSet.prototype.union = function (r) {
+ var ns = new XNodeSet();
+ ns.addArray(this.toUnsortedArray());
+ ns.addArray(r.toUnsortedArray());
+ return ns;
+ };
+
+ // XPathNamespace ////////////////////////////////////////////////////////////
+
+ XPathNamespace.prototype = new Object();
+ XPathNamespace.prototype.constructor = XPathNamespace;
+ XPathNamespace.superclass = Object.prototype;
+
+ function XPathNamespace(pre, ns, p) {
+ this.isXPathNamespace = true;
+ this.ownerDocument = p.ownerDocument;
+ this.nodeName = "#namespace";
+ this.prefix = pre;
+ this.localName = pre;
+ this.namespaceURI = ns;
+ this.nodeValue = ns;
+ this.ownerElement = p;
+ this.nodeType = XPathNamespace.XPATH_NAMESPACE_NODE;
+ }
+
+ XPathNamespace.prototype.toString = function () {
+ return "{ \"" + this.prefix + "\", \"" + this.namespaceURI + "\" }";
+ };
+
+ // XPathContext //////////////////////////////////////////////////////////////
+
+ XPathContext.prototype = new Object();
+ XPathContext.prototype.constructor = XPathContext;
+ XPathContext.superclass = Object.prototype;
+
+ function XPathContext(vr, nr, fr) {
+ this.variableResolver = vr != null ? vr : new VariableResolver();
+ this.namespaceResolver = nr != null ? nr : new NamespaceResolver();
+ this.functionResolver = fr != null ? fr : new FunctionResolver();
+ }
+
+ XPathContext.prototype.extend = function (newProps) {
+ return assign(new XPathContext(), this, newProps);
+ };
+
+ // VariableResolver //////////////////////////////////////////////////////////
+
+ VariableResolver.prototype = new Object();
+ VariableResolver.prototype.constructor = VariableResolver;
+ VariableResolver.superclass = Object.prototype;
+
+ function VariableResolver() {
+ }
+
+ VariableResolver.prototype.getVariable = function (ln, ns) {
+ return null;
+ };
+
+ // FunctionResolver //////////////////////////////////////////////////////////
+
+ FunctionResolver.prototype = new Object();
+ FunctionResolver.prototype.constructor = FunctionResolver;
+ FunctionResolver.superclass = Object.prototype;
+
+ function FunctionResolver(thisArg) {
+ this.thisArg = thisArg != null ? thisArg : Functions;
+ this.functions = new Object();
+ this.addStandardFunctions();
+ }
+
+ FunctionResolver.prototype.addStandardFunctions = function () {
+ this.functions["{}last"] = Functions.last;
+ this.functions["{}position"] = Functions.position;
+ this.functions["{}count"] = Functions.count;
+ this.functions["{}id"] = Functions.id;
+ this.functions["{}local-name"] = Functions.localName;
+ this.functions["{}namespace-uri"] = Functions.namespaceURI;
+ this.functions["{}name"] = Functions.name;
+ this.functions["{}string"] = Functions.string;
+ this.functions["{}concat"] = Functions.concat;
+ this.functions["{}starts-with"] = Functions.startsWith;
+ this.functions["{}contains"] = Functions.contains;
+ this.functions["{}substring-before"] = Functions.substringBefore;
+ this.functions["{}substring-after"] = Functions.substringAfter;
+ this.functions["{}substring"] = Functions.substring;
+ this.functions["{}string-length"] = Functions.stringLength;
+ this.functions["{}normalize-space"] = Functions.normalizeSpace;
+ this.functions["{}translate"] = Functions.translate;
+ this.functions["{}boolean"] = Functions.boolean_;
+ this.functions["{}not"] = Functions.not;
+ this.functions["{}true"] = Functions.true_;
+ this.functions["{}false"] = Functions.false_;
+ this.functions["{}lang"] = Functions.lang;
+ this.functions["{}number"] = Functions.number;
+ this.functions["{}sum"] = Functions.sum;
+ this.functions["{}floor"] = Functions.floor;
+ this.functions["{}ceiling"] = Functions.ceiling;
+ this.functions["{}round"] = Functions.round;
+ };
+
+ FunctionResolver.prototype.addFunction = function (ns, ln, f) {
+ this.functions["{" + ns + "}" + ln] = f;
+ };
+
+ FunctionResolver.getFunctionFromContext = function (qName, context) {
+ var parts = Utilities.resolveQName(qName, context.namespaceResolver, context.contextNode, false);
+
+ if (parts[0] === null) {
+ throw new Error("Cannot resolve QName " + name);
+ }
+
+ return context.functionResolver.getFunction(parts[1], parts[0]);
+ };
+
+ FunctionResolver.prototype.getFunction = function (localName, namespace) {
+ return this.functions["{" + namespace + "}" + localName];
+ };
+
+ // NamespaceResolver /////////////////////////////////////////////////////////
+
+ NamespaceResolver.prototype = new Object();
+ NamespaceResolver.prototype.constructor = NamespaceResolver;
+ NamespaceResolver.superclass = Object.prototype;
+
+ function NamespaceResolver() {
+ }
+
+ NamespaceResolver.prototype.getNamespace = function (prefix, n) {
+ if (prefix == "xml") {
+ return XPath.XML_NAMESPACE_URI;
+ } else if (prefix == "xmlns") {
+ return XPath.XMLNS_NAMESPACE_URI;
+ }
+ if (n.nodeType == 9 /*Node.DOCUMENT_NODE*/) {
+ n = n.documentElement;
+ } else if (n.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
+ n = PathExpr.getOwnerElement(n);
+ } else if (n.nodeType != 1 /*Node.ELEMENT_NODE*/) {
+ n = n.parentNode;
+ }
+ while (n != null && n.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ var nnm = n.attributes;
+ for (var i = 0; i < nnm.length; i++) {
+ var a = nnm.item(i);
+ var aname = a.name || a.nodeName;
+ if ((aname === "xmlns" && prefix === "")
+ || aname === "xmlns:" + prefix) {
+ return String(a.value || a.nodeValue);
+ }
+ }
+ n = n.parentNode;
+ }
+ return null;
+ };
+
+ // Functions /////////////////////////////////////////////////////////////////
+
+ var Functions = new Object();
+
+ Functions.last = function (c) {
+ if (arguments.length != 1) {
+ throw new Error("Function last expects ()");
+ }
+
+ return new XNumber(c.contextSize);
+ };
+
+ Functions.position = function (c) {
+ if (arguments.length != 1) {
+ throw new Error("Function position expects ()");
+ }
+
+ return new XNumber(c.contextPosition);
+ };
+
+ Functions.count = function () {
+ var c = arguments[0];
+ var ns;
+ if (arguments.length != 2 || !Utilities.instance_of(ns = arguments[1].evaluate(c), XNodeSet)) {
+ throw new Error("Function count expects (node-set)");
+ }
+ return new XNumber(ns.size);
+ };
+
+ Functions.id = function () {
+ var c = arguments[0];
+ var id;
+ if (arguments.length != 2) {
+ throw new Error("Function id expects (object)");
+ }
+ id = arguments[1].evaluate(c);
+ if (Utilities.instance_of(id, XNodeSet)) {
+ id = id.toArray().join(" ");
+ } else {
+ id = id.stringValue();
+ }
+ var ids = id.split(/[\x0d\x0a\x09\x20]+/);
+ var count = 0;
+ var ns = new XNodeSet();
+ var doc = c.contextNode.nodeType == 9 /*Node.DOCUMENT_NODE*/
+ ? c.contextNode
+ : c.contextNode.ownerDocument;
+ for (var i = 0; i < ids.length; i++) {
+ var n;
+ if (doc.getElementById) {
+ n = doc.getElementById(ids[i]);
+ } else {
+ n = Utilities.getElementById(doc, ids[i]);
+ }
+ if (n != null) {
+ ns.add(n);
+ count++;
+ }
+ }
+ return ns;
+ };
+
+ Functions.localName = function (c, eNode) {
+ var n;
+
+ if (arguments.length == 1) {
+ n = c.contextNode;
+ } else if (arguments.length == 2) {
+ n = eNode.evaluate(c).first();
+ } else {
+ throw new Error("Function local-name expects (node-set?)");
+ }
+
+ if (n == null) {
+ return new XString("");
+ }
+
+ return new XString(
+ n.localName || // standard elements and attributes
+ n.baseName || // IE
+ n.target || // processing instructions
+ n.nodeName || // DOM1 elements
+ "" // fallback
+ );
+ };
+
+ Functions.namespaceURI = function () {
+ var c = arguments[0];
+ var n;
+ if (arguments.length == 1) {
+ n = c.contextNode;
+ } else if (arguments.length == 2) {
+ n = arguments[1].evaluate(c).first();
+ } else {
+ throw new Error("Function namespace-uri expects (node-set?)");
+ }
+ if (n == null) {
+ return new XString("");
+ }
+ return new XString(n.namespaceURI);
+ };
+
+ Functions.name = function () {
+ var c = arguments[0];
+ var n;
+ if (arguments.length == 1) {
+ n = c.contextNode;
+ } else if (arguments.length == 2) {
+ n = arguments[1].evaluate(c).first();
+ } else {
+ throw new Error("Function name expects (node-set?)");
+ }
+ if (n == null) {
+ return new XString("");
+ }
+ if (n.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ return new XString(n.nodeName);
+ } else if (n.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
+ return new XString(n.name || n.nodeName);
+ } else if (n.nodeType === 7 /*Node.PROCESSING_INSTRUCTION_NODE*/) {
+ return new XString(n.target || n.nodeName);
+ } else if (n.localName == null) {
+ return new XString("");
+ } else {
+ return new XString(n.localName);
+ }
+ };
+
+ Functions.string = function () {
+ var c = arguments[0];
+ if (arguments.length == 1) {
+ return new XString(XNodeSet.prototype.stringForNode(c.contextNode));
+ } else if (arguments.length == 2) {
+ return arguments[1].evaluate(c).string();
+ }
+ throw new Error("Function string expects (object?)");
+ };
+
+ Functions.concat = function (c) {
+ if (arguments.length < 3) {
+ throw new Error("Function concat expects (string, string[, string]*)");
+ }
+ var s = "";
+ for (var i = 1; i < arguments.length; i++) {
+ s += arguments[i].evaluate(c).stringValue();
+ }
+ return new XString(s);
+ };
+
+ Functions.startsWith = function () {
+ var c = arguments[0];
+ if (arguments.length != 3) {
+ throw new Error("Function startsWith expects (string, string)");
+ }
+ var s1 = arguments[1].evaluate(c).stringValue();
+ var s2 = arguments[2].evaluate(c).stringValue();
+ return new XBoolean(s1.substring(0, s2.length) == s2);
+ };
+
+ Functions.contains = function () {
+ var c = arguments[0];
+ if (arguments.length != 3) {
+ throw new Error("Function contains expects (string, string)");
+ }
+ var s1 = arguments[1].evaluate(c).stringValue();
+ var s2 = arguments[2].evaluate(c).stringValue();
+ return new XBoolean(s1.indexOf(s2) !== -1);
+ };
+
+ Functions.substringBefore = function () {
+ var c = arguments[0];
+ if (arguments.length != 3) {
+ throw new Error("Function substring-before expects (string, string)");
+ }
+ var s1 = arguments[1].evaluate(c).stringValue();
+ var s2 = arguments[2].evaluate(c).stringValue();
+ return new XString(s1.substring(0, s1.indexOf(s2)));
+ };
+
+ Functions.substringAfter = function () {
+ var c = arguments[0];
+ if (arguments.length != 3) {
+ throw new Error("Function substring-after expects (string, string)");
+ }
+ var s1 = arguments[1].evaluate(c).stringValue();
+ var s2 = arguments[2].evaluate(c).stringValue();
+ if (s2.length == 0) {
+ return new XString(s1);
+ }
+ var i = s1.indexOf(s2);
+ if (i == -1) {
+ return new XString("");
+ }
+ return new XString(s1.substring(i + s2.length));
+ };
+
+ Functions.substring = function () {
+ var c = arguments[0];
+ if (!(arguments.length == 3 || arguments.length == 4)) {
+ throw new Error("Function substring expects (string, number, number?)");
+ }
+ var s = arguments[1].evaluate(c).stringValue();
+ var n1 = Math.round(arguments[2].evaluate(c).numberValue()) - 1;
+ var n2 = arguments.length == 4 ? n1 + Math.round(arguments[3].evaluate(c).numberValue()) : undefined;
+ return new XString(s.substring(n1, n2));
+ };
+
+ Functions.stringLength = function () {
+ var c = arguments[0];
+ var s;
+ if (arguments.length == 1) {
+ s = XNodeSet.prototype.stringForNode(c.contextNode);
+ } else if (arguments.length == 2) {
+ s = arguments[1].evaluate(c).stringValue();
+ } else {
+ throw new Error("Function string-length expects (string?)");
+ }
+ return new XNumber(s.length);
+ };
+
+ Functions.normalizeSpace = function () {
+ var c = arguments[0];
+ var s;
+ if (arguments.length == 1) {
+ s = XNodeSet.prototype.stringForNode(c.contextNode);
+ } else if (arguments.length == 2) {
+ s = arguments[1].evaluate(c).stringValue();
+ } else {
+ throw new Error("Function normalize-space expects (string?)");
+ }
+ var i = 0;
+ var j = s.length - 1;
+ while (Utilities.isSpace(s.charCodeAt(j))) {
+ j--;
+ }
+ var t = "";
+ while (i <= j && Utilities.isSpace(s.charCodeAt(i))) {
+ i++;
+ }
+ while (i <= j) {
+ if (Utilities.isSpace(s.charCodeAt(i))) {
+ t += " ";
+ while (i <= j && Utilities.isSpace(s.charCodeAt(i))) {
+ i++;
+ }
+ } else {
+ t += s.charAt(i);
+ i++;
+ }
+ }
+ return new XString(t);
+ };
+
+ Functions.translate = function (c, eValue, eFrom, eTo) {
+ if (arguments.length != 4) {
+ throw new Error("Function translate expects (string, string, string)");
+ }
+
+ var value = eValue.evaluate(c).stringValue();
+ var from = eFrom.evaluate(c).stringValue();
+ var to = eTo.evaluate(c).stringValue();
+
+ var cMap = reduce(function (acc, ch, i) {
+ if (!(ch in acc)) {
+ acc[ch] = i > to.length ? '' : to[i];
+ }
+ return acc;
+ }, {}, from);
+
+ var t = join(
+ '',
+ map(function (ch) {
+ return ch in cMap ? cMap[ch] : ch;
+ }, value)
+ );
+
+ return new XString(t);
+ };
+
+ Functions.boolean_ = function () {
+ var c = arguments[0];
+ if (arguments.length != 2) {
+ throw new Error("Function boolean expects (object)");
+ }
+ return arguments[1].evaluate(c).bool();
+ };
+
+ Functions.not = function (c, eValue) {
+ if (arguments.length != 2) {
+ throw new Error("Function not expects (object)");
+ }
+ return eValue.evaluate(c).bool().not();
+ };
+
+ Functions.true_ = function () {
+ if (arguments.length != 1) {
+ throw new Error("Function true expects ()");
+ }
+ return XBoolean.true_;
+ };
+
+ Functions.false_ = function () {
+ if (arguments.length != 1) {
+ throw new Error("Function false expects ()");
+ }
+ return XBoolean.false_;
+ };
+
+ Functions.lang = function () {
+ var c = arguments[0];
+ if (arguments.length != 2) {
+ throw new Error("Function lang expects (string)");
+ }
+ var lang;
+ for (var n = c.contextNode; n != null && n.nodeType != 9 /*Node.DOCUMENT_NODE*/; n = n.parentNode) {
+ var a = n.getAttributeNS(XPath.XML_NAMESPACE_URI, "lang");
+ if (a != null) {
+ lang = String(a);
+ break;
+ }
+ }
+ if (lang == null) {
+ return XBoolean.false_;
+ }
+ var s = arguments[1].evaluate(c).stringValue();
+ return new XBoolean(lang.substring(0, s.length) == s
+ && (lang.length == s.length || lang.charAt(s.length) == '-'));
+ };
+
+ Functions.number = function () {
+ var c = arguments[0];
+ if (!(arguments.length == 1 || arguments.length == 2)) {
+ throw new Error("Function number expects (object?)");
+ }
+ if (arguments.length == 1) {
+ return new XNumber(XNodeSet.prototype.stringForNode(c.contextNode));
+ }
+ return arguments[1].evaluate(c).number();
+ };
+
+ Functions.sum = function () {
+ var c = arguments[0];
+ var ns;
+ if (arguments.length != 2 || !Utilities.instance_of((ns = arguments[1].evaluate(c)), XNodeSet)) {
+ throw new Error("Function sum expects (node-set)");
+ }
+ ns = ns.toUnsortedArray();
+ var n = 0;
+ for (var i = 0; i < ns.length; i++) {
+ n += new XNumber(XNodeSet.prototype.stringForNode(ns[i])).numberValue();
+ }
+ return new XNumber(n);
+ };
+
+ Functions.floor = function () {
+ var c = arguments[0];
+ if (arguments.length != 2) {
+ throw new Error("Function floor expects (number)");
+ }
+ return new XNumber(Math.floor(arguments[1].evaluate(c).numberValue()));
+ };
+
+ Functions.ceiling = function () {
+ var c = arguments[0];
+ if (arguments.length != 2) {
+ throw new Error("Function ceiling expects (number)");
+ }
+ return new XNumber(Math.ceil(arguments[1].evaluate(c).numberValue()));
+ };
+
+ Functions.round = function () {
+ var c = arguments[0];
+ if (arguments.length != 2) {
+ throw new Error("Function round expects (number)");
+ }
+ return new XNumber(Math.round(arguments[1].evaluate(c).numberValue()));
+ };
+
+ // Utilities /////////////////////////////////////////////////////////////////
+
+ var Utilities = new Object();
+
+ Utilities.isAttribute = function (val) {
+ return val && (val.nodeType === 2 || val.ownerElement);
+ }
+
+ Utilities.splitQName = function (qn) {
+ var i = qn.indexOf(":");
+ if (i == -1) {
+ return [null, qn];
+ }
+ return [qn.substring(0, i), qn.substring(i + 1)];
+ };
+
+ Utilities.resolveQName = function (qn, nr, n, useDefault) {
+ var parts = Utilities.splitQName(qn);
+ if (parts[0] != null) {
+ parts[0] = nr.getNamespace(parts[0], n);
+ } else {
+ if (useDefault) {
+ parts[0] = nr.getNamespace("", n);
+ if (parts[0] == null) {
+ parts[0] = "";
+ }
+ } else {
+ parts[0] = "";
+ }
+ }
+ return parts;
+ };
+
+ Utilities.isSpace = function (c) {
+ return c == 0x9 || c == 0xd || c == 0xa || c == 0x20;
+ };
+
+ Utilities.isLetter = function (c) {
+ return c >= 0x0041 && c <= 0x005A ||
+ c >= 0x0061 && c <= 0x007A ||
+ c >= 0x00C0 && c <= 0x00D6 ||
+ c >= 0x00D8 && c <= 0x00F6 ||
+ c >= 0x00F8 && c <= 0x00FF ||
+ c >= 0x0100 && c <= 0x0131 ||
+ c >= 0x0134 && c <= 0x013E ||
+ c >= 0x0141 && c <= 0x0148 ||
+ c >= 0x014A && c <= 0x017E ||
+ c >= 0x0180 && c <= 0x01C3 ||
+ c >= 0x01CD && c <= 0x01F0 ||
+ c >= 0x01F4 && c <= 0x01F5 ||
+ c >= 0x01FA && c <= 0x0217 ||
+ c >= 0x0250 && c <= 0x02A8 ||
+ c >= 0x02BB && c <= 0x02C1 ||
+ c == 0x0386 ||
+ c >= 0x0388 && c <= 0x038A ||
+ c == 0x038C ||
+ c >= 0x038E && c <= 0x03A1 ||
+ c >= 0x03A3 && c <= 0x03CE ||
+ c >= 0x03D0 && c <= 0x03D6 ||
+ c == 0x03DA ||
+ c == 0x03DC ||
+ c == 0x03DE ||
+ c == 0x03E0 ||
+ c >= 0x03E2 && c <= 0x03F3 ||
+ c >= 0x0401 && c <= 0x040C ||
+ c >= 0x040E && c <= 0x044F ||
+ c >= 0x0451 && c <= 0x045C ||
+ c >= 0x045E && c <= 0x0481 ||
+ c >= 0x0490 && c <= 0x04C4 ||
+ c >= 0x04C7 && c <= 0x04C8 ||
+ c >= 0x04CB && c <= 0x04CC ||
+ c >= 0x04D0 && c <= 0x04EB ||
+ c >= 0x04EE && c <= 0x04F5 ||
+ c >= 0x04F8 && c <= 0x04F9 ||
+ c >= 0x0531 && c <= 0x0556 ||
+ c == 0x0559 ||
+ c >= 0x0561 && c <= 0x0586 ||
+ c >= 0x05D0 && c <= 0x05EA ||
+ c >= 0x05F0 && c <= 0x05F2 ||
+ c >= 0x0621 && c <= 0x063A ||
+ c >= 0x0641 && c <= 0x064A ||
+ c >= 0x0671 && c <= 0x06B7 ||
+ c >= 0x06BA && c <= 0x06BE ||
+ c >= 0x06C0 && c <= 0x06CE ||
+ c >= 0x06D0 && c <= 0x06D3 ||
+ c == 0x06D5 ||
+ c >= 0x06E5 && c <= 0x06E6 ||
+ c >= 0x0905 && c <= 0x0939 ||
+ c == 0x093D ||
+ c >= 0x0958 && c <= 0x0961 ||
+ c >= 0x0985 && c <= 0x098C ||
+ c >= 0x098F && c <= 0x0990 ||
+ c >= 0x0993 && c <= 0x09A8 ||
+ c >= 0x09AA && c <= 0x09B0 ||
+ c == 0x09B2 ||
+ c >= 0x09B6 && c <= 0x09B9 ||
+ c >= 0x09DC && c <= 0x09DD ||
+ c >= 0x09DF && c <= 0x09E1 ||
+ c >= 0x09F0 && c <= 0x09F1 ||
+ c >= 0x0A05 && c <= 0x0A0A ||
+ c >= 0x0A0F && c <= 0x0A10 ||
+ c >= 0x0A13 && c <= 0x0A28 ||
+ c >= 0x0A2A && c <= 0x0A30 ||
+ c >= 0x0A32 && c <= 0x0A33 ||
+ c >= 0x0A35 && c <= 0x0A36 ||
+ c >= 0x0A38 && c <= 0x0A39 ||
+ c >= 0x0A59 && c <= 0x0A5C ||
+ c == 0x0A5E ||
+ c >= 0x0A72 && c <= 0x0A74 ||
+ c >= 0x0A85 && c <= 0x0A8B ||
+ c == 0x0A8D ||
+ c >= 0x0A8F && c <= 0x0A91 ||
+ c >= 0x0A93 && c <= 0x0AA8 ||
+ c >= 0x0AAA && c <= 0x0AB0 ||
+ c >= 0x0AB2 && c <= 0x0AB3 ||
+ c >= 0x0AB5 && c <= 0x0AB9 ||
+ c == 0x0ABD ||
+ c == 0x0AE0 ||
+ c >= 0x0B05 && c <= 0x0B0C ||
+ c >= 0x0B0F && c <= 0x0B10 ||
+ c >= 0x0B13 && c <= 0x0B28 ||
+ c >= 0x0B2A && c <= 0x0B30 ||
+ c >= 0x0B32 && c <= 0x0B33 ||
+ c >= 0x0B36 && c <= 0x0B39 ||
+ c == 0x0B3D ||
+ c >= 0x0B5C && c <= 0x0B5D ||
+ c >= 0x0B5F && c <= 0x0B61 ||
+ c >= 0x0B85 && c <= 0x0B8A ||
+ c >= 0x0B8E && c <= 0x0B90 ||
+ c >= 0x0B92 && c <= 0x0B95 ||
+ c >= 0x0B99 && c <= 0x0B9A ||
+ c == 0x0B9C ||
+ c >= 0x0B9E && c <= 0x0B9F ||
+ c >= 0x0BA3 && c <= 0x0BA4 ||
+ c >= 0x0BA8 && c <= 0x0BAA ||
+ c >= 0x0BAE && c <= 0x0BB5 ||
+ c >= 0x0BB7 && c <= 0x0BB9 ||
+ c >= 0x0C05 && c <= 0x0C0C ||
+ c >= 0x0C0E && c <= 0x0C10 ||
+ c >= 0x0C12 && c <= 0x0C28 ||
+ c >= 0x0C2A && c <= 0x0C33 ||
+ c >= 0x0C35 && c <= 0x0C39 ||
+ c >= 0x0C60 && c <= 0x0C61 ||
+ c >= 0x0C85 && c <= 0x0C8C ||
+ c >= 0x0C8E && c <= 0x0C90 ||
+ c >= 0x0C92 && c <= 0x0CA8 ||
+ c >= 0x0CAA && c <= 0x0CB3 ||
+ c >= 0x0CB5 && c <= 0x0CB9 ||
+ c == 0x0CDE ||
+ c >= 0x0CE0 && c <= 0x0CE1 ||
+ c >= 0x0D05 && c <= 0x0D0C ||
+ c >= 0x0D0E && c <= 0x0D10 ||
+ c >= 0x0D12 && c <= 0x0D28 ||
+ c >= 0x0D2A && c <= 0x0D39 ||
+ c >= 0x0D60 && c <= 0x0D61 ||
+ c >= 0x0E01 && c <= 0x0E2E ||
+ c == 0x0E30 ||
+ c >= 0x0E32 && c <= 0x0E33 ||
+ c >= 0x0E40 && c <= 0x0E45 ||
+ c >= 0x0E81 && c <= 0x0E82 ||
+ c == 0x0E84 ||
+ c >= 0x0E87 && c <= 0x0E88 ||
+ c == 0x0E8A ||
+ c == 0x0E8D ||
+ c >= 0x0E94 && c <= 0x0E97 ||
+ c >= 0x0E99 && c <= 0x0E9F ||
+ c >= 0x0EA1 && c <= 0x0EA3 ||
+ c == 0x0EA5 ||
+ c == 0x0EA7 ||
+ c >= 0x0EAA && c <= 0x0EAB ||
+ c >= 0x0EAD && c <= 0x0EAE ||
+ c == 0x0EB0 ||
+ c >= 0x0EB2 && c <= 0x0EB3 ||
+ c == 0x0EBD ||
+ c >= 0x0EC0 && c <= 0x0EC4 ||
+ c >= 0x0F40 && c <= 0x0F47 ||
+ c >= 0x0F49 && c <= 0x0F69 ||
+ c >= 0x10A0 && c <= 0x10C5 ||
+ c >= 0x10D0 && c <= 0x10F6 ||
+ c == 0x1100 ||
+ c >= 0x1102 && c <= 0x1103 ||
+ c >= 0x1105 && c <= 0x1107 ||
+ c == 0x1109 ||
+ c >= 0x110B && c <= 0x110C ||
+ c >= 0x110E && c <= 0x1112 ||
+ c == 0x113C ||
+ c == 0x113E ||
+ c == 0x1140 ||
+ c == 0x114C ||
+ c == 0x114E ||
+ c == 0x1150 ||
+ c >= 0x1154 && c <= 0x1155 ||
+ c == 0x1159 ||
+ c >= 0x115F && c <= 0x1161 ||
+ c == 0x1163 ||
+ c == 0x1165 ||
+ c == 0x1167 ||
+ c == 0x1169 ||
+ c >= 0x116D && c <= 0x116E ||
+ c >= 0x1172 && c <= 0x1173 ||
+ c == 0x1175 ||
+ c == 0x119E ||
+ c == 0x11A8 ||
+ c == 0x11AB ||
+ c >= 0x11AE && c <= 0x11AF ||
+ c >= 0x11B7 && c <= 0x11B8 ||
+ c == 0x11BA ||
+ c >= 0x11BC && c <= 0x11C2 ||
+ c == 0x11EB ||
+ c == 0x11F0 ||
+ c == 0x11F9 ||
+ c >= 0x1E00 && c <= 0x1E9B ||
+ c >= 0x1EA0 && c <= 0x1EF9 ||
+ c >= 0x1F00 && c <= 0x1F15 ||
+ c >= 0x1F18 && c <= 0x1F1D ||
+ c >= 0x1F20 && c <= 0x1F45 ||
+ c >= 0x1F48 && c <= 0x1F4D ||
+ c >= 0x1F50 && c <= 0x1F57 ||
+ c == 0x1F59 ||
+ c == 0x1F5B ||
+ c == 0x1F5D ||
+ c >= 0x1F5F && c <= 0x1F7D ||
+ c >= 0x1F80 && c <= 0x1FB4 ||
+ c >= 0x1FB6 && c <= 0x1FBC ||
+ c == 0x1FBE ||
+ c >= 0x1FC2 && c <= 0x1FC4 ||
+ c >= 0x1FC6 && c <= 0x1FCC ||
+ c >= 0x1FD0 && c <= 0x1FD3 ||
+ c >= 0x1FD6 && c <= 0x1FDB ||
+ c >= 0x1FE0 && c <= 0x1FEC ||
+ c >= 0x1FF2 && c <= 0x1FF4 ||
+ c >= 0x1FF6 && c <= 0x1FFC ||
+ c == 0x2126 ||
+ c >= 0x212A && c <= 0x212B ||
+ c == 0x212E ||
+ c >= 0x2180 && c <= 0x2182 ||
+ c >= 0x3041 && c <= 0x3094 ||
+ c >= 0x30A1 && c <= 0x30FA ||
+ c >= 0x3105 && c <= 0x312C ||
+ c >= 0xAC00 && c <= 0xD7A3 ||
+ c >= 0x4E00 && c <= 0x9FA5 ||
+ c == 0x3007 ||
+ c >= 0x3021 && c <= 0x3029;
+ };
+
+ Utilities.isNCNameChar = function (c) {
+ return c >= 0x0030 && c <= 0x0039
+ || c >= 0x0660 && c <= 0x0669
+ || c >= 0x06F0 && c <= 0x06F9
+ || c >= 0x0966 && c <= 0x096F
+ || c >= 0x09E6 && c <= 0x09EF
+ || c >= 0x0A66 && c <= 0x0A6F
+ || c >= 0x0AE6 && c <= 0x0AEF
+ || c >= 0x0B66 && c <= 0x0B6F
+ || c >= 0x0BE7 && c <= 0x0BEF
+ || c >= 0x0C66 && c <= 0x0C6F
+ || c >= 0x0CE6 && c <= 0x0CEF
+ || c >= 0x0D66 && c <= 0x0D6F
+ || c >= 0x0E50 && c <= 0x0E59
+ || c >= 0x0ED0 && c <= 0x0ED9
+ || c >= 0x0F20 && c <= 0x0F29
+ || c == 0x002E
+ || c == 0x002D
+ || c == 0x005F
+ || Utilities.isLetter(c)
+ || c >= 0x0300 && c <= 0x0345
+ || c >= 0x0360 && c <= 0x0361
+ || c >= 0x0483 && c <= 0x0486
+ || c >= 0x0591 && c <= 0x05A1
+ || c >= 0x05A3 && c <= 0x05B9
+ || c >= 0x05BB && c <= 0x05BD
+ || c == 0x05BF
+ || c >= 0x05C1 && c <= 0x05C2
+ || c == 0x05C4
+ || c >= 0x064B && c <= 0x0652
+ || c == 0x0670
+ || c >= 0x06D6 && c <= 0x06DC
+ || c >= 0x06DD && c <= 0x06DF
+ || c >= 0x06E0 && c <= 0x06E4
+ || c >= 0x06E7 && c <= 0x06E8
+ || c >= 0x06EA && c <= 0x06ED
+ || c >= 0x0901 && c <= 0x0903
+ || c == 0x093C
+ || c >= 0x093E && c <= 0x094C
+ || c == 0x094D
+ || c >= 0x0951 && c <= 0x0954
+ || c >= 0x0962 && c <= 0x0963
+ || c >= 0x0981 && c <= 0x0983
+ || c == 0x09BC
+ || c == 0x09BE
+ || c == 0x09BF
+ || c >= 0x09C0 && c <= 0x09C4
+ || c >= 0x09C7 && c <= 0x09C8
+ || c >= 0x09CB && c <= 0x09CD
+ || c == 0x09D7
+ || c >= 0x09E2 && c <= 0x09E3
+ || c == 0x0A02
+ || c == 0x0A3C
+ || c == 0x0A3E
+ || c == 0x0A3F
+ || c >= 0x0A40 && c <= 0x0A42
+ || c >= 0x0A47 && c <= 0x0A48
+ || c >= 0x0A4B && c <= 0x0A4D
+ || c >= 0x0A70 && c <= 0x0A71
+ || c >= 0x0A81 && c <= 0x0A83
+ || c == 0x0ABC
+ || c >= 0x0ABE && c <= 0x0AC5
+ || c >= 0x0AC7 && c <= 0x0AC9
+ || c >= 0x0ACB && c <= 0x0ACD
+ || c >= 0x0B01 && c <= 0x0B03
+ || c == 0x0B3C
+ || c >= 0x0B3E && c <= 0x0B43
+ || c >= 0x0B47 && c <= 0x0B48
+ || c >= 0x0B4B && c <= 0x0B4D
+ || c >= 0x0B56 && c <= 0x0B57
+ || c >= 0x0B82 && c <= 0x0B83
+ || c >= 0x0BBE && c <= 0x0BC2
+ || c >= 0x0BC6 && c <= 0x0BC8
+ || c >= 0x0BCA && c <= 0x0BCD
+ || c == 0x0BD7
+ || c >= 0x0C01 && c <= 0x0C03
+ || c >= 0x0C3E && c <= 0x0C44
+ || c >= 0x0C46 && c <= 0x0C48
+ || c >= 0x0C4A && c <= 0x0C4D
+ || c >= 0x0C55 && c <= 0x0C56
+ || c >= 0x0C82 && c <= 0x0C83
+ || c >= 0x0CBE && c <= 0x0CC4
+ || c >= 0x0CC6 && c <= 0x0CC8
+ || c >= 0x0CCA && c <= 0x0CCD
+ || c >= 0x0CD5 && c <= 0x0CD6
+ || c >= 0x0D02 && c <= 0x0D03
+ || c >= 0x0D3E && c <= 0x0D43
+ || c >= 0x0D46 && c <= 0x0D48
+ || c >= 0x0D4A && c <= 0x0D4D
+ || c == 0x0D57
+ || c == 0x0E31
+ || c >= 0x0E34 && c <= 0x0E3A
+ || c >= 0x0E47 && c <= 0x0E4E
+ || c == 0x0EB1
+ || c >= 0x0EB4 && c <= 0x0EB9
+ || c >= 0x0EBB && c <= 0x0EBC
+ || c >= 0x0EC8 && c <= 0x0ECD
+ || c >= 0x0F18 && c <= 0x0F19
+ || c == 0x0F35
+ || c == 0x0F37
+ || c == 0x0F39
+ || c == 0x0F3E
+ || c == 0x0F3F
+ || c >= 0x0F71 && c <= 0x0F84
+ || c >= 0x0F86 && c <= 0x0F8B
+ || c >= 0x0F90 && c <= 0x0F95
+ || c == 0x0F97
+ || c >= 0x0F99 && c <= 0x0FAD
+ || c >= 0x0FB1 && c <= 0x0FB7
+ || c == 0x0FB9
+ || c >= 0x20D0 && c <= 0x20DC
+ || c == 0x20E1
+ || c >= 0x302A && c <= 0x302F
+ || c == 0x3099
+ || c == 0x309A
+ || c == 0x00B7
+ || c == 0x02D0
+ || c == 0x02D1
+ || c == 0x0387
+ || c == 0x0640
+ || c == 0x0E46
+ || c == 0x0EC6
+ || c == 0x3005
+ || c >= 0x3031 && c <= 0x3035
+ || c >= 0x309D && c <= 0x309E
+ || c >= 0x30FC && c <= 0x30FE;
+ };
+
+ Utilities.coalesceText = function (n) {
+ for (var m = n.firstChild; m != null; m = m.nextSibling) {
+ if (m.nodeType == 3 /*Node.TEXT_NODE*/ || m.nodeType == 4 /*Node.CDATA_SECTION_NODE*/) {
+ var s = m.nodeValue;
+ var first = m;
+ m = m.nextSibling;
+ while (m != null && (m.nodeType == 3 /*Node.TEXT_NODE*/ || m.nodeType == 4 /*Node.CDATA_SECTION_NODE*/)) {
+ s += m.nodeValue;
+ var del = m;
+ m = m.nextSibling;
+ del.parentNode.removeChild(del);
+ }
+ if (first.nodeType == 4 /*Node.CDATA_SECTION_NODE*/) {
+ var p = first.parentNode;
+ if (first.nextSibling == null) {
+ p.removeChild(first);
+ p.appendChild(p.ownerDocument.createTextNode(s));
+ } else {
+ var next = first.nextSibling;
+ p.removeChild(first);
+ p.insertBefore(p.ownerDocument.createTextNode(s), next);
+ }
+ } else {
+ first.nodeValue = s;
+ }
+ if (m == null) {
+ break;
+ }
+ } else if (m.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ Utilities.coalesceText(m);
+ }
+ }
+ };
+
+ Utilities.instance_of = function (o, c) {
+ while (o != null) {
+ if (o.constructor === c) {
+ return true;
+ }
+ if (o === Object) {
+ return false;
+ }
+ o = o.constructor.superclass;
+ }
+ return false;
+ };
+
+ Utilities.getElementById = function (n, id) {
+ // Note that this does not check the DTD to check for actual
+ // attributes of type ID, so this may be a bit wrong.
+ if (n.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ if (n.getAttribute("id") == id
+ || n.getAttributeNS(null, "id") == id) {
+ return n;
+ }
+ }
+ for (var m = n.firstChild; m != null; m = m.nextSibling) {
+ var res = Utilities.getElementById(m, id);
+ if (res != null) {
+ return res;
+ }
+ }
+ return null;
+ };
+
+ // XPathException ////////////////////////////////////////////////////////////
+
+ var XPathException = (function () {
+ function getMessage(code, exception) {
+ var msg = exception ? ": " + exception.toString() : "";
+ switch (code) {
+ case XPathException.INVALID_EXPRESSION_ERR:
+ return "Invalid expression" + msg;
+ case XPathException.TYPE_ERR:
+ return "Type error" + msg;
+ }
+ return null;
+ }
+
+ function XPathException(code, error, message) {
+ var err = Error.call(this, getMessage(code, error) || message);
+
+ err.code = code;
+ err.exception = error;
+
+ return err;
+ }
+
+ XPathException.prototype = Object.create(Error.prototype);
+ XPathException.prototype.constructor = XPathException;
+ XPathException.superclass = Error;
+
+ XPathException.prototype.toString = function () {
+ return this.message;
+ };
+
+ XPathException.fromMessage = function (message, error) {
+ return new XPathException(null, error, message);
+ };
+
+ XPathException.INVALID_EXPRESSION_ERR = 51;
+ XPathException.TYPE_ERR = 52;
+
+ return XPathException;
+ })();
+
+ // XPathExpression ///////////////////////////////////////////////////////////
+
+ XPathExpression.prototype = {};
+ XPathExpression.prototype.constructor = XPathExpression;
+ XPathExpression.superclass = Object.prototype;
+
+ function XPathExpression(e, r, p) {
+ this.xpath = p.parse(e);
+ this.context = new XPathContext();
+ this.context.namespaceResolver = new XPathNSResolverWrapper(r);
+ }
+
+ XPathExpression.getOwnerDocument = function (n) {
+ return n.nodeType === 9 /*Node.DOCUMENT_NODE*/ ? n : n.ownerDocument;
+ }
+
+ XPathExpression.detectHtmlDom = function (n) {
+ if (!n) { return false; }
+
+ var doc = XPathExpression.getOwnerDocument(n);
+
+ try {
+ return doc.implementation.hasFeature("HTML", "2.0");
+ } catch (e) {
+ return true;
+ }
+ }
+
+ XPathExpression.prototype.evaluate = function (n, t, res) {
+ this.context.expressionContextNode = n;
+ // backward compatibility - no reliable way to detect whether the DOM is HTML, but
+ // this library has been using this method up until now, so we will continue to use it
+ // ONLY when using an XPathExpression
+ this.context.caseInsensitive = XPathExpression.detectHtmlDom(n);
+
+ var result = this.xpath.evaluate(this.context);
+ return new XPathResult(result, t);
+ }
+
+ // XPathNSResolverWrapper ////////////////////////////////////////////////////
+
+ XPathNSResolverWrapper.prototype = {};
+ XPathNSResolverWrapper.prototype.constructor = XPathNSResolverWrapper;
+ XPathNSResolverWrapper.superclass = Object.prototype;
+
+ function XPathNSResolverWrapper(r) {
+ this.xpathNSResolver = r;
+ }
+
+ XPathNSResolverWrapper.prototype.getNamespace = function (prefix, n) {
+ if (this.xpathNSResolver == null) {
+ return null;
+ }
+ return this.xpathNSResolver.lookupNamespaceURI(prefix);
+ };
+
+ // NodeXPathNSResolver ///////////////////////////////////////////////////////
+
+ NodeXPathNSResolver.prototype = {};
+ NodeXPathNSResolver.prototype.constructor = NodeXPathNSResolver;
+ NodeXPathNSResolver.superclass = Object.prototype;
+
+ function NodeXPathNSResolver(n) {
+ this.node = n;
+ this.namespaceResolver = new NamespaceResolver();
+ }
+
+ NodeXPathNSResolver.prototype.lookupNamespaceURI = function (prefix) {
+ return this.namespaceResolver.getNamespace(prefix, this.node);
+ };
+
+ // XPathResult ///////////////////////////////////////////////////////////////
+
+ XPathResult.prototype = {};
+ XPathResult.prototype.constructor = XPathResult;
+ XPathResult.superclass = Object.prototype;
+
+ function XPathResult(v, t) {
+ if (t == XPathResult.ANY_TYPE) {
+ if (v.constructor === XString) {
+ t = XPathResult.STRING_TYPE;
+ } else if (v.constructor === XNumber) {
+ t = XPathResult.NUMBER_TYPE;
+ } else if (v.constructor === XBoolean) {
+ t = XPathResult.BOOLEAN_TYPE;
+ } else if (v.constructor === XNodeSet) {
+ t = XPathResult.UNORDERED_NODE_ITERATOR_TYPE;
+ }
+ }
+ this.resultType = t;
+ switch (t) {
+ case XPathResult.NUMBER_TYPE:
+ this.numberValue = v.numberValue();
+ return;
+ case XPathResult.STRING_TYPE:
+ this.stringValue = v.stringValue();
+ return;
+ case XPathResult.BOOLEAN_TYPE:
+ this.booleanValue = v.booleanValue();
+ return;
+ case XPathResult.ANY_UNORDERED_NODE_TYPE:
+ case XPathResult.FIRST_ORDERED_NODE_TYPE:
+ if (v.constructor === XNodeSet) {
+ this.singleNodeValue = v.first();
+ return;
+ }
+ break;
+ case XPathResult.UNORDERED_NODE_ITERATOR_TYPE:
+ case XPathResult.ORDERED_NODE_ITERATOR_TYPE:
+ if (v.constructor === XNodeSet) {
+ this.invalidIteratorState = false;
+ this.nodes = v.toArray();
+ this.iteratorIndex = 0;
+ return;
+ }
+ break;
+ case XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE:
+ case XPathResult.ORDERED_NODE_SNAPSHOT_TYPE:
+ if (v.constructor === XNodeSet) {
+ this.nodes = v.toArray();
+ this.snapshotLength = this.nodes.length;
+ return;
+ }
+ break;
+ }
+ throw new XPathException(XPathException.TYPE_ERR);
+ };
+
+ XPathResult.prototype.iterateNext = function () {
+ if (this.resultType != XPathResult.UNORDERED_NODE_ITERATOR_TYPE
+ && this.resultType != XPathResult.ORDERED_NODE_ITERATOR_TYPE) {
+ throw new XPathException(XPathException.TYPE_ERR);
+ }
+ return this.nodes[this.iteratorIndex++];
+ };
+
+ XPathResult.prototype.snapshotItem = function (i) {
+ if (this.resultType != XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE
+ && this.resultType != XPathResult.ORDERED_NODE_SNAPSHOT_TYPE) {
+ throw new XPathException(XPathException.TYPE_ERR);
+ }
+ return this.nodes[i];
+ };
+
+ XPathResult.ANY_TYPE = 0;
+ XPathResult.NUMBER_TYPE = 1;
+ XPathResult.STRING_TYPE = 2;
+ XPathResult.BOOLEAN_TYPE = 3;
+ XPathResult.UNORDERED_NODE_ITERATOR_TYPE = 4;
+ XPathResult.ORDERED_NODE_ITERATOR_TYPE = 5;
+ XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE = 6;
+ XPathResult.ORDERED_NODE_SNAPSHOT_TYPE = 7;
+ XPathResult.ANY_UNORDERED_NODE_TYPE = 8;
+ XPathResult.FIRST_ORDERED_NODE_TYPE = 9;
+
+ // DOM 3 XPath support ///////////////////////////////////////////////////////
+
+ function installDOM3XPathSupport(doc, p) {
+ doc.createExpression = function (e, r) {
+ try {
+ return new XPathExpression(e, r, p);
+ } catch (e) {
+ throw new XPathException(XPathException.INVALID_EXPRESSION_ERR, e);
}
};
- }
-
- function makeFunctionResolverFromObject(obj) {
- return makeFunctionResolverFromFunction(obj.getFunction.bind(obj));
- }
-
- function makeFunctionResolverFromMap(map) {
- return makeFunctionResolverFromFunction(function (name) {
- return map[name];
- });
- }
-
- function makeFunctionResolver(resolver) {
- if (resolver && typeof resolver.getFunction === "function") {
- return makeFunctionResolverFromObject(resolver);
- }
-
- if (typeof resolver === "function") {
- return makeFunctionResolverFromFunction(resolver);
- }
-
- // assume map
- if (typeof resolver === "object") {
- return makeFunctionResolverFromMap(resolver);
- }
-
- return defaultFunctionResolver;
- }
-
- function makeVariableResolverFromFunction(func) {
- return {
- getVariable: function (name, namespace) {
- var value = func(name, namespace);
- return convertValue(value);
- }
+ doc.createNSResolver = function (n) {
+ return new NodeXPathNSResolver(n);
};
+ doc.evaluate = function (e, cn, r, t, res) {
+ if (t < 0 || t > 9) {
+ throw { code: 0, toString: function () { return "Request type not supported"; } };
+ }
+ return doc.createExpression(e, r, p).evaluate(cn, t, res);
+ };
+ };
+
+ // ---------------------------------------------------------------------------
+
+ // Install DOM 3 XPath support for the current document.
+ try {
+ var shouldInstall = true;
+ try {
+ if (document.implementation
+ && document.implementation.hasFeature
+ && document.implementation.hasFeature("XPath", null)) {
+ shouldInstall = false;
+ }
+ } catch (e) {
+ }
+ if (shouldInstall) {
+ installDOM3XPathSupport(document, new XPathParser());
+ }
+ } catch (e) {
}
- function makeVariableResolver(resolver) {
- if (resolver) {
- if (typeof resolver.getVariable === "function") {
- return makeVariableResolverFromFunction(resolver.getVariable.bind(resolver));
+ // ---------------------------------------------------------------------------
+ // exports for node.js
+
+ installDOM3XPathSupport(exports, new XPathParser());
+
+ (function () {
+ var parser = new XPathParser();
+
+ var defaultNSResolver = new NamespaceResolver();
+ var defaultFunctionResolver = new FunctionResolver();
+ var defaultVariableResolver = new VariableResolver();
+
+ function makeNSResolverFromFunction(func) {
+ return {
+ getNamespace: function (prefix, node) {
+ var ns = func(prefix, node);
+
+ return ns || defaultNSResolver.getNamespace(prefix, node);
+ }
+ };
+ }
+
+ function makeNSResolverFromObject(obj) {
+ return makeNSResolverFromFunction(obj.getNamespace.bind(obj));
+ }
+
+ function makeNSResolverFromMap(map) {
+ return makeNSResolverFromFunction(function (prefix) {
+ return map[prefix];
+ });
+ }
+
+ function makeNSResolver(resolver) {
+ if (resolver && typeof resolver.getNamespace === "function") {
+ return makeNSResolverFromObject(resolver);
}
if (typeof resolver === "function") {
- return makeVariableResolverFromFunction(resolver);
+ return makeNSResolverFromFunction(resolver);
+ }
+
+ // assume prefix -> uri mapping
+ if (typeof resolver === "object") {
+ return makeNSResolverFromMap(resolver);
+ }
+
+ return defaultNSResolver;
+ }
+
+ /** Converts native JavaScript types to their XPath library equivalent */
+ function convertValue(value) {
+ if (value === null ||
+ typeof value === "undefined" ||
+ value instanceof XString ||
+ value instanceof XBoolean ||
+ value instanceof XNumber ||
+ value instanceof XNodeSet) {
+ return value;
+ }
+
+ switch (typeof value) {
+ case "string": return new XString(value);
+ case "boolean": return new XBoolean(value);
+ case "number": return new XNumber(value);
+ }
+
+ // assume node(s)
+ var ns = new XNodeSet();
+ ns.addArray([].concat(value));
+ return ns;
+ }
+
+ function makeEvaluator(func) {
+ return function (context) {
+ var args = Array.prototype.slice.call(arguments, 1).map(function (arg) {
+ return arg.evaluate(context);
+ });
+ var result = func.apply(this, [].concat(context, args));
+ return convertValue(result);
+ };
+ }
+
+ function makeFunctionResolverFromFunction(func) {
+ return {
+ getFunction: function (name, namespace) {
+ var found = func(name, namespace);
+ if (found) {
+ return makeEvaluator(found);
+ }
+ return defaultFunctionResolver.getFunction(name, namespace);
+ }
+ };
+ }
+
+ function makeFunctionResolverFromObject(obj) {
+ return makeFunctionResolverFromFunction(obj.getFunction.bind(obj));
+ }
+
+ function makeFunctionResolverFromMap(map) {
+ return makeFunctionResolverFromFunction(function (name) {
+ return map[name];
+ });
+ }
+
+ function makeFunctionResolver(resolver) {
+ if (resolver && typeof resolver.getFunction === "function") {
+ return makeFunctionResolverFromObject(resolver);
+ }
+
+ if (typeof resolver === "function") {
+ return makeFunctionResolverFromFunction(resolver);
}
// assume map
if (typeof resolver === "object") {
- return makeVariableResolverFromFunction(function (name) {
- return resolver[name];
- });
+ return makeFunctionResolverFromMap(resolver);
}
+
+ return defaultFunctionResolver;
}
- return defaultVariableResolver;
- }
-
- function copyIfPresent(prop, dest, source) {
- if (prop in source) { dest[prop] = source[prop]; }
- }
-
- function makeContext(options) {
- var context = new XPathContext();
-
- if (options) {
- context.namespaceResolver = makeNSResolver(options.namespaces);
- context.functionResolver = makeFunctionResolver(options.functions);
- context.variableResolver = makeVariableResolver(options.variables);
- context.expressionContextNode = options.node;
- copyIfPresent('allowAnyNamespaceForNoPrefix', context, options);
- copyIfPresent('isHtml', context, options);
- } else {
- context.namespaceResolver = defaultNSResolver;
+ function makeVariableResolverFromFunction(func) {
+ return {
+ getVariable: function (name, namespace) {
+ var value = func(name, namespace);
+ return convertValue(value);
+ }
+ };
}
- return context;
- }
+ function makeVariableResolver(resolver) {
+ if (resolver) {
+ if (typeof resolver.getVariable === "function") {
+ return makeVariableResolverFromFunction(resolver.getVariable.bind(resolver));
+ }
- function evaluate(parsedExpression, options) {
- var context = makeContext(options);
+ if (typeof resolver === "function") {
+ return makeVariableResolverFromFunction(resolver);
+ }
- return parsedExpression.evaluate(context);
- }
+ // assume map
+ if (typeof resolver === "object") {
+ return makeVariableResolverFromFunction(function (name) {
+ return resolver[name];
+ });
+ }
+ }
- var evaluatorPrototype = {
- evaluate: function (options) {
- return evaluate(this.expression, options);
+ return defaultVariableResolver;
}
- ,evaluateNumber: function (options) {
- return this.evaluate(options).numberValue();
+ function copyIfPresent(prop, dest, source) {
+ if (prop in source) { dest[prop] = source[prop]; }
}
- ,evaluateString: function (options) {
- return this.evaluate(options).stringValue();
+ function makeContext(options) {
+ var context = new XPathContext();
+
+ if (options) {
+ context.namespaceResolver = makeNSResolver(options.namespaces);
+ context.functionResolver = makeFunctionResolver(options.functions);
+ context.variableResolver = makeVariableResolver(options.variables);
+ context.expressionContextNode = options.node;
+ copyIfPresent('allowAnyNamespaceForNoPrefix', context, options);
+ copyIfPresent('isHtml', context, options);
+ } else {
+ context.namespaceResolver = defaultNSResolver;
+ }
+
+ return context;
}
- ,evaluateBoolean: function (options) {
- return this.evaluate(options).booleanValue();
+ function evaluate(parsedExpression, options) {
+ var context = makeContext(options);
+
+ return parsedExpression.evaluate(context);
}
- ,evaluateNodeSet: function (options) {
- return this.evaluate(options).nodeset();
+ var evaluatorPrototype = {
+ evaluate: function (options) {
+ return evaluate(this.expression, options);
+ }
+
+ , evaluateNumber: function (options) {
+ return this.evaluate(options).numberValue();
+ }
+
+ , evaluateString: function (options) {
+ return this.evaluate(options).stringValue();
+ }
+
+ , evaluateBoolean: function (options) {
+ return this.evaluate(options).booleanValue();
+ }
+
+ , evaluateNodeSet: function (options) {
+ return this.evaluate(options).nodeset();
+ }
+
+ , select: function (options) {
+ return this.evaluateNodeSet(options).toArray()
+ }
+
+ , select1: function (options) {
+ return this.select(options)[0];
+ }
+ };
+
+ function parse(xpath) {
+ var parsed = parser.parse(xpath);
+
+ return Object.create(evaluatorPrototype, {
+ expression: {
+ value: parsed
+ }
+ });
}
- ,select: function (options) {
- return this.evaluateNodeSet(options).toArray()
- }
+ exports.parse = parse;
+ })();
- ,select1: function (options) {
- return this.select(options)[0];
- }
+ exports.XPath = XPath;
+ exports.XPathParser = XPathParser;
+ exports.XPathResult = XPathResult;
+
+ exports.Step = Step;
+ exports.NodeTest = NodeTest;
+ exports.BarOperation = BarOperation;
+
+ exports.NamespaceResolver = NamespaceResolver;
+ exports.FunctionResolver = FunctionResolver;
+ exports.VariableResolver = VariableResolver;
+
+ exports.Utilities = Utilities;
+
+ exports.XPathContext = XPathContext;
+ exports.XNodeSet = XNodeSet;
+ exports.XBoolean = XBoolean;
+ exports.XString = XString;
+ exports.XNumber = XNumber;
+
+ // helper
+ exports.select = function (e, doc, single) {
+ return exports.selectWithResolver(e, doc, null, single);
};
- function parse(xpath) {
- var parsed = parser.parse(xpath);
-
- return Object.create(evaluatorPrototype, {
- expression: {
- value: parsed
+ exports.useNamespaces = function (mappings) {
+ var resolver = {
+ mappings: mappings || {},
+ lookupNamespaceURI: function (prefix) {
+ return this.mappings[prefix];
}
- });
- }
+ };
- exports.parse = parse;
-})();
+ return function (e, doc, single) {
+ return exports.selectWithResolver(e, doc, resolver, single);
+ };
+ };
-exports.XPath = XPath;
-exports.XPathParser = XPathParser;
-exports.XPathResult = XPathResult;
+ exports.selectWithResolver = function (e, doc, resolver, single) {
+ var expression = new XPathExpression(e, resolver, new XPathParser());
+ var type = XPathResult.ANY_TYPE;
-exports.Step = Step;
-exports.NodeTest = NodeTest;
-exports.BarOperation = BarOperation;
+ var result = expression.evaluate(doc, type, null);
-exports.NamespaceResolver = NamespaceResolver;
-exports.FunctionResolver = FunctionResolver;
-exports.VariableResolver = VariableResolver;
+ if (result.resultType == XPathResult.STRING_TYPE) {
+ result = result.stringValue;
+ }
+ else if (result.resultType == XPathResult.NUMBER_TYPE) {
+ result = result.numberValue;
+ }
+ else if (result.resultType == XPathResult.BOOLEAN_TYPE) {
+ result = result.booleanValue;
+ }
+ else {
+ result = result.nodes;
+ if (single) {
+ result = result[0];
+ }
+ }
-exports.Utilities = Utilities;
+ return result;
+ };
-exports.XPathContext = XPathContext;
-exports.XNodeSet = XNodeSet;
-exports.XBoolean = XBoolean;
-exports.XString = XString;
-exports.XNumber = XNumber;
+ exports.select1 = function (e, doc) {
+ return exports.select(e, doc, true);
+ };
-// helper
-exports.select = function(e, doc, single) {
- return exports.selectWithResolver(e, doc, null, single);
-};
-
-exports.useNamespaces = function(mappings) {
- var resolver = {
- mappings: mappings || {},
- lookupNamespaceURI: function(prefix) {
- return this.mappings[prefix];
- }
- };
-
- return function(e, doc, single) {
- return exports.selectWithResolver(e, doc, resolver, single);
- };
-};
-
-exports.selectWithResolver = function(e, doc, resolver, single) {
- var expression = new XPathExpression(e, resolver, new XPathParser());
- var type = XPathResult.ANY_TYPE;
-
- var result = expression.evaluate(doc, type, null);
-
- if (result.resultType == XPathResult.STRING_TYPE) {
- result = result.stringValue;
- }
- else if (result.resultType == XPathResult.NUMBER_TYPE) {
- result = result.numberValue;
- }
- else if (result.resultType == XPathResult.BOOLEAN_TYPE) {
- result = result.booleanValue;
- }
- else {
- result = result.nodes;
- if (single) {
- result = result[0];
- }
- }
-
- return result;
-};
-
-exports.select1 = function(e, doc) {
- return exports.select(e, doc, true);
-};
-
-// end non-node wrapper
+ // end non-node wrapper
})(xpath);