Problem

Modernizr has deprecated their touchevents test because it's not a reliable way of detecting touch devices, and can be misused to compromise the experience for devices that support touch and pointer devices.

There is logic in Contextual links that rely on the Modernizr.touch test to determine if hover behavior should be present. The unreliable Modernizr.touchevents should not be used to identify devices where hover behavior should be disabled

contextual.js, row 261:

// We only want mouse hover events on non-touch.
if (!Modernizr.touchevents) {
  mapping.mouseenter =  function () { this.model.focus(); };
}

contextual.js, row 393:

// We don't want mouse hover events on touch.
if (Modernizr.touchevents) {
  mapping = {};
}
return mapping;

Proposed resolution

Change the above code to have conditions based on the actual presence of touch events, instead of using Modernizr.touchevents.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

peterpoe’s picture

Status: Active » Needs review
FileSize
2.52 KB
LewisNyman’s picture

Status: Needs review » Needs work

The last submitted patch, 1: modernizrtouch-breaks-firefox-2168711-1.patch, failed testing.

mariancalinro’s picture

Assigned: Unassigned » mariancalinro
mariancalinro’s picture

Assigned: mariancalinro » Unassigned
Status: Needs work » Needs review
FileSize
4.96 KB

I have a possible solution for this issue. It's not extremely pretty, but it's smart:

If we attach a touchstart event listener to the window object very early, this is the very first event handler that will be executed when (if) a user touches the screen. We initialize a variable that represents the presence of a touch capable screen(device) to false, and set it to true inside the event listener. Also, we can attach the event using one(), so that after it's triggered it unattaches itself. Code from the patch:

// Detect if screen is touch capable. This only happens at the first user
// interaction, so you can't depend on it when te page is renderd.
Modernizr.touchDisplay = false;
if (Modernizr.touch) {
  // touchstart is the first event triggered when a user touches the
  // screen, so this will be executed before any other listener that
  // needs to know if the device is touch-capable or not.
  jQuery(window).one('touchstart', function (){
    Modernizr.touchDisplay = true;
  });
}

The only problem with this solution is that at the time the page is rendering, the user most definitely did not interact yet with the page, so we can't know yet if the device has a touch capable screen or not. This limits our use of this detection mechanism to the event handlers, because they are invoked after the user started to interact with the page.

I have created a patch that implements this ideea, I just haven't been able to test this on a touch device, I will probably test this on simplytest.me sometimes later in the day.

P.S. I am not sure if adding a new attribute to the Modernizr object is the best approach, but it has the added benefit of being the first place where someone would look for this.

mariancalinro’s picture

I managed to test this patch on my Nexus 10 in Chrome, and table drag is working. I don't know where the code from contextual.js is used, so that one is not tested on a mobile device. Also we need to test this in a desktop browser that reports it has support for touch events.

LewisNyman’s picture

Issue tags: +JavaScript, +frontend
Wim Leers’s picture

Then please also make sure to not create a UX regression in contextual links; we specifically excluded hover events there on touch-enabled devices because when you have both "hover" and "click" events on a certain DOM element, then "hover" equates to a single tap and "click" equates to a double-tap, which is an atrocious UX.

jhedstrom’s picture

Status: Needs review » Needs work

Needs work based on #8 I think.

droplet’s picture

swentel’s picture

Ok, I was taken here after a couple of duplicates :)

Thing is, contextual links don't even show up when I hover on my machine, on chrome. Firefox is fine.
Note that it's a touch enabled laptop.

droplet’s picture

Title: Wrong use of Modernizr.touch, breaks tabledrag and contextual links on Firefox » Wrong use of Modernizr.touch, breaks contextual links
Status: Needs work » Needs review
Issue tags: +Needs manual testing
FileSize
1.49 KB

Try it.

tableDrag, I think I've fixed it some times ago..

droplet’s picture

Let me explain it in a little further. Above patch works because `touchstart` event is fired before mouse event.

droplet’s picture

Ahh. I think I should add `mousemove` event to re-enable it again after any touch event

(this patch may cause little performance impacts)

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.1.x-dev » 8.2.x-dev

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

Bug reports should be targeted against the 8.2.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.3.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

Bug reports should be targeted against the 8.3.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.4.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

ChristianAdamski’s picture

Bump.

Issue still present on touch-enabled laptop. This problem won't go away.

GrandmaGlassesRopeMan’s picture

Version: 8.3.x-dev » 8.4.x-dev

@droplet

+++ b/core/modules/contextual/js/views/RegionView.js
@@ -16,16 +16,30 @@
+          istouchStart = true;

Is the expectation to completely disable the 'hover' behavior when interacting with the region?

@ChristianAdamski

Could you give the patch in #14 a shot?

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.0-alpha1 will be released the week of July 31, 2017, which means new developments and disruptive changes should now be targeted against the 8.5.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

