diff --git a/core/modules/block/block.libraries.yml b/core/modules/block/block.libraries.yml index 967a6827a1..9b5877f517 100644 --- a/core/modules/block/block.libraries.yml +++ b/core/modules/block/block.libraries.yml @@ -16,4 +16,6 @@ drupal.block.admin: dependencies: - core/jquery - core/drupal + - core/drupal.announce + - core/drupal.debounce - core/drupal.dialog.ajax diff --git a/core/modules/block/js/block.admin.es6.js b/core/modules/block/js/block.admin.es6.js index 9f99b7faba..4f8477d554 100644 --- a/core/modules/block/js/block.admin.es6.js +++ b/core/modules/block/js/block.admin.es6.js @@ -3,7 +3,7 @@ * Block admin behaviors. */ -(function ($, Drupal) { +(function ($, Drupal, debounce) { 'use strict'; @@ -56,6 +56,13 @@ // Filter if the length of the query is at least 2 characters. if (query.length >= 2) { $filter_rows.each(toggleBlockEntry); + Drupal.announce( + Drupal.formatPlural( + $table.find('tr:visible').length - 1, + '1 block is available in the modified list.', + '@count blocks are available in the modified list.' + ) + ); } else { $filter_rows.each(function (index) { @@ -66,7 +73,7 @@ if ($table.length) { $filter_rows = $table.find('div.block-filter-text-source'); - $input.on('keyup', filterBlockList); + $input.on('keyup', debounce(filterBlockList, 200)); } } }; @@ -94,4 +101,4 @@ } }; -}(jQuery, Drupal)); +}(jQuery, Drupal, Drupal.debounce)); diff --git a/core/modules/block/js/block.admin.js b/core/modules/block/js/block.admin.js index 8b13b9cca3..348782b1d7 100644 --- a/core/modules/block/js/block.admin.js +++ b/core/modules/block/js/block.admin.js @@ -5,7 +5,7 @@ * @preserve **/ -(function ($, Drupal) { +(function ($, Drupal, debounce) { 'use strict'; @@ -27,6 +27,7 @@ if (query.length >= 2) { $filter_rows.each(toggleBlockEntry); + Drupal.announce(Drupal.formatPlural($table.find('tr:visible').length - 1, '1 block is available in the modified list.', '@count blocks are available in the modified list.')); } else { $filter_rows.each(function (index) { $(this).parent().parent().show(); @@ -36,7 +37,7 @@ if ($table.length) { $filter_rows = $table.find('div.block-filter-text-source'); - $input.on('keyup', filterBlockList); + $input.on('keyup', debounce(filterBlockList, 200)); } } }; @@ -54,4 +55,4 @@ } } }; -})(jQuery, Drupal); \ No newline at end of file +})(jQuery, Drupal, Drupal.debounce); \ No newline at end of file diff --git a/core/modules/block/tests/src/FunctionalJavascript/BlockFilterTest.php b/core/modules/block/tests/src/FunctionalJavascript/BlockFilterTest.php new file mode 100644 index 0000000000..0b34f84102 --- /dev/null +++ b/core/modules/block/tests/src/FunctionalJavascript/BlockFilterTest.php @@ -0,0 +1,93 @@ +drupalCreateUser([ + 'administer blocks', + ]); + + $this->drupalLogin($admin_user); + } + + /** + * Tests block filter. + */ + public function testBlockFilter() { + $this->drupalGet('admin/structure/block'); + $assertSession = $this->assertSession(); + $session = $this->getSession(); + $page = $session->getPage(); + + // Find the block filter field on the add-block dialog. + $page->find('css', '#edit-blocks-region-header-title')->click(); + $filter = $assertSession->waitForElement('css', '.block-filter-text'); + + // Get all block rows, for assertions later. + $block_rows = $page->findAll('css', '.block-add-table tbody tr'); + + // Test block filter reduces the number of visible rows. + $filter->setValue('ad'); + $session->wait(10000, 'jQuery("#drupal-live-announce").html().indexOf("blocks are available") > -1'); + $visible_rows = $this->filterVisibleElements($block_rows); + if (count($block_rows) > 0) { + $this->assertNotEquals(count($block_rows), count($visible_rows)); + } + + // Test Drupal.announce() message when multiple matches are expected. + $expected_message = count($visible_rows) . ' blocks are available in the modified list.'; + $assertSession->elementTextContains('css', '#drupal-live-announce', $expected_message); + + // Test Drupal.announce() message when only one match is expected. + $filter->setValue('Powered by'); + $session->wait(10000, 'jQuery("#drupal-live-announce").html().indexOf("block is available") > -1'); + $visible_rows = $this->filterVisibleElements($block_rows); + $this->assertEquals(1, count($visible_rows)); + $expected_message = '1 block is available in the modified list.'; + $assertSession->elementTextContains('css', '#drupal-live-announce', $expected_message); + + // Test Drupal.announce() message when no matches are expected. + $filter->setValue('Pan-Galactic Gargle Blaster'); + $session->wait(10000, 'jQuery("#drupal-live-announce").html().indexOf("0 blocks are available") > -1'); + $visible_rows = $this->filterVisibleElements($block_rows); + $this->assertEquals(0, count($visible_rows)); + $expected_message = '0 blocks are available in the modified list.'; + $assertSession->elementTextContains('css', '#drupal-live-announce', $expected_message); + } + + /** + * Removes any non-visible elements from the passed array. + * + * @param NodeElement[] $elements + * An array of node elements. + * + * @return NodeElement[] + */ + protected function filterVisibleElements(array $elements) { + $elements = array_filter($elements, function(NodeElement $element) { + return $element->isVisible(); + }); + return $elements; + } + +}