/**
- * @file
- * Attaches behaviors for the Contextual module.
- */
+* DO NOT EDIT THIS FILE.
+* See the following change record for more information,
+* https://www.drupal.org/node/2815083
+* @preserve
+**/
(function ($, Drupal, drupalSettings, _, Backbone, JSON, storage) {
-
- 'use strict';
-
- var options = $.extend(drupalSettings.contextual,
- // Merge strings on top of drupalSettings so that they are not mutable.
- {
- strings: {
- open: Drupal.t('Open'),
- close: Drupal.t('Close')
- }
+ var options = $.extend(drupalSettings.contextual, {
+ strings: {
+ open: Drupal.t('Open'),
+ close: Drupal.t('Close')
}
- );
+ });
- // Clear the cached contextual links whenever the current user's set of
- // permissions changes.
var cachedPermissionsHash = storage.getItem('Drupal.contextual.permissionsHash');
var permissionsHash = drupalSettings.user.permissionsHash;
if (cachedPermissionsHash !== permissionsHash) {
storage.setItem('Drupal.contextual.permissionsHash', permissionsHash);
}
- /**
- * Initializes a contextual link: updates its DOM, sets up model and views.
- *
- * @param {jQuery} $contextual
- * A contextual links placeholder DOM element, containing the actual
- * contextual links as rendered by the server.
- * @param {string} html
- * The server-side rendered HTML for this contextual link.
- */
function initContextual($contextual, html) {
var $region = $contextual.closest('.contextual-region');
var contextual = Drupal.contextual;
- $contextual
- // Update the placeholder to contain its rendered contextual links.
- .html(html)
- // Use the placeholder as a wrapper with a specific class to provide
- // positioning and behavior attachment context.
- .addClass('contextual')
- // Ensure a trigger element exists before the actual contextual links.
- .prepend(Drupal.theme('contextualTrigger'));
+ $contextual.html(html).addClass('contextual').prepend(Drupal.theme('contextualTrigger'));
- // Set the destination parameter on each of the contextual links.
var destination = 'destination=' + Drupal.encodePath(drupalSettings.path.currentPath);
$contextual.find('.contextual-links a').each(function () {
var url = this.getAttribute('href');
- var glue = (url.indexOf('?') === -1) ? '?' : '&';
+ var glue = url.indexOf('?') === -1 ? '?' : '&';
this.setAttribute('href', url + glue + destination);
});
- // Create a model and the appropriate views.
var model = new contextual.StateModel({
title: $region.find('h2').eq(0).text().trim()
});
- var viewOptions = $.extend({el: $contextual, model: model}, options);
+ var viewOptions = $.extend({ el: $contextual, model: model }, options);
contextual.views.push({
visual: new contextual.VisualView(viewOptions),
aural: new contextual.AuralView(viewOptions),
keyboard: new contextual.KeyboardView(viewOptions)
});
- contextual.regionViews.push(new contextual.RegionView(
- $.extend({el: $region, model: model}, options))
- );
+ contextual.regionViews.push(new contextual.RegionView($.extend({ el: $region, model: model }, options)));
- // Add the model to the collection. This must happen after the views have
- // been associated with it, otherwise collection change event handlers can't
- // trigger the model change event handler in its views.
contextual.collection.add(model);
- // Let other JavaScript react to the adding of a new contextual link.
$(document).trigger('drupalContextualLinkAdded', {
$el: $contextual,
$region: $region,
model: model
});
- // Fix visual collisions between contextual link triggers.
adjustIfNestedAndOverlapping($contextual);
}
- /**
- * 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 {jQuery} $contextual
- * A contextual links placeholder DOM element, containing the actual
- * contextual links as rendered by the server.
- */
function adjustIfNestedAndOverlapping($contextual) {
- var $contextuals = $contextual
- // @todo confirm that .closest() is not sufficient
- .parents('.contextual-region').eq(-1)
- .find('.contextual');
+ var $contextuals = $contextual.parents('.contextual-region').eq(-1).find('.contextual');
- // Early-return when there's no nesting.
- if ($contextuals.length === 1) {
+ 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 .visually-hidden class have no dimensions, so this
- // class must be temporarily removed to the calculate the height.
+
$trigger.removeClass('visually-hidden');
height = $nestedContextual.height();
$trigger.addClass('visually-hidden');
- // Adjust nested contextual link's position.
- $nestedContextual.css({top: $nestedContextual.position().top + height});
+ $nestedContextual.css({ top: $nestedContextual.position().top + height });
}
}
- /**
- * Attaches outline behavior for regions associated with contextual links.
- *
- * Events
- * Contextual triggers an event that can be used by other scripts.
- * - drupalContextualLinkAdded: Triggered when a contextual link is added.
- *
- * @type {Drupal~behavior}
- *
- * @prop {Drupal~behaviorAttach} attach
- * Attaches the outline behavior to the right context.
- */
Drupal.behaviors.contextual = {
- attach: function (context) {
+ attach: function attach(context) {
var $context = $(context);
- // Find all contextual links placeholders, if any.
var $placeholders = $context.find('[data-contextual-id]').once('contextual-render');
if ($placeholders.length === 0) {
return;
}
- // Collect the IDs for all contextual links placeholders.
var ids = [];
$placeholders.each(function () {
ids.push($(this).attr('data-contextual-id'));
});
- // Update all contextual links placeholders whose HTML is cached.
- var uncachedIDs = _.filter(ids, function initIfCached(contextualID) {
+ var uncachedIDs = _.filter(ids, function (contextualID) {
var html = storage.getItem('Drupal.contextual.' + contextualID);
if (html && html.length) {
- // Initialize after the current execution cycle, to make the AJAX
- // request for retrieving the uncached contextual links as soon as
- // possible, but also to ensure that other Drupal behaviors have had
- // the chance to set up an event listener on the Backbone collection
- // Drupal.contextual.collection.
window.setTimeout(function () {
initContextual($context.find('[data-contextual-id="' + contextualID + '"]'), html);
});
return true;
});
- // Perform an AJAX request to let the server render the contextual links
- // for each of the placeholders.
if (uncachedIDs.length > 0) {
$.ajax({
url: Drupal.url('contextual/render'),
type: 'POST',
- data: {'ids[]': uncachedIDs},
+ data: { 'ids[]': uncachedIDs },
dataType: 'json',
- success: function (results) {
+ success: function success(results) {
_.each(results, function (html, contextualID) {
- // Store the metadata.
storage.setItem('Drupal.contextual.' + contextualID, html);
- // If the rendered contextual links are empty, then the current
- // user does not have permission to access the associated links:
- // don't render anything.
+
if (html.length > 0) {
- // Update the placeholders to contain its rendered contextual
- // links. Usually there will only be one placeholder, but it's
- // possible for multiple identical placeholders exist on the
- // page (probably because the same content appears more than
- // once).
$placeholders = $context.find('[data-contextual-id="' + contextualID + '"]');
- // Initialize the contextual links.
for (var i = 0; i < $placeholders.length; i++) {
initContextual($placeholders.eq(i), html);
}
}
};
- /**
- * Namespace for contextual related functionality.
- *
- * @namespace
- */
Drupal.contextual = {
-
- /**
- * The {@link Drupal.contextual.View} instances associated with each list
- * element of contextual links.
- *
- * @type {Array}
- */
views: [],
- /**
- * The {@link Drupal.contextual.RegionView} instances associated with each
- * contextual region element.
- *
- * @type {Array}
- */
regionViews: []
};
- /**
- * A Backbone.Collection of {@link Drupal.contextual.StateModel} instances.
- *
- * @type {Backbone.Collection}
- */
- Drupal.contextual.collection = new Backbone.Collection([], {model: Drupal.contextual.StateModel});
+ Drupal.contextual.collection = new Backbone.Collection([], { model: Drupal.contextual.StateModel });
- /**
- * A trigger is an interactive element often bound to a click handler.
- *
- * @return {string}
- * A string representing a DOM fragment.
- */
Drupal.theme.contextualTrigger = function () {
return '<button class="trigger visually-hidden focusable" type="button"></button>';
};
-
-})(jQuery, Drupal, drupalSettings, _, Backbone, window.JSON, window.sessionStorage);
+})(jQuery, Drupal, drupalSettings, _, Backbone, window.JSON, window.sessionStorage);
\ No newline at end of file