Skip to content

Commit

Permalink
support $$props and $$restProps for custom elements
Browse files Browse the repository at this point in the history
  • Loading branch information
tanhauhau committed Oct 28, 2020
1 parent 65104e8 commit 6469f9d
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 1 deletion.
2 changes: 1 addition & 1 deletion src/compiler/compile/render_dom/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -474,7 +474,7 @@ export default function dom(
${css.code && b`this.shadowRoot.innerHTML = \`<style>${css.code.replace(/\\/g, '\\\\')}${options.dev ? `\n/*# sourceMappingURL=${css.map.toUrl()} */` : ''}</style>\`;`}
@init(this, { target: this.shadowRoot }, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_indexes}, ${dirty});
@init(this, { target: this.shadowRoot, props: @attribute_to_object(this.attributes) }, ${definition}, ${has_create_fragment ? 'create_fragment': 'null'}, ${not_equal}, ${prop_indexes}, ${dirty});
${dev_props_check}
Expand Down
8 changes: 8 additions & 0 deletions src/runtime/internal/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -360,3 +360,11 @@ export class HtmlTag {
this.n.forEach(detach);
}
}

export function attribute_to_object(attributes) {
const result = {};
for (const attribute of attributes) {
result[attribute.name] = attribute.value;
}
return result;
}
21 changes: 21 additions & 0 deletions test/custom-elements/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,24 @@ export function equal(a, b, message) {
export function ok(condition, message) {
if (!condition) throw new Error(message || `Expected ${condition} to be truthy`);
}

export function htmlEqual(actual, expected, message) {
return deepEqual(
normalizeHtml(window, actual),
normalizeHtml(window, expected),
message
);
}

function normalizeHtml(window, html) {
try {
const node = window.document.createElement('div');
node.innerHTML = html
.replace(/<!--.*?-->/g, '')
.replace(/>[\s\r\n]+</g, '><')
.trim();
return node.innerHTML.replace(/<\/?noscript\/?>/g, '');
} catch (err) {
throw new Error(`Failed to normalize HTML:\n${html}`);
}
}
10 changes: 10 additions & 0 deletions test/custom-elements/samples/$$props/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<svelte:options tag="custom-element"/>

<script>
export let name;
</script>

<p>name: {name}</p>
<p>$$props: {JSON.stringify($$props)}</p>
<p>$$restProps: {JSON.stringify($$restProps)}</p>

13 changes: 13 additions & 0 deletions test/custom-elements/samples/$$props/test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import * as assert from 'assert';
import './main.svelte';

export default function (target) {
target.innerHTML = '<custom-element name="world" answer="42" test="svelte"></custom-element>';
const el = target.querySelector('custom-element');

assert.htmlEqual(el.shadowRoot.innerHTML, `
<p>name: world</p>
<p>$$props: {"name":"world","answer":"42","test":"svelte"}</p>
<p>$$restProps: {"answer":"42","test":"svelte"}</p>
`);
}

0 comments on commit 6469f9d

Please sign in to comment.