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

com.googlecode.gwt.test.internal.utils.JsoUtils Maven / Gradle / Ivy

There is a newer version: 0.63
Show newest version
package com.googlecode.gwt.test.internal.utils;

import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.*;
import com.google.gwt.user.client.ui.Widget;
import com.googlecode.gwt.test.finder.GwtFinder;
import com.googlecode.gwt.test.utils.GwtReflectionUtils;
import com.googlecode.gwt.test.utils.JavaScriptObjects;
import com.googlecode.gwt.test.utils.WidgetUtils;

import java.util.*;

/**
 * Some {@link JavaScriptObject} utility methods. For internal use only.
 *
 * @author Gael Lazzari
 */
public class JsoUtils {

    private static final Set DOM_PROPERTIES = new HashSet() {
        /**
         *
         */
        private static final long serialVersionUID = 1L;

        {
         /*
          * 
          * Parse HTML standard attributes here : http://www.w3.org/TR/html4/index/attributes.html
          * 
          * With this jQuery script :
          * 
          * 
          */
            add("abbr");
            add("accept-charset");
            add("accept");
            add("accesskey");
            add("action");
            add("align");
            add("alink");
            add("alt");
            add("archive");
            add("axis");
            add("background");
            add("bgcolor");
            add("border");
            add("cellpadding");
            add("cellspacing");
            add("char");
            add("charoff");
            add("charset");
            add("checked");
            add("cite");
            add("class");
            add("classid");
            add("clear");
            add("code");
            add("codebase");
            add("codetype");
            add("color");
            add("cols");
            add("colspan");
            add("compact");
            add("content");
            add("coords");
            add("data");
            add("datetime");
            add("declare");
            add("defer");
            add("dir");
            add("disabled");
            add("enctype");
            add("face");
            add("for");
            add("frame");
            add("frameborder");
            add("headers");
            add("height");
            add("href");
            add("hreflang");
            add("hspace");
            add("http-equiv");
            add("id");
            add("ismap");
            add("label");
            add("lang");
            add("language");
            add("link");
            add("longdesc");
            add("marginheight");
            add("marginwidth");
            add("maxlength");
            add("media");
            add("method");
            add("multiple");
            add("name");
            add("nohref");
            add("noresize");
            add("noshade");
            add("nowrap");
            add("object");
            add("onblur");
            add("onchange");
            add("onclick");
            add("ondblclick");
            add("onfocus");
            add("onkeydown");
            add("onkeypress");
            add("onkeyup");
            add("onload");
            add("onmousedown");
            add("onmousemove");
            add("onmouseout");
            add("onmouseover");
            add("onmouseup");
            add("onreset");
            add("onselect");
            add("onsubmit");
            add("onunload");
            add("profile");
            add("prompt");
            add("readonly");
            add("rel");
            add("rev");
            add("rows");
            add("rowspan");
            add("rules");
            add("scheme");
            add("scope");
            add("scrolling");
            add("selected");
            add("shape");
            add("size");
            add("span");
            add("src");
            add("standby");
            add("start");
            add("style");
            add("summary");
            add("tabindex");
            add("target");
            add("text");
            add("title");
            add("type");
            add("usemap");
            add("valign");
            add("value");
            add("valuetype");
            add("version");
            add("vlink");
            add("vspace");
            add("width");
        }
    };

    private static final String ELEM_PROPERTIES = "ELEM_PROPERTIES";
    private static final String IS_XML_ELEMENT = "IS_XML_ELEMENT";
    private static final String NODE_LIST_FIELD = "childNodes";
    private static final String NODE_LIST_INNER_LIST = "NODE_LIST_INNER_LIST";
    private static final String NODE_NAME = "nodeName";
    private static final String NODE_TYPE_FIELD = "nodeType";
    private static final String PARENT_NODE_FIELD = "parentNode";
    private static final String TAG_NAME = "tagName";

