diff --git a/core/modules/block/js/block.admin.es6.js b/core/modules/block/js/block.admin.es6.js index 197bc4beadd6460a4f9383152e68e76f2e613361..ff4d8eb20df24b7bb589b5473b55131371eebd4c 100644 --- a/core/modules/block/js/block.admin.es6.js +++ b/core/modules/block/js/block.admin.es6.js @@ -93,7 +93,8 @@ */ Drupal.behaviors.blockHighlightPlacement = { attach(context, settings) { - if (settings.blockPlacement) { + // Ensure that the block we are attempting to scroll to actually exists. + if (settings.blockPlacement && $('.js-block-placed').length) { $(context) .find('[data-drupal-selector="edit-blocks"]') .once('block-highlight') diff --git a/core/modules/block/js/block.admin.js b/core/modules/block/js/block.admin.js index 7cafed16ac64cf2108a40a7c33a39312cc0dadef..641f12d3f3a09c53b9d003657078e7ffc3750353 100644 --- a/core/modules/block/js/block.admin.js +++ b/core/modules/block/js/block.admin.js @@ -41,7 +41,7 @@ Drupal.behaviors.blockHighlightPlacement = { attach: function attach(context, settings) { - if (settings.blockPlacement) { + if (settings.blockPlacement && $('.js-block-placed').length) { $(context).find('[data-drupal-selector="edit-blocks"]').once('block-highlight').each(function () { var $container = $(this); diff --git a/core/modules/block/src/BlockListBuilder.php b/core/modules/block/src/BlockListBuilder.php index c1ccc504dbcacc811770079ef20b7c60ed26e105..d2286fcdd3644cd9b90a490a45e0a3cb399e31b7 100644 --- a/core/modules/block/src/BlockListBuilder.php +++ b/core/modules/block/src/BlockListBuilder.php @@ -354,6 +354,23 @@ public function getDefaultOperations(EntityInterface $entity) { if (isset($operations['delete'])) { $operations['delete']['title'] = $this->t('Remove'); + // Block operation links should have the `block-placement` query string + // parameter removed to ensure that JavaScript does not receive a block + // name that has been recently removed. + foreach ($operations as $operation) { + /** @var \Drupal\Core\Url $url */ + $url = $operation['url']; + $query = $url->getOption('query'); + $destination = $query['destination']; + + $destinationUrl = Url::fromUserInput($destination); + $destinationQuery = $destinationUrl->getOption('query'); + unset($destinationQuery['block-placement']); + + $destinationUrl->setOption('query', $destinationQuery); + $query['destination'] = $destinationUrl->toString(); + $url->setOption('query', $query); + } } return $operations; } diff --git a/core/modules/block/tests/src/Functional/BlockTest.php b/core/modules/block/tests/src/Functional/BlockTest.php index 53b48662cd234f1d22ffcfef4914d12a201b901e..9fb33573c46cbf4bc42e3d0c68abc9093c145c09 100644 --- a/core/modules/block/tests/src/Functional/BlockTest.php +++ b/core/modules/block/tests/src/Functional/BlockTest.php @@ -238,6 +238,30 @@ public function testBlock() { $this->assertNoRaw($block->id()); } + /** + * Tests the block operation links. + */ + public function testBlockOperationLinks() { + $this->drupalGet('admin/structure/block'); + // Go to the select block form. + $this->clickLink('Place block'); + // Select the first available block. + $this->clickLink('Place block'); + // Finally place the block + $this->submitForm([], 'Save block'); + + $url = $this->getUrl(); + $parsed = parse_url($url); + $this->assertContains('block-placement', $parsed['query']); + + $this->clickLink('Remove'); + $this->submitForm([], 'Remove'); + + $url = $this->getUrl(); + $parsed = parse_url($url); + $this->assertTrue(empty($parsed['query'])); + } + /** * Tests that the block form has a theme selector when not passed via the URL. */