diff --git a/.gitignore b/.gitignore index f285cb6..217a554 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,6 @@ bower_components *.sublime-* dist/ yarn.lock + +.idea +.DS_Store diff --git a/src/nodes/html.ts b/src/nodes/html.ts index d9210aa..2972f35 100644 --- a/src/nodes/html.ts +++ b/src/nodes/html.ts @@ -407,7 +407,7 @@ export default class HTMLElement extends Node { const attrs = this.rawAttributes; for (const key in attrs) { const val = attrs[key] || ''; - this._attrs[key] = decode(val.replace(/^['"]/, '').replace(/['"]$/, '')); + this._attrs[key] = decode(val); } return this._attrs; } @@ -421,40 +421,43 @@ export default class HTMLElement extends Node { return this._rawAttrs; const attrs = {} as RawAttributes; if (this.rawAttrs) { - const re = /\b([a-z][a-z0-9\-]*)(?:\s*=\s*("(?:[^"]*)"|'(?:[^']*)'|(?:\S+)))?/ig; + const re = /\b([a-z][a-z0-9\-]*)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|(\S+)))?/ig; let match: RegExpExecArray; while (match = re.exec(this.rawAttrs)) { - attrs[match[1]] = match[2] || null; + attrs[match[1]] = match[2] || match[3] || match[4] || null; } } this._rawAttrs = attrs; return attrs; } + /** + * Get an attribute + * @return {string} value of the attribute + */ + getAttribute(key: string) { + return this.attributes[key] || null; + } + /** * 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 */ setAttribute(key: string, value: string | number) { - // Update the this.attributes + // Invalidate current this.attributes if (this._attrs) { delete this._attrs; } - const attrs = this.rawAttributes; // ref this._rawAttrs + const attrs = this.rawAttributes; if (value === undefined || value === null) { delete attrs[key]; } else { - attrs[key] = JSON.stringify(value); - // if (typeof value === 'string') { - // attrs[key] = JSON.stringify(encode(value));//??? should we encode value here? - // } else { - // attrs[key] = JSON.stringify(value); - // } + attrs[key] = String(value); } // Update rawString this.rawAttrs = Object.keys(attrs).map((name) => { - const val = attrs[name]; + const val = JSON.stringify(attrs[name]); if (val === undefined || val === null) { return name; } else { @@ -468,11 +471,11 @@ export default class HTMLElement extends Node { * @param {Attributes} attributes the new attribute set */ setAttributes(attributes: Attributes) { - // Update the this.attributes + // Invalidate current this.attributes if (this._attrs) { delete this._attrs; } - // Update the raw attributes map + // Invalidate current this.rawAttributes if (this._rawAttrs) { delete this._rawAttrs; } @@ -482,12 +485,7 @@ export default class HTMLElement extends Node { if (val === undefined || val === null) { return name; } else { - return name + '=' + JSON.stringify(val); - // if (typeof val === 'string') { - // return name + '=' + JSON.stringify(encode(val)); //??? should we encode value here? - // } else { - // return name + '=' + JSON.stringify(val); - // } + return name + '=' + JSON.stringify(String(val)); } }).join(' '); } diff --git a/test/html.js b/test/html.js index efa1597..b5b0c7c 100644 --- a/test/html.js +++ b/test/html.js @@ -300,8 +300,8 @@ describe('HTML Parser', function () { var root = parseHTML('

'); root.firstChild.rawAttributes.should.eql({ 'a': '12', - 'data-id': '"!$$&"', - 'yAz': '\'1\'' + 'data-id': '!$$&', + 'yAz': '1' }); }); }); @@ -319,6 +319,18 @@ describe('HTML Parser', function () { }); }); + describe('#getAttribute', function () { + it('should return value of the attribute', function () { + var root = parseHTML('

'); + root.firstChild.getAttribute('a').should.eql('a1b'); + }); + + it('should return null when there is no such attribute', function () { + var root = parseHTML('

'); + should.equal(root.firstChild.getAttribute('b'), null); + }); + }); + describe('#setAttribute', function () { it('should edit the attributes of the element', function () { var root = parseHTML('

'); @@ -326,7 +338,7 @@ describe('HTML Parser', function () { root.firstChild.attributes.should.eql({ 'a': '13', }); - root.firstChild.toString().should.eql('

'); + root.firstChild.toString().should.eql('

'); }); it('should add an attribute to the element', function () { var root = parseHTML('

'); @@ -335,7 +347,7 @@ describe('HTML Parser', function () { 'a': '12', 'b': '13', }); - root.firstChild.toString().should.eql('

'); + root.firstChild.toString().should.eql('

'); }); it('should remove an attribute from the element', function () { var root = parseHTML('

'); @@ -344,7 +356,7 @@ describe('HTML Parser', function () { root.firstChild.attributes.should.eql({ 'a': '12', }); - root.firstChild.toString().should.eql('

'); + root.firstChild.toString().should.eql('

'); }); it('should keep quotes arount value', function () { var root = parseHTML('

'); @@ -355,7 +367,7 @@ describe('HTML Parser', function () { 'b': '13', 'c': '2' }); - root.firstChild.toString().should.eql('

'); + root.firstChild.toString().should.eql('

'); }); }); @@ -370,7 +382,7 @@ describe('HTML Parser', function () { 'c': '12', d: '&&<>foo' }); - root.firstChild.toString().should.eql('

'); + root.firstChild.toString().should.eql('

'); // root.firstChild.toString().should.eql('

'); }); });