All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.sksamuel.jqm4gwt.events.JQMHandlerRegistration Maven / Gradle / Ivy

package com.sksamuel.jqm4gwt.events;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Element;
import com.google.gwt.event.logical.shared.AttachEvent;
import com.google.gwt.event.shared.EventHandler;
import com.google.gwt.event.shared.GwtEvent;
import com.google.gwt.event.shared.GwtEvent.Type;
import com.google.gwt.event.shared.HandlerRegistration;
import com.google.gwt.event.shared.HasHandlers;
import com.google.gwt.user.client.EventListener;
import com.google.gwt.user.client.ui.Widget;

/**
 * This class is responsible for registering and unregistering JQM events.
 *
 * @author Andrei Costescu [email protected] 31 Oct 2013
 */
public class JQMHandlerRegistration implements HandlerRegistration {

    private String jqmEventName;
    private HandlerRegistration defaultRegistration;
    private WidgetHandlerCounter counter;
    private Type type;
    private Widget widget;
    private X handler;
    private HandlerRegistration attachHandlerRegistration;

    public static interface WidgetHandlerCounter {
        int getHandlerCountForWidget(GwtEvent.Type type);
    }

    protected JQMHandlerRegistration() {
    }

    public static  JQMHandlerRegistration registerJQueryHandler(
            WidgetHandlerCounter counter, Widget widget, X handler, String jqmEventName, Type type) {

        JQMHandlerRegistration reg = new JQMHandlerRegistration();
        reg.addHandler(counter, widget, handler, jqmEventName, type);
        return reg;
    }

    protected void addHandler(WidgetHandlerCounter counter, Widget widget,
            X handler, String jqmEventName, Type type) {

        this.widget = widget;
        this.counter = counter;
        this.jqmEventName = jqmEventName;
        this.type = type;
        this.handler = handler;

        if (widget.isAttached()) {
            attachIfNeeded();
        }

        attachHandlerRegistration = widget.addAttachHandler(new AttachEvent.Handler() {
            @Override
            public void onAttachOrDetach(AttachEvent event) {
                if (event.isAttached())
                    attachIfNeeded();
                else
                    detachIfNeeded();
            }
        });
    }

    private void attachIfNeeded() {
        boolean addInJS = counter.getHandlerCountForWidget(type) == 0;
        this.defaultRegistration = widget.addHandler(handler, type);
        if (addInJS) {
            if (JQMComponentEvents.ORIENTATIONCHANGE.equals(jqmEventName)) {
                int wHash = System.identityHashCode(widget);
                addJQueryEventToWindow(widget.getElement(), jqmEventName, String.valueOf(wHash));
            } else {
                addJQueryEvent(widget.getElement(), jqmEventName);
            }
        }
    }

    private void detachIfNeeded() {
        if (defaultRegistration != null) {
            defaultRegistration.removeHandler();
            defaultRegistration = null;
            if (counter.getHandlerCountForWidget(type) == 0) {
                if (JQMComponentEvents.ORIENTATIONCHANGE.equals(jqmEventName)) {
                    int wHash = System.identityHashCode(widget);
                    removeJQueryEventHandlerFromWindow(jqmEventName, String.valueOf(wHash));
                } else {
                    removeJQueryEventHandler(widget.getElement(), jqmEventName);
                }
            }
        }
    }

    @Override
    public void removeHandler() {
        detachIfNeeded();
        attachHandlerRegistration.removeHandler();
    }

    // Each widget needs to have a single "root" element.
    // Whenever the widget becomes attached, it create exactly one "back reference" from the element
    // to the widget that is, element.__listener = widget, performed in DOM.setEventListener()
    // This is set whenever the widget is attached, and cleared whenever it is detached.
    //
    private static native JavaScriptObject addJQueryEvent(Element element, String jqmEventName) /*-{
        if ($wnd.$ === undefined || $wnd.$ === null) return null; // jQuery is not loaded
        $wnd.$(element).on(jqmEventName + ".jqm4gwt.s", $entry(function(event) {
                @com.sksamuel.jqm4gwt.events.JQMHandlerRegistration::dispatchJQMEvent(Ljava/lang/String;Lcom/google/gwt/user/client/EventListener;Lcom/google/gwt/core/client/JavaScriptObject;)(jqmEventName, element.__listener, event);
        }));
    }-*/;

    private static native JavaScriptObject addJQueryEventToWindow(Element element,
            String jqmEventName, String eltGuid) /*-{
        if ($wnd.$ === undefined || $wnd.$ === null) return null; // jQuery is not loaded
        $wnd.$($wnd.window).on(jqmEventName + ".jqm4gwt.s." + eltGuid, $entry(function(event) {
                @com.sksamuel.jqm4gwt.events.JQMHandlerRegistration::dispatchJQMEvent(Ljava/lang/String;Lcom/google/gwt/user/client/EventListener;Lcom/google/gwt/core/client/JavaScriptObject;)(jqmEventName, element.__listener, event);
        }));
    }-*/;

    private static final void dispatchJQMEvent(String jqmEventName,
            EventListener listener, JavaScriptObject jQueryEvent) {
        if (listener != null && listener instanceof HasHandlers) {
            JQMEvent.fire((HasHandlers) listener, jqmEventName, jQueryEvent);
        }
    }

    private static native void removeJQueryEventHandler(Element element, String jqmEventName) /*-{
        if ($wnd.$ === undefined || $wnd.$ === null) return; // jQuery is not loaded
        $wnd.$(element).off(jqmEventName + ".jqm4gwt.s");
    }-*/;

    private static native void removeJQueryEventHandlerFromWindow(String jqmEventName, String eltGuid) /*-{
        if ($wnd.$ === undefined || $wnd.$ === null) return; // jQuery is not loaded
        $wnd.$($wnd.window).off(jqmEventName + ".jqm4gwt.s." + eltGuid);
    }-*/;

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy