Description:
This patch makes events sink lazily on common GWT widgets. This is a breaking change, as any subclasses which depend upon the events being sunk without adding listeners will no longer work.
Issue: 1491.
Review by: knorton
git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@1780 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/user/client/ui/CheckBox.java b/user/src/com/google/gwt/user/client/ui/CheckBox.java
index 7d6ebd7..72762f5 100644
--- a/user/src/com/google/gwt/user/client/ui/CheckBox.java
+++ b/user/src/com/google/gwt/user/client/ui/CheckBox.java
@@ -76,9 +76,6 @@
inputElem = elem;
labelElem = DOM.createLabel();
- // Hook events to input widget rather than the check box element.
- DOM.sinkEvents(inputElem, DOM.getEventsSunk(this.getElement()));
- DOM.sinkEvents(this.getElement(), 0);
DOM.appendChild(getElement(), inputElem);
DOM.appendChild(getElement(), labelElem);
@@ -174,6 +171,13 @@
DOM.setInnerText(labelElem, text);
}
+ // Unlike other widgets the CheckBox sinks on its input element, not its
+ // wrapper element.
+ @Override
+ public void sinkEvents(int eventBitsToAdd) {
+ DOM.sinkEvents(inputElem, eventBitsToAdd | DOM.getEventsSunk(inputElem));
+ }
+
/**
* This method is called when a widget is attached to the browser's document.
* onAttach needs special handling for the CheckBox case. Must still call
@@ -198,27 +202,26 @@
DOM.setEventListener(inputElem, null);
setChecked(isChecked());
}
-
+
/**
* Replace the current input element with a new one.
*
* @param elem the new input element
*/
protected void replaceInputElement(Element elem) {
+
// Collect information we need to set
int tabIndex = getTabIndex();
boolean checked = isChecked();
boolean enabled = isEnabled();
- String uid = DOM.getElementProperty(inputElem, "id");
+ String uid = DOM.getElementProperty(inputElem, "id");
String accessKey = DOM.getElementProperty(inputElem, "accessKey");
-
+ int sunkEvents = DOM.getEventsSunk(inputElem);
+
// Clear out the old input element
- setChecked(false);
- DOM.setElementProperty(inputElem, "id", "");
- DOM.setElementProperty(inputElem, "accessKey", "");
DOM.setEventListener(inputElem, null);
-
- // Quickly do the physical replace
+ DOM.setEventListener(inputElem, null);
+
DOM.removeChild(getElement(), inputElem);
DOM.insertChild(getElement(), elem, 0);
@@ -228,6 +231,7 @@
inputElem = elem;
// Setup the new element
+ DOM.sinkEvents(inputElem, sunkEvents);
DOM.setElementProperty(inputElem, "id", uid);
if (accessKey != "") {
DOM.setElementProperty(inputElem, "accessKey", accessKey);
diff --git a/user/src/com/google/gwt/user/client/ui/FocusWidget.java b/user/src/com/google/gwt/user/client/ui/FocusWidget.java
index c3df8f4..adef49b 100644
--- a/user/src/com/google/gwt/user/client/ui/FocusWidget.java
+++ b/user/src/com/google/gwt/user/client/ui/FocusWidget.java
@@ -24,7 +24,7 @@
* Abstract base class for most widgets that can receive keyboard focus.
*/
public abstract class FocusWidget extends Widget implements SourcesClickEvents,
- SourcesFocusEvents, HasFocus {
+ SourcesFocusEvents, HasFocus, SourcesKeyboardEvents {
private static final FocusImpl impl = FocusImpl.getFocusImplForWidget();
@@ -60,6 +60,7 @@
public void addClickListener(ClickListener listener) {
if (clickListeners == null) {
clickListeners = new ClickListenerCollection();
+ sinkEvents(Event.ONCLICK);
}
clickListeners.add(listener);
}
@@ -67,6 +68,7 @@
public void addFocusListener(FocusListener listener) {
if (focusListeners == null) {
focusListeners = new FocusListenerCollection();
+ sinkEvents(Event.FOCUSEVENTS );
}
focusListeners.add(listener);
}
@@ -74,6 +76,7 @@
public void addKeyboardListener(KeyboardListener listener) {
if (keyboardListeners == null) {
keyboardListeners = new KeyboardListenerCollection();
+ sinkEvents(Event.KEYEVENTS);
}
keyboardListeners.add(listener);
}
@@ -161,11 +164,6 @@
impl.setTabIndex(getElement(), index);
}
- @Override
- protected void setElement(Element elem) {
- super.setElement(elem);
- sinkEvents(Event.ONCLICK | Event.FOCUSEVENTS | Event.KEYEVENTS);
- }
/**
* Fire all current {@link ClickListener}.
diff --git a/user/src/com/google/gwt/user/client/ui/HTML.java b/user/src/com/google/gwt/user/client/ui/HTML.java
index 04e8f2e..80edbc2 100644
--- a/user/src/com/google/gwt/user/client/ui/HTML.java
+++ b/user/src/com/google/gwt/user/client/ui/HTML.java
@@ -16,7 +16,6 @@
package com.google.gwt.user.client.ui;
import com.google.gwt.user.client.DOM;
-import com.google.gwt.user.client.Event;
/**
* A widget that can contain arbitrary HTML.
@@ -34,7 +33,8 @@
* </ul>
*
* <p>
- * <h3>Example</h3> {@example com.google.gwt.examples.HTMLExample}
+ * <h3>Example</h3>
+ * {@example com.google.gwt.examples.HTMLExample}
* </p>
*/
public class HTML extends Label implements HasHTML {
@@ -43,8 +43,7 @@
* Creates an empty HTML widget.
*/
public HTML() {
- setElement(DOM.createDiv());
- sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS);
+ super(DOM.createDiv());
setStyleName("gwt-HTML");
}
diff --git a/user/src/com/google/gwt/user/client/ui/HTMLTable.java b/user/src/com/google/gwt/user/client/ui/HTMLTable.java
index 014c6b2..3cf6093 100644
--- a/user/src/com/google/gwt/user/client/ui/HTMLTable.java
+++ b/user/src/com/google/gwt/user/client/ui/HTMLTable.java
@@ -769,7 +769,6 @@
bodyElem = DOM.createTBody();
DOM.appendChild(tableElem, bodyElem);
setElement(tableElem);
- sinkEvents(Event.ONCLICK);
}
/**
@@ -780,6 +779,7 @@
public void addTableListener(TableListener listener) {
if (tableListeners == null) {
tableListeners = new TableListenerCollection();
+ sinkEvents(Event.ONCLICK);
}
tableListeners.add(listener);
}
diff --git a/user/src/com/google/gwt/user/client/ui/Label.java b/user/src/com/google/gwt/user/client/ui/Label.java
index b59f5bd..45eb7d8 100644
--- a/user/src/com/google/gwt/user/client/ui/Label.java
+++ b/user/src/com/google/gwt/user/client/ui/Label.java
@@ -16,6 +16,7 @@
package com.google.gwt.user.client.ui;
import com.google.gwt.user.client.DOM;
+import com.google.gwt.user.client.Element;
import com.google.gwt.user.client.Event;
/**
@@ -45,11 +46,19 @@
*/
public Label() {
setElement(DOM.createDiv());
- sinkEvents(Event.ONCLICK | Event.MOUSEEVENTS | Event.ONMOUSEWHEEL);
setStyleName("gwt-Label");
}
/**
+ * This constructor is used to let the HTML constructors avoid work.
+ *
+ * @param element element
+ */
+ Label(Element element) {
+ setElement(element);
+ }
+
+ /**
* Creates a label with the specified text.
*
* @param text the new label's text
@@ -73,6 +82,7 @@
public void addClickListener(ClickListener listener) {
if (clickListeners == null) {
clickListeners = new ClickListenerCollection();
+ sinkEvents(Event.ONCLICK);
}
clickListeners.add(listener);
}
@@ -80,6 +90,7 @@
public void addMouseListener(MouseListener listener) {
if (mouseListeners == null) {
mouseListeners = new MouseListenerCollection();
+ sinkEvents(Event.MOUSEEVENTS);
}
mouseListeners.add(listener);
}
@@ -87,6 +98,7 @@
public void addMouseWheelListener(MouseWheelListener listener) {
if (mouseWheelListeners == null) {
mouseWheelListeners = new MouseWheelListenerCollection();
+ sinkEvents(Event.ONMOUSEWHEEL);
}
mouseWheelListeners.add(listener);
}
diff --git a/user/src/com/google/gwt/user/client/ui/ListBox.java b/user/src/com/google/gwt/user/client/ui/ListBox.java
index f0401b4..b9af87f 100644
--- a/user/src/com/google/gwt/user/client/ui/ListBox.java
+++ b/user/src/com/google/gwt/user/client/ui/ListBox.java
@@ -156,13 +156,13 @@
*/
public ListBox(boolean isMultipleSelect) {
super(DOM.createSelect(isMultipleSelect));
- sinkEvents(Event.ONCHANGE);
setStyleName("gwt-ListBox");
}
public void addChangeListener(ChangeListener listener) {
if (changeListeners == null) {
changeListeners = new ChangeListenerCollection();
+ sinkEvents(Event.ONCHANGE);
}
changeListeners.add(listener);
}
diff --git a/user/src/com/google/gwt/user/client/ui/TextBoxBase.java b/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
index b6fff33..5daea11 100644
--- a/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
+++ b/user/src/com/google/gwt/user/client/ui/TextBoxBase.java
@@ -24,8 +24,8 @@
/**
* Abstract base class for all text entry widgets.
*/
-public class TextBoxBase extends FocusWidget implements SourcesKeyboardEvents,
- SourcesChangeEvents, SourcesClickEvents, HasText, HasName {
+public class TextBoxBase extends FocusWidget implements SourcesChangeEvents,
+ HasText, HasName {
/**
* Text alignment constant, used in
@@ -70,9 +70,7 @@
private static TextBoxImpl impl = GWT.create(TextBoxImpl.class);
private ChangeListenerCollection changeListeners;
- private ClickListenerCollection clickListeners;
private Event currentEvent;
- private KeyboardListenerCollection keyboardListeners;
/**
* Creates a text box that wraps the given browser element handle. This is
@@ -82,32 +80,16 @@
*/
protected TextBoxBase(Element elem) {
super(elem);
- sinkEvents(Event.ONCHANGE);
}
public void addChangeListener(ChangeListener listener) {
if (changeListeners == null) {
changeListeners = new ChangeListenerCollection();
+ sinkEvents(Event.ONCHANGE);
}
changeListeners.add(listener);
}
- @Override
- public void addClickListener(ClickListener listener) {
- if (clickListeners == null) {
- clickListeners = new ClickListenerCollection();
- }
- clickListeners.add(listener);
- }
-
- @Override
- public void addKeyboardListener(KeyboardListener listener) {
- if (keyboardListeners == null) {
- keyboardListeners = new KeyboardListenerCollection();
- }
- keyboardListeners.add(listener);
- }
-
/**
* If a keyboard event is currently being handled on this text box, calling
* this method will suppress it. This allows listeners to easily filter
@@ -168,27 +150,23 @@
@Override
public void onBrowserEvent(Event event) {
- // Call the superclass' implementation first (because FocusWidget fires
- // some events itself).
- super.onBrowserEvent(event);
-
int type = DOM.eventGetType(event);
- if ((keyboardListeners != null) && (type & Event.KEYEVENTS) != 0) {
+ if ((type & Event.KEYEVENTS) != 0) {
// Fire the keyboard event. Hang on to the current event object so that
// cancelKey() and setKey() can be implemented.
currentEvent = event;
- keyboardListeners.fireKeyboardEvent(this, event);
+ // Call the superclass' onBrowserEvent as that includes the key event
+ // handlers.
+ super.onBrowserEvent(event);
currentEvent = null;
- } else if (type == Event.ONCLICK) {
- // Fire the click event.
- if (clickListeners != null) {
- clickListeners.fireClick(this);
- }
} else if (type == Event.ONCHANGE) {
// Fire the change event.
if (changeListeners != null) {
changeListeners.fireChange(this);
}
+ } else {
+ // Handles Focus and Click events.
+ super.onBrowserEvent(event);
}
}
@@ -198,20 +176,6 @@
}
}
- @Override
- public void removeClickListener(ClickListener listener) {
- if (clickListeners != null) {
- clickListeners.remove(listener);
- }
- }
-
- @Override
- public void removeKeyboardListener(KeyboardListener listener) {
- if (keyboardListeners != null) {
- keyboardListeners.remove(listener);
- }
- }
-
/**
* Selects all of the text in the box.
*/