diff --git a/src/generators/nodes/Head.ts b/src/generators/nodes/Head.ts index be72087aca..fc6ceb3e3a 100644 --- a/src/generators/nodes/Head.ts +++ b/src/generators/nodes/Head.ts @@ -3,10 +3,16 @@ import { stringify } from '../../utils/stringify'; import Node from './shared/Node'; import Block from '../dom/Block'; import Attribute from './Attribute'; +import mapChildren from './shared/mapChildren'; export default class Head extends Node { type: 'Head'; - attributes: Attribute[]; + children: any[]; // TODO + + constructor(compiler, parent, scope, info) { + super(compiler, parent, scope, info); + this.children = mapChildren(compiler, parent, scope, info.children); + } init( block: Block, @@ -21,8 +27,6 @@ export default class Head extends Node { parentNode: string, parentNodes: string ) { - const { generator } = this; - this.var = 'document.head'; this.children.forEach((child: Node) => { diff --git a/src/generators/nodes/Title.ts b/src/generators/nodes/Title.ts index c081208caf..d2f553c938 100644 --- a/src/generators/nodes/Title.ts +++ b/src/generators/nodes/Title.ts @@ -2,8 +2,17 @@ import { stringify } from '../../utils/stringify'; import getExpressionPrecedence from '../../utils/getExpressionPrecedence'; import Node from './shared/Node'; import Block from '../dom/Block'; +import mapChildren from './shared/mapChildren'; export default class Title extends Node { + type: 'Title'; + children: any[]; // TODO + + constructor(compiler, parent, scope, info) { + super(compiler, parent, scope, info); + this.children = mapChildren(compiler, parent, scope, info.children); + } + build( block: Block, parentNode: string, @@ -22,8 +31,7 @@ export default class Title extends Node { if (this.children.length === 1) { // single {{tag}} — may be a non-string const { expression } = this.children[0]; - const { indexes } = block.contextualise(expression); - const { dependencies, snippet } = this.children[0].metadata; + const { dependencies, snippet, indexes } = this.children[0].expression; value = snippet; dependencies.forEach(d => { @@ -43,14 +51,13 @@ export default class Title extends Node { if (chunk.type === 'Text') { return stringify(chunk.data); } else { - const { indexes } = block.contextualise(chunk.expression); - const { dependencies, snippet } = chunk.metadata; + const { dependencies, snippet } = chunk.expression; dependencies.forEach(d => { allDependencies.add(d); }); - return getExpressionPrecedence(chunk.expression) <= 13 ? `(${snippet})` : snippet; + return getExpressionPrecedence(chunk) <= 13 ? `(${snippet})` : snippet; } }) .join(' + '); diff --git a/src/generators/nodes/shared/mapChildren.ts b/src/generators/nodes/shared/mapChildren.ts index 6bb76383b8..713b397545 100644 --- a/src/generators/nodes/shared/mapChildren.ts +++ b/src/generators/nodes/shared/mapChildren.ts @@ -2,11 +2,13 @@ import AwaitBlock from '../AwaitBlock'; import Component from '../Component'; import EachBlock from '../EachBlock'; import Element from '../Element'; +import Head from '../Head'; import IfBlock from '../IfBlock'; -import Slot from '../Slot'; -import Text from '../Text'; import MustacheTag from '../MustacheTag'; import RawMustacheTag from '../RawMustacheTag'; +import Slot from '../Slot'; +import Text from '../Text'; +import Title from '../Title'; import Window from '../Window'; import Node from './Node'; @@ -16,11 +18,13 @@ function getConstructor(type): typeof Node { case 'Component': return Component; case 'EachBlock': return EachBlock; case 'Element': return Element; + case 'Head': return Head; case 'IfBlock': return IfBlock; - case 'Slot': return Slot; - case 'Text': return Text; case 'MustacheTag': return MustacheTag; case 'RawMustacheTag': return RawMustacheTag; + case 'Slot': return Slot; + case 'Text': return Text; + case 'Title': return Title; case 'Window': return Window; default: throw new Error(`Not implemented: ${type}`); } diff --git a/src/parse/state/tag.ts b/src/parse/state/tag.ts index f4d3dd542e..7ffa139d3b 100644 --- a/src/parse/state/tag.ts +++ b/src/parse/state/tag.ts @@ -60,6 +60,16 @@ const disallowedContents = new Map([ ['th', new Set(['td', 'th', 'tr'])], ]); +function parentIsHead(stack) { + let i = stack.length; + while (i--) { + const { type } = stack[i]; + if (type === 'Head') return true; + if (type === 'Element' || type === 'Component') return false; + } + return false; +} + export default function tag(parser: Parser) { const start = parser.index++; @@ -114,6 +124,7 @@ export default function tag(parser: Parser) { const type = metaTags.has(name) ? metaTags.get(name) : (/[A-Z]/.test(name[0]) || name === 'svelte:self' || name === 'svelte:component') ? 'Component' + : name === 'title' && parentIsHead(parser.stack) ? 'Title' : name === 'slot' ? 'Slot' : 'Element'; const element: Node = {