Start at adding media events for audio/video elements. Note, the underlying implementation for HTML5 media event handling is expected to change in the near future. Review at http://gwt-code-reviews.appspot.com/1385804 Review by: pdr@google.com git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9887 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java b/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java index 6f1dfc1..2589bfd 100644 --- a/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java +++ b/dev/core/src/com/google/gwt/dev/js/ast/JsRootScope.java
@@ -237,6 +237,11 @@ "ongesturechange", "ongestureend", + // Media events + "oncanplaythrough", + "onended", + "onprogress", + // extra window methods "uneval",
diff --git a/user/src/com/google/gwt/event/dom/client/CanPlayThroughEvent.java b/user/src/com/google/gwt/event/dom/client/CanPlayThroughEvent.java new file mode 100644 index 0000000..3a65e67 --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/CanPlayThroughEvent.java
@@ -0,0 +1,64 @@ +/* + * Copyright 2011 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; + +/** + * Represents a native media can play through event. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public class CanPlayThroughEvent extends DomEvent<CanPlayThroughHandler> { + + /** + * Event type for media can play through events. Represents the meta-data + * associated with this event. + */ + private static final Type<CanPlayThroughHandler> TYPE = new Type< + CanPlayThroughHandler>("canplaythrough", new CanPlayThroughEvent()); + + /** + * Gets the event type associated with media can play through events. + * + * @return the handler type + */ + public static Type<CanPlayThroughHandler> getType() { + return TYPE; + } + + /** + * Protected constructor, use {@link + * DomEvent#fireNativeEvent(com.google.gwt.dom.client.NativeEvent, + * com.google.gwt.event.shared.HasHandlers)} to fire media can play through + * events. + */ + protected CanPlayThroughEvent() { + } + + @Override + public final Type<CanPlayThroughHandler> getAssociatedType() { + return TYPE; + } + + + @Override + protected void dispatch(CanPlayThroughHandler handler) { + handler.onCanPlayThrough(this); + } +} \ No newline at end of file
diff --git a/user/src/com/google/gwt/event/dom/client/CanPlayThroughHandler.java b/user/src/com/google/gwt/event/dom/client/CanPlayThroughHandler.java new file mode 100644 index 0000000..9d89477 --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/CanPlayThroughHandler.java
@@ -0,0 +1,37 @@ +/* + * Copyright 2011 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.event.shared.EventHandler; + +/** + * Handler interface for {@link CanPlayThroughEvent} events. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public interface CanPlayThroughHandler extends EventHandler { + + /** + * Called when CanPlayThroughEvent is fired. + * + * @param event the {@link CanPlayThroughEvent} that was fired + */ + void onCanPlayThrough(CanPlayThroughEvent event); +} \ No newline at end of file
diff --git a/user/src/com/google/gwt/event/dom/client/EndedEvent.java b/user/src/com/google/gwt/event/dom/client/EndedEvent.java new file mode 100644 index 0000000..45c5824 --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/EndedEvent.java
@@ -0,0 +1,63 @@ +/* + * Copyright 2011 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; + +/** + * Represents a native media ended event. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public class EndedEvent extends DomEvent<EndedHandler> { + + /** + * Event type for media ended events. Represents the meta-data associated with + * this event. + */ + private static final Type<EndedHandler> TYPE = new Type< + EndedHandler>("ended", new EndedEvent()); + + /** + * Gets the event type associated with media ended events. + * + * @return the handler type + */ + public static Type<EndedHandler> getType() { + return TYPE; + } + + /** + * Protected constructor, use {@link + * DomEvent#fireNativeEvent(com.google.gwt.dom.client.NativeEvent, + * com.google.gwt.event.shared.HasHandlers)} to fire media ended events. + */ + protected EndedEvent() { + } + + @Override + public final Type<EndedHandler> getAssociatedType() { + return TYPE; + } + + + @Override + protected void dispatch(EndedHandler handler) { + handler.onEnded(this); + } +} \ No newline at end of file
diff --git a/user/src/com/google/gwt/event/dom/client/EndedHandler.java b/user/src/com/google/gwt/event/dom/client/EndedHandler.java new file mode 100644 index 0000000..775a662 --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/EndedHandler.java
@@ -0,0 +1,37 @@ +/* + * Copyright 2011 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.event.shared.EventHandler; + +/** + * Handler interface for {@link EndedEvent} events. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public interface EndedHandler extends EventHandler { + + /** + * Called when EndedEvent is fired. + * + * @param event the {@link EndedEvent} that was fired + */ + void onEnded(EndedEvent event); +} \ No newline at end of file
diff --git a/user/src/com/google/gwt/event/dom/client/HasAllMediaHandlers.java b/user/src/com/google/gwt/event/dom/client/HasAllMediaHandlers.java new file mode 100644 index 0000000..58422f5 --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/HasAllMediaHandlers.java
@@ -0,0 +1,31 @@ +/* + * Copyright 2011 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; + +/** + * This is a convenience interface that includes all media handlers defined by + * the core GWT system. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public interface HasAllMediaHandlers extends HasEndedHandlers, + HasProgressHandlers, HasCanPlayThroughHandlers { +} \ No newline at end of file
diff --git a/user/src/com/google/gwt/event/dom/client/HasCanPlayThroughHandlers.java b/user/src/com/google/gwt/event/dom/client/HasCanPlayThroughHandlers.java new file mode 100644 index 0000000..c85e88f --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/HasCanPlayThroughHandlers.java
@@ -0,0 +1,39 @@ +/* + * Copyright 2011 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.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.HasHandlers; + +/** + * A widget that implements this interface provides registration for + * {@link CanPlayThroughHandler} instances. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public interface HasCanPlayThroughHandlers extends HasHandlers { + /** + * Adds a {@link CanPlayThroughEvent} handler. + * + * @param handler the media CanPlayThrough handler + * @return {@link HandlerRegistration} used to remove this handler + */ + HandlerRegistration addCanPlayThroughHandler(CanPlayThroughHandler handler); +}
diff --git a/user/src/com/google/gwt/event/dom/client/HasEndedHandlers.java b/user/src/com/google/gwt/event/dom/client/HasEndedHandlers.java new file mode 100644 index 0000000..6e1f2de --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/HasEndedHandlers.java
@@ -0,0 +1,39 @@ +/* + * Copyright 2011 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.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.HasHandlers; + +/** + * A widget that implements this interface provides registration for + * {@link EndedHandler} instances. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public interface HasEndedHandlers extends HasHandlers { + /** + * Adds a {@link EndedEvent} handler. + * + * @param handler the media ended handler + * @return {@link HandlerRegistration} used to remove this handler + */ + HandlerRegistration addEndedHandler(EndedHandler handler); +}
diff --git a/user/src/com/google/gwt/event/dom/client/HasProgressHandlers.java b/user/src/com/google/gwt/event/dom/client/HasProgressHandlers.java new file mode 100644 index 0000000..526bf3a --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/HasProgressHandlers.java
@@ -0,0 +1,39 @@ +/* + * Copyright 2011 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.event.shared.HandlerRegistration; +import com.google.gwt.event.shared.HasHandlers; + +/** + * A widget that implements this interface provides registration for + * {@link ProgressHandler} instances. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public interface HasProgressHandlers extends HasHandlers { + /** + * Adds a {@link ProgressEvent} handler. + * + * @param handler the media progress handler + * @return {@link HandlerRegistration} used to remove this handler + */ + HandlerRegistration addProgressHandler(ProgressHandler handler); +}
diff --git a/user/src/com/google/gwt/event/dom/client/ProgressEvent.java b/user/src/com/google/gwt/event/dom/client/ProgressEvent.java new file mode 100644 index 0000000..4fa6a5e --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/ProgressEvent.java
@@ -0,0 +1,63 @@ +/* + * Copyright 2011 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; + +/** + * Represents a native media progress event. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public class ProgressEvent extends DomEvent<ProgressHandler> { + + /** + * Event type for media progress events. Represents the meta-data associated + * with this event. + */ + private static final Type<ProgressHandler> TYPE = new Type< + ProgressHandler>("progress", new ProgressEvent()); + + /** + * Gets the event type associated with media progress events. + * + * @return the handler type + */ + public static Type<ProgressHandler> getType() { + return TYPE; + } + + /** + * Protected constructor, use {@link + * DomEvent#fireNativeEvent(com.google.gwt.dom.client.NativeEvent, + * com.google.gwt.event.shared.HasHandlers)} to fire media progress events. + */ + protected ProgressEvent() { + } + + @Override + public final Type<ProgressHandler> getAssociatedType() { + return TYPE; + } + + + @Override + protected void dispatch(ProgressHandler handler) { + handler.onProgress(this); + } +} \ No newline at end of file
diff --git a/user/src/com/google/gwt/event/dom/client/ProgressHandler.java b/user/src/com/google/gwt/event/dom/client/ProgressHandler.java new file mode 100644 index 0000000..f4aaad3 --- /dev/null +++ b/user/src/com/google/gwt/event/dom/client/ProgressHandler.java
@@ -0,0 +1,37 @@ +/* + * Copyright 2011 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.event.shared.EventHandler; + +/** + * Handler interface for {@link ProgressEvent} events. + * + * <p> + * <span style="color:red">Experimental API: This API is still under development + * and is subject to change. + * </span> + * </p> + */ +public interface ProgressHandler extends EventHandler { + + /** + * Called when ProgressEvent is fired. + * + * @param event the {@link ProgressEvent} that was fired + */ + void onProgress(ProgressEvent event); +} \ No newline at end of file
diff --git a/user/src/com/google/gwt/media/client/Audio.java b/user/src/com/google/gwt/media/client/Audio.java index 987dbb2..4152298 100644 --- a/user/src/com/google/gwt/media/client/Audio.java +++ b/user/src/com/google/gwt/media/client/Audio.java
@@ -19,6 +19,14 @@ import com.google.gwt.dom.client.AudioElement; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.PartialSupport; +import com.google.gwt.event.dom.client.CanPlayThroughEvent; +import com.google.gwt.event.dom.client.CanPlayThroughHandler; +import com.google.gwt.event.dom.client.EndedEvent; +import com.google.gwt.event.dom.client.EndedHandler; +import com.google.gwt.event.dom.client.HasAllMediaHandlers; +import com.google.gwt.event.dom.client.ProgressEvent; +import com.google.gwt.event.dom.client.ProgressHandler; +import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.FocusWidget; /** @@ -34,7 +42,7 @@ * This widget may not be supported on all browsers. */ @PartialSupport -public class Audio extends FocusWidget { +public class Audio extends FocusWidget implements HasAllMediaHandlers { private static AudioElementSupportDetector detector; /** @@ -83,6 +91,18 @@ setElement(element); } + public HandlerRegistration addCanPlayThroughHandler(CanPlayThroughHandler handler) { + return addDomHandler(handler, CanPlayThroughEvent.getType()); + } + + public HandlerRegistration addEndedHandler(EndedHandler handler) { + return addDomHandler(handler, EndedEvent.getType()); + } + + public HandlerRegistration addProgressHandler(ProgressHandler handler) { + return addDomHandler(handler, ProgressEvent.getType()); + } + /** * Returns the attached AudioElement. *
diff --git a/user/src/com/google/gwt/media/client/Video.java b/user/src/com/google/gwt/media/client/Video.java index 92ed14e..74eb17d 100644 --- a/user/src/com/google/gwt/media/client/Video.java +++ b/user/src/com/google/gwt/media/client/Video.java
@@ -18,6 +18,14 @@ import com.google.gwt.core.client.GWT; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.VideoElement; +import com.google.gwt.event.dom.client.CanPlayThroughEvent; +import com.google.gwt.event.dom.client.CanPlayThroughHandler; +import com.google.gwt.event.dom.client.EndedEvent; +import com.google.gwt.event.dom.client.EndedHandler; +import com.google.gwt.event.dom.client.HasAllMediaHandlers; +import com.google.gwt.event.dom.client.ProgressEvent; +import com.google.gwt.event.dom.client.ProgressHandler; +import com.google.gwt.event.shared.HandlerRegistration; import com.google.gwt.user.client.ui.FocusWidget; /** @@ -32,7 +40,7 @@ * * This widget may not be supported on all browsers. */ -public class Video extends FocusWidget { +public class Video extends FocusWidget implements HasAllMediaHandlers { private static VideoElementSupportDetector detector; /** @@ -90,6 +98,18 @@ getVideoElement().setSrc(src); } + public HandlerRegistration addCanPlayThroughHandler(CanPlayThroughHandler handler) { + return addDomHandler(handler, CanPlayThroughEvent.getType()); + } + + public HandlerRegistration addEndedHandler(EndedHandler handler) { + return addDomHandler(handler, EndedEvent.getType()); + } + + public HandlerRegistration addProgressHandler(ProgressHandler handler) { + return addDomHandler(handler, ProgressEvent.getType()); + } + /** * Returns the attached VideoElement. *
diff --git a/user/src/com/google/gwt/user/client/DOM.java b/user/src/com/google/gwt/user/client/DOM.java index 32329cd..180a60b 100644 --- a/user/src/com/google/gwt/user/client/DOM.java +++ b/user/src/com/google/gwt/user/client/DOM.java
@@ -1211,6 +1211,17 @@ } /** + * Sinks a named event. Events will be fired to the nearest + * {@link EventListener} specified on any of the element's parents. + * + * @param elem the element whose events are to be retrieved + * @param eventTypeName name of the event to sink on this element + */ + public static void sinkBitlessEvent(Element elem, String eventTypeName) { + impl.sinkBitlessEvent(elem, eventTypeName); + } + + /** * Sets the current set of events sunk by a given element. These events will * be fired to the nearest {@link EventListener} specified on any of the * element's parents.
diff --git a/user/src/com/google/gwt/user/client/Event.java b/user/src/com/google/gwt/user/client/Event.java index f1e646e..317ff7e 100644 --- a/user/src/com/google/gwt/user/client/Event.java +++ b/user/src/com/google/gwt/user/client/Event.java
@@ -399,6 +399,50 @@ 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 * reliable across all supported browsers.
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImpl.java b/user/src/com/google/gwt/user/client/impl/DOMImpl.java index 79c8b15..9493730 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImpl.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImpl.java
@@ -92,6 +92,9 @@ 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; } }-*/; @@ -131,6 +134,8 @@ elem.__listener = listener; }-*/; + public abstract void sinkBitlessEvent(Element elem, String eventTypeName); + public abstract void sinkEvents(Element elem, int eventBits); /**
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java index dd70a3a..f9c44ec 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplStandard.java
@@ -133,6 +133,12 @@ } @Override + public void sinkBitlessEvent(Element elem, String eventTypeName) { + maybeInitializeEventSystem(); + sinkBitlessEventImpl(elem, eventTypeName); + } + + @Override public void sinkEvents(Element elem, int bits) { maybeInitializeEventSystem(); sinkEventsImpl(elem, bits); @@ -205,6 +211,17 @@ $wnd.addEventListener('gestureend', @com.google.gwt.user.client.impl.DOMImplStandard::dispatchCapturedMouseEvent, true); }-*/; + protected native void sinkBitlessEventImpl(Element elem, String eventTypeName) /*-{ + if (eventTypeName == "dragenter") + elem.ondragenter = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent; + if (eventTypeName == "dragexit") + elem.ondragexit = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent; + if (eventTypeName == "dragover") + elem.ondragover = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent; + if (eventTypeName == "drop") + elem.ondrop = @com.google.gwt.user.client.impl.DOMImplStandard::dispatchEvent; + }-*/; + protected native void sinkEventsImpl(Element elem, int bits) /*-{ var chMask = (elem.__eventBits || 0) ^ bits; elem.__eventBits = bits;
diff --git a/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java b/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java index 474cd7d..94d196d 100644 --- a/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java +++ b/user/src/com/google/gwt/user/client/impl/DOMImplTrident.java
@@ -219,6 +219,11 @@ } @Override + public void sinkBitlessEvent(Element elem, String eventTypeName) { + // not supported + } + + @Override public void sinkEvents(Element elem, int bits) { maybeInitializeEventSystem(); sinkEventsImpl(elem, bits);
diff --git a/user/src/com/google/gwt/user/client/ui/UIObject.java b/user/src/com/google/gwt/user/client/ui/UIObject.java index d891873..e8abab3 100644 --- a/user/src/com/google/gwt/user/client/ui/UIObject.java +++ b/user/src/com/google/gwt/user/client/ui/UIObject.java
@@ -753,6 +753,18 @@ } /** + * Sinks a named event. Note that only {@link Widget widgets} may actually + * receive events, but can receive events from all objects contained within + * them. + * + * @param eventTypeName name of the event to sink on this element + * @see com.google.gwt.user.client.Event + */ + public void sinkBitlessEvent(String eventTypeName) { + DOM.sinkBitlessEvent(getElement(), eventTypeName); + } + + /** * Adds a set of events to be sunk by this object. Note that only * {@link Widget widgets} may actually receive events, but can receive events * from all objects contained within them.
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 18082ab..7bc1ba3 100644 --- a/user/src/com/google/gwt/user/client/ui/Widget.java +++ b/user/src/com/google/gwt/user/client/ui/Widget.java
@@ -64,6 +64,28 @@ } /** + * For <a href= + * "http://code.google.com/p/google-web-toolkit/wiki/UnderstandingMemoryLeaks" + * >browsers which do not leak</a>, adds a native event handler to the widget. + * Note that, unlike the + * {@link #addDomHandler(EventHandler, com.google.gwt.event.dom.client.DomEvent.Type)} + * implementation, there is no need to attach the widget to the DOM in order + * to cause the event handlers to be attached. + * + * @param <H> the type of handler to add + * @param type the event key + * @param handler the handler + * @return {@link HandlerRegistration} used to remove the handler + */ + public final <H extends EventHandler> HandlerRegistration addBitlessDomHandler( + final H handler, DomEvent.Type<H> type) { + assert handler != null : "handler must not be null"; + assert type != null : "type must not be null"; + sinkBitlessEvent(type.getName()); + return ensureHandlers().addHandler(type, handler); + } + + /** * Adds a native event handler to the widget and sinks the corresponding * native event. If you do not want to sink the native event, use the generic * addHandler method instead.
diff --git a/user/test/com/google/gwt/media/MediaSuite.java b/user/test/com/google/gwt/media/MediaSuite.java index 388c736..1ecc7e4 100644 --- a/user/test/com/google/gwt/media/MediaSuite.java +++ b/user/test/com/google/gwt/media/MediaSuite.java
@@ -17,6 +17,7 @@ package com.google.gwt.media; import com.google.gwt.junit.tools.GWTTestSuite; +import com.google.gwt.user.client.MediaEventsSinkTest; import junit.framework.Test; @@ -27,6 +28,8 @@ public static Test suite() { GWTTestSuite suite = new GWTTestSuite("Test suite for Media GWTTestCases"); + suite.addTestSuite(MediaEventsSinkTest.class); + /* * Tests disabled temporarily * suite.addTestSuite(AudioTest.class);
diff --git a/user/test/com/google/gwt/user/client/MediaEventsSinkTest.java b/user/test/com/google/gwt/user/client/MediaEventsSinkTest.java new file mode 100644 index 0000000..b457d91 --- /dev/null +++ b/user/test/com/google/gwt/user/client/MediaEventsSinkTest.java
@@ -0,0 +1,160 @@ +/* + * Copyright 2011 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.dom.client.CanPlayThroughEvent; +import com.google.gwt.event.dom.client.CanPlayThroughHandler; +import com.google.gwt.event.dom.client.EndedEvent; +import com.google.gwt.event.dom.client.EndedHandler; +import com.google.gwt.event.dom.client.HasAllMediaHandlers; +import com.google.gwt.event.dom.client.ProgressEvent; +import com.google.gwt.event.dom.client.ProgressHandler; +import com.google.gwt.junit.client.GWTTestCase; +import com.google.gwt.media.client.Audio; +import com.google.gwt.media.client.Video; +import com.google.gwt.user.client.ui.RootPanel; +import com.google.gwt.user.client.ui.Widget; + +/** + * Test Case for sinking of media events. + */ +public class MediaEventsSinkTest extends GWTTestCase { + + @Override + public String getModuleName() { + return "com.google.gwt.user.User"; + } + + public void testAudioMediaEventsSinkByAddingHandler() { + if (!Audio.isSupported()) { + return; + } + verifyProgressEventSinkOnAddHandler(Audio.createIfSupported()); + verifyEndedEventSinkOnAddHandler(Audio.createIfSupported()); + verifyCanPlayThroughEventSinkOnAddHandler(Audio.createIfSupported()); + } + + 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); + } + + @Override + protected void gwtTearDown() throws Exception { + // clean up after ourselves + RootPanel.get().clear(); + super.gwtTearDown(); + } + + 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); + } + + 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); + } + + private boolean isCanPlayThroughEventSunk(Element e) { + return (DOM.getEventsSunk(e) & Event.ONCANPLAYTHROUGH) != 0; + } + + private boolean isEndedEventSunk(Element e) { + return (DOM.getEventsSunk(e) & Event.ONENDED) != 0; + } + + private boolean isProgressEventSunk(Element e) { + return (DOM.getEventsSunk(e) & Event.ONPROGRESS) != 0; + } + + 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) { + } + }); + + assertSunkAfterAddHandler(w, CanPlayThroughEvent.getType().getName(), + isCanPlayThroughEventSunk(e)); + } + + private <W extends Widget & HasAllMediaHandlers> void verifyEndedEventSinkOnAddHandler( + W w) { + verifyEndedEventSinkOnAddHandler(w, w.getElement()); + } + + 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) { + } + }); + + assertSunkAfterAddHandler(w, EndedEvent.getType().getName(), + isEndedEventSunk(e)); + } + + private <W extends Widget & HasAllMediaHandlers> void verifyProgressEventSinkOnAddHandler( + W w) { + verifyProgressEventSinkOnAddHandler(w, w.getElement()); + } + + 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) { + } + }); + + assertSunkAfterAddHandler(w, ProgressEvent.getType().getName(), + isProgressEventSunk(e)); + } +} \ No newline at end of file