Bug 141456

Summary: TouchEvent.cancelable is always true
Product: WebKit Reporter: Rick Byers <rbyers>
Component: DOMAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: benjamin, dino, simon.fraser
Priority: P2    
Version: 528+ (Nightly build)   
Hardware: Unspecified   
OS: iOS 8.1   

Rick Byers
Reported 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
Attachments
Benjamin Poulain
Comment 1 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.
Rick Byers
Comment 2 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.
Rick Byers
Comment 3 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.
Lucas Forschler
Comment 4 2019-02-06 09:19:16 PST
Mass move bugs into the DOM component.
Note You need to log in before you can comment on or make changes to this bug.