/**
- * @file
- * A Backbone view for the toolbar element. Listens to mouse & touch.
- */
+* DO NOT EDIT THIS FILE.
+* See the following change record for more information,
+* https://www.drupal.org/node/2815083
+* @preserve
+**/
(function ($, Drupal, drupalSettings, Backbone) {
-
- 'use strict';
-
- Drupal.toolbar.ToolbarVisualView = Backbone.View.extend(/** @lends Drupal.toolbar.ToolbarVisualView# */{
-
- /**
- * Event map for the `ToolbarVisualView`.
- *
- * @return {object}
- * A map of events.
- */
- events: function () {
- // Prevents delay and simulated mouse events.
- var touchEndToClick = function (event) {
+ Drupal.toolbar.ToolbarVisualView = Backbone.View.extend({
+ events: function events() {
+ var touchEndToClick = function touchEndToClick(event) {
event.preventDefault();
event.target.click();
};
'touchend .toolbar-toggle-orientation button': touchEndToClick
};
},
-
- /**
- * Backbone view for the toolbar element. Listens to mouse & touch.
- *
- * @constructs
- *
- * @augments Backbone.View
- *
- * @param {object} options
- * Options for the view object.
- * @param {object} options.strings
- * Various strings to use in the view.
- */
- initialize: function (options) {
+ initialize: function initialize(options) {
this.strings = options.strings;
this.listenTo(this.model, 'change:activeTab change:orientation change:isOriented change:isTrayToggleVisible', this.render);
this.listenTo(this.model, 'change:mqMatches', this.onMediaQueryChange);
this.listenTo(this.model, 'change:offsets', this.adjustPlacement);
+ this.listenTo(this.model, 'change:activeTab change:orientation change:isOriented', this.updateToolbarHeight);
- // Add the tray orientation toggles.
- this.$el
- .find('.toolbar-tray .toolbar-lining')
- .append(Drupal.theme('toolbarOrientationToggle'));
+ this.$el.find('.toolbar-tray .toolbar-lining').append(Drupal.theme('toolbarOrientationToggle'));
- // Trigger an activeTab change so that listening scripts can respond on
- // page load. This will call render.
this.model.trigger('change:activeTab');
},
+ updateToolbarHeight: function updateToolbarHeight() {
+ var toolbarTabOuterHeight = $('#toolbar-bar').find('.toolbar-tab').outerHeight() || 0;
+ var toolbarTrayHorizontalOuterHeight = $('.is-active.toolbar-tray-horizontal').outerHeight() || 0;
+ this.model.set('height', toolbarTabOuterHeight + toolbarTrayHorizontalOuterHeight);
- /**
- * @inheritdoc
- *
- * @return {Drupal.toolbar.ToolbarVisualView}
- * The `ToolbarVisualView` instance.
- */
- render: function () {
+ $('body').css({
+ 'padding-top': this.model.get('height')
+ });
+
+ this.triggerDisplace();
+ },
+ triggerDisplace: function triggerDisplace() {
+ _.defer(function () {
+ Drupal.displace(true);
+ });
+ },
+ render: function render() {
this.updateTabs();
this.updateTrayOrientation();
this.updateBarAttributes();
- // Load the subtrees if the orientation of the toolbar is changed to
- // vertical. This condition responds to the case that the toolbar switches
- // from horizontal to vertical orientation. The toolbar starts in a
- // vertical orientation by default and then switches to horizontal during
- // initialization if the media query conditions are met. Simply checking
- // that the orientation is vertical here would result in the subtrees
- // always being loaded, even when the toolbar initialization ultimately
- // results in a horizontal orientation.
- //
- // @see Drupal.behaviors.toolbar.attach() where admin menu subtrees
- // loading is invoked during initialization after media query conditions
- // have been processed.
+
+ $('body').removeClass('toolbar-loading');
+
if (this.model.changed.orientation === 'vertical' || this.model.changed.activeTab) {
this.loadSubtrees();
}
- // Trigger a recalculation of viewport displacing elements. Use setTimeout
- // to ensure this recalculation happens after changes to visual elements
- // have processed.
- window.setTimeout(function () {
- Drupal.displace(true);
- }, 0);
+
return this;
},
-
- /**
- * Responds to a toolbar tab click.
- *
- * @param {jQuery.Event} event
- * The event triggered.
- */
- onTabClick: function (event) {
- // If this tab has a tray associated with it, it is considered an
- // activatable tab.
+ onTabClick: function onTabClick(event) {
if (event.target.hasAttribute('data-toolbar-tray')) {
var activeTab = this.model.get('activeTab');
var clickedTab = event.target;
- // Set the event target as the active item if it is not already.
- this.model.set('activeTab', (!activeTab || clickedTab !== activeTab) ? clickedTab : null);
+ this.model.set('activeTab', !activeTab || clickedTab !== activeTab ? clickedTab : null);
event.preventDefault();
event.stopPropagation();
}
},
-
- /**
- * Toggles the orientation of a toolbar tray.
- *
- * @param {jQuery.Event} event
- * The event triggered.
- */
- onOrientationToggleClick: function (event) {
+ onOrientationToggleClick: function onOrientationToggleClick(event) {
var orientation = this.model.get('orientation');
- // Determine the toggle-to orientation.
- var antiOrientation = (orientation === 'vertical') ? 'horizontal' : 'vertical';
+
+ var antiOrientation = orientation === 'vertical' ? 'horizontal' : 'vertical';
var locked = antiOrientation === 'vertical';
- // Remember the locked state.
+
if (locked) {
localStorage.setItem('Drupal.toolbar.trayVerticalLocked', 'true');
- }
- else {
+ } else {
localStorage.removeItem('Drupal.toolbar.trayVerticalLocked');
}
- // Update the model.
+
this.model.set({
locked: locked,
orientation: antiOrientation
event.preventDefault();
event.stopPropagation();
},
-
- /**
- * Updates the display of the tabs: toggles a tab and the associated tray.
- */
- updateTabs: function () {
+ updateTabs: function updateTabs() {
var $tab = $(this.model.get('activeTab'));
- // Deactivate the previous tab.
- $(this.model.previous('activeTab'))
- .removeClass('is-active')
- .prop('aria-pressed', false);
- // Deactivate the previous tray.
- $(this.model.previous('activeTray'))
- .removeClass('is-active');
-
- // Activate the selected tab.
+
+ $(this.model.previous('activeTab')).removeClass('is-active').prop('aria-pressed', false);
+
+ $(this.model.previous('activeTray')).removeClass('is-active');
+
if ($tab.length > 0) {
- $tab
- .addClass('is-active')
- // Mark the tab as pressed.
- .prop('aria-pressed', true);
+ $tab.addClass('is-active').prop('aria-pressed', true);
var name = $tab.attr('data-toolbar-tray');
- // Store the active tab name or remove the setting.
+
var id = $tab.get(0).id;
if (id) {
localStorage.setItem('Drupal.toolbar.activeTabID', JSON.stringify(id));
}
- // Activate the associated tray.
+
var $tray = this.$el.find('[data-toolbar-tray="' + name + '"].toolbar-tray');
if ($tray.length) {
$tray.addClass('is-active');
this.model.set('activeTray', $tray.get(0));
- }
- else {
- // There is no active tray.
+ } else {
this.model.set('activeTray', null);
}
- }
- else {
- // There is no active tray.
+ } else {
this.model.set('activeTray', null);
localStorage.removeItem('Drupal.toolbar.activeTabID');
}
},
-
- /**
- * Update the attributes of the toolbar bar element.
- */
- updateBarAttributes: function () {
+ updateBarAttributes: function updateBarAttributes() {
var isOriented = this.model.get('isOriented');
if (isOriented) {
this.$el.find('.toolbar-bar').attr('data-offset-top', '');
- }
- else {
+ } else {
this.$el.find('.toolbar-bar').removeAttr('data-offset-top');
}
- // Toggle between a basic vertical view and a more sophisticated
- // horizontal and vertical display of the toolbar bar and trays.
+
this.$el.toggleClass('toolbar-oriented', isOriented);
},
-
- /**
- * Updates the orientation of the active tray if necessary.
- */
- updateTrayOrientation: function () {
+ updateTrayOrientation: function updateTrayOrientation() {
var orientation = this.model.get('orientation');
- // The antiOrientation is used to render the view of action buttons like
- // the tray orientation toggle.
- var antiOrientation = (orientation === 'vertical') ? 'horizontal' : 'vertical';
- // Update the orientation of the trays.
- var $trays = this.$el.find('.toolbar-tray')
- .removeClass('toolbar-tray-horizontal toolbar-tray-vertical')
- .addClass('toolbar-tray-' + orientation);
-
- // Update the tray orientation toggle button.
+
+ var antiOrientation = orientation === 'vertical' ? 'horizontal' : 'vertical';
+
+ $('body').toggleClass('toolbar-vertical', orientation === 'vertical').toggleClass('toolbar-horizontal', orientation === 'horizontal');
+
+ var removeClass = antiOrientation === 'horizontal' ? 'toolbar-tray-horizontal' : 'toolbar-tray-vertical';
+ var $trays = this.$el.find('.toolbar-tray').removeClass(removeClass).addClass('toolbar-tray-' + orientation);
+
var iconClass = 'toolbar-icon-toggle-' + orientation;
var iconAntiClass = 'toolbar-icon-toggle-' + antiOrientation;
- var $orientationToggle = this.$el.find('.toolbar-toggle-orientation')
- .toggle(this.model.get('isTrayToggleVisible'));
- $orientationToggle.find('button')
- .val(antiOrientation)
- .attr('title', this.strings[antiOrientation])
- .text(this.strings[antiOrientation])
- .removeClass(iconClass)
- .addClass(iconAntiClass);
-
- // Update data offset attributes for the trays.
+ var $orientationToggle = this.$el.find('.toolbar-toggle-orientation').toggle(this.model.get('isTrayToggleVisible'));
+ $orientationToggle.find('button').val(antiOrientation).attr('title', this.strings[antiOrientation]).text(this.strings[antiOrientation]).removeClass(iconClass).addClass(iconAntiClass);
+
var dir = document.documentElement.dir;
- var edge = (dir === 'rtl') ? 'right' : 'left';
- // Remove data-offset attributes from the trays so they can be refreshed.
+ var edge = dir === 'rtl' ? 'right' : 'left';
+
$trays.removeAttr('data-offset-left data-offset-right data-offset-top');
- // If an active vertical tray exists, mark it as an offset element.
+
$trays.filter('.toolbar-tray-vertical.is-active').attr('data-offset-' + edge, '');
- // If an active horizontal tray exists, mark it as an offset element.
+
$trays.filter('.toolbar-tray-horizontal.is-active').attr('data-offset-top', '');
},
-
- /**
- * Sets the tops of the trays so that they align with the bottom of the bar.
- */
- adjustPlacement: function () {
+ adjustPlacement: function adjustPlacement() {
var $trays = this.$el.find('.toolbar-tray');
if (!this.model.get('isOriented')) {
- $trays.css('margin-top', 0);
$trays.removeClass('toolbar-tray-horizontal').addClass('toolbar-tray-vertical');
}
- else {
- // The toolbar container is invisible. Its placement is used to
- // determine the container for the trays.
- $trays.css('margin-top', this.$el.find('.toolbar-bar').outerHeight());
- }
},
-
- /**
- * Calls the endpoint URI that builds an AJAX command with the rendered
- * subtrees.
- *
- * The rendered admin menu subtrees HTML is cached on the client in
- * localStorage until the cache of the admin menu subtrees on the server-
- * side is invalidated. The subtreesHash is stored in localStorage as well
- * and compared to the subtreesHash in drupalSettings to determine when the
- * admin menu subtrees cache has been invalidated.
- */
- loadSubtrees: function () {
+ loadSubtrees: function loadSubtrees() {
var $activeTab = $(this.model.get('activeTab'));
var orientation = this.model.get('orientation');
- // Only load and render the admin menu subtrees if:
- // (1) They have not been loaded yet.
- // (2) The active tab is the administration menu tab, indicated by the
- // presence of the data-drupal-subtrees attribute.
- // (3) The orientation of the tray is vertical.
+
if (!this.model.get('areSubtreesLoaded') && typeof $activeTab.data('drupal-subtrees') !== 'undefined' && orientation === 'vertical') {
var subtreesHash = drupalSettings.toolbar.subtreesHash;
var theme = drupalSettings.ajaxPageState.theme;
var cachedSubtreesHash = localStorage.getItem('Drupal.toolbar.subtreesHash.' + theme);
var cachedSubtrees = JSON.parse(localStorage.getItem('Drupal.toolbar.subtrees.' + theme));
var isVertical = this.model.get('orientation') === 'vertical';
- // If we have the subtrees in localStorage and the subtree hash has not
- // changed, then use the cached data.
+
if (isVertical && subtreesHash === cachedSubtreesHash && cachedSubtrees) {
Drupal.toolbar.setSubtrees.resolve(cachedSubtrees);
- }
- // Only make the call to get the subtrees if the orientation of the
- // toolbar is vertical.
- else if (isVertical) {
- // Remove the cached menu information.
- localStorage.removeItem('Drupal.toolbar.subtreesHash.' + theme);
- localStorage.removeItem('Drupal.toolbar.subtrees.' + theme);
- // The AJAX response's command will trigger the resolve method of the
- // Drupal.toolbar.setSubtrees Promise.
- Drupal.ajax({url: endpoint}).execute();
- // Cache the hash for the subtrees locally.
- localStorage.setItem('Drupal.toolbar.subtreesHash.' + theme, subtreesHash);
- }
+ } else if (isVertical) {
+ localStorage.removeItem('Drupal.toolbar.subtreesHash.' + theme);
+ localStorage.removeItem('Drupal.toolbar.subtrees.' + theme);
+
+ Drupal.ajax({ url: endpoint }).execute();
+
+ localStorage.setItem('Drupal.toolbar.subtreesHash.' + theme, subtreesHash);
+ }
}
}
});
-
-}(jQuery, Drupal, drupalSettings, Backbone));
+})(jQuery, Drupal, drupalSettings, Backbone);
\ No newline at end of file