Skip to content

Commit

Permalink
[fix] Fix hydration duplicate svelte:head tag issue with @html ex…
Browse files Browse the repository at this point in the history
…pressions and nested components (#7745)

* Fix hydration duplicate `svelte:head` tag issue with `@html` and nested components #7444 #6463

* - Changed comment style to HEAD_${head_id}_START and HEAD_${head_id}_END
- Improved claim logic
- Changed tests accordingly
  • Loading branch information
Maximiliano Ruani authored Sep 11, 2022
1 parent 7ac3854 commit 8ffc8fd
Show file tree
Hide file tree
Showing 19 changed files with 110 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/compiler/compile/render_dom/wrappers/Head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export default class HeadWrapper extends Wrapper {
let nodes;
if (this.renderer.options.hydratable && this.fragment.nodes.length) {
nodes = block.get_unique_name('head_nodes');
block.chunks.claim.push(b`const ${nodes} = @query_selector_all('[data-svelte="${this.node.id}"]', @_document.head);`);
block.chunks.claim.push(b`const ${nodes} = @head_selector('${this.node.id}', @_document.head);`);
}

this.fragment.render(block, x`@_document.head` as unknown as Identifier, nodes);
Expand Down
4 changes: 0 additions & 4 deletions src/compiler/compile/render_ssr/handlers/Element.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,6 @@ export default function (node: Element, renderer: Renderer, options: RenderOptio
}
});

if (options.hydratable && options.head_id) {
renderer.add_string(` data-svelte="${options.head_id}"`);
}

renderer.add_string('>');

if (node_contents !== undefined) {
Expand Down
2 changes: 1 addition & 1 deletion src/compiler/compile/render_ssr/handlers/Head.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ export default function(node: Head, renderer: Renderer, options: RenderOptions)
renderer.render(node.children, head_options);
const result = renderer.pop();

renderer.add_expression(x`$$result.head += ${result}, ""`);
renderer.add_expression(x`$$result.head += '<!-- HEAD_${node.id}_START -->' + ${result} + '<!-- HEAD_${node.id}_END -->', ""`);
}
21 changes: 21 additions & 0 deletions src/runtime/internal/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,27 @@ export function query_selector_all(selector: string, parent: HTMLElement = docum
return Array.from(parent.querySelectorAll(selector)) as ChildNodeArray;
}

export function head_selector(nodeId: string, head: HTMLElement) {
const result = [];
let started = 0;

for (const node of head.childNodes) {
if (node.nodeType === 8 /* comment node */) {
const comment = node.textContent.trim();
if (comment === `HEAD_${nodeId}_END`) {
started -= 1;
result.push(node);
} else if (comment === `HEAD_${nodeId}_START`) {
started += 1;
result.push(node);
}
} else if (started > 0) {
result.push(node);
}
}
return result;
}

