Hi,
(this is a re-post of my original posting to the GWT Contributors list. Due
to suspected lack of interest there I post it here now)
I'm a huge fan of Web Notifications (or Desktop Notifications as called by
Webkit/Chrome, see http://www.w3.org/TR/notifications/) so I started to hack
away a very rudimentary implementation of them in GWT. My implementation
consists basically of four components: A Notification class acting as a
wrapper around a NativeNotification class which extends JavaScriptObject.
For handling the "display" event (which is called "show" in the W3C spec) I
created a class DisplayEvent extending DomEvent<DisplayHandler>.
For creating a Notification I borrowed the mechanism used in the
experimental Storage API of GWT 2.3:
final Notification popup = Notification.createIfSupported("", "Title",
"Body");
This creates a Notification object wrapping a NativeNotification object.
Since I'm not THAT firm with DOM events and stuff I would like you to
comment on my implementation and if it is somewhat usable or leaking memory
or sth.
The code is in prototype status and currently works in Chrome only.
Please find attached my implementation.
Cheers!
Max
--
You received this message because you are subscribed to the Google Groups
"Google Web Toolkit" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/google-web-toolkit?hl=en.
package de.maxwerner.gwtplayground.client;
import com.google.gwt.event.dom.client.DomEvent;
/**
* Represents a native display event.
*
* @author Max Jonas Werner <[email protected]>
*/
public class DisplayEvent extends DomEvent<DisplayHandler> {
/**
* Event type for display events. Represents the meta-data associated with
* this event.
*/
private static final com.google.gwt.event.dom.client.DomEvent.Type<DisplayHandler> TYPE = new com.google.gwt.event.dom.client.DomEvent.Type<DisplayHandler>(
"display", new DisplayEvent());
/**
* Gets the event type associated with display events.
*
* @return the handler type
*/
public static Type<DisplayHandler> getType() {
return TYPE;
}
/**
* Protected constructor, use
* {@link DomEvent#fireNativeEvent(com.google.gwt.dom.client.NativeEvent, com.google.gwt.event.shared.HasHandlers)}
* to fire display events.
*/
protected DisplayEvent() {
}
@Override
public final Type<DisplayHandler> getAssociatedType() {
return TYPE;
}
@Override
protected void dispatch(DisplayHandler handler) {
handler.onDisplay(this);
}
}
package de.maxwerner.gwtplayground.client;
import com.google.gwt.event.shared.EventHandler;
/**
* @author Max Jonas Werner <[email protected]>
*/
public interface DisplayHandler extends EventHandler {
public void onDisplay(DisplayEvent event);
}
package de.maxwerner.gwtplayground.client;
import com.google.gwt.core.client.JavaScriptObject;
/**
* Instances of this type represent a single notification window which can be
* displayed to the user and closed programatically. Use
* {@link Notification#createIfSupported(String, String, String)} to create an
* instance of this class.
*
* @author Max Jonas Werner <[email protected]>
*/
public class NativeNotification extends JavaScriptObject {
protected NativeNotification() {
}
public final native void show() /*-{
this.show();
}-*/;
public final native void cancel() /*-{
this.cancel();
}-*/;
}
package de.maxwerner.gwtplayground.client;
import java.util.ArrayList;
import java.util.List;
import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.GWT.UncaughtExceptionHandler;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.event.shared.HandlerRegistration;
/**
* Implementation of W3C's Web Notifications specification. Obtain a
* Notification object by invoking
* {@link #createIfSupported(String, String, String)} and then show it using the
* {@link #show()} method.
*
* @see <a href="http://www.w3.org/TR/notifications/">W3C Web Notifications</a>
*
* @author Max Jonas Werner <[email protected]>
*/
public class Notification {
private NativeNotification _nativePopup;
private List<DisplayHandler> _displayEventHandlers;
// this handler actually calls the attached GWT handlers when a 'display'
// event is fired by the notification window.
protected JavaScriptObject jsHandler;
public static Notification createIfSupported(final String icon, final String title, final String body) {
return new Notification(icon, title, body);
};
public void show() {
_nativePopup.show();
}
public void cancel() {
_nativePopup.cancel();
}
public static native void requestPermission() /*-{
window.webkitNotifications.requestPermission();
}-*/;
public HandlerRegistration addDisplayHandler(final DisplayHandler handler) {
getDisplayEventHandlers().add(handler);
if (_displayEventHandlers.size() == 1) {
addDisplayEventHandler0(this);
}
return new HandlerRegistration() {
@Override
public void removeHandler() {
Notification.this.removeDisplayEventHandler(handler);
}
};
}
public void removeDisplayEventHandler(DisplayHandler handler) {
getDisplayEventHandlers().remove(handler);
// IMHO no need to remove event handler 0 because
// it will be removed when the widget is destroyed.
}
public void handleDisplayEvent(DisplayEvent event) {
if (!hasDisplayEventHandlers()) {
return;
}
UncaughtExceptionHandler ueh = GWT.getUncaughtExceptionHandler();
for (DisplayHandler handler : _displayEventHandlers) {
if (ueh != null) {
try {
handler.onDisplay(event);
} catch (Throwable t) {
ueh.onUncaughtException(t);
}
} else {
handler.onDisplay(event);
}
}
}
protected boolean hasDisplayEventHandlers() {
return _displayEventHandlers != null && !_displayEventHandlers.isEmpty();
}
protected native void addDisplayEventHandler0(final Notification notification) /*-{
[email protected]::jsHandler = $entry(function(
event) {
[email protected]::handleDisplayEvent(Lde/maxwerner/gwtplayground/client/DisplayEvent;)(event);
});
[email protected]::_nativePopup.ondisplay = [email protected]::jsHandler;
}-*/;
protected List<DisplayHandler> getDisplayEventHandlers() {
if (_displayEventHandlers == null) {
_displayEventHandlers = new ArrayList<DisplayHandler>();
}
return _displayEventHandlers;
}
private Notification(final String icon, final String title, final String body) {
createNative(icon, title, body);
}
private native void createNative(String icon, String title, String body) /*-{
[email protected]::_nativePopup = window.webkitNotifications
.createNotification(icon, title, body);
}-*/;
}