diff options
author | Oleg <markelog@gmail.com> | 2012-08-15 00:10:10 +0400 |
---|---|---|
committer | Dave Methvin <dave.methvin@gmail.com> | 2012-10-20 22:29:18 -0400 |
commit | 9dd0b010174dbfa70142a995a875a316337e1913 (patch) | |
tree | 125990588400e181cb90c0b747a0816a9821caf1 | |
parent | 08341437e09524f757be435b185c564e8de8101d (diff) | |
download | jquery-9dd0b010174dbfa70142a995a875a316337e1913.tar.gz jquery-9dd0b010174dbfa70142a995a875a316337e1913.zip |
Fix #12061. Avoid window.onbeforeunload to permit multiple handlers. Close gh-894.
-rw-r--r-- | src/event.js | 13 | ||||
-rw-r--r-- | test/unit/event.js | 61 |
2 files changed, 56 insertions, 18 deletions
diff --git a/src/event.js b/src/event.js index 330310fc8..499a30397 100644 --- a/src/event.js +++ b/src/event.js @@ -549,16 +549,11 @@ jQuery.event = { }, beforeunload: { - setup: function( data, namespaces, eventHandle ) { - // We only want to do this special case on windows - if ( jQuery.isWindow( this ) ) { - this.onbeforeunload = eventHandle; - } - }, + postDispatch: function( event ) { - teardown: function( namespaces, eventHandle ) { - if ( this.onbeforeunload === eventHandle ) { - this.onbeforeunload = null; + // Even when returnValue equals to undefined Firefox will still show alert + if ( event.result !== undefined ) { + event.originalEvent.returnValue = event.result; } } } diff --git a/test/unit/event.js b/test/unit/event.js index 753691995..727e20ac2 100644 --- a/test/unit/event.js +++ b/test/unit/event.js @@ -1369,20 +1369,63 @@ test("Submit event can be stopped (#11049)", function() { form.remove(); }); -test("on(beforeunload) creates/deletes window property instead of adding/removing event listener", function() { - expect(3); +// Test beforeunload event only if it supported (i.e. not Opera) +if ( window.onbeforeunload === null ) { + asyncTest("on(beforeunload)", 4, function() { + var doc, + forIE6 = 0, + iframe = jQuery("<iframe src='data/iframe.html' />"); + + iframe.appendTo("#qunit-fixture").one( "load", function() { + doc = iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument; + + jQuery( doc ).on( "beforeunload", function() { + ok( true, "beforeunload event is fired" ); + }); + + strictEqual( doc.onbeforeunload, null, "onbeforeunload property on window object still equals null" ); + + jQuery( doc ).on( "beforeunload", function() { + + // On iframe in IE6 beforeunload event will not fire if event is binded through window object, + // nevertheless, test should continue + window.setTimeout(function() { + if ( !forIE6 ) { + checker(); + } + }); + }); + + doc.onbeforeunload = function() { + if ( !forIE6 ) { + forIE6++; + checker(); + } + }; - equal( window.onbeforeunload, null, "window property is null/undefined up until now" ); + function checker() { + ok( true, "window.onbeforeunload handler is called" ); + iframe = jQuery("<iframe src='data/iframe.html' />"); - var handle = function () {}; - jQuery(window).on( "beforeunload", handle ); + iframe.appendTo("#qunit-fixture").one( "load", function() { + doc = iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument; - equal( typeof window.onbeforeunload, "function", "window property is set to a function"); + jQuery( doc ).on( "beforeunload", function() { + strictEqual( doc.onbeforeunload, null, "Event handler is fired, even when onbeforeunload property on window is nulled" ); - jQuery(window).off( "beforeunload", handle ); + start(); + }); - equal( window.onbeforeunload, null, "window property has been unset to null/undefined" ); -}); + doc.onbeforeunload = null; + + doc.location.reload(); + }); + } + + doc.location.reload(); + }); + }); +} test("jQuery.Event( type, props )", function() { |