Loading core/modules/layout_builder/js/layout-builder.js +9 −0 Original line number Diff line number Diff line Loading @@ -456,4 +456,13 @@ return `<div class="layout-builder-block__content-preview-placeholder-label js-layout-builder-content-preview-placeholder-label">${contentPreviewPlaceholderText}</div>`; }; // Remove all contextual links outside the layout. $(window).on('drupalContextualLinkAdded', (event, data) => { const element = data.$el; const contextualId = element.attr('data-contextual-id'); if (contextualId && !contextualId.startsWith('layout_builder_block:')) { element.remove(); } }); })(jQuery, Drupal, Sortable); core/modules/layout_builder/tests/src/FunctionalJavascript/ContextualLinksTest.php +44 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ protected function setUp(): void { 'administer nodes', 'bypass node access', 'administer views', 'administer blocks', ]); $user->save(); $this->drupalLogin($user); Loading @@ -69,7 +70,6 @@ protected function setUp(): void { * Tests that the contextual links inside Layout Builder are removed. */ public function testContextualLinks() { // Skipped due to frequent random test failures. $page = $this->getSession()->getPage(); $this->drupalGet('node/1/layout'); Loading @@ -94,6 +94,33 @@ public function testContextualLinks() { $this->assertCorrectContextualLinksInNode(); } /** * Tests that contextual links outside the layout are removed. */ public function testContextualLinksOutsideLayout() { $assert_session = $this->assertSession(); $this->drupalPlaceBlock('system_powered_by_block', ['id' => 'global_block']); $this->drupalGet('node/1'); // Ensure global blocks contextual link is present when not on // Layout Builder. $assert_session->elementsCount('css', '[data-contextual-id*=\'block:block=global_block:\']', 1); $this->drupalGet('node/1/layout'); $this->addBlock('Test Block View: Teaser block'); // Ensure that only the layout specific contextual links are present. $this->assertCorrectContextualLinks(); $page = $this->getSession()->getPage(); $page->hasButton('Save layout'); $page->pressButton('Save layout'); $this->drupalGet('node/1/layout'); // Ensure the contextual links are correct when the Layout Builder is loaded // after being saved. $this->assertCorrectContextualLinks(); } /** * Adds block to the layout via Layout Builder's UI. * Loading Loading @@ -153,4 +180,20 @@ protected function assertCorrectContextualLinksInNode(): void { $this->assertNotEmpty($page->findAll('css', '.layout-content [data-contextual-id]')); } /** * Assert the contextual links are correct. * * @internal */ protected function assertCorrectContextualLinks() { $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); $this->assertNotEmpty($assert_session->waitForElementVisible('css', '.block-views-blocktest-block-view-block-2')); $assert_session->assertNoElementAfterWait('css', '[data-contextual-id*=\'node:\']'); // Ensure that the Layout Builder's own contextual links are not removed. $this->assertCount(3, $page->findAll('css', '[data-contextual-id*=\'layout_builder_block:\']')); // Ensure that the global block's contextual links are removed. $assert_session->elementNotExists('css', '[data-contextual-id*=\'block:block=global_block:\']'); } } Loading
core/modules/layout_builder/js/layout-builder.js +9 −0 Original line number Diff line number Diff line Loading @@ -456,4 +456,13 @@ return `<div class="layout-builder-block__content-preview-placeholder-label js-layout-builder-content-preview-placeholder-label">${contentPreviewPlaceholderText}</div>`; }; // Remove all contextual links outside the layout. $(window).on('drupalContextualLinkAdded', (event, data) => { const element = data.$el; const contextualId = element.attr('data-contextual-id'); if (contextualId && !contextualId.startsWith('layout_builder_block:')) { element.remove(); } }); })(jQuery, Drupal, Sortable);
core/modules/layout_builder/tests/src/FunctionalJavascript/ContextualLinksTest.php +44 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,7 @@ protected function setUp(): void { 'administer nodes', 'bypass node access', 'administer views', 'administer blocks', ]); $user->save(); $this->drupalLogin($user); Loading @@ -69,7 +70,6 @@ protected function setUp(): void { * Tests that the contextual links inside Layout Builder are removed. */ public function testContextualLinks() { // Skipped due to frequent random test failures. $page = $this->getSession()->getPage(); $this->drupalGet('node/1/layout'); Loading @@ -94,6 +94,33 @@ public function testContextualLinks() { $this->assertCorrectContextualLinksInNode(); } /** * Tests that contextual links outside the layout are removed. */ public function testContextualLinksOutsideLayout() { $assert_session = $this->assertSession(); $this->drupalPlaceBlock('system_powered_by_block', ['id' => 'global_block']); $this->drupalGet('node/1'); // Ensure global blocks contextual link is present when not on // Layout Builder. $assert_session->elementsCount('css', '[data-contextual-id*=\'block:block=global_block:\']', 1); $this->drupalGet('node/1/layout'); $this->addBlock('Test Block View: Teaser block'); // Ensure that only the layout specific contextual links are present. $this->assertCorrectContextualLinks(); $page = $this->getSession()->getPage(); $page->hasButton('Save layout'); $page->pressButton('Save layout'); $this->drupalGet('node/1/layout'); // Ensure the contextual links are correct when the Layout Builder is loaded // after being saved. $this->assertCorrectContextualLinks(); } /** * Adds block to the layout via Layout Builder's UI. * Loading Loading @@ -153,4 +180,20 @@ protected function assertCorrectContextualLinksInNode(): void { $this->assertNotEmpty($page->findAll('css', '.layout-content [data-contextual-id]')); } /** * Assert the contextual links are correct. * * @internal */ protected function assertCorrectContextualLinks() { $assert_session = $this->assertSession(); $page = $this->getSession()->getPage(); $this->assertNotEmpty($assert_session->waitForElementVisible('css', '.block-views-blocktest-block-view-block-2')); $assert_session->assertNoElementAfterWait('css', '[data-contextual-id*=\'node:\']'); // Ensure that the Layout Builder's own contextual links are not removed. $this->assertCount(3, $page->findAll('css', '[data-contextual-id*=\'layout_builder_block:\']')); // Ensure that the global block's contextual links are removed. $assert_session->elementNotExists('css', '[data-contextual-id*=\'block:block=global_block:\']'); } }