mirror of
https://github.com/danbulant/node-html-parser
synced 2026-05-24 12:35:10 +00:00
🐛 issue #17
This commit is contained in:
parent
b27963930c
commit
193a685766
2 changed files with 86 additions and 24 deletions
|
|
@ -431,37 +431,55 @@ export default class HTMLElement extends Node {
|
||||||
return attrs;
|
return attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public removeAttribute(key: string) {
|
||||||
|
const attrs = this.rawAttributes;
|
||||||
|
delete attrs[key];
|
||||||
|
// Update this.attribute
|
||||||
|
if (this._attrs) {
|
||||||
|
delete this._attrs[key];
|
||||||
|
}
|
||||||
|
// Update rawString
|
||||||
|
this.rawAttrs = Object.keys(attrs).map((name) => {
|
||||||
|
const val = JSON.stringify(attrs[name]);
|
||||||
|
if (val === undefined || val === 'null') {
|
||||||
|
return name;
|
||||||
|
} else {
|
||||||
|
return name + '=' + val;
|
||||||
|
}
|
||||||
|
}).join(' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
public hasAttribute(key: string) {
|
||||||
|
console.error(this.attributes, key);
|
||||||
|
return key in this.attributes;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an attribute
|
* Get an attribute
|
||||||
* @return {string} value of the attribute
|
* @return {string} value of the attribute
|
||||||
*/
|
*/
|
||||||
getAttribute(key: string) {
|
public getAttribute(key: string) {
|
||||||
return this.attributes[key] || null;
|
return this.attributes[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set an attribute value to the HTMLElement
|
* Set an attribute value to the HTMLElement
|
||||||
* @param {string} key The attribute name
|
* @param {string} key The attribute name
|
||||||
* @param {string|number} value The value to set, or null / undefined to remove an attribute
|
* @param {string} value The value to set, or null / undefined to remove an attribute
|
||||||
*/
|
*/
|
||||||
setAttribute(key: string, value: string | number) {
|
public setAttribute(key: string, value: string) {
|
||||||
const attrs = this.rawAttributes;
|
if (arguments.length < 2) {
|
||||||
if (value === undefined || value === null) {
|
throw new Error('Failed to execute \'setAttribute\' on \'Element\'');
|
||||||
delete attrs[key];
|
|
||||||
// Update this.attribute
|
|
||||||
if (this._attrs && this._attrs[key]) {
|
|
||||||
delete this._attrs[key];
|
|
||||||
}
|
}
|
||||||
} else {
|
const attrs = this.rawAttributes;
|
||||||
attrs[key] = String(value);
|
attrs[key] = String(value);
|
||||||
if (this._attrs) {
|
if (this._attrs) {
|
||||||
this._attrs[key] = decode(attrs[key]);
|
this._attrs[key] = decode(attrs[key]);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// Update rawString
|
// Update rawString
|
||||||
this.rawAttrs = Object.keys(attrs).map((name) => {
|
this.rawAttrs = Object.keys(attrs).map((name) => {
|
||||||
const val = JSON.stringify(attrs[name]);
|
const val = JSON.stringify(attrs[name]);
|
||||||
if (val === undefined || val === null) {
|
if (val === undefined || val === 'null') {
|
||||||
return name;
|
return name;
|
||||||
} else {
|
} else {
|
||||||
return name + '=' + val;
|
return name + '=' + val;
|
||||||
|
|
@ -473,7 +491,7 @@ export default class HTMLElement extends Node {
|
||||||
* Replace all the attributes of the HTMLElement by the provided attributes
|
* Replace all the attributes of the HTMLElement by the provided attributes
|
||||||
* @param {Attributes} attributes the new attribute set
|
* @param {Attributes} attributes the new attribute set
|
||||||
*/
|
*/
|
||||||
setAttributes(attributes: Attributes) {
|
public setAttributes(attributes: Attributes) {
|
||||||
// Invalidate current this.attributes
|
// Invalidate current this.attributes
|
||||||
if (this._attrs) {
|
if (this._attrs) {
|
||||||
delete this._attrs;
|
delete this._attrs;
|
||||||
|
|
|
||||||
56
test/html.js
56
test/html.js
|
|
@ -329,6 +329,19 @@ describe('HTML Parser', function () {
|
||||||
var root = parseHTML('<p></p>');
|
var root = parseHTML('<p></p>');
|
||||||
should.equal(root.firstChild.getAttribute('b'), null);
|
should.equal(root.firstChild.getAttribute('b'), null);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should return empty string as broser behavior', function () {
|
||||||
|
var root = parseHTML('<input required>');
|
||||||
|
var input = root.firstChild;
|
||||||
|
input.getAttribute('required').should.eql('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return null as broser behavior', function () {
|
||||||
|
var root = parseHTML('<input required>');
|
||||||
|
var input = root.firstChild;
|
||||||
|
input.setAttribute('readonly', null);
|
||||||
|
input.getAttribute('readonly').should.eql('null');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#setAttribute', function () {
|
describe('#setAttribute', function () {
|
||||||
|
|
@ -351,14 +364,20 @@ describe('HTML Parser', function () {
|
||||||
});
|
});
|
||||||
root.firstChild.toString().should.eql('<p a="12" b="13"></p>');
|
root.firstChild.toString().should.eql('<p a="12" b="13"></p>');
|
||||||
});
|
});
|
||||||
it('should remove an attribute from the element', function () {
|
it('should convert value to string', function () {
|
||||||
var root = parseHTML('<p a=12 b=13 c=14></p>');
|
var root = parseHTML('<p a=12 b=13 c=14></p>');
|
||||||
root.firstChild.setAttribute('b', null);
|
var p = root.firstChild;
|
||||||
root.firstChild.setAttribute('c');
|
p.setAttribute('b', null);
|
||||||
root.firstChild.attributes.should.eql({
|
p.setAttribute('c', undefined);
|
||||||
'a': '12',
|
p.getAttribute('b').should.eql('null');
|
||||||
|
p.getAttribute('c').should.eql('undefined');
|
||||||
|
p.toString().should.eql('<p a="12" b="null" c="undefined"></p>');
|
||||||
});
|
});
|
||||||
root.firstChild.toString().should.eql('<p a="12"></p>');
|
it('should throw type Error', function () {
|
||||||
|
var root = parseHTML('<p a=12 b=13 c=14></p>');
|
||||||
|
var p = root.firstChild;
|
||||||
|
should.throws(function () { p.setAttribute('b') });
|
||||||
|
should.throws(function () { p.setAttribute() });
|
||||||
});
|
});
|
||||||
it('should keep quotes arount value', function () {
|
it('should keep quotes arount value', function () {
|
||||||
var root = parseHTML('<p a="12"></p>');
|
var root = parseHTML('<p a="12"></p>');
|
||||||
|
|
@ -389,6 +408,21 @@ describe('HTML Parser', function () {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('#removeAttribute', function () {
|
||||||
|
var root = parseHTML('<input required>');
|
||||||
|
var input = root.firstChild;
|
||||||
|
input.removeAttribute('required');
|
||||||
|
input.toString().should.eql('<input />');
|
||||||
|
});
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
describe('#querySelector()', function () {
|
describe('#querySelector()', function () {
|
||||||
it('should return correct elements in DOM tree', function () {
|
it('should return correct elements in DOM tree', function () {
|
||||||
var root = parseHTML('<a id="id" data-id="myid"><div><span class="a b"></span><span></span><span></span></div></a>');
|
var root = parseHTML('<a id="id" data-id="myid"><div><span class="a b"></span><span></span><span></span></div></a>');
|
||||||
|
|
@ -469,6 +503,16 @@ describe('HTML Parser', function () {
|
||||||
root.toString().should.eql('<div>abc</div>');
|
root.toString().should.eql('<div>abc</div>');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('encode/decode', function () {
|
||||||
|
it('should decode attributes value', function () {
|
||||||
|
var root = parseHTML('<img src="default.jpg" alt="Verissimo, Ilaria D'Amico: «Sogno una bambina. Buffon mi ha chiesto in moglie tante volte»">');
|
||||||
|
root.firstChild.getAttribute('alt').should.eql(`Verissimo, Ilaria D'Amico: «Sogno una bambina. Buffon mi ha chiesto in moglie tante volte»`);
|
||||||
|
root.firstChild.attributes.alt.should.eql(`Verissimo, Ilaria D'Amico: «Sogno una bambina. Buffon mi ha chiesto in moglie tante volte»`);
|
||||||
|
root.firstChild.setAttribute('alt', '«Sogno');
|
||||||
|
root.firstChild.getAttribute('alt').should.eql('«Sogno');
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('stringify', function () {
|
describe('stringify', function () {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue