Skip to content

Commit 394dec9

Browse files
authored
Merge pull request #1024 from sveltejs/gh-1013
update SSR render method, and introduce <:Head>
2 parents ca6a4a7 + 8a3898c commit 394dec9

File tree

68 files changed

+393
-136
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+393
-136
lines changed

src/generators/Generator.ts

+4-1
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,9 @@ export default class Generator {
161161

162162
this.computations = [];
163163
this.templateProperties = {};
164-
this.name = this.alias(name);
165164

166165
this.walkJs(dom);
166+
this.name = this.alias(name);
167167

168168
if (options.customElement === true) {
169169
this.customElement = {
@@ -731,6 +731,9 @@ export default class Generator {
731731
} else if (node.name === ':Window') { // TODO do this in parse?
732732
node.type = 'Window';
733733
node.__proto__ = nodes.Window.prototype;
734+
} else if (node.name === ':Head') { // TODO do this in parse?
735+
node.type = 'Head';
736+
node.__proto__ = nodes.Head.prototype;
734737
} else if (node.type === 'Element' && node.name === 'slot' && !generator.customElement) {
735738
node.type = 'Slot';
736739
node.__proto__ = nodes.Slot.prototype;

src/generators/dom/Block.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -132,10 +132,11 @@ export default class Block {
132132
) {
133133
this.addVariable(name);
134134
this.builders.create.addLine(`${name} = ${renderStatement};`);
135-
this.builders.claim.addLine(`${name} = ${claimStatement};`);
135+
this.builders.claim.addLine(`${name} = ${claimStatement || renderStatement};`);
136136

137137
if (parentNode) {
138138
this.builders.mount.addLine(`@appendNode(${name}, ${parentNode});`);
139+
if (parentNode === 'document.head') this.builders.unmount.addLine(`@detachNode(${name});`);
139140
} else {
140141
this.builders.mount.addLine(`@insertNode(${name}, #target, anchor);`);
141142
this.builders.unmount.addLine(`@detachNode(${name});`);
@@ -203,7 +204,7 @@ export default class Block {
203204
this.builders.hydrate.addLine(`this.first = ${this.first};`);
204205
}
205206

206-
if (this.builders.create.isEmpty()) {
207+
if (this.builders.create.isEmpty() && this.builders.hydrate.isEmpty()) {
207208
properties.addBlock(`c: @noop,`);
208209
} else {
209210
properties.addBlock(deindent`
@@ -215,7 +216,7 @@ export default class Block {
215216
}
216217

217218
if (this.generator.hydratable) {
218-
if (this.builders.claim.isEmpty()) {
219+
if (this.builders.claim.isEmpty() && this.builders.hydrate.isEmpty()) {
219220
properties.addBlock(`l: @noop,`);
220221
} else {
221222
properties.addBlock(deindent`

src/generators/nodes/Attribute.ts

+7-4
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,7 @@ export default class Attribute {
7777
? '@setXlinkAttribute'
7878
: '@setAttribute';
7979

80-
const isDynamic =
81-
(this.value !== true && this.value.length > 1) ||
82-
(this.value.length === 1 && this.value[0].type !== 'Text');
83-
80+
const isDynamic = this.isDynamic();
8481
const isLegacyInputType = this.generator.legacy && name === 'type' && this.parent.name === 'input';
8582

8683
const isDataSet = /^data-/.test(name) && !this.generator.legacy && !node.namespace;
@@ -310,6 +307,12 @@ export default class Attribute {
310307
);
311308
});
312309
}
310+
311+
isDynamic() {
312+
if (this.value === true || this.value.length === 0) return false;
313+
if (this.value.length > 1) return true;
314+
return this.value[0].type !== 'Text';
315+
}
313316
}
314317

315318
// source: https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes

src/generators/nodes/AwaitBlock.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ export default class AwaitBlock extends Node {
6868
) {
6969
const name = this.var;
7070

71-
const anchor = this.getOrCreateAnchor(block, parentNode);
71+
const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes);
7272
const updateMountNode = this.getUpdateMountNode(anchor);
7373

7474
const params = block.params.join(', ');
@@ -143,9 +143,11 @@ export default class AwaitBlock extends Node {
143143
${await_block}.c();
144144
`);
145145

146-
block.builders.claim.addBlock(deindent`
147-
${await_block}.l(${parentNodes});
148-
`);
146+
if (parentNodes) {
147+
block.builders.claim.addBlock(deindent`
148+
${await_block}.l(${parentNodes});
149+
`);
150+
}
149151

150152
const initialMountNode = parentNode || '#target';
151153
const anchorNode = parentNode ? 'null' : 'anchor';

src/generators/nodes/Component.ts

+11-7
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ export default class Component extends Node {
248248
block.contextualise(this.expression);
249249
const { dependencies, snippet } = this.metadata;
250250

251-
const anchor = this.getOrCreateAnchor(block, parentNode);
251+
const anchor = this.getOrCreateAnchor(block, parentNode, parentNodes);
252252

253253
const params = block.params.join(', ');
254254

@@ -281,9 +281,11 @@ export default class Component extends Node {
281281
`if (${name}) ${name}._fragment.c();`
282282
);
283283

284-
block.builders.claim.addLine(
285-
`if (${name}) ${name}._fragment.l(${parentNodes});`
286-
);
284+
if (parentNodes) {
285+
block.builders.claim.addLine(
286+
`if (${name}) ${name}._fragment.l(${parentNodes});`
287+
);
288+
}
287289

288290
block.builders.mount.addLine(
289291
`if (${name}) ${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});`
@@ -350,9 +352,11 @@ export default class Component extends Node {
350352

351353
block.builders.create.addLine(`${name}._fragment.c();`);
352354

353-
block.builders.claim.addLine(
354-
`${name}._fragment.l(${parentNodes});`
355-
);
355+
if (parentNodes) {
356+
block.builders.claim.addLine(
357+
`${name}._fragment.l(${parentNodes});`
358+
);
359+
}
356360

357361
block.builders.mount.addLine(
358362
`${name}._mount(${parentNode || '#target'}, ${parentNode ? 'null' : 'anchor'});`

src/generators/nodes/EachBlock.ts

+18-14
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ export default class EachBlock extends Node {
154154
block.addElement(
155155
anchor,
156156
`@createComment()`,
157-
`@createComment()`,
157+
parentNodes && `@createComment()`,
158158
parentNode
159159
);
160160
}
@@ -263,7 +263,7 @@ export default class EachBlock extends Node {
263263
this.block.addElement(
264264
this.block.first,
265265
`@createComment()`,
266-
`@createComment()`,
266+
parentNodes && `@createComment()`,
267267
null
268268
);
269269
}
@@ -293,13 +293,15 @@ export default class EachBlock extends Node {
293293
}
294294
`);
295295

296-
block.builders.claim.addBlock(deindent`
297-
var ${iteration} = ${head};
298-
while (${iteration}) {
299-
${iteration}.l(${parentNodes});
300-
${iteration} = ${iteration}.next;
301-
}
302-
`);
296+
if (parentNodes) {
297+
block.builders.claim.addBlock(deindent`
298+
var ${iteration} = ${head};
299+
while (${iteration}) {
300+
${iteration}.l(${parentNodes});
301+
${iteration} = ${iteration}.next;
302+
}
303+
`);
304+
}
303305

304306
block.builders.mount.addBlock(deindent`
305307
var ${iteration} = ${head};
@@ -481,11 +483,13 @@ export default class EachBlock extends Node {
481483
}
482484
`);
483485

484-
block.builders.claim.addBlock(deindent`
485-
for (var #i = 0; #i < ${iterations}.length; #i += 1) {
486-
${iterations}[#i].l(${parentNodes});
487-
}
488-
`);
486+
if (parentNodes) {
487+
block.builders.claim.addBlock(deindent`
488+
for (var #i = 0; #i < ${iterations}.length; #i += 1) {
489+
${iterations}[#i].l(${parentNodes});
490+
}
491+
`);
492+
}
489493

490494
block.builders.mount.addBlock(deindent`
491495
for (var #i = 0; #i < ${iterations}.length; #i += 1) {

src/generators/nodes/Element.ts

+22-13
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ export default class Element extends Node {
163163

164164
const childState = {
165165
parentNode: this.var,
166-
parentNodes: block.getUniqueName(`${this.var}_nodes`)
166+
parentNodes: parentNodes && block.getUniqueName(`${this.var}_nodes`) // if we're in unclaimable territory, i.e. <head>, parentNodes is null
167167
};
168168

169169
const name = this.var;
@@ -175,25 +175,32 @@ export default class Element extends Node {
175175
parentNode;
176176

177177
block.addVariable(name);
178+
const renderStatement = getRenderStatement(this.generator, this.namespace, this.name);
178179
block.builders.create.addLine(
179-
`${name} = ${getRenderStatement(
180-
this.generator,
181-
this.namespace,
182-
this.name
183-
)};`
180+
`${name} = ${renderStatement};`
184181
);
185182

186183
if (this.generator.hydratable) {
187-
block.builders.claim.addBlock(deindent`
188-
${name} = ${getClaimStatement(generator, this.namespace, parentNodes, this)};
189-
var ${childState.parentNodes} = @children(${name});
190-
`);
184+
if (parentNodes) {
185+
block.builders.claim.addBlock(deindent`
186+
${name} = ${getClaimStatement(generator, this.namespace, parentNodes, this)};
187+
var ${childState.parentNodes} = @children(${name});
188+
`);
189+
} else {
190+
block.builders.claim.addLine(
191+
`${name} = ${renderStatement};`
192+
);
193+
}
191194
}
192195

193196
if (initialMountNode) {
194197
block.builders.mount.addLine(
195198
`@appendNode(${name}, ${initialMountNode});`
196199
);
200+
201+
if (initialMountNode === 'document.head') {
202+
block.builders.unmount.addLine(`@detachNode(${name});`);
203+
}
197204
} else {
198205
block.builders.mount.addLine(`@insertNode(${name}, #target, anchor);`);
199206

@@ -394,9 +401,11 @@ export default class Element extends Node {
394401
block.builders.mount.addBlock(this.initialUpdate);
395402
}
396403

397-
block.builders.claim.addLine(
398-
`${childState.parentNodes}.forEach(@detachNode);`
399-
);
404+
if (childState.parentNodes) {
405+
block.builders.claim.addLine(
406+
`${childState.parentNodes}.forEach(@detachNode);`
407+
);
408+
}
400409

401410
function toHTML(node: Element | Text) {
402411
if (node.type === 'Text') return node.data;

src/generators/nodes/Head.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import deindent from '../../utils/deindent';
2+
import { stringify } from '../../utils/stringify';
3+
import Node from './shared/Node';
4+
import Block from '../dom/Block';
5+
import Attribute from './Attribute';
6+
7+
export default class Head extends Node {
8+
type: 'Head';
9+
attributes: Attribute[];
10+
11+
init(
12+
block: Block,
13+
stripWhitespace: boolean,
14+
nextSibling: Node
15+
) {
16+
this.initChildren(block, true, null);
17+
}
18+
19+
build(
20+
block: Block,
21+
parentNode: string,
22+
parentNodes: string
23+
) {
24+
const { generator } = this;
25+
26+
this.var = 'document.head';
27+
28+
this.children.forEach((child: Node) => {
29+
child.build(block, 'document.head', null);
30+
});
31+
}
32+
}

src/generators/nodes/IfBlock.ts

+6-4
Original file line numberDiff line numberDiff line change
@@ -133,15 +133,17 @@ export default class IfBlock extends Node {
133133

134134
block.builders.create.addLine(`${if_name}${name}.c();`);
135135

136-
block.builders.claim.addLine(
137-
`${if_name}${name}.l(${parentNodes});`
138-
);
136+
if (parentNodes) {
137+
block.builders.claim.addLine(
138+
`${if_name}${name}.l(${parentNodes});`
139+
);
140+
}
139141

140142
if (needsAnchor) {
141143
block.addElement(
142144
anchor,
143145
`@createComment()`,
144-
`@createComment()`,
146+
parentNodes && `@createComment()`,
145147
parentNode
146148
);
147149
}

src/generators/nodes/MustacheTag.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ export default class MustacheTag extends Tag {
2222
block.addElement(
2323
this.var,
2424
`@createText(${init})`,
25-
`@claimText(${parentNodes}, ${init})`,
25+
parentNodes && `@claimText(${parentNodes}, ${init})`,
2626
parentNode
2727
);
2828
}

src/generators/nodes/RawMustacheTag.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export default class RawMustacheTag extends Tag {
6161
block.addElement(
6262
anchorBefore,
6363
`@createElement('noscript')`,
64-
`@createElement('noscript')`,
64+
parentNodes && `@createElement('noscript')`,
6565
parentNode
6666
);
6767
}
@@ -70,7 +70,7 @@ export default class RawMustacheTag extends Tag {
7070
block.addElement(
7171
anchorAfter,
7272
`@createElement('noscript')`,
73-
`@createElement('noscript')`,
73+
parentNodes && `@createElement('noscript')`,
7474
parentNode
7575
);
7676
}

src/generators/nodes/Text.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ export default class Text extends Node {
5353
block.addElement(
5454
this.var,
5555
`@createText(${stringify(this.data)})`,
56-
`@claimText(${parentNodes}, ${stringify(this.data)})`,
56+
parentNodes && `@claimText(${parentNodes}, ${stringify(this.data)})`,
5757
parentNode
5858
);
5959
}

src/generators/nodes/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Element from './Element';
1010
import ElseBlock from './ElseBlock';
1111
import EventHandler from './EventHandler';
1212
import Fragment from './Fragment';
13+
import Head from './Head';
1314
import IfBlock from './IfBlock';
1415
import MustacheTag from './MustacheTag';
1516
import PendingBlock from './PendingBlock';
@@ -33,6 +34,7 @@ const nodes: Record<string, any> = {
3334
ElseBlock,
3435
EventHandler,
3536
Fragment,
37+
Head,
3638
IfBlock,
3739
MustacheTag,
3840
PendingBlock,

src/generators/nodes/shared/Node.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ export default class Node {
138138
if (this.parent) return this.parent.findNearest(selector);
139139
}
140140

141-
getOrCreateAnchor(block: Block, parentNode: string) {
141+
getOrCreateAnchor(block: Block, parentNode: string, parentNodes: string) {
142142
// TODO use this in EachBlock and IfBlock — tricky because
143143
// children need to be created first
144144
const needsAnchor = this.next ? !this.next.isDomNode() : !parentNode || !this.parent.isDomNode();
@@ -150,7 +150,7 @@ export default class Node {
150150
block.addElement(
151151
anchor,
152152
`@createComment()`,
153-
`@createComment()`,
153+
parentNodes && `@createComment()`,
154154
parentNode
155155
);
156156
}

0 commit comments

Comments
 (0)