epubavocado
Version:
I am an EPUB object model aspiring to be standards compliant.
65 lines (56 loc) • 1.66 kB
text/typescript
import type { SelectedValue } from 'xpath'
import { Maybe } from '../../util.js'
import { select, selectAll } from '../../xpath.js'
import { Constructor } from './constructor.js'
export type EntityConstructor = Constructor<Entity>
export class Entity {
_node: Node
_context: Entity
constructor(node: Node, context?: Entity) {
this._node = node
this._context = context || this
}
_select(expression: string): Maybe<SelectedValue> {
return select(expression, this._node)
}
_selectAll(expression: string): SelectedValue[] {
return selectAll(expression, this._node)
}
_resolve(expression: string): Maybe<string>
_resolve<T>(expression: string, constructor: Constructor<T>): Maybe<T>
_resolve<T>(
expression: string,
constructor?: Constructor<T>,
): Maybe<T | string> {
const node = this._select(expression)
if (!node) {
return null
}
if (constructor) {
return new constructor(node, this._context)
}
const attrType = node as Attr
const nodeType = node as Node
if (attrType.value) {
return attrType.value
}
if (nodeType.nodeValue) {
return nodeType.nodeValue
}
}
_resolveAll(expression: string): string[]
_resolveAll<T>(expression: string, constructor: Constructor<T>): T[]
_resolveAll<T>(
expression: string,
constructor?: Constructor<T>,
): T[] | string[] {
const nodes = this._selectAll(expression)
if (!nodes) {
return []
}
if (constructor) {
return nodes.map((node) => new constructor(node, this._context))
}
return nodes.map((node) => (node as Node).nodeValue) as string[]
}
}