Revision: 10274
Author:   [email protected]
Date:     Fri Jun  3 10:56:12 2011
Log: Making media events bitless, freeing up a few event bits, since modern,
implementing browsers don't leak the way old ones did.

The following constants, marked as 'experimental', have been removed:
- com.google.gwt.user.client.Event.MEDIAEVENTS
- com.google.gwt.user.client.Event.ONCANPLAYTHROUGH
- com.google.gwt.user.client.Event.ONENDED
- com.google.gwt.user.client.Event.ONPROGRESS

Review at http://gwt-code-reviews.appspot.com/1447816

Review by: [email protected]
http://code.google.com/p/google-web-toolkit/source/detail?r=10274

Modified:
 /trunk/tools/api-checker/config/gwt23_24userApi.conf
 /trunk/user/src/com/google/gwt/media/client/MediaBase.java
 /trunk/user/src/com/google/gwt/user/client/Event.java
 /trunk/user/src/com/google/gwt/user/client/impl/DOMImpl.java
 /trunk/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
 /trunk/user/test/com/google/gwt/user/client/MediaEventsSinkTest.java

=======================================
--- /trunk/tools/api-checker/config/gwt23_24userApi.conf Thu Jun 2 11:49:52 2011 +++ /trunk/tools/api-checker/config/gwt23_24userApi.conf Fri Jun 3 10:56:12 2011
@@ -142,3 +142,8 @@
# Overloading AbstractHasData constructor to allow a widget or element as the root. com.google.gwt.user.cellview.client.AbstractHasData::AbstractHasData(Lcom/google/gwt/dom/client/Element;ILcom/google/gwt/view/client/ProvidesKey;) OVERLOADED_METHOD_CALL

+# Bitless media events no longer these experimental API constants
+com.google.gwt.user.client.Event::MEDIAEVENTS MISSING
+com.google.gwt.user.client.Event::ONCANPLAYTHROUGH MISSING
+com.google.gwt.user.client.Event::ONENDED MISSING
+com.google.gwt.user.client.Event::ONPROGRESS MISSING
=======================================
--- /trunk/user/src/com/google/gwt/media/client/MediaBase.java Mon May 2 06:45:06 2011 +++ /trunk/user/src/com/google/gwt/media/client/MediaBase.java Fri Jun 3 10:56:12 2011
@@ -49,17 +49,20 @@
     setElement(element);
   }

+  @Override
   public HandlerRegistration addCanPlayThroughHandler(
       CanPlayThroughHandler handler) {
-    return addDomHandler(handler, CanPlayThroughEvent.getType());
+    return addBitlessDomHandler(handler, CanPlayThroughEvent.getType());
   }

+  @Override
   public HandlerRegistration addEndedHandler(EndedHandler handler) {
-    return addDomHandler(handler, EndedEvent.getType());
+    return addBitlessDomHandler(handler, EndedEvent.getType());
   }

+  @Override
   public HandlerRegistration addProgressHandler(ProgressHandler handler) {
-    return addDomHandler(handler, ProgressEvent.getType());
+    return addBitlessDomHandler(handler, ProgressEvent.getType());
   }

   /**
=======================================
--- /trunk/user/src/com/google/gwt/user/client/Event.java Wed Mar 23 13:32:42 2011 +++ /trunk/user/src/com/google/gwt/user/client/Event.java Fri Jun 3 10:56:12 2011
@@ -398,50 +398,6 @@
    */
public static final int GESTUREEVENTS = ONGESTURESTART | ONGESTURECHANGE | ONGESTUREEND;

-  /**
- * Fired when media is fully buffered and can be played through to the end.
-   *
-   * <p>
- * <span style="color:red">Experimental API: This API is still under development
-   * and is subject to change.
-   * </span>
-   * </p>
-   */
-  public static final int ONCANPLAYTHROUGH = 0x20000000;
-
-  /**
-   * Fired when media stops playing.
-   *
-   * <p>
- * <span style="color:red">Experimental API: This API is still under development
-   * and is subject to change.
-   * </span>
-   * </p>
-   */
-  public static final int ONENDED = 0x8000000;
-
-  /**
-   * Fired when progress is made downloading media.
-   *
-   * <p>
- * <span style="color:red">Experimental API: This API is still under development
-   * and is subject to change.
-   * </span>
-   * </p>
-   */
-  public static final int ONPROGRESS = 0x10000000;
-
-  /**
-   * A bit-mask covering all media events.
-   *
-   * <p>
- * <span style="color:red">Experimental API: This API is still under development
-   * and is subject to change.
-   * </span>
-   * </p>
-   */
- public static final int MEDIAEVENTS = ONCANPLAYTHROUGH | ONENDED | ONPROGRESS;
-
   /**
* Value returned by accessors when the actual integer value is undefined. In * Development Mode, most accessors assert that the requested attribute is
=======================================
--- /trunk/user/src/com/google/gwt/user/client/impl/DOMImpl.java Wed Mar 23 13:32:42 2011 +++ /trunk/user/src/com/google/gwt/user/client/impl/DOMImpl.java Fri Jun 3 10:56:12 2011
@@ -92,9 +92,6 @@
     case "gesturestart": return 0x1000000;
     case "gesturechange": return 0x2000000;
     case "gestureend": return 0x4000000;
-    case "ended": return 0x8000000;
-    case "progress": return 0x10000000;
-    case "canplaythrough": return 0x20000000;
     default: return -1;
     }
   }-*/;
=======================================
--- /trunk/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java Wed May 4 11:04:47 2011 +++ /trunk/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java Fri Jun 3 10:56:12 2011
@@ -220,20 +220,39 @@
   }-*/;

