From cce3a30ef2ed37a905b07a8da1e92dd920fe0df1 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 5 Aug 2018 13:44:29 -0400 Subject: [PATCH 1/2] use props when passing data to custom elements (#875) --- src/compile/nodes/Attribute.ts | 8 ++++--- src/shared/dom.js | 10 ++++++++ test/custom-elements/samples/props/main.html | 15 ++++++++++++ .../samples/props/my-widget.html | 9 ++++++++ test/custom-elements/samples/props/test.js | 23 +++++++++++++++++++ 5 files changed, 62 insertions(+), 3 deletions(-) create mode 100644 test/custom-elements/samples/props/main.html create mode 100644 test/custom-elements/samples/props/my-widget.html create mode 100644 test/custom-elements/samples/props/test.js diff --git a/src/compile/nodes/Attribute.ts b/src/compile/nodes/Attribute.ts index 53996469e910..0165dc98fb81 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 03aaf8aaeb39..3b823cfaae93 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 000000000000..db8465591e1c --- /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 000000000000..e5b0e723e8f4 --- /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 000000000000..1e95fe3ad281 --- /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 From b26ee1c3bb385f0d0c23a3a3c3c27e3b413ba285 Mon Sep 17 00:00:00 2001 From: Rich Harris Date: Sun, 5 Aug 2018 14:00:47 -0400 Subject: [PATCH 2/2] tweak test --- test/custom-elements/samples/props/my-widget.html | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/test/custom-elements/samples/props/my-widget.html b/test/custom-elements/samples/props/my-widget.html index e5b0e723e8f4..b4ed9b38a6b2 100644 --- a/test/custom-elements/samples/props/my-widget.html +++ b/test/custom-elements/samples/props/my-widget.html @@ -1,9 +1,14 @@ -

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

-

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

-

{JSON.stringify(items)}

+

{items.length} items

+

{items.join(', ')}

\ No newline at end of file