From 577a3ef841182475b6a665095c8f09decc8cda2c Mon Sep 17 00:00:00 2001 From: webchick <webchick@24967.no-reply.drupal.org> Date: Wed, 3 Apr 2013 12:26:39 -0700 Subject: [PATCH] Issue #1914966 by Wim Leers, jessebeach: Fixed Nested contextual links triggers don't work well. --- core/modules/contextual/contextual.js | 46 ++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/core/modules/contextual/contextual.js b/core/modules/contextual/contextual.js index aa80b31e1939..f09043df2063 100644 --- a/core/modules/contextual/contextual.js +++ b/core/modules/contextual/contextual.js @@ -14,17 +14,57 @@ var contextuals = []; */ Drupal.behaviors.contextual = { attach: function (context) { + var that = this; $('ul.contextual-links', context).once('contextual', function () { var $this = $(this); var contextual = new Drupal.contextual($this, $this.closest('.contextual-region')); contextuals.push(contextual); $this.data('drupal-contextual', contextual); + that._adjustIfNestedAndOverlapping(this); }); // Bind to edit mode changes. $('body').once('contextual', function () { $(document).on('drupalEditModeChanged.contextual', toggleEditMode); }); + }, + + /** + * Determines if a contextual link is nested & overlapping, if so: adjusts it. + * + * This only deals with two levels of nesting; deeper levels are not touched. + * + * @param DOM contextualLink + * A contextual link DOM element. + */ + _adjustIfNestedAndOverlapping: function (contextualLink) { + var $contextuals = $(contextualLink) + .parents('.contextual-region').eq(-1) + .find('.contextual'); + + // Early-return when there's no nesting. + if ($contextuals.length === 1) { + return; + } + + // If the two contextual links overlap, then we move the second one. + var firstTop = $contextuals.eq(0).offset().top; + var secondTop = $contextuals.eq(1).offset().top; + if (firstTop === secondTop) { + var $nestedContextual = $contextuals.eq(1); + + // Retrieve height of nested contextual link. + var height = 0; + var $trigger = $nestedContextual.find('.trigger'); + // Elements with the .element-invisible class have no dimensions, so this + // class must be temporarily removed to the calculate the height. + $trigger.removeClass('element-invisible'); + height = $nestedContextual.height(); + $trigger.addClass('element-invisible'); + + // Adjust nested contextual link's position. + $nestedContextual.css({ top: $nestedContextual.position().top + height }); + } } }; @@ -67,7 +107,7 @@ Drupal.contextual.prototype.init = function() { // The trigger behaviors are never detached or mutated. this.$region - .on('click.contextual', '.contextual .trigger', $.proxy(this.triggerClickHandler, this)) + .on('click.contextual', '.contextual .trigger:first', $.proxy(this.triggerClickHandler, this)) .on('mouseleave.contextual', '.contextual', {show: false}, $.proxy(this.triggerLeaveHandler, this)); // Attach highlight behaviors. this.attachHighlightBehaviors(); @@ -128,6 +168,8 @@ Drupal.contextual.prototype.highlightRegion = function(event) { */ Drupal.contextual.prototype.triggerClickHandler = function (event) { event.preventDefault(); + // Hide all nested contextual triggers while the links are shown for this one. + this.$region.find('.contextual .trigger:not(:first)').hide(); this.showLinks(); }; @@ -139,6 +181,8 @@ Drupal.contextual.prototype.triggerClickHandler = function (event) { */ Drupal.contextual.prototype.triggerLeaveHandler = function (event) { var show = event && event.data && event.data.show; + // Show all nested contextual triggers when the links are hidden for this one. + this.$region.find('.contextual .trigger:not(:first)').show(); this.showLinks(show); }; -- GitLab