joelpittet’s picture

Status: Needs review » Needs work

The conditional if(!istouchStart = false;) followed by assignment: istouchStart = false; seems a bit overkill considering the variable is already checked to be false.

I really like that it's removing the Modernizr dependency!

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.0-alpha1 will be released the week of January 17, 2018, which means new developments and disruptive changes should now be targeted against the 8.6.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Kgaut’s picture

Version: 8.6.x-dev » 8.7.x-dev

Drupal 8.6.0-alpha1 will be released the week of July 16, 2018, which means new developments and disruptive changes should now be targeted against the 8.7.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Version: 8.7.x-dev » 8.8.x-dev

Drupal 8.7.0-alpha1 will be released the week of March 11, 2019, which means new developments and disruptive changes should now be targeted against the 8.8.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

kostyashupenko’s picture

For this issue need to update core modernizr at first since it's outdated (v 3.3.1 currently).

Modernizr 3.7.1 got an update for touchevent tests. See here https://github.com/Modernizr/Modernizr/pull/2409 . This update was related to the latest versions of Chrome browser. So right now Modernizr.touchevents returns "true" always in chrome browser (???). These changes looks a bit weird for me, so maybe better to postpone an update for this issue, until we get how to detect "real" touch screens.

Sam152’s picture

Hit the same issue as #26, using an updated version of modernizr, created from a build pipeline breaks contextual links in recent versions of chrome.

Quoted from the chrome platform status post:

Site should use navigator.maxTouchPoints for touchscreen detection, and Windows.TouchEvent for TouchEvent feature detection.

So in new versions of modernizr, the Modernizr.touch check is based on support for window.TouchEvent, which is supported in desktop versions of Chrome and not necessarily just touch devices. Forcing a downgrade to 3.3.1 should fix this, but a long term solution for core should be detecting touch devices not touch events.

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

larowlan’s picture

yogeshmpawar’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
FileSize
3.73 KB
5.85 KB

Rerolled patch with reroll diff against 9.4.x branch.

alexpott’s picture

If #34 is the solution then we can remove Modernizr from the dependencies of RegionView.js

yogeshmpawar’s picture

Status: Needs review » Needs work

The last submitted patch, 36: 2168711-36.patch, failed testing. View results

bnjmnm’s picture

Status: Needs work » Needs review
FileSize
8.06 KB

I like the approach! The earlier patches remove some docs and formatting so I created a new patch that doesn't remove/restructure anything that can remain intact. The interdiff would be incoherent, so it's just a new patch. I also added some comments to explain what the logic is doing, and removed the Modernizr dependency entirely.

Status: Needs review » Needs work

The last submitted patch, 38: 2168711-36.patch, failed testing. View results

bnjmnm’s picture

Issue summary: View changes
Status: Needs work » Needs review

Tabledrag stopped using Modernizr ~6 years ago: #2177293: Drag and drop broken on touch enabled laptops. I updated the issue summary a bit.

bnjmnm’s picture

Title: Wrong use of Modernizr.touch, breaks contextual links » Modernizr.touchevents use can lead to scenarios that break contextual links
nod_’s picture

Status: Needs review » Reviewed & tested by the community

I don't have a touch enabled laptop so I can't actually test this properly. But the code makes sense and is in line with #14 so that's a pretty good indication this should be the right solution :)

lauriii’s picture

benjifisher’s picture

I tested the patch from #43 using a fresh install of the Standard profile on 10.0.x.

I am using a laptop with a touch pad and a touch screen. I did not see any difference between the contextual links with and without the patch. Either way, I could use the touch pad to hover and then click on a contextual link, or I could click on the Edit button and then click on the contextual links. Using the touch screen, I could use the Edit button and then the contextual links.

My laptop has a 13" screen, and the first time I tried to click on a contextual link using the touch screen (without the patch), I had trouble. I zoomed the screen a bit, and then it worked fine.

  • lauriii committed 10bdae2 on 10.0.x
    Issue #2168711 by yogeshmpawar, droplet, mariancalinro, bnjmnm, peterpoe...

  • lauriii committed e894995 on 9.5.x
    Issue #2168711 by yogeshmpawar, droplet, mariancalinro, bnjmnm, peterpoe...
lauriii’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs manual testing

Removing needs manual testing tag based on #44.

Committed 10bdae2 and pushed to 10.0.x. Also committed to 9.5.x and cherry-picked to 9.4.x. Thanks!

Committed from 37000ft above Firebaugh, California, on the way home from DrupalCon Portland 2022.

  • lauriii committed 49a87f1 on 9.4.x
    Issue #2168711 by yogeshmpawar, droplet, mariancalinro, bnjmnm, peterpoe...

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.