update
This commit is contained in:
+3
@@ -0,0 +1,3 @@
|
||||
export default function arr_back(arr) {
|
||||
return arr[arr.length - 1];
|
||||
}
|
||||
+7
@@ -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
@@ -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
@@ -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}-->`;
|
||||
}
|
||||
}
|
||||
+1092
File diff suppressed because it is too large
Load Diff
+18
@@ -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
@@ -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| )*$/.test(this.rawText);
|
||||
}
|
||||
toString() {
|
||||
return this.text;
|
||||
}
|
||||
}
|
||||
+7
@@ -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
@@ -0,0 +1 @@
|
||||
export { parse as default } from './nodes/html';
|
||||
+9
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user