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);
|
||||
}
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
export { default as CommentNode } from './nodes/comment';
|
||||
export { default as HTMLElement, parse, parse as default, Options } from './nodes/html';
|
||||
export { default as HTMLElement, Options } 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';
|
||||
|
||||
+14
-7
@@ -1,14 +1,21 @@
|
||||
"use strict";
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.NodeType = exports.TextNode = exports.Node = exports.valid = exports.default = exports.parse = exports.HTMLElement = exports.CommentNode = void 0;
|
||||
var comment_1 = require("./nodes/comment");
|
||||
exports.CommentNode = comment_1.default;
|
||||
Object.defineProperty(exports, "CommentNode", { enumerable: true, get: function () { return __importDefault(comment_1).default; } });
|
||||
var html_1 = require("./nodes/html");
|
||||
exports.HTMLElement = html_1.default;
|
||||
exports.parse = html_1.parse;
|
||||
exports.default = html_1.parse;
|
||||
Object.defineProperty(exports, "HTMLElement", { enumerable: true, get: function () { return __importDefault(html_1).default; } });
|
||||
var parse_1 = require("./parse");
|
||||
Object.defineProperty(exports, "parse", { enumerable: true, get: function () { return __importDefault(parse_1).default; } });
|
||||
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return __importDefault(parse_1).default; } });
|
||||
var valid_1 = require("./valid");
|
||||
Object.defineProperty(exports, "valid", { enumerable: true, get: function () { return __importDefault(valid_1).default; } });
|
||||
var node_1 = require("./nodes/node");
|
||||
exports.Node = node_1.default;
|
||||
Object.defineProperty(exports, "Node", { enumerable: true, get: function () { return __importDefault(node_1).default; } });
|
||||
var text_1 = require("./nodes/text");
|
||||
exports.TextNode = text_1.default;
|
||||
Object.defineProperty(exports, "TextNode", { enumerable: true, get: function () { return __importDefault(text_1).default; } });
|
||||
var type_1 = require("./nodes/type");
|
||||
exports.NodeType = type_1.default;
|
||||
Object.defineProperty(exports, "NodeType", { enumerable: true, get: function () { return __importDefault(type_1).default; } });
|
||||
|
||||
+933
-574
File diff suppressed because it is too large
Load Diff
+5
-40
@@ -1,41 +1,6 @@
|
||||
import { Adapter } from 'css-select/lib/types';
|
||||
import HTMLElement from './nodes/html';
|
||||
/**
|
||||
* Matcher class to make CSS match
|
||||
*
|
||||
* @class Matcher
|
||||
*/
|
||||
export default class Matcher {
|
||||
private matchers;
|
||||
private nextMatch;
|
||||
/**
|
||||
* Creates an instance of Matcher.
|
||||
* @param {string} selector
|
||||
*
|
||||
* @memberof Matcher
|
||||
*/
|
||||
constructor(selector: string);
|
||||
/**
|
||||
* Trying to advance match pointer
|
||||
* @param {HTMLElement} el element to make the match
|
||||
* @return {bool} true when pointer advanced.
|
||||
*/
|
||||
advance(el: HTMLElement): boolean;
|
||||
/**
|
||||
* Rewind the match pointer
|
||||
*/
|
||||
rewind(): void;
|
||||
/**
|
||||
* Trying to determine if match made.
|
||||
* @return {bool} true when the match is made
|
||||
*/
|
||||
get matched(): boolean;
|
||||
/**
|
||||
* Rest match pointer.
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
reset(): void;
|
||||
/**
|
||||
* flush cache to free memory
|
||||
*/
|
||||
flushCache(): void;
|
||||
}
|
||||
import Node from './nodes/node';
|
||||
export declare type Predicate = (node: Node) => node is HTMLElement;
|
||||
declare const _default: Adapter<Node, HTMLElement>;
|
||||
export default _default;
|
||||
|
||||
+101
-243
@@ -1,248 +1,106 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
/**
|
||||
* Cache to store generated match functions
|
||||
* @type {Object}
|
||||
*/
|
||||
var pMatchFunctionCache = {};
|
||||
/**
|
||||
* Function cache
|
||||
*/
|
||||
var functionCache = {
|
||||
f145: function (el, tagName, classes) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
classes = classes || [];
|
||||
if (el.id !== tagName.substr(1)) {
|
||||
return false;
|
||||
}
|
||||
for (var cls = classes, i = 0; i < cls.length; i++) {
|
||||
if (el.classNames.indexOf(cls[i]) === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
f45: function (el, tagName, classes) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
classes = classes || [];
|
||||
for (var cls = classes, i = 0; i < cls.length; i++) {
|
||||
if (el.classNames.indexOf(cls[i]) === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
f15: function (el, tagName) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
if (el.id !== tagName.substr(1)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
f1: function (el, tagName) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
if (el.id !== tagName.substr(1)) {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
f5: function () {
|
||||
'use strict';
|
||||
return true;
|
||||
},
|
||||
f55: function (el, tagName, classes, attr_key) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
classes = classes || [];
|
||||
attr_key = attr_key || '';
|
||||
var attrs = el.attributes;
|
||||
return attrs.hasOwnProperty(attr_key);
|
||||
},
|
||||
f245: function (el, tagName, classes, attr_key, value) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
classes = classes || [];
|
||||
attr_key = attr_key || '';
|
||||
value = value || '';
|
||||
var attrs = el.attributes;
|
||||
return Object.keys(attrs).some(function (key) {
|
||||
var val = attrs[key];
|
||||
return key === attr_key && val === value;
|
||||
});
|
||||
// for (let cls = classes, i = 0; i < cls.length; i++) {if (el.classNames.indexOf(cls[i]) === -1){ return false;}}
|
||||
// return true;
|
||||
},
|
||||
f25: function (el, tagName, classes, attr_key, value) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
classes = classes || [];
|
||||
attr_key = attr_key || '';
|
||||
value = value || '';
|
||||
var attrs = el.attributes;
|
||||
return Object.keys(attrs).some(function (key) {
|
||||
var val = attrs[key];
|
||||
return key === attr_key && val === value;
|
||||
});
|
||||
// return true;
|
||||
},
|
||||
f2: function (el, tagName, classes, attr_key, value) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
classes = classes || [];
|
||||
attr_key = attr_key || '';
|
||||
value = value || '';
|
||||
var attrs = el.attributes;
|
||||
return Object.keys(attrs).some(function (key) {
|
||||
var val = attrs[key];
|
||||
return key === attr_key && val === value;
|
||||
});
|
||||
},
|
||||
f345: function (el, tagName, classes) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
classes = classes || [];
|
||||
if (el.tagName !== tagName) {
|
||||
return false;
|
||||
}
|
||||
for (var cls = classes, i = 0; i < cls.length; i++) {
|
||||
if (el.classNames.indexOf(cls[i]) === -1) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
},
|
||||
f35: function (el, tagName) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
return el.tagName === tagName;
|
||||
},
|
||||
f3: function (el, tagName) {
|
||||
'use strict';
|
||||
tagName = tagName || '';
|
||||
if (el.tagName !== tagName) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { "default": mod };
|
||||
};
|
||||
/**
|
||||
* Matcher class to make CSS match
|
||||
*
|
||||
* @class Matcher
|
||||
*/
|
||||
var Matcher = /** @class */ (function () {
|
||||
/**
|
||||
* Creates an instance of Matcher.
|
||||
* @param {string} selector
|
||||
*
|
||||
* @memberof Matcher
|
||||
*/
|
||||
function Matcher(selector) {
|
||||
this.nextMatch = 0;
|
||||
functionCache.f5 = functionCache.f5;
|
||||
this.matchers = selector.split(' ').map(function (matcher) {
|
||||
if (pMatchFunctionCache[matcher])
|
||||
return pMatchFunctionCache[matcher];
|
||||
var parts = matcher.split('.');
|
||||
var tagName = parts[0];
|
||||
var classes = parts.slice(1).sort();
|
||||
// let source = '"use strict";';
|
||||
var function_name = 'f';
|
||||
var attr_key = '';
|
||||
var value = '';
|
||||
if (tagName && tagName !== '*') {
|
||||
var reg = void 0;
|
||||
if (tagName.startsWith('#')) {
|
||||
// source += 'if (el.id != ' + JSON.stringify(tagName.substr(1)) + ') return false;';// 1
|
||||
function_name += '1';
|
||||
}
|
||||
else {
|
||||
reg = /^\[\s*(\S+)\s*(=|!=)\s*((((["'])([^\6]*)\6))|(\S*?))\]\s*/.exec(tagName);
|
||||
if (reg) {
|
||||
attr_key = reg[1];
|
||||
var method = reg[2];
|
||||
if (method !== '=' && method !== '!=') {
|
||||
throw new Error('Selector not supported, Expect [key${op}value].op must be =,!=');
|
||||
}
|
||||
if (method === '=') {
|
||||
method = '==';
|
||||
}
|
||||
value = reg[7] || reg[8];
|
||||
// source += `let attrs = el.attributes;for (let key in attrs){const val = attrs[key]; if (key == "${attr_key}" && val == "${value}"){return true;}} return false;`;// 2
|
||||
function_name += '2';
|
||||
}
|
||||
else if (reg = /^\[(.*?)\]/.exec(tagName)) {
|
||||
attr_key = reg[1];
|
||||
function_name += '5';
|
||||
}
|
||||
else {
|
||||
// source += 'if (el.tagName != ' + JSON.stringify(tagName) + ') return false;';// 3
|
||||
function_name += '3';
|
||||
}
|
||||
}
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var type_1 = __importDefault(require("./nodes/type"));
|
||||
function isTag(node) {
|
||||
return node && node.nodeType === type_1.default.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) {
|
||||
var idx = nodes.length;
|
||||
var node;
|
||||
var ancestor;
|
||||
var 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;
|
||||
}
|
||||
if (classes.length > 0) {
|
||||
// source += 'for (let cls = ' + JSON.stringify(classes) + ', i = 0; i < cls.length; i++) if (el.classNames.indexOf(cls[i]) === -1) return false;';// 4
|
||||
function_name += '4';
|
||||
}
|
||||
// source += 'return true;';// 5
|
||||
function_name += '5';
|
||||
var obj = {
|
||||
func: functionCache[function_name],
|
||||
tagName: tagName || '',
|
||||
classes: classes || '',
|
||||
attr_key: attr_key || '',
|
||||
value: value || ''
|
||||
};
|
||||
// source = source || '';
|
||||
return pMatchFunctionCache[matcher] = obj;
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Trying to advance match pointer
|
||||
* @param {HTMLElement} el element to make the match
|
||||
* @return {bool} true when pointer advanced.
|
||||
*/
|
||||
Matcher.prototype.advance = function (el) {
|
||||
if (this.nextMatch < this.matchers.length &&
|
||||
this.matchers[this.nextMatch].func(el, this.matchers[this.nextMatch].tagName, this.matchers[this.nextMatch].classes, this.matchers[this.nextMatch].attr_key, this.matchers[this.nextMatch].value)) {
|
||||
this.nextMatch++;
|
||||
return true;
|
||||
ancestor = getParent(ancestor);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
/**
|
||||
* Rewind the match pointer
|
||||
*/
|
||||
Matcher.prototype.rewind = function () {
|
||||
this.nextMatch--;
|
||||
};
|
||||
Object.defineProperty(Matcher.prototype, "matched", {
|
||||
/**
|
||||
* Trying to determine if match made.
|
||||
* @return {bool} true when the match is made
|
||||
*/
|
||||
get: function () {
|
||||
return this.nextMatch === this.matchers.length;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
// 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(function (elem) {
|
||||
return isTag(elem) ? test(elem) || existsOne(test, getChildren(elem)) : false;
|
||||
});
|
||||
/**
|
||||
* Rest match pointer.
|
||||
* @return {[type]} [description]
|
||||
*/
|
||||
Matcher.prototype.reset = function () {
|
||||
this.nextMatch = 0;
|
||||
};
|
||||
/**
|
||||
* flush cache to free memory
|
||||
*/
|
||||
Matcher.prototype.flushCache = function () {
|
||||
pMatchFunctionCache = {};
|
||||
};
|
||||
return Matcher;
|
||||
}());
|
||||
exports.default = Matcher;
|
||||
}
|
||||
function getSiblings(node) {
|
||||
var parent = getParent(node);
|
||||
return parent && getChildren(parent);
|
||||
}
|
||||
function hasAttrib(elem, name) {
|
||||
return getAttributeValue(elem, name) !== undefined;
|
||||
}
|
||||
function findOne(test, elems) {
|
||||
var elem = null;
|
||||
for (var i = 0, l = elems.length; i < l && !elem; i++) {
|
||||
var el = elems[i];
|
||||
if (test(el)) {
|
||||
elem = el;
|
||||
}
|
||||
else {
|
||||
var childs = getChildren(el);
|
||||
if (childs && childs.length > 0) {
|
||||
elem = findOne(test, childs);
|
||||
}
|
||||
}
|
||||
}
|
||||
return elem;
|
||||
}
|
||||
function findAll(test, nodes) {
|
||||
var result = [];
|
||||
for (var i = 0, j = nodes.length; i < j; i++) {
|
||||
if (!isTag(nodes[i]))
|
||||
continue;
|
||||
if (test(nodes[i]))
|
||||
result.push(nodes[i]);
|
||||
var childs = getChildren(nodes[i]);
|
||||
if (childs)
|
||||
result = result.concat(findAll(test, childs));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
exports.default = {
|
||||
isTag: isTag,
|
||||
getAttributeValue: getAttributeValue,
|
||||
getName: getName,
|
||||
getChildren: getChildren,
|
||||
getParent: getParent,
|
||||
getText: getText,
|
||||
removeSubsets: removeSubsets,
|
||||
existsOne: existsOne,
|
||||
getSiblings: getSiblings,
|
||||
hasAttrib: hasAttrib,
|
||||
findOne: findOne,
|
||||
findAll: findAll
|
||||
};
|
||||
|
||||
+4
-2
@@ -1,7 +1,9 @@
|
||||
import Node from './node';
|
||||
import NodeType from './type';
|
||||
import HTMLElement from './html';
|
||||
export default class CommentNode extends Node {
|
||||
constructor(value: string);
|
||||
rawText: string;
|
||||
constructor(rawText: string, parentNode: HTMLElement);
|
||||
/**
|
||||
* Node Type declaration.
|
||||
* @type {Number}
|
||||
@@ -12,5 +14,5 @@ export default class CommentNode extends Node {
|
||||
* @return {string} text content
|
||||
*/
|
||||
get text(): string;
|
||||
toString(): string;
|
||||
toString(): `<!--${string}-->`;
|
||||
}
|
||||
|
||||
+7
-5
@@ -3,10 +3,12 @@ var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
@@ -20,14 +22,14 @@ var node_1 = __importDefault(require("./node"));
|
||||
var type_1 = __importDefault(require("./type"));
|
||||
var CommentNode = /** @class */ (function (_super) {
|
||||
__extends(CommentNode, _super);
|
||||
function CommentNode(value) {
|
||||
var _this = _super.call(this) || this;
|
||||
function CommentNode(rawText, parentNode) {
|
||||
var _this = _super.call(this, parentNode) || this;
|
||||
_this.rawText = rawText;
|
||||
/**
|
||||
* Node Type declaration.
|
||||
* @type {Number}
|
||||
*/
|
||||
_this.nodeType = type_1.default.COMMENT_NODE;
|
||||
_this.rawText = value;
|
||||
return _this;
|
||||
}
|
||||
Object.defineProperty(CommentNode.prototype, "text", {
|
||||
@@ -38,7 +40,7 @@ var CommentNode = /** @class */ (function (_super) {
|
||||
get: function () {
|
||||
return this.rawText;
|
||||
},
|
||||
enumerable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
CommentNode.prototype.toString = function () {
|
||||
|
||||
+59
-29
@@ -1,7 +1,5 @@
|
||||
import Node from './node';
|
||||
import NodeType from './type';
|
||||
import TextNode from './text';
|
||||
import Matcher from '../matcher';
|
||||
export interface KeyAttributes {
|
||||
id?: string;
|
||||
class?: string;
|
||||
@@ -13,6 +11,21 @@ export interface RawAttributes {
|
||||
[key: string]: string;
|
||||
}
|
||||
export declare type InsertPosition = 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend';
|
||||
declare class DOMTokenList {
|
||||
private _set;
|
||||
private _afterUpdate;
|
||||
private _validate;
|
||||
constructor(valuesInit?: string[], afterUpdate?: ((t: DOMTokenList) => void));
|
||||
add(c: string): void;
|
||||
replace(c1: string, c2: string): void;
|
||||
remove(c: string): void;
|
||||
toggle(c: string): void;
|
||||
contains(c: string): boolean;
|
||||
get length(): number;
|
||||
values(): IterableIterator<string>;
|
||||
get value(): string[];
|
||||
toString(): string;
|
||||
}
|
||||
/**
|
||||
* HTMLElement, which contains a set of children.
|
||||
*
|
||||
@@ -23,17 +36,22 @@ export declare type InsertPosition = 'beforebegin' | 'afterbegin' | 'beforeend'
|
||||
* @extends {Node}
|
||||
*/
|
||||
export default class HTMLElement extends Node {
|
||||
tagName: string;
|
||||
private rawAttrs;
|
||||
parentNode: Node;
|
||||
private _attrs;
|
||||
private _rawAttrs;
|
||||
rawTagName: string;
|
||||
id: string;
|
||||
classNames: string[];
|
||||
classList: DOMTokenList;
|
||||
/**
|
||||
* Node Type declaration.
|
||||
*/
|
||||
nodeType: NodeType;
|
||||
/**
|
||||
* Quote attribute values
|
||||
* @param attr attribute value
|
||||
* @returns {string} quoted value
|
||||
*/
|
||||
private quoteAttribute;
|
||||
/**
|
||||
* Creates an instance of HTMLElement.
|
||||
* @param keyAttrs id and class attribute
|
||||
@@ -41,7 +59,11 @@ export default class HTMLElement extends Node {
|
||||
*
|
||||
* @memberof HTMLElement
|
||||
*/
|
||||
constructor(tagName: string, keyAttrs: KeyAttributes, rawAttrs?: string, parentNode?: Node);
|
||||
constructor(tagName: string, keyAttrs: KeyAttributes, rawAttrs: string, parentNode: HTMLElement | null);
|
||||
/**
|
||||
* Remove current element
|
||||
*/
|
||||
remove(): void;
|
||||
/**
|
||||
* Remove Child element from childNodes array
|
||||
* @param {HTMLElement} node node to remove
|
||||
@@ -53,11 +75,15 @@ export default class HTMLElement extends Node {
|
||||
* @param {HTMLElement} newNode new node
|
||||
*/
|
||||
exchangeChild(oldNode: Node, newNode: Node): void;
|
||||
get tagName(): string;
|
||||
get localName(): string;
|
||||
/**
|
||||
* Get escpaed (as-it) text value of current node and its children.
|
||||
* @return {string} text content
|
||||
*/
|
||||
get rawText(): string;
|
||||
get textContent(): string;
|
||||
set textContent(val: string);
|
||||
/**
|
||||
* Get unescaped text value of current node and its children.
|
||||
* @return {string} text content
|
||||
@@ -70,7 +96,9 @@ export default class HTMLElement extends Node {
|
||||
get structuredText(): string;
|
||||
toString(): string;
|
||||
get innerHTML(): string;
|
||||
set innerHTML(content: string);
|
||||
set_content(content: string | Node | Node[], options?: Options): void;
|
||||
replaceWith(...nodes: (string | Node)[]): void;
|
||||
get outerHTML(): string;
|
||||
/**
|
||||
* Trim element from right (in block) after seeing pattern in a TextNode.
|
||||
@@ -91,17 +119,20 @@ export default class HTMLElement extends Node {
|
||||
/**
|
||||
* Query CSS selector to find matching nodes.
|
||||
* @param {string} selector Simplified CSS selector
|
||||
* @param {Matcher} selector A Matcher instance
|
||||
* @return {HTMLElement[]} matching elements
|
||||
*/
|
||||
querySelectorAll(selector: string | Matcher): HTMLElement[];
|
||||
querySelectorAll(selector: string): HTMLElement[];
|
||||
/**
|
||||
* Query CSS Selector to find matching node.
|
||||
* @param {string} selector Simplified CSS selector
|
||||
* @param {Matcher} selector A Matcher instance
|
||||
* @return {HTMLElement} matching node
|
||||
*/
|
||||
querySelector(selector: string | Matcher): HTMLElement;
|
||||
querySelector(selector: string): HTMLElement;
|
||||
/**
|
||||
* traverses the Element and its parents (heading toward the document root) until it finds a node that matches the provided selector string. Will return itself or the matching ancestor. If no such element exists, it returns null.
|
||||
* @param selector a DOMString containing a selector list
|
||||
*/
|
||||
closest(selector: string): Node;
|
||||
/**
|
||||
* Append a child node to childNodes
|
||||
* @param {Node} node node to append
|
||||
@@ -120,9 +151,11 @@ export default class HTMLElement extends Node {
|
||||
get lastChild(): Node;
|
||||
/**
|
||||
* Get attributes
|
||||
* @access private
|
||||
* @return {Object} parsed and unescaped attributes
|
||||
*/
|
||||
get attributes(): Attributes;
|
||||
get attrs(): Attributes;
|
||||
get attributes(): Record<string, string>;
|
||||
/**
|
||||
* Get escaped (as-it) attributes
|
||||
* @return {Object} parsed attributes
|
||||
@@ -147,13 +180,16 @@ export default class HTMLElement extends Node {
|
||||
*/
|
||||
setAttributes(attributes: Attributes): void;
|
||||
insertAdjacentHTML(where: InsertPosition, html: string): void;
|
||||
get nextSibling(): Node;
|
||||
get nextElementSibling(): HTMLElement;
|
||||
get classNames(): string;
|
||||
}
|
||||
export interface Options {
|
||||
lowerCaseTagName?: boolean;
|
||||
script?: boolean;
|
||||
style?: boolean;
|
||||
pre?: boolean;
|
||||
comment?: boolean;
|
||||
lowerCaseTagName: boolean;
|
||||
comment: boolean;
|
||||
blockTextElements: {
|
||||
[tag: string]: boolean;
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Parses HTML and returns a root element
|
||||
@@ -161,16 +197,10 @@ export interface Options {
|
||||
* @param {string} data html
|
||||
* @return {HTMLElement} root element
|
||||
*/
|
||||
export declare function parse(data: string, options?: Options): HTMLElement & {
|
||||
valid: boolean;
|
||||
};
|
||||
export declare function parse(data: string, options?: Options & {
|
||||
noFix: false;
|
||||
}): HTMLElement & {
|
||||
valid: boolean;
|
||||
};
|
||||
export declare function parse(data: string, options?: Options & {
|
||||
noFix: true;
|
||||
}): (HTMLElement | TextNode) & {
|
||||
valid: boolean;
|
||||
};
|
||||
export declare function base_parse(data: string, options?: Partial<Options>): HTMLElement[];
|
||||
/**
|
||||
* Parses HTML and returns a root element
|
||||
* Parse a chuck of HTML source.
|
||||
*/
|
||||
export declare function parse(data: string, options?: Partial<Options>): HTMLElement;
|
||||
export {};
|
||||
|
||||
+687
-263
File diff suppressed because it is too large
Load Diff
+9
-3
@@ -1,11 +1,17 @@
|
||||
import NodeType from './type';
|
||||
import HTMLElement from './html';
|
||||
/**
|
||||
* Node Class as base class for TextNode and HTMLElement.
|
||||
*/
|
||||
export default abstract class Node {
|
||||
nodeType: NodeType;
|
||||
parentNode: HTMLElement;
|
||||
abstract nodeType: NodeType;
|
||||
childNodes: Node[];
|
||||
text: string;
|
||||
rawText: string;
|
||||
abstract text: string;
|
||||
abstract rawText: string;
|
||||
abstract toString(): string;
|
||||
constructor(parentNode?: HTMLElement);
|
||||
get innerText(): string;
|
||||
get textContent(): string;
|
||||
set textContent(val: string);
|
||||
}
|
||||
|
||||
+20
-1
@@ -4,9 +4,28 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
||||
* Node Class as base class for TextNode and HTMLElement.
|
||||
*/
|
||||
var Node = /** @class */ (function () {
|
||||
function Node() {
|
||||
function Node(parentNode) {
|
||||
if (parentNode === void 0) { parentNode = null; }
|
||||
this.parentNode = parentNode;
|
||||
this.childNodes = [];
|
||||
}
|
||||
Object.defineProperty(Node.prototype, "innerText", {
|
||||
get: function () {
|
||||
return this.rawText;
|
||||
},
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Node.prototype, "textContent", {
|
||||
get: function () {
|
||||
return this.rawText;
|
||||
},
|
||||
set: function (val) {
|
||||
this.rawText = val;
|
||||
},
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
return Node;
|
||||
}());
|
||||
exports.default = Node;
|
||||
|
||||
+8
-1
@@ -1,16 +1,23 @@
|
||||
import NodeType from './type';
|
||||
import Node from './node';
|
||||
import HTMLElement from './html';
|
||||
/**
|
||||
* TextNode to contain a text element in DOM tree.
|
||||
* @param {string} value [description]
|
||||
*/
|
||||
export default class TextNode extends Node {
|
||||
constructor(value: string);
|
||||
rawText: string;
|
||||
constructor(rawText: string, parentNode: HTMLElement);
|
||||
/**
|
||||
* Node Type declaration.
|
||||
* @type {Number}
|
||||
*/
|
||||
nodeType: NodeType;
|
||||
private _trimmedText?;
|
||||
/**
|
||||
* Returns text with all whitespace trimmed except single leading/trailing non-breaking space
|
||||
*/
|
||||
get trimmedText(): string;
|
||||
/**
|
||||
* Get unescaped text value of current node and its children.
|
||||
* @return {string} text content
|
||||
|
||||
+47
-6
@@ -3,10 +3,12 @@ var __extends = (this && this.__extends) || (function () {
|
||||
var extendStatics = function (d, b) {
|
||||
extendStatics = Object.setPrototypeOf ||
|
||||
({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
|
||||
function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
|
||||
function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
|
||||
return extendStatics(d, b);
|
||||
};
|
||||
return function (d, b) {
|
||||
if (typeof b !== "function" && b !== null)
|
||||
throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
|
||||
extendStatics(d, b);
|
||||
function __() { this.constructor = d; }
|
||||
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
||||
@@ -24,16 +26,55 @@ var node_1 = __importDefault(require("./node"));
|
||||
*/
|
||||
var TextNode = /** @class */ (function (_super) {
|
||||
__extends(TextNode, _super);
|
||||
function TextNode(value) {
|
||||
var _this = _super.call(this) || this;
|
||||
function TextNode(rawText, parentNode) {
|
||||
var _this = _super.call(this, parentNode) || this;
|
||||
_this.rawText = rawText;
|
||||
/**
|
||||
* Node Type declaration.
|
||||
* @type {Number}
|
||||
*/
|
||||
_this.nodeType = type_1.default.TEXT_NODE;
|
||||
_this.rawText = value;
|
||||
return _this;
|
||||
}
|
||||
Object.defineProperty(TextNode.prototype, "trimmedText", {
|
||||
/**
|
||||
* Returns text with all whitespace trimmed except single leading/trailing non-breaking space
|
||||
*/
|
||||
get: function () {
|
||||
if (this._trimmedText !== undefined)
|
||||
return this._trimmedText;
|
||||
var text = this.rawText;
|
||||
var i = 0;
|
||||
var startPos;
|
||||
var 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;
|
||||
var hasLeadingSpace = startPos > 0 && /[^\S\r\n]/.test(text[startPos - 1]);
|
||||
var hasTrailingSpace = endPos < (text.length - 1) && /[^\S\r\n]/.test(text[endPos + 1]);
|
||||
this._trimmedText = (hasLeadingSpace ? ' ' : '') + text.slice(startPos, endPos + 1) + (hasTrailingSpace ? ' ' : '');
|
||||
return this._trimmedText;
|
||||
},
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(TextNode.prototype, "text", {
|
||||
/**
|
||||
* Get unescaped text value of current node and its children.
|
||||
@@ -42,7 +83,7 @@ var TextNode = /** @class */ (function (_super) {
|
||||
get: function () {
|
||||
return this.rawText;
|
||||
},
|
||||
enumerable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(TextNode.prototype, "isWhitespace", {
|
||||
@@ -53,7 +94,7 @@ var TextNode = /** @class */ (function (_super) {
|
||||
get: function () {
|
||||
return /^(\s| )*$/.test(this.rawText);
|
||||
},
|
||||
enumerable: true,
|
||||
enumerable: false,
|
||||
configurable: true
|
||||
});
|
||||
TextNode.prototype.toString = function () {
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export { parse as default } from './nodes/html';
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.default = void 0;
|
||||
var html_1 = require("./nodes/html");
|
||||
Object.defineProperty(exports, "default", { enumerable: true, get: function () { return html_1.parse; } });
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
import { Options } from './nodes/html';
|
||||
/**
|
||||
* Parses HTML and returns a root element
|
||||
* Parse a chuck of HTML source.
|
||||
*/
|
||||
export default function valid(data: string, options?: Partial<Options>): boolean;
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var html_1 = require("./nodes/html");
|
||||
/**
|
||||
* Parses HTML and returns a root element
|
||||
* Parse a chuck of HTML source.
|
||||
*/
|
||||
function valid(data, options) {
|
||||
if (options === void 0) { options = { lowerCaseTagName: false, comment: false }; }
|
||||
var stack = html_1.base_parse(data, options);
|
||||
return Boolean(stack.length === 1);
|
||||
}
|
||||
exports.default = valid;
|
||||
Reference in New Issue
Block a user