W3C home > Mailing lists > Public > www-dom@w3.org > April to June 2010

Re: Proposal to ammend the composition event spec.

From: Ojan Vafai <ojan@chromium.org>
Date: Tue, 15 Jun 2010 09:43:54 -0700
Message-ID: <AANLkTil-bokUmz0zaZlju_x7FNekS2ra09EXq-dIU68v@mail.gmail.com>
To: tony@chromium.org
Cc: www-dom@w3.org
I support this proposal. It is certainly much easier to implement than
always firing textInput before any IME input. It makes dealing with
textInput and IME a bit confusing for web developers, but it's better than
the current state of things and I believe that this is probably the best we
can do given existing IMEs if we want textInput to be cancelable.

Ojan

On Tue, Jun 15, 2010 at 12:56 AM, Tony Chang <tony@chromium.org> wrote:

> 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 16:44:49 GMT

This archive was generated by hypermail 2.2.0+W3C-0.50 : Friday, 22 June 2012 06:14:04 GMT