import com.google.gwt.query.client.js.JsNamedArray;
import com.google.gwt.query.client.js.JsObjectArray;
import com.google.gwt.query.client.js.JsUtils;
- import com.google.gwt.query.client.plugins.events.SpecialEvent.AbstractSpecialEvent;
++import com.google.gwt.query.client.plugins.events.SpecialEvent.DefaultSpecialEvent;
import com.google.gwt.user.client.DOM;
import com.google.gwt.user.client.Event;
import com.google.gwt.user.client.EventListener;
/**
* Used for simulating mouseenter and mouseleave events
*/
- private static class MouseSpecialEvent extends AbstractSpecialEvent {
- public static class MouseSpecialEvent implements SpecialEvent {
-
- private String originalType;
- private String delegateType;
-
- public MouseSpecialEvent(String originalType, String delegateType) {
- this.originalType = originalType;
- this.delegateType = delegateType;
- }
-
- public String getDelegateType() {
- return delegateType;
- }
-
- public String getOriginalType() {
- return originalType;
- }
-
- public Function createDelegateHandler(Function originalHandler) {
- return new SpecialMouseEventHandler(originalHandler);
++ private static class MouseSpecialEvent extends DefaultSpecialEvent {
+ public MouseSpecialEvent(final String type, String delegateType) {
+ super(type, delegateType);
+ handler = new Function() {
+ public boolean f(Event e, Object... arg) {
+ EventTarget eventTarget = e.getCurrentEventTarget();
+ Element target = eventTarget != null ? eventTarget.<Element> cast() : null;
+
+ EventTarget relatedEventTarget = e.getRelatedEventTarget();
+ Element related = relatedEventTarget != null ? relatedEventTarget.<Element> cast() : null;
+
+ if (related == null || (related != target && !GQuery.contains(target, related))) {
+ getInstance(target).dispatchEvent(e, type);
+ }
+ return true;
+ };
+ };
}
}
- /**
- * Used for simulating mouseenter and mouseleave events
- */
- private static class FocusSpecialEvent extends AbstractSpecialEvent {
- public FocusSpecialEvent(final String type, String delegateType) {
- super(type, delegateType);
- handler = new Function() {
- public boolean f(Event e, Object... arg) {
- setEvent(e);
- getInstance(getElement()).dispatchEvent(e, type);
- return true;
- };
- };
- }
- private interface HandlerWrapper {
- Function getOriginalHandler();
-- }
- private static class SpecialMouseEventHandler extends Function implements HandlerWrapper {
-
- private Function delegateHandler;
-
- public SpecialMouseEventHandler(Function originalHandler) {
- this.delegateHandler = originalHandler;
- }
-
- @Override
- public boolean f(Event e, Object... data) {
- EventTarget eventTarget = e.getCurrentEventTarget();
- Element target = eventTarget != null ? eventTarget.<Element> cast() : null;
-
- EventTarget relatedEventTarget = e.getRelatedEventTarget();
- Element related = relatedEventTarget != null ? relatedEventTarget.<Element> cast() : null;
--
- // For mousenter/leave call the handler if related is outside the target.
- if (related == null || (related != target && !GQuery.contains(target, related))) {
- return delegateHandler != null ? delegateHandler.f(e, data) : false;
+ /**
+ * Utility class to split a list of events with or without namespaces
+ */
+ private static class EvPart {
+ String nameSpace;
+ String eventName;
+ public EvPart(String n, String e) {
+ nameSpace = n;
+ eventName = e;
+ }
+
+ static List<EvPart> split(String events) {
+ List<EvPart> ret = new ArrayList<EvPart>();
+ String[] parts = events.split("[\\s,]+");
+ for (String event : parts) {
+ String[] tmp = event.split("\\.", 2);
+ String eventName = tmp[0];
+ String nameSpace = tmp.length > 1 ? tmp[1] : null;
+ ret.add(new EvPart(nameSpace, eventName));
}
-
- return false;
- }
-
- public Function getOriginalHandler() {
- return delegateHandler;
+ return ret;
}
}
public static String MOUSEENTER = "mouseenter";
public static String MOUSELEAVE = "mouseleave";
+ public static String FOCUSIN = "focusin";
+ public static String FOCUSOUT = "focusout";
- public static JsMap<String, SpecialEvent> special;
+ public static HashMap<String, SpecialEvent> special;
static {
- special = JsMap.create();
+ // Register some special events which already exist in jQuery
+ special = new HashMap<String, SpecialEvent>();
special.put(MOUSEENTER, new MouseSpecialEvent(MOUSEENTER, "mouseover"));
special.put(MOUSELEAVE, new MouseSpecialEvent(MOUSELEAVE, "mouseout"));
- special.put(FOCUSIN, new FocusSpecialEvent(FOCUSIN, "focus"));
- special.put(FOCUSOUT, new FocusSpecialEvent(FOCUSOUT, "blur"));
++ special.put(FOCUSIN, new DefaultSpecialEvent(FOCUSIN, "focus"));
++ special.put(FOCUSOUT, new DefaultSpecialEvent(FOCUSOUT, "blur"));
}
public static void clean(Element e) {
--- /dev/null
- * Abstract implementation of SpecialEvents
+/*
+ * Copyright 2014, The gwtquery team.
+ *
+ * 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.query.client.plugins.events;
+
+import com.google.gwt.dom.client.Element;
+import com.google.gwt.query.client.Function;
+import com.google.gwt.user.client.Event;
+
+/**
+ * Interface used to register special events.
+ *
+ * Use EventsListeners.special.add(
+ */
+public interface SpecialEvent {
+
+ /**
- public static abstract class AbstractSpecialEvent implements SpecialEvent {
++ * Default implementation of SpecialEvents for simple cases like
++ * creating event aliases. Extend this for creating more complex
++ * cases.
+ */
- protected Function handler = null;
++ public static class DefaultSpecialEvent implements SpecialEvent {
+ protected final String delegateType;
+ protected final String type;
- public AbstractSpecialEvent(String type, String delegateType) {
+
- // Nothing to do, let gQuery use default eentEvents mechanism
++ protected Function handler = new Function() {
++ public boolean f(Event e, Object... arg) {
++ setEvent(e);
++ EventsListener.getInstance(getElement()).dispatchEvent(e, type);
++ return true;
++ };
++ };
++
++ public DefaultSpecialEvent(String type, String delegateType) {
+ this.type = type;
+ this.delegateType = delegateType;
+ }
+
+ protected EventsListener listener(Element e) {
+ return EventsListener.getInstance(e);
+ }
+
+ @Override
+ public void add(Element e, String eventType, String nameSpace, Object data, Function f) {
- // Nothing to do, let gQuery use default eentEvents mechanism
++ // Nothing to do, let gQuery use default events mechanism
+ }
+
+ @Override
+ public boolean hasHandlers(Element e) {
+ return listener(e).hasHandlers(Event.getTypeInt(type), type);
+ }
+
+ @Override
+ public void remove(Element e, String eventType, String nameSpace, Function f) {
- listener(e).bind(Event.getTypeInt(delegateType), null, delegateType, null, handler, -1);
++ // Nothing to do, let gQuery use default events mechanism
+ }
+
+ @Override
+ public boolean setup(Element e) {
+ if (!hasHandlers(e)) {
- listener(e).unbind(Event.getTypeInt(delegateType), null, delegateType, handler);
++ listener(e).bind(delegateType, null, handler);
+ }
+ return false;
+ }
+
+ @Override
+ public boolean tearDown(Element e) {
+ if (!hasHandlers(e)) {
++ listener(e).unbind(delegateType, handler);
+ }
+ return false;
+ }
+ }
+
+ /**
+ * For each bind call the add function is called.
+ */
+ void add(Element e, String eventType, String nameSpace, Object data, Function f);
+
+ /**
+ * Return true if there are handlers bound to this special event.
+ */
+ boolean hasHandlers(Element e);
+
+ /**
+ * For each unbind call the remove function is called.
+ */
+ void remove(Element e, String eventType, String nameSpace, Function f);
+
+ /**
+ * When the first event handler is bound for an EventsListener gQuery executes the setup function.
+ *
+ * If the method returns false means that gQuery has to run the default bind for the event before
+ * calling add.
+ */
+ boolean setup(Element e);
+
+ /**
+ * The last unbind call triggers the tearDown method.
+ *
+ * If the method returns false means that gQuery has to run the default unbind for the event
+ * before calling remove.
+ */
+ boolean tearDown(Element e);
+}