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

Page <head> content is replaced when <svelte:head> starts with {@html ...} #2805

Closed
trbrc opened this issue May 17, 2019 · 3 comments
Closed

Comments

@trbrc
Copy link
Contributor

trbrc commented May 17, 2019

If <svelte:head> starts with {@html ...} and has additional elements after it, you get a runtime error. Try switching the order in this REPL example, or put any tag before the {@html ...}, and it works: https://svelte.dev/repl/5f5a4608cf10419a832d83c3eb5b695a?version=3.4.1

Chrome: Uncaught DOMException: Failed to execute 'insertAdjacentHTML' on 'Element': The element has no parent.

Safari: NoModificationAllowedError: The object can not be modified.

Firefox: NoModificationAllowedError: Modifications are not allowed for this document

@trbrc
Copy link
Contributor Author

trbrc commented May 17, 2019

Looks like if you start <svelte:head> with a HTML interpolation it simply removes everything else from the head tag. It's compiled to document.head.innerHTML = raw_value;. That would explain the errors when it tries to insert the next element. See the following example, where you can see the default styles being stripped away when the <meta> tag is removed.
https://svelte.dev/repl/41425268ab8647549c15f6e79922a0c4?version=3.4.1

@trbrc trbrc changed the title Runtime error when <svelte:head> starts with {@html ...} Page <head> content is replace when <svelte:head> starts with {@html ...} May 17, 2019
@trbrc trbrc changed the title Page <head> content is replace when <svelte:head> starts with {@html ...} Page <head> content is replaced when <svelte:head> starts with {@html ...} May 17, 2019
@trbrc
Copy link
Contributor Author

trbrc commented May 25, 2019

So I've tracked this down to

if (anchor_before === 'null' && anchor_after === 'null') {
use_innerhtml = true;
detach = `${parent_node}.innerHTML = '';`;
insert = content => `${parent_node}.innerHTML = ${content};`;

I believe the condition should be something equivalent to:

if (anchor_before === 'null' && anchor_after === 'null' && parent_node !== 'document.head') {

That doesn't seem like a good way to achieve it, but something to the same effect. I don't have a good picture of how the compiler works, but I'm thinking it should consult the parent node's .can_use_innerhtml flag somehow?

@Rich-Harris
Copy link
Member

Released 3.4.4 with @cudr's fix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants