Bug 173851

Summary: Can't scrub video if in a container with on which touch events are being preventDefault()-ed
Product: WebKit Reporter: Simon Fraser (smfr) <simon.fraser>
Component: MediaAssignee: Nobody <webkit-unassigned>
Status: NEW ---    
Severity: Normal CC: ahmad.saleem792, a_protyasha, eoconnor, graouts, jer.noble, nekr.fabula, simon.fraser, webkit-bug-importer
Priority: P2 Keywords: InRadar
Version: Safari Technology Preview   
Hardware: Unspecified   
OS: Unspecified   
URL: http://output.jsbin.com/kizenof

Description Simon Fraser (smfr) 2017-06-26 14:46:29 PDT
Can't scrub video if in a container with on which touch events are being preventDefault():

https://twitter.com/nekrtemplar/status/876055291594514432

Testcase:
http://output.jsbin.com/kizenof

Video controls still send touch events. They shouldn't or at least should fire touchcancel.
Comment 1 Simon Fraser (smfr) 2017-06-26 14:46:39 PDT
rdar://problem/32989828
Comment 2 Arthur 2017-06-26 15:02:48 PDT
Here is another repro: http://jsbin.com/comiten
This time I set touch listeners to the capture phase and with it, it isn't possible to start playing video by tapping on the big "play" button.
Also if you start playing the audio somehow (e.g. via script) you won't be able to show native controls because touch events have e.stopPropagation().

Removing e.stopPropagation() makes allows you to play video / show the UI again.
Comment 3 Antoine Quint 2017-06-27 00:54:09 PDT
Hi Arthur. What is your expectation here? If you prevent propagation of touch events, then you ought to expect that content contained in the subtree will be affected, media controls require touch event to operate correctly.
Comment 4 Arthur 2017-06-27 17:45:37 PDT
I expect it to work as every other browser works. Putting a <video> tag with native controls to a touch based carousel essentially makes the video usable since you cannot scrub it.

By following your logic, preventing touch action should prevent Safari's history navigation on swipe, but it doesn't.

That's why I hate filing bugs on WebKit tracker, it's never web developer friendly.
Comment 5 Antoine Quint 2017-06-27 23:02:14 PDT
Arthur, it's a shame you feel that way, I'm trying to add to the discussion.

The way media controls are implemented is that we use a ShadowRoot (of the user-agent kind) and their UI is implemented directly in HTML, CSS and JavaScript. You can see that by toggling the "Show shadow DOM nodes" button in the Web Inspector Elements view bar and poking around a <video> element's shadow root. As such, they behave just like any other Web content would in that sub-tree hierarchy, and stopping the propagation of touch events means that the media controls cannot receive them.

I think media controls have behaved this way a long time since we've been using this technique. If this is a recent regression in Safari Technology Preview of the macOS High Sierra and iOS 11 betas, please let us know.
Comment 6 Arthur 2017-06-28 02:41:00 PDT
It isn't a regression, I see the same behavior even in iOS 8 and that makes me sad. I guess nobody is using native controls in touch-prevented block. 

I actually understand how it's done in the browser, but why do you think it's the right way especially when in all other browsers there isn't such problems? 

Also if we are talking about that it's implemented as normal web UI, then why webkit doesn't call stopProgagation() itself on the events when scrubbing is happening? How is it useful to be able to preventDefault() scrubbing on video's native controls? (might be kind of useful for ads, but it would be easier just to hide the UI completely)

Anyway, if you think that all that is wrong, how would you suggest to implement that what I'm trying to do (<video> elements with native controls in carousel)?
Comment 7 Antoine Quint 2017-06-28 04:09:00 PDT
(In reply to Arthur from comment #6)
> It isn't a regression, I see the same behavior even in iOS 8 and that makes
> me sad. I guess nobody is using native controls in touch-prevented block. 
> 
> I actually understand how it's done in the browser, but why do you think
> it's the right way especially when in all other browsers there isn't such
> problems? 



> Also if we are talking about that it's implemented as normal web UI, then
> why webkit doesn't call stopProgagation() itself on the events when
> scrubbing is happening? How is it useful to be able to preventDefault()
> scrubbing on video's native controls? (might be kind of useful for ads, but
> it would be easier just to hide the UI completely)

I think the suggestion that we stop the propagation of touch events handled by video controls is a sound one. However, in the case of scrubbing, we do not actually capture touch events per se. We have an <input type="range"> element that fires "input" and "change" events and we scrub the media element as we handle those events. We could add touch event listeners to ensure that the scrubber, as well as any other interactive element, calls stopPropagation().

> Anyway, if you think that all that is wrong, how would you suggest to
> implement that what I'm trying to do (<video> elements with native controls
> in carousel)?

I'm not saying it is all wrong, I was just trying to explain the root cause of the behaviour you noticed. As far as your particular example, if we start preventing touch events from propagating for interactive elements in the controls, you would be able to deal with touch events yourself for your carousel for touches anywhere but these elements. Would that be satisfactory?
Comment 8 Arthur 2017-07-01 05:09:24 PDT
Yes, it would be great. Just keep in mind that it's probably desirable to be able to start swipe from Play button for example.

I'm actually thinking about making a GitHub repo and bringing as much as possible browser folks (from different browser) to it to make native media control more consistent.