" ).appendTo( "#qunit-fixture" ),
cb = markup.find( "input" )[ 0 ];
jQuery( cb ).on( "click", function() {
assert.equal( this.checked, false, "just-clicked checkbox is not checked" );
} );
markup.on( "click", function() {
assert.equal( cb.checked, false, "checkbox is not checked in bubbled event" );
} );
// Native click
cb.checked = true;
assert.equal( cb.checked, true, "native - checkbox is initially checked" );
cb.click();
assert.equal( cb.checked, false, "native - checkbox is no longer checked" );
// jQuery click
cb.checked = true;
assert.equal( cb.checked, true, "jQuery - checkbox is initially checked" );
jQuery( cb ).trigger( "click" );
assert.equal( cb.checked, false, "jQuery - checkbox is no longer checked" );
// Handlers only; checkbox state remains false
jQuery( cb ).triggerHandler( "click" );
} );
QUnit.test( "event object properties on natively-triggered event", function( assert ) {
assert.expect( 3 );
var link = document.createElement( "a" ),
$link = jQuery( link ),
evt = document.createEvent( "MouseEvents" );
// Support: IE <=9 - 11 only
// IE requires element to be in the body before it will dispatch
$link.appendTo( "body" ).on( "click", function( e ) {
// Not trying to assert specific values here, just ensure the property exists
assert.equal( "detail" in e, true, "has .detail" );
assert.equal( "cancelable" in e, true, "has .cancelable" );
assert.equal( "bubbles" in e, true, "has .bubbles" );
} );
evt.initEvent( "click", true, true );
link.dispatchEvent( evt );
$link.off( "click" ).remove();
} );
QUnit.test( "addProp extensions", function( assert ) {
assert.expect( 2 );
var $fixture = jQuery( "
" ).appendTo( "#qunit-fixture" );
// Ensure the property doesn't exist
$fixture.on( "click", function( event ) {
assert.ok( !( "testProperty" in event ), "event.testProperty does not exist" );
} );
fireNative( $fixture[ 0 ], "click" );
$fixture.off( "click" );
jQuery.event.addProp( "testProperty", function() { return 42; } );
// Trigger a native click and ensure the property is set
$fixture.on( "click", function( event ) {
assert.equal( event.testProperty, 42, "event.testProperty getter was invoked" );
} );
fireNative( $fixture[ 0 ], "click" );
$fixture.off( "click" );
$fixture.remove();
} );
QUnit.test( "drag/drop events copy mouse-related event properties (gh-1925, gh-2009)", function( assert ) {
assert.expect( 4 );
var $fixture = jQuery( "
" ).appendTo( "body" );
$fixture.on( "dragmove", function( evt ) {
assert.ok( "pageX" in evt, "checking for pageX property on dragmove" );
assert.ok( "pageY" in evt, "checking for pageY property on dragmove" );
} );
fireNative( $fixture[ 0 ], "dragmove" );
$fixture.on( "drop", function( evt ) {
assert.ok( "pageX" in evt, "checking for pageX property on drop" );
assert.ok( "pageY" in evt, "checking for pageY property on drop" );
} );
fireNative( $fixture[ 0 ], "drop" );
$fixture.unbind( "dragmove drop" ).remove();
} );
QUnit.test( "focusin using non-element targets", function( assert ) {
assert.expect( 2 );
jQuery( document ).on( "focusin", function( e ) {
assert.ok( e.type === "focusin", "got a focusin event on a document" );
} ).trigger( "focusin" ).off( "focusin" );
jQuery( window ).on( "focusin", function( e ) {
assert.ok( e.type === "focusin", "got a focusin event on a window" );
} ).trigger( "focusin" ).off( "focusin" );
} );
testIframe(
"focusin from an iframe",
"event/focusinCrossFrame.html",
function( assert, framejQuery, frameWin, frameDoc ) {
assert.expect( 1 );
var input = jQuery( frameDoc ).find( "#frame-input" );
// Create a focusin handler on the parent; shouldn't affect the iframe's fate
jQuery( "body" ).on( "focusin.iframeTest", function() {
assert.ok( false, "fired a focusin event in the parent document" );
} );
input.on( "focusin", function() {
assert.ok( true, "fired a focusin event in the iframe" );
} );
// Avoid a native event; Chrome can't force focus to another frame
input.trigger( "focusin" );
// Must manually remove handler to avoid leaks in our data store
input.remove();
// Be sure it was removed; nothing should happen
input.trigger( "focusin" );
// Remove body handler manually since it's outside the fixture
jQuery( "body" ).off( "focusin.iframeTest" );
}
);
testIframe(
"jQuery.ready promise",
"event/promiseReady.html",
function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "$.when( $.ready ) works" );
}
);
// need PHP here to make the incepted IFRAME hang
if ( hasPHP ) {
testIframe(
"jQuery.ready uses interactive",
"event/interactiveReady.html",
function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "jQuery fires ready when the DOM can truly be interacted with" );
}
);
}
testIframe(
"Focusing iframe element",
"event/focusElem.html",
function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "Focused an element in an iframe" );
}
);
testIframe(
"triggerHandler(onbeforeunload)",
"event/triggerunload.html",
function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "Triggered onbeforeunload without an error" );
}
);
// need PHP here to make the incepted IFRAME hang
if ( hasPHP ) {
testIframe(
"jQuery.ready synchronous load with long loading subresources",
"event/syncReady.html",
function( assert, jQuery, window, document, isOk ) {
assert.expect( 1 );
assert.ok( isOk, "jQuery loaded synchronously fires ready when the DOM can truly be interacted with" );
}
);
}
QUnit.test( "change handler should be detached from element", function( assert ) {
assert.expect( 2 );
var $fixture = jQuery( "
" ).appendTo( "body" ),
originRemoveEvent = jQuery.removeEvent,
wrapperRemoveEvent = function( elem, type, handle ) {
assert.equal( "change", type, "Event handler for 'change' event should be removed" );
assert.equal( "change-ie-leak", jQuery( elem ).attr( "id" ), "Event handler for 'change' event should be removed from appropriate element" );
originRemoveEvent( elem, type, handle );
};
jQuery.removeEvent = wrapperRemoveEvent;
$fixture.on( "change", function() {} );
$fixture.off( "change" );
$fixture.remove();
jQuery.removeEvent = originRemoveEvent;
} );
QUnit.test( "trigger click on checkbox, fires change event", function( assert ) {
assert.expect( 1 );
var check = jQuery( "#check2" );
var done = assert.async();
check.on( "change", function() {
// get it?
check.off( "change" );
assert.ok( true, "Change event fired as a result of triggered click" );
done();
} ).trigger( "click" );
} );
QUnit.test( "Namespace preserved when passed an Event (#12739)", function( assert ) {
assert.expect( 4 );
var markup = jQuery(
"
"
),
triggered = 0,
fooEvent;
markup.find( "div" )
.addBack()
.on( "foo.bar", function( e ) {
if ( !e.handled ) {
triggered++;
e.handled = true;
assert.equal( e.namespace, "bar", "namespace is bar" );
jQuery( e.target ).find( "div" ).each( function() {
jQuery( this ).triggerHandler( e );
} );
}
} )
.on( "foo.bar2", function() {
assert.ok( false, "foo.bar2 called on trigger " + triggered + " id " + this.id );
} );
markup.trigger( "foo.bar" );
markup.trigger( jQuery.Event( "foo.bar" ) );
fooEvent = jQuery.Event( "foo" );
fooEvent.namespace = "bar";
markup.trigger( fooEvent );
markup.remove();
assert.equal( triggered, 3, "foo.bar triggered" );
} );
QUnit.test( "make sure events cloned correctly", function( assert ) {
assert.expect( 18 );
var clone,
fixture = jQuery( "#qunit-fixture" ),
checkbox = jQuery( "#check1" ),
p = jQuery( "#firstp" );
fixture.on( "click change", function( event, result ) {
assert.ok( result, event.type + " on original element is fired" );
} ).on( "click", "#firstp", function( event, result ) {
assert.ok( result, "Click on original child element though delegation is fired" );
} ).on( "change", "#check1", function( event, result ) {
assert.ok( result, "Change on original child element though delegation is fired" );
} );
p.on( "click", function() {
assert.ok( true, "Click on original child element is fired" );
} );
checkbox.on( "change", function() {
assert.ok( true, "Change on original child element is fired" );
} );
fixture.clone().trigger( "click" ).trigger( "change" ); // 0 events should be fired
clone = fixture.clone( true );
clone.find( "p" ).eq( 0 ).trigger( "click", true ); // 3 events should fire
clone.find( "#check1" ).trigger( "change", true ); // 3 events should fire
clone.remove();
clone = fixture.clone( true, true );
clone.find( "p" ).eq( 0 ).trigger( "click", true ); // 3 events should fire
clone.find( "#check1" ).trigger( "change", true ); // 3 events should fire
fixture.off();
p.off();
checkbox.off();
p.trigger( "click" ); // 0 should be fired
checkbox.trigger( "change" ); // 0 should be fired
clone.find( "p" ).eq( 0 ).trigger( "click", true ); // 3 events should fire
clone.find( "#check1" ).trigger( "change", true ); // 3 events should fire
clone.remove();
clone.find( "p" ).eq( 0 ).trigger( "click" ); // 0 should be fired
clone.find( "#check1" ).trigger( "change" ); // 0 events should fire
} );
QUnit.test( "String.prototype.namespace does not cause trigger() to throw (#13360)", function( assert ) {
assert.expect( 1 );
var errored = false;
String.prototype.namespace = function() {};
try {
jQuery( "
" ).trigger( "foo.bar" );
} catch ( e ) {
errored = true;
}
assert.equal( errored, false, "trigger() did not throw exception" );
delete String.prototype.namespace;
} );
QUnit.test( "Inline event result is returned (#13993)", function( assert ) {
assert.expect( 1 );
var result = jQuery( "
hello
" ).triggerHandler( "click" );
assert.equal( result, 42, "inline handler returned value" );
} );
QUnit.test( ".off() removes the expando when there's no more data", function( assert ) {
assert.expect( 2 );
var key,
div = jQuery( "
" ).appendTo( "#qunit-fixture" );
div.on( "click", false );
div.on( "custom", function() {
assert.ok( true, "Custom event triggered" );
} );
div.trigger( "custom" );
div.off( "click custom" );
// Make sure the expando is gone
for ( key in div[ 0 ] ) {
if ( /^jQuery/.test( key ) ) {
assert.strictEqual(
div[ 0 ][ key ], undefined,
"Expando was not removed when there was no more data"
);
}
}
} );
QUnit.test( "jQuery.Event( src ) does not require a target property", function( assert ) {
assert.expect( 2 );
var event = jQuery.Event( { type: "offtarget" } );
assert.equal( event.type, "offtarget", "correct type" );
assert.equal( event.target, undefined, "no target" );
} );
QUnit.test( "preventDefault() on focusin does not throw exception", function( assert ) {
assert.expect( 1 );
var done = assert.async(),
input = jQuery( "
" ).appendTo( "#form" );
input.on( "focusin", function( event ) {
if ( !done ) {
return;
}
var exceptionCaught;
try {
event.preventDefault();
} catch ( theException ) {
exceptionCaught = theException;
}
assert.strictEqual( exceptionCaught, undefined,
"Preventing default on focusin throws no exception" );
done();
done = null;
} );
input.trigger( "focus" );
// DOM focus is unreliable in TestSwarm; set a simulated event workaround timeout
setTimeout( function() {
if ( !done ) {
return;
}
input[ 0 ].addEventListener( "click", function( nativeEvent ) {
jQuery.event.simulate( "focusin", this, jQuery.event.fix( nativeEvent ) );
} );
input[ 0 ].click();
}, QUnit.config.testTimeout / 4 || 1000 );
} );
QUnit.test( "Donor event interference", function( assert ) {
assert.expect( 8 );
var outer = jQuery(
"
" +
"" +
"
"
).appendTo( "#qunit-fixture" ),
input = jQuery( "#donor-input" );
input.on( "click", function( event ) {
assert.equal( event.type, "click", "click event at input" );
assert.ok( !event.isPropagationStopped(), "click event at input is still propagating" );
assert.equal( typeof event.originalEvent, "object",
"click event at input has originalEvent property" );
} );
outer.on( "click", function( event ) {
assert.equal( event.type, "click", "click event at ancestor" );
assert.ok( !event.isPropagationStopped(), "click event at ancestor is still propagating" );
assert.equal( typeof event.originalEvent, "object",
"click event at ancestor has originalEvent property" );
} );
input.on( "change", function( event ) {
assert.equal( event.type, "change", "change event at input" );
assert.equal( typeof event.originalEvent, "object",
"change event at input has originalEvent property" );
event.stopPropagation();
} );
input[ 0 ].click();
} );
QUnit.test(
"simulated events shouldn't forward stopPropagation/preventDefault methods",
function( assert ) {
assert.expect( 3 );
var outer = jQuery(
"
" +
"" +
"
"
).appendTo( "#qunit-fixture" ),
input = jQuery( "#donor-input" ),
spy = {};
jQuery( "#donor-form" )
.on( "simulated", function( event ) {
spy.prevent = sinon.stub( event.originalEvent, "preventDefault" );
event.preventDefault();
} )
.on( "simulated", function( event ) {
spy.stop = sinon.stub( event.originalEvent, "stopPropagation" );
event.stopPropagation();
} )
.on( "simulated", function( event ) {
spy.immediate = sinon.stub( event.originalEvent, "stopImmediatePropagation" );
event.stopImmediatePropagation();
} )
.on( "simulated", function( event ) {
assert.ok( false, "simulated event immediate propagation stopped" );
} );
outer
.on( "simulated", function( event ) {
assert.ok( false, "simulated event propagation stopped" );
} );
// Force a simulated event
input[ 0 ].addEventListener( "click", function( nativeEvent ) {
jQuery.event.simulate( "simulated", this, jQuery.event.fix( nativeEvent ) );
} );
input[ 0 ].click();
assert.strictEqual( spy.prevent.called, false, "Native preventDefault not called" );
assert.strictEqual( spy.stop.called, false, "Native stopPropagation not called" );
assert.strictEqual( spy.immediate.called, false,
"Native stopImmediatePropagation not called" );
}
);
QUnit.test( "originalEvent type of simulated event", function( assert ) {
assert.expect( 2 );
var done = assert.async(),
outer = jQuery(
"
" +
"" +
"
"
).appendTo( "#qunit-fixture" ),
input = jQuery( "#donor-input" ),
expectedType = jQuery.support.focusin ? "focusin" : "focus",
finish = function() {
finish = null;
// Remove jQuery handlers to ensure removal of capturing handlers on the document
outer.off( "focusin" );
done();
};
outer.on( "focusin", function( event ) {
assert.equal( event.type, "focusin", "focusin event at ancestor" );
assert.equal( event.originalEvent.type, expectedType,
"focus event at ancestor has correct originalEvent type" );
setTimeout( finish );
} );
input.trigger( "focus" );
// DOM focus is unreliable in TestSwarm; set a simulated event workaround timeout
setTimeout( function() {
if ( !finish ) {
return;
}
input[ 0 ].addEventListener( "click", function( nativeEvent ) {
expectedType = nativeEvent.type;
jQuery.event.simulate( "focusin", this, jQuery.event.fix( nativeEvent ) );
} );
input[ 0 ].click();
}, QUnit.config.testTimeout / 4 || 1000 );
} );
QUnit.test( "trigger('click') on radio passes extra params", function( assert ) {
assert.expect( 1 );
var $radio = jQuery( "
" ).appendTo( "#qunit-fixture" )
.on( "click", function( e, data ) {
assert.ok( data, "Trigger data is passed to radio click handler" );
} );
$radio.trigger( "click", [ true ] );
} );
// Support: IE <=9 only
// https://msdn.microsoft.com/en-us/library/hh801223(v=vs.85).aspx
QUnit.test( "VML with special event handlers (trac-7071)", function( assert ) {
assert.expect( 1 );
var ns = jQuery( "
" ).appendTo( "head" );
jQuery( "
" ).appendTo( "#form" );
jQuery( "#form" ).on( "keydown", function() {
assert.ok( true, "no error was thrown" );
} );
jQuery( "#oval" ).trigger( "click" ).trigger( "keydown" );
ns.remove();
} );
QUnit.test( "Check order of focusin/focusout events", function( assert ) {
assert.expect( 2 );
var focus, blur,
input = jQuery( "#name" );
input
.on( "focus", function() {
focus = true;
} )
.on( "focusin", function() {
assert.ok( !focus, "Focusin event should fire before focus does" );
focus = true;
} )
.on( "blur", function() {
blur = true;
} )
.on( "focusout", function() {
assert.ok( !blur, "Focusout event should fire before blur does" );
blur = true;
} );
// gain focus
input.trigger( "focus" );
// then lose it
jQuery( "#search" ).trigger( "focus" );
// cleanup
input.off();
// DOM focus is unreliable in TestSwarm
if ( !focus ) {
assert.ok( true, "GAP: Could not observe focus change" );
assert.ok( true, "GAP: Could not observe focus change" );
}
} );
QUnit.test( "focus-blur order (#12868)", function( assert ) {
assert.expect( 5 );
var order,
$text = jQuery( "#text1" ),
$radio = jQuery( "#radio1" ).trigger( "focus" ),
// Support: IE <=10 only
// IE8-10 fire focus/blur events asynchronously; this is the resulting mess.
// IE's browser window must be topmost for this to work properly!!
done = assert.async();
$radio[ 0 ].focus();
setTimeout( function() {
$text
.on( "focus", function() {
assert.equal( order++, 1, "text focus" );
} )
.on( "blur", function() {
assert.equal( order++, 0, "text blur" );
} );
$radio
.on( "focus", function() {
assert.equal( order++, 1, "radio focus" );
} )
.on( "blur", function() {
assert.equal( order++, 0, "radio blur" );
} );
// Enabled input getting focus
order = 0;
assert.equal( document.activeElement, $radio[ 0 ], "radio has focus" );
$text.trigger( "focus" );
setTimeout( function() {
// DOM focus is unreliable in TestSwarm
if ( order === 0 ) {
assert.ok( true, "GAP: Could not observe focus change" );
assert.ok( true, "GAP: Could not observe focus change" );
}
assert.equal( document.activeElement, $text[ 0 ], "text has focus" );
// Run handlers without native method on an input
order = 1;
$radio.triggerHandler( "focus" );
// Clean up
$text.off();
$radio.off();
done();
}, 50 );
}, 50 );
} );