core/lib/Drupal/Core/Ajax/CloseDialogCommand.php | 13 ++++++++++++- core/lib/Drupal/Core/Ajax/CloseModalDialogCommand.php | 8 +++++++- core/misc/dialog.ajax.js | 3 +++ core/misc/dialog.js | 6 ++++++ core/modules/edit/js/views/AppView.js | 6 +++++- .../system/lib/Drupal/system/Tests/Ajax/DialogTest.php | 1 + core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php | 6 ++++-- 7 files changed, 38 insertions(+), 5 deletions(-) diff --git a/core/lib/Drupal/Core/Ajax/CloseDialogCommand.php b/core/lib/Drupal/Core/Ajax/CloseDialogCommand.php index 1788ceb..aab1a8a 100644 --- a/core/lib/Drupal/Core/Ajax/CloseDialogCommand.php +++ b/core/lib/Drupal/Core/Ajax/CloseDialogCommand.php @@ -20,13 +20,23 @@ class CloseDialogCommand implements CommandInterface { protected $selector; /** + * Whether to remove the dialog from the DOM or not. + * + * @var bool + */ + protected $remove; + + /** * Constructs a CloseDialogCommand object. * * @param string $selector * A CSS selector string of the dialog to close. + * @param bool $remove + * (optional) Whether to remove the dialog from the DOM or not. */ - public function __construct($selector = NULL) { + public function __construct($selector = NULL, $remove = TRUE) { $this->selector = $selector ? $selector : '#drupal-modal'; + $this->remove = $remove; } /** @@ -36,6 +46,7 @@ public function render() { return array( 'command' => 'closeDialog', 'selector' => $this->selector, + 'remove' => $this->remove, ); } } diff --git a/core/lib/Drupal/Core/Ajax/CloseModalDialogCommand.php b/core/lib/Drupal/Core/Ajax/CloseModalDialogCommand.php index 0897700..8f4d706 100644 --- a/core/lib/Drupal/Core/Ajax/CloseModalDialogCommand.php +++ b/core/lib/Drupal/Core/Ajax/CloseModalDialogCommand.php @@ -13,10 +13,16 @@ * Defines an AJAX command that closes the currently visible modal dialog. */ class CloseModalDialogCommand extends CloseDialogCommand { + /** * Constructs a CloseModalDialogCommand object. + * + * @param bool $remove + * (optional) Whether to remove the dialog from the DOM or not. */ - public function __construct() { + public function __construct($remove = TRUE) { $this->selector = '#drupal-modal'; + $this->remove = $remove; } + } diff --git a/core/misc/dialog.ajax.js b/core/misc/dialog.ajax.js index c56515b..3cd0475 100644 --- a/core/misc/dialog.ajax.js +++ b/core/misc/dialog.ajax.js @@ -118,6 +118,9 @@ var $dialog = $(response.selector); if ($dialog.length) { Drupal.dialog($dialog).close(); + if (response.remove) { + $dialog.remove(); + } } }; diff --git a/core/misc/dialog.js b/core/misc/dialog.js index 94f2101..0ba6f1b 100644 --- a/core/misc/dialog.js +++ b/core/misc/dialog.js @@ -14,6 +14,12 @@ drupalSettings.dialog = { autoResize: true, maxHeight: '95%', dialogClass: '', + // When using this API directly (when generating dialogson the client side), + // you may want to override this method and do + // @code + // jQuery(event.target).remove() + // @endcode + // as well, to remove the dialog on closing. close: function (event) { Drupal.detachBehaviors(event.target, null, 'unload'); } diff --git a/core/modules/edit/js/views/AppView.js b/core/modules/edit/js/views/AppView.js index fa8f861..6e1ed41 100644 --- a/core/modules/edit/js/views/AppView.js +++ b/core/modules/edit/js/views/AppView.js @@ -368,7 +368,11 @@ Drupal.edit.AppView = Backbone.View.extend({ create: function () { $(this).parent().find('.ui-dialog-titlebar-close').remove(); }, - beforeClose: false + beforeClose: false, + close: function (event) { + // Automatically destroy the DOM element that was used for the dialog. + $(event.target).remove(); + } }); this.model.set('activeModal', discardDialog); diff --git a/core/modules/system/lib/Drupal/system/Tests/Ajax/DialogTest.php b/core/modules/system/lib/Drupal/system/Tests/Ajax/DialogTest.php index 8810649..3b1236d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Ajax/DialogTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Ajax/DialogTest.php @@ -94,6 +94,7 @@ public function testDialog() { $close_expected_response = array( 'command' => 'closeDialog', 'selector' => '#ajax-test-dialog-wrapper-1', + 'remove' => TRUE, ); // Check that requesting a modal dialog without JS goes to a page. diff --git a/core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php b/core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php index 880ac77..3597d8a 100644 --- a/core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php +++ b/core/tests/Drupal/Tests/Core/Ajax/AjaxCommandsTest.php @@ -360,6 +360,7 @@ public function testCloseModalDialogCommand() { $expected = array( 'command' => 'closeDialog', 'selector' => '#drupal-modal', + 'remove' => TRUE, ); $this->assertEquals($command->render(), $expected, "CloseModalDialogCommand::render() didn't return the expected array."); @@ -369,13 +370,14 @@ public function testCloseModalDialogCommand() { * Tests that CloseDialogCommand objects can be constructed and rendered. */ public function testCloseDialogCommand() { - $command = new CloseDialogCommand('#some-dialog'); + $command = new CloseDialogCommand('#some-dialog', FALSE); $expected = array( 'command' => 'closeDialog', 'selector' => '#some-dialog', + 'remove' => FALSE, ); - $this->assertEquals($command->render(), $expected, "CloseDialogCommand::render() with a selector didn't return the expected array."); + $this->assertEquals($command->render(), $expected, "CloseDialogCommand::render() with a selector and removal disabled didn't return the expected array."); } /**