This commit is contained in:
2022-07-18 02:50:52 +00:00
parent befd344ab0
commit 06181b34d6
8569 changed files with 818704 additions and 352705 deletions
+3
View File
@@ -0,0 +1,3 @@
export default function arr_back(arr) {
return arr[arr.length - 1];
}
+7
View File
@@ -0,0 +1,7 @@
export { default as CommentNode } from './nodes/comment';
export { default as HTMLElement } from './nodes/html';
export { default as parse, default } from './parse';
export { default as valid } from './valid';
export { default as Node } from './nodes/node';
export { default as TextNode } from './nodes/text';
export { default as NodeType } from './nodes/type';
+101
View File
@@ -0,0 +1,101 @@
import NodeType from './nodes/type';
function isTag(node) {
return node && node.nodeType === NodeType.ELEMENT_NODE;
}
function getAttributeValue(elem, name) {
return isTag(elem) ? elem.getAttribute(name) : undefined;
}
function getName(elem) {
return ((elem && elem.rawTagName) || '').toLowerCase();
}
function getChildren(node) {
return node && node.childNodes;
}
function getParent(node) {
return node ? node.parentNode : null;
}
function getText(node) {
return node.text;
}
function removeSubsets(nodes) {
let idx = nodes.length;
let node;
let ancestor;
let replace;
// 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
nodes[idx] = null;
replace = true;
while (ancestor) {
if (nodes.indexOf(ancestor) > -1) {
replace = false;
nodes.splice(idx, 1);
break;
}
ancestor = getParent(ancestor);
}
// If the node has been found to be unique, re-insert it.
if (replace) {
nodes[idx] = node;
}
}
return nodes;
}
function existsOne(test, elems) {
return elems.some((elem) => {
return isTag(elem) ? test(elem) || existsOne(test, getChildren(elem)) : false;
});
}
function getSiblings(node) {
const parent = getParent(node);
return parent && getChildren(parent);
}
function hasAttrib(elem, name) {
return getAttributeValue(elem, name) !== undefined;
}
function findOne(test, elems) {
let elem = null;
for (let i = 0, l = elems.length; i < l && !elem; i++) {
const el = elems[i];
if (test(el)) {
elem = el;
}
else {
const childs = getChildren(el);
if (childs && childs.length > 0) {
elem = findOne(test, childs);
}
}
}
return elem;
}
function findAll(test, nodes) {
let result = [];
for (let i = 0, j = nodes.length; i < j; i++) {
if (!isTag(nodes[i]))
continue;
if (test(nodes[i]))
result.push(nodes[i]);
const childs = getChildren(nodes[i]);
if (childs)
result = result.concat(findAll(test, childs));
}
return result;
}
export default {
isTag,
getAttributeValue,
getName,
getChildren,
getParent,
getText,
removeSubsets,
existsOne,
getSiblings,
hasAttrib,
findOne,
findAll
};
+23
View File
@@ -0,0 +1,23 @@
import Node from './node';
import NodeType from './type';
export default class CommentNode extends Node {
constructor(rawText, parentNode) {
super(parentNode);
this.rawText = rawText;
/**
* Node Type declaration.
* @type {Number}
*/
this.nodeType = NodeType.COMMENT_NODE;
}
/**
* Get unescaped text value of current node and its children.
* @return {string} text content
*/
get text() {
return this.rawText;
}
toString() {
return `<!--${this.rawText}-->`;
}
}
File diff suppressed because it is too large Load Diff
+18
View File
@@ -0,0 +1,18 @@
/**
* Node Class as base class for TextNode and HTMLElement.
*/
export default class Node {
constructor(parentNode = null) {
this.parentNode = parentNode;
this.childNodes = [];
}
get innerText() {
return this.rawText;
}
get textContent() {
return this.rawText;
}
set textContent(val) {
this.rawText = val;
}
}
+69
View File
@@ -0,0 +1,69 @@
import NodeType from './type';
import Node from './node';
/**
* TextNode to contain a text element in DOM tree.
* @param {string} value [description]
*/
export default class TextNode extends Node {
constructor(rawText, parentNode) {
super(parentNode);
this.rawText = rawText;
/**
* Node Type declaration.
* @type {Number}
*/
this.nodeType = NodeType.TEXT_NODE;
}
/**
* Returns text with all whitespace trimmed except single leading/trailing non-breaking space
*/
get trimmedText() {
if (this._trimmedText !== undefined)
return this._trimmedText;
const text = this.rawText;
let i = 0;
let startPos;
let endPos;
while (i >= 0 && i < text.length) {
if (/\S/.test(text[i])) {
if (startPos === undefined) {
startPos = i;
i = text.length;
}
else {
endPos = i;
i = void 0;
}
}
if (startPos === undefined)
i++;
else
i--;
}
if (startPos === undefined)
startPos = 0;
if (endPos === undefined)
endPos = text.length - 1;
const hasLeadingSpace = startPos > 0 && /[^\S\r\n]/.test(text[startPos - 1]);
const hasTrailingSpace = endPos < (text.length - 1) && /[^\S\r\n]/.test(text[endPos + 1]);
this._trimmedText = (hasLeadingSpace ? ' ' : '') + text.slice(startPos, endPos + 1) + (hasTrailingSpace ? ' ' : '');
return this._trimmedText;
}
/**
* Get unescaped text value of current node and its children.
* @return {string} text content
*/
get text() {
return this.rawText;
}
/**
* Detect if the node contains only white space.
* @return {bool}
*/
get isWhitespace() {
return /^(\s|&nbsp;)*$/.test(this.rawText);
}
toString() {
return this.text;
}
}
+7
View File
@@ -0,0 +1,7 @@
var NodeType;
(function (NodeType) {
NodeType[NodeType["ELEMENT_NODE"] = 1] = "ELEMENT_NODE";
NodeType[NodeType["TEXT_NODE"] = 3] = "TEXT_NODE";
NodeType[NodeType["COMMENT_NODE"] = 8] = "COMMENT_NODE";
})(NodeType || (NodeType = {}));
export default NodeType;
+1
View File
@@ -0,0 +1 @@
export { parse as default } from './nodes/html';
+9
View File
@@ -0,0 +1,9 @@
import { base_parse } from './nodes/html';
/**
* Parses HTML and returns a root element
* Parse a chuck of HTML source.
*/
export default function valid(data, options = { lowerCaseTagName: false, comment: false }) {
const stack = base_parse(data, options);
return Boolean(stack.length === 1);
}