mirror of
https://github.com/danbulant/node-html-parser
synced 2026-05-19 04:18:52 +00:00
issue: #24 Add method insertAdjacentHTML
This commit is contained in:
parent
45e77f3771
commit
a72c0da9ee
3 changed files with 89 additions and 16 deletions
|
|
@ -126,6 +126,10 @@ Query CSS Selector to find matching node.
|
|||
|
||||
Append a child node to childNodes
|
||||
|
||||
### HTMLElement#insertAdjacentHTML(where, html)
|
||||
|
||||
parses the specified text as HTML and inserts the resulting nodes into the DOM tree at a specified position.
|
||||
|
||||
### HTMLElement#firstChild
|
||||
|
||||
Get first child node
|
||||
|
|
|
|||
|
|
@ -19,6 +19,8 @@ export interface RawAttributes {
|
|||
[key: string]: string;
|
||||
}
|
||||
|
||||
export type InsertPosition = 'beforebegin' | 'afterbegin' | 'beforeend' | 'afterend';
|
||||
|
||||
const kBlockElements = {
|
||||
div: true,
|
||||
p: true,
|
||||
|
|
@ -57,7 +59,7 @@ export default class HTMLElement extends Node {
|
|||
*
|
||||
* @memberof HTMLElement
|
||||
*/
|
||||
constructor(public tagName: string, keyAttrs: KeyAttributes, private rawAttrs = '', public parentNode = null as Node) {
|
||||
public constructor(public tagName: string, keyAttrs: KeyAttributes, private rawAttrs = '', public parentNode = null as Node) {
|
||||
super();
|
||||
this.rawAttrs = rawAttrs || '';
|
||||
this.parentNode = parentNode || null;
|
||||
|
|
@ -97,7 +99,7 @@ export default class HTMLElement extends Node {
|
|||
* Get escpaed (as-it) text value of current node and its children.
|
||||
* @return {string} text content
|
||||
*/
|
||||
get rawText() {
|
||||
public get rawText() {
|
||||
return this.childNodes.reduce((pre, cur) => {
|
||||
return pre += cur.rawText;
|
||||
}, '');
|
||||
|
|
@ -106,14 +108,14 @@ export default class HTMLElement extends Node {
|
|||
* Get unescaped text value of current node and its children.
|
||||
* @return {string} text content
|
||||
*/
|
||||
get text() {
|
||||
public get text() {
|
||||
return decode(this.rawText);
|
||||
}
|
||||
/**
|
||||
* Get structured Text (with '\n' etc.)
|
||||
* @return {string} structured text
|
||||
*/
|
||||
get structuredText() {
|
||||
public get structuredText() {
|
||||
let currentBlock = [] as string[];
|
||||
const blocks = [currentBlock];
|
||||
function dfs(node: Node) {
|
||||
|
|
@ -170,7 +172,7 @@ export default class HTMLElement extends Node {
|
|||
}
|
||||
}
|
||||
|
||||
get innerHTML() {
|
||||
public get innerHTML() {
|
||||
return this.childNodes.map((child) => {
|
||||
return child.toString();
|
||||
}).join('');
|
||||
|
|
@ -186,7 +188,7 @@ export default class HTMLElement extends Node {
|
|||
this.childNodes = content;
|
||||
}
|
||||
|
||||
get outerHTML() {
|
||||
public get outerHTML() {
|
||||
return this.toString();
|
||||
}
|
||||
|
||||
|
|
@ -215,7 +217,7 @@ export default class HTMLElement extends Node {
|
|||
* Get DOM structure
|
||||
* @return {string} strucutre
|
||||
*/
|
||||
get structure() {
|
||||
public get structure() {
|
||||
const res = [] as string[];
|
||||
let indention = 0;
|
||||
function write(str: string) {
|
||||
|
|
@ -383,7 +385,7 @@ export default class HTMLElement extends Node {
|
|||
* Get first child node
|
||||
* @return {Node} first child node
|
||||
*/
|
||||
get firstChild() {
|
||||
public get firstChild() {
|
||||
return this.childNodes[0];
|
||||
}
|
||||
|
||||
|
|
@ -391,7 +393,7 @@ export default class HTMLElement extends Node {
|
|||
* Get last child node
|
||||
* @return {Node} last child node
|
||||
*/
|
||||
get lastChild() {
|
||||
public get lastChild() {
|
||||
return arr_back(this.childNodes);
|
||||
}
|
||||
|
||||
|
|
@ -399,7 +401,7 @@ export default class HTMLElement extends Node {
|
|||
* Get attributes
|
||||
* @return {Object} parsed and unescaped attributes
|
||||
*/
|
||||
get attributes() {
|
||||
public get attributes() {
|
||||
if (this._attrs) {
|
||||
return this._attrs;
|
||||
}
|
||||
|
|
@ -416,7 +418,7 @@ export default class HTMLElement extends Node {
|
|||
* Get escaped (as-it) attributes
|
||||
* @return {Object} parsed attributes
|
||||
*/
|
||||
get rawAttributes() {
|
||||
public get rawAttributes() {
|
||||
if (this._rawAttrs)
|
||||
return this._rawAttrs;
|
||||
const attrs = {} as RawAttributes;
|
||||
|
|
@ -510,4 +512,29 @@ export default class HTMLElement extends Node {
|
|||
}
|
||||
}).join(' ');
|
||||
}
|
||||
|
||||
public insertAdjacentHTML(where: InsertPosition, html: string) {
|
||||
if (arguments.length < 2) {
|
||||
throw new Error('2 arguments required');
|
||||
}
|
||||
const p = parse(html) as HTMLElement;
|
||||
if (where === 'afterend') {
|
||||
p.childNodes.forEach((n) => {
|
||||
(this.parentNode as HTMLElement).appendChild(n);
|
||||
});
|
||||
} else if (where === 'afterbegin') {
|
||||
this.childNodes.unshift(...p.childNodes);
|
||||
} else if (where === 'beforeend') {
|
||||
p.childNodes.forEach((n) => {
|
||||
this.appendChild(n);
|
||||
});
|
||||
} else if (where === 'beforebegin') {
|
||||
(this.parentNode as HTMLElement).childNodes.unshift(...p.childNodes);
|
||||
} else {
|
||||
throw new Error(`The value provided ('${where}') is not one of 'beforebegin', 'afterbegin', 'beforeend', or 'afterend'`);
|
||||
}
|
||||
if (!where || html === undefined || html === null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
52
test/html.js
52
test/html.js
|
|
@ -416,11 +416,13 @@ describe('HTML Parser', function () {
|
|||
});
|
||||
|
||||
describe('#hasAttribute', function () {
|
||||
var root = parseHTML('<input required>');
|
||||
var input = root.firstChild;
|
||||
input.hasAttribute('required').should.eql(true);
|
||||
input.removeAttribute('required');
|
||||
input.hasAttribute('required').should.eql(false);
|
||||
it('should return true or false when has or has not some attribute', function () {
|
||||
var root = parseHTML('<input required>');
|
||||
var input = root.firstChild;
|
||||
input.hasAttribute('required').should.eql(true);
|
||||
input.removeAttribute('required');
|
||||
input.hasAttribute('required').should.eql(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('#querySelector()', function () {
|
||||
|
|
@ -514,6 +516,46 @@ describe('HTML Parser', function () {
|
|||
root.firstChild.rawAttributes.alt.should.eql('«Sogno');
|
||||
});
|
||||
});
|
||||
|
||||
describe('#insertAdjacentHTML() should parse and insert childrens', function () {
|
||||
it('shoud insert children after current node', function () {
|
||||
const html = '<a><b></b></a>';
|
||||
const root = parseHTML(html);
|
||||
const a = root.firstChild;
|
||||
const b = a.firstChild;
|
||||
b.insertAdjacentHTML('afterend', '<c><d></d></c>');
|
||||
a.toString().should.eql('<a><b></b><c><d></d></c></a>');
|
||||
});
|
||||
|
||||
it('shoud insert children before current node', function () {
|
||||
const html = '<a><b></b></a>';
|
||||
const root = parseHTML(html);
|
||||
const a = root.firstChild;
|
||||
const b = a.firstChild;
|
||||
b.insertAdjacentHTML('beforebegin', '<c></c>');
|
||||
a.toString().should.eql('<a><c></c><b></b></a>');
|
||||
});
|
||||
|
||||
it('shoud append children in current node', function () {
|
||||
const html = '<a></a>';
|
||||
const root = parseHTML(html);
|
||||
const a = root.firstChild;
|
||||
a.insertAdjacentHTML('beforeend', '<b></b>');
|
||||
a.toString().should.eql('<a><b></b></a>');
|
||||
a.insertAdjacentHTML('beforeend', '<c></c>');
|
||||
a.toString().should.eql('<a><b></b><c></c></a>');
|
||||
});
|
||||
|
||||
it('shoud insert children at position 0', function () {
|
||||
const html = '<a></a>';
|
||||
const root = parseHTML(html);
|
||||
const a = root.firstChild;
|
||||
a.insertAdjacentHTML('afterbegin', '<b></b>');
|
||||
a.toString().should.eql('<a><b></b></a>');
|
||||
a.insertAdjacentHTML('afterbegin', '<c></c>');
|
||||
a.toString().should.eql('<a><c></c><b></b></a>');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('stringify', function () {
|
||||
|
|
|
|||
Loading…
Reference in a new issue