diff --git a/core/misc/dialog/dialog.ajax.es6.js b/core/misc/dialog/dialog.ajax.es6.js index a6f2e71ce7..419d0ea58c 100644 --- a/core/misc/dialog/dialog.ajax.es6.js +++ b/core/misc/dialog/dialog.ajax.es6.js @@ -132,6 +132,10 @@ response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); } + if (ajax.hasOwnProperty('element')) { + response.dialogOptions.drupalTriggerElement = ajax.element; + } + // Bind dialogButtonsChange. $dialog.on('dialogButtonsChange', () => { const buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); diff --git a/core/misc/dialog/dialog.ajax.js b/core/misc/dialog/dialog.ajax.js index de1d3c9219..ba9659f65c 100644 --- a/core/misc/dialog/dialog.ajax.js +++ b/core/misc/dialog/dialog.ajax.js @@ -85,6 +85,10 @@ response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); } + if (ajax.hasOwnProperty('element')) { + response.dialogOptions.drupalTriggerElement = ajax.element; + } + $dialog.on('dialogButtonsChange', function () { var buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); $dialog.dialog('option', 'buttons', buttons); diff --git a/core/modules/contextual/js/contextual.es6.js b/core/modules/contextual/js/contextual.es6.js index 701ed126cb..290d4d7134 100644 --- a/core/modules/contextual/js/contextual.es6.js +++ b/core/modules/contextual/js/contextual.es6.js @@ -4,6 +4,7 @@ */ (function ($, Drupal, drupalSettings, _, Backbone, JSON, storage) { + let drupalTriggerElement; const options = $.extend(drupalSettings.contextual, // Merge strings on top of drupalSettings so that they are not mutable. { @@ -263,4 +264,22 @@ $(document).on('drupalContextualLinkAdded', (event, data) => { Drupal.ajax.bindAjaxLinks(data.$el[0]); }); + + // Manage Active editable class on opening and closing of the dialog. + $(window).on({ + 'dialog:beforecreate': (event, dialog, $element, settings) => { + if (settings.hasOwnProperty('drupalTriggerElement')) { + drupalTriggerElement = settings.drupalTriggerElement; + } + }, + 'dialog:afterclose': (event, dialog, $element) => { + if (drupalTriggerElement) { + $(drupalTriggerElement) + .closest('[data-contextual-id]') + .find('button') + .get(0) + .focus(); + } + }, + }); }(jQuery, Drupal, drupalSettings, _, Backbone, window.JSON, window.sessionStorage)); diff --git a/core/modules/contextual/js/contextual.js b/core/modules/contextual/js/contextual.js index ed210d070d..57dfd6a47b 100644 --- a/core/modules/contextual/js/contextual.js +++ b/core/modules/contextual/js/contextual.js @@ -6,6 +6,7 @@ **/ (function ($, Drupal, drupalSettings, _, Backbone, JSON, storage) { + var drupalTriggerElement = void 0; var options = $.extend(drupalSettings.contextual, { strings: { open: Drupal.t('Open'), @@ -148,4 +149,17 @@ $(document).on('drupalContextualLinkAdded', function (event, data) { Drupal.ajax.bindAjaxLinks(data.$el[0]); }); + + $(window).on({ + 'dialog:beforecreate': function dialogBeforecreate(event, dialog, $element, settings) { + if (settings.hasOwnProperty('drupalTriggerElement')) { + drupalTriggerElement = settings.drupalTriggerElement; + } + }, + 'dialog:afterclose': function dialogAfterclose(event, dialog, $element) { + if (drupalTriggerElement) { + $(drupalTriggerElement).closest('[data-contextual-id]').find('button').get(0).focus(); + } + } + }); })(jQuery, Drupal, drupalSettings, _, Backbone, window.JSON, window.sessionStorage); \ No newline at end of file diff --git a/core/modules/contextual/tests/src/FunctionalJavascript/ContextualLinksTest.php b/core/modules/contextual/tests/src/FunctionalJavascript/ContextualLinksTest.php index de83692411..f8e414dbb0 100644 --- a/core/modules/contextual/tests/src/FunctionalJavascript/ContextualLinksTest.php +++ b/core/modules/contextual/tests/src/FunctionalJavascript/ContextualLinksTest.php @@ -80,6 +80,11 @@ public function testContextualLinksClick() { // Check to make sure that page was not reloaded. $this->assertSession()->pageTextContains($current_page_string); + // Close the dialog. + $this->getSession()->getPage()->find('css', '.ui-dialog .ui-dialog-titlebar-close')->click(); + // Confirm the contextual button has become the active element. + $this->assertJsCondition('document.activeElement === document.querySelector("#block-branding [data-contextual-id] button")'); + // Test clicking contextual link with toolbar. $this->container->get('module_installer')->install(['toolbar']); $this->grantPermissions(Role::load(Role::AUTHENTICATED_ID), ['access toolbar']);