diff --git a/core/misc/dialog/dialog.ajax.es6.js b/core/misc/dialog/dialog.ajax.es6.js index 8dca3720..7721a14a 100644 --- a/core/misc/dialog/dialog.ajax.es6.js +++ b/core/misc/dialog/dialog.ajax.es6.js @@ -132,6 +132,10 @@ Drupal.behaviors.dialog.prepareDialogButtons($dialog); } + if (ajax.hasOwnProperty('element') && ajax.element instanceof 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 c470491a..f5e2b181 100644 --- a/core/misc/dialog/dialog.ajax.js +++ b/core/misc/dialog/dialog.ajax.js @@ -83,6 +83,10 @@ response.dialogOptions.buttons = Drupal.behaviors.dialog.prepareDialogButtons($dialog); } + if (ajax.hasOwnProperty('element') && ajax.element instanceof 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 1c1c485c..b17c2634 100644 --- a/core/modules/contextual/js/contextual.es6.js +++ b/core/modules/contextual/js/contextual.es6.js @@ -286,6 +286,36 @@ $(document).on('drupalContextualLinkAdded', (event, data) => { Drupal.ajax.bindAjaxLinks(data.$el[0]); }); + + // The contextual button for the link that opened the dialog. + let dialogLinkContextualButton; + $(window).on({ + 'dialog:beforecreate': (event, dialog, $element, settings) => { + if (settings.hasOwnProperty('drupalTriggerElement')) { + // Determine if the trigger element is a contextual link. + if ( + $(settings.drupalTriggerElement) + .closest('[data-contextual-id]') + .find('button').length + ) { + /** + * Save the contextual link button so it will be available for + * 'dialog:afterclose'. + */ + dialogLinkContextualButton = $(settings.drupalTriggerElement) + .closest('[data-contextual-id]') + .find('button') + .get(0); + } + } + }, + 'dialog:afterclose': (event, dialog, $element) => { + if (dialogLinkContextualButton) { + // Set focus to the contextual trigger button. + $(dialogLinkContextualButton).focus(); + } + }, + }); })( jQuery, Drupal, diff --git a/core/modules/contextual/js/contextual.js b/core/modules/contextual/js/contextual.js index 4911b294..d99f214d 100644 --- a/core/modules/contextual/js/contextual.js +++ b/core/modules/contextual/js/contextual.js @@ -158,4 +158,19 @@ $(document).on('drupalContextualLinkAdded', function (event, data) { Drupal.ajax.bindAjaxLinks(data.$el[0]); }); + var dialogLinkContextualButton; + $(window).on({ + 'dialog:beforecreate': function dialogBeforecreate(event, dialog, $element, settings) { + if (settings.hasOwnProperty('drupalTriggerElement')) { + if ($(settings.drupalTriggerElement).closest('[data-contextual-id]').find('button').length) { + dialogLinkContextualButton = $(settings.drupalTriggerElement).closest('[data-contextual-id]').find('button').get(0); + } + } + }, + 'dialog:afterclose': function dialogAfterclose(event, dialog, $element) { + if (dialogLinkContextualButton) { + $(dialogLinkContextualButton).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 f3391995..9bafb0f8 100644 --- a/core/modules/contextual/tests/src/FunctionalJavascript/ContextualLinksTest.php +++ b/core/modules/contextual/tests/src/FunctionalJavascript/ContextualLinksTest.php @@ -85,6 +85,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']);