Re: Proposal to ammend the composition event spec.

I have also been convinced by James' arguments.  The new proposal
(only firing textInput once before compositionend) sounds good
to me.

James Su <suzhe@chromium.org> wrote:
> --001636c5bd59d21de404890b8b6c
> Content-Type: text/plain; charset=UTF-8
> Content-Transfer-Encoding: quoted-printable
>
> This new proposal looks good to me. Thanks a lot for your hard work.
>
> Regards
> James Su
>
> 2010/6/14 Daniel Danilatos <daniel@danilatos.com>
>
>> So, after a bunch more discussion, I'd like to propose the following,
>> the second point of which involves changing the spec.
>>
>> 1. All dom mutations resulting from composition must be strictly bound
>> between compositionstart and compositionend
>> 2. textInput should be fired before compositionend
>>
>> E.g.
>>
>> to type "wo" -> =E6=88=91
>>
>> user "w"
>> event compositionstart
>> ("w")
>>
>> user "o"
>> ("wo")
>>
>> user <space>
>> ("=E6=88=91")
>>
>> user <space> (to commit the composition)
>> ("")
>> event textInput (cancelable)
>> ("=E6=88=91")
>> event compositionend
>>
>> Notes: I have omitted compositionupdate events for simplicity. The
>> fact that the user hits space twice is just how the IME example I am
>> using works (many pinyin IMEs do this).
>>
>> If the user hit <ESC> instead of the final <space>, the composition
>> would be cancelled - in this case, textInput would simply not fire,
>> and compositionend would be fired with no composition text in the
>> composition state.
>>
>> If the event handler prevents default for textInput, compositionend
>> would again still fire. Canceling the compositionend is meaningless.
>>
>> To summarize again, compositionend must always fire for every
>> compositionstart, and changes related to the composition must always
>> be bound between the two events no matter what. We feel the above is
>> the best option because:
>> a) Satisfies the use case of having mutations being bound by
>> composition events. This is extremely important from our work with
>> using these events to date.
>> b) Preserves textInput's existing semantics of firing before the final
>> composition is committed. This satisfies James Su's concerns stated
>> earlier.
>> c) Is consistent with existing Firefox behavior (to the extent that's
>> possible, given that FF doesn't yet support textInput)
>>
>> Please let me know if I need to clarify anything.
>> Thanks
>>
>> Dan
>>
>> On Sat, May 29, 2010 at 10:39 AM, James Su <suzhe@chromium.org> wrote:
>> >
>> >
>> > =E5=9C=A8 2010=E5=B9=B45=E6=9C=8828=E6=97=A5 =E4=B8=8A=E5=8D=887:30=EF=
>=BC=8COjan Vafai <ojan@chromium.org>=E5=86=99=E9=81=93=EF=BC=9A
>> >>
>> >> On Fri, May 21, 2010 at 4:17 PM, James Su <suzhe@chromium.org> wrote:
>> >>>
>> >>> More points about the second proposal:
>> >>> For the second proposal, we do:
>> >>> 1. fire compositionupdate event after mutating the dom
>> >>> 2. delete composition string before firing compositionend event
>> >>> 3. fire textInput after compositionend but before inserting the text
>> >>> So that:
>> >>> 1. We can know when composition mode starts by hooking compositionsta=
> rt
>> >>> event
>> >>> 2. We can get updated composition string in compositionupdate handler
>> >>> synchronously
>> >>> 3. We can know when composition mode finishes by hooking compositione=
> nd
>> >>> event
>> >>> 4. textInput event can be cancelled in order to revert the DOM tree
>> >>> completely.
>> >>
>> >> What's the use-case for canceling the confirmed composition? I can
>> >> see canceling individual keypresses, but I don't see why someone would
>> want
>> >> to cancel the composition when the user just confirmed it.
>> >
>> > textInput event is defined as cancellable. Not sure if there is any rea=
> l
>> > world use-case.
>> >
>> >>
>> >> Firing textInput before each time the DOM is modified does make
>> >> compositionUpdate a bit redundant, but it makes textInput more useful =
> by
>> >> making it consistently happen before the DOM is ever modified from a
>> >> user-initiated text input.
>> >
>> > The text being composed and the confirmed text are different. I don't
>> think
>> > we should mix them. The effect of textInput event for a node is to appe=
> nd
>> a
>> > piece of text to existing content, while compositionUpdate is not. And
>> > textInput is already in specification for quite a long time, it's not
>> good
>> > to change its behavior which may break backward compatibility.
>> >
>> >>>
>> >>> About the deleting and inserting again issue: because compositionend
>> and
>> >>> textInsert events are fired in the same event loop iteration, it shou=
> ld
>> not
>> >>> cause additional rendering. So the visual and performance impact woul=
> d
>> >>> be negligible.
>> >>> The only issue of this proposal is: we need to change composition*
>> events
>> >>> to non-cancellable. But anyway, cancelling these events make complete=
> ly
>> no
>> >>> sense. If somebody really wants to cancel the composition process,
>> he/she
>> >>> can just cancel the keydown event.
>> >>> Regards
>> >>> James Su
>> >>> =E5=9C=A8 2010=E5=B9=B45=E6=9C=8818=E6=97=A5 =E4=B8=8A=E5=8D=887:49=
>=EF=BC=8CDaniel Danilatos <daniel@danilatos.com>=E5=86=99=E9=81=93=EF=BC=9A
>> >>>>
>> >>>> The spec should make it clear that mutations must be bounded between
>> >>>> compositionstart and compositionend events.
>> >>>>
>> >>>> Background:
>> >>>>
>> >>>> https://bugs.webkit.org/show_bug.cgi?id=3D31902
>> >>>> Hironori has asked me to write up this email arguing for adjusting t=
> he
>> >>>> spec..
>> >>>>
>> >>>> Summary:
>> >>>>
>> >>>> >From our implementation experience, it is broken not to bound
>> >>>> mutations with compositionstart and compositionend events. not havin=
> g
>> >>>> this severely limits their utility - and requires large amounts of
>> >>>> hacky workaround code, even involving asynchronous logic.
>> >>>> Firefox already has the correct behaviour, and it is off firefox tha=
> t
>> >>>> we largely based the spec (so the spec should be adjusted)
>> >>>> The fix for webkit is already implemented - it was just rejected
>> >>>> because it supposedly doesn't match the spec; once the spec is
>> >>>> adjusted, both Webkit and FF will be in line with eachother with
>> >>>> respect to the composition events.
>> >>>> The tricky thing to consider is, when should a textinput event be
>> >>>> fired. This is a secondary issue to the strong requirement, that
>> >>>> mutations must be bounded by composition events. The options then se=
> em
>> >>>> to be:
>> >>>>
>> >>>> (Compatible with existing spec) Fire textInput after the composition
>> >>>> has ended - thus textInput would no longer be a pre-input-event, but
>> >>>> really, it never was, as the dom is mutating before the event anyway=
> .
>> >>>> Currently, webkit creates the composition text, then removes it agai=
> n,
>> >>>> just so it can then fire the textInput event, and if not cancelled,
>> >>>> will then insert the content.
>> >>>> (Compatible with existing spec) If textInput really, really must fir=
> e
>> >>>> before input, even though the dom has already been mutating from the
>> >>>> composition, then delete the composition, but do that BEFORE the
>> >>>> compositionend event. then fire a regular cancellable textInput. In =
> my
>> >>>> opinion this seems wasteful, though.
>> >>>> (Incompatible with existing spec) Fire textInput before every change=
> .
>> >>>> This is more generally consistent, especially with other proposals t=
> o
>> >>>> extend textInput (or introduce a similar event) that fires before
>> >>>> every change to the DOM at all, including for things like paste, und=
> o,
>> >>>> and deletion. For the use case where the application wants to know
>> >>>> when some content is ready and in a consistent state (i.e. not durin=
> g
>> >>>> composition), a post-change event is more applicable. Such an event
>> >>>> does not have to fire after every single change.
>> >>>> We shouldn't fear the final option above - the composition events sp=
> ec
>> >>>> is still in its infancy. Now is the time to make meaningful changes.
>> >>>>
>> >>>> Best,
>> >>>> Dan
>> >>>>
>> >>>
>> >>
>> >
>> >
>>
>
> --001636c5bd59d21de404890b8b6c
> Content-Type: text/html; charset=UTF-8
> Content-Transfer-Encoding: quoted-printable
>
> This new proposal looks good to me. Thanks a lot for your hard work.<div><b=
> r></div><div>Regards</div><div>James Su<br><br><div class=3D"gmail_quote">2=
> 010/6/14 Daniel Danilatos <span dir=3D"ltr">&lt;<a href=3D"mailto:daniel@da=
> nilatos.com">daniel@danilatos.com</a>&gt;</span><br>
>
><blockquote class=3D"gmail_quote" style=3D"margin:0 0 0 .8ex;border-left:1p=
> x #ccc solid;padding-left:1ex;">So, after a bunch more discussion, I&#39;d =
> like to propose the following,<br>
> the second point of which involves changing the spec.<br>
><br>
> 1. All dom mutations resulting from composition must be strictly bound<br>
> between compositionstart and compositionend<br>
> 2. textInput should be fired before compositionend<br>
><br>
> E.g.<br>
><br>
> to type &quot;wo&quot; -&gt; =E6=88=91<br>
><br>
> user &quot;w&quot;<br>
> event compositionstart<br>
> (&quot;w&quot;)<br>
><br>
> user &quot;o&quot;<br>
> (&quot;wo&quot;)<br>
><br>
> user &lt;space&gt;<br>
> (&quot;=E6=88=91&quot;)<br>
><br>
> user &lt;space&gt; (to commit the composition)<br>
> (&quot;&quot;)<br>
> event textInput (cancelable)<br>
> (&quot;=E6=88=91&quot;)<br>
> event compositionend<br>
><br>
> Notes: I have omitted compositionupdate events for simplicity. The<br>
> fact that the user hits space twice is just how the IME example I am<br>
> using works (many pinyin IMEs do this).<br>
><br>
> If the user hit &lt;ESC&gt; instead of the final &lt;space&gt;, the composi=
> tion<br>
> would be cancelled - in this case, textInput would simply not fire,<br>
> and compositionend would be fired with no composition text in the<br>
> composition state.<br>
><br>
> If the event handler prevents default for textInput, compositionend<br>
> would again still fire. Canceling the compositionend is meaningless.<br>
><br>
> To summarize again, compositionend must always fire for every<br>
> compositionstart, and changes related to the composition must always<br>
> be bound between the two events no matter what. We feel the above is<br>
> the best option because:<br>
> a) Satisfies the use case of having mutations being bound by<br>
> composition events. This is extremely important from our work with<br>
> using these events to date.<br>
> b) Preserves textInput&#39;s existing semantics of firing before the final<=
> br>
> composition is committed. This satisfies James Su&#39;s concerns stated<br>
> earlier.<br>
> c) Is consistent with existing Firefox behavior (to the extent that&#39;s<b=
> r>
> possible, given that FF doesn&#39;t yet support textInput)<br>
><br>
> Please let me know if I need to clarify anything.<br>
> Thanks<br>
><br>
> Dan<br>
><div><div></div><div class=3D"h5"><br>
> On Sat, May 29, 2010 at 10:39 AM, James Su &lt;<a href=3D"mailto:suzhe@chro=
> mium.org">suzhe@chromium.org</a>&gt; wrote:<br>
> &gt;<br>
> &gt;<br>
> &gt; =E5=9C=A8 2010=E5=B9=B45=E6=9C=8828=E6=97=A5 =E4=B8=8A=E5=8D=887:30=EF=
>=BC=8COjan Vafai &lt;<a href=3D"mailto:ojan@chromium.org">ojan@chromium.org=
></a>&gt;=E5=86=99=E9=81=93=EF=BC=9A<br>
> &gt;&gt;<br>
> &gt;&gt; On Fri, May 21, 2010 at 4:17 PM, James Su &lt;<a href=3D"mailto:su=
> zhe@chromium.org">suzhe@chromium.org</a>&gt; wrote:<br>
> &gt;&gt;&gt;<br>
> &gt;&gt;&gt; More points about the second proposal:<br>
> &gt;&gt;&gt; For the second proposal, we do:<br>
> &gt;&gt;&gt; 1. fire compositionupdate event after mutating the dom<br>
> &gt;&gt;&gt; 2. delete composition string before firing compositionend even=
> t<br>
> &gt;&gt;&gt; 3. fire textInput after compositionend but before inserting th=
> e text<br>
> &gt;&gt;&gt; So that:<br>
> &gt;&gt;&gt; 1. We can know when composition mode starts by hooking composi=
> tionstart<br>
> &gt;&gt;&gt; event<br>
> &gt;&gt;&gt; 2. We can get updated composition string in compositionupdate =
> handler<br>
> &gt;&gt;&gt; synchronously<br>
> &gt;&gt;&gt; 3. We can know when composition mode finishes by hooking compo=
> sitionend<br>
> &gt;&gt;&gt; event<br>
> &gt;&gt;&gt; 4. textInput event can be cancelled in order to revert the DOM=
>  tree<br>
> &gt;&gt;&gt; completely.<br>
> &gt;&gt;<br>
> &gt;&gt; What&#39;s the use-case for canceling the confirmed composition? I=
>  can<br>
> &gt;&gt; see canceling individual keypresses, but I don&#39;t see why someo=
> ne would want<br>
> &gt;&gt; to cancel the composition when the user just confirmed it.<br>
> &gt;<br>
> &gt; textInput event is defined as cancellable. Not sure if there is any re=
> al<br>
> &gt; world use-case.<br>
> &gt;<br>
> &gt;&gt;<br>
> &gt;&gt; Firing textInput before each time the DOM is modified does make<br=
>>
> &gt;&gt; compositionUpdate a bit redundant, but it makes textInput more use=
> ful by<br>
> &gt;&gt; making it consistently happen before the DOM is ever modified from=
>  a<br>
> &gt;&gt; user-initiated text input.<br>
> &gt;<br>
> &gt; The text being composed and the confirmed text are different. I don&#3=
> 9;t think<br>
> &gt; we should mix them. The effect of textInput event for a node is to app=
> end a<br>
> &gt; piece of text to existing content, while compositionUpdate is not. And=
><br>
> &gt; textInput is already in specification for quite a long time, it&#39;s =
> not good<br>
> &gt; to change its behavior which may break backward compatibility.<br>
> &gt;<br>
> &gt;&gt;&gt;<br>
> &gt;&gt;&gt; About the deleting and inserting again issue: because composit=
> ionend and<br>
> &gt;&gt;&gt; textInsert events are fired in the same event loop iteration, =
> it should not<br>
> &gt;&gt;&gt; cause additional rendering. So the visual and performance impa=
> ct would<br>
> &gt;&gt;&gt; be negligible.<br>
> &gt;&gt;&gt; The only issue of this proposal is: we need to change composit=
> ion* events<br>
> &gt;&gt;&gt; to non-cancellable. But anyway, cancelling these events make c=
> ompletely no<br>
> &gt;&gt;&gt; sense. If somebody really wants to cancel the composition proc=
> ess, he/she<br>
> &gt;&gt;&gt; can just cancel the keydown event.<br>
> &gt;&gt;&gt; Regards<br>
> &gt;&gt;&gt; James Su<br>
> &gt;&gt;&gt; =E5=9C=A8 2010=E5=B9=B45=E6=9C=8818=E6=97=A5 =E4=B8=8A=E5=8D=
>=887:49=EF=BC=8CDaniel Danilatos &lt;<a href=3D"mailto:daniel@danilatos.com=
> ">daniel@danilatos.com</a>&gt;=E5=86=99=E9=81=93=EF=BC=9A<br>
> &gt;&gt;&gt;&gt;<br>
> &gt;&gt;&gt;&gt; The spec should make it clear that mutations must be bound=
> ed between<br>
> &gt;&gt;&gt;&gt; compositionstart and compositionend events.<br>
> &gt;&gt;&gt;&gt;<br>
> &gt;&gt;&gt;&gt; Background:<br>
> &gt;&gt;&gt;&gt;<br>
> &gt;&gt;&gt;&gt; <a href=3D"https://bugs.webkit.org/show_bug.cgi?id=3D31902=
> " target=3D"_blank">https://bugs.webkit.org/show_bug.cgi?id=3D31902</a><br>
> &gt;&gt;&gt;&gt; Hironori has asked me to write up this email arguing for a=
> djusting the<br>
> &gt;&gt;&gt;&gt; spec..<br>
> &gt;&gt;&gt;&gt;<br>
> &gt;&gt;&gt;&gt; Summary:<br>
> &gt;&gt;&gt;&gt;<br>
> &gt;&gt;&gt;&gt; &gt;From our implementation experience, it is broken not t=
> o bound<br>
> &gt;&gt;&gt;&gt; mutations with compositionstart and compositionend events.=
>  not having<br>
> &gt;&gt;&gt;&gt; this severely limits their utility - and requires large am=
> ounts of<br>
> &gt;&gt;&gt;&gt; hacky workaround code, even involving asynchronous logic.<=
> br>
> &gt;&gt;&gt;&gt; Firefox already has the correct behaviour, and it is off f=
> irefox that<br>
> &gt;&gt;&gt;&gt; we largely based the spec (so the spec should be adjusted)=
><br>
> &gt;&gt;&gt;&gt; The fix for webkit is already implemented - it was just re=
> jected<br>
> &gt;&gt;&gt;&gt; because it supposedly doesn&#39;t match the spec; once the=
>  spec is<br>
> &gt;&gt;&gt;&gt; adjusted, both Webkit and FF will be in line with eachothe=
> r with<br>
> &gt;&gt;&gt;&gt; respect to the composition events.<br>
> &gt;&gt;&gt;&gt; The tricky thing to consider is, when should a textinput e=
> vent be<br>
> &gt;&gt;&gt;&gt; fired. This is a secondary issue to the strong requirement=
> , that<br>
> &gt;&gt;&gt;&gt; mutations must be bounded by composition events. The optio=
> ns then seem<br>
> &gt;&gt;&gt;&gt; to be:<br>
> &gt;&gt;&gt;&gt;<br>
> &gt;&gt;&gt;&gt; (Compatible with existing spec) Fire textInput after the c=
> omposition<br>
> &gt;&gt;&gt;&gt; has ended - thus textInput would no longer be a pre-input-=
> event, but<br>
> &gt;&gt;&gt;&gt; really, it never was, as the dom is mutating before the ev=
> ent anyway.<br>
> &gt;&gt;&gt;&gt; Currently, webkit creates the composition text, then remov=
> es it again,<br>
> &gt;&gt;&gt;&gt; just so it can then fire the textInput event, and if not c=
> ancelled,<br>
> &gt;&gt;&gt;&gt; will then insert the content.<br>
> &gt;&gt;&gt;&gt; (Compatible with existing spec) If textInput really, reall=
> y must fire<br>
> &gt;&gt;&gt;&gt; before input, even though the dom has already been mutatin=
> g from the<br>
> &gt;&gt;&gt;&gt; composition, then delete the composition, but do that BEFO=
> RE the<br>
> &gt;&gt;&gt;&gt; compositionend event. then fire a regular cancellable text=
> Input. In my<br>
> &gt;&gt;&gt;&gt; opinion this seems wasteful, though.<br>
> &gt;&gt;&gt;&gt; (Incompatible with existing spec) Fire textInput before ev=
> ery change.<br>
> &gt;&gt;&gt;&gt; This is more generally consistent, especially with other p=
> roposals to<br>
> &gt;&gt;&gt;&gt; extend textInput (or introduce a similar event) that fires=
>  before<br>
> &gt;&gt;&gt;&gt; every change to the DOM at all, including for things like =
> paste, undo,<br>
> &gt;&gt;&gt;&gt; and deletion. For the use case where the application wants=
>  to know<br>
> &gt;&gt;&gt;&gt; when some content is ready and in a consistent state (i.e.=
>  not during<br>
> &gt;&gt;&gt;&gt; composition), a post-change event is more applicable. Such=
>  an event<br>
> &gt;&gt;&gt;&gt; does not have to fire after every single change.<br>
> &gt;&gt;&gt;&gt; We shouldn&#39;t fear the final option above - the composi=
> tion events spec<br>
> &gt;&gt;&gt;&gt; is still in its infancy. Now is the time to make meaningfu=
> l changes.<br>
> &gt;&gt;&gt;&gt;<br>
> &gt;&gt;&gt;&gt; Best,<br>
> &gt;&gt;&gt;&gt; Dan<br>
> &gt;&gt;&gt;&gt;<br>
> &gt;&gt;&gt;<br>
> &gt;&gt;<br>
> &gt;<br>
> &gt;<br>
></div></div></blockquote></div><br></div>
>
> --001636c5bd59d21de404890b8b6c--
>
>

Received on Tuesday, 15 June 2010 07:57:18 UTC