Initial Drupal 11 with DDEV setup
This commit is contained in:
		
							
								
								
									
										401
									
								
								web/core/modules/toolbar/js/toolbar.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										401
									
								
								web/core/modules/toolbar/js/toolbar.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,401 @@
 | 
			
		||||
/**
 | 
			
		||||
 * @file
 | 
			
		||||
 * Defines the behavior of the Drupal administration toolbar.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
(function ($, Drupal, drupalSettings) {
 | 
			
		||||
  // Set UI-impacting toolbar classes before Drupal behaviors initialize to
 | 
			
		||||
  // minimize flickering on load. This is encapsulated in a function to
 | 
			
		||||
  // emphasize this having a distinct purpose than the code that follows it.
 | 
			
		||||
  (() => {
 | 
			
		||||
    if (!sessionStorage.getItem('Drupal.toolbar.toolbarState')) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    const toolbarState = JSON.parse(
 | 
			
		||||
      sessionStorage.getItem('Drupal.toolbar.toolbarState'),
 | 
			
		||||
    );
 | 
			
		||||
    const { activeTray, orientation, isOriented } = toolbarState;
 | 
			
		||||
    const activeTrayElement = document.querySelector(
 | 
			
		||||
      `.toolbar-tray[data-toolbar-tray="${activeTray}"]`,
 | 
			
		||||
    );
 | 
			
		||||
    const activeTrayToggle = document.querySelector(
 | 
			
		||||
      `.toolbar-item[data-toolbar-tray="${activeTray}"]`,
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    if (activeTrayElement) {
 | 
			
		||||
      activeTrayElement.classList.add(
 | 
			
		||||
        `toolbar-tray-${orientation}`,
 | 
			
		||||
        'is-active',
 | 
			
		||||
      );
 | 
			
		||||
      activeTrayToggle.classList.add('is-active');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (isOriented) {
 | 
			
		||||
      document
 | 
			
		||||
        .querySelector('#toolbar-administration')
 | 
			
		||||
        .classList.add('toolbar-oriented');
 | 
			
		||||
    }
 | 
			
		||||
  })();
 | 
			
		||||
 | 
			
		||||
  // Merge run-time settings with the defaults.
 | 
			
		||||
  const options = $.extend(
 | 
			
		||||
    {
 | 
			
		||||
      breakpoints: {
 | 
			
		||||
        'toolbar.narrow': '',
 | 
			
		||||
        'toolbar.standard': '',
 | 
			
		||||
        'toolbar.wide': '',
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
    drupalSettings.toolbar,
 | 
			
		||||
    // Merge strings on top of drupalSettings so that they are not mutable.
 | 
			
		||||
    {
 | 
			
		||||
      strings: {
 | 
			
		||||
        horizontal: Drupal.t('Horizontal orientation'),
 | 
			
		||||
        vertical: Drupal.t('Vertical orientation'),
 | 
			
		||||
      },
 | 
			
		||||
    },
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Registers tabs with the toolbar.
 | 
			
		||||
   *
 | 
			
		||||
   * The Drupal toolbar allows modules to register top-level tabs. These may
 | 
			
		||||
   * point directly to a resource or toggle the visibility of a tray.
 | 
			
		||||
   *
 | 
			
		||||
   * Modules register tabs with hook_toolbar().
 | 
			
		||||
   *
 | 
			
		||||
   * @type {Drupal~behavior}
 | 
			
		||||
   *
 | 
			
		||||
   * @prop {Drupal~behaviorAttach} attach
 | 
			
		||||
   *   Attaches the toolbar rendering functionality to the toolbar element.
 | 
			
		||||
   */
 | 
			
		||||
  Drupal.behaviors.toolbar = {
 | 
			
		||||
    attach(context) {
 | 
			
		||||
      // Verify that the user agent understands media queries. Complex admin
 | 
			
		||||
      // toolbar layouts require media query support.
 | 
			
		||||
      if (!window.matchMedia('only screen').matches) {
 | 
			
		||||
        return;
 | 
			
		||||
      }
 | 
			
		||||
      // Process the administrative toolbar.
 | 
			
		||||
      once('toolbar', '#toolbar-administration', context).forEach((toolbar) => {
 | 
			
		||||
        // Establish the toolbar models and views.
 | 
			
		||||
        const model = new Drupal.toolbar.ToolbarModel({
 | 
			
		||||
          locked: JSON.parse(
 | 
			
		||||
            localStorage.getItem('Drupal.toolbar.trayVerticalLocked'),
 | 
			
		||||
          ),
 | 
			
		||||
          activeTab: document.getElementById(
 | 
			
		||||
            JSON.parse(localStorage.getItem('Drupal.toolbar.activeTabID')),
 | 
			
		||||
          ),
 | 
			
		||||
          height: $('#toolbar-administration').outerHeight(),
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Drupal.toolbar.models.toolbarModel = model;
 | 
			
		||||
 | 
			
		||||
        // Attach a listener to the configured media query breakpoints.
 | 
			
		||||
        // Executes it before Drupal.toolbar.views to avoid extra rendering.
 | 
			
		||||
        Object.keys(options.breakpoints).forEach((label) => {
 | 
			
		||||
          const mq = options.breakpoints[label];
 | 
			
		||||
          const mql = window.matchMedia(mq);
 | 
			
		||||
          Drupal.toolbar.mql[label] = mql;
 | 
			
		||||
          // Curry the model and the label of the media query breakpoint to
 | 
			
		||||
          // the mediaQueryChangeHandler function.
 | 
			
		||||
          mql.addListener(
 | 
			
		||||
            Drupal.toolbar.mediaQueryChangeHandler.bind(null, model, label),
 | 
			
		||||
          );
 | 
			
		||||
          // Fire the mediaQueryChangeHandler for each configured breakpoint
 | 
			
		||||
          // so that they process once.
 | 
			
		||||
          Drupal.toolbar.mediaQueryChangeHandler.call(null, model, label, mql);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        Drupal.toolbar.views.toolbarVisualView =
 | 
			
		||||
          new Drupal.toolbar.ToolbarVisualView({
 | 
			
		||||
            el: toolbar,
 | 
			
		||||
            model,
 | 
			
		||||
            strings: options.strings,
 | 
			
		||||
          });
 | 
			
		||||
        Drupal.toolbar.views.toolbarAuralView =
 | 
			
		||||
          new Drupal.toolbar.ToolbarAuralView({
 | 
			
		||||
            el: toolbar,
 | 
			
		||||
            model,
 | 
			
		||||
            strings: options.strings,
 | 
			
		||||
          });
 | 
			
		||||
        Drupal.toolbar.views.bodyVisualView = new Drupal.toolbar.BodyVisualView(
 | 
			
		||||
          {
 | 
			
		||||
            el: toolbar,
 | 
			
		||||
            model,
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // Force layout render to fix mobile view. Only needed on load, not
 | 
			
		||||
        // for every media query match.
 | 
			
		||||
        model.trigger('change:isFixed', model, model.get('isFixed'));
 | 
			
		||||
        model.trigger('change:activeTray', model, model.get('activeTray'));
 | 
			
		||||
 | 
			
		||||
        // Render collapsible menus.
 | 
			
		||||
        const menuModel = new Drupal.toolbar.MenuModel();
 | 
			
		||||
        Drupal.toolbar.models.menuModel = menuModel;
 | 
			
		||||
        Drupal.toolbar.views.menuVisualView = new Drupal.toolbar.MenuVisualView(
 | 
			
		||||
          {
 | 
			
		||||
            el: $(toolbar).find('.toolbar-menu-administration').get(0),
 | 
			
		||||
            model: menuModel,
 | 
			
		||||
            strings: options.strings,
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
 | 
			
		||||
        // Handle the resolution of Drupal.toolbar.setSubtrees.
 | 
			
		||||
        // This is handled with a deferred so that the function may be invoked
 | 
			
		||||
        // asynchronously.
 | 
			
		||||
        Drupal.toolbar.setSubtrees.done((subtrees) => {
 | 
			
		||||
          menuModel.set('subtrees', subtrees);
 | 
			
		||||
          const theme = drupalSettings.ajaxPageState.theme;
 | 
			
		||||
          localStorage.setItem(
 | 
			
		||||
            `Drupal.toolbar.subtrees.${theme}`,
 | 
			
		||||
            JSON.stringify(subtrees),
 | 
			
		||||
          );
 | 
			
		||||
          // Indicate on the toolbarModel that subtrees are now loaded.
 | 
			
		||||
          model.set('areSubtreesLoaded', true);
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        // Trigger an initial attempt to load menu subitems. This first attempt
 | 
			
		||||
        // is made after the media query handlers have had an opportunity to
 | 
			
		||||
        // process. The toolbar starts in the vertical orientation by default,
 | 
			
		||||
        // unless the viewport is wide enough to accommodate a horizontal
 | 
			
		||||
        // orientation. Thus we give the Toolbar a chance to determine if it
 | 
			
		||||
        // should be set to horizontal orientation before attempting to load
 | 
			
		||||
        // menu subtrees.
 | 
			
		||||
        Drupal.toolbar.views.toolbarVisualView.loadSubtrees();
 | 
			
		||||
 | 
			
		||||
        $(document)
 | 
			
		||||
          // Update the model when the viewport offset changes.
 | 
			
		||||
          .on('drupalViewportOffsetChange.toolbar', (event, offsets) => {
 | 
			
		||||
            model.set('offsets', offsets);
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
        // Broadcast model changes to other modules.
 | 
			
		||||
        model
 | 
			
		||||
          .on('change:orientation', (model, orientation) => {
 | 
			
		||||
            $(document).trigger('drupalToolbarOrientationChange', orientation);
 | 
			
		||||
          })
 | 
			
		||||
          .on('change:activeTab', (model, tab) => {
 | 
			
		||||
            $(document).trigger('drupalToolbarTabChange', tab);
 | 
			
		||||
          })
 | 
			
		||||
          .on('change:activeTray', (model, tray) => {
 | 
			
		||||
            $(document).trigger('drupalToolbarTrayChange', tray);
 | 
			
		||||
          });
 | 
			
		||||
 | 
			
		||||
        const toolbarState = sessionStorage.getItem(
 | 
			
		||||
          'Drupal.toolbar.toolbarState',
 | 
			
		||||
        )
 | 
			
		||||
          ? JSON.parse(sessionStorage.getItem('Drupal.toolbar.toolbarState'))
 | 
			
		||||
          : {};
 | 
			
		||||
        // If the toolbar's orientation is horizontal, no active tab is defined,
 | 
			
		||||
        // and the orientation state is not set (which means the user has not
 | 
			
		||||
        // yet interacted with the toolbar), then show the tray of the first
 | 
			
		||||
        // toolbar tab by default (but not the first 'Home' toolbar tab).
 | 
			
		||||
        if (
 | 
			
		||||
          Drupal.toolbar.models.toolbarModel.get('orientation') ===
 | 
			
		||||
            'horizontal' &&
 | 
			
		||||
          Drupal.toolbar.models.toolbarModel.get('activeTab') === null &&
 | 
			
		||||
          !toolbarState.orientation
 | 
			
		||||
        ) {
 | 
			
		||||
          Drupal.toolbar.models.toolbarModel.set({
 | 
			
		||||
            activeTab: $(
 | 
			
		||||
              '.toolbar-bar .toolbar-tab:not(.home-toolbar-tab) a',
 | 
			
		||||
            ).get(0),
 | 
			
		||||
          });
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        window.addEventListener('dialog:aftercreate', (e) => {
 | 
			
		||||
          const $element = $(e.target);
 | 
			
		||||
          const { settings } = e;
 | 
			
		||||
          const toolbarBar = document.getElementById('toolbar-bar');
 | 
			
		||||
          if (toolbarBar) {
 | 
			
		||||
            toolbarBar.style.marginTop = '0';
 | 
			
		||||
 | 
			
		||||
            // When off-canvas is positioned in top, toolbar has to be moved down.
 | 
			
		||||
            if (settings.drupalOffCanvasPosition === 'top') {
 | 
			
		||||
              const height = Drupal.offCanvas
 | 
			
		||||
                .getContainer($element)
 | 
			
		||||
                .outerHeight();
 | 
			
		||||
              toolbarBar.style.marginTop = `${height}px`;
 | 
			
		||||
 | 
			
		||||
              $element.on('dialogContentResize.off-canvas', () => {
 | 
			
		||||
                const newHeight = Drupal.offCanvas
 | 
			
		||||
                  .getContainer($element)
 | 
			
		||||
                  .outerHeight();
 | 
			
		||||
                toolbarBar.style.marginTop = `${newHeight}px`;
 | 
			
		||||
              });
 | 
			
		||||
            }
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
 | 
			
		||||
        window.addEventListener('dialog:beforeclose', () => {
 | 
			
		||||
          const toolbarBar = document.getElementById('toolbar-bar');
 | 
			
		||||
          if (toolbarBar) {
 | 
			
		||||
            toolbarBar.style.marginTop = '0';
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      // Add anti-flicker functionality.
 | 
			
		||||
      if (
 | 
			
		||||
        once('toolbarAntiFlicker', '#toolbar-administration', context).length
 | 
			
		||||
      ) {
 | 
			
		||||
        Drupal.toolbar.models.toolbarModel.on(
 | 
			
		||||
          'change:activeTab change:orientation change:isOriented change:isTrayToggleVisible change:offsets',
 | 
			
		||||
          function () {
 | 
			
		||||
            const userButton = document.querySelector('#toolbar-item-user');
 | 
			
		||||
            const hasActiveTab = !!$(this.get('activeTab')).length > 0;
 | 
			
		||||
            const previousToolbarState = sessionStorage.getItem(
 | 
			
		||||
              'Drupal.toolbar.toolbarState',
 | 
			
		||||
            )
 | 
			
		||||
              ? JSON.parse(
 | 
			
		||||
                  sessionStorage.getItem('Drupal.toolbar.toolbarState'),
 | 
			
		||||
                )
 | 
			
		||||
              : {};
 | 
			
		||||
            const toolbarState = {
 | 
			
		||||
              ...previousToolbarState,
 | 
			
		||||
              orientation:
 | 
			
		||||
                Drupal.toolbar.models.toolbarModel.get('orientation'),
 | 
			
		||||
              hasActiveTab,
 | 
			
		||||
              activeTabId: hasActiveTab ? this.get('activeTab').id : null,
 | 
			
		||||
              activeTray: $(this.get('activeTab')).attr('data-toolbar-tray'),
 | 
			
		||||
              isOriented: this.get('isOriented'),
 | 
			
		||||
              isFixed: this.get('isFixed'),
 | 
			
		||||
              userButtonMinWidth: userButton ? userButton.clientWidth : 0,
 | 
			
		||||
            };
 | 
			
		||||
            // Store toolbar UI state in session storage, so it can be accessed
 | 
			
		||||
            // by JavaScript that executes before the first paint.
 | 
			
		||||
            // @see core/modules/toolbar/js/toolbar.anti-flicker.js
 | 
			
		||||
            sessionStorage.setItem(
 | 
			
		||||
              'Drupal.toolbar.toolbarState',
 | 
			
		||||
              JSON.stringify(toolbarState),
 | 
			
		||||
            );
 | 
			
		||||
          },
 | 
			
		||||
        );
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Toolbar methods of Backbone objects.
 | 
			
		||||
   *
 | 
			
		||||
   * @namespace
 | 
			
		||||
   */
 | 
			
		||||
  Drupal.toolbar = {
 | 
			
		||||
    /**
 | 
			
		||||
     * A hash of View instances.
 | 
			
		||||
     *
 | 
			
		||||
     * @type {object.<string, Backbone.View>}
 | 
			
		||||
     */
 | 
			
		||||
    views: {},
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A hash of Model instances.
 | 
			
		||||
     *
 | 
			
		||||
     * @type {object.<string, Backbone.Model>}
 | 
			
		||||
     */
 | 
			
		||||
    models: {},
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A hash of MediaQueryList objects tracked by the toolbar.
 | 
			
		||||
     *
 | 
			
		||||
     * @type {object.<string, object>}
 | 
			
		||||
     */
 | 
			
		||||
    mql: {},
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Accepts a list of subtree menu elements.
 | 
			
		||||
     *
 | 
			
		||||
     * A deferred object that is resolved by an inlined JavaScript callback.
 | 
			
		||||
     *
 | 
			
		||||
     * @type {jQuery.Deferred}
 | 
			
		||||
     *
 | 
			
		||||
     * @see toolbar_subtrees_jsonp().
 | 
			
		||||
     */
 | 
			
		||||
    setSubtrees: new $.Deferred(),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Respond to configured narrow media query changes.
 | 
			
		||||
     *
 | 
			
		||||
     * @param {Drupal.toolbar.ToolbarModel} model
 | 
			
		||||
     *   A toolbar model
 | 
			
		||||
     * @param {string} label
 | 
			
		||||
     *   Media query label.
 | 
			
		||||
     * @param {object} mql
 | 
			
		||||
     *   A MediaQueryList object.
 | 
			
		||||
     */
 | 
			
		||||
    mediaQueryChangeHandler(model, label, mql) {
 | 
			
		||||
      switch (label) {
 | 
			
		||||
        case 'toolbar.narrow':
 | 
			
		||||
          model.set({
 | 
			
		||||
            isOriented: mql.matches,
 | 
			
		||||
            isTrayToggleVisible: false,
 | 
			
		||||
          });
 | 
			
		||||
          // If the toolbar doesn't have an explicit orientation yet, or if the
 | 
			
		||||
          // narrow media query doesn't match then set the orientation to
 | 
			
		||||
          // vertical.
 | 
			
		||||
          if (!mql.matches || !model.get('orientation')) {
 | 
			
		||||
            model.set({ orientation: 'vertical' }, { validate: true });
 | 
			
		||||
          }
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case 'toolbar.standard':
 | 
			
		||||
          model.set({
 | 
			
		||||
            isFixed: mql.matches,
 | 
			
		||||
          });
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        case 'toolbar.wide':
 | 
			
		||||
          model.set(
 | 
			
		||||
            {
 | 
			
		||||
              orientation:
 | 
			
		||||
                mql.matches && !model.get('locked') ? 'horizontal' : 'vertical',
 | 
			
		||||
            },
 | 
			
		||||
            { validate: true },
 | 
			
		||||
          );
 | 
			
		||||
          // The tray orientation toggle visibility does not need to be
 | 
			
		||||
          // validated.
 | 
			
		||||
          model.set({
 | 
			
		||||
            isTrayToggleVisible: mql.matches,
 | 
			
		||||
          });
 | 
			
		||||
          break;
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * A toggle is an interactive element often bound to a click handler.
 | 
			
		||||
   *
 | 
			
		||||
   * @return {string}
 | 
			
		||||
   *   A string representing a DOM fragment.
 | 
			
		||||
   */
 | 
			
		||||
  Drupal.theme.toolbarOrientationToggle = function () {
 | 
			
		||||
    return (
 | 
			
		||||
      '<div class="toolbar-toggle-orientation"><div class="toolbar-lining">' +
 | 
			
		||||
      '<button class="toolbar-icon" type="button"></button>' +
 | 
			
		||||
      '</div></div>'
 | 
			
		||||
    );
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Ajax command to set the toolbar subtrees.
 | 
			
		||||
   *
 | 
			
		||||
   * @param {Drupal.Ajax} ajax
 | 
			
		||||
   *   {@link Drupal.Ajax} object created by {@link Drupal.ajax}.
 | 
			
		||||
   * @param {object} response
 | 
			
		||||
   *   JSON response from the Ajax request.
 | 
			
		||||
   * @param {number} [status]
 | 
			
		||||
   *   XMLHttpRequest status.
 | 
			
		||||
   */
 | 
			
		||||
  Drupal.AjaxCommands.prototype.setToolbarSubtrees = function (
 | 
			
		||||
    ajax,
 | 
			
		||||
    response,
 | 
			
		||||
    status,
 | 
			
		||||
  ) {
 | 
			
		||||
    Drupal.toolbar.setSubtrees.resolve(response.subtrees);
 | 
			
		||||
  };
 | 
			
		||||
})(jQuery, Drupal, drupalSettings);
 | 
			
		||||
		Reference in New Issue
	
	Block a user