Bug 141456 - TouchEvent.cancelable is always true
Summary: TouchEvent.cancelable is always true
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: DOM (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified iOS 8.1
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-02-10 18:17 PST by Rick Byers
Modified: 2019-02-06 09:19 PST (History)
3 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Rick Byers 2015-02-10 18:17:03 PST
Event.cancelable is defined as follows:
http://www.w3.org/TR/DOM-Level-3-Events/#event-flow-default-cancel

When an event is canceled, then the conditional default actions associated with the event must be skipped (or as mentioned above, if the default actions are carried out before the dispatch, their effect must be undone). Whether an event object is cancelable must be indicated by the Event.cancelable attribute.

For TouchEvents, knowing whether calling preventDefault is going to have an effect can be valuable (eg. when detecting that it's too late to prevent scrolling from starting).  Chromium now sets cancelable=true if and only if the event is sent synchronously and therefore calling preventDefault will prevent/suspend an action like scrolling (eg. see https://crrev.com/266470).  You can see this in action here: http://rbyers.github.io/touch-action.html (ignore the touch-action bit - just scroll the document or the 'auto' box).  You'll see something like:

touchstart cancelable 493672ms
touchmove cancelable 124ms
touchmove 17ms
touchmove 228ms
touchend 0ms

The TouchEvents community group agrees there's currently a bug in the spec here, and will be updating the spec soon: https://github.com/w3c/touch-events/issues/6
Comment 1 Benjamin Poulain 2015-02-12 14:36:52 PST
If I understand correctly, Event.cancelable would be true if and only if Event.preventDefault() can cancel the native actions. If the actions have started OR if preventDefault() was called on a previous event, then it is false.

Is that correct? Any other case?

If that's right that would be likely a one line change, I can do that.
Comment 2 Rick Byers 2015-02-13 01:08:15 PST
> If I understand correctly, Event.cancelable would be true if and only if Event.preventDefault() can cancel the native actions. If the actions have started OR if preventDefault() was called on a previous event, then it is false.

In chromium we set it true if and only if preventDefault will cancel the native action for _that_ event (i.e. whether we're waiting to hear the disposition before scrolling) - previous events have nothing to do with it.  But that makes sense for us because we support (re)starting scrolling by not calling preventDefault on a touchmove after a sequence of touchmove's where preventDefault was called.  So each event is really independent for us.

In Safari if scrolling has already been prevented, then I think it makes the most sense to still have cancelable=true.  Just because there are no native actions for an event doesn't mean you can't still 'cancel' the event.  I expect developers to use 'cancelable=false' as a signal that something else is consuming the touch stream and they shouldn't be also moving something around (or the user will see "double handling").  Does that sound reasonable to you?

> If that's right that would be likely a one line change, I can do that.

Awesome, thanks!  I hope this is just as simple.
Comment 3 Rick Byers 2016-01-30 16:40:05 PST
Looks like this was fixed (at least in iOS 9).  Tested with http://rbyers.net/eventTest.html with "-webkit-overflow-scrolling: touch" enabled and "simple" and "coalesced" disabled.
Comment 4 Lucas Forschler 2019-02-06 09:19:16 PST
Mass move bugs into the DOM component.