Merging releases/1.6@4366 :4385 into trunk.
svn merge -r4366:4385 https://google-web-toolkit.googlecode.com/svn/releases/1.6 .
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@4386 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
index 6b7d755..3acd448 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/JClassType.java
@@ -27,14 +27,22 @@
HasMetaData {
/**
+ * Cached set of supertypes for this type (including itself). If null,
+ * the set has not been calculated yet.
+ */
+ private Set<JClassType> flattenedSupertypes;
+
+ /**
* Returns all of the superclasses and superinterfaces for a given type
* including the type itself.
*/
protected static Set<JClassType> getFlattenedSuperTypeHierarchy(
JClassType type) {
- Set<JClassType> typesSeen = new HashSet<JClassType>();
- getFlattenedSuperTypeHierarchyRecursive(type, typesSeen);
- return typesSeen;
+ if (type.flattenedSupertypes == null) {
+ type.flattenedSupertypes = new HashSet<JClassType>();
+ getFlattenedSuperTypeHierarchyRecursive(type, type.flattenedSupertypes);
+ }
+ return type.flattenedSupertypes;
}
/**
@@ -309,13 +317,13 @@
// Superclass
JClassType superclass = type.getSuperclass();
if (superclass != null) {
- getFlattenedSuperTypeHierarchyRecursive(superclass, typesSeen);
+ typesSeen.addAll(getFlattenedSuperTypeHierarchy(superclass));
}
// Check the interfaces
JClassType[] intfs = type.getImplementedInterfaces();
for (JClassType intf : intfs) {
- getFlattenedSuperTypeHierarchyRecursive(intf, typesSeen);
+ typesSeen.addAll(getFlattenedSuperTypeHierarchy(intf));
}
}
diff --git a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
index 75e8e2e..424a3ca 100644
--- a/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
+++ b/dev/core/src/com/google/gwt/core/ext/typeinfo/TypeOracle.java
@@ -22,6 +22,7 @@
import java.lang.annotation.Annotation;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@@ -167,7 +168,11 @@
}
}
- private final Set<JRealClassType> allTypes = new HashSet<JRealClassType>();
+ /**
+ * A map of fully-qualify source names (ie, use "." rather than "$" for nested
+ * classes) to JRealClassTypes.
+ */
+ private final Map<String, JRealClassType> allTypes = new HashMap<String, JRealClassType>();
private final Map<JType, JArrayType> arrayTypes = new IdentityHashMap<JType, JArrayType>();
@@ -210,33 +215,16 @@
}
/**
- * Finds a class or interface given its fully-qualified name. For nested
+ * Finds a class or interface given its fully-qualified name.
+ *
+ * @param name fully-qualified class/interface name - for nested
* classes, use its source name rather than its binary name (that is, use a
- * "." rather than a "$").
+ * "." rather than a "$")
*
* @return <code>null</code> if the type is not found
*/
public JClassType findType(String name) {
- // Try the dotted pieces, right to left.
- //
- int i = name.length() - 1;
- while (i >= 0) {
- int dot = name.lastIndexOf('.', i);
- String pkgName = "";
- String typeName = name;
- if (dot != -1) {
- pkgName = name.substring(0, dot);
- typeName = name.substring(dot + 1);
- i = dot - 1;
- } else {
- i = -1;
- }
- JClassType result = findType(pkgName, typeName);
- if (result != null) {
- return result;
- }
- }
- return null;
+ return allTypes.get(name);
}
/**
@@ -482,7 +470,8 @@
* @return an array of types, possibly of zero length
*/
public JClassType[] getTypes() {
- return allTypes.toArray(NO_JCLASSES);
+ Collection<JRealClassType> values = allTypes.values();
+ return values.toArray(new JClassType[values.size()]);
}
public JWildcardType getWildcardType(JWildcardType.BoundType boundType,
@@ -611,7 +600,8 @@
}
void addNewType(JRealClassType newType) {
- allTypes.add(newType);
+ String fqcn = newType.getQualifiedSourceName();
+ allTypes.put(fqcn, newType);
recentTypes.add(newType);
}
@@ -990,9 +980,9 @@
*/
private void removeTypes(Set<JRealClassType> invalidTypes) {
for (Iterator<JRealClassType> iter = invalidTypes.iterator(); iter.hasNext();) {
- JClassType classType = iter.next();
-
- allTypes.remove(classType);
+ JRealClassType classType = iter.next();
+ String fqcn = classType.getQualifiedSourceName();
+ allTypes.remove(fqcn);
JPackage pkg = classType.getPackage();
if (pkg != null) {
diff --git a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
index 666b1e6..6076260 100644
--- a/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
+++ b/dev/core/src/com/google/gwt/dev/resource/impl/ZipFileClassPathEntry.java
@@ -52,6 +52,7 @@
private Set<ZipFileResource> allZipFileResources;
private Set<AbstractResource> cachedAnswers;
+ private String cachedLocation;
private PathPrefixSet lastPrefixSet;
private final ZipFile zipFile;
@@ -80,7 +81,10 @@
@Override
public String getLocation() {
- return new File(zipFile.getName()).toURI().toString();
+ if (cachedLocation == null) {
+ cachedLocation = new File(zipFile.getName()).toURI().toString();
+ }
+ return cachedLocation;
}
public ZipFile getZipFile() {
diff --git a/eclipse/settings/code-style/gwt-checkstyle-tests.xml b/eclipse/settings/code-style/gwt-checkstyle-tests.xml
index ea2aa98..87f66b2 100644
--- a/eclipse/settings/code-style/gwt-checkstyle-tests.xml
+++ b/eclipse/settings/code-style/gwt-checkstyle-tests.xml
@@ -89,7 +89,7 @@
</module>
<module name="RegexpHeader">
<property name="severity" value="error"/>
- <property name="header" value="/\*\n \* Copyright 200[678] Google Inc\.\n \*[ ]*\n \* Licensed under the Apache License, Version 2\.0 \(the "License"\); you may not\n \* use this file except in compliance with the License\. You may obtain a copy of\n \* the License at\n \*[ ]*\n \* http://www\.apache\.org/licenses/LICENSE-2\.0\n \*[ ]*\n \* Unless required by applicable law or agreed to in writing, software\n \* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\n \* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\. See the\n \* License for the specific language governing permissions and limitations under\n \* the License\.\n \*/"/>
+ <property name="header" value="/\*\n \* Copyright 200[6789] Google Inc\.\n \*[ ]*\n \* Licensed under the Apache License, Version 2\.0 \(the "License"\); you may not\n \* use this file except in compliance with the License\. You may obtain a copy of\n \* the License at\n \*[ ]*\n \* http://www\.apache\.org/licenses/LICENSE-2\.0\n \*[ ]*\n \* Unless required by applicable law or agreed to in writing, software\n \* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\n \* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\. See the\n \* License for the specific language governing permissions and limitations under\n \* the License\.\n \*/"/>
</module>
<module name="ImportOrder">
<property name="severity" value="error"/>
diff --git a/eclipse/settings/code-style/gwt-checkstyle.xml b/eclipse/settings/code-style/gwt-checkstyle.xml
index a2c9272..17aa99c 100644
--- a/eclipse/settings/code-style/gwt-checkstyle.xml
+++ b/eclipse/settings/code-style/gwt-checkstyle.xml
@@ -82,7 +82,7 @@
</module>
<module name="RegexpHeader">
<property name="severity" value="error"/>
- <property name="header" value="/\*\n \* Copyright 200[678] Google Inc\.\n \*[ ]*\n \* Licensed under the Apache License, Version 2\.0 \(the "License"\); you may not\n \* use this file except in compliance with the License\. You may obtain a copy of\n \* the License at\n \*[ ]*\n \* http://www\.apache\.org/licenses/LICENSE-2\.0\n \*[ ]*\n \* Unless required by applicable law or agreed to in writing, software\n \* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\n \* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\. See the\n \* License for the specific language governing permissions and limitations under\n \* the License\.\n \*/"/>
+ <property name="header" value="/\*\n \* Copyright 200[6789] Google Inc\.\n \*[ ]*\n \* Licensed under the Apache License, Version 2\.0 \(the "License"\); you may not\n \* use this file except in compliance with the License\. You may obtain a copy of\n \* the License at\n \*[ ]*\n \* http://www\.apache\.org/licenses/LICENSE-2\.0\n \*[ ]*\n \* Unless required by applicable law or agreed to in writing, software\n \* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT\n \* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied\. See the\n \* License for the specific language governing permissions and limitations under\n \* the License\.\n \*/"/>
</module>
<module name="ImportOrder">
<property name="severity" value="error"/>
diff --git a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/Issue1932.java b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/Issue1932.java
index 67b5d33..e51c222 100644
--- a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/Issue1932.java
+++ b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/Issue1932.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -21,8 +21,9 @@
import com.google.gwt.museum.client.common.AbstractIssue;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
-import com.google.gwt.user.client.EventPreview;
import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Grid;
@@ -116,29 +117,29 @@
sandbox.getElement().getStyle().setProperty("cursor", "crosshair");
// Keep the crosshair under the cursor
- DOM.addEventPreview(new EventPreview() {
- public boolean onEventPreview(Event event) {
+ Event.addNativePreviewHandler(new NativePreviewHandler() {
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
// Ignore events outside of the sandbox
- Element target = DOM.eventGetTarget(event);
+ Event nativeEvent = event.getNativeEvent();
+ Element target = nativeEvent.getTarget();
if (!sandbox.getElement().isOrHasChild(target)
&& !positioner.getElement().isOrHasChild(target)) {
positioner.removeFromParent();
- return true;
+ return;
}
- switch (DOM.eventGetType(event)) {
+ switch (nativeEvent.getTypeInt()) {
case Event.ONMOUSEMOVE:
- int absX = event.getClientX() + Window.getScrollLeft();
- int absY = event.getClientY() + Window.getScrollTop();
+ int absX = nativeEvent.getClientX() + Window.getScrollLeft();
+ int absY = nativeEvent.getClientY() + Window.getScrollTop();
RootPanel.get().add(positioner, absX, absY);
- echo.setHTML("event.clientX: " + event.getClientX() + "<br>"
- + "event.clientY: " + event.getClientY() + "<br>"
+ echo.setHTML("event.clientX: " + nativeEvent.getClientX() + "<br>"
+ + "event.clientY: " + nativeEvent.getClientY() + "<br>"
+ "absolute left: " + positioner.getAbsoluteLeft() + "<br>"
+ "absolute top: " + positioner.getAbsoluteTop());
break;
}
- return true;
}
});
diff --git a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDialogBox.java b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDialogBox.java
index 403d7be..40df95a 100644
--- a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDialogBox.java
+++ b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForDialogBox.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -17,13 +17,18 @@
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.ClickEvent;
+import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseDownEvent;
import com.google.gwt.event.dom.client.MouseDownHandler;
import com.google.gwt.museum.client.common.AbstractIssue;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.FlexTable;
+import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
+import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import java.util.HashMap;
@@ -80,12 +85,14 @@
maybeClose = true;
return;
}
+ break;
case Event.ONMOUSEUP:
if (maybeClose && isCloseBoxEvent(event)) {
maybeClose = false;
hide();
return;
}
+ break;
}
maybeClose = false;
super.onBrowserEvent(event);
@@ -149,22 +156,46 @@
@Override
public Widget createIssue() {
+ // Create a few extra dialog boxes
+ final DialogBox dialog0 = showCustomDialog(true, true, false, "Dialog 0",
+ "I cannot be dragged or closed until Dialog 2 is closed", 0, 100);
+ final DialogBox dialog1 = showCustomDialog(true, false, false, "Dialog 1",
+ "I cannot be dragged or closed until Dialog 2 is closed", 0, 200);
+ final DialogBox dialog2 = showCustomDialog(false, false, true, "Dialog 2",
+ "I can be dragged", 0, 300);
+ final DialogBox dialog3 = showCustomDialog(
+ true,
+ false,
+ false,
+ "Dialog 3",
+ "I should auto close as soon as you click outside of me and Dialog 4 or greater",
+ 0, 400);
+ final DialogBox dialog4 = showCustomDialog(false, false, false, "Dialog 4",
+ "I can be dragged", 0, 500);
+
final VisibleDialogBox dialog = showVisibleDialog();
SimplePanel panel = new SimplePanel() {
@Override
protected void onUnload() {
- dialog.hide();
+ if (dialog.isAttached()) {
+ dialog.hide();
+ dialog0.hide();
+ dialog1.hide();
+ dialog2.hide();
+ dialog3.hide();
+ dialog4.hide();
+ }
}
};
-
return panel;
}
@Override
public String getInstructions() {
return "Confirm color change on mouse over caption, that the "
- + "custom close box works, and that each mouse event fires.";
+ + "custom close box works, and that each mouse event fires. "
+ + "Verify that the text in each DialogBox is true.";
}
@Override
@@ -177,6 +208,37 @@
return false;
}
+ private DialogBox showCustomDialog(boolean autoHide,
+ boolean previewAllEvents, boolean modal, String caption, String message,
+ int left, int top) {
+ final DialogBox dialog = new DialogBox(autoHide, modal);
+ dialog.setPreviewingAllNativeEvents(previewAllEvents);
+
+ // Set the caption
+ caption += " (autoHide=" + dialog.isAutoHideEnabled();
+ caption += ", previewAllEvents=" + dialog.isPreviewingAllNativeEvents();
+ caption += ", modal=" + dialog.isModal() + ")";
+ dialog.setText(caption);
+
+ // Set the content
+ Label content = new Label(message);
+ if (autoHide || previewAllEvents) {
+ dialog.setWidget(content);
+ } else {
+ VerticalPanel vPanel = new VerticalPanel();
+ vPanel.add(content);
+ vPanel.add(new Button("Close", new ClickHandler() {
+ public void onClick(ClickEvent event) {
+ dialog.hide();
+ }
+ }));
+ dialog.setWidget(vPanel);
+ }
+ dialog.setPopupPosition(left, top);
+ dialog.show();
+ return dialog;
+ }
+
private VisibleDialogBox showVisibleDialog() {
final VisibleDialogBox dialog = new VisibleDialogBox();
dialog.setModal(false);
diff --git a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForTree.java b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForTree.java
index aadc408..ca8e319 100644
--- a/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForTree.java
+++ b/reference/code-museum/src/com/google/gwt/museum/client/defaultmuseum/VisualsForTree.java
@@ -18,7 +18,9 @@
import com.google.gwt.museum.client.common.AbstractIssue;
import com.google.gwt.user.client.ui.CheckBox;
+import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RadioButton;
+import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Tree;
import com.google.gwt.user.client.ui.TreeItem;
import com.google.gwt.user.client.ui.VerticalPanel;
@@ -41,6 +43,9 @@
TreeItem d = new TreeItem(new RadioButton("myradio",
"I should line up nicely"));
TreeItem e = new TreeItem(new CheckBox("I should line up nicely"));
+ SimplePanel panel = new SimplePanel();
+ panel.setWidget(new Label("There should not be any space above me"));
+ TreeItem f = new TreeItem(panel);
t.setSelectedItem(b);
t.addItem(a);
@@ -48,6 +53,7 @@
t.addItem(c);
t.addItem(d);
t.addItem(e);
+ t.addItem(f);
b.addItem(ba);
b.addItem(bb);
bb.addItem(bba);
diff --git a/user/src/com/google/gwt/event/dom/client/DomEvent.java b/user/src/com/google/gwt/event/dom/client/DomEvent.java
index d751bdf..7e2df65 100644
--- a/user/src/com/google/gwt/event/dom/client/DomEvent.java
+++ b/user/src/com/google/gwt/event/dom/client/DomEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -29,7 +29,8 @@
* @param <H> handler type
*
*/
-public abstract class DomEvent<H extends EventHandler> extends GwtEvent<H> {
+public abstract class DomEvent<H extends EventHandler> extends GwtEvent<H>
+ implements HasNativeEvent {
/**
* Type class used by dom event subclasses. Type is specialized for dom in
* order to carry information about the native event.
@@ -61,10 +62,10 @@
*
*
* @param eventToSink the integer value used by sink events to set up event
- * handling for this dom type
+ * handling for this dom type
* @param eventName the raw native event name
* @param flyweight the instance that will be used as a flyweight to wrap a
- * native event
+ * native event
*/
protected Type(int eventToSink, String eventName, DomEvent<H> flyweight) {
this.flyweight = flyweight;
@@ -100,7 +101,7 @@
}
private static PrivateMap<Type<?>> registered;
-
+
/**
* Fires the given native event on the specified handlers.
*
@@ -122,7 +123,7 @@
}
}
}
-
+
// This method can go away once we have eager clinits.
static void init() {
registered = new PrivateMap<Type<?>>();
@@ -130,11 +131,6 @@
private Event nativeEvent;
- /**
- * Gets the underlying native event for this {@link DomEvent}.
- *
- * @return gets the native event
- */
public final Event getNativeEvent() {
assertLive();
return nativeEvent;
diff --git a/user/src/com/google/gwt/event/dom/client/HasNativeEvent.java b/user/src/com/google/gwt/event/dom/client/HasNativeEvent.java
new file mode 100644
index 0000000..510c273
--- /dev/null
+++ b/user/src/com/google/gwt/event/dom/client/HasNativeEvent.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+package com.google.gwt.event.dom.client;
+
+import com.google.gwt.user.client.Event;
+
+/**
+ * An object that implements this interface has a native event associated with
+ * it.
+ */
+public interface HasNativeEvent {
+ /**
+ * Gets the underlying native event.
+ *
+ * @return the native event
+ */
+ Event getNativeEvent();
+}
diff --git a/user/src/com/google/gwt/event/shared/GwtEvent.java b/user/src/com/google/gwt/event/shared/GwtEvent.java
index 8eaba34..33787e2 100644
--- a/user/src/com/google/gwt/event/shared/GwtEvent.java
+++ b/user/src/com/google/gwt/event/shared/GwtEvent.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -137,18 +137,19 @@
}
/**
- * Revives the event. Used when recycling event instances.
+ * Kill the event. After the event has been killed, users cannot really on
+ * its values or functions being available.
*/
- protected void revive() {
- dead = false;
+ protected void kill() {
+ dead = true;
source = null;
}
/**
- * Called after the event manager has finished processing the event.
+ * Revives the event. Used when recycling event instances.
*/
- void onRelease() {
- dead = true;
+ protected void revive() {
+ dead = false;
source = null;
}
diff --git a/user/src/com/google/gwt/event/shared/HandlerManager.java b/user/src/com/google/gwt/event/shared/HandlerManager.java
index 898ad91..ca4138e 100644
--- a/user/src/com/google/gwt/event/shared/HandlerManager.java
+++ b/user/src/com/google/gwt/event/shared/HandlerManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -378,7 +378,7 @@
}
if (oldSource == null) {
// This was my event, so I should kill it now that I'm done.
- event.onRelease();
+ event.kill();
} else {
// Restoring the source for the next handler to use.
event.setSource(oldSource);
diff --git a/user/src/com/google/gwt/user/client/DOM.java b/user/src/com/google/gwt/user/client/DOM.java
index b7865d5..8ddd25b 100644
--- a/user/src/com/google/gwt/user/client/DOM.java
+++ b/user/src/com/google/gwt/user/client/DOM.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -39,6 +39,7 @@
private static Element sCaptureElem;
// <BrowserEventPreview>
+ @SuppressWarnings("deprecation")
private static ArrayList<EventPreview> sEventPreviewStack;
/**
@@ -49,7 +50,10 @@
* handlers only receive explicitly sunk events.
*
* @param preview the event preview to be added to the stack.
+ * @deprecated replaced by
+ * {@link Event#addNativePreviewHandler(Event.NativePreviewHandler)}
*/
+ @Deprecated
public static void addEventPreview(EventPreview preview) {
impl.maybeInitializeEventSystem();
@@ -90,6 +94,7 @@
* @return <code>true</code> if they are in fact the same element
* @deprecated Use identity comparison.
*/
+ @Deprecated
public static boolean compare(Element elem1, Element elem2) {
return elem1 == elem2;
}
@@ -376,8 +381,7 @@
}
/**
- * Generates a unique DOM id. The id is of the form "gwt-id-<unique
- * integer>".
+ * Generates a unique DOM id. The id is of the form "gwt-id-<unique integer>".
*
* @return a unique DOM id
*/
@@ -934,8 +938,8 @@
* <code><option></code>; cannot be <code>null</code>
* @param index the index at which to insert the child
*/
- public static void insertListItem(Element selectElem, String item, String value,
- int index) {
+ public static void insertListItem(Element selectElem, String item,
+ String value, int index) {
SelectElement select = selectElem.<SelectElement> cast();
OptionElement option = Document.get().createOptionElement();
option.setText(item);
@@ -999,7 +1003,11 @@
* capture events, though any preview underneath it will begin to do so.
*
* @param preview the event preview to be removed from the stack
+ * @deprecated use {@link com.google.gwt.event.shared.HandlerRegistration}
+ * returned from
+ * {@link Event#addNativePreviewHandler(Event.NativePreviewHandler)}
*/
+ @Deprecated
public static void removeEventPreview(EventPreview preview) {
// Remove the event preview from the stack. If it was on top,
// any preview underneath it will automatically begin to
@@ -1265,17 +1273,22 @@
* @param evt a handle to the event being previewed
* @return <code>false</code> to cancel the event
*/
+ @SuppressWarnings("deprecation")
static boolean previewEvent(Event evt) {
+ // Fire a NativePreviewEvent to NativePreviewHandlers
+ boolean ret = Event.fireNativePreviewEvent(evt);
+
// If event previews are present, redirect events to the topmost of them.
- boolean ret = true;
if (sEventPreviewStack != null && sEventPreviewStack.size() > 0) {
EventPreview preview = sEventPreviewStack.get(sEventPreviewStack.size() - 1);
- if (!(ret = preview.onEventPreview(evt))) {
- // If the preview cancels the event, stop it from bubbling and
- // performing its default action.
- eventCancelBubble(evt, true);
- eventPreventDefault(evt);
- }
+ ret = preview.onEventPreview(evt) && ret;
+ }
+
+ // If the preview cancels the event, stop it from bubbling and performing
+ // its default action. Check for a null evt to allow unit tests to run.
+ if (!ret && evt != null) {
+ eventCancelBubble(evt, true);
+ eventPreventDefault(evt);
}
return ret;
diff --git a/user/src/com/google/gwt/user/client/Event.java b/user/src/com/google/gwt/user/client/Event.java
index f4dccd6..4ec22fe 100644
--- a/user/src/com/google/gwt/user/client/Event.java
+++ b/user/src/com/google/gwt/user/client/Event.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -17,6 +17,13 @@
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
+import com.google.gwt.event.dom.client.HasNativeEvent;
+import com.google.gwt.event.shared.EventHandler;
+import com.google.gwt.event.shared.GwtEvent;
+import com.google.gwt.event.shared.HandlerRegistration;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* <p>
@@ -42,6 +49,166 @@
* </p>
*/
public class Event extends JavaScriptObject {
+ /**
+ * Represents a preview of a native {@link Event}.
+ */
+ public static class NativePreviewEvent extends GwtEvent<NativePreviewHandler>
+ implements HasNativeEvent {
+
+ /**
+ * Handler type.
+ */
+ private static Type<NativePreviewHandler> TYPE;
+
+ /**
+ * The singleton instance of {@link NativePreviewEvent}.
+ */
+ private static NativePreviewEvent singleton;
+
+ /**
+ * Gets the type associated with this event.
+ *
+ * @return returns the handler type
+ */
+ public static Type<NativePreviewHandler> getType() {
+ if (TYPE == null) {
+ TYPE = new Type<NativePreviewHandler>();
+ }
+ return TYPE;
+ }
+
+ /**
+ * Fire a {@link NativePreviewEvent} for the native event.
+ *
+ * @param handlers the list of {@link NativePreviewHandler}
+ * @param nativeEvent the native event
+ * @return true to fire the event normally, false to cancel the event
+ */
+ static boolean fire(List<NativePreviewHandler> handlers, Event nativeEvent) {
+ if (TYPE != null && handlers != null) {
+ // Revive the event
+ if (singleton == null) {
+ singleton = new NativePreviewEvent();
+ } else {
+ singleton.revive();
+ }
+ singleton.setNativeEvent(nativeEvent);
+
+ // Fire the event to all handlers
+ int numHandlers = handlers.size();
+ for (int i = numHandlers - 1; i >= 0; i--) {
+ handlers.get(i).onPreviewNativeEvent(singleton);
+ }
+
+ // Kill the event and return
+ singleton.kill();
+ return !(singleton.isCanceled() && !singleton.isConsumed());
+ }
+ return true;
+ }
+
+ /**
+ * A boolean indicating that the native event should be canceled.
+ */
+ private boolean isCanceled = false;
+
+ /**
+ * A boolean indicating whether or not canceling the native event should be
+ * prevented. This supercedes {@link #isCanceled}.
+ */
+ private boolean isConsumed = false;
+
+ /**
+ * The event being previewed.
+ */
+ private Event nativeEvent;
+
+ /**
+ * Cancel the native event and prevent it from firing. Note that the event
+ * can still fire if another handler calls {@link #consume()}.
+ *
+ * Classes overriding this method should still call super.cancel().
+ */
+ public void cancel() {
+ isCanceled = true;
+ }
+
+ /**
+ * Consume the native event and prevent it from being canceled, even if it
+ * has already been canceled by another handler.
+ * {@link NativePreviewHandler} that fire first have priority over later
+ * handlers, so all handlers should check if the event has already been
+ * canceled before calling this method.
+ */
+ public void consume() {
+ isConsumed = true;
+ }
+
+ public Event getNativeEvent() {
+ return nativeEvent;
+ }
+
+ /**
+ * Has the event already been canceled? Note that {@link #isConsumed()} will
+ * still return true if the native event has also been consumed.
+ *
+ * @return true if the event has been canceled
+ * @see #cancel()
+ */
+ public boolean isCanceled() {
+ return isCanceled;
+ }
+
+ /**
+ * Has the native event been consumed? Note that {@link #isCanceled()} will
+ * still return true if the native event has also been canceled.
+ *
+ * @return true if the event has been consumed
+ * @see #consume()
+ */
+ public boolean isConsumed() {
+ return isConsumed;
+ }
+
+ @Override
+ protected void dispatch(NativePreviewHandler handler) {
+ handler.onPreviewNativeEvent(this);
+ }
+
+ @Override
+ protected Type<NativePreviewHandler> getAssociatedType() {
+ return TYPE;
+ }
+
+ @Override
+ protected void revive() {
+ super.revive();
+ isCanceled = false;
+ isConsumed = false;
+ nativeEvent = null;
+ }
+
+ /**
+ * Set the native event.
+ *
+ * @param nativeEvent the native {@link Event} being previewed.
+ */
+ private void setNativeEvent(Event nativeEvent) {
+ this.nativeEvent = nativeEvent;
+ }
+ }
+
+ /**
+ * Handler interface for {@link NativePreviewEvent} events.
+ */
+ public static interface NativePreviewHandler extends EventHandler {
+ /**
+ * Called when {@link NativePreviewEvent} is fired.
+ *
+ * @param event the {@link NativePreviewEvent} that was fired
+ */
+ void onPreviewNativeEvent(NativePreviewEvent event);
+ }
/**
* The left mouse button (used in {@link DOM#eventGetButton(Event)}).
@@ -184,6 +351,14 @@
public static final int UNDEFINED = 0;
/**
+ * The list of {@link NativePreviewHandler}. We use a list instead of a
+ * handler manager for efficiency and because we want to fire the handlers in
+ * reverse order. When the last handler is removed, handlers is reset to
+ * null.
+ */
+ private static ArrayList<NativePreviewHandler> handlers;
+
+ /**
* Adds an event preview to the preview stack. As long as this preview remains
* on the top of the stack, it will receive all events before they are fired
* to their listeners. Note that the event preview will receive <u>all </u>
@@ -191,12 +366,54 @@
* handlers only receive explicitly sunk events.
*
* @param preview the event preview to be added to the stack.
+ * @deprecated replaced by
+ * {@link #addNativePreviewHandler(NativePreviewHandler)}
*/
+ @Deprecated
public static void addEventPreview(EventPreview preview) {
DOM.addEventPreview(preview);
}
/**
+ * <p>
+ * Adds a {@link NativePreviewHandler} that will receive all events before
+ * they are fired to their handlers. Note that the handler will receive
+ * <u>all</u> native events, including those received due to bubbling, whereas
+ * normal event handlers only receive explicitly sunk events.
+ * </p>
+ *
+ * <p>
+ * Unlike other event handlers, {@link NativePreviewHandler} are fired in the
+ * reverse order that they are added, such that the last
+ * {@link NativePreviewEvent} that was added is the first to be fired.
+ * </p>
+ *
+ * @param handler the {@link NativePreviewHandler}
+ * @return {@link HandlerRegistration} used to remove this handler
+ */
+ public static HandlerRegistration addNativePreviewHandler(
+ final NativePreviewHandler handler) {
+ assert handler != null : "Cannot add a null handler";
+ // Initialize the type
+ NativePreviewEvent.getType();
+ if (handlers == null) {
+ handlers = new ArrayList<NativePreviewHandler>();
+ }
+ handlers.add(handler);
+ return new HandlerRegistration() {
+ public void removeHandler() {
+ if (handlers != null) {
+ handlers.remove(handler);
+ if (handlers.size() == 0) {
+ // Set handlers to null so we can optimize fireNativePreviewEvent
+ handlers = null;
+ }
+ }
+ }
+ };
+ }
+
+ /**
* Gets the current event that is being fired. The current event is only
* available within the lifetime of the onBrowserEvent function. Once the
* onBrowserEvent method returns, the current event is reset to null.
@@ -234,7 +451,10 @@
* capture events, though any preview underneath it will begin to do so.
*
* @param preview the event preview to be removed from the stack
+ * @deprecated use {@link HandlerRegistration} returned from
+ * {@link Event#addNativePreviewHandler(NativePreviewHandler)}
*/
+ @Deprecated
public static void removeEventPreview(EventPreview preview) {
DOM.removeEventPreview(preview);
}
@@ -263,6 +483,16 @@
}
/**
+ * Fire a {@link NativePreviewEvent} for the native event.
+ *
+ * @param nativeEvent the native event
+ * @return true to fire the event normally, false to cancel the event
+ */
+ static boolean fireNativePreviewEvent(Event nativeEvent) {
+ return NativePreviewEvent.fire(handlers, nativeEvent);
+ }
+
+ /**
* Not directly instantiable. Subclasses should also define a protected no-arg
* constructor to prevent client code from directly instantiating the class.
*/
@@ -355,7 +585,7 @@
* </p>
*
* @return the Unicode character or key code.
- * @see com.google.gwt.user.client.ui.KeyboardListener
+ * @see com.google.gwt.event.dom.client.KeyCodes
*/
public final int getKeyCode() {
return DOM.eventGetKeyCode(this);
diff --git a/user/src/com/google/gwt/user/client/EventPreview.java b/user/src/com/google/gwt/user/client/EventPreview.java
index 3b2503d..a419256 100644
--- a/user/src/com/google/gwt/user/client/EventPreview.java
+++ b/user/src/com/google/gwt/user/client/EventPreview.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -19,7 +19,10 @@
* A listener interface for previewing browser events.
*
* @see com.google.gwt.user.client.DOM#addEventPreview(EventPreview)
+ * @deprecated replaced by
+ * {@link com.google.gwt.user.client.Event.NativePreviewHandler}
*/
+@Deprecated
public interface EventPreview {
/**
@@ -29,6 +32,9 @@
* @param event the browser event
* @return <code>false</code> to cancel the event
* @see DOM#addEventPreview(EventPreview)
+ * @deprecated replaced by
+ * {@link com.google.gwt.user.client.Event.NativePreviewHandler#onPreviewNativeEvent(com.google.gwt.user.client.Event.NativePreviewEvent)}
*/
+ @Deprecated
boolean onEventPreview(Event event);
}
diff --git a/user/src/com/google/gwt/user/client/ui/ChangeListener.java b/user/src/com/google/gwt/user/client/ui/ChangeListener.java
index 29e1bc4..cf75a46 100644
--- a/user/src/com/google/gwt/user/client/ui/ChangeListener.java
+++ b/user/src/com/google/gwt/user/client/ui/ChangeListener.java
@@ -19,6 +19,8 @@
/**
* Event listener interface for 'change' events.
+ *
+ * @deprecated use {@link com.google.gwt.event.dom.client.ChangeHandler} instead
*/
@Deprecated
public interface ChangeListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/ChangeListenerCollection.java b/user/src/com/google/gwt/user/client/ui/ChangeListenerCollection.java
index 12ce182..ea4ca5a 100644
--- a/user/src/com/google/gwt/user/client/ui/ChangeListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/ChangeListenerCollection.java
@@ -21,6 +21,9 @@
* A helper class for implementers of the SourcesChangeEvents interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.ChangeListener}.
+ *
+ * @deprecated use <code>addDomHandler(myHandler, ChangeEvent.getType())</code>
+ * instead to manage handlers for your widget
*/
@Deprecated
public class ChangeListenerCollection extends ArrayList<ChangeListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/ClickListener.java b/user/src/com/google/gwt/user/client/ui/ClickListener.java
index 4c34bb6..cf998cc 100644
--- a/user/src/com/google/gwt/user/client/ui/ClickListener.java
+++ b/user/src/com/google/gwt/user/client/ui/ClickListener.java
@@ -19,6 +19,7 @@
/**
* Event listener interface for click events.
+ * @deprecated use {@link com.google.gwt.event.dom.client.ClickHandler} instead
*/
@Deprecated
public interface ClickListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/ClickListenerCollection.java b/user/src/com/google/gwt/user/client/ui/ClickListenerCollection.java
index 3f150ff..9d13313 100644
--- a/user/src/com/google/gwt/user/client/ui/ClickListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/ClickListenerCollection.java
@@ -21,6 +21,9 @@
* A helper class for implementers of the SourcesClickEvents interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.ClickListener}.
+ *
+ * @deprecated use <code>addDomHandler(myHandler, ClickEvent.getType())</code>
+ * to manage handlers for your widget instead
*/
@Deprecated
public class ClickListenerCollection extends ArrayList<ClickListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/Composite.java b/user/src/com/google/gwt/user/client/ui/Composite.java
index 1bb5a3e..c7ed3bd 100644
--- a/user/src/com/google/gwt/user/client/ui/Composite.java
+++ b/user/src/com/google/gwt/user/client/ui/Composite.java
@@ -47,6 +47,9 @@
@Override
public void onBrowserEvent(Event event) {
+ // Fire any handler added to the composite itself.
+ super.onBrowserEvent(event);
+
// Delegate events to the widget.
widget.onBrowserEvent(event);
}
diff --git a/user/src/com/google/gwt/user/client/ui/DialogBox.java b/user/src/com/google/gwt/user/client/ui/DialogBox.java
index f4b328e..e1d3e34 100644
--- a/user/src/com/google/gwt/user/client/ui/DialogBox.java
+++ b/user/src/com/google/gwt/user/client/ui/DialogBox.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -34,6 +34,7 @@
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
/**
* A form of popup that has a caption area at the top and can be dragged by the
@@ -229,18 +230,6 @@
super.onBrowserEvent(event);
}
- @Override
- public boolean onEventPreview(Event event) {
- // We need to preventDefault() on mouseDown events (outside of the
- // DialogBox content) to keep text from being selected when it
- // is dragged.
- if (DOM.eventGetType(event) == Event.ONMOUSEDOWN && isCaptionEvent(event)) {
- DOM.eventPreventDefault(event);
- }
-
- return super.onEventPreview(event);
- }
-
/**
* @deprecated Use {@link #beginDragging} instead and {@link #getCaption}
* instead
@@ -401,6 +390,20 @@
ensureDebugId(getCellElement(1, 1), baseID, "content");
}
+ @Override
+ protected void onPreviewNativeEvent(NativePreviewEvent event) {
+ // We need to preventDefault() on mouseDown events (outside of the
+ // DialogBox content) to keep text from being selected when it
+ // is dragged.
+ Event nativeEvent = event.getNativeEvent();
+ if (!event.isCanceled() && nativeEvent.getTypeInt() == Event.ONMOUSEDOWN
+ && isCaptionEvent(nativeEvent)) {
+ nativeEvent.preventDefault();
+ }
+
+ super.onPreviewNativeEvent(event);
+ }
+
private boolean isCaptionEvent(Event event) {
return getCellElement(0, 1).getParentElement().isOrHasChild(
event.getTarget());
diff --git a/user/src/com/google/gwt/user/client/ui/DisclosureHandler.java b/user/src/com/google/gwt/user/client/ui/DisclosureHandler.java
index 5d09bd0..dd283e5 100644
--- a/user/src/com/google/gwt/user/client/ui/DisclosureHandler.java
+++ b/user/src/com/google/gwt/user/client/ui/DisclosureHandler.java
@@ -14,12 +14,14 @@
* the License.
*/
package com.google.gwt.user.client.ui;
-
+
import java.util.EventListener;
/**
* Event handler interface for {@link DisclosureEvent}.
*
+ * @deprecated use {@link com.google.gwt.event.logical.shared.CloseHandler}
+ * and/or {@link com.google.gwt.event.logical.shared.OpenHandler} instead
* @see DisclosurePanel
*/
@Deprecated
@@ -39,4 +41,4 @@
*/
@Deprecated
void onOpen(DisclosureEvent event);
-}
\ No newline at end of file
+}
diff --git a/user/src/com/google/gwt/user/client/ui/FocusListener.java b/user/src/com/google/gwt/user/client/ui/FocusListener.java
index e89ceed..23b707d 100644
--- a/user/src/com/google/gwt/user/client/ui/FocusListener.java
+++ b/user/src/com/google/gwt/user/client/ui/FocusListener.java
@@ -19,6 +19,9 @@
/**
* Event listener for focus events.
+ *
+ * @deprecated use {@link com.google.gwt.event.dom.client.FocusHandler} and/or
+ * {@link com.google.gwt.event.dom.client.BlurHandler} instead
*/
@Deprecated
public interface FocusListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/FocusListenerAdapter.java b/user/src/com/google/gwt/user/client/ui/FocusListenerAdapter.java
index 121269c..c72d948 100644
--- a/user/src/com/google/gwt/user/client/ui/FocusListenerAdapter.java
+++ b/user/src/com/google/gwt/user/client/ui/FocusListenerAdapter.java
@@ -18,6 +18,9 @@
/**
* An adapter to simplify focus event listeners that do not need all events
* defined on the FocusListener interface.
+ *
+ * @deprecated use {@link com.google.gwt.event.dom.client.FocusHandler} and
+ * {@link com.google.gwt.event.dom.client.BlurHandler} instead
*/
@Deprecated
public abstract class FocusListenerAdapter implements FocusListener {
diff --git a/user/src/com/google/gwt/user/client/ui/FocusListenerCollection.java b/user/src/com/google/gwt/user/client/ui/FocusListenerCollection.java
index cfa0409..b2981aa 100644
--- a/user/src/com/google/gwt/user/client/ui/FocusListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/FocusListenerCollection.java
@@ -24,7 +24,11 @@
* A helper class for implementers of the
* {@link com.google.gwt.user.client.ui.SourcesFocusEvents} interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
- * type {@link com.google.gwt.user.client.ui.FocusListener}.
+ * type {@link com.google.gwt.user.client.ui.FocusListener}
+ *
+ * @deprecated use <code>addDomHandler(myHandler, FocusEvent.getType())</code>
+ * and <code>addDomHandler(myHandler, BlurEvent.getType())</code>
+ * to manage your widget's handlers instead
*/
@Deprecated
public class FocusListenerCollection extends ArrayList<FocusListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/FormHandler.java b/user/src/com/google/gwt/user/client/ui/FormHandler.java
index 4c5faec..f4f8ab8 100644
--- a/user/src/com/google/gwt/user/client/ui/FormHandler.java
+++ b/user/src/com/google/gwt/user/client/ui/FormHandler.java
@@ -19,6 +19,7 @@
/**
* Handler interface for form submit events.
+ * @deprecated use {@link FormPanel.SubmitCompleteHandler} and/or {@link FormPanel.SubmitHandler} instead
*/
@Deprecated
public interface FormHandler extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/FormHandlerCollection.java b/user/src/com/google/gwt/user/client/ui/FormHandlerCollection.java
index ecb31b8..66c6a4c 100644
--- a/user/src/com/google/gwt/user/client/ui/FormHandlerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/FormHandlerCollection.java
@@ -22,6 +22,8 @@
* {@link com.google.gwt.user.client.ui.FormHandler FormHandlers}. This
* subclass of ArrayList assumes that all items added to it will be of type
* {@link com.google.gwt.user.client.ui.FormHandler}.
+ *
+ * @deprecated {@link FormPanel} now handles all handler management internally
*/
@Deprecated
public class FormHandlerCollection extends ArrayList<FormHandler> {
diff --git a/user/src/com/google/gwt/user/client/ui/Hyperlink.java b/user/src/com/google/gwt/user/client/ui/Hyperlink.java
index c4ceead..7bb6109 100644
--- a/user/src/com/google/gwt/user/client/ui/Hyperlink.java
+++ b/user/src/com/google/gwt/user/client/ui/Hyperlink.java
@@ -138,13 +138,10 @@
@Override
public void onBrowserEvent(Event event) {
- if (DOM.eventGetType(event) == Event.ONCLICK) {
- super.onBrowserEvent(event);
-
- if (impl.handleAsClick(event)) {
- History.newItem(getTargetHistoryToken());
- DOM.eventPreventDefault(event);
- }
+ super.onBrowserEvent(event);
+ if (DOM.eventGetType(event) == Event.ONCLICK && impl.handleAsClick(event)) {
+ History.newItem(getTargetHistoryToken());
+ DOM.eventPreventDefault(event);
}
}
diff --git a/user/src/com/google/gwt/user/client/ui/KeyboardListener.java b/user/src/com/google/gwt/user/client/ui/KeyboardListener.java
index 2680f96..e0a90d1 100644
--- a/user/src/com/google/gwt/user/client/ui/KeyboardListener.java
+++ b/user/src/com/google/gwt/user/client/ui/KeyboardListener.java
@@ -19,6 +19,9 @@
/**
* Event listener interface for keyboard events.
+ *
+ * @deprecated use {@link com.google.gwt.event.dom.client.KeyDownHandler}, {@link com.google.gwt.event.dom.client.KeyUpHandler} and/or {@link com.google.gwt.event.dom.client.KeyPressHandler}
+ * instead
*/
@Deprecated
public interface KeyboardListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/KeyboardListenerAdapter.java b/user/src/com/google/gwt/user/client/ui/KeyboardListenerAdapter.java
index 1a2d6b1..52cc564 100644
--- a/user/src/com/google/gwt/user/client/ui/KeyboardListenerAdapter.java
+++ b/user/src/com/google/gwt/user/client/ui/KeyboardListenerAdapter.java
@@ -18,6 +18,10 @@
/**
* An adapter to simplify keyboard event listeners that do not need all events
* defined on the KeyboardListener interface.
+ *
+ * @deprecated use {@link com.google.gwt.event.dom.client.KeyDownHandler},
+ * {@link com.google.gwt.event.dom.client.KeyUpHandler} and/or
+ * {@link com.google.gwt.event.dom.client.KeyPressHandler} instead
*/
@Deprecated
public class KeyboardListenerAdapter implements KeyboardListener {
diff --git a/user/src/com/google/gwt/user/client/ui/KeyboardListenerCollection.java b/user/src/com/google/gwt/user/client/ui/KeyboardListenerCollection.java
index 74a1945..315913a 100644
--- a/user/src/com/google/gwt/user/client/ui/KeyboardListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/KeyboardListenerCollection.java
@@ -24,6 +24,10 @@
* A helper class for implementers of the SourcesKeyboardEvents interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.KeyboardListener}.
+ *
+ * @deprecated use
+ * <code>addDomHandler(myHandler, Key(Down/Up/Press)Event.getType())</code>
+ * to manage handlers within your widget
*/
@Deprecated
public class KeyboardListenerCollection extends ArrayList<KeyboardListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/LoadListener.java b/user/src/com/google/gwt/user/client/ui/LoadListener.java
index 149259c..fed7374 100644
--- a/user/src/com/google/gwt/user/client/ui/LoadListener.java
+++ b/user/src/com/google/gwt/user/client/ui/LoadListener.java
@@ -19,6 +19,10 @@
/**
* Event listener interface for 'load' events.
+ *
+ * @deprecated use {@link com.google.gwt.event.dom.client.LoadHandler}
+ * and/or {@link com.google.gwt.event.dom.client.ErrorHandler}
+ * instead
*/
@Deprecated
public interface LoadListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/LoadListenerCollection.java b/user/src/com/google/gwt/user/client/ui/LoadListenerCollection.java
index ffebb8c..e39b182 100644
--- a/user/src/com/google/gwt/user/client/ui/LoadListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/LoadListenerCollection.java
@@ -21,6 +21,10 @@
* A helper class for implementers of the SourcesLoadEvents interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.LoadListener}.
+ *
+ * @deprecated use
+ * <code>addDomHandler(myHandler, (Load/Error)Event.getType())</code>
+ * to manage handlers within your widget instead
*/
@Deprecated
public class LoadListenerCollection extends ArrayList<LoadListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/MenuBar.java b/user/src/com/google/gwt/user/client/ui/MenuBar.java
index 04dc6b3..a8b00b6 100644
--- a/user/src/com/google/gwt/user/client/ui/MenuBar.java
+++ b/user/src/com/google/gwt/user/client/ui/MenuBar.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -27,6 +27,7 @@
import com.google.gwt.user.client.DeferredCommand;
import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
import com.google.gwt.user.client.ui.PopupPanel.AnimationType;
import java.util.ArrayList;
@@ -395,8 +396,6 @@
@Override
public void onBrowserEvent(Event event) {
- super.onBrowserEvent(event);
-
MenuItem item = findItem(DOM.eventGetTarget(event));
switch (DOM.eventGetType(event)) {
case Event.ONCLICK: {
@@ -469,6 +468,7 @@
break;
} // end case Event.ONKEYDOWN
} // end switch (DOM.eventGetType(event))
+ super.onBrowserEvent(event);
}
/**
@@ -959,29 +959,34 @@
popup = new DecoratedPopupPanel(true, false, "menuPopup") {
{
setWidget(item.getSubMenu());
+ setPreviewingAllNativeEvents(true);
item.getSubMenu().onShow();
}
@Override
- public boolean onEventPreview(Event event) {
+ protected void onPreviewNativeEvent(NativePreviewEvent event) {
// Hook the popup panel's event preview. We use this to keep it from
// auto-hiding when the parent menu is clicked.
- switch (DOM.eventGetType(event)) {
- case Event.ONMOUSEDOWN:
- // If the event target is part of the parent menu, suppress the
- // event altogether.
- Element target = DOM.eventGetTarget(event);
- Element parentMenuElement = item.getParentMenu().getElement();
- if (DOM.isOrHasChild(parentMenuElement, target)) {
- return false;
- }
- boolean cancel = super.onEventPreview(event);
- if (cancel) {
- selectItem(null);
- }
- return cancel;
+ if (!event.isCanceled()) {
+ Event nativeEvent = event.getNativeEvent();
+ switch (nativeEvent.getTypeInt()) {
+ case Event.ONMOUSEDOWN:
+ // If the event target is part of the parent menu, suppress the
+ // event altogether.
+ com.google.gwt.dom.client.Element target = nativeEvent.getTarget();
+ Element parentMenuElement = item.getParentMenu().getElement();
+ if (parentMenuElement.isOrHasChild(target)) {
+ event.cancel();
+ return;
+ }
+ super.onPreviewNativeEvent(event);
+ if (event.isCanceled()) {
+ selectItem(null);
+ }
+ return;
+ }
}
- return super.onEventPreview(event);
+ super.onPreviewNativeEvent(event);
}
};
popup.setAnimationType(AnimationType.ONE_WAY_CORNER);
diff --git a/user/src/com/google/gwt/user/client/ui/MouseListener.java b/user/src/com/google/gwt/user/client/ui/MouseListener.java
index 9c250b2..f80c5c8 100644
--- a/user/src/com/google/gwt/user/client/ui/MouseListener.java
+++ b/user/src/com/google/gwt/user/client/ui/MouseListener.java
@@ -19,6 +19,13 @@
/**
* Event listener interface for mouse events.
+ *
+ * @deprecated use
+ * {@link com.google.gwt.event.dom.client.MouseDownHandler},
+ * {@link com.google.gwt.event.dom.client.MouseUpHandler},
+ * {@link com.google.gwt.event.dom.client.MouseOverHandler},
+ * {@link com.google.gwt.event.dom.client.MouseMoveHandler}, and/or
+ * {@link com.google.gwt.event.dom.client.MouseOutHandler} instead
*/
@Deprecated
public interface MouseListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/MouseListenerAdapter.java b/user/src/com/google/gwt/user/client/ui/MouseListenerAdapter.java
index bceee83..10b5018 100644
--- a/user/src/com/google/gwt/user/client/ui/MouseListenerAdapter.java
+++ b/user/src/com/google/gwt/user/client/ui/MouseListenerAdapter.java
@@ -18,6 +18,13 @@
/**
* An adapter to simplify mouse event listeners that do not need all events
* defined on the MouseListener interface.
+ *
+ * @deprecated use
+ * {@link com.google.gwt.event.dom.client.MouseDownHandler},
+ * {@link com.google.gwt.event.dom.client.MouseUpHandler},
+ * {@link com.google.gwt.event.dom.client.MouseOverHandler},
+ * {@link com.google.gwt.event.dom.client.MouseMoveHandler}, and/or
+ * {@link com.google.gwt.event.dom.client.MouseOutHandler} instead
*/
@Deprecated
public class MouseListenerAdapter implements MouseListener {
diff --git a/user/src/com/google/gwt/user/client/ui/MouseListenerCollection.java b/user/src/com/google/gwt/user/client/ui/MouseListenerCollection.java
index 9d201b9..08c1336 100644
--- a/user/src/com/google/gwt/user/client/ui/MouseListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/MouseListenerCollection.java
@@ -26,6 +26,10 @@
* A helper class for implementers of the SourcesMouseEvents interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.MouseListener}.
+ *
+ * @deprecated use
+ * <code>addDomHandler(myHandler, Mouse(Down/Up/Move/Over/Out)Event.getType())</code>
+ * to manage handlers within your widget
*/
@Deprecated
public class MouseListenerCollection extends ArrayList<MouseListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/MouseWheelListener.java b/user/src/com/google/gwt/user/client/ui/MouseWheelListener.java
index a74b3cc..b60bd93 100644
--- a/user/src/com/google/gwt/user/client/ui/MouseWheelListener.java
+++ b/user/src/com/google/gwt/user/client/ui/MouseWheelListener.java
@@ -19,6 +19,10 @@
/**
* Event listener interface for mouse wheel events.
+ *
+ * @deprecated use
+ * {@link com.google.gwt.event.dom.client.MouseWheelHandler} instead
+ *
*/
@Deprecated
public interface MouseWheelListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/MouseWheelListenerCollection.java b/user/src/com/google/gwt/user/client/ui/MouseWheelListenerCollection.java
index 6bf8be5..16d10a1 100644
--- a/user/src/com/google/gwt/user/client/ui/MouseWheelListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/MouseWheelListenerCollection.java
@@ -24,6 +24,10 @@
* A helper class for implementers of the SourcesMouseWheelEvents interface.
* This subclass of {@link ArrayList} assumes that all objects added to it will
* be of type {@link com.google.gwt.user.client.ui.MouseWheelListener}.
+ *
+ * @deprecated use
+ * <code>addDomHandler(myHandler, MouseWheelEvent.getType())</code>
+ * to manage handlers within your widget
*/
@Deprecated
public class MouseWheelListenerCollection extends ArrayList<MouseWheelListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/PopupListener.java b/user/src/com/google/gwt/user/client/ui/PopupListener.java
index bcae3c1..98cef26 100644
--- a/user/src/com/google/gwt/user/client/ui/PopupListener.java
+++ b/user/src/com/google/gwt/user/client/ui/PopupListener.java
@@ -19,6 +19,9 @@
/**
* Event listener interface for popup events.
+ *
+ * @deprecated use
+ * {@link com.google.gwt.event.logical.shared.CloseHandler} instead
*/
@Deprecated
public interface PopupListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/PopupListenerCollection.java b/user/src/com/google/gwt/user/client/ui/PopupListenerCollection.java
index b17e1b6..0c18403 100644
--- a/user/src/com/google/gwt/user/client/ui/PopupListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/PopupListenerCollection.java
@@ -21,6 +21,8 @@
* A helper class for implementers of the SourcesPopupEvents interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.PopupListener}.
+ * @deprecated use <code>addHandler(myHandler, CloseEvent.getType())</code>
+ * to manage handlers within your widget instead
*/
@Deprecated
public class PopupListenerCollection extends ArrayList<PopupListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/PopupPanel.java b/user/src/com/google/gwt/user/client/ui/PopupPanel.java
index 8cfeeba..105b3be 100644
--- a/user/src/com/google/gwt/user/client/ui/PopupPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/PopupPanel.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -18,6 +18,7 @@
import com.google.gwt.animation.client.Animation;
import com.google.gwt.core.client.GWT;
import com.google.gwt.dom.client.Document;
+import com.google.gwt.dom.client.Element;
import com.google.gwt.event.logical.shared.CloseEvent;
import com.google.gwt.event.logical.shared.CloseHandler;
import com.google.gwt.event.logical.shared.HasCloseHandlers;
@@ -26,10 +27,11 @@
import com.google.gwt.user.client.Command;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.DeferredCommand;
-import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventPreview;
import com.google.gwt.user.client.Window;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.Event.NativePreviewHandler;
import com.google.gwt.user.client.ui.impl.PopupImpl;
/**
@@ -55,10 +57,12 @@
* {@example com.google.gwt.examples.PopupPanelExample}
* </p>
* <h3>CSS Style Rules</h3>
- * <ul class='css'>
- * <li>.gwt-PopupPanel { the outside of the popup }</li>
- * <li>.gwt-PopupPanel .popupContent { the wrapper around the content }</li>
- * </ul>
+ * <dl>
+ * <dt>.gwt-PopupPanel</dt>
+ * <dd>the outside of the popup</dd>
+ * <dt>.gwt-PopupPanel .popupContent</dt>
+ * <dd>the wrapper around the content</dd>
+ * </dl>
*/
@SuppressWarnings("deprecation")
public class PopupPanel extends SimplePanel implements SourcesPopupEvents,
@@ -265,7 +269,9 @@
*/
private AnimationType animType = AnimationType.CENTER;
- private boolean autoHide, modal, showing;
+ private HandlerRegistration nativePreviewHandlerRegistration;
+
+ private boolean autoHide, previewAllNativeEvents, modal, showing;
// Used to track requested size across changing child widgets
private String desiredHeight;
@@ -273,7 +279,7 @@
private String desiredWidth;
private boolean isAnimationEnabled = false;
-
+
private Element autoHidePartner;
/**
@@ -357,7 +363,7 @@
if (!initiallyShowing) {
setAnimationEnabled(initiallyAnimated);
- // Run the animation. The popup is already visible, so we can skip the
+ // Run the animation. The popup is already visible, so we can skip the
// call to setState.
if (initiallyAnimated) {
impl.setClip(getElement(), "rect(0px, 0px, 0px, 0px)");
@@ -433,6 +439,10 @@
return;
}
showing = false;
+ if (nativePreviewHandlerRegistration != null) {
+ nativePreviewHandlerRegistration.removeHandler();
+ nativePreviewHandlerRegistration = null;
+ }
// Hide the popup
resizeAnimation.setState(false);
@@ -463,74 +473,22 @@
return modal;
}
- @SuppressWarnings("deprecation")
+ /**
+ * Returns <code>true</code> if the popup should preview all native events,
+ * even if the event has already been consumed by another popup.
+ *
+ * @return true if previewAllNativeEvents is enabled, false if disabled
+ */
+ public boolean isPreviewingAllNativeEvents() {
+ return previewAllNativeEvents;
+ }
+
+ /**
+ * @deprecated use {@link #onPreviewNativeEvent(NativePreviewEvent)} instead
+ */
+ @Deprecated
public boolean onEventPreview(Event event) {
- Element target = DOM.eventGetTarget(event);
-
- boolean eventTargetsPopup = (target != null)
- && DOM.isOrHasChild(getElement(), target);
-
- int type = DOM.eventGetType(event);
- switch (type) {
- case Event.ONKEYDOWN: {
- boolean allow = onKeyDownPreview((char) DOM.eventGetKeyCode(event),
- KeyboardListenerCollection.getKeyboardModifiers(event));
- return allow && (eventTargetsPopup || !modal);
- }
- case Event.ONKEYUP: {
- boolean allow = onKeyUpPreview((char) DOM.eventGetKeyCode(event),
- KeyboardListenerCollection.getKeyboardModifiers(event));
- return allow && (eventTargetsPopup || !modal);
- }
- case Event.ONKEYPRESS: {
- boolean allow = onKeyPressPreview((char) DOM.eventGetKeyCode(event),
- KeyboardListenerCollection.getKeyboardModifiers(event));
- return allow && (eventTargetsPopup || !modal);
- }
-
- case Event.ONMOUSEDOWN:
- // Don't eat events if event capture is enabled, as this can interfere
- // with dialog dragging, for example.
- if (DOM.getCaptureElement() != null) {
- return true;
- }
-
- if (!eventTargetsPopup && shouldAutoHide(event)) {
- hide(true);
- return true;
- }
- break;
- case Event.ONMOUSEUP:
- case Event.ONMOUSEMOVE:
- case Event.ONCLICK:
- case Event.ONDBLCLICK: {
- // Don't eat events if event capture is enabled, as this can interfere
- // with dialog dragging, for example.
- if (DOM.getCaptureElement() != null) {
- return true;
- }
-
- // If it's an outside click and auto-hide is enabled:
- // hide the popup and _don't_ eat the event. ONMOUSEDOWN is used to
- // prevent problems with showing a popup in response to a mousedown.
- if (!eventTargetsPopup && shouldAutoHide(event)
- && (type == Event.ONMOUSEDOWN)) {
- hide(true);
- return true;
- }
-
- break;
- }
-
- case Event.ONFOCUS: {
- if (modal && !eventTargetsPopup && (target != null)) {
- blur(target);
- return false;
- }
- }
- }
-
- return !modal || eventTargetsPopup;
+ return true;
}
/**
@@ -541,7 +499,9 @@
* @param modifiers keyboard modifiers, as specified in
* {@link com.google.gwt.event.dom.client.KeyCodes}.
* @return <code>false</code> to suppress the event
+ * @deprecated use {@link #onPreviewNativeEvent(NativePreviewEvent)} instead
*/
+ @Deprecated
public boolean onKeyDownPreview(char key, int modifiers) {
return true;
}
@@ -554,7 +514,9 @@
* @param modifiers keyboard modifiers, as specified in
* {@link com.google.gwt.event.dom.client.KeyCodes}.
* @return <code>false</code> to suppress the event
+ * @deprecated use {@link #onPreviewNativeEvent(NativePreviewEvent)} instead
*/
+ @Deprecated
public boolean onKeyPressPreview(char key, int modifiers) {
return true;
}
@@ -567,7 +529,9 @@
* @param modifiers keyboard modifiers, as specified in
* {@link com.google.gwt.event.dom.client.KeyCodes}.
* @return <code>false</code> to suppress the event
+ * @deprecated use {@link #onPreviewNativeEvent(NativePreviewEvent)} instead
*/
+ @Deprecated
public boolean onKeyUpPreview(char key, int modifiers) {
return true;
}
@@ -592,8 +556,9 @@
}
/**
- * If the auto hide partner is non null, its mouse events will
- * not hide a panel set to autohide.
+ * If the auto hide partner is non null, its mouse events will not hide a
+ * panel set to autohide.
+ *
* @param element new auto hide partner
*/
public void setAutoHidePartner(Element element) {
@@ -633,7 +598,7 @@
public void setModal(boolean modal) {
this.modal = modal;
}
-
+
/**
* Sets the popup's position relative to the browser's client area. The
* popup's position may be set before calling {@link #show()}.
@@ -655,8 +620,8 @@
// called before show() is called (so a popup can be positioned without it
// 'jumping' on the screen).
Element elem = getElement();
- DOM.setStyleAttribute(elem, "left", left + "px");
- DOM.setStyleAttribute(elem, "top", top + "px");
+ elem.getStyle().setPropertyPx("left", left);
+ elem.getStyle().setPropertyPx("top", top);
}
/**
@@ -676,13 +641,31 @@
setVisible(true);
}
+ /**
+ * <p>
+ * When enabled, the popup will preview all native events, even if another
+ * popup was opened after this one.
+ * </p>
+ * <p>
+ * If autoHide is enabled, enabling this feature will cause the popup to
+ * autoHide even if another non-modal popup was shown after it. If this
+ * feature is disabled, the popup will only autoHide if it was the last popup
+ * opened.
+ * </p>
+ *
+ * @param previewAllNativeEvents true to enable, false to disable
+ */
+ public void setPreviewingAllNativeEvents(boolean previewAllNativeEvents) {
+ this.previewAllNativeEvents = previewAllNativeEvents;
+ }
+
@Override
public void setTitle(String title) {
Element containerElement = getContainerElement();
if (title == null || title.length() == 0) {
- DOM.removeElementAttribute(containerElement, "title");
+ containerElement.removeAttribute("title");
} else {
- DOM.setElementAttribute(containerElement, "title", title);
+ containerElement.setAttribute("title", title);
}
}
@@ -744,7 +727,11 @@
return;
}
showing = true;
- DOM.addEventPreview(this);
+ nativePreviewHandlerRegistration = Event.addNativePreviewHandler(new NativePreviewHandler() {
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ previewNativeEvent(event);
+ }
+ });
resizeAnimation.setState(true);
}
@@ -768,19 +755,24 @@
}
@Override
- protected Element getContainerElement() {
- return impl.getContainerElement(DOM.getFirstChild(super.getContainerElement()));
+ protected com.google.gwt.user.client.Element getContainerElement() {
+ return impl.getContainerElement(getPopupImplElement());
+ }
+
+ @Override
+ protected com.google.gwt.user.client.Element getStyleElement() {
+ return impl.getStyleElement(getPopupImplElement());
}
/**
- * This method is called when a widget is detached from the browser's
- * document. To receive notification before the PopupPanel is removed from the
- * document, override the {@link Widget#onUnload()} method instead.
+ * @see NativePreviewHandler#onPreviewNativeEvent(NativePreviewEvent)
*/
- @Override
- protected void onDetach() {
- DOM.removeEventPreview(this);
- super.onDetach();
+ @SuppressWarnings("deprecation")
+ protected void onPreviewNativeEvent(NativePreviewEvent event) {
+ // Cancel the event based on the deprecated onEventPreview() method
+ if (!event.isCanceled() && !onEventPreview(event.getNativeEvent())) {
+ event.cancel();
+ }
}
/**
@@ -841,9 +833,37 @@
}
}-*/;
- private boolean eventInPartner(Event event) {
+ /**
+ * Does the event target the partner element?
+ *
+ * @param event the native event
+ * @return true if the event targets the partner
+ */
+ private boolean eventTargetsPartner(Event event) {
return autoHidePartner != null
- && autoHidePartner.isOrHasChild(event.getTarget());
+ && autoHidePartner.isOrHasChild(event.getTarget());
+ }
+
+ /**
+ * Does the event target this popup?
+ *
+ * @param event the native event
+ * @return true if the event targets the popup
+ */
+ private boolean eventTargetsPopup(Event event) {
+ return getElement().isOrHasChild(event.getTarget());
+ }
+
+ /**
+ * Get the element that {@link PopupImpl} uses. PopupImpl creates an element
+ * that goes inside of the outer element, so all methods in PopupImpl are
+ * relative to the first child of the outer element, not the outer element
+ * itself.
+ *
+ * @return the Element that {@link PopupImpl} creates and expects
+ */
+ private com.google.gwt.user.client.Element getPopupImplElement() {
+ return DOM.getFirstChild(super.getContainerElement());
}
/**
@@ -974,10 +994,103 @@
}
setPopupPosition(left, top);
}
-
- private boolean shouldAutoHide(Event event) {
- boolean shouldAutoHide = autoHide && !eventInPartner(event);
- return shouldAutoHide;
- }
+ /**
+ * Preview the {@link NativePreviewEvent}.
+ *
+ * @param event the {@link NativePreviewEvent}
+ */
+ private void previewNativeEvent(NativePreviewEvent event) {
+ // If the event has been canceled or consumed, ignore it
+ if (event.isCanceled() || (!previewAllNativeEvents && event.isConsumed())) {
+ // We need to ensure that we cancel the event even if its been consumed so
+ // that popups lower on the stack do not auto hide
+ if (modal) {
+ event.cancel();
+ }
+ return;
+ }
+
+ // Fire the event hook and return if the event is canceled
+ onPreviewNativeEvent(event);
+ if (event.isCanceled()) {
+ return;
+ }
+
+ // If the event targets the popup or the partner, consume it
+ Event nativeEvent = event.getNativeEvent();
+ boolean eventTargetsPopupOrPartner = eventTargetsPopup(nativeEvent)
+ || eventTargetsPartner(nativeEvent);
+ if (eventTargetsPopupOrPartner) {
+ event.consume();
+ }
+
+ // Cancel the event if it doesn't target the modal popup. Note that the
+ // event can be both canceled and consumed.
+ if (modal) {
+ event.cancel();
+ }
+
+ // Switch on the event type
+ int type = nativeEvent.getTypeInt();
+ switch (type) {
+ case Event.ONKEYDOWN: {
+ if (!onKeyDownPreview((char) nativeEvent.getKeyCode(),
+ KeyboardListenerCollection.getKeyboardModifiers(nativeEvent))) {
+ event.cancel();
+ }
+ return;
+ }
+ case Event.ONKEYUP: {
+ if (!onKeyUpPreview((char) nativeEvent.getKeyCode(),
+ KeyboardListenerCollection.getKeyboardModifiers(nativeEvent))) {
+ event.cancel();
+ }
+ return;
+ }
+ case Event.ONKEYPRESS: {
+ if (!onKeyPressPreview((char) nativeEvent.getKeyCode(),
+ KeyboardListenerCollection.getKeyboardModifiers(nativeEvent))) {
+ event.cancel();
+ }
+ return;
+ }
+
+ case Event.ONMOUSEDOWN:
+ // Don't eat events if event capture is enabled, as this can
+ // interfere with dialog dragging, for example.
+ if (DOM.getCaptureElement() != null) {
+ event.consume();
+ return;
+ }
+
+ if (!eventTargetsPopupOrPartner && autoHide) {
+ hide(true);
+ return;
+ }
+ break;
+ case Event.ONMOUSEUP:
+ case Event.ONMOUSEMOVE:
+ case Event.ONCLICK:
+ case Event.ONDBLCLICK: {
+ // Don't eat events if event capture is enabled, as this can
+ // interfere with dialog dragging, for example.
+ if (DOM.getCaptureElement() != null) {
+ event.consume();
+ return;
+ }
+ break;
+ }
+
+ case Event.ONFOCUS: {
+ Element target = nativeEvent.getTarget();
+ if (modal && !eventTargetsPopupOrPartner && (target != null)) {
+ blur(target);
+ event.cancel();
+ return;
+ }
+ break;
+ }
+ }
+ }
}
diff --git a/user/src/com/google/gwt/user/client/ui/ScrollListener.java b/user/src/com/google/gwt/user/client/ui/ScrollListener.java
index d7e6130..6b50121 100644
--- a/user/src/com/google/gwt/user/client/ui/ScrollListener.java
+++ b/user/src/com/google/gwt/user/client/ui/ScrollListener.java
@@ -19,6 +19,9 @@
/**
* Event listener interface for scroll events.
+ *
+ * @deprecated use {@link com.google.gwt.event.dom.client.ScrollHandler}
+ * instead
*/
@Deprecated
public interface ScrollListener extends EventListener {
diff --git a/user/src/com/google/gwt/user/client/ui/ScrollListenerCollection.java b/user/src/com/google/gwt/user/client/ui/ScrollListenerCollection.java
index 5576063..15a0b03 100644
--- a/user/src/com/google/gwt/user/client/ui/ScrollListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/ScrollListenerCollection.java
@@ -21,6 +21,9 @@
* A helper class for implementers of the SourcesScrollEvents interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.ScrollListener}.
+ *
+ * @deprecated use <code>addDomHandler(myHandler, ScrollEvent.getType())</code>
+ * to manage handlers within your widget instead
*/
@Deprecated
public class ScrollListenerCollection extends ArrayList<ScrollListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/SourcesChangeEvents.java b/user/src/com/google/gwt/user/client/ui/SourcesChangeEvents.java
index 27f6c16..268f3ad 100644
--- a/user/src/com/google/gwt/user/client/ui/SourcesChangeEvents.java
+++ b/user/src/com/google/gwt/user/client/ui/SourcesChangeEvents.java
@@ -19,7 +19,7 @@
* A widget that implements this interface sources the events defined by the
* {@link com.google.gwt.user.client.ui.ChangeListener} interface.
*
- * @deprecated Use {@link com.google.gwt.event.dom.client.HasChangeHandlers}
+ * @deprecated use {@link com.google.gwt.event.dom.client.HasChangeHandlers}
* instead
*/
@Deprecated
diff --git a/user/src/com/google/gwt/user/client/ui/SourcesMouseEvents.java b/user/src/com/google/gwt/user/client/ui/SourcesMouseEvents.java
index ce3c60a..96a6cad 100644
--- a/user/src/com/google/gwt/user/client/ui/SourcesMouseEvents.java
+++ b/user/src/com/google/gwt/user/client/ui/SourcesMouseEvents.java
@@ -19,7 +19,7 @@
* A widget that implements this interface sources the events defined by the
* {@link com.google.gwt.user.client.ui.MouseListener} interface.
*
- * @deprecated use {@link com.google.gwt.event.dom.client.HasAllMouseHandlerss}
+ * @deprecated use {@link com.google.gwt.event.dom.client.HasAllMouseHandlers}
* instead
*/
@Deprecated
diff --git a/user/src/com/google/gwt/user/client/ui/SourcesMouseWheelEvents.java b/user/src/com/google/gwt/user/client/ui/SourcesMouseWheelEvents.java
index c003da6..f342544 100644
--- a/user/src/com/google/gwt/user/client/ui/SourcesMouseWheelEvents.java
+++ b/user/src/com/google/gwt/user/client/ui/SourcesMouseWheelEvents.java
@@ -19,9 +19,10 @@
* A widget that implements this interface sources the events defined by the
* {@link com.google.gwt.user.client.ui.MouseWheelListener} interface.
*
- * @deprecated use {@link com.google.gwt.event.dom.client.HasMouseDownHandlers}
+ * @deprecated use {@link com.google.gwt.event.dom.client.HasMouseWheelHandlers}
* instead
*/
+@Deprecated
public interface SourcesMouseWheelEvents {
/**
diff --git a/user/src/com/google/gwt/user/client/ui/SourcesTreeEvents.java b/user/src/com/google/gwt/user/client/ui/SourcesTreeEvents.java
index 4f7e8fe..e47c443 100644
--- a/user/src/com/google/gwt/user/client/ui/SourcesTreeEvents.java
+++ b/user/src/com/google/gwt/user/client/ui/SourcesTreeEvents.java
@@ -22,7 +22,7 @@
* @deprecated use
* {@link com.google.gwt.event.logical.shared.HasBeforeSelectionHandlers}
* , {@link com.google.gwt.event.logical.shared.HasOpenHandlers},
- * {@link com.google.gwt.event.logical.shared.HasClickHandlers}
+ * {@link com.google.gwt.event.dom.client.HasClickHandlers}
* instead
*/
@Deprecated
diff --git a/user/src/com/google/gwt/user/client/ui/SplitPanel.java b/user/src/com/google/gwt/user/client/ui/SplitPanel.java
index ff58976..aaf5692 100644
--- a/user/src/com/google/gwt/user/client/ui/SplitPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/SplitPanel.java
@@ -316,6 +316,7 @@
break;
}
}
+ super.onBrowserEvent(event);
}
@Override
diff --git a/user/src/com/google/gwt/user/client/ui/StackPanel.java b/user/src/com/google/gwt/user/client/ui/StackPanel.java
index ae17c23..8432a01 100644
--- a/user/src/com/google/gwt/user/client/ui/StackPanel.java
+++ b/user/src/com/google/gwt/user/client/ui/StackPanel.java
@@ -171,6 +171,7 @@
showStack(index);
}
}
+ super.onBrowserEvent(event);
}
@Override
diff --git a/user/src/com/google/gwt/user/client/ui/SuggestBox.java b/user/src/com/google/gwt/user/client/ui/SuggestBox.java
index 8fd59b2..eacf785 100644
--- a/user/src/com/google/gwt/user/client/ui/SuggestBox.java
+++ b/user/src/com/google/gwt/user/client/ui/SuggestBox.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -240,6 +240,7 @@
super(true, false, "suggestPopup");
setWidget(suggestionMenu);
setStyleName(STYLENAME_DEFAULT);
+ setPreviewingAllNativeEvents(true);
}
/**
@@ -475,6 +476,7 @@
*
* @deprecated use addSelectionHandler instead.
*/
+ @Deprecated
public void addEventHandler(final SuggestionHandler handler) {
ListenerWrapper.Suggestion.add(this, handler);
}
diff --git a/user/src/com/google/gwt/user/client/ui/TabListenerCollection.java b/user/src/com/google/gwt/user/client/ui/TabListenerCollection.java
index 2cf6fce..4693454 100644
--- a/user/src/com/google/gwt/user/client/ui/TabListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/TabListenerCollection.java
@@ -22,6 +22,9 @@
* {@link com.google.gwt.user.client.ui.SourcesTabEvents} interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.TabListener}.
+ *
+ * @deprecated {@link TabPanel} and {@link TabBar} should now completely manage
+ * their own handlers
*/
@Deprecated
public class TabListenerCollection extends ArrayList<TabListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/TableListenerCollection.java b/user/src/com/google/gwt/user/client/ui/TableListenerCollection.java
index 638f7d2..d013eed 100644
--- a/user/src/com/google/gwt/user/client/ui/TableListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/TableListenerCollection.java
@@ -22,6 +22,10 @@
* {@link com.google.gwt.user.client.ui.SourcesTableEvents} interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.TableListener}.
+ *
+ * @deprecated use
+ * {@link HTMLTable#getCellForEvent(com.google.gwt.event.dom.client.ClickEvent)}
+ * or similar code
*/
@Deprecated
public class TableListenerCollection extends ArrayList<TableListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/TreeListenerCollection.java b/user/src/com/google/gwt/user/client/ui/TreeListenerCollection.java
index 92a2320..92bd35d 100644
--- a/user/src/com/google/gwt/user/client/ui/TreeListenerCollection.java
+++ b/user/src/com/google/gwt/user/client/ui/TreeListenerCollection.java
@@ -21,6 +21,8 @@
* A helper class for implementers of the SourcesClickEvents interface. This
* subclass of {@link ArrayList} assumes that all objects added to it will be of
* type {@link com.google.gwt.user.client.ui.ClickListener}.
+ *
+ * @deprecated {@link Tree} should now completely manage its own handlers
*/
@Deprecated
public class TreeListenerCollection extends ArrayList<TreeListener> {
diff --git a/user/src/com/google/gwt/user/client/ui/Widget.java b/user/src/com/google/gwt/user/client/ui/Widget.java
index 7d0725e..7f23170 100644
--- a/user/src/com/google/gwt/user/client/ui/Widget.java
+++ b/user/src/com/google/gwt/user/client/ui/Widget.java
@@ -183,19 +183,23 @@
}
/**
- * If a widget implements HasWidgets, it must override this method and call
- * {@link #onAttach()} for each of its child widgets.
+ * If a widget contains one or more child widgets that are not in the logical
+ * widget hierarchy (the child is physically connected only on the DOM level),
+ * it must override this method and call {@link #onAttach()} for each of its
+ * child widgets.
*
- * @see Panel#onAttach()
+ * @see #onAttach()
*/
protected void doAttachChildren() {
}
/**
- * If a widget implements HasWidgets, it must override this method and call
- * onDetach() for each of its child widgets.
+ * If a widget contains one or more child widgets that are not in the logical
+ * widget hierarchy (the child is physically connected only on the DOM level),
+ * it must override this method and call {@link #onDetach()} for each of its
+ * child widgets.
*
- * @see Panel#onDetach()
+ * @see #onDetach()
*/
protected void doDetachChildren() {
}
diff --git a/user/src/com/google/gwt/user/client/ui/impl/PopupImpl.java b/user/src/com/google/gwt/user/client/ui/impl/PopupImpl.java
index 9af98c1..d8897cc 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/PopupImpl.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/PopupImpl.java
@@ -31,6 +31,10 @@
return popup;
}
+ public Element getStyleElement(Element popup) {
+ return DOM.getParent(popup);
+ }
+
public void onHide(Element popup) {
}
diff --git a/user/src/com/google/gwt/user/client/ui/impl/PopupImplMozilla.java b/user/src/com/google/gwt/user/client/ui/impl/PopupImplMozilla.java
index a11fe48..eaa6c94 100644
--- a/user/src/com/google/gwt/user/client/ui/impl/PopupImplMozilla.java
+++ b/user/src/com/google/gwt/user/client/ui/impl/PopupImplMozilla.java
@@ -99,6 +99,11 @@
}
@Override
+ public Element getStyleElement(Element outerElem) {
+ return isMac ? outerElem : super.getStyleElement(outerElem);
+ }
+
+ @Override
public void setClip(Element popup, String rect) {
super.setClip(popup, rect);
DOM.setStyleAttribute(popup, "display", "none");
diff --git a/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css b/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css
index f9ed0a6..f71a4a9 100644
--- a/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css
+++ b/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome.css
@@ -1073,7 +1073,7 @@
}
.gwt-Tree .gwt-TreeItem {
- padding: 1px;
+ padding: 1px 0px;
margin: 0px;
white-space: nowrap;
cursor: hand;
diff --git a/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css b/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css
index 693c41f..6d8a276 100644
--- a/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css
+++ b/user/src/com/google/gwt/user/theme/chrome/public/gwt/chrome/chrome_rtl.css
@@ -1073,7 +1073,7 @@
}
.gwt-Tree .gwt-TreeItem {
- padding: 1px;
+ padding: 1px 0px;
margin: 0px;
white-space: nowrap;
cursor: hand;
diff --git a/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css b/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css
index 1e341c2..6b274f3 100644
--- a/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css
+++ b/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark.css
@@ -977,7 +977,7 @@
}
.gwt-Tree .gwt-TreeItem {
- padding: 1px;
+ padding: 1px 0px;
margin: 0px;
white-space: nowrap;
cursor: hand;
diff --git a/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css b/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css
index f73cbff..4c7e922 100644
--- a/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css
+++ b/user/src/com/google/gwt/user/theme/dark/public/gwt/dark/dark_rtl.css
@@ -977,7 +977,7 @@
}
.gwt-Tree .gwt-TreeItem {
- padding: 1px;
+ padding: 1px 0px;
margin: 0px;
white-space: nowrap;
cursor: hand;
diff --git a/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css b/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css
index 7b4b8ae..2b0341d 100644
--- a/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css
+++ b/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard.css
@@ -1072,7 +1072,7 @@
}
.gwt-Tree .gwt-TreeItem {
- padding: 1px;
+ padding: 1px 0px;
margin: 0px;
white-space: nowrap;
cursor: hand;
diff --git a/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css b/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css
index e3e65af..22db0da 100644
--- a/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css
+++ b/user/src/com/google/gwt/user/theme/standard/public/gwt/standard/standard_rtl.css
@@ -1072,7 +1072,7 @@
}
.gwt-Tree .gwt-TreeItem {
- padding: 1px;
+ padding: 1px 0px;
margin: 0px;
white-space: nowrap;
cursor: hand;
diff --git a/user/test/com/google/gwt/user/UISuite.java b/user/test/com/google/gwt/user/UISuite.java
index 864e0d6..515955b 100644
--- a/user/test/com/google/gwt/user/UISuite.java
+++ b/user/test/com/google/gwt/user/UISuite.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -19,6 +19,7 @@
import com.google.gwt.user.client.AsyncProxyTest;
import com.google.gwt.user.client.CommandExecutorTest;
import com.google.gwt.user.client.CookieTest;
+import com.google.gwt.user.client.EventTest;
import com.google.gwt.user.client.WindowTest;
import com.google.gwt.user.client.ui.AbsolutePanelTest;
import com.google.gwt.user.client.ui.AnchorTest;
@@ -114,6 +115,7 @@
suite.addTestSuite(DockPanelTest.class);
suite.addTestSuite(DOMTest.class);
suite.addTestSuite(ElementWrappingTest.class);
+ suite.addTestSuite(EventTest.class);
suite.addTestSuite(FastStringMapTest.class);
suite.addTestSuite(FlexTableTest.class);
suite.addTestSuite(FlowPanelTest.class);
diff --git a/user/test/com/google/gwt/user/client/EventTest.java b/user/test/com/google/gwt/user/client/EventTest.java
new file mode 100644
index 0000000..a894e85
--- /dev/null
+++ b/user/test/com/google/gwt/user/client/EventTest.java
@@ -0,0 +1,410 @@
+/*
+ * Copyright 2009 Google Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.google.gwt.user.client;
+
+import com.google.gwt.event.shared.HandlerRegistration;
+import com.google.gwt.junit.client.GWTTestCase;
+import com.google.gwt.user.client.Event.NativePreviewEvent;
+import com.google.gwt.user.client.Event.NativePreviewHandler;
+
+/**
+ * Test Case for {@link Event}.
+ */
+public class EventTest extends GWTTestCase {
+ /**
+ * An EventPreview used for testing.
+ */
+ @SuppressWarnings("deprecation")
+ private static class TestEventPreview implements EventPreview {
+ private boolean doCancel;
+ private boolean isFired = false;
+
+ /**
+ * Construct a new {@link TestEventPreview}.
+ *
+ * @param doCancel if true, cancel the event
+ */
+ public TestEventPreview(boolean doCancel) {
+ this.doCancel = doCancel;
+ }
+
+ @Deprecated
+ public boolean onEventPreview(Event event) {
+ assertFalse(isFired);
+ isFired = true;
+ return !doCancel;
+ }
+
+ public void assertIsFired(boolean expected) {
+ assertEquals(expected, isFired);
+ }
+ }
+
+ /**
+ * A NativePreviewHandler used for testing.
+ */
+ private static class TestNativePreviewHandler implements NativePreviewHandler {
+ private boolean doCancel;
+ private boolean doPreventCancel;
+ private boolean isFired = false;
+
+ /**
+ * Construct a new {@link TestNativePreviewHandler}.
+ *
+ * @param doCancel if true, cancel the event
+ * @param doPreventCancel if true, prevent the event from being canceled
+ */
+ public TestNativePreviewHandler(boolean doCancel, boolean doPreventCancel) {
+ this.doCancel = doCancel;
+ this.doPreventCancel = doPreventCancel;
+ }
+
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ assertFalse(isFired);
+ isFired = true;
+ if (doCancel) {
+ event.cancel();
+ }
+ if (doPreventCancel) {
+ event.consume();
+ }
+ }
+
+ public void assertIsFired(boolean expected) {
+ assertEquals(expected, isFired);
+ }
+ }
+
+ @Override
+ public String getModuleName() {
+ return "com.google.gwt.user.User";
+ }
+
+ /**
+ * Test that {@link Event#fireNativePreviewEvent(Event)} returns the correct
+ * value if the native event is canceled.
+ */
+ public void testFireNativePreviewEventCancel() {
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(true,
+ false);
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(true,
+ false);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+ assertFalse(Event.fireNativePreviewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(true);
+ reg0.removeHandler();
+ reg1.removeHandler();
+ }
+
+ /**
+ * Test that {@link Event#fireNativePreviewEvent(Event)} returns the correct
+ * value if the native event is prevented from being canceled, even if another
+ * handler cancels the event.
+ */
+ public void testFireNativePreviewEventPreventCancel() {
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
+ true);
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(true,
+ false);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+ assertTrue(Event.fireNativePreviewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(true);
+ reg0.removeHandler();
+ reg1.removeHandler();
+ }
+
+ /**
+ * Test that {@link Event#fireNativePreviewEvent(Event)} fires handlers in
+ * reverse order. Also verify that the legacy EventPreview fires last.
+ */
+ @SuppressWarnings("deprecation")
+ public void testFireNativePreviewEventReverseOrder() {
+ final TestEventPreview preview = new TestEventPreview(false);
+ final TestNativePreviewHandler handler0 = new TestNativePreviewHandler(
+ false, false) {
+ @Override
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ super.onPreviewNativeEvent(event);
+ preview.assertIsFired(false);
+ }
+ };
+ final TestNativePreviewHandler handler1 = new TestNativePreviewHandler(
+ false, false) {
+ @Override
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ super.onPreviewNativeEvent(event);
+ handler0.assertIsFired(false);
+ preview.assertIsFired(false);
+ }
+ };
+ final TestNativePreviewHandler handler2 = new TestNativePreviewHandler(
+ false, false) {
+ @Override
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ super.onPreviewNativeEvent(event);
+ handler0.assertIsFired(false);
+ handler1.assertIsFired(false);
+ preview.assertIsFired(false);
+ }
+ };
+ final TestNativePreviewHandler handler3 = new TestNativePreviewHandler(
+ false, false) {
+ @Override
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ super.onPreviewNativeEvent(event);
+ handler0.assertIsFired(false);
+ handler1.assertIsFired(false);
+ handler2.assertIsFired(false);
+ preview.assertIsFired(false);
+ }
+ };
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+ HandlerRegistration reg2 = Event.addNativePreviewHandler(handler2);
+ HandlerRegistration reg3 = Event.addNativePreviewHandler(handler3);
+ DOM.addEventPreview(preview);
+ assertTrue(DOM.previewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(true);
+ handler2.assertIsFired(true);
+ handler3.assertIsFired(true);
+ preview.assertIsFired(true);
+ reg0.removeHandler();
+ reg1.removeHandler();
+ reg2.removeHandler();
+ reg3.removeHandler();
+ DOM.removeEventPreview(preview);
+ }
+
+ /**
+ * Test removal of a {@link NativePreviewHandler} works.
+ */
+ public void testFireNativePreviewEventRemoval() {
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
+ false);
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(false,
+ false);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+ reg1.removeHandler();
+ assertTrue(Event.fireNativePreviewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(false);
+ reg0.removeHandler();
+ }
+
+ /**
+ * Test that {@link Event#fireNativePreviewEvent(Event)} returns the correct
+ * value if the native event is not canceled.
+ */
+ public void testFireNativePreviewEventWithoutCancel() {
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
+ false);
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(false,
+ false);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+ assertTrue(Event.fireNativePreviewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(true);
+ reg0.removeHandler();
+ reg1.removeHandler();
+ }
+
+ /**
+ * Test that {@link Event#fireNativePreviewEvent(Event)} returns the correct
+ * value if no handlers are present.
+ */
+ public void testFireNativePreviewEventWithoutHandlers() {
+ assertTrue(Event.fireNativePreviewEvent(null));
+ }
+
+ /**
+ * Test that legacy EventPreview and NativePreviewHandlers can both cancel the
+ * event.
+ */
+ @Deprecated
+ public void testLegacyEventPreviewCancelByBoth() {
+ // Add handlers
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
+ false);
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(true,
+ false);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+
+ // Add legacy EventPreview
+ TestEventPreview preview = new TestEventPreview(true);
+ DOM.addEventPreview(preview);
+
+ // Fire the event
+ assertFalse(DOM.previewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(true);
+ preview.assertIsFired(true);
+ reg0.removeHandler();
+ reg1.removeHandler();
+ DOM.removeEventPreview(preview);
+ }
+
+ /**
+ * Test that legacy EventPreview can cancel the event.
+ */
+ @Deprecated
+ public void testLegacyEventPreviewCancelByEventPreview() {
+ // Add handlers
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
+ false);
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(false,
+ false);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+
+ // Add legacy EventPreview
+ TestEventPreview preview = new TestEventPreview(true);
+ DOM.addEventPreview(preview);
+
+ // Fire the event
+ assertFalse(DOM.previewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(true);
+ preview.assertIsFired(true);
+ reg0.removeHandler();
+ reg1.removeHandler();
+ DOM.removeEventPreview(preview);
+ }
+
+ /**
+ * Test that legacy EventPreview still fires after the NativeHandler cancels
+ * the event.
+ */
+ @Deprecated
+ public void testLegacyEventPreviewCancelByHandler() {
+ // Add handlers
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
+ false);
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(true,
+ false);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+
+ // Add legacy EventPreview
+ TestEventPreview preview = new TestEventPreview(false);
+ DOM.addEventPreview(preview);
+
+ // Fire the event
+ assertFalse(DOM.previewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(true);
+ preview.assertIsFired(true);
+ reg0.removeHandler();
+ reg1.removeHandler();
+ DOM.removeEventPreview(preview);
+ }
+
+ /**
+ * Test that legacy EventPreview still fires after the NativeHandlers without
+ * canceling the event.
+ */
+ @Deprecated
+ public void testLegacyEventPreviewWithoutCancel() {
+ // Add handlers
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(false,
+ false);
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(false,
+ false);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+
+ // Add legacy EventPreview
+ TestEventPreview preview = new TestEventPreview(false);
+ DOM.addEventPreview(preview);
+
+ // Fire the event
+ assertTrue(DOM.previewEvent(null));
+ handler0.assertIsFired(true);
+ handler1.assertIsFired(true);
+ preview.assertIsFired(true);
+ reg0.removeHandler();
+ reg1.removeHandler();
+ DOM.removeEventPreview(preview);
+ }
+
+ /**
+ * Test the accessors in {@link NativePreviewEvent}.
+ */
+ public void testNativePreviewEventAccessors() {
+ // cancelNativeEvent
+ {
+ NativePreviewEvent event = new NativePreviewEvent();
+ assertFalse(event.isCanceled());
+ event.cancel();
+ assertTrue(event.isCanceled());
+ }
+
+ // preventCancelNativeEvent
+ {
+ NativePreviewEvent event = new NativePreviewEvent();
+ assertFalse(event.isConsumed());
+ event.consume();
+ assertTrue(event.isConsumed());
+ }
+
+ // revive
+ {
+ NativePreviewEvent event = new NativePreviewEvent();
+ event.cancel();
+ event.consume();
+ assertTrue(event.isCanceled());
+ assertTrue(event.isConsumed());
+ event.revive();
+ assertFalse(event.isCanceled());
+ assertFalse(event.isConsumed());
+ }
+ }
+
+ /**
+ * Test that the singleton instance of {@link NativePreviewEvent} is revived
+ * correctly.
+ */
+ public void testReviveNativePreviewEvent() {
+ // Fire the event and cancel it
+ TestNativePreviewHandler handler0 = new TestNativePreviewHandler(true, true);
+ HandlerRegistration reg0 = Event.addNativePreviewHandler(handler0);
+ Event.fireNativePreviewEvent(null);
+ handler0.assertIsFired(true);
+ reg0.removeHandler();
+
+ // Fire the event again, but don't cancel it
+ TestNativePreviewHandler handler1 = new TestNativePreviewHandler(false,
+ false) {
+ @Override
+ public void onPreviewNativeEvent(NativePreviewEvent event) {
+ assertFalse(event.isCanceled());
+ assertFalse(event.isConsumed());
+ super.onPreviewNativeEvent(event);
+ }
+ };
+ HandlerRegistration reg1 = Event.addNativePreviewHandler(handler1);
+ assertTrue(Event.fireNativePreviewEvent(null));
+ handler1.assertIsFired(true);
+ reg1.removeHandler();
+ }
+}
diff --git a/user/test/com/google/gwt/user/client/ui/PopupTest.java b/user/test/com/google/gwt/user/client/ui/PopupTest.java
index f42b84c..8aa91e3 100644
--- a/user/test/com/google/gwt/user/client/ui/PopupTest.java
+++ b/user/test/com/google/gwt/user/client/ui/PopupTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2008 Google Inc.
+ * Copyright 2009 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
@@ -74,6 +74,12 @@
assertTrue(popup.isAutoHideEnabled());
popup.setAutoHideEnabled(false);
assertFalse(popup.isAutoHideEnabled());
+
+ // PreviewAllNativeEvents enabled
+ popup.setPreviewingAllNativeEvents(true);
+ assertTrue(popup.isPreviewingAllNativeEvents());
+ popup.setPreviewingAllNativeEvents(false);
+ assertFalse(popup.isPreviewingAllNativeEvents());
}
/**