- From: Piotr Koszuliński <p.koszulinski@cksource.com>
- Date: Wed, 8 Feb 2017 15:59:32 +0100
- To: Johannes Wilm <johannes@fiduswriter.org>
- Cc: Alexandre Elias <aelias@google.com>, Dave Tapuska <dtapuska@chromium.org>, Chong Zhang <chongz@chromium.org>, "public-editing-tf@w3.org" <public-editing-tf@w3.org>
- Message-ID: <CAFk9newHafRJXLH9t=WtA=uW6zbsESnrGQXeejyoBS4Eb2eXzA@mail.gmail.com>
Hey, I won't try to go too deep into how IME related events should work because I don't know IME mechanisms and all its variations well enough, despite working with cE for more than 5 years. Perhaps, this answers some questions like how hard IME is actually and what's the average knowledge about it, even amongst quite experienced RTE developers ;). Anyway, I'd like to rather focus on how non-preventable the beforeinput event can be to make any value for CKEditor 5. I hope it will provide some context for the discussion. ### Text insertion ############ A couple of months ago I created a PoC of CKEditor 5's typing feature working based on the beforeinput event available at that time in Blink [1]. Unfortunately, I can't quickly check how the editor would behave if the event wasn't cancelled, but that would be very similar to how the editor needs to work without the beforeinput event. So how it works now? 1. We use a mutation observer to catch the input (typed characters). There's a special case when selection isn't empty when the user starts to type. We needed to hardcode the unsafe keys and delete the selected content on keydown. Otherwise, typing a single letter might cause hundreds of mutations if selection crossed some complicated content. We must avoid that. 2. We diff the DOM with our virtual DOM implementation to get a simplified form of the mutations. Browser may fire dozens of them, while for us it can be just a few changed text nodes or removed elements. 3. Then we analyse the mutations. We try to find a fragment of removed and inserted text, plus, the position of the selection after the change. 4. Then, if a feature (in this case, the typing feature) can handle certain mutations (i.e. they were not too complex) it applies the necessary changes to the model. 5. The changes in the model are converted to the virtual DOM. 6. If virtual DOM differs from the real DOM, minimal changes are applied. This architecture allows us to: * Apply understandable changes to the model, without re-rendering the DOM. This is crucial to support IME because some changes in the DOM break the composition (see the "IME" section in [1]). * Re-render the DOM before paint happens if changes were rejected by the editor. That, fortunately, needs to happen very rarely, but it's nice that there's no flickering anyway. How would beforeinput simplify our implementation? * We wouldn't need to listen to mutations and normalize them (1. & 2.). * We wouldn't need that ugly unsafe keys handler meant to empty the selection before a character is inserted (1.). * We would avoid the diffing mechanism, which is quite complex already despite missing few edge cases with spell checking or auto correction (3.). * We would have a perfect clarity whether the inserted space was meant to be a space or non-breaking space (it's problem to learn that when it's at the end of a block). * Etc, etc. So, that's the profit even if we can't cancel the event. It's still a pretty significant simplification, comparing to what we have to do now. 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). In general, there are a couple of options here. * If we'd be able to cancel all beforeinput events, that would be perfect, because we'd be able to handle the deletion of the content by ourselves first, and then we'd insert the typed characters. * If the beforeinput event is not cancellable, then: * it'd be nice if for the non-empty selection there would be a beforeinput with type=deleteContent fired before beforeinput with type=insert* (that would natively split the process into two steps – deletion and insertion), * alternatively, we should be able to change the DOM on beforeinput event without breaking the native insertion itself (then we can simply delete the selected content and set selection in a correct place, where the new character should be inserted). One of these options must be true because, otherwise, we won't be able to use the event. We'd still need to base on some ugly heuristic for discovering keys which are about to delete the content of the selection. What I don't know is how these options apply to IME. Let's assume that its events are non-cancellable, so we get some beforeinput event of delete* type followed by insertCompositionText. The deletion part is unclear for me because the insertion might've been in a middle of composition (so you get deleteCompositionText + insertCompositionText) or it might be the first composed character. What do we get in this case? I'm asking because I assume that when the user is composing already, the browser will never do some significant DOM changes. Composition would normally only touch the text nodes in a certain block, but not the block itself. Besides, while composition takes place, we're not able to re-render the DOM anyway, because that breaks the composition (see the "IME section in [1]). So, if something is wrong, we need to wait for the composition to finish anyway. But this is acceptable because I don't expect significant changes to be required. Maybe just some inline styling. However, if the insertion starts the composition, then the content which was previously selected might contain multiple blocks, tables, etc. and we must handle deletion of that piece ourselves. So, at least in this case, we must be able to either act upon inserComopositionText or there must be a separate deleteContent event. Uhh... that was about text insertion. ### Other beforeinput types ################## A non-cancellable beforeinput for the text insertion (and text deletion) is acceptable (with couple limitations, as I tried to explain above). However, other before input events must be cancellable. Otherwise, there will be quite pointless. 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. The same with text formatting – we can easily listen to CTRL+B to know whether someone wants to bold a text. We can cancel the keydown event. It'd be much worse if we had to listen to the beforeinput event and fix the DOM broken by the browser which incorrectly applied some <b> tag. The beforeinput event would only help with localizing the keystroke (in some languages it won't be CTRL+B). And so on, and so on. I can understand that IME makes some beforeinput events non-cancellable. But I totally don't understand why would deleteContentForward or insertUndeorderList be non-cancellable too (as was proposed in the document [2]). The set of non-cancellable events should be minimal. Otherwise, the situation is not going to improve. [1] https://github.com/w3c/editing/issues/149 [2] https://docs.google.com/document/d/1yPZEkHl_WOPjVeilZjE1XmlyjLCe-uS7THI0SboyrMM/edit# -- Best Regards, Piotrek Koszuliński | CKEditor Lead Developer -- CKSource – http://cksource.com | Follow CKSource on: Twitter <http://twitter.com/cksource> | Facebook <http://www.facebook.com/cksource> | Google+ <https://plus.google.com/+CKSource> | LinkedIn <http://www.linkedin.com/company/cksource> On Wed, Feb 8, 2017 at 12:46 PM, Johannes Wilm <johannes@fiduswriter.org> wrote: > > > On Wed, Feb 8, 2017 at 3:56 AM, Alexandre Elias <aelias@google.com> wrote: > >> OK, thanks for the clarifications. >> >> For me the bottom line I want to achieve is to have 1-to-1 mapping >> between IME commands intended to mutate text and beforeinput+input pairs. >> I don't like the idea of splitting any one of them into fragmentary pieces >> nor of generating phantom ones not corresponding to any text mutation. >> That generates unnecessary side effects and is difficult to reason about. >> >> Sometimes this would cause "natural" platform differences based on the >> different behavior of the actual IMEs, and that's fine because that likely >> means a different user-facing UX that JS would also need to conform to. On >> Android in the replacement scenario described, there is exactly one >> mutation where the nodes are both collapsed and replaced by the new word, >> so there should be exactly one input event. On Mac OS X there is first a >> visible collapse at the beginning of the composition, then (later on) a >> change to the new word, so there should be exactly two input events. I'm >> okay with such "natural" complexity but not with artificial >> spec-originating complexity. >> >> The idea of supporting a "preventDefault" on a fragmentary or phantom >> event is particularly alarming to me, because I think "preventDefault" >> should always be implemented by UAs as a simple early-return not performing >> some action. >> > But the implication of "preventDefault" on a phantom event is that the UA >> needs to proactively change the text when preventDefault is called but do >> nothing when it isn't, which is weird and bound to lead to a cascade of >> complexity. In my way of seeing things, "cancelability" is not a sane >> basis for fragmenting events, and the fragmenting is even counterproductive >> to permitting workable cancelability. (That's why I assumed the reason for >> the split might be a "cannot-replace" assumption.) >> > > That wasn't ever the intention. But course, having IME behave more > similarly across browsers would be an advantage. It used to be the case > that Chrome on desktop at the end of the composition would first remove the > entire compositionstring and would then readd it. This was very convenient > and it is why we made the last two events. From you description of it, you > either no longer have those two things happening or you just don't have it > on Android. That is less ideal. > > Ultimately I cannot see why IME input should not be standardized in some > way when everything else is standardized. > > > Imagine if instead of having keyboard, every country had inevented a > diferent inut device. Most developers would likely support the devices of > Germany, US, UK, France. But the input devices of Denmark and Nicaragua > would have more difficulty finding traction. Some Asian countries that > mainly use IME have a lot of population and Android is more popular than > many desktop operating systems, but a lot of richtext editing is mainly > confined to desktop (mobile clients often just have a function to write > two-three words without styling which is realistic for someone on a metro > to be doing) and a lot of things are mainly done in the European languages. > > > For example, we may think that everyone should be able to write a W3C spec > on their mobile phone in any possible langage, but in practice it will > almost always be on done on dekstop and it will almost always be with > keyboard input. In order to get support for the 1% of writers who will use > IME anyway, it would be of great help for the IME in those 1% to behave the > same way and not have 100 different IMEs with different behavor as that > will mean that the JS developer will have to spend much more time than what > is reasonable on something that is ultimately doesn't make any economic > sense. > > So instead of dealing with all this complexity and hundreds of different > ways of doing it, JS editors often decide that it's "good enough" to just > diff the DOM before and after and then have a rough idea of what the user > was trying to do. > > >> >> > I don't quite get what you mean by combining steps two and three. >> Step two was the reinsertion of the initial composition string into the >> DOM. Step three is the change during the composition. There will usually be >> many step threes, but only one step two. >> >> I simply meant combining step 2 into the first of the step 3s. >> >> > There is one problem in that compositionend with data="" could mean >> the composition has been cancelled or that the final compositionstring is >> empty. >> >> I propose to solve it always sending another step-3-style >> insertCompositionText("") before the compositionEnd in the case that the >> text is cleared, and no input event in the cancellation case. Then there >> would be no need to ever look at the data field of compositionEnd. >> > > If it doesn't read the data attribute of compositionEnd, then the JS will > have to follow all the compositionupdate events to figure out what the > final string will be, right? And as long as the beforeinput events related > to IME cannot be canceled and one has to wait for the entire IME string to > be done, the JS will have to calculate and combine what the total > targetrange of the composition is, right? If we don't really give the JS > developers anythign new with the beofreinput event, why would it be used? > Why wouldn't they just continue to diff the relevant part of the DOM? > > >> >> > Btw -- just to make it clear because this seems to have been a common >> misconception between JS developers and browser developers in the past: >> When we ask for these things to be cancelable, in 80% of cases this is not >> because we want to stop the user from doing things. It's more than we want >> to do the corresponding DOM changes in JS code, because they are specific >> to the JS editor the user is currently using and they may not necessarily >> make sense to the browser. >> >> That's useful context. But my take from this is that beforeinput >> preventDefaulting in *any* form cannot be used to meet this use case, at >> least on Android. Reason: on Android, we need to call the IME with >> "restartInput()" whenever the text changes unexpectedly, which fully >> reinitializes the IME and cancels ongoing compositions. This call is not >> at all desirable or needed if the JS editor is doing essentially the same >> thing as the default implementation would have. But unfortunately, there >> is no sane way for UAs to know whether the JS is "trying" to stop the >> action or if it's "trying" to recreate it. We'd have to bias towards >> oversending or undersending restartInput, likely via unreliable >> heuristics. The bugginess would be severe with either kind of bias. >> >> An alternate proposal: what if, when JS modifies the DOM within the scope >> of any "input" event, then the UA would run a before/after comparison to >> verify whether the summation of JS changes wound up changing the plain >> text distillation of the DOM (and therefore whether it's provable that the >> IME can sit blissfully unaware that anything strange happened). If the >> plain text representation changed, then the UA would always send >> restartInput and cancel composition, as UAs largely do in response to >> unexpected JS changes today. But if the only thing that changed was >> styling or other rich DOM substructure, the UA would *not* send >> restartInput and it would also reconstruct the composition range to keep it >> at the same plain-text-character offsets against the new DOM nodes. >> > > > Ok, this would kind of be to babysit the JavaScript, right? The problem is > that the plaintext distillation may eb slightly different, if for example, > the JavaScript uses animated gifs for some of the letters, or if it needs > to insert an empty space node. So I would prefer to say that all > preventdefualting of beforeinput will always jsut prevent the DOM update > from going through, but not for the action behdind it to be cancelled (we > did discuss at an earlier meeting if it was possible to make two types of > preventdefault to be able to distinguish between them). But yes, your > proposal does sound better than what we had until now and should work under > almost all cricumstances (editors that insert animated gifs just have to > add those when the composition is done). > > >> >> In this model, the JS editor would need to stash a copy of the previous >> DOM at time of "beforeinput", allow the "input" to happen, and then >> reconstruct the rich structure. Then we could avoid the entire can of >> worms of what particular IME events are "cancelable" or not and how to work >> around cases where they are not. >> > > I don't understand. Keeping the DOM at the start of the composition and > diffing when it's done, etc. is what is happening already. The beforeinput > event seems to not add much value for that. > > I thought you had just made a suggestion on how to make beforeinput events > during IME cancelable. > > To sum up, these two would give an advantage over todays situation: > > 1. Have all five beforeinput events, of which the middle three are not > cancelable and the first two only happen if one is recomposing. The 1st and > the last of these events can be used by JS to adjust the IME so that it > happens where it should and the final result is placed according to its own > logic. > > 2. Have one, two or three different input events that are cancelablein so > that the JS can manage the DOM updates itself. > > What gives hardly any advantage over today's situation: > > * Have one or two noncancelable beforeinput events that are not surrounded > by cancelable ones. > > What cripples the beforeinput event for most use cases even on desktop: > > * Make most beforeinput events non-cancelable. > > > > The only advantage left of having the beforeinput event that I can see is: > > * handling UA button clicks and keyboard shortcuts > > * I understand that some editors don't monitor how the selection changes, > so they may not have known where the selection was before something > happened when it is done. > > > The handling of UA native buttons is further complicated by the fact that > browsers have a concept of a global undo stack, whereas all JS editors we > have been able to find use a undo stack that is specific to one > contenteditable host. As long as there is just one editing host on a page > or one encloses all editing hosts in iframes, this doesn't seem to be a > problem, but in all other cases it will mean that under some circumstances > the undo and redo buttons will not behave as expected. From Safri we even > heard they will not be able to turn these buttons on and off as needed. So > what we will be shipping will nor work correctly for history in Safari > right from the start. > > Which leaves us with buttons for richtext operations such as "make bold" > and "make italic". As far as I know, these are only shipped with Safari, so > really only Safari would need to add these. > > >> >> -- >> Alex >> >> On Mon, Feb 6, 2017 at 7:44 PM, Johannes Wilm <johannes@fiduswriter.org> >> wrote: >> >>> >>> >>> On Tue, Feb 7, 2017 at 4:00 AM, Alexandre Elias <aelias@google.com> >>> wrote: >>> >>>> On Mon, Feb 6, 2017 at 6:18 PM, Johannes Wilm <johannes@fiduswriter.org >>>> > wrote: >>>> >>>>> >>>>> >>>>> On Tue, Feb 7, 2017 at 12:23 AM, Alexandre Elias <aelias@google.com> >>>>> wrote: >>>>> >>>>>> Hi, I'm the maintainer of IME on Android. I'll be happy to attend >>>>>> the conference call next week. As you've surmised, Android does need to >>>>>> perform a DOM change to merge two nodes "later". However, I disagree that >>>>>> those 5 steps are somehow needed. Our plan is to send a single >>>>>> insertCompositionText beforeinput event instead of 5 events. >>>>>> >>>>> >>>>> Nice to meet you Alexandre! >>>>> >>>>> It's a bit unfrotunate that you haven't been able to participate in >>>>> the last 3 years of discussions about this subject (I think some people >>>>> have even been discussing this for more than 8 years), and it seems that >>>>> the mailing list isn't as alive any more as it once used to be, but I'll do >>>>> my best to give the reasoning why we came to the conclusion that these >>>>> events are needed. I would also recommend consulting the various open and >>>>> closed issues on github and to consult the archive of the mailing list. >>>>> Also, various Google people have been behind a lot if not most of the >>>>> various various concepts, so they can probably give you more background >>>>> about this as well. >>>>> >>>>> >>>>>> >>>>>> Arguments why each is not needed: >>>>>> >>>>>> > 1. deleteByComposition --This step is only needed when >>>>>> recomposing. A composed word can go across element boundaries, so this may >>>>>> delete more than just contents of a text node. (fx " He<b>ll</b><i>o >>>>>> fish</i>!"). This step needs to be executed at the moment your Android IME >>>>>> changes the DOM, whether this is at the moment the user taps the word and >>>>>> the underline appears or at a later stage. >>>>>> >>>>>> There's no need for a separate "delete" event, because >>>>>> insertion-to-replace-range is general enough to represent a deletion range >>>>>> as well. I prefer to reserve "delete" events exclusively for intended IME >>>>>> deletions (e.g. select word and press backspace). >>>>>> >>>>> >>>>> But I am a little confused: From the proposal Chong sent in, it >>>>> sounded like you just wouldn't have any beforeinput event for this initial >>>>> deletion. That would create a range of different problems, such as: >>>>> >>>> >>>> I agree we should not hide any editing information from JS. I am >>>> saying that event 2/3 can encompass the deletion. An implied, wrong >>>> assumption underlying your argument seems to be that an insertion operation >>>> can only ever add new text but not remove existing text. >>>> >>> >>> >>> No, that must be a misunderstanding. I don't know why you would think >>> that. As I said previsouly, if beforeinput events during IME are >>> cancelable, 1 (deletion) and 2 (addition cshould be combinable into one >>> single event, >>> >>> >>> I don't quite get what you mean by combining steps two and three. Step >>> two was the reinsertion of the initial composition string into the DOM. >>> Step three is the change during the composition. There will usually be many >>> step threes, but only one step two. >>> >>> The reason there is a step one and two at all is that the IME converts >>> the composition string from being something that can contain a complex >>> html-structure to just be a plaintext string (in most cases anyway). >>> >>> So step 1 will remove "He<b>l</b>p" and step 2 will re-add it as "Help". >>> Combining step 1 + 2 should work if step 2 is also cancelable. Combining >>> step 2 and 3, or maybe 1 and 2 and 3 (?) would mean that we go straight >>> from "He<b>l</b>p" to "Hel". and then the next two step 3 would add "l" and >>> "o". In many cases the JS will probably be able to guess what the >>> individual parts of this combination of 1/2/3 initially were (what part was >>> just about turning it into a plaintext and which part was then about >>> modifying the plaintext), but it would seem a bit meshed and I'm not sure >>> one always can determine it. Nevertheless, if iME input is cancelable, then >>> this does sound better than what was on the table previosuly. >>> >>> >>> >>> >>>> In reality, insertions are always *replacements* of the content of >>>> the caret/selection/composition with text (for example, if you select text >>>> with the mouse and then type "a" on a physical keyboard, no deletion event >>>> is sent). >>>> >>> >>> right. That'sw hy we have targetranges. But the difference for keyboard >>> inout is that it is cancelable and there is no automatic normalization to >>> plaintext. This is different than the situation with IME. >>> >>>> >>>> >>>>> * The more advanced editors today are moving toward a model where they >>>>> hold a json version of the document which is separate from the DOM. They >>>>> only make adjustments to the DOM when needed, and if the user changes >>>>> something about the DOM, they make adjustments to the json document. The >>>>> json version is the authoritative copy of the document. For this to work, >>>>> they need to know about any change to the DOM. If you make user-initiated >>>>> DOM changes that are not causing any beforeinput event at all, the >>>>> beforeinput event is somewhat useless, aand they will have to continue to >>>>> monitor user initiated DOM-changes in other ways. >>>>> >>>>> * In a collaborative editor, if you make a change to the DOM of one >>>>> user, and the JS is not being made aware of this change, then it won't >>>>> notify the collaborators of this change, and so the collaborator will ahve >>>>> different versions of the document. Again, the point of beforeinput events >>>>> will be gone. JS develoeprs will use mutation observers or some other >>>>> technology instead. >>>>> >>>>> >>>>> >>>>> >>>>>> >>>>>> > 2. insertCompositionText -- Also this step only needs to happen at >>>>>> the moment only for recompositions. It reinserts the word from step one, >>>>>> but this time as plaintext in one element (fx "Hello" => "<i>Hello >>>>>> fish</i>") >>>>>> >>>>>> On Android because of the "late" timing, this merge operation would >>>>>> happen in the same message loop task as step 3, so there is no need for >>>>>> this event. We prefer to go directly from "He<b>ll</b><i>o fish</i>" -> >>>>>> "<i>Help<i>". >>>>>> >>>>> >>>>> >>>>> Yes, in a perfect world, where all IME-related events are cancelable, >>>>> this could be done and would be preferable, as for example Yosin has >>>>> pointed out ( https://github.com/w3c/input-e >>>>> vents/issues/45#issuecomment-261427648 ). We had a long discussion >>>>> during the fall of 2015 about this, and among other ones several developers >>>>> from Chromium eventually convinced us here that IME-events cannot be >>>>> guaranteed to be cancelable. Even moving the caret to somewhere else during >>>>> the composition may somehow crash the IME (hwo this is possible is a bit of >>>>> a mystery to me as a JS developer). >>>>> >>>>> One could then say ok, combine 1 and 2 and make them both >>>>> non-cancelable. The problem with that is that the browser doesn't always >>>>> know the seamntic meaning of the various DOM elements used within a >>>>> document and it may end up making decisions of what to delete that are >>>>> problematic. >>>>> >>>> >>>> I've been trying to figure out where these claims about IME from some >>>> Chromium team members came from exactly and haven't figured it out, nobody >>>> has a precise memory. They seem to be based on a vague fears rather than >>>> concrete knowledge of how IMEs behave. I agree with your instinct that the >>>> assumptions behind it don't make too much sense, that's why I think we >>>> should hold off before we commit to a complicated model based on those >>>> assumptions. >>>> >>> >>> Well, maybe you guys need to discuss that internally. Until now what we >>> said here is that we will assume the worst case scenario (that IMEs not >>> being allowed to directly modify the DOM will lead to them crashing) and >>> then in a future version to hopefully get one that doesn't crash. >>> >>> Btw -- just to make it clear because this seems to have been a common >>> misconception between JS developers and browser developers in the past: >>> When we ask for these things to be cancelable, in 80% of cases this is not >>> because we want to stop the user from doing things. It's more than we want >>> to do the corresponding DOM changes in JS code, because they are specific >>> to the JS editor the user is currently using and they may not necessarily >>> make sense to the browser. >>> >>> >>> >>>> >>>> >>>>> >>>>> >>>>> >>>>>> However, rniwa@apple.com has told us that on OS X, the standard >>>>>> platform behavior is to merge the nodes at time of composition start. >>>>>> Therefore, on OS X step 2 is still needed and there would be 2 beforeinput >>>>>> events in total, but on Android there would be only 1. This represents a >>>>>> substantive platform difference that I think it makes sense to allow to >>>>>> differ in the spec. I don't think we should try to artificially >>>>>> synchronize the platforms by always sending 2 events -- on Android this >>>>>> would simply result in unnecessary work and side effects that would never >>>>>> be seen by the user. >>>>>> >>>>> >>>>> I think you should instead consider making this two events on Android. >>>>> Android is really great, but text editing in Chrome on Android is really >>>>> problematic especially when it comes to IME recomposition, as I am sure you >>>>> are aware. I have tried various keyboard, and but even on mainstream sites >>>>> such as Facebook, using a Google-provided keyboard, recomposition tends to >>>>> just mess up entire sentences, throw random words around, deleting or >>>>> merging words that are close to what one is trying to recompose, etc. >>>>> >>>> >>>> Right, we are in process of fixing all of these bugs and expect to get >>>> the remaining ones fixed in M58/M59 timeframe. Anyway, this doesn't >>>> address my point. Personally, I believe that firing additional unnecessary >>>> events will prove harmful to both UAs and JS editors -- in reality an >>>> atomic IME change that just happened, but you are proposing to drip-feed it >>>> into many separate events. Your proposal doesn't provide JS any additional >>>> information (it just splits information into pieces), so therefore I don't >>>> think it can possibly be needed for any use case either. >>>> >>>> >>>> >>>>> Speed is not as much a concern anyway because it all depends on the >>>>> human who is interacting with it, but in addition these really major issues >>>>> mean that recomposition as it exists on Android as of today is not very >>>>> useful. In addition there are the various issues that JS developers have >>>>> complained about for a while: no compositionstart event, etc. . I am sure >>>>> you know the list of grievances with it all too well. >>>>> >>>> >>>> We should always be firing compositionStart today. Feel free to file a >>>> bug against me if you know of a case where we don't. >>>> >>> >>> I recently sent a list of prioritized bugs from several JS editor >>> projects to the Chromium team that they had requested from em. I assume >>> they forwarded those issues relevant to Android to you. >>> >>>> >>>> >>>>> >>>>> Not knowing the details, but I could imagine you can check for event >>>>> listeners, and only if those are present you make it two events. >>>>> >>>>> But as an alternative, and to try to get a bit closer to both your and >>>>> Yosin's position, how about this: We make two IME models, one for IMEs >>>>> where the beforeinput events can be cancelled in which step 1 and 2 are >>>>> merged and one where they cannot be cancelled where they are separate. >>>>> >>>> >>>> Disagree, we should keep things as simple as possible. I want us to >>>> fire a minimum of events and avoid complicated logic forking. I don't want >>>> us to introduce permanent complexity into the platform for the sake of a >>>> short-term compromise. >>>> >>> >>> Well, you said that Apple does one thing and you do another. So either >>> the two of you can agree or you don't. If you cannot agree, we'll have to >>> have two different models. >>> >>> In theis scenario, if the Chrome model consists of just cutting out 4 of >>> 5 events on Android, then as I tried to explain in the last few emails and >>> the comments on the proposal doc, the event will no longer function to >>> build an editor on top of. At least not without combining it with mutation >>> observers and other technologies. >>> >>> Having a model where IME events are cancelable is really something we >>> all hoped to do in a future version of the spec. If the situation is such >>> that Chromium/Android would prefer to do this right now, whereas Apple >>> prefers to stay with the non-cancelable IME-model then that would not seem >>> like terribly different models. >>> >>> >>>> >>>> >>>>> >>>>>> >>>>> > 4. deleteCompositionText -- removed (fx "help"): It removed the text >>>>>> from the underline and it may not be the entire composition. >>>>>> >>>>>> > 5. insertFromComposition -- adds "help" permanently, and gives the >>>>>> JS the opposrtunity to rebuild the complex HTML structure lost in step 1. >>>>>> >>>>>> Step 3 is already permanent. The fact that there is still an active >>>>>> composition underline at the time of step 3 does not make it somehow >>>>>> temporary. It has already been injected into the DOM and caused all side >>>>>> effects. So the JS should rebuild its complex structure at time of event >>>>>> 3, and events 4/5 are redundant. >>>>>> >>>>> >>>>> When a composition starts, they temporarily pause most activities >>>>> because they are not really allowed to intervene. Then, once the >>>>> composition is finished, they deal with the finished text. input. For >>>>> example, in step 5 they may reapply some partial styling that was lost in >>>>> step 1. >>>>> >>>> >>>> "compositionend" event is fired at the same timing that steps 4/5 would >>>> be, isn't it sufficient for this use case? >>>> >>> >>> There is one problem in that compositionend with data="" could mean the >>> composition has been cancelled or that the final compositionstring is >>> empty. The distinction between 4 and 5 is needed if 2, 3 & 4 are >>> non-cancelable. If they are cancelable, then one should be able to combine >>> 1 and 2, and skip 4 and 5 and the JS would continously make any adjustments >>> it needs to the DOM (while taking into consideration what the >>> compositionstring is at any moment). >>> >>> >>>> >>>> >>>>> >>>>> >>>>> >>>>>> >>>>>>> >>>>>>> The reason you state for the proposed change is that "On Android >>>>>>> it’s very common for IME to start composition whenever a cursor is moved >>>>>>> onto a word. This is primarily intended to passively show an underline to >>>>>>> the user (to indicate what would be replaced *if* user selects an alternate >>>>>>> spelling)." >>>>>>> >>>>>>> If such tapping leads to actual DOM changes, then the JS needs to >>>>>>> know about those(step 1/2). But if you don't change the DOM immediately and >>>>>>> only do so at a later stage when you "really" start the composition, then >>>>>>> you can also wait until that stage. >>>>>>> >>>>>>> >>>>>>> So these steps are needed on allplattforms, no matter whether or not >>>>>>> you change how IMEs work on Android. >>>>>>> >>>>>>> >>>>>>>> >>>>>>>> Adding aelias@ to make sure he is able to make the call on the >>>>>>>> 14th. >>>>>>>> >>>>>>>> dave. >>>>>>>> >>>>>>>> On Fri, Feb 3, 2017 at 1:33 AM, Johannes Wilm < >>>>>>>> johannes@fiduswriter.org> wrote: >>>>>>>> >>>>>>>>> Could we get the person or people who came up with these changes >>>>>>>>> due to Android to participate in the call on the 14th? I think it's very >>>>>>>>> important to have them invovled in this discussion. >>>>>>>>> >>>>>>>>> On Fri, Feb 3, 2017 at 10:21 AM, Johannes Wilm < >>>>>>>>> johannes@fiduswriter.org> wrote: >>>>>>>>> >>>>>>>>>> >>>>>>>>>> On Fri, Feb 3, 2017 at 10:18 AM, Johannes Wilm < >>>>>>>>>> johannes@fiduswriter.org> wrote: >>>>>>>>>> ... >>>>>>>>>> >>>>>>>>>>> Right now I cannot see any purpose of the beforeinput event with >>>>>>>>>>> these changes applied, but maybe I am missing something? >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> I need to restarct that. I guess it could still be useful to stop >>>>>>>>>> native bold/italic buttons from making their own, non-controlled DOM >>>>>>>>>> changes. It's just for text input that it is irrelevant. And IME will >>>>>>>>>> continue to be a mess. >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Johannes Wilm >>>>>>>>>> Fidus Writer >>>>>>>>>> http://www.fiduswriter.org >>>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> -- >>>>>>>>> Johannes Wilm >>>>>>>>> Fidus Writer >>>>>>>>> http://www.fiduswriter.org >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Johannes Wilm >>>>>>> Fidus Writer >>>>>>> http://www.fiduswriter.org >>>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> -- >>>>> Johannes Wilm >>>>> Fidus Writer >>>>> http://www.fiduswriter.org >>>>> >>>> >>>> >>> >>> >>> -- >>> Johannes Wilm >>> Fidus Writer >>> http://www.fiduswriter.org >>> >> >> > > > -- > Johannes Wilm > Fidus Writer > http://www.fiduswriter.org >
Received on Wednesday, 8 February 2017 15:00:40 UTC