diff --git a/src/validate/html/validateElement.js b/src/validate/html/validateElement.js
index c3405c75a2..beca2086ec 100644
--- a/src/validate/html/validateElement.js
+++ b/src/validate/html/validateElement.js
@@ -1,5 +1,11 @@
import flattenReference from '../../utils/flattenReference.js';
+const validBuiltins = new Set([
+ 'set',
+ 'fire',
+ 'destroy'
+]);
+
export default function validateElement ( validator, node ) {
const isComponent = node.name === ':Self' || validator.components.has( node.name );
@@ -56,10 +62,15 @@ export default function validateElement ( validator, node ) {
const { name } = flattenReference( callee );
if ( name === 'this' || name === 'event' ) return;
- if ( callee.type === 'Identifier' && callee.name === 'set' || callee.name === 'fire' || validator.methods.has( callee.name ) ) return;
+ if ( callee.type === 'Identifier' && validBuiltins.has( callee.name ) || validator.methods.has( callee.name ) ) return;
+
+ const validCallees = [ 'this.*', 'event.*' ]
+ .concat(
+ Array.from( validBuiltins ),
+ Array.from( validator.methods.keys() )
+ );
- const validCallees = list( [ 'this.*', 'event.*', 'set', 'fire' ].concat( Array.from( validator.methods.keys() ) ) );
- let message = `'${validator.source.slice( callee.start, callee.end )}' is an invalid callee (should be one of ${validCallees})`;
+ let message = `'${validator.source.slice( callee.start, callee.end )}' is an invalid callee (should be one of ${list( validCallees )})`;
if ( callee.type === 'Identifier' && validator.helpers.has( callee.name ) ) {
message += `. '${callee.name}' exists on 'helpers', did you put it in the wrong place?`;
diff --git a/test/runtime/samples/event-handler-destroy/_config.js b/test/runtime/samples/event-handler-destroy/_config.js
new file mode 100644
index 0000000000..417f0da041
--- /dev/null
+++ b/test/runtime/samples/event-handler-destroy/_config.js
@@ -0,0 +1,20 @@
+export default {
+ html: `
+
+ `,
+
+ test ( assert, component, target, window ) {
+ const button = target.querySelector( 'button' );
+ const event = new window.MouseEvent( 'click' );
+
+ let destroyed = false;
+ component.on( 'destroy', () => {
+ destroyed = true;
+ });
+
+ button.dispatchEvent( event );
+ assert.htmlEqual( target.innerHTML, `` );
+
+ assert.ok( destroyed );
+ }
+};
diff --git a/test/runtime/samples/event-handler-destroy/main.html b/test/runtime/samples/event-handler-destroy/main.html
new file mode 100644
index 0000000000..01b2bb8221
--- /dev/null
+++ b/test/runtime/samples/event-handler-destroy/main.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/test/validator/samples/method-nonexistent-helper/errors.json b/test/validator/samples/method-nonexistent-helper/errors.json
index 80183498ca..02512426a1 100644
--- a/test/validator/samples/method-nonexistent-helper/errors.json
+++ b/test/validator/samples/method-nonexistent-helper/errors.json
@@ -1,5 +1,5 @@
[{
- "message": "'foo' is an invalid callee (should be one of this.*, event.*, set, fire or bar). 'foo' exists on 'helpers', did you put it in the wrong place?",
+ "message": "'foo' is an invalid callee (should be one of this.*, event.*, set, fire, destroy or bar). 'foo' exists on 'helpers', did you put it in the wrong place?",
"pos": 18,
"loc": {
"line": 1,
diff --git a/test/validator/samples/method-nonexistent/errors.json b/test/validator/samples/method-nonexistent/errors.json
index 2eaf6c215d..8debbf8132 100644
--- a/test/validator/samples/method-nonexistent/errors.json
+++ b/test/validator/samples/method-nonexistent/errors.json
@@ -1,5 +1,5 @@
[{
- "message": "'foo' is an invalid callee (should be one of this.*, event.*, set, fire or bar)",
+ "message": "'foo' is an invalid callee (should be one of this.*, event.*, set, fire, destroy or bar)",
"pos": 18,
"loc": {
"line": 1,