- From: Rick Byers <rbyers@google.com>
- Date: Tue, 17 Feb 2015 17:34:07 -0500
- To: Jacob Rossi <Jacob.Rossi@microsoft.com>
- Cc: "public-touchevents@w3.org" <public-touchevents@w3.org>, Mustaq Ahmed <mustaq@chromium.org>
- Message-ID: <CAFUtAY9TJ_L=tLz2XZoNEENdAfYpyiPAx0-V1woe6Q1xfp5=Kw@mail.gmail.com>
For the record, we agreed <http://www.w3.org/2015/02/17-touchevents-minutes.html> that we should try to fix the bug <https://code.google.com/p/chromium/issues/detail?id=457497> with mouseenter/mouseleave not being fired in Chrome (Jacob says it looks like it shouldn't be that risky). Mustaq is aiming to land a fix in Chrome 43 and will follow up here once it's available in Canary for website compat testing. Rick On Tue, Feb 10, 2015 at 8:05 PM, Rick Byers <rbyers@google.com> wrote: > On Thu, Feb 5, 2015 at 10:36 AM, Jacob Rossi <Jacob.Rossi@microsoft.com> > wrote: > >> I’ve mentioned before that we’re exploring firing the Touch Event >> spec’s model for compatibility mouse events so we’re more interoperable. >> In doing so, we uncovered a nasty interoperability issue that’s quite >> frustrating. This one takes a minute to explain, so grab a cup of coffee >> and bear with me. :-) >> >> >> >> Safari implements a proprietary heuristic for detecting hover menus. It >> works something like this on a simple tap: >> >> >> >> 1. Fire touch events >> >> 2. Fire mouse events for hover (e.g. mouseover/enter) , down, up >> >> 3. If “page content changes” (insert undocumented proprietary >> heuristic), then persist the hover on the node & suppress firing the click >> event [1] >> >> 4. If not, then fire events to remove hover and fire click >> >> >> >> The heuristic is attempting to detect a hover menu intended for mouse, >> which enables a “tap to hover menu, tap again to click” type of experience >> when it works. However, sometimes the heuristic has a false positive >> causing non-hover-menus to require multiple taps to get a click event on >> something. This leads web developers to try to work around the heuristic. >> >> >> >> Here’s a common pattern we’ve found on popular sites like Netflix: >> >> >> http://stackoverflow.com/questions/3038898/ipad-iphone-hover-problem-causes-the-user-to-double-click-a-link/22444819#22444819 >> >> >> >> In summary, it looks like: >> mouseenter – open hover menu >> mouseleave – close hover menu >> >> click – toggle hover menu >> >> >> >> For a mouse in Safari, the menu opens when you mouse over and closes when >> you click something or move your mouse out. Cool. >> >> For touch, the menu opens after you tap. The mouseenter causes “page >> content changes” in step #2 above. Thus mouseleave and click do not fire. >> Therefore the menu stays open. You can tap again to click an item in the >> menu. Cool. >> >> >> >> Now, consider a browser that does not implement Safari’s non-standard >> heuristic. In this case, Blink/Gecko follow the Touch Events spec [2] >> essentially and do this: >> >> 1. Fire touch events >> >> 2. Fire mousemove >> >> a. (While not explicitly mentioned in the spec, this causes a >> mouseover to fire) >> >> 3. Fire mouse down, up >> >> 4. Fire click >> >> >> >> Note, like Safari, this means hover state essentially persists on the >> node until you tap another node (which fires a new mousemove, which removes >> hover from the old node and applies it to the new). The Touch Events spec >> does not, however, explicitly state when hover related events, like >> over/out/enter/leave occur. It’s just assumed the mousemove causes it >> (grrr…the spec should say this!). >> > > Agreed, please submit a PR for this. I've always taken it for granted > that over/out/enter/leave events should ALWAYS be consistent with mousemove > (any time you get a move with a new target, they're fired appropriate), but > stating that explicitly doesn't hurt. > > Still with me? :-) Here’s the rub: Blink doesn’t fire >> mouseenter/mouseleave for touch, only mouseover/mouseout (I didn’t have a >> Firefox mobile device handy to test, but I assume it’s similar). This is >> despite the fact that Blink does support mouseenter/mouseleave for mouse >> input. [3] >> > > This is simply a bug from when mouseenter/mouseleave events were first > implemented. I only noticed this recently from code inspection (I added a FIXME > in the code > <https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/core/page/EventHandler.cpp&q=EventHandler.cpp%20mouseenter&sq=package:chromium&type=cs&l=2659> > but failed to file a bug - just filed one now <http://crbug.com/457497>). > > >> It turns out this is a critical detail missing from the spec. Because >> if you make the mistake we did, which was to fire mouseenter/mouseleave >> when processing the mousemove for touch, then the above code I described >> breaks as you get: >> >> >> >> 1. Fire touch events >> >> 2. Fire mousemove >> >> a. Fire mouseover >> >> b. Fire mouseenter – open hover menu >> >> 3. Fire mouse down, up >> >> 4. Fire click – hover menu toggles >> >> >> >> So the hover menu opens and then immediately closes. Not cool. >> >> >> >> tl;dr – for best compatibility, browsers need to choose either: >> (a) try to reverse engineer Safari’s heuristic (not >> likely to be very interoperable) >> >> (b) do not implement mouseenter/mouseleave for touch >> > > Crap crap crap crap. > > How prevalent is this pattern? I.e. how much pain would we cause by > fixing our bug in blink? > > The only pragmatic solution I can see (should we end up shipping the Touch >> Event model for mouse events in IE) is B. It should be noted that I’ve >> tried to get the Safari engineers to share details about the heuristic, but >> they have declined. >> >> >> >> I think this critical detail (not firing mouseenter/mouseleave for touch) >> should probably be added as errata to the current spec. WDYT? >> > > If we think this is what's best for the web (i.e. enough people have > already taken a dependency on our bug), then that's OK with me (although as > Patrick says - perhaps that's part of TEv2, not TEv1 errata). It's not > very rational though. Is there a better pattern we could advocate for? > What about combining this with some sort of more explicit signal of > developer intent (like your aria-hasrole=popup)? Ideally we'd have a path > where browser's default behavior can be one (confusing) way for compat, but > we have clear explicit APIs that could be implemented by all browsers to > get developers out of this mess. > > -Jacob >> >> >> >> [1] >> https://developer.apple.com/library/ios/documentation/AppleApplications/Reference/SafariWebContent/HandlingEvents/HandlingEvents.html >> >> [2] http://www.w3.org/TR/touch-events/#mouse-events >> >> [3] https://status.modern.ie/dom3mouseentermouseleaveevents >> >> >> >> >> >> >> > >
Received on Tuesday, 17 February 2015 22:34:55 UTC