Closed Bug 966919 Opened 7 years ago Closed 4 years ago

event.preventDefault() does not cancel default action of "touchend" event (resulting in click events firing on unintended elements on vimeo.com)

Categories

(Web Compatibility :: Mobile, defect)

Other
Android
defect
Not set
normal

Tracking

(firefox27 affected, firefox28 affected, firefox29 affected)

RESOLVED WORKSFORME
Tracking Status
firefox27 --- affected
firefox28 --- affected
firefox29 --- affected

People

(Reporter: costinel, Assigned: miketaylr)

References

()

Details

(Whiteboard: [notcontactready][country-all])

Attachments

(1 file)

Attached video tmp_vimeo-763440829.mp4
User Agent: Mozilla/5.0 (Android; Tablet; rv:27.0) Gecko/27.0 Firefox/27.0 (Nightly/Aurora)
Build ID: 20140127124221

Steps to reproduce:

opening a new bug as requested here https://bugzilla.mozilla.org/show_bug.cgi?id=719694#c38

when i open a vimeo link, the page loads as expected but when I tap the play button it appears to start caching/downloading but the play button transforms into pause button then back into play button (instantly). no video is played, even though the stream appears to be received from vimeo! (also my network traffic app displays sustained incoming flow at maximum wifi speed during video caching - when the playback bar starts filling)
moreover when i tap the play button the audio plays for an instant before the pause button transforms into play button again
using firefox 27 beta on android 4.4.2 with art runtime on nexus 7 2013 lte
don't know if related but attached bug video exhibits same behaviour :)) i tap the clip name, it opens, it downloads the entire file, shows placeholder and play button and displays total time but tapping the play button quickly transforms into pause button then back into play button
Taping on the play button toggles the button for a second but the video does not play.
Taping on the video content works as play/pause. Taping once to start the video playback, tap again to pause the video playback.
On Google Chrome tapping on the video works as show/hide the video controls.

Tested on Google Nexus 7 (Android 4.4.2).
Status: UNCONFIRMED → NEW
Ever confirmed: true
In your video I noticed you are on Vimeo's desktop website where their player is more than likely not tested nor compatible with Firefox for Android. They purposely updated their libraries to support Firefox on their mobile site as we discussed in the tech evangelism bug.

Do you see these issues using Vimeo's mobile site?

I couldn't reproduce.
Component: General → Mobile
Product: Firefox for Android → Tech Evangelism
Summary: vimeo clips do not play → Vimeo desktop clips do not play
Version: Firefox 27 → unspecified
(In reply to Aaron Train [:aaronmt] from comment #3)
> In your video I noticed you are on Vimeo's desktop website where their
> player is more than likely not tested nor compatible with Firefox for
> Android. They purposely updated their libraries to support Firefox on their
> mobile site as we discussed in the tech evangelism bug.
> 
> Do you see these issues using Vimeo's mobile site?
> 
> I couldn't reproduce.

if you pay attention to the clip you will notice I am tapping a mobile url.
manually going to vimeo.com/m redirects me to regular website
also, did you check the attachment, too? it exhibits the same behaviour as vimeo!
on what device did you try to reproduce?!
(In reply to flaviu.cos from comment #2)
> Taping on the play button toggles the button for a second but the video does
> not play.
> Taping on the video content works as play/pause. Taping once to start the
> video playback, tap again to pause the video playback.
> On Google Chrome tapping on the video works as show/hide the video controls.
> 
> Tested on Google Nexus 7 (Android 4.4.2).

tapping the video content starts playing apparently but there is no video. i can hear the audio track and i can tap randomly on play bar and it seems to jump at the whatever point i tap, but only audio.
One thing to note, using Firefox for Android on a Nexus 7 means your UA string has a "Tablet" token, rather than "Mobile". Vimeo has decided to send the desktop site to tablets, that's why vimeo.com/m redirects to the Desktop site. I do not consider this a bug.

I can confirm the play/pause issue. To reproduce, using a Nexus 7 (possibly any tablet ua):

1) navigate to http://vimeo.com/85577159
2) Press Play

expected: video plays
actual: Pause button shows briefly, then video stops.

