xmlapi
Version:
a common interface for Node and browser native XML APIs
114 lines (113 loc) • 3.34 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
const wu = require('wu');
class AbstractNode {
isElement() {
return this.type() === 'element';
}
isText() {
return this.type() === 'text';
}
isCdata() {
return this.type() === 'cdata';
}
isComment() {
return this.type() === 'comment';
}
isRoot() {
return this.document().root().isSame(this); // todo: fragments?
}
lang() {
if (this.isElement()) {
throw new Error('lang() must be overriden in Element');
}
return this.parent().lang();
}
ancestors() {
return wu(this._ancestors());
}
previousSiblings() {
return wu(this._previousSiblings());
}
previousElementSiblings() {
return this.previousSiblings().filter(x => x.isElement());
}
previousElementSibling() {
return this.previousElementSiblings().next().value || null;
}
nextSiblings() {
return wu(this._nextSiblings());
}
nextElementSiblings() {
return this.nextSiblings().filter(x => x.isElement());
}
nextElementSibling() {
return this.nextElementSiblings().next().value || null;
}
/** Document order */
next() {
if (this.isElement()) {
let firstChild = this.asElement().firstChild();
if (firstChild) {
return firstChild;
}
}
// todo: wait for tail call optimization, check it jumps
return this.nextSibling() || this.ancestors().map(x => x.nextSibling()).find(x => !!x) || null;
}
evaluateBoolean(xpath, nsMap) {
let ret = this.evaluate(xpath, nsMap);
if (typeof ret !== 'boolean') {
throw new Error('XPath result is not a boolean');
}
return ret;
}
evaluateNumber(xpath, nsMap) {
let ret = this.evaluate(xpath, nsMap);
if (typeof ret !== 'number') {
throw new Error('XPath result is not a number');
}
return ret;
}
evaluateString(xpath, nsMap) {
let ret = this.evaluate(xpath, nsMap);
if (typeof ret !== 'string') {
throw new Error('XPath result is not a string');
}
return ret;
}
asElement() {
if (!this.isElement()) {
throw new Error('asElement() called on non-element');
}
return this; // todo: wait for ts 2.0
}
// isAttached() {
// return this.r
// }
// lookupPrefix(nsUri: string) {
// // todo: ts 2.0
// let chain = wu.chain(this.isElement() ? [(this as any) as AbstractElement] : [], this.ancestors());
// for (let el of chain) {
// }
// }
/*
* private
*/
/*protected*/ *_ancestors() {
for (let pointer = this.parent(); pointer; pointer = pointer.parent()) {
yield pointer;
}
}
/*protected*/ *_previousSiblings() {
for (let pointer = this.previousSibling(); pointer; pointer = pointer.previousSibling()) {
yield pointer;
}
}
/*protected*/ *_nextSiblings() {
for (let pointer = this.nextSibling(); pointer; pointer = pointer.nextSibling()) {
yield pointer;
}
}
}
exports.AbstractNode = AbstractNode;