diff --git a/src/compile/nodes/Attribute.ts b/src/compile/nodes/Attribute.ts index 53996469e9..0165dc98fb 100644 --- a/src/compile/nodes/Attribute.ts +++ b/src/compile/nodes/Attribute.ts @@ -130,9 +130,11 @@ export default class Attribute extends Node { // xlink is a special case... we could maybe extend this to generic // namespaced attributes but I'm not sure that's applicable in // HTML5? - const method = name.slice(0, 6) === 'xlink:' - ? '@setXlinkAttribute' - : '@setAttribute'; + const method = /-/.test(node.name) + ? '@setCustomElementData' + : name.slice(0, 6) === 'xlink:' + ? '@setXlinkAttribute' + : '@setAttribute'; const isLegacyInputType = this.compiler.options.legacy && name === 'type' && this.parent.name === 'input'; diff --git a/src/shared/dom.js b/src/shared/dom.js index 03aaf8aaeb..3b823cfaae 100644 --- a/src/shared/dom.js +++ b/src/shared/dom.js @@ -96,6 +96,16 @@ export function setAttributes(node, attributes) { } } +export function setCustomElementData(node, prop, value) { + if (prop in node) { + node[prop] = value; + } else if (value) { + setAttribute(node, prop, value); + } else { + removeAttribute(node, prop); + } +} + export function removeAttribute(node, attribute) { node.removeAttribute(attribute); } diff --git a/test/custom-elements/samples/props/main.html b/test/custom-elements/samples/props/main.html new file mode 100644 index 0000000000..db8465591e --- /dev/null +++ b/test/custom-elements/samples/props/main.html @@ -0,0 +1,15 @@ + + + \ No newline at end of file diff --git a/test/custom-elements/samples/props/my-widget.html b/test/custom-elements/samples/props/my-widget.html new file mode 100644 index 0000000000..e5b0e723e8 --- /dev/null +++ b/test/custom-elements/samples/props/my-widget.html @@ -0,0 +1,9 @@ +

{(items || []).length} items

+

{(items || []).join(', ')}

+

{JSON.stringify(items)}

+ + \ No newline at end of file diff --git a/test/custom-elements/samples/props/test.js b/test/custom-elements/samples/props/test.js new file mode 100644 index 0000000000..1e95fe3ad2 --- /dev/null +++ b/test/custom-elements/samples/props/test.js @@ -0,0 +1,23 @@ +import * as assert from 'assert'; +import CustomElement from './main.html'; + +export default function (target) { + new CustomElement({ + target + }); + + assert.equal(target.innerHTML, ''); + + const el = target.querySelector('custom-element'); + const widget = el.shadowRoot.querySelector('my-widget'); + + const [p1, p2] = widget.shadowRoot.querySelectorAll('p'); + + assert.equal(p1.textContent, '3 items'); + assert.equal(p2.textContent, 'a, b, c'); + + el.items = ['d', 'e', 'f', 'g', 'h']; + + assert.equal(p1.textContent, '5 items'); + assert.equal(p2.textContent, 'd, e, f, g, h'); +} \ No newline at end of file