Tests: Account for extra focus/blur listeners in jQuery >=3.4

jQuery >=3.4.0 uses a special focus/blur handler pair
needed to fix various issues with checkboxes/radio buttons
as well as being able to pass data in focus triggers.
However, this leaves dummy focus & blur events if any of these
events were ever listened to at a particular element. There's not
a lot UI can do to fix this so we now just skip these handlers for
data comparisons in tests.

Ref jquery/jquery#4496
Closes gh-1930

Co-authored-by: Richard Gibson <richard.gibson@gmail.com>
This commit is contained in:
Michał Gołębiowski-Owczarek 2020-07-23 15:54:16 +02:00 committed by GitHub
parent 91037d66b0
commit 5e2fc44c0c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -93,6 +93,28 @@ function getElementStyles( elem ) {
return styles;
}
// Returns 0 if v1 == v2, -1 if v1 < v2, 1 if v1 > v2
function compareVersions( v1, v2 ) {
var i,
rVersionParts = /^(\d+)\.(\d+)\.(\d+)/,
v1p = rVersionParts.exec( v1 ) || [ ],
v2p = rVersionParts.exec( v2 ) || [ ];
for ( i = 1; i <= 3; i++ ) {
if ( +v1p[ i ] > +v2p[ i ] ) {
return 1;
}
if ( +v1p[ i ] < +v2p[ i ] ) {
return -1;
}
}
return 0;
}
function jQueryVersionSince( version ) {
return compareVersions( $.fn.jquery, version ) >= 0;
}
function extract( selector, message ) {
var elem = $( selector );
if ( !elem.length ) {
@ -113,6 +135,54 @@ function extract( selector, message ) {
} );
result.style = getElementStyles( elem[ 0 ] );
result.events = $._data( elem[ 0 ], "events" );
// jQuery >=3.4.0 uses a special focus/blur handler pair
// needed to fix various issues with checkboxes/radio buttons
// as well as being able to pass data in focus triggers.
// However, this leaves dummy focus & blur events if any of these
// events were ever listened to at a particular element. There's not
// a lot UI can do to fix this so just skip these handlers for
// data comparisons in tests.
// See https://github.com/jquery/jquery/issues/4496
if ( result.events && jQueryVersionSince( "3.4.0" ) ) {
var i, eventDataList, eventData;
$.each( [ "focus", "blur" ], function( index, eventType ) {
if ( !result.events[ eventType ] ) {
return;
}
// Only the special internal handlers
// have the namespace field set to boolean `false`;
// filter them out.
result.events[ eventType ] = result.events[ eventType ].filter( function( eventData ) {
return eventData.namespace !== false;
} );
eventDataList = result.events[ eventType ];
for ( i = eventDataList.length - 1; i > -1; i-- ) {
eventData = eventDataList[ i ];
// Only these special jQuery internal handlers
// have the `namespace` field set to `false`;
// all other events use a string value, possibly
// an empty string if no namespace was set.
if ( eventData.namespace === false ) {
eventDataList.splice( i, 1 );
}
}
// Remove empty eventData collections to follow jQuery behavior.
if ( !eventDataList.length ) {
delete result.events[ eventType ];
}
} );
// Simulate empty events collections removal to follow jQuery behavior.
if ( !Object.keys( result.events ).length ) {
result.events = undefined;
}
}
result.data = $.extend( {}, elem.data() );
delete result.data[ $.expando ];
children = elem.children();