diff --git a/src/compile/nodes/Element.ts b/src/compile/nodes/Element.ts
index ac2b81b3e7..2b76d68e6d 100644
--- a/src/compile/nodes/Element.ts
+++ b/src/compile/nodes/Element.ts
@@ -544,7 +544,7 @@ export default class Element extends Node {
message: `'group' binding can only be used with or `
});
}
- } else if (name == 'files') {
+ } else if (name === 'files') {
if (this.name !== 'input') {
component.error(binding, {
code: `invalid-binding`,
@@ -560,6 +560,14 @@ export default class Element extends Node {
message: `'files' binding can only be used with `
});
}
+
+ } else if (name === 'open') {
+ if (this.name !== 'details') {
+ component.error(binding, {
+ code: `invalid-binding`,
+ message: `'${name}' binding can only be used with `
+ });
+ }
} else if (
name === 'currentTime' ||
name === 'duration' ||
diff --git a/src/compile/render-dom/wrappers/Element/index.ts b/src/compile/render-dom/wrappers/Element/index.ts
index 22ea7a78cd..ad85a46db3 100644
--- a/src/compile/render-dom/wrappers/Element/index.ts
+++ b/src/compile/render-dom/wrappers/Element/index.ts
@@ -91,6 +91,12 @@ const events = [
name === 'playbackRate'
},
+ // details event
+ {
+ event_names: ['toggle'],
+ filter: (node: Element, name: string) =>
+ node.name === 'details'
+ },
];
export default class ElementWrapper extends Wrapper {
diff --git a/test/js/samples/bind-open/expected.js b/test/js/samples/bind-open/expected.js
new file mode 100644
index 0000000000..7c73c8ddac
--- /dev/null
+++ b/test/js/samples/bind-open/expected.js
@@ -0,0 +1,69 @@
+/* generated by Svelte vX.Y.Z */
+import {
+ SvelteComponent,
+ detach,
+ element,
+ init,
+ insert,
+ listen,
+ noop,
+ safe_not_equal
+} from "svelte/internal";
+
+function create_fragment(ctx) {
+ var details, dispose;
+
+ return {
+ c() {
+ details = element("details");
+ details.innerHTML = `summary
content
+ `;
+ dispose = listen(details, "toggle", ctx.details_toggle_handler);
+ },
+
+ m(target, anchor) {
+ insert(target, details, anchor);
+
+ details.open = ctx.open;
+ },
+
+ p(changed, ctx) {
+ if (changed.open) details.open = ctx.open;
+ },
+
+ i: noop,
+ o: noop,
+
+ d(detaching) {
+ if (detaching) {
+ detach(details);
+ }
+
+ dispose();
+ }
+ };
+}
+
+function instance($$self, $$props, $$invalidate) {
+ let { open } = $$props;
+
+ function details_toggle_handler() {
+ open = this.open;
+ $$invalidate('open', open);
+ }
+
+ $$self.$set = $$props => {
+ if ('open' in $$props) $$invalidate('open', open = $$props.open);
+ };
+
+ return { open, details_toggle_handler };
+}
+
+class Component extends SvelteComponent {
+ constructor(options) {
+ super();
+ init(this, options, instance, create_fragment, safe_not_equal, ["open"]);
+ }
+}
+
+export default Component;
diff --git a/test/js/samples/bind-open/input.svelte b/test/js/samples/bind-open/input.svelte
new file mode 100644
index 0000000000..3dd2b03a73
--- /dev/null
+++ b/test/js/samples/bind-open/input.svelte
@@ -0,0 +1,7 @@
+
+
+
+ summary
content
+
diff --git a/test/runtime/samples/binding-details-open/_config.js b/test/runtime/samples/binding-details-open/_config.js
new file mode 100644
index 0000000000..e5e81b2c93
--- /dev/null
+++ b/test/runtime/samples/binding-details-open/_config.js
@@ -0,0 +1,25 @@
+export default {
+ html: `
+ toggle
+ `,
+
+ async test({ assert, component, target, window }) {
+ const details = target.querySelector('details');
+ const event = new window.Event('toggle');
+
+ details.open = true;
+ await details.dispatchEvent(event);
+ assert.equal(component.open, true);
+ assert.htmlEqual(target.innerHTML, `
+ toggle
+ hello!
+ `);
+
+ details.open = false;
+ await details.dispatchEvent(event);
+ assert.equal(component.open, false);
+ assert.htmlEqual(target.innerHTML, `
+ toggle
+ `);
+ }
+};
diff --git a/test/runtime/samples/binding-details-open/main.svelte b/test/runtime/samples/binding-details-open/main.svelte
new file mode 100644
index 0000000000..3a7a08e121
--- /dev/null
+++ b/test/runtime/samples/binding-details-open/main.svelte
@@ -0,0 +1,9 @@
+
+
+toggle
+
+{#if visible}
+ hello!
+{/if}