UNPKG

@ara-web/sds

Version:

Write code faster without worry about future debts or scalability in the future

135 lines (112 loc) 3.94 kB
import { Debug } from "@ara-web/p-hintjens"; import { Adapter } from "../src/tree"; export class NodeAdapter<BranchedModuleObject extends Node> implements Adapter<Node, BranchedModuleObject>{ private EMPTY_OBJECT = {}; public isTag(elem: Node): elem is BranchedModuleObject { return elem.nodeType === 1; } public getChildren(elem: Node): Node[] { return elem.childNodes ? Array.prototype.slice.call(elem.childNodes, 0) : []; } public getParent(elem: BranchedModuleObject): BranchedModuleObject|null { return elem.parentNode as unknown as BranchedModuleObject; } public removeSubsets(nodes: Node[]): Node[] { let idx = nodes.length; let node: Node; let ancestor: Node | null; let replace: boolean; // Check if each node (or one of its ancestors) is already contained in the // array. while(--idx > -1) { node = ancestor = nodes[idx]; // Temporarily remove the node under consideration delete nodes[idx]; replace = true; while(ancestor) { if(nodes.indexOf(ancestor) > -1) { replace = false; nodes.splice(idx, 1); break; } ancestor = this.getParent(ancestor as unknown as BranchedModuleObject) } // If the node has been found to be unique, re-insert it. if(replace) { nodes[idx] = node; } } return nodes; } public existsOne(test, elems){ return elems.some((elem) => { return this.isTag(elem) ? test(elem) || this.existsOne(test, this.getChildren(elem)) : false; }); } public getSiblings (elem){ var parent = this.getParent(elem); return parent ? this.getChildren(parent) : [elem]; } public getAttributeValue(elem, name){ if(elem.attributes && name in elem.attributes){ var attr = elem.attributes[name]; return typeof attr === "string" ? attr : attr.value; } else if (name === "class" && elem.classList) { return Array.from(elem.classList).join(" "); } } public hasAttrib(elem, name){ return name in (elem.attributes || this.EMPTY_OBJECT); } public getName(elem){ return (elem.tagName || "").toLowerCase(); } public findOne(test, arr){ var elem = null; for(var i = 0, l = arr.length; i < l && !elem; i++){ if(test(arr[i])){ elem = arr[i]; } else { var childs = this.getChildren(arr[i]); if(childs && childs.length > 0){ elem = this.findOne(test, childs); } } } return elem; } public findAll(test, elems: Node[]): BranchedModuleObject[] { Debug.push(`findAll`) Debug.log(`Find all predicate: ${test.toString()}`) var result: BranchedModuleObject[] = []; for(var i = 0, j = elems.length; i < j; i++){ Debug.log(`\n\n\n`) Debug.log(`${i}/${elems.length-1}) name '${test.name}' against elem name '${this.getName(elems[i] as unknown as BranchedModuleObject)}'`) Debug.log(`${i}/${elems.length-1}) ${JSON.stringify(test.next, null, 4)}`) Debug.log(`${i}/${elems.length-1}) ${JSON.stringify(elems[i].nodeName, null, 4)}`) if(!this.isTag(elems[i])) continue; if(test(elems[i])) { Debug.log(`${i}/${elems.length-1}) passed`) result.push(elems[i] as unknown as BranchedModuleObject); } else { Debug.log(`${i}/${elems.length-1}) not passed`) } var childs = this.getChildren(elems[i]); if(childs) { const foundChildren = this.findAll(test, childs); Debug.log(`${i}/${elems.length-1}) found children: ${foundChildren.length}`) result = result.concat(foundChildren); } } Debug.pop(); return result; } public getText(elem) { if(Array.isArray(elem)) return elem.map(this.getText).join(""); if(this.isTag(elem)) return this.getText(this.getChildren(elem)); if(elem.nodeType === 3) return elem.nodeValue; return ""; } }