From db3b6ef6800127d8f4d53d4a72b83f1fbd5715e4 Mon Sep 17 00:00:00 2001 From: bnjmnm Date: Wed, 8 Dec 2021 12:32:38 -0500 Subject: [PATCH 1/5] fix issue 2002 by rewriting live region after delay --- ui/widgets/autocomplete.js | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/ui/widgets/autocomplete.js b/ui/widgets/autocomplete.js index 4166029b2ed..a3af2b6e185 100644 --- a/ui/widgets/autocomplete.js +++ b/ui/widgets/autocomplete.js @@ -66,6 +66,7 @@ $.widget( "ui.autocomplete", { requestIndex: 0, pending: 0, + liveRegionTimer: null, _create: function() { @@ -267,8 +268,10 @@ $.widget( "ui.autocomplete", { // Announce the value in the liveRegion label = ui.item.attr( "aria-label" ) || item.value; if ( label && String.prototype.trim.call( label ).length ) { - this.liveRegion.children().hide(); - $( "
" ).text( label ).appendTo( this.liveRegion ); + clearTimeout( this.liveRegionTimer ); + this.liveRegionTimer = setTimeout(() => { + this.liveRegion.html($( "
" ).text( label )); + }, 400); } }, menuselect: function( event, ui ) { @@ -663,8 +666,10 @@ $.widget( "ui.autocomplete", $.ui.autocomplete, { } else { message = this.options.messages.noResults; } - this.liveRegion.children().hide(); - $( "
" ).text( message ).appendTo( this.liveRegion ); + clearTimeout( this.liveRegionTimer ); + this.liveRegionTimer = setTimeout(() => { + this.liveRegion.html($( "
" ).text( message )); + }, 400); } } ); From ec52d38cceb40cbdac556f67bdf9e67084a2efaa Mon Sep 17 00:00:00 2001 From: bnjmnm Date: Wed, 8 Dec 2021 16:22:44 -0500 Subject: [PATCH 2/5] Autocomplete: eslint and test updates --- tests/unit/autocomplete/core.js | 80 +++++++++++++++++++-------------- ui/widgets/autocomplete.js | 14 +++--- 2 files changed, 54 insertions(+), 40 deletions(-) diff --git a/tests/unit/autocomplete/core.js b/tests/unit/autocomplete/core.js index d78db3bb90e..d2779e11095 100644 --- a/tests/unit/autocomplete/core.js +++ b/tests/unit/autocomplete/core.js @@ -293,6 +293,7 @@ QUnit.test( "simultaneous searches (#9334)", function( assert ) { } ); QUnit.test( "ARIA", function( assert ) { + var ready = assert.async(); assert.expect( 13 ); var element = $( "#autocomplete" ).autocomplete( { source: [ "java", "javascript" ] @@ -308,43 +309,51 @@ QUnit.test( "ARIA", function( assert ) { "Live region's role attribute must be status" ); element.autocomplete( "search", "j" ); - assert.equal( liveRegion.children().first().text(), - "2 results are available, use up and down arrow keys to navigate.", - "Live region for multiple values" ); + setTimeout( function() { + assert.equal( liveRegion.children().first().text(), + "2 results are available, use up and down arrow keys to navigate.", + "Live region for multiple values" ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - assert.equal( liveRegion.children().filter( ":visible" ).text(), "java", - "Live region changed on keydown to announce the highlighted value" ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout( function() { + assert.equal( liveRegion.children().filter( ":visible" ).text(), "java", + "Live region changed on keydown to announce the highlighted value" ); - element.one( "autocompletefocus", function( event ) { - event.preventDefault(); - } ); - element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - assert.equal( liveRegion.children().filter( ":visible" ).text(), "javascript", - "Live region updated when default focus is prevented" ); - - element.autocomplete( "search", "javas" ); - assert.equal( liveRegion.children().filter( ":visible" ).text(), - "1 result is available, use up and down arrow keys to navigate.", - "Live region for one value" ); - - element.autocomplete( "search", "z" ); - assert.equal( liveRegion.children().filter( ":visible" ).text(), "No search results.", - "Live region for no values" ); - - assert.equal( liveRegion.children().length, 5, - "Should be five children in the live region after the above" ); - assert.equal( liveRegion.children().filter( ":visible" ).length, 1, - "Only one should be still visible" ); - assert.ok( liveRegion.children().filter( ":visible" )[ 0 ] === liveRegion.children().last()[ 0 ], - "The last one should be the visible one" ); - - element.autocomplete( "destroy" ); - assert.equal( liveRegion.parent().length, 0, - "The liveRegion should be detached after destroy" ); + element.one( "autocompletefocus", function( event ) { + event.preventDefault(); + } ); + element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); + setTimeout( function() { + assert.equal( liveRegion.children().filter( ":visible" ).text(), "javascript", + "Live region updated when default focus is prevented" ); + element.autocomplete( "search", "javas" ); + setTimeout( function() { + assert.equal( liveRegion.children().filter( ":visible" ).text(), + "1 result is available, use up and down arrow keys to navigate.", + "Live region for one value" ); + element.autocomplete( "search", "z" ); + setTimeout( function() { + assert.equal( liveRegion.children().filter( ":visible" ).text(), "No search results.", + "Live region for no values" ); + assert.equal( liveRegion.children().length, 1, + "Should be one child in the live region after the above" ); + assert.equal( liveRegion.children().filter( ":visible" ).length, 1, + "Only one should be still visible" ); + assert.ok( liveRegion.children().filter( ":visible" )[ 0 ] === liveRegion.children().last()[ 0 ], + "The last one should be the visible one" ); + element.autocomplete( "destroy" ); + assert.equal( liveRegion.parent().length, 0, + "The liveRegion should be detached after destroy" ); + ready(); + }, 500 ); + }, 500 ); + }, 500 ); + }, 500 ); + }, 500 ); } ); QUnit.test( "ARIA, aria-label announcement", function( assert ) { + var ready = assert.async(); assert.expect( 1 ); $.widget( "custom.catcomplete", $.ui.autocomplete, { _renderMenu: function( ul, items ) { @@ -361,8 +370,11 @@ QUnit.test( "ARIA, aria-label announcement", function( assert ) { liveRegion = element.catcomplete( "instance" ).liveRegion; element.catcomplete( "search", "a" ); element.simulate( "keydown", { keyCode: $.ui.keyCode.DOWN } ); - assert.equal( liveRegion.children().filter( ":visible" ).text(), "People : anders andersson", - "Live region changed on keydown to announce the highlighted value's aria-label attribute" ); + setTimeout( function() { + assert.equal( liveRegion.children().filter( ":visible" ).text(), "People : anders andersson", + "Live region changed on keydown to announce the highlighted value's aria-label attribute" ); + ready(); + }, 500 ); } ); QUnit.test( "ARIA, init on detached input", function( assert ) { diff --git a/ui/widgets/autocomplete.js b/ui/widgets/autocomplete.js index a3af2b6e185..ddfa92f6841 100644 --- a/ui/widgets/autocomplete.js +++ b/ui/widgets/autocomplete.js @@ -269,9 +269,10 @@ $.widget( "ui.autocomplete", { label = ui.item.attr( "aria-label" ) || item.value; if ( label && String.prototype.trim.call( label ).length ) { clearTimeout( this.liveRegionTimer ); - this.liveRegionTimer = setTimeout(() => { - this.liveRegion.html($( "
" ).text( label )); - }, 400); + var that = this; + this.liveRegionTimer = setTimeout( function() { + that.liveRegion.html( $( "
" ).text( label ) ); + }, 400 ); } }, menuselect: function( event, ui ) { @@ -667,9 +668,10 @@ $.widget( "ui.autocomplete", $.ui.autocomplete, { message = this.options.messages.noResults; } clearTimeout( this.liveRegionTimer ); - this.liveRegionTimer = setTimeout(() => { - this.liveRegion.html($( "
" ).text( message )); - }, 400); + var that = this; + this.liveRegionTimer = setTimeout( function() { + that.liveRegion.html( $( "
" ).text( message ) ); + }, 400 ); } } ); From 7a6ce7e107fe4cd933c459bc4779308990ecd81b Mon Sep 17 00:00:00 2001 From: bnjmnm Date: Fri, 10 Dec 2021 15:02:40 -0500 Subject: [PATCH 3/5] Autocomplete: 2002 Reduce menufocus timeout --- tests/unit/autocomplete/core.js | 12 ++++++------ ui/widgets/autocomplete.js | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/tests/unit/autocomplete/core.js b/tests/unit/autocomplete/core.js index d2779e11095..a2a36cb4c1c 100644 --- a/tests/unit/autocomplete/core.js +++ b/tests/unit/autocomplete/core.js @@ -345,11 +345,11 @@ QUnit.test( "ARIA", function( assert ) { assert.equal( liveRegion.parent().length, 0, "The liveRegion should be detached after destroy" ); ready(); - }, 500 ); - }, 500 ); - }, 500 ); - }, 500 ); - }, 500 ); + }, 110 ); + }, 110 ); + }, 110 ); + }, 110 ); + }, 110 ); } ); QUnit.test( "ARIA, aria-label announcement", function( assert ) { @@ -374,7 +374,7 @@ QUnit.test( "ARIA, aria-label announcement", function( assert ) { assert.equal( liveRegion.children().filter( ":visible" ).text(), "People : anders andersson", "Live region changed on keydown to announce the highlighted value's aria-label attribute" ); ready(); - }, 500 ); + }, 110 ); } ); QUnit.test( "ARIA, init on detached input", function( assert ) { diff --git a/ui/widgets/autocomplete.js b/ui/widgets/autocomplete.js index ddfa92f6841..1f50a42bf19 100644 --- a/ui/widgets/autocomplete.js +++ b/ui/widgets/autocomplete.js @@ -272,7 +272,7 @@ $.widget( "ui.autocomplete", { var that = this; this.liveRegionTimer = setTimeout( function() { that.liveRegion.html( $( "
" ).text( label ) ); - }, 400 ); + }, 100 ); } }, menuselect: function( event, ui ) { @@ -671,7 +671,7 @@ $.widget( "ui.autocomplete", $.ui.autocomplete, { var that = this; this.liveRegionTimer = setTimeout( function() { that.liveRegion.html( $( "
" ).text( message ) ); - }, 400 ); + }, 100 ); } } ); From fb22d35b4f308d8c2fc1812456e9452268f50ec6 Mon Sep 17 00:00:00 2001 From: bnjmnm Date: Tue, 14 Dec 2021 23:26:15 -0500 Subject: [PATCH 4/5] Autocomplete: change two uses of setTimeout to call this._delay --- ui/widgets/autocomplete.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ui/widgets/autocomplete.js b/ui/widgets/autocomplete.js index 1f50a42bf19..1e1d16f5803 100644 --- a/ui/widgets/autocomplete.js +++ b/ui/widgets/autocomplete.js @@ -270,7 +270,7 @@ $.widget( "ui.autocomplete", { if ( label && String.prototype.trim.call( label ).length ) { clearTimeout( this.liveRegionTimer ); var that = this; - this.liveRegionTimer = setTimeout( function() { + this.liveRegionTimer = this._delay( function() { that.liveRegion.html( $( "
" ).text( label ) ); }, 100 ); } @@ -669,7 +669,7 @@ $.widget( "ui.autocomplete", $.ui.autocomplete, { } clearTimeout( this.liveRegionTimer ); var that = this; - this.liveRegionTimer = setTimeout( function() { + this.liveRegionTimer = this._delay( function() { that.liveRegion.html( $( "
" ).text( message ) ); }, 100 ); } From e0aeaa8bd6fc7146dc8ccf6e0fadf3c39a18234c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Th=C3=A9odore=20BIADALA?= Date: Thu, 23 Dec 2021 11:13:22 +0100 Subject: [PATCH 5/5] Autocomplete: remove extra "that" variable --- ui/widgets/autocomplete.js | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ui/widgets/autocomplete.js b/ui/widgets/autocomplete.js index 1e1d16f5803..a7b6f52bd19 100644 --- a/ui/widgets/autocomplete.js +++ b/ui/widgets/autocomplete.js @@ -269,9 +269,8 @@ $.widget( "ui.autocomplete", { label = ui.item.attr( "aria-label" ) || item.value; if ( label && String.prototype.trim.call( label ).length ) { clearTimeout( this.liveRegionTimer ); - var that = this; this.liveRegionTimer = this._delay( function() { - that.liveRegion.html( $( "
" ).text( label ) ); + this.liveRegion.html( $( "
" ).text( label ) ); }, 100 ); } }, @@ -668,9 +667,8 @@ $.widget( "ui.autocomplete", $.ui.autocomplete, { message = this.options.messages.noResults; } clearTimeout( this.liveRegionTimer ); - var that = this; this.liveRegionTimer = this._delay( function() { - that.liveRegion.html( $( "
" ).text( message ) ); + this.liveRegion.html( $( "
" ).text( message ) ); }, 100 ); } } );