diff --git a/render/render.js b/render/render.js index 8d9bd366..731ebdf3 100644 --- a/render/render.js +++ b/render/render.js @@ -435,14 +435,14 @@ module.exports = function($window) { } function setAttr(vnode, key, old, value, ns) { var element = vnode.dom - if (key === "key" || (old === value && !isFormAttribute(vnode, key)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key)) return + if (key === "key" || key === "is" || (old === value && !isFormAttribute(vnode, key)) && typeof value !== "object" || typeof value === "undefined" || isLifecycleMethod(key)) return var nsLastIndex = key.indexOf(":") if (nsLastIndex > -1 && key.substr(0, nsLastIndex) === "xlink") { element.setAttributeNS("http://www.w3.org/1999/xlink", key.slice(nsLastIndex + 1), value) } else if (key[0] === "o" && key[1] === "n" && typeof value === "function") updateEvent(vnode, key, value) else if (key === "style") updateStyle(element, old, value) - else if (key in element && !isAttribute(key) && ns === undefined) { + else if (key in element && !isAttribute(key) && ns === undefined && !isCustomElement(vnode)) { //setting input[value] to same value by typing on focused element moves cursor to end in Chrome if (vnode.tag === "input" && key === "value" && vnode.dom.value === value && vnode.dom === $doc.activeElement) return //setting select[value] to same value while having select open blinks select dropdown in Chrome @@ -491,6 +491,9 @@ module.exports = function($window) { function isAttribute(attr) { return attr === "href" || attr === "list" || attr === "form" || attr === "width" || attr === "height"// || attr === "type" } + function isCustomElement(vnode){ + return vnode.attrs.is || vnode.tag.indexOf("-") > -1 + } function hasIntegrationMethods(source) { return source != null && (source.oncreate || source.onupdate || source.onbeforeremove || source.onremove) } diff --git a/render/tests/test-attributes.js b/render/tests/test-attributes.js index 73cbd685..2d08007b 100644 --- a/render/tests/test-attributes.js +++ b/render/tests/test-attributes.js @@ -11,7 +11,43 @@ o.spec("attributes", function() { root = $window.document.body render = vdom($window).render }) + o.spec("customElements", function(){ + + o("when vnode is customElement, custom setAttribute called", function(){ + var normal = [ + { tag: "input", attrs: { value: 'hello' } }, + { tag: "input", attrs: { value: 'hello' } }, + { tag: "input", attrs: { value: 'hello' } } + ] + + var custom = [ + { tag: "custom-element", attrs: { custom: 'x' } }, + { tag: "input", attrs: { is: 'something-special', custom: 'x' } }, + { tag: "custom-element", attrs: { is: 'something-special', custom: 'x' } } + ] + + var view = normal.concat(custom) + + var f = $window.document.createElement + var spy + + $window.document.createElement = function(tag, is){ + var el = f(tag, is) + if(!spy){ + spy = o.spy(el.setAttribute) + } + el.setAttribute = spy + + return el + } + + render(root, view) + + o(spy.callCount).equals( custom.length ) + }) + + }) o.spec("input readonly", function() { o("when input readonly is true, attribute is present", function() { var a = {tag: "input", attrs: {readonly: true}}