diff --git a/src/instance/attributes.js b/src/instance/attributes.js index 7d63567010..1ef6ae6d36 100644 --- a/src/instance/attributes.js +++ b/src/instance/attributes.js @@ -62,24 +62,30 @@ deserializeValue: function(stringValue, defaultValue) { return scope.deserializeValue(stringValue, defaultValue); }, - serializeValue: function(value) { - if (typeof value != 'object' && value !== undefined) { + serializeValue: function(value, inferredType) { + if (inferredType === 'boolean') { + return value ? '' : undefined; + } else if (inferredType !== 'object' && typeof value !== 'object' && + value !== undefined) { return value; } }, propertyToAttribute: function(name) { if (Object.keys(this[PUBLISHED]).indexOf(name) >= 0) { - var serializedValue = this.serializeValue(this[name]); + var inferredType = typeof this.__proto__[name]; + var serializedValue = this.serializeValue(this[name], inferredType); // boolean properties must reflect as boolean attributes - if (typeof this.__proto__[name] === 'boolean') { - if (serializedValue) { - this.setAttribute(name, ''); - } else { - this.removeAttribute(name); - } - } else if (serializedValue !== undefined) { + if (serializedValue !== undefined) { this.setAttribute(name, serializedValue); + // TODO(sorvell): we should remove attr for all properties + // that have undefined serialization; however, we will need to + // refine the attr reflection system to achieve this; pica, for example, + // relies on having inferredType object properties not removed as + // attrs. + } else if (inferredType === 'boolean') { + this.removeAttribute(name); } + } } }; diff --git a/test/html/prop-attr-reflection.html b/test/html/prop-attr-reflection.html index 7f17f342e9..84cffd44d0 100644 --- a/test/html/prop-attr-reflection.html +++ b/test/html/prop-attr-reflection.html @@ -11,7 +11,10 @@ @@ -69,12 +72,12 @@ Platform.endOfMicrotask(function() { assert.equal(xbar.foo, xbar.getAttribute('foo'), 'inherited published property is reflected'); assert.equal(String(xbar.zot), xbar.getAttribute('zot'), 'attribute reflects property as number'); - assert.equal('', xbar.getAttribute('zim'), 'attribute reflects true valued boolean property as having attribute'); + assert.equal(xbar.getAttribute('zim'), '', 'attribute reflects true valued boolean property as having attribute'); assert.equal(xbar.str, xbar.getAttribute('str'), 'attribute reflects property as published string'); assert.isFalse(xbar.hasAttribute('obj'), 'attribute does not reflect object property'); + xbar.setAttribute('zim', 'false'); xbar.setAttribute('foo', 'foo!!'); xbar.setAttribute('zot', 54); - xbar.setAttribute('zim', 'false'); xbar.setAttribute('str', 'str!!'); xbar.setAttribute('obj', "{'hello': 'world'}"); assert.equal(xbar.foo, xbar.getAttribute('foo'), 'property reflects attribute as string'); @@ -86,7 +89,13 @@ Platform.flush(); Platform.endOfMicrotask(function() { assert.isFalse(xbar.hasAttribute('zim'), 'attribute reflects false valued boolean property as NOT having attribute'); - done(); + var objAttr = xbar.getAttribute('obj'); + xbar.obj = 'hi'; + Platform.endOfMicrotask(function() { + assert.equal(xbar.getAttribute('obj'), objAttr, 'do not reflect property with default type of object'); + //assert.isFalse(xbar.hasAttribute('obj'), 'property with default type of object does not serialize'); + done(); + }); }); }); });