Need to dig in and figure out what's up.
Assignee: nobody → miket
Whiteboard: [notcontactready][country-all]
changing UA with Phony addon from default to "android phone" makes vimeo redirect to mobile site and from there the video plays with image and sound. changing UA to anything else the behaviour remains as described before.
changing UA with Phony addon from default to "android phone" makes vimeo redirect to mobile site and from there the video plays with image and sound. changing UA to anything else the behaviour remains as described before.
(don't know if this related and i'm tired of filling bugs to mozilla) the attached clip of this bug still does not play no matter what user agent I choose with phony
(In reply to costinel from comment #9)
> (don't know if this related and i'm tired of filling bugs to mozilla) the
> attached clip of this bug still does not play no matter what user agent I
> choose with phony

The video doesn't work for me in any browser. But it doesn't matter at this point--we have all the info we need in Comment 6 to proceed with analysis. Will try to get to this in the next few days.
I haven't nailed this one down just yet. I spent quite a bit of time chasing the wrong hypotheses, thinking it was related to video decoders.

However, when remote debugging:

document.querySelector('.video video').play()
document.querySelector('.video video').pause()

in the console do exactly what one would expect. So there's something weird going on with the play button that is somehow calling pause right after (and an error event is getting dispatched as well?).
Summary: Vimeo desktop clips do not play → Clicking Vimeo play controls on Firefox for Android tablet plays, then pauses video
Switched back from art to dalvik and now clips play when tapping the main area (not play button) but i have no time scroll bar. Don't know if this is because some changes when updating firefox beta 28 or because of switching runtimes. Will update if i ever switch to art again. Anyway it's not what i'd expect but at least i can watch a clip but only able to pause, no scroll.
It's possibly Bug 866080 which is allowing you to see the videos now (that fix landed in 28, I believe). But the actual bug as described in this issue still exists in Nightly.
More pieces to the puzzle, in player.js

attachClickHandler: function(c, e, f, k) {
    k = "function" === typeof e ? f : k;
    f = "function" === typeof e ? e : f;
    var m = function(c) {
        if ("touchend" === c.type) {
            if (c.changedTouches) {
                var d = b.elementFromPoint(c.changedTouches[0].pageX - a.pageXOffset, c.changedTouches[0].pageY - a.pageYOffset);
                null !== d && this.contains(d) && f.call(this, c);
            }
            "function" === typeof k && k.call(this, c);
            return !1;
        }
        return f.call(this, c);
    };
    if ("function" === typeof e) Gator(c).on([ "click", "touchend" ], m); else Gator(c).on([ "click", "touchend" ], e, m);
}

(Gator is defined here: https://gist.github.com/miketaylr/8939631

Later on, r.attachClickHandler(f, ".play", t); (".play" being the play button on the player).

So what's happening is _both_ the click and touchend event handlers are firing, so the play button is getting toggled twice: play() then pause().

I added some logging and here's the difference between Firefox for Android and Chrome Mobile on my Nexus 7:

Firefox for Android:
"touchend being sent to <button tabindex="20" [snip...] player.js:4
"pause() [object HTMLVideoElement]" player.js:14
"play() [object HTMLVideoElement]" player.js:9
"click being sent to <button tabindex="20" [snip...] player.js:4
"pause() [object HTMLVideoElement]"

Chrome Mobile:
touchend being sent to <div class="play-icon"><svg [snip...] player.js:4
pause() [object HTMLVideoElement] player.js:14
XHR finished loading: "http://player.vimeo.com/v2/log/play". player.js:4691
play() [object HTMLVideoElement] 

That initial pause() before play() should be expected while it's buffering (I think). Two things that jump out at me: Chrome never fires "click" and touchend is sent to .play-icon (but presumably that bubbles up to .play so it shouldn't matter).

I don't know if firing touchend and click is considered a bug here (AFAICT other browsers do the same thing--jQuery Mobile has its own virtual mouse events to normalize touch/click, for example). It's possible Vimeo is relying on WebKit behavior and needs to cancel the click or touchend event (whichever comes 2nd) or "debounce" the callback to the listeners.
Matt & Wes, can you clarify what events we're sending when the user touches a control for Mike?
Flags: needinfo?(wjohnston)
Flags: needinfo?(mbrubeck)
Our events look right AFAICT. You can only cancel click events by calling preventDefault on touchstart/the first touchmove. I'm not sure why the targetting is different. Looking at the page a bit, there's some room where the button/icon don't overlap. Maybe you lucked into one of those places?
Flags: needinfo?(wjohnston)
(In reply to Wesley Johnston (:wesj) from comment #16)
> Our events look right AFAICT. You can only cancel click events by calling
> preventDefault on touchstart/the first touchmove. 

Cool, thanks. The spec says preventing the default action of touchend will prevent a click event [1]. And they're using `return !1`, which should be good enough. According to this simple test [2], Firefox for Android (Nightly) cancels the click events if you return false/preventDefault for touchstart or touchend (but not Firefox for Android stable, so apparently this has changed recently).

If I change `attachClickHandler` to listen for "touchstart", rather than "touchend"--the play button (and everything else on the page) works just fine in Nightly (and Chrome Android & iPad Safari):

> attachClickHandler: function(c, e, f, k) {
>     k = "function" === typeof e ? f : k;
>     f = "function" === typeof e ? e : f;
>     var m = function(c) {
>         if ("touchstart" === c.type) {
>             if (c.changedTouches) {
>                 var d = b.elementFromPoint(c.changedTouches[0].pageX -
> a.pageXOffset, c.changedTouches[0].pageY - a.pageYOffset);
>                 null !== d && this.contains(d) && f.call(this, c);
>             }
>             "function" === typeof k && k.call(this, c);
>             return !1;
>         }
>         return f.call(this, c);
>     };
>     if ("function" === typeof e) Gator(c).on([ "click", "touchstart" ], m);
> else Gator(c).on([ "click", "touchstart" ], e, m);

But given the consistent test results in [2]... I still don't understand why `return !1` for "touchend" fails to cancel the click. There could be some other script interacting here. I'd like to really know what's up before we approach Vimeo with this kind of suggestion, just because it works.
(In reply to Mike Taylor [:miketaylr] from comment #17)
> Cool, thanks. The spec says preventing the default action of touchend will
> prevent a click event [1].

The spec is really explicit about this in the touchstart/touchmove sections. I guess we've never interpreted the "default actions" section of that table to be that, but it does read that way. Lets get mbrubeck's feedback before we implement something.

> (Nightly) cancels the click events if you return false/preventDefault for
> touchstart or touchend (but not Firefox for Android stable, so apparently

I don't think we did this intentionally, but there were some changes to this in Aurora recently, so maybe we regressed something.
(In reply to Wesley Johnston (:wesj) from comment #19)
> The spec is really explicit about this in the touchstart/touchmove sections.
> I guess we've never interpreted the "default actions" section of that table
> to be that, but it does read that way. Lets get mbrubeck's feedback before
> we implement something.

Sure thing. I'm not quite convinced we're the ones with the bug--there's still a few missing pieces to the puzzle in really knowing what's going on here.

> > (Nightly) cancels the click events if you return false/preventDefault for
> > touchstart or touchend (but not Firefox for Android stable, so apparently
> 
> I don't think we did this intentionally, but there were some changes to this
> in Aurora recently, so maybe we regressed something.

For better or worse, we're consistent with Android Chrome and iOS Safari now (probably better, compat-wise).
(In reply to Wesley Johnston (:wesj) from comment #19)
> (In reply to Mike Taylor [:miketaylr] from comment #17)
> > Cool, thanks. The spec says preventing the default action of touchend will
> > prevent a click event [1].
> 
> The spec is really explicit about this in the touchstart/touchmove sections.
> I guess we've never interpreted the "default actions" section of that table
> to be that, but it does read that way. Lets get mbrubeck's feedback before
> we implement something.

Back in bug 653009 we discovered that other browsers were inconsistent here; even different versions of Safari had different behavior when cancelling the "touchend" event.  It sounds like the major browsers have now converged on preventing "click" events in this case, so I agree that we should too.  (It sounds like we already have, possibly unintentionally.)  And the best advice we can give to publishers is to not rely on this behavior.
Flags: needinfo?(mbrubeck)
See Also: → 1007017
(In reply to Matt Brubeck (:mbrubeck) from comment #21)
> It sounds like the major browsers have now converged on
> preventing "click" events in this case, so I agree that we should too.  (It
> sounds like we already have, possibly unintentionally.)  And the best advice
> we can give to publishers is to not rely on this behavior.

So this came up again in Bug 1007017, which prompted me to actually figure out the issue--calling event.preventDefault() from inside a "touchend" handler will not cancel the default "click" event. 

My earlier observation that Nightly allowed you to prevent clicks after touchstart doesn't hold true anymore (see https://miketaylr.com/bzla/touchend.html)--so I might have just observed an unintentional anomaly.

Matt, should we file a new bug to track this change? I'm happy to do so--but I don't know where the right place to file it.
Duplicate of this bug: 1007017
See https://bugzilla.mozilla.org/show_bug.cgi?id=1007017#c4 for a more detailed explanation of how this bug manifests itself in Vimeo's codebase, and a minimal test case in https://miketaylr.com/bzla/1007017-2.html.
Summary: Clicking Vimeo play controls on Firefox for Android tablet plays, then pauses video → event.preventDefault() does not cancel default action of "touchend" event (resulting in click events firing on unintended elements on vimeo.com)
Keywords: site-compat
Keywords: site-compat
(In reply to Mike Taylor [:miketaylr] from comment #22)
> My earlier observation that Nightly allowed you to prevent clicks after
> touchstart doesn't hold true anymore (see
> https://miketaylr.com/bzla/touchend.html)--so I might have just observed an
> unintentional anomaly.
> 
> Matt, should we file a new bug to track this change? I'm happy to do so--but
> I don't know where the right place to file it.

Sorry for the late reply.  Yes, we should probably file one bug for this in the "Firefox for Android" product, and another under "Core: Panning and Zooming" if Firefox OS needs to be changed too.
Flags: needinfo?(mbrubeck)
Thanks Matt, will do.
Depends on: 1016480
Depends on: 1016481
This seems to be fixed for me on my Nexus 7, can you verify costinel?
yes but vimeo is still unfriendly:
1. if i tap the play button before the page finishes loading, it either
1.1. displays the message "the video can't be played with your current setup"
or
1.2 does nothing, then i tap pause, then i tap play and it starts playing
2. unlike in desktop browsers, playback does not start/pause by tapping inside the clip but only by playback button.
3. entering fullscreen is a lottery because vimeo thinks "hi resolution equals large display", which is not true, and shows me the desktop site. under these conditions the fullscreen button is so small that i have to zoom in first and even then you have to be very lucky to get it to respond to my tap. when finally entering fullscreen, video plays with interruptions, albeit in hi quality.
4. request to access the mobile site vimeo.com/m is ignored and i am always redirected to regular site. attempting to cheat by changing user agent into firefox/phone with phony addon makes it display the simplified interface which has a big play button in the middle that automatically starts clip in fullscreen mode, however in this mode it gives me a poor quality video.
Flags: needinfo?(costinel)
this is an example of a clip that plays jerky (and all i've described in previous comment) http://vimeo.com/100888579
OK, it sounds like the original issue has been fixed then based on that. 

#2 is probably worth filing a new bug for. #3 and and #4 are due to the fact that they serve Tablet UAs the Desktop site. Some sites (and users) prefer this, but I can see how what you're describing is frustrating. Would you like to close this and open a new issue for #2?
Testing a few UAs to understand if vimeo is consistent with its tablet UX choices.
Using http://vimeo.com/103411714

* Galaxy Tab2: Mozilla/5.0 (Linux; Android 4.2.2; GT-P3113 Build/JDQ39) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.141 Safari/537.36
* Sony S Tablet: Mozilla/5.0 (Linux; U; Android 4.0.3; ja-jp; Sony Tablet S Build/TISU0R0110) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Safari/534.30
* Safari iPad: Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A403 Safari/8536.25
* Firefox OS Tablet: Mozilla/5.0 (Android; Tablet; rv:30.0) Gecko/30.0 Firefox/30.0

All of these do the same thing.
1. Receiving desktop site.
2. http://vimeo.com/m/103411714 redirected to http://vimeo.com/103411714

**except for…** 

Firefox OS tablet which is receiving the mobile version :)
Mozilla/5.0 (Tablet; rv:30.0) Gecko/30.0 Firefox/30.0
http://vimeo.com/m/103411714
And above I meant meant Firefox Android Tablet in "* Firefox OS Tablet: Mozilla/5.0 (Android; Tablet; rv:30.0) Gecko/30.0 Firefox/30.0". I want an edit this comment button ;)
This seems to be working for me.
Status: NEW → RESOLVED
Closed: 4 years ago
Resolution: --- → WORKSFORME
Product: Tech Evangelism → Web Compatibility
You need to log in before you can comment on or make changes to this bug.