Unverified Commit 10bdae28 authored by Lauri Timmanee's avatar Lauri Timmanee
Browse files

Issue #2168711 by yogeshmpawar, droplet, mariancalinro, bnjmnm, peterpoe,...

Issue #2168711 by yogeshmpawar, droplet, mariancalinro, bnjmnm, peterpoe, lauriii, Kgaut, nod_, benjifisher:  Modernizr.touchevents use can lead to scenarios that break contextual links
parent de481621
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ drupal.contextual-links:
    - core/drupalSettings
    # @todo Remove this in https://www.drupal.org/project/drupal/issues/3203920
    - core/internal.backbone
    - core/modernizr
    - core/once

drupal.contextual-toolbar:
+26 −10
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * A Backbone View that renders the visual view of a contextual region element.
 */

(function (Drupal, Backbone, Modernizr) {
(function (Drupal, Backbone) {
  Drupal.contextual.RegionView = Backbone.View.extend(
    /** @lends Drupal.contextual.RegionView# */ {
      /**
@@ -13,19 +13,35 @@
       *   A mapping of events to be used in the view.
       */
      events() {
        let mapping = {
        // Used for tracking the presence of touch events. When true, the
        // mousemove and mouseenter event handlers are effectively disabled.
        // This is used instead of preventDefault() on touchstart as some
        // touchstart events are not cancelable.
        let touchStart = false;
        return {
          touchstart() {
            // Set to true so the mouseenter and mouseleave events that follow
            // know to not execute any hover related logic.
            touchStart = true;
          },
          mouseenter() {
            if (!touchStart) {
              this.model.set('regionIsHovered', true);
            }
          },
          mouseleave() {
            if (!touchStart) {
              this.model.close().blur().set('regionIsHovered', false);
            }
          },
          mousemove() {
            // Because there are scenarios where there are both touchscreens
            // and pointer devices, the touchStart flag should be set back to
            // false after mouseenter and mouseleave complete. It will be set to
            // true if another touchstart event occurs.
            touchStart = false;
          },
        };
        // We don't want mouse hover events on touch.
        if (Modernizr.touchevents) {
          mapping = {};
        }
        return mapping;
      },

      /**
@@ -52,4 +68,4 @@
      },
    },
  );
})(Drupal, Backbone, Modernizr);
})(Drupal, Backbone);
+18 −11
Original line number Diff line number Diff line
@@ -5,25 +5,32 @@
* @preserve
**/

(function (Drupal, Backbone, Modernizr) {
(function (Drupal, Backbone) {
  Drupal.contextual.RegionView = Backbone.View.extend({
    events() {
      let mapping = {
      let touchStart = false;
      return {
        touchstart() {
          touchStart = true;
        },

        mouseenter() {
          if (!touchStart) {
            this.model.set('regionIsHovered', true);
          }
        },

        mouseleave() {
          if (!touchStart) {
            this.model.close().blur().set('regionIsHovered', false);
          }
        },

      };

      if (Modernizr.touchevents) {
        mapping = {};
        mousemove() {
          touchStart = false;
        }

      return mapping;
      };
    },

    initialize() {
@@ -36,4 +43,4 @@
    }

  });
})(Drupal, Backbone, Modernizr);
 No newline at end of file
})(Drupal, Backbone);
 No newline at end of file
+28 −10
Original line number Diff line number Diff line
@@ -3,7 +3,7 @@
 * A Backbone View that provides the visual view of a contextual link.
 */

(function (Drupal, Backbone, Modernizr) {
(function (Drupal, Backbone) {
  Drupal.contextual.VisualView = Backbone.View.extend(
    /** @lends Drupal.contextual.VisualView# */ {
      /**
@@ -18,7 +18,32 @@
          event.preventDefault();
          event.target.click();
        };
        const mapping = {

        // Used for tracking the presence of touch events. When true, the
        // mousemove and mouseenter event handlers are effectively disabled.
        // This is used instead of preventDefault() on touchstart as some
        // touchstart events are not cancelable.
        let touchStart = false;

        return {
          touchstart() {
            // Set to true so the mouseenter events that follows knows to not
            // execute any hover related logic.
            touchStart = true;
          },
          mouseenter() {
            // We only want mouse hover events on non-touch.
            if (!touchStart) {
              this.model.focus();
            }
          },
          mousemove() {
            // Because there are scenarios where there are both touchscreens
            // and pointer devices, the touchStart flag should be set back to
            // false after mouseenter and mouseleave complete. It will be set to
            // true if another touchstart event occurs.
            touchStart = false;
          },
          'click .trigger': function () {
            this.model.toggleOpen();
          },
@@ -28,13 +53,6 @@
          },
          'touchend .contextual-links a': touchEndToClick,
        };
        // We only want mouse hover events on non-touch.
        if (!Modernizr.touchevents) {
          mapping.mouseenter = function () {
            this.model.focus();
          };
        }
        return mapping;
      },

      /**
@@ -84,4 +102,4 @@
      },
    },
  );
})(Drupal, Backbone, Modernizr);
})(Drupal, Backbone);
+18 −11
Original line number Diff line number Diff line
@@ -5,7 +5,7 @@
* @preserve
**/

(function (Drupal, Backbone, Modernizr) {
(function (Drupal, Backbone) {
  Drupal.contextual.VisualView = Backbone.View.extend({
    events() {
      const touchEndToClick = function (event) {
@@ -13,7 +13,22 @@
        event.target.click();
      };

      const mapping = {
      let touchStart = false;
      return {
        touchstart() {
          touchStart = true;
        },

        mouseenter() {
          if (!touchStart) {
            this.model.focus();
          }
        },

        mousemove() {
          touchStart = false;
        },

        'click .trigger': function () {
          this.model.toggleOpen();
        },
@@ -23,14 +38,6 @@
        },
        'touchend .contextual-links a': touchEndToClick
      };

      if (!Modernizr.touchevents) {
        mapping.mouseenter = function () {
          this.model.focus();
        };
      }

      return mapping;
    },

    initialize() {
@@ -50,4 +57,4 @@
    }

  });
})(Drupal, Backbone, Modernizr);
 No newline at end of file
})(Drupal, Backbone);
 No newline at end of file