    public static JavaScriptObject cloneJso(JavaScriptObject oldJso, boolean deep) {
        JavaScriptObject newJso = JavaScriptObject.createObject();

        if (Node.is(oldJso)) {
            short nodeType = oldJso.cast().getNodeType();
            JavaScriptObjects.setProperty(newJso, NODE_TYPE_FIELD, nodeType);
        }

        for (Map.Entry entry : JavaScriptObjects.entrySet(oldJso)) {

            if (PARENT_NODE_FIELD.equals(entry.getKey())) {
                // Nothing to do : new cloned node does not have any parent
            } else if (NODE_TYPE_FIELD.equals(entry.getKey())) {
                // ignore it since it has to be handled at the very beginning of
                // cloning
            } else if (JsoProperties.NODE_OWNER_DOCUMENT.equals(entry.getKey())) {
                JavaScriptObjects.setProperty(newJso, JsoProperties.NODE_OWNER_DOCUMENT,
                        JavaScriptObjects.getObject(oldJso, JsoProperties.NODE_OWNER_DOCUMENT));
            } else if (GwtStyleUtils.STYLE_OBJECT_FIELD.equals(entry.getKey())) {
                Style newStyle = GwtStyleUtils.getStyle(newJso.cast());
                GwtStyleUtils.cloneStyle(newStyle, (Style) entry.getValue());
            } else if (NODE_LIST_FIELD.equals(entry.getKey())) {
                Node newNode = newJso.cast();
                Node oldNode = oldJso.cast();
                cloneChildNodes(newNode, oldNode, deep);
            } else if (ELEM_PROPERTIES.equals(entry.getKey())) {
                PropertyContainer newPc = getDomProperties(newJso.cast());
                PropertyContainer oldPc = getDomProperties(oldJso.cast());

                for (Map.Entry entry2 : oldPc.entrySet()) {
                    newPc.put(entry2.getKey(), entry2.getValue());
                }
            } else if (JavaScriptObject.class.isInstance(entry.getValue())) {
                JavaScriptObject oldChildJso = (JavaScriptObject) entry.getValue();
                JavaScriptObject newChildJso = cloneJso(oldChildJso, deep);
                JavaScriptObjects.setProperty(newJso, entry.getKey(), newChildJso);
            } else {
                // copy the property, which should be a String or a primitive type
                // (or
                // corresponding wrapper object)
                JavaScriptObjects.setProperty(newJso, entry.getKey(), entry.getValue());
            }
        }

        return newJso;

    }

    @SuppressWarnings("unchecked")
    public static List getChildNodeInnerList(Node node) {
        NodeList nodeList = getChildNodes(node);
        return (List) JavaScriptObjects.getObject(nodeList, NODE_LIST_INNER_LIST);
    }

    @SuppressWarnings("unchecked")
    public static  List getChildNodeInnerList(NodeList nodeList) {
        assert isNodeList(nodeList) : "not a NodeList";

        return (List) JavaScriptObjects.getObject(nodeList, NODE_LIST_INNER_LIST);
    }

    public static NodeList getChildNodes(Node node) {
        assert Node.is(node) : "not a Node";
        NodeList nodeList = JavaScriptObjects.getObject(node, NODE_LIST_FIELD);

        if (nodeList == null) {
            nodeList = newNodeList();
            JavaScriptObjects.setProperty(node, NODE_LIST_FIELD, nodeList);
        }

        return nodeList;
    }

    public static PropertyContainer getDomProperties(Element element) {
        assert Node.is(element) : "not a Node";

        PropertyContainer pc = JavaScriptObjects.getObject(element, ELEM_PROPERTIES);

        if (pc == null) {
            // a propertyContainer with a LinkedHashMap to record the order of DOM
            // properties
            pc = PropertyContainer.newInstance(new LinkedHashMap());
            JavaScriptObjects.setProperty(element, ELEM_PROPERTIES, pc);
        }

        return pc;
    }

    public static short getNodeType(JavaScriptObject jso) {
        return JavaScriptObjects.hasProperty(jso, NODE_TYPE_FIELD) ? JavaScriptObjects.getShort(jso,
                NODE_TYPE_FIELD) : -1;
    }

    public static String getTagName(Element element) {
        assert Element.is(element) : "not an Element";

        return JavaScriptObjects.getString(element, TAG_NAME);
    }

    public static boolean isNodeList(JavaScriptObject jso) {
        return JavaScriptObjects.hasProperty(jso, NODE_LIST_INNER_LIST);
    }

    public static boolean isStandardDOMProperty(String propertyName) {
        return "className".equals(propertyName) || !"class".equals(propertyName)
                && DOM_PROPERTIES.contains(propertyName);
    }

