UNPKG

@awesome-fe/translate

Version:
350 lines 10.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.defaultSelectors = exports.DomTableRowElement = exports.DomTableCellElement = exports.DomTableElement = exports.DomText = exports.DomElement = exports.DomDocumentType = exports.DomDocumentFragment = exports.DomDocument = exports.DomComment = exports.DomParentNode = exports.DomChildNode = exports.DomAttr = exports.DomNode = void 0; const parse5_1 = require("parse5"); const dom_tree_adapter_1 = require("./dom-tree-adapter"); class DomNode { static treeAdapter = dom_tree_adapter_1.DomTreeAdapter.create(); nodeName; parentNode; childNodes = []; get index() { if (!(this instanceof DomChildNode)) { return -1; } return this.parentNode?.childNodes.indexOf(this); } get indexOfElement() { if (!(this instanceof DomElement)) { return -1; } return this.parentNode?.children.indexOf(this); } get firstChild() { return this.childNodes?.[0]; } get lastChild() { return this.childNodes?.[this.childNodes.length - 1]; } get children() { return this.childNodes?.filter(child => child instanceof DomElement); } get firstElementChild() { return this.children?.[0]; } get lastElementChild() { return this.children?.[this.children.length - 1]; } get textContent() { let result = ''; if (this instanceof DomText) { result += this.value; } else if (this instanceof DomParentNode) { result += this.childNodes.map(it => it.textContent).join(''); } return result; } set textContent(value) { this.childNodes = [new DomText(value)]; } get parentElement() { let parent = this.parentNode; while (parent) { if (parent instanceof DomElement) { return parent; } parent = parent.parentNode; } } get previousElementSibling() { let node = this.previousSibling(); while (node) { if (node instanceof DomElement) { return node; } node = node.previousSibling(); } } get nextElementSibling() { let node = this.nextSibling(); while (node) { if (node instanceof DomElement) { return node; } node = node.nextSibling(); } } previousSibling() { if (this.index === -1) { return; } return this.parentNode?.childNodes[this.index - 1]; } nextSibling() { if (this.index === -1) { return; } return this.parentNode?.childNodes[this.index + 1]; } queryAncestor(selector) { return this.parentElement && (selector(this.parentElement) || this.parentElement.queryAncestor(selector)); } appendChild(child) { if (this instanceof DomParentNode) { child.parentNode = this; this.childNodes.push(child); } return child; } insertBefore(newNode, referenceNode) { newNode.remove(); this.childNodes.splice(referenceNode.index, 0, newNode); return newNode; } insertAfter(newNode, referenceNode) { newNode.remove(); this.childNodes.splice(referenceNode.index + 1, 0, newNode); return newNode; } } exports.DomNode = DomNode; class DomAttr { name; value; } exports.DomAttr = DomAttr; class DomChildNode extends DomNode { remove() { if (!this.parentNode) { return; } this.parentNode.childNodes.splice(this.index, 1); } } exports.DomChildNode = DomChildNode; class DomParentNode extends DomChildNode { get children() { return this.childNodes.filter(it => it instanceof DomElement); } prepend(node) { this.childNodes.unshift(node); } querySelectorAll(selector) { const result = []; for (const child of this.children) { if (selector(child)) { result.push(child); } result.push(...child.querySelectorAll(selector)); } return result; } querySelector(selector) { for (const child of this.children) { if (selector(child)) { return child; } const subNode = child.querySelector(selector); if (subNode) { return subNode; } } } mergeTextNodes() { let text = ''; for (let i = this.childNodes.length - 1; i >= 0; i--) { const node = this.childNodes[i]; if (node instanceof DomText) { text = node.value + text; if (!(node.previousSibling() instanceof DomText)) { node.value = text; text = ''; } else { node.remove(); } } if (node instanceof DomParentNode) { node.mergeTextNodes(); } } } } exports.DomParentNode = DomParentNode; class DomComment extends DomChildNode { data; nodeName = '#comment'; constructor(data) { super(); this.data = data; } } exports.DomComment = DomComment; class DomDocument extends DomParentNode { nodeName = '#document'; mode; get head() { return this.querySelector(it => it.isTagOf('head')); } get body() { return this.querySelector(it => it.isTagOf('body')); } get title() { return this.titleElement?.textContent; } set title(value) { const element = this.titleElement || this.head.appendChild(new DomElement('title')); element.textContent = value ?? ''; } get titleElement() { const element = this.querySelector(it => it.isTagOf('title')); if (element) { return element; } } toHtml() { return (0, parse5_1.serialize)(this, { treeAdapter: DomNode.treeAdapter }); } toFragment() { // 如果是文档片段,则只序列化 body return (0, parse5_1.serialize)(this.body, { treeAdapter: DomNode.treeAdapter }); } isFragment() { // 目前看来,片段和非片段的主要差别是 mode 为 'quirks',并且head 中没有任何东西 return this.mode === 'quirks' && this.head.childNodes.length === 0; } static parse(content) { return (0, parse5_1.parse)(content, { treeAdapter: DomNode.treeAdapter }); } } exports.DomDocument = DomDocument; class DomDocumentFragment extends DomParentNode { nodeName = '#document-fragment'; toHtml() { return (0, parse5_1.serialize)(this, { treeAdapter: DomNode.treeAdapter }); } static parse(content) { return (0, parse5_1.parseFragment)(content, { treeAdapter: DomNode.treeAdapter }); } } exports.DomDocumentFragment = DomDocumentFragment; class DomDocumentType extends DomChildNode { name; publicId; systemId; nodeName = '#documentType'; constructor(name, publicId, systemId) { super(); this.name = name; this.publicId = publicId; this.systemId = systemId; } } exports.DomDocumentType = DomDocumentType; function isSameName(name1, name2) { return name1?.localeCompare(name2) === 0; } class DomElement extends DomParentNode { tagName; attrs; namespaceURI; constructor(tagName, attrs = [], namespaceURI = 'http://www.w3.org/1999/xhtml') { super(); this.tagName = tagName; this.attrs = attrs; this.namespaceURI = namespaceURI; this.nodeName = tagName; } get innerHTML() { return (0, parse5_1.serialize)(this, { treeAdapter: DomNode.treeAdapter }); } set innerHTML(html) { const fragment = (0, parse5_1.parseFragment)(html, { treeAdapter: DomNode.treeAdapter }); this.childNodes = fragment.childNodes; } get outerHTML() { const node = new DomElement('div'); node.childNodes = [this]; return node.innerHTML; } get className() { return this.getAttributeNode('class')?.value; } get templateContent() { let parent = this.parentNode; while (parent) { if (parent instanceof DomDocumentFragment) { return parent; } parent = parent.parentNode; } } getAttributeNode(name) { return this.attrs.find(it => isSameName(it.name, name)); } getAttribute(name) { return this.getAttributeNode(name)?.value; } hasAttribute(name) { return !!this.getAttributeNode(name); } setAttribute(name, value) { const attr = this.getAttributeNode(name); if (!attr) { this.attrs.push({ name, value }); } else { attr.value = value; } } getAttributes() { return this.attrs; } setAttributes(...domAttrs) { this.attrs.push(...domAttrs); } removeAttribute(name) { const index = this.attrs.findIndex(it => isSameName(it.name, name)); if (index !== -1) { this.attrs.splice(index, 1); } } isSameTag(element) { return this.isTagOf(element.tagName); } isTagOf(...names) { return !!names.find(name => isSameName(this.tagName, name)); } hasClass(...classNames) { const classes = this.getAttribute('class')?.split(' '); return classNames.some(it => classes?.includes(it)); } } exports.DomElement = DomElement; class DomText extends DomChildNode { value; nodeName = '#text'; constructor(value) { super(); this.value = value; } } exports.DomText = DomText; class DomTableElement extends DomElement { } exports.DomTableElement = DomTableElement; class DomTableCellElement extends DomElement { } exports.DomTableCellElement = DomTableCellElement; class DomTableRowElement extends DomElement { get cells() { return this.children.filter(it => it.isTagOf('td') || it.isTagOf('th')); } } exports.DomTableRowElement = DomTableRowElement; const elementSelectors = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'p', 't', 'nt-wrapper'] .map(it => (node) => node.isTagOf(it)); const attributeSelector = (node) => node.hasAttribute('ng-should-translate'); exports.defaultSelectors = [...elementSelectors, attributeSelector]; //# sourceMappingURL=dom-models.js.map