From e699e44ca1864c344e6b7d70853c8a5019662d75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82e=CC=A8biowski-Owczarek?= Date: Wed, 24 Jun 2020 17:20:50 +0200 Subject: [PATCH 1/2] 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 --- tests/lib/qunit-assert-domequal.js | 68 ++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/tests/lib/qunit-assert-domequal.js b/tests/lib/qunit-assert-domequal.js index 35695c4f1c0..f2028c25d15 100644 --- a/tests/lib/qunit-assert-domequal.js +++ b/tests/lib/qunit-assert-domequal.js @@ -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,52 @@ 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; + } + + // We're going to do a shallow copy of the event list to + // avoid mutating internal jQuery structures when removing + // extraneous focus/blur handlers. + result.events[ eventType ] = result.events[ eventType ].slice(); + + 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(); From a4fba3c542009e136f88616d70d42206a9af2b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Go=C5=82=C4=99biowski-Owczarek?= Date: Thu, 2 Jul 2020 00:57:36 +0200 Subject: [PATCH 2/2] Tests: Update tests/lib/qunit-assert-domequal.js Co-authored-by: Richard Gibson --- tests/lib/qunit-assert-domequal.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/lib/qunit-assert-domequal.js b/tests/lib/qunit-assert-domequal.js index f2028c25d15..83ac60b9751 100644 --- a/tests/lib/qunit-assert-domequal.js +++ b/tests/lib/qunit-assert-domequal.js @@ -151,10 +151,12 @@ function extract( selector, message ) { return; } - // We're going to do a shallow copy of the event list to - // avoid mutating internal jQuery structures when removing - // extraneous focus/blur handlers. - result.events[ eventType ] = result.events[ eventType ].slice(); + // 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-- ) {