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

unexpected behavior using unwrapped html expression as component output #2711

Closed
CreaturesInUnitards opened this issue May 7, 2019 · 6 comments

Comments

@CreaturesInUnitards
Copy link
Contributor

https://svelte.dev/repl/98745830909e4c88979965fe00a8ba3a?version=3.2.1

Repro Steps:

  1. change the text in any field to modify the alphabetical order
  2. change the focus

Repros in Chrome, FF, Safari. Svelte 3.2.1

Doesn't repro if the html expression is wrapped in an html tag by itself

@EmilTholin
Copy link
Member

Hi @CreaturesInUnitards! Very interesting. It happens if the HTML string is in the topmost component as well. If you as an experiment remove the each block key and change the ordering, the HTML isn't duplicated.

@sanderhahn
Copy link
Contributor

Here is a minimal example that shows the same problem: https://svelte.dev/repl/8d71f3064391458aae9f917c3b693888?version=3. The problem seems to be related to the keyed each, because non-keyed each makes the problem go away.

@sanderhahn
Copy link
Contributor

sanderhahn commented May 9, 2019

Have been trying to figure out what causes this. Think that the code for the indexed each will not call the d() that is made in its create_each_block, because no keys are removed. However the m() code does an insertAdjacentHTML call. So it seems to duplicate HTML on every mount call. The trouble is that it is impossible to create the HTML node beforehand without a parent element.

One way to solve this might be to call the detach logic when the node is mounted. However this logic must be called before the <noscript> markers are moved. Adding detach logic on the insert in the RawMustacheTagWrapper failed because of this...

@sanderhahn
Copy link
Contributor

Maybe it is a pragmatic idea to make it a syntax error to have an {@html ...} outside of an element. This gives the user less control about the actual html structure. However it makes it easier/more efficient to handle without the need for <noscript> markers. For instance React also uses a property on an element: https://reactjs.org/docs/dom-elements.html#dangerouslysetinnerhtml. Vue does have mustache markers but also a v-html directive on an element. Literal html should also be discouraged because of potential security issues :)

@Ryuno-Ki
Copy link

Ryuno-Ki commented May 9, 2019

However the m() code does an insertAdjacentHTML call. So it seems to duplicate HTML on every mount call. The trouble is that it is impossible to create the HTML node beforehand without a parent element.

I haven't touched Svelte code so far … but in Vanilla JS, you could use a DocumentFragment for it, I guess.

@sanderhahn
Copy link
Contributor

Adding arbitrary html to a documentFragment using something like innerHTML seems not possible. So you would still need a nesting element. Seems that both Vue and React only allow arbitrary html on an element using a directive (v-html and dangerouslySetInnerHTML). So it might not be strange to enforce such a limitation...

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

4 participants