Repository: sveltejs/svelte (JavaScript)
Date: 2021-03-30 09:37:22+00:00
Task type: Feature

Issue:
trusted events modifier
**Is your feature request related to a problem? Please describe.**
To make events like on:click not programmatical callable, I wish the events to check if the event isTrusted. Problem is, i have to check it in each function. 

**Describe the solution you'd like**
A eventModifier like |once or |passive - call it trusted
`<button on:click|trusted={() => console.log('Trusted event'); }></button>`




Issue discussion:

Solution patch:
diff --git a/src/compiler/compile/nodes/Element.ts b/src/compiler/compile/nodes/Element.ts
--- a/src/compiler/compile/nodes/Element.ts
+++ b/src/compiler/compile/nodes/Element.ts
@@ -82,7 +82,8 @@ const valid_modifiers = new Set([
 	'once',
 	'passive',
 	'nonpassive',
-	'self'
+	'self',
+	'trusted'
 ]);
 
 const passive_events = new Set([
diff --git a/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts b/src/compiler/compile/render_dom/wrappers/Element/EventHandler.ts
--- 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('trusted')) snippet = x`@trusted(${snippet})`;
 
 		const args = [];
 
diff --git a/src/runtime/internal/dom.ts b/src/runtime/internal/dom.ts
--- a/src/runtime/internal/dom.ts
+++ b/src/runtime/internal/dom.ts
@@ -85,6 +85,13 @@ export function self(fn) {
 	};
 }
 
+export function trusted(fn) {
+	return function(event) {
+		// @ts-ignore
+		if (event.isTrusted) fn.call(this, event);
+	};
+}
+
 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);


Test patch:
diff --git a/test/runtime/samples/event-handler-modifier-trusted/_config.js b/test/runtime/samples/event-handler-modifier-trusted/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/event-handler-modifier-trusted/_config.js
@@ -0,0 +1,9 @@
+export default {
+	async test({ assert, component, target, window }) {
+		const button = target.querySelector('button');
+		const event = new window.MouseEvent('click');
+
+		await button.dispatchEvent(event);
+		assert.equal(component.trusted, true);
+	}
+};
diff --git a/test/runtime/samples/event-handler-modifier-trusted/main.svelte b/test/runtime/samples/event-handler-modifier-trusted/main.svelte
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/event-handler-modifier-trusted/main.svelte
@@ -0,0 +1,5 @@
+<script>
+	export let trusted = true;
+</script>
+
+<button on:click|trusted="{() => trusted = false}">Only trusted events: {trusted?'true':'false'}</button>
diff --git a/test/validator/samples/event-modifiers-invalid/errors.json b/test/validator/samples/event-modifiers-invalid/errors.json
--- 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, nonpassive or self",
+	"message": "Valid event modifiers are preventDefault, stopPropagation, capture, once, passive, nonpassive, self or trusted",
 	"code": "invalid-event-modifier",
 	"start": {
 		"line": 1,