Skip to content

Commit 5b5fda7

Browse files
authored
Tests: Account for an extra noop focus/blur listener 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. This leaves extra focus & blur events if any of these events were ever listened to at a particular element. We've started skipping these handlers in the `domEqual` assertion in gh-1930 but we missed a case where an event is triggered before any handler is attached - jQuery >=3.4.0 attaches then an extra noop listener just to force the code path to go through the setup code before the trigger happens. We now skip this extra handler as well. This fixes a test failure in "dialog: methods" destroy tests. Closes gh-1945 Ref jquery/jquery#4496 Ref gh-1930
1 parent 19c6286 commit 5b5fda7

File tree

1 file changed

+22
-21
lines changed

1 file changed

+22
-21
lines changed

tests/lib/qunit-assert-domequal.js

+22-21
Original file line numberDiff line numberDiff line change
@@ -145,34 +145,35 @@ function extract( selector, message ) {
145145
// data comparisons in tests.
146146
// See https://github.com/jquery/jquery/issues/4496
147147
if ( result.events && jQueryVersionSince( "3.4.0" ) ) {
148-
var i, eventDataList, eventData;
149148
$.each( [ "focus", "blur" ], function( index, eventType ) {
150149
if ( !result.events[ eventType ] ) {
151150
return;
152151
}
153152

154-
// Only the special internal handlers
155-
// have the namespace field set to boolean `false`;
156-
// filter them out.
157-
result.events[ eventType ] = result.events[ eventType ].filter( function( eventData ) {
158-
return eventData.namespace !== false;
159-
} );
160-
161-
eventDataList = result.events[ eventType ];
162-
for ( i = eventDataList.length - 1; i > -1; i-- ) {
163-
eventData = eventDataList[ i ];
164-
165-
// Only these special jQuery internal handlers
166-
// have the `namespace` field set to `false`;
167-
// all other events use a string value, possibly
168-
// an empty string if no namespace was set.
169-
if ( eventData.namespace === false ) {
170-
eventDataList.splice( i, 1 );
171-
}
172-
}
153+
// Filter special jQuery focus-related handlers out.
154+
result.events[ eventType ] = result.events[ eventType ]
155+
.filter( function( eventData ) {
156+
var handlerBody = eventData.handler.toString().replace(
157+
/^[^{]+\{[\s\n]*((?:.|\n)*?)\s*;?\s*\}[^}]*$/,
158+
"$1"
159+
);
160+
161+
// Only these special jQuery internal handlers
162+
// have the `namespace` field set to `false`;
163+
// all other events use a string value, possibly
164+
// an empty string if no namespace was set.
165+
return eventData.namespace !== false &&
166+
167+
// If a focus event was triggered without adding a handler first,
168+
// jQuery attaches an empty handler at the beginning of a trigger
169+
// call. Ignore this handler as well; it's a function with just
170+
// `return true;` in the body.
171+
// Handle the minified version as well.
172+
handlerBody !== "return true" && handlerBody !== "return!0";
173+
} );
173174

174175
// Remove empty eventData collections to follow jQuery behavior.
175-
if ( !eventDataList.length ) {
176+
if ( !result.events[ eventType ].length ) {
176177
delete result.events[ eventType ];
177178
}
178179
} );

0 commit comments

Comments
 (0)