diff --git a/site/content/docs/02-template-syntax.md b/site/content/docs/02-template-syntax.md
index 070dc46687..769c6c0bf1 100644
--- a/site/content/docs/02-template-syntax.md
+++ b/site/content/docs/02-template-syntax.md
@@ -474,6 +474,7 @@ The following modifiers are available:
* `capture` — fires the handler during the *capture* phase instead of the *bubbling* phase
* `once` — remove the handler after the first time it runs
* `self` — only trigger handler if event.target is the element itself
+* `detail` — calls the handler with the event.detail value, instead of the event object.
Modifiers can be chained together, e.g. `on:click|once|capture={...}`.
diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts
index 7a70e603a7..ff5e291cc0 100644
--- a/src/compiler/compile/nodes/Element.ts
+++ b/src/compiler/compile/nodes/Element.ts
@@ -69,7 +69,8 @@ const valid_modifiers = new Set([
'capture',
'once',
'passive',
- 'self'
+ 'self',
+ 'detail'
]);
const passive_events = new Set([
diff --git a/src/compiler/compile/nodes/InlineComponent.ts b/src/compiler/compile/nodes/InlineComponent.ts
index 0bd1c9a6a7..b90ae635cb 100644
--- a/src/compiler/compile/nodes/InlineComponent.ts
+++ b/src/compiler/compile/nodes/InlineComponent.ts
@@ -102,10 +102,10 @@ export default class InlineComponent extends Node {
this.handlers.forEach(handler => {
handler.modifiers.forEach(modifier => {
- if (modifier !== 'once') {
+ if (['once', 'detail'].indexOf(modifier) === -1) {
component.error(handler, {
code: 'invalid-event-modifier',
- message: `Event modifiers other than 'once' can only be used on DOM elements`
+ message: `Event modifiers other than 'once' and 'detail' can only be used on DOM elements`
});
}
});
diff --git a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts
index 157e186ea6..90d16b2424 100644
--- a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts
+++ b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts
@@ -42,6 +42,7 @@ export default class EventHandlerWrapper {
if (this.node.modifiers.has('preventDefault')) snippet = x`@prevent_default(${snippet})`;
if (this.node.modifiers.has('stopPropagation')) snippet = x`@stop_propagation(${snippet})`;
if (this.node.modifiers.has('self')) snippet = x`@self(${snippet})`;
+ if (this.node.modifiers.has('detail')) snippet = x`@detail(${snippet})`;
const args = [];
diff --git a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts
index 271b3de1e1..0dbff646a4 100644
--- a/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts
+++ b/src/compiler/compile/render_dom/wrappers/InlineComponent/index.ts
@@ -391,6 +391,7 @@ export default class InlineComponentWrapper extends Wrapper {
const event_handler = new EventHandler(handler, this);
let snippet = event_handler.get_snippet(block);
if (handler.modifiers.has('once')) snippet = x`@once(${snippet})`;
+ if (handler.modifiers.has('detail')) snippet = x`@detail(${snippet})`;
return b`${name}.$on("${handler.name}", ${snippet});`;
});
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
index 0cd670fcb9..64343442da 100644
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -85,6 +85,13 @@ export function self(fn) {
};
}
+export function detail(fn) {
+ return function(event) {
+ // @ts-ignore
+ fn.call(this, event.detail);
+ };
+}
+
export function attr(node: Element, attribute: string, value?: string) {
if (value == null) node.removeAttribute(attribute);
else if (node.getAttribute(attribute) !== value) node.setAttribute(attribute, value);
diff --git a/test/runtime/samples/component-event-handler-modifier-detail/Row.svelte b/test/runtime/samples/component-event-handler-modifier-detail/Row.svelte
new file mode 100644
index 0000000000..d95c28838a
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-modifier-detail/Row.svelte
@@ -0,0 +1,11 @@
+
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/component-event-handler-modifier-detail/_config.js b/test/runtime/samples/component-event-handler-modifier-detail/_config.js
new file mode 100644
index 0000000000..1289979c6c
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-modifier-detail/_config.js
@@ -0,0 +1,13 @@
+export default {
+ html: `
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+ const event = new window.MouseEvent('click');
+
+ await button.dispatchEvent(event);
+ assert.equal(component.selected, "apple");
+ }
+};
diff --git a/test/runtime/samples/component-event-handler-modifier-detail/main.svelte b/test/runtime/samples/component-event-handler-modifier-detail/main.svelte
new file mode 100644
index 0000000000..e36a7ef920
--- /dev/null
+++ b/test/runtime/samples/component-event-handler-modifier-detail/main.svelte
@@ -0,0 +1,11 @@
+
+
+
\ No newline at end of file
diff --git a/test/runtime/samples/event-handler-modifier-detail/_config.js b/test/runtime/samples/event-handler-modifier-detail/_config.js
new file mode 100644
index 0000000000..3c15cb6ee4
--- /dev/null
+++ b/test/runtime/samples/event-handler-modifier-detail/_config.js
@@ -0,0 +1,14 @@
+export default {
+ html: `
+
+ `,
+
+ async test({ assert, component, target, window }) {
+ const button = target.querySelector('button');
+ const event = new window.CustomEvent('click', { detail: 1 });
+
+ await button.dispatchEvent(event);
+
+ assert.ok(component.button === 1);
+ }
+};
diff --git a/test/runtime/samples/event-handler-modifier-detail/main.svelte b/test/runtime/samples/event-handler-modifier-detail/main.svelte
new file mode 100644
index 0000000000..3f1e991f94
--- /dev/null
+++ b/test/runtime/samples/event-handler-modifier-detail/main.svelte
@@ -0,0 +1,9 @@
+
+
+
\ No newline at end of file
diff --git a/test/validator/samples/component-event-modifiers-invalid/errors.json b/test/validator/samples/component-event-modifiers-invalid/errors.json
index da608063fe..baaf612092 100644
--- a/test/validator/samples/component-event-modifiers-invalid/errors.json
+++ b/test/validator/samples/component-event-modifiers-invalid/errors.json
@@ -1,5 +1,5 @@
[{
- "message": "Event modifiers other than 'once' can only be used on DOM elements",
+ "message": "Event modifiers other than 'once' and 'detail' can only be used on DOM elements",
"code": "invalid-event-modifier",
"start": {
"line": 6,
diff --git a/test/validator/samples/event-modifiers-invalid/errors.json b/test/validator/samples/event-modifiers-invalid/errors.json
index 8be2ca7348..6fb389ec65 100644
--- a/test/validator/samples/event-modifiers-invalid/errors.json
+++ b/test/validator/samples/event-modifiers-invalid/errors.json
@@ -1,5 +1,5 @@
[{
- "message": "Valid event modifiers are preventDefault, stopPropagation, capture, once, passive or self",
+ "message": "Valid event modifiers are preventDefault, stopPropagation, capture, once, passive, self or detail",
"code": "invalid-event-modifier",
"start": {
"line": 1,