validate slot attribute placement

pull/942/head
Rich Harris 8 years ago
parent d590dbe165
commit abdce5c249

@ -7,7 +7,4 @@ export default function isChildOfComponent(node: Node, generator: Generator) {
if (generator.components.has(node.name)) return true;
if (/-/.test(node.name)) return false;
}
// TODO do this in validation
throw new Error(`Element with a slot='...' attribute must be a descendant of a component or custom element`);
}

@ -1,6 +1,6 @@
import * as namespaces from '../../utils/namespaces';
import validateEventHandler from './validateEventHandler';
import { Validator } from '../index';
import validate, { Validator } from '../index';
import { Node } from '../../interfaces';
const svg = /^(?:altGlyph|altGlyphDef|altGlyphItem|animate|animateColor|animateMotion|animateTransform|circle|clipPath|color-profile|cursor|defs|desc|discard|ellipse|feBlend|feColorMatrix|feComponentTransfer|feComposite|feConvolveMatrix|feDiffuseLighting|feDisplacementMap|feDistantLight|feDropShadow|feFlood|feFuncA|feFuncB|feFuncG|feFuncR|feGaussianBlur|feImage|feMerge|feMergeNode|feMorphology|feOffset|fePointLight|feSpecularLighting|feSpotLight|feTile|feTurbulence|filter|font|font-face|font-face-format|font-face-name|font-face-src|font-face-uri|foreignObject|g|glyph|glyphRef|hatch|hatchpath|hkern|image|line|linearGradient|marker|mask|mesh|meshgradient|meshpatch|meshrow|metadata|missing-glyph|mpath|path|pattern|polygon|polyline|radialGradient|rect|set|solidcolor|stop|switch|symbol|text|textPath|title|tref|tspan|unknown|use|view|vkern)$/;
@ -191,22 +191,7 @@ export default function validateElement(
}
if (attribute.name === 'slot' && !isComponent) {
let i = stack.length;
while (i--) {
const parent = stack[i];
if (parent.type === 'Element' && validator.components.has(parent.name)) break;
if (parent.type === 'IfBlock' || parent.type === 'EachBlock') {
const message = `Cannot place slotted elements inside an ${parent.type === 'IfBlock' ? 'if' : 'each'}-block`;
validator.error(message, attribute.start);
}
}
if (isDynamic(attribute)) {
validator.error(
`slot attribute cannot have a dynamic value`,
attribute.start
);
}
checkSlotAttribute(validator, node, attribute, stack);
}
}
});
@ -232,6 +217,32 @@ function checkTypeAttribute(validator: Validator, node: Node) {
return attribute.value[0].data;
}
function checkSlotAttribute(validator: Validator, node: Node, attribute: Node, stack: Node[]) {
if (isDynamic(attribute)) {
validator.error(
`slot attribute cannot have a dynamic value`,
attribute.start
);
}
let i = stack.length;
while (i--) {
const parent = stack[i];
if (parent.type === 'Element') {
// if we're inside a component or a custom element, gravy
if (validator.components.has(parent.name)) return;
if (/-/.test(parent.name)) return;
}
if (parent.type === 'IfBlock' || parent.type === 'EachBlock') {
const message = `Cannot place slotted elements inside an ${parent.type === 'IfBlock' ? 'if' : 'each'}-block`;
validator.error(message, attribute.start);
}
}
validator.error(`Element with a slot='...' attribute must be a descendant of a component or custom element`, attribute.start);
}
function isDynamic(attribute: Node) {
return attribute.value.length > 1 || attribute.value[0].type !== 'Text';
}

@ -0,0 +1,8 @@
[{
"message": "Element with a slot='...' attribute must be a descendant of a component or custom element",
"loc": {
"line": 1,
"column": 5
},
"pos": 5
}]
Loading…
Cancel
Save