UNPKG

xpath-ts2

Version:

DOM 3 and 4 XPath 1.0 implementation for browser and Node.js environment with support for typescript 5.

325 lines 11.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Functions = void 0; const consts_1 = require("./consts"); const character_1 = require("./utils/character"); const types_1 = require("./utils/types"); const xml_1 = require("./utils/xml"); const xpath_types_1 = require("./xpath-types"); // tslint:disable:prefer-for-of class Functions { static last(c, ...args) { checkArguments(0, args, 'last'); return new xpath_types_1.XNumber(c.contextSize); } static position(c, ...args) { checkArguments(0, args, 'position'); return new xpath_types_1.XNumber(c.contextPosition); } static count(c, ...args) { checkArguments(1, args, 'count'); const ns = args[0].evaluate(c); if (!(ns instanceof xpath_types_1.XNodeSet)) { throw new Error('Function count expects (node-set)'); } return new xpath_types_1.XNumber(ns.size); } static id(c, ...args) { checkArguments(1, args, 'id'); const eRes = args[0].evaluate(c); let ids; if (eRes instanceof xpath_types_1.XNodeSet) { ids = eRes.toArray().map((node) => xpath_types_1.XNodeSet.prototype.stringForNode(node)); } else { const id = eRes.stringValue; ids = id.split(/[\x0d\x0a\x09\x20]+/); } const ns = new xpath_types_1.XNodeSet(); const doc = (0, types_1.isDocument)(c.contextNode) ? c.contextNode : c.contextNode.ownerDocument; for (let i = 0; i < ids.length; i++) { let n; if (doc.getElementById) { n = doc.getElementById(ids[i]); } else { n = (0, xml_1.getElementById)(doc, ids[i]); } if (n != null) { ns.add(n); } } return ns; } static localName(c, ...args) { checkArguments([0, 1], args, 'local-name'); let n; if (args.length === 0) { n = c.contextNode; } else { const eRes = args[0].evaluate(c); if (!(eRes instanceof xpath_types_1.XNodeSet)) { throw new Error('Function local-name expects (node-set?)'); } n = eRes.first(); } if (n == null) { return new xpath_types_1.XString(''); } if (((0, types_1.isElement)(n) || (0, types_1.isAttribute)(n)) && n.localName != null) { return new xpath_types_1.XString(n.localName); } else if ((0, types_1.isProcessingInstruction)(n)) { return new xpath_types_1.XString(n.target); } else { return new xpath_types_1.XString(n.nodeName != null ? n.nodeName : ''); } } static namespaceURI(c, ...args) { checkArguments([0, 1], args, 'namespace-uri'); let n; if (args.length === 0) { n = c.contextNode; } else { const eRes = args[0].evaluate(c); if (!(eRes instanceof xpath_types_1.XNodeSet)) { throw new Error('Function namspace-uri expects (node-set?)'); } n = eRes.first(); } if (n == null) { return new xpath_types_1.XString(''); } if ((0, types_1.isElement)(n) || (0, types_1.isAttribute)(n)) { return new xpath_types_1.XString(n.namespaceURI); } else { return new xpath_types_1.XString(''); } } static name_(c, ...args) { checkArguments([0, 1], args, 'name'); let n; if (args.length === 0) { n = c.contextNode; } else { const eRes = args[0].evaluate(c); if (!(eRes instanceof xpath_types_1.XNodeSet)) { throw new Error('Function name expects (node-set?)'); } n = eRes.first(); } if (n == null) { return new xpath_types_1.XString(''); } if ((0, types_1.isElement)(n)) { return new xpath_types_1.XString(n.nodeName); } else if ((0, types_1.isAttribute)(n)) { return new xpath_types_1.XString(n.name || n.nodeName); } else if ((0, types_1.isProcessingInstruction)(n)) { return new xpath_types_1.XString(n.target || n.nodeName); } else if (n.localName == null) { return new xpath_types_1.XString(''); } else { return new xpath_types_1.XString(n.localName); } } static string(c, ...args) { checkArguments([0, 1], args, 'string'); if (args.length === 0) { return new xpath_types_1.XString(xpath_types_1.XNodeSet.prototype.stringForNode(c.contextNode)); } else { return args[0].evaluate(c).string; } } static concat(c, ...args) { if (args.length < 2) { throw new Error('Function concat expects (string, string[, string]*)'); } let s = ''; for (let i = 0; i < args.length; i++) { s += args[i].evaluate(c).stringValue; } return new xpath_types_1.XString(s); } static startsWith(c, ...args) { checkArguments(2, args, 'starts-with'); const s1 = args[0].evaluate(c).stringValue; const s2 = args[1].evaluate(c).stringValue; return new xpath_types_1.XBoolean(s1.substring(0, s2.length) === s2); } static contains(c, ...args) { checkArguments(2, args, 'contains'); const s1 = args[0].evaluate(c).stringValue; const s2 = args[1].evaluate(c).stringValue; return new xpath_types_1.XBoolean(s1.indexOf(s2) !== -1); } static substringBefore(c, ...args) { checkArguments(2, args, 'substring-before'); const s1 = args[0].evaluate(c).stringValue; const s2 = args[1].evaluate(c).stringValue; return new xpath_types_1.XString(s1.substring(0, s1.indexOf(s2))); } static substringAfter(c, ...args) { checkArguments(2, args, 'substring-after'); const s1 = args[0].evaluate(c).stringValue; const s2 = args[1].evaluate(c).stringValue; if (s2.length === 0) { return new xpath_types_1.XString(s1); } const i = s1.indexOf(s2); if (i === -1) { return new xpath_types_1.XString(''); } return new xpath_types_1.XString(s1.substring(i + s2.length)); } static substring(c, ...args) { checkArguments([2, 3], args, 'substring'); const s = args[0].evaluate(c).stringValue; const n1 = Math.round(args[1].evaluate(c).numberValue) - 1; const n2 = args.length === 3 ? n1 + Math.round(args[2].evaluate(c).numberValue) : undefined; return new xpath_types_1.XString(s.substring(n1, n2)); } static stringLength(c, ...args) { checkArguments([0, 1], args, 'string-length'); let s; if (args.length === 0) { s = xpath_types_1.XNodeSet.prototype.stringForNode(c.contextNode) || ''; } else { s = args[0].evaluate(c).stringValue; } return new xpath_types_1.XNumber(s.length); } static normalizeSpace(c, ...args) { checkArguments([0, 1], args, 'normalize-space'); let s; if (args.length === 0) { s = xpath_types_1.XNodeSet.prototype.stringForNode(c.contextNode); } else { s = args[0].evaluate(c).stringValue; } let i = 0; let j = s.length - 1; while ((0, character_1.isSpace)(s.charCodeAt(j))) { j--; } let t = ''; while (i <= j && (0, character_1.isSpace)(s.charCodeAt(i))) { i++; } while (i <= j) { if ((0, character_1.isSpace)(s.charCodeAt(i))) { t += ' '; while (i <= j && (0, character_1.isSpace)(s.charCodeAt(i))) { i++; } } else { t += s.charAt(i); i++; } } return new xpath_types_1.XString(t); } static translate(c, ...args) { checkArguments(3, args, 'translate'); const value = args[0].evaluate(c).stringValue; const from = args[1].evaluate(c).stringValue; const to = args[2].evaluate(c).stringValue; const cMap = [...from].reduce((acc, ch, i) => { if (!(ch in acc)) { acc[ch] = i > to.length ? '' : to[i]; } return acc; }, {}); const t = [...value].map((ch) => (ch in cMap ? cMap[ch] : ch)).join(''); return new xpath_types_1.XString(t); } static boolean_(c, ...args) { checkArguments(1, args, 'boolean'); return args[0].evaluate(c).bool; } static not(c, ...args) { checkArguments(1, args, 'not'); return args[0].evaluate(c).bool.not(); } static true_(_c, ...args) { checkArguments(0, args, 'true'); return xpath_types_1.XBoolean.TRUE; } static false_(_c, ...args) { checkArguments(0, args, 'false'); return xpath_types_1.XBoolean.FALSE; } static lang(c, ...args) { checkArguments(1, args, 'lang'); let lang = null; for (let n = c.contextNode; n != null && !(0, types_1.isDocument)(n); n = n.parentNode) { if ((0, types_1.isElement)(n)) { const a = n.getAttributeNS(consts_1.XML_NAMESPACE_URI, 'lang'); if (a != null) { lang = String(a); break; } } } if (lang == null) { return xpath_types_1.XBoolean.FALSE; } const s = args[0].evaluate(c).stringValue; return new xpath_types_1.XBoolean(lang.substring(0, s.length) === s && (lang.length === s.length || lang.charAt(s.length) === '-')); } static number(c, ...args) { checkArguments([0, 1], args, 'number'); if (args.length === 0) { return new xpath_types_1.XNumber(xpath_types_1.XNodeSet.prototype.stringForNode(c.contextNode)); } return args[0].evaluate(c).number; } static sum(c, ...args) { checkArguments(1, args, 'sum'); const ns = args[0].evaluate(c); if (!(ns instanceof xpath_types_1.XNodeSet)) { throw new Error('Function sum expects (node-set)'); } const ua = ns.toUnsortedArray(); let n = 0; for (let i = 0; i < ua.length; i++) { n += new xpath_types_1.XNumber(xpath_types_1.XNodeSet.prototype.stringForNode(ua[i])).numberValue; } return new xpath_types_1.XNumber(n); } static floor(c, ...args) { checkArguments(1, args, 'floor'); return new xpath_types_1.XNumber(Math.floor(args[0].evaluate(c).numberValue)); } static ceiling(c, ...args) { checkArguments(1, args, 'ceiling'); return new xpath_types_1.XNumber(Math.ceil(args[0].evaluate(c).numberValue)); } static round(c, ...args) { checkArguments(1, args, 'round'); return new xpath_types_1.XNumber(Math.round(args[0].evaluate(c).numberValue)); } } exports.Functions = Functions; function checkArguments(expected, args, name) { if (typeof expected === 'number') { expected = [expected]; } if (!expected.includes(args.length)) { throw new Error(`Function ${name} expects ${expected.join(' or ')} arguments instead of ${args.length}`); } } //# sourceMappingURL=functions.js.map