- From: Rick Byers <rbyers@chromium.org>
- Date: Mon, 6 Jul 2015 10:34:02 -0400
- To: Olli Pettay <olli@pettay.fi>
- Cc: "public-pointer-events@w3.org" <public-pointer-events@w3.org>, Jared Duke <jdduke@chromium.org>, Nathaniel Duca <nduca@chromium.org>
- Message-ID: <CAFUtAY9KxMEWGeqz1zbxM-1ouFUuW8fjGeD1UOkj5YVvY1sqqA@mail.gmail.com>
I've written a more formal (but probably still sloppy by W3C standards)
spec for this here
<http://rbyers.github.io/EventListenerOptions/EventListenerOptions.html>.
Olli, I've tried to reflect all of your feedback, either in the spec or as
open issues (in particular #2
<https://github.com/RByers/EventListenerOptions/issues/2> and #12
<https://github.com/RByers/EventListenerOptions/issues/12>).
Please file issues <https://github.com/RByers/EventListenerOptions/issues>
or submit pull requests for other feedback. Once there's a bit more
consensus on the API shape, I plan to write a polyfill and W3C-style tests
and bring this to www-dom.
Thanks,
Rick
On Wed, Apr 22, 2015 at 1:04 PM, Olli Pettay <olli@pettay.fi> wrote:
> On 04/22/2015 09:49 AM, Rick Byers wrote:
>
>>
>> On Wed, Apr 22, 2015 at 12:44 PM, Olli Pettay <olli@pettay.fi <mailto:
>> olli@pettay.fi>> wrote:
>>
>> I was thinking { preventDefault: "never" } would be just a hint. In
>> order to be backwards compatible it would not affect at all how any other
>> parts of the DOM Events API works.
>> But it could affect to the behavior of the UA while it is dealing
>> with possibly asynchronous stuff, like touch/mouse/wheel.
>>
>>
>> I see. And what should the behavior be if the "hint" is violated (call
>> preventDefault in a handler which said it wouldn't)? I'm just worried about
>> predictability here. I think if a developer says they won't call
>> preventDefault in a handler, we should ensure they can't (i.e. the event is
>> uncancelable), otherwise we may not be able to depend on it without
>> triggering bugs.
>>
>
>
> Well it doesn't really make sense for event listener registration to
> change the state of the DOM Event to be dispatched.
> And if the page doesn't honor the hint it set, that is a bug in it.
> Though, perhaps that hint name should be something a bit different...
> something which hints that the dispatcher of the event doesn't need to
> honor event's defaultPrevented state - in other words the return value of
> dispatchEvent().
>
>
>
>> On 04/22/2015 09:13 AM, Rick Byers wrote:
>>
>> On Tue, Apr 21, 2015 at 11:24 AM, Olli Pettay <olli@pettay.fi
>> <mailto:olli@pettay.fi> <mailto:olli@pettay.fi <mailto:olli@pettay.fi>>>
>> wrote:
>>
>> On 04/21/2015 08:00 AM, Olli Pettay wrote:
>>
>> On 04/21/2015 07:10 AM, Rick Byers wrote:
>>
>> On Tue, Apr 21, 2015 at 9:43 AM, Olli Pettay <
>> olli@pettay.fi <mailto:olli@pettay.fi> <mailto:olli@pettay.fi
>> <mailto:olli@pettay.fi>> <mailto:olli@pettay.fi <mailto:
>> olli@pettay.fi> <mailto:olli@pettay.fi <mailto:olli@pettay.fi>>>> wrote:
>>
>> On 04/15/2015 08:31 AM, Rick Byers wrote:
>>
>> It's common for libraries (eg. ads
>> frameworks) to want to passively track some notion of user interaction with
>> the
>> page. For
>> touch, Pointer
>> Events is
>> a good API for this because the event
>> listeners don't block scrolling. But what about for wheel events? Adding a
>> document wheel
>> event
>> handler for
>> this (when none existed previously) is bad
>> for scroll performance.
>>
>>
>> I wonder how bad the performance issues
>> actually are here. Comparing to pointer events, wheel events fire rarely,
>> and there
>> are just
>> couple of them
>> in a row. So an implementation could have
>> enough time to hit test and dispatch an event before the next animation
>> frame tick.
>> (I'm a bit worried making the platform more
>> complicated than it needs to be.)
>>
>>
>> Why do you say there's just a couple of them in a
>> row?
>>
>> I'm comparing to touch events for example. But you're
>> right, pixel level wheel events happen rather often.
>>
>> I'm thinking primarily of scrolling on high-quality
>> touchpads here (eg. macbooks,
>> chromebooks). There wheel events are similar to
>> touchmove events in terms of frequency and duration during a scroll. That
>> said,
>> there
>> are some big
>> differences:
>> 1) wheel scrolling tends to be done on much faster
>> devices than touch scrolling
>> 2) indirect manipulation is more forgiving
>> psychologically than direct manipulation (since with touch your finger acts
>> as a point of
>> reference that
>> makes at least latency substantially more
>> noticeable, but I'm not sure how it affects the perception of smoothness).
>>
>> So I agree it may not be that important. But as we
>> look to provide control over the blocking behavior of touch and scroll
>> handlers (eg.
>> scroll-blocks-on proposal <
>> https://docs.google.com/a/chromium.org/document/d/1aOQRw76C0enLBd0mCG_-IM6bso7DxXwvqTiRWgNdTn8/edit>),
>> I'm
>> trying to
>> consider wheel handlers also for consistency and
>> completeness.
>>
>>
>>
>> Would wheel+ctrl behave differently to wheel? Or other
>> event+modifier combinations? (I think events should be for consistency
>> dispatched the
>> same way,
>> either always async or always sync, whether or not there
>> are modifiers)
>>
>>
>> Should PEWG consider trying to address this
>> scenario?
>>
>> One option (that I think we've discussed a
>> bit in some form) would be to have a new non-blocking event ('pointerwheel'
>> maybe?)
>> and a new
>> 'wheel-action' CSS property (similar to
>> touch-action) that declaratively says what sort of wheel movement should
>> cause
>> scrolling. This would
>> be most
>> like pointer events, but adding new event
>> types for this seems unfortunate (now what about keyboard scrolling?).
>>
>> well, keyboard scrolling doesn't cause wheel
>> events either.
>>
>>
>> Right, but the same problem exists there in theory.
>> Perhaps there should be some mechanism to permit keyboard event listeners
>> that won't
>> block
>> scrolling? But this is even less important than the
>> wheel case IMHO.
>>
>> Another option would be to augment event
>> handler registration with an options dictionary (instead of just the single
>> 'capture'
>> boolean). Eg:
>> addEventListener('wheel', myHandler,
>> {blocksScroll: false});
>>
>> Definitely not this. This is not a strong
>> enough case to change an API which has existed for 15+ years, IMO.
>>
>>
>> Would you feel any better about this if the API had
>> a new name?
>>
>> Not really
>>
>> Although I share your gut reaction that we shouldn't
>> be messing with
>> addEventListener, in debates internally I haven't
>> been able to formulate a clear technical argument against extending
>> addEventListener to
>> have some
>> mechanism for additional options. If what the
>> developer wants to say is "I want to observe wheel events, but I'm never
>> going to call
>> preventDefault
>> on them so please don't block scrolling"
>>
>> Aha, if you formulate the behavior in a bit different
>> way, then it becomes more generic...
>> So, "I'm not going to call preventDefault()" might be
>> such, useful also in other cases than just with wheel.
>> A bit odd API, but might be useful, really useful.
>>
>> enum PreventDefaultHints {
>> "never"
>> ""
>> };
>> addEventListener("wheel", listener, { preventDefault:
>> "never",
>> capture: true});
>>
>>
>> That's an interesting idea. If all handlers say they they'll
>> never preventDefault then Event.cancelable should be false so that
>> preventDefault is
>> ignored (Chrome also generates a console warning if you attempt
>> to cancel an uncancelable event). Perhaps we'd want to phrase the API as
>> indicating
>> whether you want cancelable events or not rather than a "prevent
>> default hint".
>>
>> A couple issues:
>> 1) What if one handler asks for cancelable events and other asks
>> for uncancelable events? Should 'Event.cancelable' just be true on the
>> events that
>> are fired? That risks developers having bugs where their handler
>> accidentally relies on being able to cancel an event they requested to be
>> uncancelable (due to some other component on the test page asking
>> for cancelable events). Perhaps we should allow Event.cancelable to change
>> for each
>> handler receiving the event?
>> 2) Only some event types support cancellation. I think it's fine
>> to request cancelable=false on events that are always cancelable (just
>> indicating
>> your intent not to cancel them yourself). But what if a
>> developer requests cancelable events of a type that can never be canceled
>> (eg. scroll
>> events)? Should it fail somehow? Should a developer be able to
>> feature detect this somehow?
>>
>> 3) The one thing my earlier proposal here (or my scroll-blocks-on
>> design) could support that this can't is scroll event listeners that block
>> scrolling. scroll events should never be cancelable, but we
>> argue (to much debate) that there are some limited scenarios where we should
>> allow a site
>> to opt-in to scroll event handlers that run in-sync with
>> scrolling. You could argue that scenario is different enough that it
>> either should
>> never be
>> supported or should require a different API.
>>
>> ...but unfortunately that is not backwards compatible. If we
>> could find a nice backwards compatible syntax.
>> addEventListener("wheel", listener, true, { preventDefault:
>> "never" }); would behave fine, but is a bit long.
>> Would it be good enough?
>>
>>
>> Why not? Couldn't we either use overloading <
>> http://www.w3.org/TR/WebIDL/#idl-overloading> (boolean is
>> "distinguishable" from dictionary) or
>> union
>> types <http://www.w3.org/TR/WebIDL/#idl-union>?
>>
>>
>> then it does feel most natural to allow them to say
>> that at event handler registration time somehow. Any
>> suggestion for how such a mechanism should look?
>>
>> A third option is to leave the event system
>> unmodified and rely on a CSS property to independently control when events
>> block
>> scrolling. This
>> is what
>> my 'scroll-blocks-on
>> <
>> https://docs.google.com/document/d/1aOQRw76C0enLBd0mCG_-IM6bso7DxXwvqTiRWgNdTn8/edit#heading=h.wi06xpj70hhd>'
>> proposal
>> does (for
>> which I've landed an experimental partial
>> implementation in blink). A key downside here is the 'spooky action at a
>> distance'
>> between event
>> registration and CSS property application.
>> Eg. how to multiple components each putting wheel handlers on the document
>> effectively co-ordinate
>> on what
>> the combined effect on the document should
>> be? For this particular scenario (not one of the original goals of
>> scroll-blocks-on)
>> indicating
>> intent at
>> event registration time seems much better
>> for composition.
>>
>> But this would work with keyboard events too.
>>
>> In fact, what do we actually want here.
>> wheel/key event handling, or notification about what user just did?
>> So, would some kind intentional event work here?
>>
>> addEventListener("userIntention", function(e) {
>> if (e.intention == "scroll") {
>> // do something
>> }
>> });
>> Or should "scroll" event be extended so that it
>> tells what triggered the action? That can be a bit difficult to implement,
>> but might
>> be rather
>> nice to have.
>>
>>
>> The main use case I've got in mind is activity
>> tracking. Most ad frameworks have some system (like it or not) of
>> monitoring user
>> activity
>> (where was
>> the mouse cursor, where on the page is the user
>> touching, etc.). Today this hurts scroll performance substantially.
>> Pointer events
>> solves this for
>> touch (although I'm not sure yet whether that's good
>> enough - we may still pursue a solution with touch events), but no-one has
>> proposed a
>> good design
>> that could also address the touchpad case
>> (scroll-blocks-on gets awkward in the composition cases - all components on
>> the page
>> need to use
>> some
>> library/pattern to mediate the combination of
>> desires from the different components).
>>
>> So for that use case, I don't think a scroll
>> intention is really adequate. We could have some generic 'user activity'
>> intention that
>> included a
>> screen co-ordinate, but that would quickly end up
>> looking pretty redundant with pointer events.
>>
>>
>> well, pointer events don't deal with key events.
>>
>> I can see non-ad use cases for user-activity events too
>> (do some heavy clean up in the page while user isn't interacting with it and
>> there are
>> no rAF
>> callbacks called and so.)
>>
>>
>>
>>
>>
>>
>>
>> See some more chromium-specific debate here
>> <
>> https://groups.google.com/a/chromium.org/forum/#!topic/input-dev/4B7VFPZvHY0
>> >.
>>
>> Thoughts? Out of scope for this group?
>>
>>
>> Sounds like out of scope for this group, but I
>> don't really mind whether discussed here or in WebApps.
>>
>>
>> -Olli
>>
>>
>>
>>
>> Rick
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>
Received on Monday, 6 July 2015 14:34:51 UTC