<svelte:head> and <title>

pull/1746/head
Rich Harris 8 years ago
parent 81bf0fd4ad
commit ec6bc6e6de

@ -2,12 +2,14 @@ import Wrapper from './shared/Wrapper';
import AwaitBlock from './AwaitBlock';
import EachBlock from './EachBlock';
import Element from './Element';
import Head from './Head';
import IfBlock from './IfBlock';
import InlineComponent from './InlineComponent';
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 '../../nodes/shared/Node';
import { trimStart, trimEnd } from '../../../utils/trim';
@ -20,12 +22,14 @@ const wrappers = {
Comment: null,
EachBlock,
Element,
Head,
IfBlock,
InlineComponent,
MustacheTag,
RawMustacheTag,
Slot,
Text,
Title,
Window
};

@ -0,0 +1,33 @@
import Wrapper from './shared/Wrapper';
import Renderer from '../Renderer';
import Block from '../Block';
import Head from '../../nodes/Head';
import FragmentWrapper from './Fragment';
export default class HeadWrapper extends Wrapper {
fragment: FragmentWrapper;
constructor(
renderer: Renderer,
block: Block,
parent: Wrapper,
node: Head,
stripWhitespace: boolean,
nextSibling: Wrapper
) {
super(renderer, block, parent, node);
this.fragment = new FragmentWrapper(
renderer,
block,
node.children,
parent,
stripWhitespace,
nextSibling
);
}
render(block: Block, parentNode: string, parentNodes: string) {
this.fragment.render(block, 'document.head', null);
}
}

@ -0,0 +1,99 @@
import Wrapper from './shared/Wrapper';
import Renderer from '../Renderer';
import Block from '../Block';
import Title from '../../nodes/Title';
import FragmentWrapper from './Fragment';
import { stringify } from '../../../utils/stringify';
export default class TitleWrapper extends Wrapper {
node: Title;
constructor(
renderer: Renderer,
block: Block,
parent: Wrapper,
node: Title,
stripWhitespace: boolean,
nextSibling: Wrapper
) {
super(renderer, block, parent, node);
}
render(block: Block, parentNode: string, parentNodes: string) {
const isDynamic = !!this.node.children.find(node => node.type !== 'Text');
if (isDynamic) {
let value;
const allDependencies = new Set();
// TODO some of this code is repeated in Tag.ts — would be good to
// DRY it out if that's possible without introducing crazy indirection
if (this.node.children.length === 1) {
// single {tag} — may be a non-string
const { expression } = this.node.children[0];
const { dependencies, snippet } = this.node.children[0].expression;
value = snippet;
dependencies.forEach(d => {
allDependencies.add(d);
});
} else {
// '{foo} {bar}' — treat as string concatenation
value =
(this.node.children[0].type === 'Text' ? '' : `"" + `) +
this.node.children
.map((chunk: Node) => {
if (chunk.type === 'Text') {
return stringify(chunk.data);
} else {
const { dependencies, snippet } = chunk.expression;
dependencies.forEach(d => {
allDependencies.add(d);
});
return chunk.expression.getPrecedence() <= 13 ? `(${snippet})` : snippet;
}
})
.join(' + ');
}
const last = this.node.shouldCache && block.getUniqueName(
`title_value`
);
if (this.node.shouldCache) block.addVariable(last);
let updater;
const init = this.node.shouldCache ? `${last} = ${value}` : value;
block.builders.init.addLine(
`document.title = ${init};`
);
updater = `document.title = ${this.node.shouldCache ? last : value};`;
if (allDependencies.size) {
const dependencies = Array.from(allDependencies);
const changedCheck = (
( block.hasOutros ? `!#current || ` : '' ) +
dependencies.map(dependency => `changed.${dependency}`).join(' || ')
);
const updateCachedValue = `${last} !== (${last} = ${value})`;
const condition = this.node.shouldCache ?
( dependencies.length ? `(${changedCheck}) && ${updateCachedValue}` : updateCachedValue ) :
changedCheck;
block.builders.update.addConditional(
condition,
updater
);
}
} else {
const value = stringify(this.node.children[0].data);
block.builders.hydrate.addLine(`document.title = ${value};`);
}
}
}
Loading…
Cancel
Save