]> source.dussan.org Git - jquery.git/commitdiff
Fix #12061. Avoid window.onbeforeunload to permit multiple handlers. Close gh-894.
authorOleg <markelog@gmail.com>
Tue, 14 Aug 2012 20:10:10 +0000 (00:10 +0400)
committerDave Methvin <dave.methvin@gmail.com>
Sun, 21 Oct 2012 02:29:18 +0000 (22:29 -0400)
src/event.js
test/unit/event.js

index 330310fc804fab2cc3652df30a499d1df3d9e525..499a30397ca0ff1f5acd7535a8b308700b73f31a 100644 (file)
@@ -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;
                                }
                        }
                }
index 7536919951a043b641535277cabf9cb01debd58f..727e20ac2ad0e98b051d20b5ef1a5c5ca731b9df 100644 (file)
@@ -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() {