- From: Alexandre Elias <aelias@google.com>
- Date: Wed, 08 Feb 2017 20:54:55 +0000
- To: Johannes Wilm <johannes@fiduswriter.org>
- Cc: Piotr Koszuliński <p.koszulinski@cksource.com>, Chong Zhang <chongz@chromium.org>, Dave Tapuska <dtapuska@chromium.org>, "public-editing-tf@w3.org" <public-editing-tf@w3.org>
- Message-ID: <CADeTeo5j3HyTthfKtZf+WbDLHe5-j9Q-so_trC8GRAVhzODUgA@mail.gmail.com>
> One of the editors, ProseMirror therefore recently changed to a model where it would let the browser handle changes to text nodes and then roll-back those changes if undesired. The problem was that this lead to "edit flashes" [2] where the user can see the DOM changes twice rapidly. Right, my proposal you described as "babysitting Javascript" would be to treat such "edit flashes" as a UA bug that we could fix (provided the JS DOM change is completed synchronously within scope of input event, and does not change the plaintext distillation). This approach would not require any new web platform API, it would just make the longstanding APIs work better for your use case. > The problem is that the plaintext distillation may eb slightly different, if for example, the JavaScript uses animated gifs for some of the letters I believe this use case can only be solved by the long-term "full model/view/controller" IME solution yosin@ and I ultimately prefer, whereby IME talks to an invisible textbox "model" and JS maps it to any DOM/canvas/WebGL. You need 100% separation between plaintext distillation and user-visible representation to do things like this, and none of the proposals on the table address it. > For example, how do we handle the backspace and delete keys now? We listen to keydown, discover which key was pressed and with what modifiers and delete the content. We might not be able to implement "delete word" or "delete soft line" very precisely, but these are really minor issues. So, in this case the before input wouldn't give us anything. Actually, it'd be even worse than listening to the keydown event because we can cancel the keydown event. Acknowledged, the backspace-to-delete-line problem is quite familiar to me. Note that on Android, IME typically send deleteSurroundingText(1, 0) IME event when soft backspace key is pressed, or even setComposition("hell") (if previous text was currently-being-composed "hello"). So some amount of JS hackery for rich backspace seems unavoidable, unfortunately. > The same with text formatting – we can easily listen to CTRL+B to know whether someone wants to bold a text. The current plan is that we will allow Ctrl-B beforeinput to be one of the few cancelable ones. It never originates from any known IME so it's relatively easy, and there will be no other event fired for Mac OS X touchbar buttons for bold/italic. > However, there's one nasty case which may still require hacking if the event isn't cancelled. It's how the editor can delete the content itself when the user is typing over a non-empty selection. We can't let the browser do that because we wouldn't know how to convert those changes to the model (and sometimes it might simply be impossible). Understood. I'm not a fan of the solutions to this issue proposed so far, but how about this: what if we extend "getTargetRanges()" to work on the "input" event (not only "beforeinput") to indicate what range of text has just been inserted? That should provide the same information as the "deletion/insert" split option, without adding one of those "phantom" events I dislike. Knowing precisely what range has just been inserted, your JS could then remove it from DOM, apply your deletion reconciliation algorithm, and then reinsert it. -- Alex On Wed, Feb 8, 2017 at 9:35 AM, Johannes Wilm <johannes@fiduswriter.org> wrote: > So maybe one could say that as long as a change is limited to only an > inline node, it is ok nott o be cancelabble? > > How about this for example: > > <p>a[bc<span contenteditable=false>def<span contenteditable=true>gh]i</ > span>jkl</span>mno</p> > > or > > <p>ab[c<table>...<tr><td>de]f</td></tr></table>ghi</p> (is this change > inline or block?) > > > Not that these are the most common piece of html to be found in an editor, > but it certainly is something that could be there. I fear a little bit that > every time we say something like "this looks so simple, surely the browser > won't be able to mess that up", we'll find new edge cases where the browser > wasn't able to figure out what to do. And we continue to have to diff it, > make virtual DOMs, etc. > > The point of making input* non-cancellable seems to have been to make > keyboard and IME input be handled by the same JS code as if there was no > difference. Does that seem feasible to you, Piotr? > > On Wed, Feb 8, 2017 at 5:09 PM, Piotr Koszuliński < > p.koszulinski@cksource.com> wrote: > >> >> >> On Wed, Feb 8, 2017 at 4:28 PM, Johannes Wilm <johannes@fiduswriter.org> >> wrote: >> >>> That is very interesting. I am wondering if what you are saying is that >>> it is ok for beforeinput events not to be cancelable as long as they don't >>> affect more than a single text node and if they change anything beyond that >>> you really need to start diffing or using other kinds of events? >>> >> >> >> Not exactly. It's acceptable if we can't cancel events which default >> actions are "local". I mean, if I make such a selection: >> >> <h1>a[b</h1> >> <p>c]d</p> >> >> And press "x", then someone needs to delete "b" and "c", perhaps merge >> those two blocks and move the selection to a correct place. We want to >> control that behaviour, because there are couple of potential results. E.g. >> Chrome tends to a lot of mess with inline elements and styles when merging >> two blocks. We must prevent that. >> >> Currently, we prevent that by discovering the keydown event, checking >> that (**most likely**) it means inserting the "x" letter. So what we do >> now, is that we call our internal deleteContent() method which results in: >> >> <h1>a[]</h1><p>d</p> >> >> and let the browser insert "x" after "a". >> >> The situation is a bit simpler if we have a selection like: >> >> <p><b>a[b</b>c]d</p> >> >> If we wouldn't be able to call our deleteContent() method for that >> content because, for example, a composition takes place and if the browser >> would insert the composed text outside the <b> element (let's assume we >> want it to be inside), it's okeysh if we fix that after composition has >> ended. It's not perfect, but it's acceptable because the expected result >> isn't much different from what browser produced. >> >> >> > > > > -- > Johannes Wilm > Fidus Writer > http://www.fiduswriter.org >
Received on Wednesday, 8 February 2017 21:46:20 UTC