diff --git a/core/misc/ajax.es6.js b/core/misc/ajax.es6.js index daa62548a0..ebe1d2315b 100644 --- a/core/misc/ajax.es6.js +++ b/core/misc/ajax.es6.js @@ -46,25 +46,7 @@ } } - // Bind Ajax behaviors to all items showing the class. - $('.use-ajax').once('ajax').each(function () { - const element_settings = {}; - // Clicked links look better with the throbber than the progress bar. - element_settings.progress = { type: 'throbber' }; - - // For anchor tags, these will go to the target of the anchor rather - // than the usual location. - const href = $(this).attr('href'); - if (href) { - element_settings.url = href; - element_settings.event = 'click'; - } - element_settings.dialogType = $(this).data('dialog-type'); - element_settings.dialog = $(this).data('dialog-options'); - element_settings.base = $(this).attr('id'); - element_settings.element = this; - Drupal.ajax(element_settings); - }); + Drupal.ajax.bindAjaxLinks($('body')); // This class means to submit the form to the action using Ajax. $('.use-ajax-submit').once('ajax').each(function () { @@ -268,6 +250,33 @@ Drupal.ajax.expired = function () { return Drupal.ajax.instances.filter(instance => instance && instance.element !== false && !document.body.contains(instance.element)); }; + /** + * Bind Ajax functionality to links that use the 'use-ajax' class. + * + * @param $element + * Element to enable Ajax functionality for. + */ + Drupal.ajax.bindAjaxLinks = ($element) => { + // Bind Ajax behaviors to all items showing the class. + $element.find('.use-ajax').once('ajax').each(function () { + const element_settings = {}; + // Clicked links look better with the throbber than the progress bar. + element_settings.progress = { type: 'throbber' }; + + // For anchor tags, these will go to the target of the anchor rather + // than the usual location. + const href = $(this).attr('href'); + if (href) { + element_settings.url = href; + element_settings.event = 'click'; + } + element_settings.dialogType = $(this).data('dialog-type'); + element_settings.dialog = $(this).data('dialog-options'); + element_settings.base = $(this).attr('id'); + element_settings.element = this; + Drupal.ajax(element_settings); + }); + }; /** * Settings for an Ajax object. @@ -1331,4 +1340,18 @@ } }, }; + + /** + * Bind Ajax contextual links when 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) => { + Drupal.ajax.bindAjaxLinks($(data.$el[0])); + }); }(jQuery, window, Drupal, drupalSettings)); diff --git a/core/misc/ajax.js b/core/misc/ajax.js index 1e15175edd..6a60e0d982 100644 --- a/core/misc/ajax.js +++ b/core/misc/ajax.js @@ -27,22 +27,7 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr } } - $('.use-ajax').once('ajax').each(function () { - var element_settings = {}; - - element_settings.progress = { type: 'throbber' }; - - var href = $(this).attr('href'); - if (href) { - element_settings.url = href; - element_settings.event = 'click'; - } - element_settings.dialogType = $(this).data('dialog-type'); - element_settings.dialog = $(this).data('dialog-options'); - element_settings.base = $(this).attr('id'); - element_settings.element = this; - Drupal.ajax(element_settings); - }); + Drupal.ajax.bindAjaxLinks($('body')); $('.use-ajax-submit').once('ajax').each(function () { var element_settings = {}; @@ -138,6 +123,25 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr }); }; + Drupal.ajax.bindAjaxLinks = function ($element) { + $element.find('.use-ajax').once('ajax').each(function () { + var element_settings = {}; + + element_settings.progress = { type: 'throbber' }; + + var href = $(this).attr('href'); + if (href) { + element_settings.url = href; + element_settings.event = 'click'; + } + element_settings.dialogType = $(this).data('dialog-type'); + element_settings.dialog = $(this).data('dialog-options'); + element_settings.base = $(this).attr('id'); + element_settings.element = this; + Drupal.ajax(element_settings); + }); + }; + Drupal.Ajax = function (base, element, element_settings) { var defaults = { event: element ? 'mousedown' : null, @@ -582,4 +586,8 @@ function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr } } }; + + $(document).on('drupalContextualLinkAdded', function (event, data) { + Drupal.ajax.bindAjaxLinks($(data.$el[0])); + }); })(jQuery, window, Drupal, drupalSettings); \ No newline at end of file diff --git a/core/modules/outside_in/js/outside_in.es6.js b/core/modules/outside_in/js/outside_in.es6.js index 66708cea0d..1d7e8298b6 100644 --- a/core/modules/outside_in/js/outside_in.es6.js +++ b/core/modules/outside_in/js/outside_in.es6.js @@ -11,6 +11,41 @@ const quickEditItemSelector = '[data-quickedit-entity-id]'; /** + * Prepare Ajax links to work with off-canvas and Settings Tray module. + * + * @todo Remove logic dealing with 'data-dialog-renderer' in + * https://www.drupal.org/node/2844261 + */ + function prepareAjaxLinks() { + const search = `${Drupal.ajax.WRAPPER_FORMAT}=drupal_dialog`; + const replace = `${Drupal.ajax.WRAPPER_FORMAT}=drupal_dialog_off_canvas`; + // Loop through all Ajax links and change the format to dialog-off-canvas when + // needed. + Drupal.ajax.instances + .filter((instance) => { + const hasElement = instance && !!instance.element; + let rendererOffCanvas = false; + let wrapperOffCanvas = false; + if (hasElement) { + rendererOffCanvas = $(instance.element).attr('data-dialog-renderer') === 'off_canvas'; + wrapperOffCanvas = instance.options.url.indexOf('drupal_dialog_off_canvas') === -1; + } + return hasElement && rendererOffCanvas && wrapperOffCanvas; + }) + .forEach((instance) => { + // @todo Move logic for data-dialog-renderer attribute into ajax.js + // https://www.drupal.org/node/2784443 + instance.options.url = instance.options.url.replace(search, replace); + // Check to make sure existing dialogOptions aren't overridden. + if (!('dialogOptions' in instance.options.data)) { + instance.options.data.dialogOptions = {}; + } + instance.options.data.dialogOptions.outsideInActiveEditableId = $(instance.element).parents('.outside-in-editable').attr('id'); + instance.progress = {type: 'fullscreen'}; + }); + } + + /** * Reacts to contextual links being added. * * @param {jQuery.Event} event @@ -21,10 +56,7 @@ * @listens event:drupalContextualLinkAdded */ $(document).on('drupalContextualLinkAdded', (event, data) => { - // Bind Ajax behaviors to all items showing the class. - // @todo Fix contextual links to work with use-ajax links in - // https://www.drupal.org/node/2764931. - Drupal.attachBehaviors(data.$el[0]); + prepareAjaxLinks(); // Bind a listener to all 'Quick edit' links for blocks // Click "Edit" button in toolbar to force Contextual Edit which starts @@ -209,33 +241,8 @@ Drupal.behaviors.toggleEditMode = { attach() { $(toggleEditSelector).once('outsidein').on('click.outsidein', toggleEditMode); - - const search = `${Drupal.ajax.WRAPPER_FORMAT}=drupal_dialog`; - const replace = `${Drupal.ajax.WRAPPER_FORMAT}=drupal_dialog_off_canvas`; - // Loop through all Ajax links and change the format to dialog-off-canvas when - // needed. - Drupal.ajax.instances - .filter((instance) => { - const hasElement = instance && !!instance.element; - let rendererOffCanvas = false; - let wrapperOffCanvas = false; - if (hasElement) { - rendererOffCanvas = $(instance.element).attr('data-dialog-renderer') === 'off_canvas'; - wrapperOffCanvas = instance.options.url.indexOf('drupal_dialog_off_canvas') === -1; - } - return hasElement && rendererOffCanvas && wrapperOffCanvas; - }) - .forEach((instance) => { - // @todo Move logic for data-dialog-renderer attribute into ajax.js - // https://www.drupal.org/node/2784443 - instance.options.url = instance.options.url.replace(search, replace); - // Check to make sure existing dialogOptions aren't overridden. - if (!('dialogOptions' in instance.options.data)) { - instance.options.data.dialogOptions = {}; - } - instance.options.data.dialogOptions.outsideInActiveEditableId = $(instance.element).parents('.outside-in-editable').attr('id'); - instance.progress = { type: 'fullscreen' }; - }); + // @todo Remove call in https://www.drupal.org/node/2844261 + prepareAjaxLinks(); }, }; diff --git a/core/modules/outside_in/js/outside_in.js b/core/modules/outside_in/js/outside_in.js index 635196d88f..bcebfd36c9 100644 --- a/core/modules/outside_in/js/outside_in.js +++ b/core/modules/outside_in/js/outside_in.js @@ -12,8 +12,32 @@ var contextualItemsSelector = '[data-contextual-id] a, [data-contextual-id] button'; var quickEditItemSelector = '[data-quickedit-entity-id]'; + function prepareAjaxLinks() { + var search = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog'; + var replace = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog_off_canvas'; + + Drupal.ajax.instances.filter(function (instance) { + var hasElement = instance && !!instance.element; + var rendererOffCanvas = false; + var wrapperOffCanvas = false; + if (hasElement) { + rendererOffCanvas = $(instance.element).attr('data-dialog-renderer') === 'off_canvas'; + wrapperOffCanvas = instance.options.url.indexOf('drupal_dialog_off_canvas') === -1; + } + return hasElement && rendererOffCanvas && wrapperOffCanvas; + }).forEach(function (instance) { + instance.options.url = instance.options.url.replace(search, replace); + + if (!('dialogOptions' in instance.options.data)) { + instance.options.data.dialogOptions = {}; + } + instance.options.data.dialogOptions.outsideInActiveEditableId = $(instance.element).parents('.outside-in-editable').attr('id'); + instance.progress = { type: 'fullscreen' }; + }); + } + $(document).on('drupalContextualLinkAdded', function (event, data) { - Drupal.attachBehaviors(data.$el[0]); + prepareAjaxLinks(); data.$el.find(blockConfigureSelector).on('click.outsidein', function () { if (!isInEditMode()) { @@ -125,27 +149,7 @@ attach: function attach() { $(toggleEditSelector).once('outsidein').on('click.outsidein', toggleEditMode); - var search = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog'; - var replace = Drupal.ajax.WRAPPER_FORMAT + '=drupal_dialog_off_canvas'; - - Drupal.ajax.instances.filter(function (instance) { - var hasElement = instance && !!instance.element; - var rendererOffCanvas = false; - var wrapperOffCanvas = false; - if (hasElement) { - rendererOffCanvas = $(instance.element).attr('data-dialog-renderer') === 'off_canvas'; - wrapperOffCanvas = instance.options.url.indexOf('drupal_dialog_off_canvas') === -1; - } - return hasElement && rendererOffCanvas && wrapperOffCanvas; - }).forEach(function (instance) { - instance.options.url = instance.options.url.replace(search, replace); - - if (!('dialogOptions' in instance.options.data)) { - instance.options.data.dialogOptions = {}; - } - instance.options.data.dialogOptions.outsideInActiveEditableId = $(instance.element).parents('.outside-in-editable').attr('id'); - instance.progress = { type: 'fullscreen' }; - }); + prepareAjaxLinks(); } };