protected native void sinkBitlessEventImpl(Element elem, String eventTypeName) /*-{
-    if (eventTypeName == "drag")
- elem.ondrag = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
-    else if (eventTypeName == "dragend")
- elem.ondragend = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
-    else if (eventTypeName == "dragenter")
- elem.ondragenter = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchDragEvent;
-    else if (eventTypeName == "dragleave")
- elem.ondragleave = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
-    else if (eventTypeName == "dragover")
- elem.ondragover = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchDragEvent;
-    else if (eventTypeName == "dragstart")
- elem.ondragstart = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
-    else if (eventTypeName == "drop")
- elem.ondrop = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
+    switch(eventTypeName) {
+      case "drag":
+ elem.ondrag = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
+        break;
+      case "dragend":
+ elem.ondragend = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
+        break;
+      case "dragenter":
+ elem.ondragenter = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchDragEvent;
+        break;
+      case "dragleave":
+ elem.ondragleave = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
+        break;
+      case "dragover":
+ elem.ondragover = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchDragEvent;
+        break;
+      case "dragstart":
+ elem.ondragstart = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
+        break;
+      case "drop":
+ elem.ondrop = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent;
+        break;
+      case "canplaythrough":
+      case "ended":
+      case "progress":
+ // First call removeEventListener, so as not to add the same event listener more than once + elem.removeEventListener(eventTypeName, @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent, false); + elem.addEventListener(eventTypeName, @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent, false);
+        break;
+      default:
+        // catch missing cases
+        throw "Trying to sink unknown event type " + eventTypeName;
+    }
   }-*/;

   protected native void sinkEventsImpl(Element elem, int bits) /*-{
@@ -295,17 +314,6 @@
@com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
     if (chMask & 0x4000000) elem.ongestureend    = (bits & 0x4000000) ?
@com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent : null;
-
-    if (bits & 0x8000000) {
- elem.addEventListener('ended', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent, false);
-    } else {
- elem.removeEventListener('ended', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent, false);
-    }
-    if (bits & 0x10000000) {
- elem.addEventListener('progress', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent, false);
-    } else {
- elem.removeEventListener('progress', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent, false);
-    }
   }-*/;

   private native void releaseCaptureImpl(Element elem) /*-{
=======================================
--- /trunk/user/test/com/google/gwt/user/client/MediaEventsSinkTest.java Wed Mar 23 13:32:42 2011 +++ /trunk/user/test/com/google/gwt/user/client/MediaEventsSinkTest.java Fri Jun 3 10:56:12 2011
@@ -34,127 +34,136 @@
  */
 public class MediaEventsSinkTest extends GWTTestCase {

-  @Override
-  public String getModuleName() {
-    return "com.google.gwt.user.User";
+ private static class CanPlayThroughHandlerImpl extends HandlerImpl implements
+      CanPlayThroughHandler {
+    @Override
+    public void onCanPlayThrough(CanPlayThroughEvent event) {
+      eventFired();
+    }
   }

-  public void testAudioMediaEventsSinkByAddingHandler() {
-    if (!Audio.isSupported()) {
-      return;
-    }
-    verifyProgressEventSinkOnAddHandler(Audio.createIfSupported());
-    verifyEndedEventSinkOnAddHandler(Audio.createIfSupported());
-    verifyCanPlayThroughEventSinkOnAddHandler(Audio.createIfSupported());
+ private static class EndedHandlerImpl extends HandlerImpl implements EndedHandler {
+    @Override
+    public void onEnded(EndedEvent event) {
+      eventFired();
+    }
   }

-  public void testVideoMediaEventsSinkByAddingHandler() {
-    if (!Audio.isSupported()) {
-      return;
-    }
-    verifyProgressEventSinkOnAddHandler(Video.createIfSupported());
-    verifyEndedEventSinkOnAddHandler(Video.createIfSupported());
-    verifyCanPlayThroughEventSinkOnAddHandler(Video.createIfSupported());
-  }
-
-  public void testMediaEventBitFieldsNotTriviallyZero() {
-    assertNotSame(0, Event.ONCANPLAYTHROUGH);
-    assertNotSame(0, Event.ONPROGRESS);
-    assertNotSame(0, Event.ONENDED);
+  private static class HandlerImpl {
+    private boolean fired = false;
+
+    public void eventFired() {
+      fired = true;
+    }
+
+    boolean hasEventFired() {
+      return fired;
+    }
   }

-  @Override
-  protected void gwtTearDown() throws Exception {
-    // clean up after ourselves
-    RootPanel.get().clear();
-    super.gwtTearDown();
+ private static class ProgressHandlerImpl extends HandlerImpl implements ProgressHandler {
+    @Override
+    public void onProgress(ProgressEvent event) {
+      eventFired();
+    }
   }

- private <W extends Widget & HasAllMediaHandlers> void assertNotSunkAfterAttach(
-      W w, String eventName, boolean isSunk) {
-    assertFalse("Event should not be sunk on " + w.getClass().getName()
-        + " until a " + eventName + " handler has been added", isSunk);
+  /**
+   * Interface to create a widget.
+   *
+   * @param <W> the widget type
+   */
+  private interface WidgetCreator<W extends Widget & HasAllMediaHandlers> {
+    /**
+     * Create a widget to test.
+     *
+     * @return the new widget
+     */
+    W createWidget();
   }

- private <W extends Widget & HasAllMediaHandlers> void assertSunkAfterAddHandler(
-      W w, String eventName, boolean isSunk) {
-    assertTrue("Event should have been sunk on " + w.getClass().getName()
-        + " once the widget has been attached and a " + eventName
-        + " handler has been added", isSunk);
+  @Override
+  public String getModuleName() {
+    return "com.google.gwt.user.User";
   }

-  private boolean isCanPlayThroughEventSunk(Element e) {
-    return (DOM.getEventsSunk(e) & Event.ONCANPLAYTHROUGH) != 0;
-  }
-
-  private boolean isEndedEventSunk(Element e) {
-    return (DOM.getEventsSunk(e) & Event.ONENDED) != 0;
+  public void testAudioEventSink() {
+    // skip tests on browsers that do not support audio
+    if (!Audio.isSupported()) {
+      return;
+    }
+
+    verifyMediaEventSink(new WidgetCreator<Audio>() {
+      @Override
+      public Audio createWidget() {
+        return Audio.createIfSupported();
+      }
+    });
   }

-  private boolean isProgressEventSunk(Element e) {
-    return (DOM.getEventsSunk(e) & Event.ONPROGRESS) != 0;
+  public void testEventBitsUnmapped() throws Exception {
+    ProgressEvent.getType();
+    assertEquals(-1, Event.getTypeInt("progress"));
+    assertEquals(-1, Event.getTypeInt("ended"));
+    assertEquals(-1, Event.getTypeInt("canplaythrough"));
   }

- private <W extends Widget & HasAllMediaHandlers> void verifyCanPlayThroughEventSinkOnAddHandler(
-      W w) {
-    verifyCanPlayThroughEventSinkOnAddHandler(w, w.getElement());
-  }
-
- private <W extends Widget & HasAllMediaHandlers> void verifyCanPlayThroughEventSinkOnAddHandler(
-      W w, Element e) {
-    RootPanel.get().add(w);
-
-    assertNotSunkAfterAttach(w, CanPlayThroughEvent.getType().getName(),
-        isCanPlayThroughEventSunk(e));
-
-    w.addCanPlayThroughHandler(new CanPlayThroughHandler() {
-      public void onCanPlayThrough(CanPlayThroughEvent event) {
+  public void testVideoEventSink() {
+    // skip tests on browsers that do not support video
+    if (!Video.isSupported()) {
+      return;
+    }
+
+    verifyMediaEventSink(new WidgetCreator<Video>() {
+      @Override
+      public Video createWidget() {
+        return Video.createIfSupported();
       }
     });
-
-    assertSunkAfterAddHandler(w, CanPlayThroughEvent.getType().getName(),
-        isCanPlayThroughEventSunk(e));
   }

- private <W extends Widget & HasAllMediaHandlers> void verifyEndedEventSinkOnAddHandler(
-      W w) {
-    verifyEndedEventSinkOnAddHandler(w, w.getElement());
+  @Override
+  protected void gwtTearDown() throws Exception {
+    // clean up after ourselves
+    RootPanel.get().clear();
+    super.gwtTearDown();
   }

- private <W extends Widget & HasAllMediaHandlers> void verifyEndedEventSinkOnAddHandler(
-      W w, Element e) {
-    RootPanel.get().add(w);
-
-    assertNotSunkAfterAttach(w, EndedEvent.getType().getName(),
-        isEndedEventSunk(e));
-
-    w.addEndedHandler(new EndedHandler() {
-      public void onEnded(EndedEvent event) {
-      }
+ private <W extends Widget & HasAllMediaHandlers> void verifyCanPlayThroughEventSink(W w) {
+    CanPlayThroughHandlerImpl handler = new CanPlayThroughHandlerImpl();
+    w.addCanPlayThroughHandler(handler);
+
+    assertFalse(handler.hasEventFired());
+    w.fireEvent(new CanPlayThroughEvent() {
     });
-
-    assertSunkAfterAddHandler(w, EndedEvent.getType().getName(),
-        isEndedEventSunk(e));
+    assertTrue(handler.hasEventFired());
+  }
+
+ private <W extends Widget & HasAllMediaHandlers> void verifyEndedEventSink(W w) {
+    EndedHandlerImpl handler = new EndedHandlerImpl();
+    w.addEndedHandler(handler);
+
+    assertFalse(handler.hasEventFired());
+    w.fireEvent(new EndedEvent() {
+    });
+    assertTrue(handler.hasEventFired());
   }

- private <W extends Widget & HasAllMediaHandlers> void verifyProgressEventSinkOnAddHandler(
-      W w) {
-    verifyProgressEventSinkOnAddHandler(w, w.getElement());
+  private void verifyMediaEventSink(WidgetCreator<?>... creators) {
+    for (WidgetCreator<?> creator : creators) {
+      verifyProgressEventSink(creator.createWidget());
+      verifyCanPlayThroughEventSink(creator.createWidget());
+      verifyEndedEventSink(creator.createWidget());
+    }
   }

- private <W extends Widget & HasAllMediaHandlers> void verifyProgressEventSinkOnAddHandler(
-      W w, Element e) {
-    RootPanel.get().add(w);
-
-    assertNotSunkAfterAttach(w, ProgressEvent.getType().getName(),
-        isProgressEventSunk(e));
-
-    w.addProgressHandler(new ProgressHandler() {
-      public void onProgress(ProgressEvent event) {
-      }
+ private <W extends Widget & HasAllMediaHandlers> void verifyProgressEventSink(W w) {
+    ProgressHandlerImpl handler = new ProgressHandlerImpl();
+    w.addProgressHandler(handler);
+
+    assertFalse(handler.hasEventFired());
+    w.fireEvent(new ProgressEvent() {
     });
-
-    assertSunkAfterAddHandler(w, ProgressEvent.getType().getName(),
-        isProgressEventSunk(e));
+    assertTrue(handler.hasEventFired());
   }
 }

--
http://groups.google.com/group/Google-Web-Toolkit-Contributors

Reply via email to