wrap fallback hydration code in conditional

pull/787/head
Rich Harris 7 years ago
parent a023346c91
commit 361a19df17

@ -51,6 +51,7 @@ export default function visitSlot(
);
block.builders.create.pushCondition(`!${content_name}`);
block.builders.hydrate.pushCondition(`!${content_name}`);
block.builders.mount.pushCondition(`!${content_name}`);
block.builders.unmount.pushCondition(`!${content_name}`);
block.builders.destroy.pushCondition(`!${content_name}`);
@ -60,6 +61,7 @@ export default function visitSlot(
});
block.builders.create.popCondition();
block.builders.hydrate.popCondition();
block.builders.mount.popCondition();
block.builders.unmount.popCondition();
block.builders.destroy.popCondition();

@ -5,12 +5,17 @@ enum ChunkType {
Block
}
interface Condition {
condition: string;
used: boolean;
}
export default class CodeBuilder {
result: string;
first: ChunkType;
last: ChunkType;
lastCondition: string;
conditionStack: string[];
conditionStack: Condition[];
indent: string;
constructor(str = '') {
@ -28,6 +33,8 @@ export default class CodeBuilder {
}
addConditional(condition: string, body: string) {
this.reifyConditions();
body = body.replace(/^/gm, `${this.indent}\t`);
if (condition === this.lastCondition) {
@ -45,6 +52,8 @@ export default class CodeBuilder {
}
addLine(line: string) {
this.reifyConditions();
if (this.lastCondition) {
this.result += `\n${this.indent}}`;
this.lastCondition = null;
@ -63,6 +72,8 @@ export default class CodeBuilder {
}
addLineAtStart(line: string) {
this.reifyConditions();
if (this.first === ChunkType.Block) {
this.result = `${line}\n\n${this.indent}${this.result}`;
} else if (this.first === ChunkType.Line) {
@ -76,6 +87,8 @@ export default class CodeBuilder {
}
addBlock(block: string) {
this.reifyConditions();
if (this.indent) block = block.replace(/^/gm, `${this.indent}`);
if (this.lastCondition) {
@ -94,6 +107,8 @@ export default class CodeBuilder {
}
addBlockAtStart(block: string) {
this.reifyConditions();
if (this.result) {
this.result = `${block}\n\n${this.indent}${this.result}`;
} else {
@ -109,15 +124,37 @@ export default class CodeBuilder {
}
pushCondition(condition: string) {
this.conditionStack.push(condition);
this.addLine(`if (${condition}) {`);
this.indent = repeat('\t', this.conditionStack.length);
this.conditionStack.push({ condition, used: false });
}
popCondition() {
this.conditionStack.pop();
const { used } = this.conditionStack.pop();
this.indent = repeat('\t', this.conditionStack.length);
this.addLine('}');
if (used) this.addLine('}');
}
reifyConditions() {
for (let i = 0; i < this.conditionStack.length; i += 1) {
const condition = this.conditionStack[i];
if (!condition.used) {
const line = `if (${condition.condition}) {`;
if (this.last === ChunkType.Block) {
this.result += `\n\n${this.indent}${line}`;
} else if (this.last === ChunkType.Line) {
this.result += `\n${this.indent}${line}`;
} else {
this.result += line;
}
this.last = ChunkType.Line;
if (!this.first) this.first = ChunkType.Line;
this.indent = repeat('\t', this.conditionStack.length);
condition.used = true;
}
}
}
toString() {

@ -120,12 +120,16 @@ function cleanChildren(node) {
}
export function normalizeHtml(window, html) {
const node = window.document.createElement('div');
node.innerHTML = html
.replace(/>[\s\r\n]+</g, '><')
.trim();
cleanChildren(node, '');
return node.innerHTML.replace(/<\/?noscript\/?>/g, '');
try {
const node = window.document.createElement('div');
node.innerHTML = html
.replace(/>[\s\r\n]+</g, '><')
.trim();
cleanChildren(node, '');
return node.innerHTML.replace(/<\/?noscript\/?>/g, '');
} catch (err) {
throw new Error(`Failed to normalize HTML:\n${html}`);
}
}
export function setupHtmlEqual() {

@ -1,5 +1,5 @@
<div>
<slot>default fallback content</slot>
<slot name='bar'>bar fallback content</slot>
<slot name='foo'>foo fallback content</slot>
<slot><p class='default'>default fallback content</p></slot>
<slot name='bar'><p class='default'>bar fallback content</p></slot>
<slot name='foo'><p class='default'>foo fallback content</p></slot>
</div>

@ -1,9 +1,9 @@
export default {
html: `
<div>
<slot>default fallback content</slot>
<slot name='bar'>bar fallback content</slot>
<slot name='foo'>foo fallback content</slot>
<slot><p>not fallback</p></slot>
<slot name='bar'><p class='default'>bar fallback content</p></slot>
<slot name='foo'><p class='default'>foo fallback content</p></slot>
</div>
`
};

@ -1,4 +1,6 @@
<Nested ref:nested></Nested>
<Nested ref:nested>
<p>not fallback</p>
</Nested>
<script>
import Nested from './Nested.html';

Loading…
Cancel
Save