export class HtmlTag {
private is_svg = false;
// parent for creating node
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{@html '<meta name="head_nested_html" content="head_nested_html">'}
<meta name="head_nested" content="head_nested">
5 changes: 5 additions & 0 deletions test/hydration/samples/head-html-and-component/Nested.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

<svelte:head>
{@html '<meta name="nested_html" content="nested_html">'}
<meta name="nested" content="nested">
</svelte:head>
Empty file.
12 changes: 12 additions & 0 deletions test/hydration/samples/head-html-and-component/_after_head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!-- HEAD_svelte-17ibcve_START -->
<!-- HTML_TAG_START --><meta name="main_html" content="main_html"><!-- HTML_TAG_END -->
<meta name="main" content="main">
<!-- HTML_TAG_START --><meta name="head_nested_html" content="head_nested_html"><!-- HTML_TAG_END -->
<meta name="head_nested" content="head_nested">
<!-- HEAD_svelte-17ibcve_END -->

<!-- HEAD_svelte-1gqzvnn_START -->
<!-- HTML_TAG_START --><meta name="nested_html" content="nested_html"><!-- HTML_TAG_END -->
<meta name="nested" content="nested">
<!-- HEAD_svelte-1gqzvnn_END -->

Empty file.
11 changes: 11 additions & 0 deletions test/hydration/samples/head-html-and-component/_before_head.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- HEAD_svelte-17ibcve_START -->
<!-- HTML_TAG_START --><meta name="main_html" content="main_html"><!-- HTML_TAG_END -->
<meta name="main" content="main">
<!-- HTML_TAG_START --><meta name="head_nested_html" content="head_nested_html"><!-- HTML_TAG_END -->
<meta name="head_nested" content="head_nested">
<!-- HEAD_svelte-17ibcve_END -->

<!-- HEAD_svelte-1gqzvnn_START -->
<!-- HTML_TAG_START --><meta name="nested_html" content="nested_html"><!-- HTML_TAG_END -->
<meta name="nested" content="nested">
<!-- HEAD_svelte-1gqzvnn_END -->
12 changes: 12 additions & 0 deletions test/hydration/samples/head-html-and-component/main.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script>
import HeadNested from './HeadNested.svelte';
import Nested from './Nested.svelte';
</script>

<svelte:head>
{@html '<meta name="main_html" content="main_html">'}
<meta name="main" content="main">
<HeadNested />
</svelte:head>

<Nested/>
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<title>Some Title</title>
<link href="/" rel="canonical">
<meta content="some description" name="description">
<meta content="some keywords" name="keywords">
<!-- HEAD_svelte-1s8aodm_START -->
<link rel="canonical" href="/">
<meta name="description" content="some description">
<meta name="keywords" content="some keywords">
<!-- HEAD_svelte-1s8aodm_END -->
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<title>Some Title</title>
<link rel="canonical" href="/" data-svelte="svelte-1s8aodm">
<meta name="description" content="some description" data-svelte="svelte-1s8aodm">
<meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm">
<!-- HEAD_svelte-1s8aodm_START -->
<link rel="canonical" href="/">
<meta name="description" content="some description">
<meta name="keywords" content="some keywords">
<!-- HEAD_svelte-1s8aodm_END -->
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{@html '<meta name="head_nested_html" content="head_nested_html">'}
<meta name="head_nested" content="head_nested">
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

<svelte:head>
{@html '<meta name="nested_html" content="nested_html">'}
<meta name="nested" content="nested">
</svelte:head>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!-- HEAD_svelte-17ibcve_START -->
<!-- HTML_TAG_START --><meta name="main_html" content="main_html"><!-- HTML_TAG_END -->
<meta name="main" content="main">
<!-- HTML_TAG_START --><meta name="head_nested_html" content="head_nested_html"><!-- HTML_TAG_END -->
<meta name="head_nested" content="head_nested">
<!-- HEAD_svelte-17ibcve_END -->

<!-- HEAD_svelte-1gqzvnn_START -->
<!-- HTML_TAG_START --><meta name="nested_html" content="nested_html"><!-- HTML_TAG_END -->
<meta name="nested" content="nested">
<!-- HEAD_svelte-1gqzvnn_END -->
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script>
import HeadNested from './HeadNested.svelte';
import Nested from './Nested.svelte';
</script>

<svelte:head>
{@html '<meta name="main_html" content="main_html">'}
<meta name="main" content="main">
<HeadNested />
</svelte:head>

<Nested/>
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<title>Some Title</title>
<link rel="canonical" href="/" data-svelte="svelte-1s8aodm">
<meta name="description" content="some description" data-svelte="svelte-1s8aodm">
<meta name="keywords" content="some keywords" data-svelte="svelte-1s8aodm">
<!-- HEAD_svelte-1s8aodm_START -->
<link rel="canonical" href="/">
<meta name="description" content="some description">
<meta name="keywords" content="some keywords">
<!-- HEAD_svelte-1s8aodm_END -->

0 comments on commit 8ffc8fd

Please sign in to comment.