- From: Alexandre Elias <aelias@google.com>
- Date: Thu, 09 Feb 2017 05:04: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: <CADeTeo4Es=YkewYOd4gjHQ9XA3AW21UdkTZ65_h=T7ZuN2vnsQ@mail.gmail.com>
> But I cannot really see why we should replace the current spec, which really solves a lot of issues as it is with a severely limited version for which it's not clear if there is a value of having it for most editors. Well, in my view the "restartInput" argument I made earlier basically eliminates almost all the value that preventDefaulting IME events is intended to provide. preventDefaulting an IME event would wind up with a behavior that's basically broken and far inferior to editing the DOM at "input" event time, at least on one platform (and it's very important to us that what we ship is usable on all platforms). What the problem would look like in practice is one of: A) if we always restartInput, then compositions are constantly canceled unnecessarily on JS editors that maintain the plaintext distillation, or B) if we never restartInput, then whenever some JS preventDefaults *without* maintaining the plaintext distillation, then the Android IME would get out of sync and start showing once again those wacky text duplication and deletion bugs that you were complaining about earlier. The only possible remaining value for preventDefaulting is for "rich backspace"-style use cases which actually do intend to modify the plain text distillation, but that's much narrower than what you have in mind. On the other hand, Piotr stated that the conservative proposal still allows "a pretty significant simplification, comparing to what we have to do now." so it sounds like non-cancelable IME beforeinput still would provide value to editors, while being relatively painless and risk-free for UAs. So personally, I'm increasingly convinced after chewing on the discussion so far that our proposal (plus those two 2 additional tweaks) is the best way forward for everyone. -- Alex On Wed, Feb 8, 2017 at 4:14 PM, Johannes Wilm <johannes@fiduswriter.org> wrote: > > > On Wed, Feb 8, 2017 at 5:54 PM, Alexandre Elias <aelias@google.com> wrote: > >> > 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. >> > > Ok, I will let the developer know. Thanks for that! > >> >> > 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. >> > > If all the beforeinput events related to IME can be made cancellable (in > the sense that the IME assumes that the JS does all necessary DOM updates), > then this should be possible. > > Or, if we keep the spec as it is now with all five beforeinput events, > then this exchange an be easily done at the moment the IME process ends. > > > >> >> > 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? >> > > Having this information around cold be very interesting indeed. > > But I wonder whether you are suggesting for JS developers to henceforth > create editors where they have to diff and potentially roll-back all > keyboard input. We were kind of hoping one could do less of that with the > advent of the beforeinput event. Instead of doing all that, I am afraid a > lot of users will simply intercept the keydown and use that instead on > desktop and do as Piotr described on mobile and not care about the > beforeinput event at all. > > As for the touchbar -- true, that is a real painpoint and that seems to be > one of the few use cases left for the beforeinput event if we are to take > in the proposals you guys are making. > > Although I think much more important for the touchbar is to figure out how > to turn it off. > > > >> 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. >> > > When you talk of phantom events, you are talking about phantom events you > mean those of the five events in the IME that Android currently does not > emit, right? These events seem to be real in the Chrome desktop version. If > you fully expect the JS to roll back u to major DOM changes with every key > that is being pressed, why is tiing so crucial when IME is to start so that > you cannot separate the two initial events? I mean some extra complexity > has to come in somewhere to make a working editor. > > Also, on the desktop, deletion in most cases seem to happen outside of > compositions, also for those users who do use IMEs. > > And for keyboard users, this shouldn't be a problem at all. I don't really > get why we create this problem that seems to invalidate the beforeinut > event for a so many use cases out of solidarity with mobile users, when > it's technically only an an isolated issue for mobile users who often won't > have as much of a richtext interface anyway (just look at the mobile html > version of Gmail). And even that is mainly a matter of the Android team not > wanting to add these events, not because it is technically impossible. > > I can see two useful proposals in this: > > * Treating edit flashes as bugs may lead to this being less of a problem. > * Adding the targetranges to the input event so that we can see where > something has happened. This could turn out to be of interest to some > editors. > > > But I cannot really see why we should replace the current spec, which > really solves a lot of issues as it is with a severely limited version for > which it's not clear if there is a value of having it for most editors. > > >> >> -- >> 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 >>> >> >> > > > -- > Johannes Wilm > Fidus Writer > http://www.fiduswriter.org >
Received on Thursday, 9 February 2017 12:59:37 UTC