fix: warn against accidental global event referenced (#10442)

* fix: warn against accidental global event referenced

closes #10393

* remove list

* remove else

* tweak

* update test

---------

Co-authored-by: Rich Harris <rich.harris@vercel.com>
pull/10510/head
Simon H 2 years ago committed by GitHub
parent 49ad7f9589
commit 71601ba2e5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -0,0 +1,5 @@
---
"svelte": patch
---
fix: warn against accidental global event referenced

@ -1,5 +1,11 @@
import { error } from '../../errors.js';
import { extract_identifiers, get_parent, is_text_attribute, object } from '../../utils/ast.js';
import {
extract_identifiers,
get_parent,
is_expression_attribute,
is_text_attribute,
object
} from '../../utils/ast.js';
import { warn } from '../../warnings.js';
import fuzzymatch from '../1-parse/utils/fuzzymatch.js';
import { disallowed_parapgraph_contents, interactive_elements } from '../1-parse/utils/html.js';
@ -66,12 +72,23 @@ function validate_element(node, context) {
}
if (attribute.name.startsWith('on') && attribute.name.length > 2) {
if (!is_expression_attribute(attribute)) {
error(attribute, 'invalid-event-attribute-value');
}
const value = attribute.value[0].expression;
if (
attribute.value === true ||
is_text_attribute(attribute) ||
attribute.value.length > 1
value.type === 'Identifier' &&
value.name === attribute.name &&
!context.state.scope.get(value.name)
) {
error(attribute, 'invalid-event-attribute-value');
warn(
context.state.analysis.warnings,
attribute,
context.path,
'global-event-reference',
attribute.name
);
}
}

@ -36,7 +36,7 @@ export function is_text_attribute(attribute) {
* @param {import('#compiler').Attribute} attribute
* @returns {attribute is import('#compiler').Attribute & { value: [import('#compiler').ExpressionTag] }}
*/
function is_expression_attribute(attribute) {
export function is_expression_attribute(attribute) {
return (
attribute.value !== true &&
attribute.value.length === 1 &&

@ -12,7 +12,10 @@ const css = {
/** @satisfies {Warnings} */
const attributes = {
'avoid-is': () => 'The "is" attribute is not supported cross-browser and should be avoided'
'avoid-is': () => 'The "is" attribute is not supported cross-browser and should be avoided',
/** @param {string} name */
'global-event-reference': (name) =>
`You are referencing globalThis.${name}. Did you forget to declare a variable with that name?`
};
/** @satisfies {Warnings} */

@ -0,0 +1,3 @@
import { test } from '../../test';
export default test({});

@ -0,0 +1,9 @@
<script>
let onclick;
</script>
<button {onclick}></button>
<button onclick={onclick}></button>
<button {onkeydown}></button>
<button onkeydown={onkeydown}></button>

@ -0,0 +1,26 @@
[
{
"code": "global-event-reference",
"message": "You are referencing globalThis.onkeydown. Did you forget to declare a variable with that name?",
"start": {
"column": 8,
"line": 8
},
"end": {
"column": 19,
"line": 8
}
},
{
"code": "global-event-reference",
"message": "You are referencing globalThis.onkeydown. Did you forget to declare a variable with that name?",
"start": {
"column": 8,
"line": 9
},
"end": {
"column": 29,
"line": 9
}
}
]
Loading…
Cancel
Save