prevent invalid scripts

pull/1839/head
Rich Harris 7 years ago
parent 6ecf9e59d3
commit 43cdd943b2

@ -38,17 +38,6 @@ childKeys.EachBlock = childKeys.IfBlock = ['children', 'else'];
childKeys.Attribute = ['value']; childKeys.Attribute = ['value'];
childKeys.ExportNamedDeclaration = ['declaration', 'specifiers']; childKeys.ExportNamedDeclaration = ['declaration', 'specifiers'];
function get_context(script) {
const context = script.attributes.find(attribute => attribute.name === 'context');
if (!context) return 'default';
if (context.value.length !== 1 || context.value[0].type !== 'Text') {
throw new Error(`context attribute must be static`);
}
return context.value[0].data;
}
export default class Component { export default class Component {
stats: Stats; stats: Stats;
@ -132,8 +121,25 @@ export default class Component {
this.stylesheet = new Stylesheet(source, ast, options.filename, options.dev); this.stylesheet = new Stylesheet(source, ast, options.filename, options.dev);
this.stylesheet.validate(this); this.stylesheet.validate(this);
this.module_script = ast.js.find(script => get_context(script) === 'module'); const module_scripts = ast.js.filter(script => this.get_context(script) === 'module');
this.instance_script = ast.js.find(script => get_context(script) === 'default'); const instance_scripts = ast.js.filter(script => this.get_context(script) === 'default');
if (module_scripts.length > 1) {
this.error(module_scripts[1], {
code: `invalid-script`,
message: `A component can only have one <script context="module"> element`
});
}
if (instance_scripts.length > 1) {
this.error(instance_scripts[1], {
code: `invalid-script`,
message: `A component can only have one instance-level <script> element`
});
}
this.module_script = module_scripts[0];
this.instance_script = instance_scripts[0];
this.meta = process_meta(this, this.ast.html.children); this.meta = process_meta(this, this.ast.html.children);
this.namespace = namespaces[this.meta.namespace] || this.meta.namespace; this.namespace = namespaces[this.meta.namespace] || this.meta.namespace;
@ -884,6 +890,29 @@ export default class Component {
message: `'${name}' is not defined` message: `'${name}' is not defined`
}); });
} }
get_context(script) {
const context = script.attributes.find(attribute => attribute.name === 'context');
if (!context) return 'default';
if (context.value.length !== 1 || context.value[0].type !== 'Text') {
this.error(script, {
code: 'invalid-script',
message: `context attribute must be static`
});
}
const value = context.value[0].data;
if (value !== 'module') {
this.error(context, {
code: `invalid-script`,
message: `If the context attribute is supplied, its value must be "module"`
});
}
return value;
}
} }
function process_meta(component, nodes) { function process_meta(component, nodes) {

@ -0,0 +1,15 @@
[{
"code": "invalid-script",
"message": "A component can only have one instance-level <script> element",
"pos": 30,
"start": {
"line": 5,
"column": 0,
"character": 30
},
"end": {
"line": 7,
"column": 9,
"character": 58
}
}]

@ -0,0 +1,7 @@
<script>
let foo;
</script>
<script>
let bar;
</script>

@ -0,0 +1,15 @@
[{
"code": "invalid-script",
"message": "A component can only have one <script context=\"module\"> element",
"pos": 47,
"start": {
"line": 5,
"column": 0,
"character": 47
},
"end": {
"line": 7,
"column": 9,
"character": 92
}
}]

@ -0,0 +1,7 @@
<script context="module">
let foo;
</script>
<script context="module">
let bar;
</script>

@ -0,0 +1,15 @@
[{
"code": "invalid-script",
"message": "If the context attribute is supplied, its value must be \"module\"",
"pos": 8,
"start": {
"line": 1,
"column": 8,
"character": 8
},
"end": {
"line": 1,
"column": 22,
"character": 22
}
}]

@ -0,0 +1,3 @@
<script context="nope">
let foo;
</script>
Loading…
Cancel
Save