Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[fix] Fix hydration duplicate svelte:head tag issue with @html expressions and nested components #7745

Merged
merged 2 commits into from
Sep 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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_START data-svelte="${node.id}" -->' + ${result} + '<!-- HEAD_END data-svelte="${node.id}" -->', ""`);
maxiruani marked this conversation as resolved.
Show resolved Hide resolved
}
18 changes: 18 additions & 0 deletions src/runtime/internal/dom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,24 @@ 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 */ && node.textContent.trim() === `HEAD_END data-svelte="${nodeId}"`) {
started -= 1;
result.push(node);
} else if (node.nodeType === 8 /* comment node */ && node.textContent.trim() === `HEAD_START data-svelte="${nodeId}"`) {
started += 1;
result.push(node);
} else if (started > 0) {
result.push(node);
}
maxiruani marked this conversation as resolved.
Show resolved Hide resolved
}
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_START data-svelte="svelte-17ibcve" -->
<!-- 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_END data-svelte="svelte-17ibcve" -->

<!-- HEAD_START data-svelte="svelte-1gqzvnn" -->
<!-- HTML_TAG_START --><meta name="nested_html" content="nested_html"><!-- HTML_TAG_END -->
<meta name="nested" content="nested">
<!-- HEAD_END data-svelte="svelte-1gqzvnn" -->

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_START data-svelte="svelte-17ibcve" -->
<!-- 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_END data-svelte="svelte-17ibcve" -->

<!-- HEAD_START data-svelte="svelte-1gqzvnn" -->
<!-- HTML_TAG_START --><meta name="nested_html" content="nested_html"><!-- HTML_TAG_END -->
<meta name="nested" content="nested">
<!-- HEAD_END data-svelte="svelte-1gqzvnn" -->
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_START data-svelte="svelte-1s8aodm" -->
<link rel="canonical" href="/">
<meta name="description" content="some description">
<meta name="keywords" content="some keywords">
<!-- HEAD_END data-svelte="svelte-1s8aodm" -->
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_START data-svelte="svelte-1s8aodm" -->
<link rel="canonical" href="/">
<meta name="description" content="some description">
<meta name="keywords" content="some keywords">
<!-- HEAD_END data-svelte="svelte-1s8aodm" -->
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">
tanhauhau marked this conversation as resolved.
Show resolved Hide resolved
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,12 @@
<!-- HEAD_START data-svelte="svelte-17ibcve" -->
<!-- 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_END data-svelte="svelte-17ibcve" -->

<!-- HEAD_START data-svelte="svelte-1gqzvnn" -->
<!-- HTML_TAG_START --><meta name="nested_html" content="nested_html"><!-- HTML_TAG_END -->
<meta name="nested" content="nested">
<!-- HEAD_END data-svelte="svelte-1gqzvnn" -->

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_START data="svelte-1s8aodm" -->
<link rel="canonical" href="/">
<meta name="description" content="some description">
<meta name="keywords" content="some keywords">
<!-- HEAD_END data="svelte-1s8aodm" -->