🐛 issue #17

This commit is contained in:
taoqf 2020-02-06 11:36:32 +08:00
parent b27963930c
commit 193a685766
2 changed files with 86 additions and 24 deletions

View file

@ -431,37 +431,55 @@ export default class HTMLElement extends Node {
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
* @return {string} value of the attribute
*/
getAttribute(key: string) {
return this.attributes[key] || null;
public getAttribute(key: string) {
return this.attributes[key];
}
/**
* Set an attribute value to the HTMLElement
* @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) {
if (arguments.length < 2) {
throw new Error('Failed to execute \'setAttribute\' on \'Element\'');
}
const attrs = this.rawAttributes;
if (value === undefined || value === null) {
delete attrs[key];
// Update this.attribute
if (this._attrs && this._attrs[key]) {
delete this._attrs[key];
}
} else {
attrs[key] = String(value);
if (this._attrs) {
this._attrs[key] = decode(attrs[key]);
}
attrs[key] = String(value);
if (this._attrs) {
this._attrs[key] = decode(attrs[key]);
}
// Update rawString
this.rawAttrs = Object.keys(attrs).map((name) => {
const val = JSON.stringify(attrs[name]);
if (val === undefined || val === null) {
if (val === undefined || val === 'null') {
return name;
} else {
return name + '=' + val;
@ -473,7 +491,7 @@ export default class HTMLElement extends Node {
* Replace all the attributes of the HTMLElement by the provided attributes
* @param {Attributes} attributes the new attribute set
*/
setAttributes(attributes: Attributes) {
public setAttributes(attributes: Attributes) {
// Invalidate current this.attributes
if (this._attrs) {
delete this._attrs;

View file

@ -329,6 +329,19 @@ describe('HTML Parser', function () {
var root = parseHTML('<p></p>');
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 () {
@ -351,14 +364,20 @@ describe('HTML Parser', function () {
});
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>');
root.firstChild.setAttribute('b', null);
root.firstChild.setAttribute('c');
root.firstChild.attributes.should.eql({
'a': '12',
});
root.firstChild.toString().should.eql('<p a="12"></p>');
var p = root.firstChild;
p.setAttribute('b', null);
p.setAttribute('c', undefined);
p.getAttribute('b').should.eql('null');
p.getAttribute('c').should.eql('undefined');
p.toString().should.eql('<p a="12" b="null" c="undefined"></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 () {
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 () {
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>');
@ -469,6 +503,16 @@ describe('HTML Parser', function () {
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&#39;Amico: &laquo;Sogno una bambina. Buffon mi ha chiesto in moglie tante volte&raquo;">');
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', '&laquo;Sogno');
root.firstChild.getAttribute('alt').should.eql('«Sogno');
});
});
});
describe('stringify', function () {