There is already bind:innerHTML and bind:textContent implemented for elements with contenteditable="true". But there is also a third property that is also would nice to have: bind:innerText.
InnerText approximates the text the user would get if they highlighted the contents of the element with the cursor and then copied it to the clipboard
I would love to take on this issue! If possible, could someone direct me to where I would need to look to get started here?
I think this binding would apply to non contenteditable elements as well, correct?
@himynameisdave I think it makes no sense to bind to non contenteditable elements. The idea is to have user input inside contenteditable elements synced with the local state. That's what bind is for. Please check the docs (https://svelte.dev/docs#bind_element_property).
@khorpy yep fair point, I'll be sure to only apply it to contenteditable elements in my PR then. Thanks for the feedback!
@khorpy I'm having some slight issues testing this, would you mind providing some examples of the expected values you'd be getting from bind:innerText vs bind:innerHTML?
I can't wait to be able to use this new feature bind:innerText for contenteditable 馃憤 . I need innerText because it handles returns \n.
Is there any known workaround for the time being?
@josdejong not sure about workarounds, but if you could provide some test cases with \n that would be extremely helpful. #4291 is mostly complete, I'm just having some issues around testing it.
Just to explain a bit about my use case: I'm currently working on a proof-of-concept of JSONEditor written in Svelte (my way to learn Svelte). In this editor, I need input fields which automatically fit their contents. For that reason, I'm using contenteditable divs and not a textarea for example. Unfortunately there is no simple way to keep multiline plain text in sync with the contents of an contenteditable div. What comes closest is innerText, but this has serious issues too. Setting the innerText works like a charm, but the other way around, getting innerText, often results in too many return characters. In the JSONEditor, I had to write a custom getInnerText which traverses the HTML contents of the div. Besides that it's tricky to keep the cursor in place whilst typing and getting/setting innerText concurrently.
I hope this new feature bind:innerText will magically solve the issues I've always struggled with using editable divs, but I may be too optimistic 馃槃 . As far as I know there does not exist a solution to keep multiline plain text in sync with the contents of an editable div, which is probably the main reason to use innerText in the first place. It could be a killer feature if Svelte can tackle these complexities once and for all, though it's not trivial. Maybe it shouldn't be named after the (partly broken) innerText and should be named bind:text={text} for example. Just thinking aloud here. If you're interested in thinking this through I may be able to help, I've walked into all traps around dealing editable divs multiple times already 馃槣 .
Here is a small test playground I was using a few days ago to debug issues with .innerText, you can type in both the contenteditable div and the textarea to see how they behave with: https://jsbin.com/begicis/edit?html,output
Beyond the missing binding, I have the impression that there are some bugs with contenteditable.
I tried to isolate a minimal example here:
https://github.com/hbbio/svelte-md
In this demo, a single store containing markdown is used in 3 editors (one HTML, two instances of markdown). Editing the HTML view does trigger updates to the other editors, but editing the markdown only updates the other markdown. This is despite logs showing proper updates to the store.
Also, when rapidly editing text, some substrings get copied erroneously (probably what you mention @josdejong).
I tried some other bindings methods (in other branches) to no avail.
Edit: I updated the repo with a simpler example (without _immer_ and multiple editors), which shows the two different problems: 1. updating the store does not re-render the rich text editor and 2. editing the markdown adds extra characters (using bind:this={elt} and elt.innerText does not work better).
Most helpful comment
Just to explain a bit about my use case: I'm currently working on a proof-of-concept of JSONEditor written in Svelte (my way to learn Svelte). In this editor, I need input fields which automatically fit their contents. For that reason, I'm using contenteditable divs and not a textarea for example. Unfortunately there is no simple way to keep multiline plain text in sync with the contents of an contenteditable div. What comes closest is
innerText, but this has serious issues too. Setting the innerText works like a charm, but the other way around, getting innerText, often results in too many return characters. In the JSONEditor, I had to write a customgetInnerTextwhich traverses the HTML contents of the div. Besides that it's tricky to keep the cursor in place whilst typing and getting/setting innerText concurrently.I hope this new feature
bind:innerTextwill magically solve the issues I've always struggled with using editable divs, but I may be too optimistic 馃槃 . As far as I know there does not exist a solution to keep multiline plain text in sync with the contents of an editable div, which is probably the main reason to useinnerTextin the first place. It could be a killer feature if Svelte can tackle these complexities once and for all, though it's not trivial. Maybe it shouldn't be named after the (partly broken)innerTextand should be namedbind:text={text}for example. Just thinking aloud here. If you're interested in thinking this through I may be able to help, I've walked into all traps around dealing editable divs multiple times already 馃槣 .Here is a small test playground I was using a few days ago to debug issues with
.innerText, you can type in both the contenteditable div and the textarea to see how they behave with: https://jsbin.com/begicis/edit?html,output