| /* | |
| * Copyright 2012 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 $PACKAGE; | |
| $IMPORTS | |
| import com.google.gwt.core.client.GWT; | |
| import com.google.gwt.core.client.JavaScriptObject; | |
| import elemental.events.*; | |
| import elemental.util.*; | |
| import elemental.dom.*; | |
| import elemental.html.*; | |
| import elemental.svg.*; | |
| import elemental.js.util.JsElementalBase; | |
| import java.util.Date; | |
| /** | |
| * A base class containing all of the IDL interfaces which are shared | |
| * between disjoint type hierarchies. Because of the GWT compiler | |
| * SingleJsoImpl restriction that only a single JavaScriptObject | |
| * may implement a given interface, we hoist all of the explicit | |
| * mixin classes into a base JSO used by all of elemental. | |
| */ | |
| @Deprecated | |
| public class JsElementalMixinBase $EXTENDS $IMPLEMENTS { | |
| protected JsElementalMixinBase() {} | |
| $!MEMBERS | |
| private static class Remover implements EventRemover { | |
| private final EventTarget target; | |
| private final String type; | |
| private final JavaScriptObject handler; | |
| private final boolean useCapture; | |
| private Remover(EventTarget target, String type, JavaScriptObject handler, | |
| boolean useCapture) { | |
| this.target = target; | |
| this.type = type; | |
| this.handler = handler; | |
| this.useCapture = useCapture; | |
| } | |
| @Override | |
| public void remove() { | |
| removeEventListener(target, type, handler, useCapture); | |
| } | |
| private static Remover create(EventTarget target, String type, JavaScriptObject handler, | |
| boolean useCapture) { | |
| return new Remover(target, type, handler, useCapture); | |
| } | |
| } | |
| // NOTES: | |
| // - This handler/listener structure is currently the same in DevMode and ProdMode but it is | |
| // subject to change. In fact, I would like to use: | |
| // { listener : listener, handleEvent : function() } | |
| // but Firefox doesn't properly support that form of handler for onEvent type events. | |
| // - The handler property on listener can be removed when removeEventListener is removed. | |
| private native static JavaScriptObject createHandler(EventListener listener) /*-{ | |
| var handler = listener.handler; | |
| if (!handler) { | |
| handler = $entry(function(event) { | |
| @elemental.js.dom.JsElementalMixinBase::handleEvent(Lelemental/events/EventListener;Lelemental/events/Event;)(listener, event); | |
| }); | |
| handler.listener = listener; | |
| // TODO(knorton): Remove at Christmas when removeEventListener is removed. | |
| listener.handler = handler; | |
| } | |
| return handler; | |
| }-*/; | |
| private static class ForDevMode { | |
| private static java.util.Map<EventListener, JavaScriptObject> handlers; | |
| static { | |
| if (!com.google.gwt.core.client.GWT.isScript()) { | |
| handlers = new java.util.HashMap<EventListener, JavaScriptObject>(); | |
| } | |
| } | |
| private static JavaScriptObject getHandlerFor(EventListener listener) { | |
| if (listener == null) { | |
| return null; | |
| } | |
| JavaScriptObject handler = handlers.get(listener); | |
| if (handler == null) { | |
| handler = createHandler(listener); | |
| handlers.put(listener, handler); | |
| } | |
| return handler; | |
| } | |
| private native static JavaScriptObject createHandler(EventListener listener) /*-{ | |
| var handler = $entry(function(event) { | |
| @elemental.js.dom.JsElementalMixinBase::handleEvent(Lelemental/events/EventListener;Lelemental/events/Event;)(listener, event); | |
| }); | |
| handler.listener = listener; | |
| return handler; | |
| }-*/; | |
| private native static EventListener getListenerFor(JavaScriptObject handler) /*-{ | |
| return handler && handler.listener; | |
| }-*/; | |
| } | |
| private static class ForProdMode { | |
| private static JavaScriptObject getHandlerFor(EventListener listener) { | |
| return listener == null ? null : createHandler(listener); | |
| } | |
| private native static EventListener getListenerFor(JavaScriptObject handler) /*-{ | |
| return handler && handler.listener; | |
| }-*/; | |
| } | |
| private static void handleEvent(EventListener listener, Event event) { | |
| listener.handleEvent(event); | |
| } | |
| private static EventListener getListenerFor(JavaScriptObject handler) { | |
| return com.google.gwt.core.client.GWT.isScript() | |
| ? ForProdMode.getListenerFor(handler) | |
| : ForDevMode.getListenerFor(handler); | |
| } | |
| private static JavaScriptObject getHandlerFor(EventListener listener) { | |
| return com.google.gwt.core.client.GWT.isScript() | |
| ? ForProdMode.getHandlerFor(listener) | |
| : ForDevMode.getHandlerFor(listener); | |
| } | |
| public native final EventRemover addEventListener(String type, EventListener listener, boolean useCapture) /*-{ | |
| var handler = @elemental.js.dom.JsElementalMixinBase::getHandlerFor(Lelemental/events/EventListener;)(listener); | |
| this.addEventListener(type, handler, useCapture); | |
| return @elemental.js.dom.JsElementalMixinBase.Remover::create(Lelemental/events/EventTarget;Ljava/lang/String;Lcom/google/gwt/core/client/JavaScriptObject;Z) | |
| (this, type, handler, useCapture); | |
| }-*/; | |
| public final EventRemover addEventListener(String type, EventListener listener) { | |
| return addEventListener(type, listener, false); | |
| } | |
| @Deprecated | |
| public final void removeEventListener(String type, EventListener listener, boolean useCapture) { | |
| final JavaScriptObject handler = getHandlerFor(listener); | |
| if (handler != null) { | |
| removeEventListener(this, type, handler, useCapture); | |
| } | |
| } | |
| @Deprecated | |
| public final void removeEventListener(String type, EventListener listener) { | |
| final JavaScriptObject handler = getHandlerFor(listener); | |
| if (handler != null) { | |
| removeEventListener(this, type, handler); | |
| } | |
| } | |
| private static native void removeEventListener(EventTarget target, String type, | |
| JavaScriptObject handler, boolean useCapture) /*-{ | |
| target.removeEventListener(type, handler, useCapture); | |
| }-*/; | |
| private static native void removeEventListener(EventTarget target, String type, | |
| JavaScriptObject handler) /*-{ | |
| target.removeEventListener(type, handler); | |
| }-*/; | |
| } |