110 lines
3.4 KiB
JavaScript
110 lines
3.4 KiB
JavaScript
/**
|
|
* @file
|
|
* A Backbone View that provides the visual view of a contextual link.
|
|
*/
|
|
|
|
(function (Drupal, Backbone) {
|
|
/**
|
|
* @deprecated in drupal:9.4.0 and is removed from drupal:11.0.0. There is no
|
|
* replacement.
|
|
*/
|
|
Drupal.contextual.VisualView = Backbone.View.extend(
|
|
/** @lends Drupal.contextual.VisualView# */ {
|
|
/**
|
|
* Events for the Backbone view.
|
|
*
|
|
* @return {object}
|
|
* A mapping of events to be used in the view.
|
|
*/
|
|
events() {
|
|
// Prevents delay and simulated mouse events.
|
|
const touchEndToClick = function (event) {
|
|
event.preventDefault();
|
|
event.target.click();
|
|
};
|
|
|
|
// 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();
|
|
},
|
|
'touchend .trigger': touchEndToClick,
|
|
'click .contextual-links a': function () {
|
|
this.model.close().blur();
|
|
},
|
|
'touchend .contextual-links a': touchEndToClick,
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Renders the visual view of a contextual link. Listens to mouse & touch.
|
|
*
|
|
* @constructs
|
|
*
|
|
* @augments Backbone.View
|
|
*/
|
|
initialize() {
|
|
this.listenTo(this.model, 'change', this.render);
|
|
},
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*
|
|
* @return {Drupal.contextual.VisualView}
|
|
* The current contextual visual view.
|
|
*/
|
|
render() {
|
|
const isOpen = this.model.get('isOpen');
|
|
// The trigger should be visible when:
|
|
// - the mouse hovered over the region,
|
|
// - the trigger is locked,
|
|
// - and for as long as the contextual menu is open.
|
|
const isVisible =
|
|
this.model.get('isLocked') ||
|
|
this.model.get('regionIsHovered') ||
|
|
isOpen;
|
|
|
|
this.$el
|
|
// The open state determines if the links are visible.
|
|
.toggleClass('open', isOpen)
|
|
// Update the visibility of the trigger.
|
|
.find('.trigger')
|
|
.toggleClass('visually-hidden', !isVisible);
|
|
|
|
// Nested contextual region handling: hide any nested contextual triggers.
|
|
if ('isOpen' in this.model.changed) {
|
|
this.$el
|
|
.closest('.contextual-region')
|
|
.find('.contextual .trigger:not(:first)')
|
|
.toggle(!isOpen);
|
|
}
|
|
|
|
return this;
|
|
},
|
|
},
|
|
);
|
|
})(Drupal, Backbone);
|