Skip to content

Commit

Permalink
Merge pull request #2880 from cudr/head_html_fix
Browse files Browse the repository at this point in the history
repair dynamic {@html} in head
  • Loading branch information
Rich-Harris authored May 27, 2019
2 parents ed72aea + 7071ce8 commit e291893
Show file tree
Hide file tree
Showing 14 changed files with 142 additions and 17 deletions.
2 changes: 1 addition & 1 deletion src/compile/render-dom/Block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export default class Block {

if (parent_node) {
this.builders.mount.add_line(`@append(${parent_node}, ${name});`);
if (parent_node === 'document.head') this.builders.destroy.add_line(`@detach(${name});`);
if (parent_node === 'document.head' && !no_detach) this.builders.destroy.add_line(`@detach(${name});`);
} else {
this.builders.mount.add_line(`@insert(#target, ${name}, anchor);`);
if (!no_detach) this.builders.destroy.add_conditional('detaching', `@detach(${name});`);
Expand Down
4 changes: 2 additions & 2 deletions src/compile/render-dom/wrappers/Head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,6 @@ export default class HeadWrapper extends Wrapper {
}

render(block: Block, parent_node: string, parent_nodes: string) {
this.fragment.render(block, 'document.head', null);
this.fragment.render(block, 'document.head', 'nodes');
}
}
}
23 changes: 14 additions & 9 deletions src/compile/render-dom/wrappers/IfBlock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -154,16 +154,18 @@ export default class IfBlockWrapper extends Wrapper {

const vars = { name, anchor, if_name, has_else, has_transitions };

const detaching = (parent_node && parent_node !== 'document.head') ? '' : 'detaching';

if (this.node.else) {
if (has_outros) {
this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars);
this.render_compound_with_outros(block, parent_node, parent_nodes, dynamic, vars, detaching);

block.builders.outro.add_line(`if (${name}) ${name}.o();`);
} else {
this.render_compound(block, parent_node, parent_nodes, dynamic, vars);
this.render_compound(block, parent_node, parent_nodes, dynamic, vars, detaching);
}
} else {
this.render_simple(block, parent_node, parent_nodes, dynamic, vars);
this.render_simple(block, parent_node, parent_nodes, dynamic, vars, detaching);

if (has_outros) {
block.builders.outro.add_line(`if (${name}) ${name}.o();`);
Expand Down Expand Up @@ -201,7 +203,8 @@ export default class IfBlockWrapper extends Wrapper {
parent_node: string,
parent_nodes: string,
dynamic,
{ name, anchor, has_else, if_name, has_transitions }
{ name, anchor, has_else, if_name, has_transitions },
detaching
) {
const select_block_type = this.renderer.component.get_unique_name(`select_block_type`);
const current_block_type = block.get_unique_name(`current_block_type`);
Expand Down Expand Up @@ -254,7 +257,7 @@ export default class IfBlockWrapper extends Wrapper {
`);
}

block.builders.destroy.add_line(`${if_name}${name}.d(${parent_node ? '' : 'detaching'});`);
block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`);
}

// if any of the siblings have outros, we need to keep references to the blocks
Expand All @@ -264,7 +267,8 @@ export default class IfBlockWrapper extends Wrapper {
parent_node: string,
parent_nodes: string,
dynamic,
{ name, anchor, has_else, has_transitions }
{ name, anchor, has_else, has_transitions },
detaching
) {
const select_block_type = this.renderer.component.get_unique_name(`select_block_type`);
const current_block_type_index = block.get_unique_name(`current_block_type_index`);
Expand Down Expand Up @@ -375,7 +379,7 @@ export default class IfBlockWrapper extends Wrapper {
}

block.builders.destroy.add_line(deindent`
${if_current_block_type_index}${if_blocks}[${current_block_type_index}].d(${parent_node ? '' : 'detaching'});
${if_current_block_type_index}${if_blocks}[${current_block_type_index}].d(${detaching});
`);
}

Expand All @@ -384,7 +388,8 @@ export default class IfBlockWrapper extends Wrapper {
parent_node: string,
parent_nodes: string,
dynamic,
{ name, anchor, if_name, has_transitions }
{ name, anchor, if_name, has_transitions },
detaching
) {
const branch = this.branches[0];

Expand Down Expand Up @@ -450,6 +455,6 @@ export default class IfBlockWrapper extends Wrapper {
}
`);

block.builders.destroy.add_line(`${if_name}${name}.d(${parent_node ? '' : 'detaching'});`);
block.builders.destroy.add_line(`${if_name}${name}.d(${detaching});`);
}
}
15 changes: 12 additions & 3 deletions src/compile/render-dom/wrappers/RawMustacheTag.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,18 @@ export default class RawMustacheTagWrapper extends Tag {
render(block: Block, parent_node: string, parent_nodes: string) {
const name = this.var;

const in_head = parent_node === 'document.head';
const needs_anchors = !parent_node || in_head;

// if in head always needs anchors
if (in_head) {
this.prev = null;
this.next = null;
}

// TODO use is_dom_node instead of type === 'Element'?
const needs_anchor_before = this.prev ? this.prev.node.type !== 'Element' : !parent_node;
const needs_anchor_after = this.next ? this.next.node.type !== 'Element' : !parent_node;
const needs_anchor_before = this.prev ? this.prev.node.type !== 'Element' : needs_anchors;
const needs_anchor_after = this.next ? this.next.node.type !== 'Element' : needs_anchors;

const anchor_before = needs_anchor_before
? block.get_unique_name(`${name}_before`)
Expand Down Expand Up @@ -90,7 +99,7 @@ export default class RawMustacheTagWrapper extends Tag {

block.builders.mount.add_line(insert(init));

if (!parent_node) {
if (needs_anchors) {
block.builders.destroy.add_conditional('detaching', needs_anchor_before
? `${detach}\n@detach(${anchor_before});`
: detach);
Expand Down
2 changes: 1 addition & 1 deletion test/runtime/samples/head-if-block/_config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ export default {
component.condition = true;
assert.equal(window.document.title, 'woo!!!');
}
};
};
2 changes: 1 addition & 1 deletion test/runtime/samples/head-if-block/main.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@
{#if condition}
<title>woo!!!</title>
{/if}
</svelte:head>
</svelte:head>
14 changes: 14 additions & 0 deletions test/runtime/samples/head-if-else-block/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export default {
props: {
condition: false
},

test({ assert, component, target, window }) {
assert.equal(window.document.title, '');
assert.equal(Boolean(window.document.getElementById('meta')), true);

component.condition = true;
assert.equal(window.document.title, 'woo!!!');
assert.equal(window.document.getElementById('meta'), null);
}
};
11 changes: 11 additions & 0 deletions test/runtime/samples/head-if-else-block/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
export let condition;
</script>

<svelte:head>
{#if condition}
<title>woo!!!</title>
{:else}
<meta id="meta" name="title" content="woo!!!"/>
{/if}
</svelte:head>
19 changes: 19 additions & 0 deletions test/runtime/samples/head-if-else-raw-dynamic/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
const foo = '<script type="application/json">{ "foo": "true" }</script>';
const bar = '<script type="application/json">{ "bar": "true" }</script>';

export default {
props: {
condition: false,
foo,
bar
},

test({ assert, component, window }) {
assert.equal(window.document.head.innerHTML.includes(foo), false);
assert.equal(window.document.head.innerHTML.includes(bar), true);

component.condition = true;
assert.equal(window.document.head.innerHTML.includes(foo), true);
assert.equal(window.document.head.innerHTML.includes(bar), false);
}
};
11 changes: 11 additions & 0 deletions test/runtime/samples/head-if-else-raw-dynamic/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
export let condition, foo, bar;
</script>

<svelte:head>
{#if condition}
{@html foo}
{:else}
{@html bar}
{/if}
</svelte:head>
11 changes: 11 additions & 0 deletions test/runtime/samples/head-raw-dynamic/Bar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script>
export let bar;
</script>

<svelte:head>
<meta id="meta" name="title" content="bar!!!"/>
{#if true}
{@html bar}
{/if}
<title>bar!!!</title>
</svelte:head>
7 changes: 7 additions & 0 deletions test/runtime/samples/head-raw-dynamic/Foo.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<script>
export let foo;
</script>

<svelte:head>
{@html foo}
</svelte:head>
26 changes: 26 additions & 0 deletions test/runtime/samples/head-raw-dynamic/_config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const foo = '<script type="application/json">{ "foo": "true" }</script>';
const bar = '<script type="application/json">{ "bar": "true" }</script>';

export default {
props: {
condition: 1,
foo,
bar
},

test({ assert, component, window }) {
assert.equal(window.document.head.innerHTML.includes(foo), true);

component.condition = false;
assert.equal(window.document.head.innerHTML.includes(foo), false);

component.condition = 2;
assert.equal(window.document.title, 'bar!!!');
assert.equal(window.document.head.innerHTML.includes(bar), true);
assert.equal(Boolean(window.document.getElementById('meta')), true);

component.condition = false;
assert.equal(window.document.head.innerHTML.includes(bar), false);
assert.equal(window.document.getElementById('meta'), null);
}
};
12 changes: 12 additions & 0 deletions test/runtime/samples/head-raw-dynamic/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script>
import Foo from './Foo.svelte';
import Bar from './Bar.svelte';

export let condition, foo, bar;
</script>

{#if condition === 1}
<Foo {foo} />
{:else if condition === 2}
<Bar {bar} />
{/if}

0 comments on commit e291893

Please sign in to comment.