    public static boolean isXmlElement(JavaScriptObject jso) {
        return JavaScriptObjects.hasProperty(jso, IS_XML_ELEMENT);
    }

    public static Document newDocument() {
        Document document = newNode(Node.DOCUMENT_NODE).cast();
        JavaScriptObjects.setProperty(document, JsoProperties.NODE_OWNER_DOCUMENT, document);
        return document;

    }

    public static Element newElement(String tag, Document ownerDocument) {
        Element elem = newNode(Node.ELEMENT_NODE).cast();
        JavaScriptObjects.setProperty(elem, TAG_NAME, tag);
        JavaScriptObjects.setProperty(elem, JsoProperties.NODE_OWNER_DOCUMENT, ownerDocument);

        if (tag.equalsIgnoreCase("html")) {
            JavaScriptObjects.setProperty(elem, NODE_NAME, "HTML");
        }

        return elem;
    }

    public static Node newNode(int nodeType) {
        Node newNode = JavaScriptObject.createObject().cast();
        JavaScriptObjects.setProperty(newNode, NODE_TYPE_FIELD, (short) nodeType);
        return newNode;
    }

    public static  NodeList newNodeList() {
        return newNodeList(new ArrayList());
    }

    @SuppressWarnings("unchecked")
    public static  NodeList newNodeList(List innerList) {
        NodeList nodeList = (NodeList) JavaScriptObject.createObject().cast();
        JavaScriptObjects.setProperty(nodeList, NODE_LIST_INNER_LIST, innerList);
        return nodeList;
    }

    public static Text newText(String data, Document ownerDocument) {
        Text text = newNode(Node.TEXT_NODE).cast();
        JavaScriptObjects.setProperty(text, JsoProperties.NODE_OWNER_DOCUMENT, ownerDocument);
        text.setData(data);

        return text;
    }

    public static Element newXmlElement(Document document, String tagName) {
        Element xmlElement = document.createElement(tagName);
        JavaScriptObjects.setProperty(xmlElement, IS_XML_ELEMENT, true);

        return xmlElement;
    }

    public static void onSetHTML(JavaScriptObject jso, String newHTML, String oldHTML) {
        Widget w = WidgetUtils.getWidget(jso.cast());

        if (w != null) {
            GwtReflectionUtils.callStaticMethod(GwtFinder.class, "onSetHTML", w, newHTML, oldHTML);
        }

    }

    public static void onSetId(JavaScriptObject jso, String newId, String oldId) {
        Widget w = WidgetUtils.getWidget(jso.cast());

        if (w != null) {
            GwtReflectionUtils.callStaticMethod(GwtFinder.class, "onSetId", w, newId, oldId);
        }
    }

    public static void onSetText(JavaScriptObject jso, String newText, String oldText) {
        Widget w = WidgetUtils.getWidget(jso.cast());

        if (w != null) {
            GwtReflectionUtils.callStaticMethod(GwtFinder.class, "onSetText", w, newText, oldText);
        }
    }

    public static String serialize(JavaScriptObject jso) {
        if (Node.is(jso)) {
            return jso.toString();
        }

        StringBuilder sb = new StringBuilder();
        // FIXME : provide support for JavaScriptObject arrays
        sb.append("{ ");

        for (Map.Entry entry : JavaScriptObjects.entrySet(jso)) {
            sb.append("\"").append(entry.getKey()).append("\": ");
            sb.append(entry.getValue()).append(", ");
        }

        sb.replace(sb.length() - 2, sb.length(), "");
        sb.append(" }");

        return sb.toString();

    }

    public static void setParentNode(Node child, Node parent) {
        JavaScriptObjects.setProperty(child, PARENT_NODE_FIELD, parent);
    }

    private static void cloneChildNodes(Node newNode, Node oldNode, boolean deep) {

        List childs = getChildNodeInnerList(oldNode);
        if (deep) {
            // copy all child nodes
            for (Node child : childs) {
                newNode.appendChild(child.cloneNode(deep));
            }
        } else {
            // only copy the TextNode if exists
            for (Node child : childs) {
                if (Node.TEXT_NODE == child.getNodeType()) {
                    newNode.appendChild(Document.get().createTextNode(child.getNodeValue()));
                    break;
                }
            }
        }
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy