org.jboss.errai.common.client.util.EventTestingUtil.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.errai.common.client.util.EventTestingUtil.java

Source

/*
 * Copyright (C) 2016 Red Hat, Inc. and/or its affiliates.
 *
 * 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 org.jboss.errai.common.client.util;

import org.jboss.errai.common.client.dom.HTMLElement;
import org.jboss.errai.common.client.ui.ElementWrapperWidget;

import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.logical.shared.ValueChangeEvent;
import com.google.gwt.user.client.ui.HasValue;

/**
 * Contains utility methods for intercepting calls to add and remove web browser event listeners necessary for tests
 * with certain versions of HTMLUnit.
 *
 * @author Max Barkley <mbarkley@redhat.com>
 */
public abstract class EventTestingUtil {

    private EventTestingUtil() {
    }

    /**
     * This is a really disgusting workaround for the inability to
     * dispatch native browser events in the version of HtmlUnit currently
     * bundled in gwt-dev.
     *
     * What does this do?
     * This replaces "addEventListener" and "removeEventListener"
     * in the HTMLElement prototype with functions that intercept
     * and store registered listeners.
     *
     * Why does it do it?
     * So that subsequent calls to "invokeEventListeners" can
     * manually call any functions added with "addEventListener".
     *
     * In short because we cannot dispatch browser events, to test
     * binding of native elements we must store and then manually invoke
     * all event listeners.
     */
    public static native void setupAddEventListenerInterceptor() /*-{
                                                                 console.log("Setting up event listener interceptors.");
                                                                 function ListenerMap() {
                                                                 var map = new Map();
                                                                     
                                                                 this.add = function(element, type, listener) {
                                                                 var curList = this.get(element, type);
                                                                 console.debug("Adding listener for " + type + " event in " + element + ". Total of " + (curList.length + 1) + " listeners.");
                                                                 curList.push(listener);
                                                                 };
                                                                     
                                                                 this.remove = function(element, type, listener) {
                                                                 var listeners = this.get(element, type);
                                                                 var index = listeners.indexOf(listener);
                                                                 if (index > -1) {
                                                                 listeners.splice(index, 1);
                                                                 }
                                                                 };
                                                                     
                                                                 this.get = function(element, type) {
                                                                 if (map.get(element) === undefined) {
                                                                 map.set(element, new Map());
                                                                 }
                                                                 if (map.get(element).get(type) === undefined) {
                                                                 map.get(element).set(type, []);
                                                                 }
                                                                 return map.get(element).get(type);
                                                                 };
                                                                 };
                                                                 if ($wnd.HTMLElement.prototype._addEventListener === undefined) {
                                                                 listeners = new ListenerMap();
                                                                 $wnd.HTMLElement.prototype._addEventListener = $wnd.HTMLElement.prototype.addEventListener;
                                                                 $wnd.HTMLElement.prototype._removeEventListener = $wnd.HTMLElement.prototype.removeEventListener;
                                                                 console.log("Replacing addEventListener.");
                                                                 $wnd.HTMLElement.prototype.addEventListener = function(type, listener, capture) {
                                                                 console.debug("Intercepted addEventListener(" + this + ", " + type + ", " + capture + ")");
                                                                 listeners.add(this, type, listener);
                                                                 this._addEventListener(type, listener, capture);
                                                                 };
                                                                 console.log("Replacing removeEventListener.");
                                                                 $wnd.HTMLElement.prototype.removeEventListener = function(type, listener, capture) {
                                                                 console.debug("Intercepted removeEventListener for " + this + " with type " + type);
                                                                 listeners.remove(this, type, listener);
                                                                 this._removeEventListener(type, listener, capture);
                                                                 };
                                                                 }
                                                                 }-*/;

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void invokeEventListeners(final HTMLElement element, final String eventType) {
        invokeEventListeners((Object) element, eventType);
        if ("change".equals(eventType)) {
            final ElementWrapperWidget elem = ElementWrapperWidget.getWidget(element);
            if (elem instanceof HasValue) {
                ValueChangeEvent.fire(((HasValue) elem), ((HasValue) elem).getValue());
            }
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public static void invokeEventListeners(final Element element, final String eventType) {
        invokeEventListeners((Object) element, eventType);
        if ("change".equals(eventType)) {
            final ElementWrapperWidget elem = ElementWrapperWidget.getWidget(element);
            if (elem instanceof HasValue) {
                ValueChangeEvent.fire(((HasValue) elem), ((HasValue) elem).getValue());
            }
        }
    }

    public static void invokeEventListeners(final Object element, final String eventType) {
        final NativeEvent event = Document.get().createHtmlEvent(eventType, true, true);
        invokeEventListeners(element, eventType, event);
    }

    public static native void invokeEventListeners(Object element, String type, Object evt) /*-{
                                                                                            var foundListeners = listeners.get(element, type);
                                                                                            console.debug("Found " + foundListeners.length + " for " + type + " event on element " + element);
                                                                                            foundListeners.forEach(function(l) { l(evt); });
                                                                                            }-*/;

}