Chris@0: /** Chris@0: * @file Chris@0: * A Backbone View that provides the visual view of a contextual link. Chris@0: */ Chris@0: Chris@17: (function(Drupal, Backbone, Modernizr) { Chris@17: Drupal.contextual.VisualView = Backbone.View.extend( Chris@17: /** @lends Drupal.contextual.VisualView# */ { Chris@17: /** Chris@17: * Events for the Backbone view. Chris@17: * Chris@17: * @return {object} Chris@17: * A mapping of events to be used in the view. Chris@17: */ Chris@17: events() { Chris@17: // Prevents delay and simulated mouse events. Chris@17: const touchEndToClick = function(event) { Chris@17: event.preventDefault(); Chris@17: event.target.click(); Chris@17: }; Chris@17: const mapping = { Chris@17: 'click .trigger': function() { Chris@17: this.model.toggleOpen(); Chris@17: }, Chris@17: 'touchend .trigger': touchEndToClick, Chris@17: 'click .contextual-links a': function() { Chris@17: this.model.close().blur(); Chris@17: }, Chris@17: 'touchend .contextual-links a': touchEndToClick, Chris@17: }; Chris@17: // We only want mouse hover events on non-touch. Chris@17: if (!Modernizr.touchevents) { Chris@17: mapping.mouseenter = function() { Chris@17: this.model.focus(); Chris@17: }; Chris@17: } Chris@17: return mapping; Chris@17: }, Chris@0: Chris@17: /** Chris@17: * Renders the visual view of a contextual link. Listens to mouse & touch. Chris@17: * Chris@17: * @constructs Chris@17: * Chris@17: * @augments Backbone.View Chris@17: */ Chris@17: initialize() { Chris@17: this.listenTo(this.model, 'change', this.render); Chris@17: }, Chris@17: Chris@17: /** Chris@17: * @inheritdoc Chris@17: * Chris@17: * @return {Drupal.contextual.VisualView} Chris@17: * The current contextual visual view. Chris@17: */ Chris@17: render() { Chris@17: const isOpen = this.model.get('isOpen'); Chris@17: // The trigger should be visible when: Chris@17: // - the mouse hovered over the region, Chris@17: // - the trigger is locked, Chris@17: // - and for as long as the contextual menu is open. Chris@17: const isVisible = Chris@17: this.model.get('isLocked') || Chris@17: this.model.get('regionIsHovered') || Chris@17: isOpen; Chris@17: Chris@17: this.$el Chris@17: // The open state determines if the links are visible. Chris@17: .toggleClass('open', isOpen) Chris@17: // Update the visibility of the trigger. Chris@17: .find('.trigger') Chris@17: .toggleClass('visually-hidden', !isVisible); Chris@17: Chris@17: // Nested contextual region handling: hide any nested contextual triggers. Chris@17: if ('isOpen' in this.model.changed) { Chris@17: this.$el Chris@17: .closest('.contextual-region') Chris@17: .find('.contextual .trigger:not(:first)') Chris@17: .toggle(!isOpen); Chris@17: } Chris@17: Chris@17: return this; Chris@17: }, Chris@0: }, Chris@17: ); Chris@17: })(Drupal, Backbone, Modernizr);