123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- /**
- * @file
- * Drupal's Settings Tray library.
- *
- * @private
- */
- (($, Drupal) => {
- const blockConfigureSelector = '[data-settings-tray-edit]';
- const toggleEditSelector = '[data-drupal-settingstray="toggle"]';
- const itemsToToggleSelector =
- '[data-off-canvas-main-canvas], #toolbar-bar, [data-drupal-settingstray="editable"] a, [data-drupal-settingstray="editable"] button';
- const contextualItemsSelector =
- '[data-contextual-id] a, [data-contextual-id] button';
- const quickEditItemSelector = '[data-quickedit-entity-id]';
- /**
- * Prevent default click events except contextual links.
- *
- * In edit mode the default action of click events is suppressed.
- *
- * @param {jQuery.Event} event
- * The click event.
- */
- function preventClick(event) {
- // Do not prevent contextual links.
- if ($(event.target).closest('.contextual-links').length) {
- return;
- }
- event.preventDefault();
- }
- /**
- * Close any active toolbar tray before entering edit mode.
- */
- function closeToolbarTrays() {
- $(Drupal.toolbar.models.toolbarModel.get('activeTab')).trigger('click');
- }
- /**
- * Disables the QuickEdit module editor if open.
- */
- function disableQuickEdit() {
- $('.quickedit-toolbar button.action-cancel').trigger('click');
- }
- /**
- * Closes/removes off-canvas.
- */
- function closeOffCanvas() {
- $('.ui-dialog-off-canvas .ui-dialog-titlebar-close').trigger('click');
- }
- /**
- * Gets all items that should be toggled with class during edit mode.
- *
- * @return {jQuery}
- * Items that should be toggled.
- */
- function getItemsToToggle() {
- return $(itemsToToggleSelector).not(contextualItemsSelector);
- }
- /**
- * Helper to switch edit mode state.
- *
- * @param {boolean} editMode
- * True enable edit mode, false disable edit mode.
- */
- function setEditModeState(editMode) {
- if (!document.querySelector('[data-off-canvas-main-canvas]')) {
- throw new Error(
- 'data-off-canvas-main-canvas is missing from settings-tray-page-wrapper.html.twig',
- );
- }
- editMode = !!editMode;
- const $editButton = $(toggleEditSelector);
- let $editables;
- // Turn on edit mode.
- if (editMode) {
- $editButton.text(Drupal.t('Editing'));
- closeToolbarTrays();
- $editables = $('[data-drupal-settingstray="editable"]').once(
- 'settingstray',
- );
- if ($editables.length) {
- // Use event capture to prevent clicks on links.
- document
- .querySelector('[data-off-canvas-main-canvas]')
- .addEventListener('click', preventClick, true);
- /**
- * When a click occurs try and find the settings-tray edit link
- * and click it.
- */
- $editables.not(contextualItemsSelector).on('click.settingstray', e => {
- // Contextual links are allowed to function in Edit mode.
- if (
- $(e.target).closest('.contextual').length ||
- !localStorage.getItem('Drupal.contextualToolbar.isViewing')
- ) {
- return;
- }
- $(e.currentTarget)
- .find(blockConfigureSelector)
- .trigger('click');
- disableQuickEdit();
- });
- $(quickEditItemSelector)
- .not(contextualItemsSelector)
- .on('click.settingstray', e => {
- /**
- * For all non-contextual links or the contextual QuickEdit link
- * close the off-canvas dialog.
- */
- if (
- !$(e.target)
- .parent()
- .hasClass('contextual') ||
- $(e.target)
- .parent()
- .hasClass('quickedit')
- ) {
- closeOffCanvas();
- }
- // Do not trigger if target is quick edit link to avoid loop.
- if (
- $(e.target)
- .parent()
- .hasClass('contextual') ||
- $(e.target)
- .parent()
- .hasClass('quickedit')
- ) {
- return;
- }
- $(e.currentTarget)
- .find('li.quickedit a')
- .trigger('click');
- });
- }
- }
- // Disable edit mode.
- else {
- $editables = $('[data-drupal-settingstray="editable"]').removeOnce(
- 'settingstray',
- );
- if ($editables.length) {
- document
- .querySelector('[data-off-canvas-main-canvas]')
- .removeEventListener('click', preventClick, true);
- $editables.off('.settingstray');
- $(quickEditItemSelector).off('.settingstray');
- }
- $editButton.text(Drupal.t('Edit'));
- closeOffCanvas();
- disableQuickEdit();
- }
- getItemsToToggle().toggleClass('js-settings-tray-edit-mode', editMode);
- $('.edit-mode-inactive').toggleClass('visually-hidden', editMode);
- }
- /**
- * Helper to check the state of the settings-tray mode.
- *
- * @todo don't use a class for this.
- *
- * @return {boolean}
- * State of the settings-tray edit mode.
- */
- function isInEditMode() {
- return $('#toolbar-bar').hasClass('js-settings-tray-edit-mode');
- }
- /**
- * Helper to toggle Edit mode.
- */
- function toggleEditMode() {
- setEditModeState(!isInEditMode());
- }
- /**
- * Prepares Ajax links to work with off-canvas and Settings Tray module.
- */
- function prepareAjaxLinks() {
- // Find all Ajax instances that use the 'off_canvas' renderer.
- Drupal.ajax.instances
- /**
- * If there is an element and the renderer is 'off_canvas' then we want
- * to add our changes.
- */
- .filter(
- instance =>
- instance &&
- $(instance.element).attr('data-dialog-renderer') === 'off_canvas',
- )
- /**
- * Loop through all Ajax instances that use the 'off_canvas' renderer to
- * set active editable ID.
- */
- .forEach(instance => {
- // Check to make sure existing dialogOptions aren't overridden.
- if (!instance.options.data.hasOwnProperty('dialogOptions')) {
- instance.options.data.dialogOptions = {};
- }
- instance.options.data.dialogOptions.settingsTrayActiveEditableId = $(
- instance.element,
- )
- .parents('.settings-tray-editable')
- .attr('id');
- instance.progress = { type: 'fullscreen' };
- });
- }
- /**
- * Reacts to contextual links being added.
- *
- * @param {jQuery.Event} event
- * The `drupalContextualLinkAdded` event.
- * @param {object} data
- * An object containing the data relevant to the event.
- *
- * @listens event:drupalContextualLinkAdded
- */
- $(document).on('drupalContextualLinkAdded', (event, data) => {
- /**
- * When contextual links are add we need to set extra properties on the
- * instances in Drupal.ajax.instances for them to work with Edit Mode.
- */
- prepareAjaxLinks();
- // When the first contextual link is added to the page set Edit Mode.
- $('body')
- .once('settings_tray.edit_mode_init')
- .each(() => {
- const editMode =
- localStorage.getItem('Drupal.contextualToolbar.isViewing') ===
- 'false';
- if (editMode) {
- setEditModeState(true);
- }
- });
- /**
- * Bind a listener to all 'Quick edit' links for blocks. Click "Edit"
- * button in toolbar to force Contextual Edit which starts Settings Tray
- * edit mode also.
- */
- data.$el.find(blockConfigureSelector).on('click.settingstray', () => {
- if (!isInEditMode()) {
- $(toggleEditSelector)
- .trigger('click')
- .trigger('click.settings_tray');
- }
- /**
- * Always disable QuickEdit regardless of whether "EditMode" was just
- * enabled.
- */
- disableQuickEdit();
- });
- });
- $(document).on('keyup.settingstray', e => {
- if (isInEditMode() && e.keyCode === 27) {
- Drupal.announce(Drupal.t('Exited edit mode.'));
- toggleEditMode();
- }
- });
- /**
- * Toggle the js-settings-tray-edit-mode class on items that we want to
- * disable while in edit mode.
- *
- * @type {Drupal~behavior}
- *
- * @prop {Drupal~behaviorAttach} attach
- * Toggle the js-settings-tray-edit-mode class.
- */
- Drupal.behaviors.toggleEditMode = {
- attach() {
- $(toggleEditSelector)
- .once('settingstray')
- .on('click.settingstray', toggleEditMode);
- },
- };
- // Manage Active editable class on opening and closing of the dialog.
- $(window).on({
- 'dialog:beforecreate': (event, dialog, $element, settings) => {
- if ($element.is('#drupal-off-canvas')) {
- $('body .settings-tray-active-editable').removeClass(
- 'settings-tray-active-editable',
- );
- const $activeElement = $(`#${settings.settingsTrayActiveEditableId}`);
- if ($activeElement.length) {
- $activeElement.addClass('settings-tray-active-editable');
- }
- }
- },
- 'dialog:beforeclose': (event, dialog, $element) => {
- if ($element.is('#drupal-off-canvas')) {
- $('body .settings-tray-active-editable').removeClass(
- 'settings-tray-active-editable',
- );
- }
- },
- });
- })(jQuery, Drupal);
|