diff --git a/package-lock.json b/package-lock.json
index 68d2518..947006e 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,7 +9,7 @@
"version": "0.0.32",
"license": "MIT",
"devDependencies": {
- "@xmldom/xmldom": "^0.8.8",
+ "@xmldom/xmldom": "^0.8.9",
"es-check": "^7.1.1",
"mocha": "^9.0.2"
},
@@ -85,9 +85,9 @@
"dev": true
},
"node_modules/@xmldom/xmldom": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.8.tgz",
- "integrity": "sha512-0LNz4EY8B/8xXY86wMrQ4tz6zEHZv9ehFMJPm8u2gq5lQ71cfRKdaKyxfJAx5aUoyzx0qzgURblTisPGgz3d+Q==",
+ "version": "0.8.9",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.9.tgz",
+ "integrity": "sha512-4VSbbcMoxc4KLjb1gs96SRmi7w4h1SF+fCoiK0XaQX62buCc1G5d0DC5bJ9xJBNPDSVCmIrcl8BiYxzjrqaaJA==",
"dev": true,
"engines": {
"node": ">=10.0.0"
@@ -1561,9 +1561,9 @@
"dev": true
},
"@xmldom/xmldom": {
- "version": "0.8.8",
- "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.8.tgz",
- "integrity": "sha512-0LNz4EY8B/8xXY86wMrQ4tz6zEHZv9ehFMJPm8u2gq5lQ71cfRKdaKyxfJAx5aUoyzx0qzgURblTisPGgz3d+Q==",
+ "version": "0.8.9",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.8.9.tgz",
+ "integrity": "sha512-4VSbbcMoxc4KLjb1gs96SRmi7w4h1SF+fCoiK0XaQX62buCc1G5d0DC5bJ9xJBNPDSVCmIrcl8BiYxzjrqaaJA==",
"dev": true
},
"acorn": {
diff --git a/package.json b/package.json
index 3380f89..ac67ccf 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
}
],
"devDependencies": {
- "@xmldom/xmldom": "^0.8.8",
+ "@xmldom/xmldom": "^0.8.9",
"es-check": "^7.1.1",
"mocha": "^9.0.2"
},
diff --git a/test.js b/test.js
index 42f2453..962586d 100644
--- a/test.js
+++ b/test.js
@@ -1051,4 +1051,136 @@ describe('xpath', () => {
assert.strictEqual(xpath.select1('local-name(/book/characters)', doc), 'characters');
});
});
+
+ describe('Node type tests', () => {
+ it('should correctly identify a Node of type Element', () => {
+ var doc = parseXml('');
+ var element = doc.createElement('characters');
+
+ assert.ok(xpath.isNodeLike(element));
+ assert.ok(xpath.isElement(element));
+ assert.ok(!xpath.isAttribute(doc));
+ });
+
+ it('should correctly identify a Node of type Attribute', () => {
+ var doc = parseXml('');
+ var attribute = doc.createAttribute('name');
+
+ assert.ok(xpath.isNodeLike(attribute));
+ assert.ok(xpath.isAttribute(attribute));
+ assert.ok(!xpath.isTextNode(attribute));
+ });
+
+ it('should correctly identify a Node of type Text', () => {
+ var doc = parseXml('');
+ var text = doc.createTextNode('Harry Potter');
+
+ assert.ok(xpath.isNodeLike(text));
+ assert.ok(xpath.isTextNode(text));
+ assert.ok(!xpath.isCDATASection(text));
+ });
+
+ it('should correctly identify a Node of type CDATASection', () => {
+ var doc = parseXml('');
+ var cdata = doc.createCDATASection('Harry Potter');
+
+ assert.ok(xpath.isNodeLike(cdata));
+ assert.ok(xpath.isCDATASection(cdata));
+ assert.ok(!xpath.isProcessingInstruction(cdata));
+ });
+
+ it('should correctly identify a Node of type ProcessingInstruction', () => {
+ var doc = parseXml('');
+ var pi = doc.createProcessingInstruction('xml-stylesheet', 'href="mycss.css" type="text/css"');
+
+ // This test fails due to a bug in @xmldom/xmldom@0.8.8
+ // assert.ok(xpath.isNodeLike(pi));
+ assert.ok(xpath.isProcessingInstruction(pi));
+ assert.ok(!xpath.isComment(pi));
+ });
+
+ it('should correctly identify a Node of type Comment', () => {
+ var doc = parseXml('');
+ var comment = doc.createComment('Harry Potter');
+
+ assert.ok(xpath.isNodeLike(comment));
+ assert.ok(xpath.isComment(comment));
+ assert.ok(!xpath.isDocumentNode(comment));
+ });
+
+ it('should correctly identify a Node of type Document', () => {
+ var doc = parseXml('');
+
+ assert.ok(xpath.isNodeLike(doc));
+ assert.ok(xpath.isDocumentNode(doc));
+ assert.ok(!xpath.isDocumentTypeNode(doc));
+ });
+
+ it('should correctly identify a Node of type DocumentType', () => {
+ var doc = parseXml('');
+ var doctype = doc.implementation.createDocumentType('book', null, null);
+
+ assert.ok(xpath.isNodeLike(doctype));
+ assert.ok(xpath.isDocumentTypeNode(doctype));
+ assert.ok(!xpath.isDocumentFragment(doctype));
+ });
+
+ it('should correctly identify a Node of type DocumentFragment', () => {
+ var doc = parseXml('');
+ var fragment = doc.createDocumentFragment();
+
+ assert.ok(xpath.isNodeLike(fragment));
+ assert.ok(xpath.isDocumentFragment(fragment));
+ assert.ok(!xpath.isElement(fragment));
+ });
+
+ it('should not identify a string as a Node', () => {
+ assert.ok(!xpath.isNodeLike('Harry Potter'));
+ });
+
+ it('should not identify a number as a Node', () => {
+ assert.ok(!xpath.isNodeLike(45));
+ });
+
+ it('should not identify a boolean as a Node', () => {
+ assert.ok(!xpath.isNodeLike(true));
+ });
+
+ it('should not identify null as a Node', () => {
+ assert.ok(!xpath.isNodeLike(null));
+ });
+
+ it('should not identify undefined as a Node', () => {
+ assert.ok(!xpath.isNodeLike(undefined));
+ });
+
+ it('should not identify an array as a Node', () => {
+ assert.ok(!xpath.isNodeLike([]));
+ });
+
+ it('should identify an array of Nodes as such', () => {
+ var doc = parseXml('');
+ var fragment = doc.createDocumentFragment();
+ var nodes = [doc, fragment];
+
+ assert.ok(xpath.isArrayOfNodes(nodes));
+ assert.ok(!xpath.isNodeLike(nodes));
+ });
+
+ it('should not identify an array of non-Nodes as an array of Nodes', () => {
+ var nodes = ['Harry Potter', 45];
+
+ assert.ok(!xpath.isArrayOfNodes(nodes));
+ assert.ok(!xpath.isNodeLike(nodes));
+ });
+
+ it('should not identify an array of mixed Nodes and non-Nodes as an array of Nodes', () => {
+ var doc = parseXml('');
+ var fragment = doc.createDocumentFragment();
+ var nodes = [doc, fragment, 'Harry Potter'];
+
+ assert.ok(!xpath.isArrayOfNodes(nodes));
+ assert.ok(!xpath.isNodeLike(nodes));
+ });
+ });
});
\ No newline at end of file
diff --git a/xpath.d.ts b/xpath.d.ts
index d774463..9d1a734 100644
--- a/xpath.d.ts
+++ b/xpath.d.ts
@@ -1,11 +1,51 @@
///
-type SelectedValue = Node | Attr | string | number | boolean;
-interface XPathSelect {
- (expression: string, node?: Node): Array;
- (expression: string, node: Node, single: true): SelectedValue | undefined;
+export type SelectedValue = Node | string | number | boolean | null;
+
+export type SelectReturnType = Array | SelectedValue;
+export type SelectSingleReturnType = SelectedValue;
+
+export interface XPathSelect {
+ (expression: string, node: Node): SelectReturnType;
+ (expression: string, node: Node, single: false): SelectReturnType;
+ (expression: string, node: Node, single: true): SelectSingleReturnType;
}
-export var select: XPathSelect;
-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;
+
+/**
+ * Evaluate an XPath expression against a DOM node.
+ */
+export function select(expression: string, node: Node): SelectReturnType;
+export function select(expression: string, node: Node, single: false): SelectReturnType;
+export function select(expression: string, node: Node, single: true): SelectSingleReturnType;
+
+/**
+ * Evaluate an xpath expression against a DOM node, returning the first result only.
+ */
+export function select1(expression: string, node: Node): SelectSingleReturnType;
+
+/**
+ * Evaluate an XPath expression against a DOM node using a given namespace resolver.
+ */
+export function selectWithResolver(expression: string, node: Node, resolver?: XPathNSResolver | null): SelectReturnType;
+export function selectWithResolver(expression: string, node: Node, resolver: XPathNSResolver | null, single: false): SelectReturnType;
+export function selectWithResolver(expression: string, node: Node, resolver: XPathNSResolver | null, single: true): SelectSingleReturnType;
+
+/**
+ * Creates a `select` function that uses the given namespace prefix to URI mappings when evaluating queries.
+ * @param namespaceMap an object mapping namespace prefixes to namespace URIs. Each key is a prefix; each value is a URI.
+ * @return a function with the same signature as `xpath.select`
+ */
+export function useNamespaces(namespaceMap: Record): XPathSelect;
+
+// Type guards to narrow down the type of the selected type of a returned Node object
+export function isNodeLike(value: SelectedValue): value is Node;
+export function isArrayOfNodes(value: SelectedValue): value is Node[];
+export function isElement(value: SelectedValue): value is Element;
+export function isAttribute(value: SelectedValue): value is Attr;
+export function isTextNode(value: SelectedValue): value is Text;
+export function isCDATASection(value: SelectedValue): value is CDATASection;
+export function isProcessingInstruction(value: SelectedValue): value is ProcessingInstruction;
+export function isComment(value: SelectedValue): value is Comment;
+export function isDocumentNode(value: SelectedValue): value is Document;
+export function isDocumentTypeNode(value: SelectedValue): value is DocumentType;
+export function isDocumentFragment(value: SelectedValue): value is DocumentFragment;
diff --git a/xpath.js b/xpath.js
index 5a0af41..1189c1a 100644
--- a/xpath.js
+++ b/xpath.js
@@ -201,6 +201,18 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
return to;
}
+ var NodeTypes = {
+ ELEMENT_NODE: 1,
+ ATTRIBUTE_NODE: 2,
+ TEXT_NODE: 3,
+ CDATA_SECTION_NODE: 4,
+ PROCESSING_INSTRUCTION_NODE: 7,
+ COMMENT_NODE: 8,
+ DOCUMENT_NODE: 9,
+ DOCUMENT_TYPE_NODE: 10,
+ DOCUMENT_FRAGMENT_NODE: 11,
+ };
+
// XPathParser ///////////////////////////////////////////////////////////////
XPathParser.prototype = new Object();
@@ -1800,7 +1812,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
PathExpr.getRoot = function (xpc, nodes) {
var firstNode = nodes[0];
- if (firstNode.nodeType === 9 /*Node.DOCUMENT_NODE*/) {
+ if (firstNode.nodeType === NodeTypes.DOCUMENT_NODE) {
return firstNode;
}
@@ -1834,7 +1846,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
break;
}
var m;
- if (xpc.contextNode.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
+ if (xpc.contextNode.nodeType == NodeTypes.ATTRIBUTE_NODE) {
m = PathExpr.getOwnerElement(xpc.contextNode);
} else {
m = xpc.contextNode.parentNode;
@@ -1852,7 +1864,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
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) {
+ for (var m = xpc.contextNode; m != null; m = m.nodeType == NodeTypes.ATTRIBUTE_NODE ? PathExpr.getOwnerElement(m) : m.parentNode) {
if (step.nodeTest.matches(m, xpc)) {
newNodes.push(m);
}
@@ -1934,7 +1946,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
} 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) {
+ for (var m = xpc.contextNode.parentNode; m != null && m.nodeType != NodeTypes.DOCUMENT_NODE && m !== xpc.virtualRoot; m = m.parentNode) {
st.unshift(m.nextSibling);
}
do {
@@ -1965,10 +1977,10 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
case Step.NAMESPACE:
var n = {};
- if (xpc.contextNode.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ if (xpc.contextNode.nodeType == NodeTypes.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 m = xpc.contextNode; m != null && m.nodeType == NodeTypes.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);
@@ -1996,7 +2008,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
case Step.PARENT:
m = null;
if (xpc.contextNode !== xpc.virtualRoot) {
- if (xpc.contextNode.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
+ if (xpc.contextNode.nodeType == NodeTypes.ATTRIBUTE_NODE) {
m = PathExpr.getOwnerElement(xpc.contextNode);
} else {
m = xpc.contextNode.parentNode;
@@ -2180,7 +2192,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
} catch (e) {
}
// Other DOM 1 implementations must use this egregious search
- var doc = n.nodeType == 9 /*Node.DOCUMENT_NODE*/
+ var doc = n.nodeType == NodeTypes.DOCUMENT_NODE
? n
: n.ownerDocument;
var elts = doc.getElementsByTagName("*");
@@ -2380,7 +2392,13 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
NodeTest.NAMETESTQNAME,
{
matches: function (n, xpc) {
- return NodeTest.isNodeType([1, 2, XPathNamespace.XPATH_NAMESPACE_NODE])(n) &&
+ return NodeTest.isNodeType(
+ [
+ NodeTypes.ELEMENT_NODE,
+ NodeTypes.ATTRIBUTE_NODE,
+ XPathNamespace.XPATH_NAMESPACE_NODE,
+ ]
+ )(n) &&
NodeTest.nameSpaceMatches(this.prefix, xpc, n) &&
NodeTest.localNameMatches(this.localName, xpc, n);
},
@@ -2399,7 +2417,10 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
NodeTest.PITest = NodeTest.makeNodeTestType(NodeTest.PI, {
matches: function (n, xpc) {
- return NodeTest.isNodeType([7])(n) && (n.target || n.nodeName) === this.name;
+ return NodeTest.isNodeType(
+ [NodeTypes.PROCESSING_INSTRUCTION_NODE]
+ )(n) &&
+ (n.target || n.nodeName) === this.name;
},
toString: function () {
return wrap('processing-instruction("', '")', this.name);
@@ -2409,13 +2430,48 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
// singletons
// elements, attributes, namespaces
- NodeTest.nameTestAny = NodeTest.makeNodeTypeTest(NodeTest.NAMETESTANY, [1, 2, XPathNamespace.XPATH_NAMESPACE_NODE], '*');
+ NodeTest.nameTestAny = NodeTest.makeNodeTypeTest(
+ NodeTest.NAMETESTANY,
+ [
+ NodeTypes.ELEMENT_NODE,
+ NodeTypes.ATTRIBUTE_NODE,
+ XPathNamespace.XPATH_NAMESPACE_NODE,
+ ],
+ '*'
+ );
// text, cdata
- NodeTest.textTest = NodeTest.makeNodeTypeTest(NodeTest.TEXT, [3, 4], 'text()');
- NodeTest.commentTest = NodeTest.makeNodeTypeTest(NodeTest.COMMENT, [8], 'comment()');
+ NodeTest.textTest = NodeTest.makeNodeTypeTest(
+ NodeTest.TEXT,
+ [
+ NodeTypes.TEXT_NODE,
+ NodeTypes.CDATA_SECTION_NODE,
+ ],
+ 'text()'
+ );
+ NodeTest.commentTest = NodeTest.makeNodeTypeTest(
+ NodeTest.COMMENT,
+ [NodeTypes.COMMENT_NODE],
+ '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()');
+ NodeTest.nodeTest = NodeTest.makeNodeTypeTest(
+ NodeTest.NODE,
+ [
+ NodeTypes.ELEMENT_NODE,
+ NodeTypes.ATTRIBUTE_NODE,
+ NodeTypes.TEXT_NODE,
+ NodeTypes.CDATA_SECTION_NODE,
+ NodeTypes.PROCESSING_INSTRUCTION_NODE,
+ NodeTypes.COMMENT_NODE,
+ NodeTypes.DOCUMENT_NODE,
+ ],
+ 'node()'
+ );
+ NodeTest.anyPiTest = NodeTest.makeNodeTypeTest(
+ NodeTest.PI,
+ [NodeTypes.PROCESSING_INSTRUCTION_NODE],
+ 'processing-instruction()'
+ );
// VariableReference /////////////////////////////////////////////////////////
@@ -3163,12 +3219,12 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
};
XNodeSet.prototype.stringForNode = function (n) {
- if (n.nodeType == 9 /*Node.DOCUMENT_NODE*/ ||
- n.nodeType == 1 /*Node.ELEMENT_NODE */ ||
- n.nodeType === 11 /*Node.DOCUMENT_FRAGMENT*/) {
+ if (n.nodeType == NodeTypes.DOCUMENT_NODE ||
+ n.nodeType == NodeTypes.ELEMENT_NODE ||
+ n.nodeType === NodeTypes.DOCUMENT_FRAGMENT_NODE) {
return this.stringForContainerNode(n);
}
- if (n.nodeType === 2 /* Node.ATTRIBUTE_NODE */) {
+ if (n.nodeType === NodeTypes.ATTRIBUTE_NODE) {
return n.value || n.nodeValue;
}
if (n.isNamespaceNode) {
@@ -3452,14 +3508,14 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
} else if (prefix == "xmlns") {
return XPath.XMLNS_NAMESPACE_URI;
}
- if (n.nodeType == 9 /*Node.DOCUMENT_NODE*/) {
+ if (n.nodeType == NodeTypes.DOCUMENT_NODE) {
n = n.documentElement;
- } else if (n.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
+ } else if (n.nodeType == NodeTypes.ATTRIBUTE_NODE) {
n = PathExpr.getOwnerElement(n);
- } else if (n.nodeType != 1 /*Node.ELEMENT_NODE*/) {
+ } else if (n.nodeType != NodeTypes.ELEMENT_NODE) {
n = n.parentNode;
}
- while (n != null && n.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ while (n != null && n.nodeType == NodeTypes.ELEMENT_NODE) {
var nnm = n.attributes;
for (var i = 0; i < nnm.length; i++) {
var a = nnm.item(i);
@@ -3518,7 +3574,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
var ids = id.split(/[\x0d\x0a\x09\x20]+/);
var count = 0;
var ns = new XNodeSet();
- var doc = c.contextNode.nodeType == 9 /*Node.DOCUMENT_NODE*/
+ var doc = c.contextNode.nodeType == NodeTypes.DOCUMENT_NODE
? c.contextNode
: c.contextNode.ownerDocument;
for (var i = 0; i < ids.length; i++) {
@@ -3589,11 +3645,11 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
if (n == null) {
return new XString("");
}
- if (n.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ if (n.nodeType == NodeTypes.ELEMENT_NODE) {
return new XString(n.nodeName);
- } else if (n.nodeType == 2 /*Node.ATTRIBUTE_NODE*/) {
+ } else if (n.nodeType == NodeTypes.ATTRIBUTE_NODE) {
return new XString(n.name || n.nodeName);
- } else if (n.nodeType === 7 /*Node.PROCESSING_INSTRUCTION_NODE*/) {
+ } else if (n.nodeType === NodeTypes.PROCESSING_INSTRUCTION_NODE) {
return new XString(n.target || n.nodeName);
} else if (n.localName == null) {
return new XString("");
@@ -3788,7 +3844,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
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) {
+ for (var n = c.contextNode; n != null && n.nodeType != NodeTypes.DOCUMENT_NODE; n = n.parentNode) {
var a = n.getAttributeNS(XPath.XML_NAMESPACE_URI, "lang");
if (a != null) {
lang = String(a);
@@ -3857,7 +3913,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
var Utilities = new Object();
Utilities.isAttribute = function (val) {
- return val && (val.nodeType === 2 || val.ownerElement);
+ return val && (val.nodeType === NodeTypes.ATTRIBUTE_NODE || val.ownerElement);
}
Utilities.splitQName = function (qn) {
@@ -4227,17 +4283,17 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
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*/) {
+ if (m.nodeType == NodeTypes.TEXT_NODE || m.nodeType == NodeTypes.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*/)) {
+ while (m != null && (m.nodeType == NodeTypes.TEXT_NODE || m.nodeType == NodeTypes.CDATA_SECTION_NODE)) {
s += m.nodeValue;
var del = m;
m = m.nextSibling;
del.parentNode.removeChild(del);
}
- if (first.nodeType == 4 /*Node.CDATA_SECTION_NODE*/) {
+ if (first.nodeType == NodeTypes.CDATA_SECTION_NODE) {
var p = first.parentNode;
if (first.nextSibling == null) {
p.removeChild(first);
@@ -4253,7 +4309,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
if (m == null) {
break;
}
- } else if (m.nodeType == 1 /*Node.ELEMENT_NODE*/) {
+ } else if (m.nodeType == NodeTypes.ELEMENT_NODE) {
Utilities.coalesceText(m);
}
}
@@ -4275,7 +4331,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
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.nodeType == NodeTypes.ELEMENT_NODE) {
if (n.getAttribute("id") == id
|| n.getAttributeNS(null, "id") == id) {
return n;
@@ -4344,7 +4400,7 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
}
XPathExpression.getOwnerDocument = function (n) {
- return n.nodeType === 9 /*Node.DOCUMENT_NODE*/ ? n : n.ownerDocument;
+ return n.nodeType === NodeTypes.DOCUMENT_NODE ? n : n.ownerDocument;
}
XPathExpression.detectHtmlDom = function (n) {
@@ -4843,5 +4899,40 @@ var xpath = (typeof exports === 'undefined') ? {} : exports;
return exports.select(e, doc, true);
};
+ var isNodeLike = function (value) {
+ return value
+ && typeof value.nodeType === "number"
+ && Number.isInteger(value.nodeType)
+ && value.nodeType >= 1
+ && value.nodeType <= 11
+ && typeof value.nodeName === "string";
+ };
+
+ var isArrayOfNodes = function (value) {
+ return Array.isArray(value) && value.every(isNodeLike);
+ };
+
+ var isNodeOfType = function (type) {
+ return function (value) {
+ return isNodeLike(value) && value.nodeType === type;
+ };
+ };
+
+ assign(
+ exports,
+ {
+ isNodeLike: isNodeLike,
+ isArrayOfNodes: isArrayOfNodes,
+ isElement: isNodeOfType(NodeTypes.ELEMENT_NODE),
+ isAttribute: isNodeOfType(NodeTypes.ATTRIBUTE_NODE),
+ isTextNode: isNodeOfType(NodeTypes.TEXT_NODE),
+ isCDATASection: isNodeOfType(NodeTypes.CDATA_SECTION_NODE),
+ isProcessingInstruction: isNodeOfType(NodeTypes.PROCESSING_INSTRUCTION_NODE),
+ isComment: isNodeOfType(NodeTypes.COMMENT_NODE),
+ isDocumentNode: isNodeOfType(NodeTypes.DOCUMENT_NODE),
+ isDocumentTypeNode: isNodeOfType(NodeTypes.DOCUMENT_TYPE_NODE),
+ isDocumentFragment: isNodeOfType(NodeTypes.DOCUMENT_FRAGMENT_NODE),
+ }
+ );
// end non-node wrapper
})(xpath);