diff --git a/src/compiler/parse/state/tag.js b/src/compiler/parse/state/tag.js index 8fde01f952..78e0979982 100644 --- a/src/compiler/parse/state/tag.js +++ b/src/compiler/parse/state/tag.js @@ -11,43 +11,46 @@ const valid_tag_name = /^\!?[a-zA-Z]{1,}:?[a-zA-Z0-9\-]*/; /** Invalid attribute characters if the attribute is not surrounded by quotes */ const regex_starts_with_invalid_attr_value = /^(\/>|[\s"'=<>`])/; const meta_tags = new Map([ - ['svelte:head', 'Head'], - ['svelte:options', 'Options'], - ['svelte:window', 'Window'], - ['svelte:document', 'Document'], - ['svelte:body', 'Body'] + ['svelte:head', 'Head'], + ['svelte:options', 'Options'], + ['svelte:window', 'Window'], + ['svelte:document', 'Document'], + ['svelte:body', 'Body'] ]); -const valid_meta_tags = Array.from(meta_tags.keys()).concat('svelte:self', 'svelte:component', 'svelte:fragment', 'svelte:element'); +const valid_meta_tags = Array.from(meta_tags.keys()).concat( + 'svelte:self', + 'svelte:component', + 'svelte:fragment', + 'svelte:element' +); const specials = new Map([ - [ - 'script', - { - read: read_script, - property: 'js' - } - ], - [ - 'style', - { - read: read_style, - property: 'css' - } - ] + [ + 'script', + { + read: read_script, + property: 'js' + } + ], + [ + 'style', + { + read: read_style, + property: 'css' + } + ] ]); const SELF = /^svelte:self(?=[\s/>])/; const COMPONENT = /^svelte:component(?=[\s/>])/; const SLOT = /^svelte:fragment(?=[\s/>])/; const ELEMENT = /^svelte:element(?=[\s/>])/; function parent_is_head(stack) { - let i = stack.length; - while (i--) { - const { type } = stack[i]; - if (type === 'Head') - return true; - if (type === 'Element' || type === 'InlineComponent') - return false; - } - return false; + let i = stack.length; + while (i--) { + const { type } = stack[i]; + if (type === 'Head') return true; + if (type === 'Element' || type === 'InlineComponent') return false; + } + return false; } const regex_closing_textarea_tag = /^<\/textarea(\s[^>]*)?>/i; const regex_closing_comment = /-->/; @@ -57,165 +60,175 @@ const regex_capital_letter = /[A-Z]/; * @param {Parser} parser */ export default function tag(parser) { - const start = parser.index++; - let parent = parser.current(); - if (parser.eat('!--')) { - const data = parser.read_until(regex_closing_comment); - parser.eat('-->', true, parser_errors.unclosed_comment); - parser.current().children.push({ - start, - end: parser.index, - type: 'Comment', - data, - ignores: extract_svelte_ignore(data) - }); - return; - } - const is_closing_tag = parser.eat('/'); - const name = read_tag_name(parser); - if (meta_tags.has(name)) { - const slug = meta_tags.get(name).toLowerCase(); - if (is_closing_tag) { - if ((name === 'svelte:window' || name === 'svelte:body') && - parser.current().children.length) { - parser.error(parser_errors.invalid_element_content(slug, name), parser.current().children[0].start); - } - } - else { - if (name in parser.meta_tags) { - parser.error(parser_errors.duplicate_element(slug, name), start); - } - if (parser.stack.length > 1) { - parser.error(parser_errors.invalid_element_placement(slug, name), start); - } - parser.meta_tags[name] = true; - } - } - const type = meta_tags.has(name) - ? meta_tags.get(name) - : regex_capital_letter.test(name[0]) || name === 'svelte:self' || name === 'svelte:component' - ? 'InlineComponent' - : name === 'svelte:fragment' - ? 'SlotTemplate' - : name === 'title' && parent_is_head(parser.stack) - ? 'Title' - : name === 'slot' - ? 'Slot' - : 'Element'; + const start = parser.index++; + let parent = parser.current(); + if (parser.eat('!--')) { + const data = parser.read_until(regex_closing_comment); + parser.eat('-->', true, parser_errors.unclosed_comment); + parser.current().children.push({ + start, + end: parser.index, + type: 'Comment', + data, + ignores: extract_svelte_ignore(data) + }); + return; + } + const is_closing_tag = parser.eat('/'); + const name = read_tag_name(parser); + if (meta_tags.has(name)) { + const slug = meta_tags.get(name).toLowerCase(); + if (is_closing_tag) { + if ( + (name === 'svelte:window' || name === 'svelte:body') && + parser.current().children.length + ) { + parser.error( + parser_errors.invalid_element_content(slug, name), + parser.current().children[0].start + ); + } + } else { + if (name in parser.meta_tags) { + parser.error(parser_errors.duplicate_element(slug, name), start); + } + if (parser.stack.length > 1) { + parser.error(parser_errors.invalid_element_placement(slug, name), start); + } + parser.meta_tags[name] = true; + } + } + const type = meta_tags.has(name) + ? meta_tags.get(name) + : regex_capital_letter.test(name[0]) || name === 'svelte:self' || name === 'svelte:component' + ? 'InlineComponent' + : name === 'svelte:fragment' + ? 'SlotTemplate' + : name === 'title' && parent_is_head(parser.stack) + ? 'Title' + : name === 'slot' + ? 'Slot' + : 'Element'; - /** - * @type {TemplateNode} - */ - const element = { - start, - end: null, - type, - name, - attributes: [], - children: [] - }; - parser.allow_whitespace(); - if (is_closing_tag) { - if (is_void(name)) { - parser.error(parser_errors.invalid_void_content(name), start); - } - parser.eat('>', true); - // close any elements that don't have their own closing tags, e.g.