Reviewers: jgw, Description: Description: =========== If an event fires while a preview handler is handling an event, the NativePreviewEvent singleton will be reset but not returned to its original state. I observed this behavior occurring natively on Chrome and Safari, but it can also occur programatically.
Fix: ==== We now store the current state of the NativePreviewEvent before resetting it, and return it to its original state before exiting the fire method. Testing: ======= I added a JUnit test and confirmed that it fails without the fix, but passes with it. Please review this at http://gwt-code-reviews.appspot.com/68804 Affected files: user/src/com/google/gwt/user/client/Event.java user/test/com/google/gwt/user/client/EventTest.java Index: user/src/com/google/gwt/user/client/Event.java =================================================================== --- user/src/com/google/gwt/user/client/Event.java (revision 6161) +++ user/src/com/google/gwt/user/client/Event.java (working copy) @@ -72,13 +72,27 @@ */ private static boolean fire(HandlerManager handlers, NativeEvent nativeEvent) { if (TYPE != null && handlers != null && handlers.isEventHandled(TYPE)) { + // Cache the current values in the singleton in case we are in the + // middle of handling another event. + boolean lastIsCanceled = singleton.isCanceled; + boolean lastIsConsumed = singleton.isConsumed; + boolean lastIsFirstHandler = singleton.isFirstHandler; + NativeEvent lastNativeEvent = singleton.nativeEvent; + // Revive the event singleton.revive(); singleton.setNativeEvent(nativeEvent); // Fire the event handlers.fireEvent(singleton); - return !(singleton.isCanceled() && !singleton.isConsumed()); + boolean ret = !(singleton.isCanceled() && !singleton.isConsumed()); + + // Restore the state of the singleton. + singleton.isCanceled = lastIsCanceled; + singleton.isConsumed = lastIsConsumed; + singleton.isFirstHandler = lastIsFirstHandler; + singleton.nativeEvent = lastNativeEvent; + return ret; } return true; } Index: user/test/com/google/gwt/user/client/EventTest.java =================================================================== --- user/test/com/google/gwt/user/client/EventTest.java (revision 6161) +++ user/test/com/google/gwt/user/client/EventTest.java (working copy) @@ -326,6 +326,29 @@ /** * Test that {...@link Event#fireNativePreviewEvent(NativeEvent)} returns the + * correct value even if another event is fired while handling the current + * event. + */ + public void testFireNativePreviewEventWithInterupt() { + NativePreviewHandler handler = new NativePreviewHandler() { + private boolean first = true; + + public void onPreviewNativeEvent(NativePreviewEvent event) { + if (first) { + event.cancel(); + first = false; + assertTrue(Event.fireNativePreviewEvent(null)); + assertTrue(event.isCanceled()); + } + } + }; + HandlerRegistration reg = Event.addNativePreviewHandler(handler); + assertFalse(Event.fireNativePreviewEvent(null)); + reg.removeHandler(); + } + + /** + * Test that {...@link Event#fireNativePreviewEvent(NativeEvent)} returns the * correct value if the native event is not canceled. */ public void testFireNativePreviewEventWithoutCancel() { @@ -524,6 +547,6 @@ } private native boolean isInternetExplorer() /*-{ - return navigator.userAgent.toLowerCase().indexOf("msie") != -1; - }-*/; + return navigator.userAgent.toLowerCase().indexOf("msie") != -1; + }-*/; } --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
