Skip to content

Commit

Permalink
Merge branch 'jquery:main' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
uplusware authored Jan 15, 2022
2 parents 854b1e4 + 0c5becc commit 3b620c5
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 41 deletions.
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ Eric Hynds <[email protected]>
Ethan Romba <[email protected]> <[email protected]>
EungJun Yi <[email protected]>
Eyal Kobrigo <[email protected]>
Felix Nagel <[email protected]> <[email protected]>
Filippo Cavallarin <[email protected]> <[email protected]>
Florian Gutmann <[email protected]> <[email protected]>
Genie <[email protected]>
Expand Down
2 changes: 2 additions & 0 deletions AUTHORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,5 @@ sakshi87 <[email protected]>
Mikolaj Wolicki <[email protected]>
Patrick McKay <[email protected]>
c-lambert <[email protected]>
Josep Sanz <[email protected]>
Ben Mullins <[email protected]>
103 changes: 69 additions & 34 deletions tests/unit/autocomplete/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -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" ]
Expand All @@ -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();
}, 110 );
}, 110 );
}, 110 );
}, 110 );
}, 110 );
} );

QUnit.test( "ARIA, aria-label announcement", function( assert ) {
var ready = assert.async();
assert.expect( 1 );
$.widget( "custom.catcomplete", $.ui.autocomplete, {
_renderMenu: function( ul, items ) {
Expand All @@ -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();
}, 110 );
} );

QUnit.test( "ARIA, init on detached input", function( assert ) {
Expand Down Expand Up @@ -431,4 +443,27 @@ QUnit.test( "Close on click outside when focus remains", function( assert ) {
} );
} );

QUnit.test( "extra listeners created during typing (trac-15082, trac-15095)", function( assert ) {
assert.expect( 2 );

var origRemoveListenersCount;
var element = $( "#autocomplete" ).autocomplete( {
source: [ "java", "javascript" ],
delay: 0
} );

element.val( "j" ).autocomplete( "search", "j" );
origRemoveListenersCount = jQuery._data( element[ 0 ], "events" ).remove.length;

element.val( "ja" ).autocomplete( "search", "ja" );
assert.equal( jQuery._data( element[ 0 ], "events" ).remove.length,
origRemoveListenersCount,
"No extra listeners after typing multiple letters" );

element.val( "jav" ).autocomplete( "search", "jav" );
assert.equal( jQuery._data( element[ 0 ], "events" ).remove.length,
origRemoveListenersCount,
"No extra listeners after typing multiple letters" );
} );

} );
30 changes: 30 additions & 0 deletions tests/unit/selectmenu/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -404,4 +404,34 @@ QUnit.test( "Options with hidden attribute should not be rendered", function( as
} );
} );

QUnit.test( "extra listeners created after selection (trac-15078, trac-15152)", function( assert ) {
assert.expect( 3 );

var origRemoveListenersCount;
var element = $( "#speed" ).selectmenu();
var menu = element.selectmenu( "widget" );

element.val( "Slow" );
element.selectmenu( "refresh" );
origRemoveListenersCount = jQuery._data( menu[ 0 ], "events" ).remove.length;

element.val( "Fast" );
element.selectmenu( "refresh" );
assert.equal( jQuery._data( menu[ 0 ], "events" ).remove.length,
origRemoveListenersCount,
"No extra listeners after typing multiple letters" );

element.val( "Faster" );
element.selectmenu( "refresh" );
assert.equal( jQuery._data( menu[ 0 ], "events" ).remove.length,
origRemoveListenersCount,
"No extra listeners after typing multiple letters" );

element.val( "Slow" );
element.selectmenu( "refresh" );
assert.equal( jQuery._data( menu[ 0 ], "events" ).remove.length,
origRemoveListenersCount,
"No extra listeners after typing multiple letters" );
} );

} );
52 changes: 52 additions & 0 deletions tests/unit/tabs/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -675,4 +675,56 @@ QUnit.test( "#4033 - IE expands hash to full url and misinterprets tab as ajax",
state( assert, element, 1 );
} );


QUnit.test( "extra listeners created when tabs are added/removed (trac-15136)", function( assert ) {
assert.expect( 3 );

var origRemoveListenersCount;
var element = $( "#tabs1" ).tabs();
var tabCounter = 10;

function addTab() {
var label = "Tab " + tabCounter;
var id = "tabs-" + tabCounter;
var li = $(
"<li>" +
" <a href='#" + id + "'>" + label + "</a> " +
" <span class='ui-icon ui-icon-close' role='presentation'>Remove Tab</span>" +
"</li>"
);
var tabContentHtml = "Tab " + tabCounter + " content.";

element.find( ".ui-tabs-nav" ).append( li );
element.append( "<div id='" + id + "'><p>" + tabContentHtml + "</p></div>" );
element.tabs( "refresh" );
tabCounter++;
}

function removeLastTab() {
element.find( ".ui-icon-close" ).last().trigger( "click" );
}

origRemoveListenersCount = jQuery._data( element[ 0 ], "events" ).remove.length;

addTab();
assert.equal( jQuery._data( element[ 0 ], "events" ).remove.length,
origRemoveListenersCount,
"No extra listeners after adding a new tab" );

addTab();
addTab();
addTab();
assert.equal( jQuery._data( element[ 0 ], "events" ).remove.length,
origRemoveListenersCount,
"No extra listeners after adding multiple tabs" );

removeLastTab();
removeLastTab();
removeLastTab();
removeLastTab();
assert.equal( jQuery._data( element[ 0 ], "events" ).remove.length,
origRemoveListenersCount,
"No extra listeners after removing all the extra tabs" );
} );

} );
10 changes: 7 additions & 3 deletions ui/widget.js
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,8 @@ $.Widget.prototype = {
}, options );

function bindRemoveEvent() {
var nodesToBind = [];

options.element.each( function( _, element ) {
var isTracked = $.map( that.classesElementLookup, function( elements ) {
return elements;
Expand All @@ -508,11 +510,13 @@ $.Widget.prototype = {
} );

if ( !isTracked ) {
that._on( $( element ), {
remove: "_untrackClassesElement"
} );
nodesToBind.push( element );
}
} );

that._on( $( nodesToBind ), {
remove: "_untrackClassesElement"
} );
}

function processClassString( classes, checkOption ) {
Expand Down
13 changes: 9 additions & 4 deletions ui/widgets/autocomplete.js
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ $.widget( "ui.autocomplete", {

requestIndex: 0,
pending: 0,
liveRegionTimer: null,

_create: function() {

Expand Down Expand Up @@ -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();
$( "<div>" ).text( label ).appendTo( this.liveRegion );
clearTimeout( this.liveRegionTimer );
this.liveRegionTimer = this._delay( function() {
this.liveRegion.html( $( "<div>" ).text( label ) );
}, 100 );
}
},
menuselect: function( event, ui ) {
Expand Down Expand Up @@ -663,8 +666,10 @@ $.widget( "ui.autocomplete", $.ui.autocomplete, {
} else {
message = this.options.messages.noResults;
}
this.liveRegion.children().hide();
$( "<div>" ).text( message ).appendTo( this.liveRegion );
clearTimeout( this.liveRegionTimer );
this.liveRegionTimer = this._delay( function() {
this.liveRegion.html( $( "<div>" ).text( message ) );
}, 100 );
}
} );

Expand Down

0 comments on commit 3b620c5

Please sign in to comment.