Unverified Commit e894995a authored by lauriii's avatar lauriii
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 33527a5f
......@@ -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
- core/jquery.once.bc
......
......@@ -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() {
this.model.set('regionIsHovered', true);
if (!touchStart) {
this.model.set('regionIsHovered', true);
}
},
mouseleave() {
this.model.close().blur().set('regionIsHovered', false);
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);
......@@ -5,23 +5,28 @@
* @preserve
**/
(function (Drupal, Backbone, Modernizr) {
(function (Drupal, Backbone) {
Drupal.contextual.RegionView = Backbone.View.extend({
events: function events() {
var mapping = {
var touchStart = false;
return {
touchstart: function touchstart() {
touchStart = true;
},
mouseenter: function mouseenter() {
this.model.set('regionIsHovered', true);
if (!touchStart) {
this.model.set('regionIsHovered', true);
}
},
mouseleave: function mouseleave() {
this.model.close().blur().set('regionIsHovered', false);
if (!touchStart) {
this.model.close().blur().set('regionIsHovered', false);
}
},
mousemove: function mousemove() {
touchStart = false;
}
};
if (Modernizr.touchevents) {
mapping = {};
}
return mapping;
},
initialize: function initialize() {
this.listenTo(this.model, 'change:hasFocus', this.render);
......@@ -31,4 +36,4 @@
return this;
}
});
})(Drupal, Backbone, Modernizr);
\ No newline at end of file
})(Drupal, Backbone);
\ No newline at end of file
......@@ -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);
......@@ -5,7 +5,7 @@
* @preserve
**/
(function (Drupal, Backbone, Modernizr) {
(function (Drupal, Backbone) {
Drupal.contextual.VisualView = Backbone.View.extend({
events: function events() {
var touchEndToClick = function touchEndToClick(event) {
......@@ -13,7 +13,19 @@
event.target.click();
};
var mapping = {
var touchStart = false;
return {
touchstart: function touchstart() {
touchStart = true;
},
mouseenter: function mouseenter() {
if (!touchStart) {
this.model.focus();
}
},
mousemove: function mousemove() {
touchStart = false;
},
'click .trigger': function clickTrigger() {
this.model.toggleOpen();
},
......@@ -23,14 +35,6 @@
},
'touchend .contextual-links a': touchEndToClick
};
if (!Modernizr.touchevents) {
mapping.mouseenter = function () {
this.model.focus();
};
}
return mapping;
},
initialize: function initialize() {
this.listenTo(this.model, 'change', this.render);
......@@ -47,4 +51,4 @@
return this;
}
});
})(Drupal, Backbone, Modernizr);
\ No newline at end of file
})(Drupal, Backbone);
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment