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

org.vectomatic.dom.svg.utils.DOMHelper Maven / Gradle / Ivy

/**********************************************
 * Copyright (C) 2010 Lukas Laag
 * This file is part of lib-gwt-svg.
 * 
 * libgwtsvg is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * libgwtsvg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with libgwtsvg.  If not, see http://www.gnu.org/licenses/
 **********************************************/
/*
 * Copyright (c) 2004 World Wide Web Consortium,
 *
 * (Massachusetts Institute of Technology, European Research Consortium for
 * Informatics and Mathematics, Keio University). All Rights Reserved. This
 * work is distributed under the W3C(r) Software License [1] in the hope that
 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231
 */
package org.vectomatic.dom.svg.utils;

import java.util.Iterator;
import java.util.NoSuchElementException;

import org.vectomatic.dom.svg.OMElement;
import org.vectomatic.dom.svg.OMNode;
import org.vectomatic.dom.svg.OMSVGElement;
import org.vectomatic.dom.svg.impl.Attr;
import org.vectomatic.dom.svg.impl.DOMHelperImpl;
import org.vectomatic.dom.svg.impl.NamedNodeMap;
import org.w3c.dom.DOMException;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.JavaScriptException;
import com.google.gwt.core.client.JavaScriptObject;
import com.google.gwt.dom.client.Document;
import com.google.gwt.dom.client.Element;
import com.google.gwt.dom.client.Node;
import com.google.gwt.dom.client.NodeList;
import com.google.gwt.dom.client.Text;
import com.google.gwt.event.dom.client.LoseCaptureHandler;
import com.google.gwt.event.shared.HandlerRegistration;

/**
 * Class to group miscellaneous DOM level 2 methods. These
 * methods are missing from the GWT DOM overlay types (such as 
 * {@link com.google.gwt.dom.client.Element} or {@link com.google.gwt.dom.client.Node})
 * but exist in almost all browsers and are sometimes required
 * to develop an SVG application.
 * @author laaglu
 */
public class DOMHelper {
	private static final DOMHelperImpl impl = GWT.create(DOMHelperImpl.class);
	
    /**
     * Creates an element of the given qualified name and namespace URI.
     * 
Per [XML Namespaces] * , applications must use the value null as the * namespaceURI parameter for methods if they wish to have no namespace. * @param document The document in which the element is to be created. * @param namespaceURI The namespace URI of the element to create. * @param qualifiedName The qualified name of the element type to * instantiate. * @return A new Element object with the following * attributes: * * * * * * * * * * * * * * * * * * * * * * * * * *
AttributeValue
Node.nodeName * qualifiedName
Node.namespaceURI * namespaceURI
Node.prefixprefix, extracted * from qualifiedName, or null if there is * no prefix
Node.localNamelocal name, extracted from * qualifiedName
Element.tagName * qualifiedName
* @exception DOMException * INVALID_CHARACTER_ERR: Raised if the specified * qualifiedName is not an XML name according to the XML * version in use specified in the Document.xmlVersion * attribute. *
NAMESPACE_ERR: Raised if the qualifiedName is a * malformed qualified name, if the qualifiedName has a * prefix and the namespaceURI is null, or * if the qualifiedName has a prefix that is "xml" and * the namespaceURI is different from " * http://www.w3.org/XML/1998/namespace" [XML Namespaces] * , or if the qualifiedName or its prefix is "xmlns" and * the namespaceURI is different from "http://www.w3.org/2000/xmlns/", or if the namespaceURI is "http://www.w3.org/2000/xmlns/" and neither the qualifiedName nor its prefix is "xmlns". *
NOT_SUPPORTED_ERR: Always thrown if the current document does not * support the "XML" feature, since namespaces were * defined by XML. */ public static final native Element createElementNS(Document document, String namespaceURI, String qualifiedName) throws JavaScriptException /*-{ return document.createElementNS(namespaceURI, qualifiedName); }-*/; /** * Creates a new empty SVG document * @return * a new empty SVG document */ public static final native Document createDocument(String uri, String qname) /*-{ return $doc.implementation.createDocument(uri, qname, null); }-*/; /** * Imports a node from another document to this document, without altering * or removing the source node from the original document; this method * creates a new copy of the source node. The returned node has no * parent; (parentNode is null). *
For all nodes, importing a node creates a node object owned by the * importing document, with attribute values identical to the source * node's nodeName and nodeType, plus the * attributes related to namespaces (prefix, * localName, and namespaceURI). As in the * cloneNode operation, the source node is not altered. * User data associated to the imported node is not carried over. * However, if any UserDataHandlers has been specified * along with the associated data these handlers will be called with the * appropriate parameters before this method returns. *
Additional information is copied as appropriate to the * nodeType, attempting to mirror the behavior expected if * a fragment of XML or HTML source was copied from one document to * another, recognizing that the two documents may have different DTDs * in the XML case. The following list describes the specifics for each * type of node. *
*
ATTRIBUTE_NODE
*
The ownerElement attribute * is set to null and the specified flag is * set to true on the generated Attr. The * descendants of the source Attr are recursively imported * and the resulting nodes reassembled to form the corresponding subtree. * Note that the deep parameter has no effect on * Attr nodes; they always carry their children with them * when imported.
*
DOCUMENT_FRAGMENT_NODE
*
If the deep option * was set to true, the descendants of the source * DocumentFragment are recursively imported and the * resulting nodes reassembled under the imported * DocumentFragment to form the corresponding subtree. * Otherwise, this simply generates an empty * DocumentFragment.
*
DOCUMENT_NODE
*
Document * nodes cannot be imported.
*
DOCUMENT_TYPE_NODE
*
DocumentType * nodes cannot be imported.
*
ELEMENT_NODE
*
Specified attribute nodes of the source element are imported, and the generated * Attr nodes are attached to the generated * Element. Default attributes are not copied, though if the document being imported into defines default * attributes for this element name, those are assigned. If the * importNode deep parameter was set to * true, the descendants of the source element are * recursively imported and the resulting nodes reassembled to form the * corresponding subtree.
*
ENTITY_NODE
*
Entity nodes can be * imported, however in the current release of the DOM the * DocumentType is readonly. Ability to add these imported * nodes to a DocumentType will be considered for addition * to a future release of the DOM.On import, the publicId, * systemId, and notationName attributes are * copied. If a deep import is requested, the descendants * of the the source Entity are recursively imported and * the resulting nodes reassembled to form the corresponding subtree.
*
* ENTITY_REFERENCE_NODE
*
Only the EntityReference itself is * copied, even if a deep import is requested, since the * source and destination documents might have defined the entity * differently. If the document being imported into provides a * definition for this entity name, its value is assigned.
*
NOTATION_NODE
*
* Notation nodes can be imported, however in the current * release of the DOM the DocumentType is readonly. Ability * to add these imported nodes to a DocumentType will be * considered for addition to a future release of the DOM.On import, the * publicId and systemId attributes are copied. * Note that the deep parameter has no effect on this type * of nodes since they cannot have any children.
*
* PROCESSING_INSTRUCTION_NODE
*
The imported node copies its * target and data values from those of the * source node.Note that the deep parameter has no effect * on this type of nodes since they cannot have any children.
*
TEXT_NODE, * CDATA_SECTION_NODE, COMMENT_NODE
*
These three types of nodes inheriting * from CharacterData copy their data and * length attributes from those of the source node.Note * that the deep parameter has no effect on these types of * nodes since they cannot have any children.
*
* @param document The document in which to import the node. * @param importedNode The node to import. * @param deep If true, recursively import the subtree under * the specified node; if false, import only the node * itself, as explained above. This has no effect on nodes that cannot * have any children, and on Attr, and * EntityReference nodes. * @return The imported node that belongs to this Document. * @exception DOMException * NOT_SUPPORTED_ERR: Raised if the type of node being imported is not * supported. *
INVALID_CHARACTER_ERR: Raised if one of the imported names is not * an XML name according to the XML version in use specified in the * Document.xmlVersion attribute. This may happen when * importing an XML 1.1 [XML 1.1] element * into an XML 1.0 document, for instance. */ public static final native Node importNode(Document document, Node importedNode, boolean deep) /*-{ return document.importNode(importedNode, deep); }-*/; /** * Puts all Text nodes in the full depth of the sub-tree * underneath this Node, including attribute nodes, into a * "normal" form where only structure (e.g., elements, comments, * processing instructions, CDATA sections, and entity references) * separates Text nodes, i.e., there are neither adjacent * Text nodes nor empty Text nodes. This can * be used to ensure that the DOM view of a document is the same as if * it were saved and re-loaded, and is useful when operations (such as * XPointer [XPointer] * lookups) that depend on a particular document tree structure are to * be used. If the parameter "normalize-characters" of the * DOMConfiguration object attached to the * Node.ownerDocument is true, this method * will also fully normalize the characters of the Text * nodes. *

Note: In cases where the document contains * CDATASections, the normalize operation alone may not be * sufficient, since XPointers do not differentiate between * Text nodes and CDATASection nodes. * @param node the node to normalize */ public static final native void normalize(Node node) /*-{ return node.normalize(); }-*/; /** * Extracts a range of data from the node. * @param text the text node * @param offset Start offset of substring to extract. * @param count The number of 16-bit units to extract. * @return The specified substring. If the sum of offset and * count exceeds the length, then all 16-bit * units to the end of the data are returned. * @exception DOMException * INDEX_SIZE_ERR: Raised if the specified offset is * negative or greater than the number of 16-bit units in * data, or if the specified count is * negative. *
DOMSTRING_SIZE_ERR: Raised if the specified range of text does * not fit into a String. */ public static final native String substringData(Text text, int offset, int count) throws JavaScriptException /*-{ return text.substringData(offset, count); }-*/; /** * Append the string to the end of the character data of the node. Upon * success, data provides access to the concatenation of * data and the String specified. * @param text the text node * @param arg The String to append. * @exception DOMException * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. */ public static final native void appendData(Text text, String arg) throws JavaScriptException /*-{ text.appendData(offset, arg); }-*/; /** * Retrieves an attribute value by local name and namespace URI on * the specified element. *
Per [XML Namespaces] * , applications must use the value null as the * namespaceURI parameter for methods if they wish to have * no namespace. * @param elem the element * @param namespaceURI The namespace URI of the attribute to retrieve. * @param localName The local name of the attribute to retrieve. * @return The Attr value as a string, or the empty string * if that attribute does not have a specified or default value. * @exception DOMException * NOT_SUPPORTED_ERR: May be raised if the implementation does not * support the feature "XML" and the language exposed * through the Document does not support XML Namespaces (such as [HTML 4.01]). * @since DOM Level 2 */ public static final native String getAttributeNS(Element elem, String namespaceURI, String localName) throws JavaScriptException /*-{ return elem.getAttributeNS(namespaceURI, localName); }-*/; /** * Returns a NodeList of all the descendant * Elements of the specified element * with a given local name and namespace URI in * document order. * @param elem The element * @param namespaceURI The namespace URI of the elements to match on. The * special value "*" matches all namespaces. * @param localName The local name of the elements to match on. The * special value "*" matches all local names. * @return A new NodeList object containing all the matched * Elements. * @exception DOMException * NOT_SUPPORTED_ERR: May be raised if the implementation does not * support the feature "XML" and the language exposed * through the Document does not support XML Namespaces (such as [HTML 4.01]). * @since DOM Level 2 */ public static final native NodeList getElementsByTagNameNS(Element elem, String namespaceURI, String localName) throws JavaScriptException /*-{ return elem.getElementsByTagNameNS(namespaceURI, localName); }-*/; /** * Returns a NodeList of all the Elements * in the specified document with a * given local name and namespace URI in document order. * @param doc The document * @param namespaceURI The namespace URI of the elements to match on. The * special value "*" matches all namespaces. * @param localName The local name of the elements to match on. The * special value "*" matches all local names. * @return A new NodeList object containing all the matched * Elements. * @since DOM Level 2 */ public static final native NodeList getElementsByTagNameNS(Document doc, String namespaceURI, String localName) throws JavaScriptException /*-{ return doc.getElementsByTagNameNS(namespaceURI, localName); }-*/; /** * Returns the current document * @return the current document */ public static final native Document getCurrentDocument() /*-{ return $doc; }-*/; /** * Returns a NamedNodeMap containing the attributes of the * specified element. * @param elem The element * @return a NamedNodeMap containing the attributes of the * specified element */ public static final native NamedNodeMap getAttributes(Element elem) /*-{ return elem.attributes; }-*/; /** * Retrieves an attribute node by name on the specified element. *
To retrieve an attribute node by qualified name and namespace URI, * use the getAttributeNodeNS method. * @param elt The element * @param attrName The name (nodeName) of the attribute to * retrieve. * @return The Attr node with the specified name ( * nodeName) or null if there is no such * attribute. */ public static final native Attr getAttributeNode(Element elt, String attrName) /*-{ return elt.getAttributeNode(attrName); }-*/; /** * Adds a new attribute node to the specified element. If an attribute with that name ( * nodeName) is already present in the element, it is * replaced by the new one. Replacing an attribute node by itself has no * effect. *
To add a new attribute node with a qualified name and namespace * URI, use the setAttributeNodeNS method. * @param elt The element * @param attr The Attr node to add to the attribute list. * @return If the attr attribute replaces an existing * attribute, the replaced Attr node is returned, * otherwise null is returned. * @exception DOMException * WRONG_DOCUMENT_ERR: Raised if attr was created from a * different document than the one that created the element. *
NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. *
INUSE_ATTRIBUTE_ERR: Raised if attr is already an * attribute of another Element object. The DOM user must * explicitly clone Attr nodes to re-use them in other * elements. */ public static final native Attr setAttributeNode(Element elt, Attr attr) throws JavaScriptException /*-{ return elt.setAttributeNode(attr); }-*/; /** * Returns true when an attribute with a given local name and * namespace URI is specified on the specified element or has a default value, * false otherwise. *
Per [XML Namespaces] * , applications must use the value null as the * namespaceURI parameter for methods if they wish to have * no namespace. * @param elem The element * @param namespaceURI The namespace URI of the attribute to look for. * @param localName The local name of the attribute to look for. * @return true if an attribute with the given local name * and namespace URI is specified or has a default value on this * element, false otherwise. * @exception DOMException * NOT_SUPPORTED_ERR: May be raised if the implementation does not * support the feature "XML" and the language exposed * through the Document does not support XML Namespaces (such as [HTML 4.01]). */ public static final native boolean hasAttributeNS(Element elem, String namespaceURI, String localName) throws JavaScriptException /*-{ return elem.hasAttributeNS(namespaceURI, localName); }-*/; /** * Adds a new attribute to the specified element. If an attribute with the same local name and * namespace URI is already present on the element, its prefix is * changed to be the prefix part of the qualifiedName, and * its value is changed to be the value parameter. This * value is a simple string; it is not parsed as it is being set. So any * markup (such as syntax to be recognized as an entity reference) is * treated as literal text, and needs to be appropriately escaped by the * implementation when it is written out. In order to assign an * attribute value that contains entity references, the user must create * an Attr node plus any Text and * EntityReference nodes, build the appropriate subtree, * and use setAttributeNodeNS or * setAttributeNode to assign it as the value of an * attribute. *
Per [XML Namespaces] * , applications must use the value null as the * namespaceURI parameter for methods if they wish to have * no namespace. * @param elem The element * @param namespaceURI The namespace URI of the attribute to create or * alter. * @param localName The local name of the attribute to create or * alter. * @param value The value to set in string form. * @exception DOMException * INVALID_CHARACTER_ERR: Raised if the specified qualified name is not * an XML name according to the XML version in use specified in the * Document.xmlVersion attribute. *
NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. *
NAMESPACE_ERR: Raised if the qualifiedName is * malformed per the Namespaces in XML specification, if the * qualifiedName has a prefix and the * namespaceURI is null, if the * qualifiedName has a prefix that is "xml" and the * namespaceURI is different from " * http://www.w3.org/XML/1998/namespace", if the qualifiedName or its prefix is "xmlns" and the * namespaceURI is different from "http://www.w3.org/2000/xmlns/", or if the namespaceURI is "http://www.w3.org/2000/xmlns/" and neither the qualifiedName nor its prefix is "xmlns". *
NOT_SUPPORTED_ERR: May be raised if the implementation does not * support the feature "XML" and the language exposed * through the Document does not support XML Namespaces (such as [HTML 4.01]). */ public static final native void setAttributeNS(Element elem, String namespaceURI, String localName, String value) throws JavaScriptException /*-{ elem.setAttributeNS(namespaceURI, localName, value); }-*/; /** * The namespace URI of the specified node, or null if it is * unspecified (see ). *
This is not a computed value that is the result of a namespace * lookup based on an examination of the namespace declarations in * scope. It is merely the namespace URI given at creation time. *
For nodes of any type other than ELEMENT_NODE and * ATTRIBUTE_NODE and nodes created with a DOM Level 1 * method, such as Document.createElement(), this is always * null. *

Note: Per the Namespaces in XML Specification [XML Namespaces] * an attribute does not inherit its namespace from the element it is * attached to. If an attribute is not explicitly given a namespace, it * simply has no namespace. * @param node a DOM node * @return The namespace URI of this node */ public static native String getNamespaceURI(Node node) /*-{ return node.namespaceURI; }-*/; /** * Returns the local part of the qualified name of this node. *
For nodes of any type other than ELEMENT_NODE and * ATTRIBUTE_NODE and nodes created with a DOM Level 1 * method, such as Document.createElement(), this is always * null. * @param node a DOM node * @return The local part of the qualified name of this node */ public static native String getLocalName(Node node) /*-{ return node.localName; }-*/; /** * Makes a node sink the events emitted by the specified element * @param elem The element emitting the events * @param eventName The event name */ public static void bindEventListener(Element elem, String eventName) { impl.bindEventListener(elem, eventName); } /** * Stops making a node sink the events emitted by the specified element * @param elem The element emitting the events * @param eventName The event name */ public static void unbindEventListener(Element elem, String eventName) { impl.unbindEventListener(elem, eventName); } /** * Returns the element which currently captures all the * events after a call to {@link org.vectomatic.dom.svg.utils.DOMHelper#setCaptureElement(OMSVGElement, LoseCaptureHandler)} * or null if element is set to capture events * @return The event capturing element */ public static OMSVGElement getCaptureElement() { return impl.getCaptureElement(); } /** * Makes the specified element capture all the events, until * a call to {@link org.vectomatic.dom.svg.utils.DOMHelper#releaseCaptureElement()} * terminates the capture * @param element The capturing element * @param loseCaptureHandler A handler which will be invoked * if the element loses capture * @return {@link HandlerRegistration} used to remove this handler */ public static HandlerRegistration setCaptureElement(OMSVGElement element, LoseCaptureHandler loseCaptureHandler) { return impl.setCaptureElement(element, loseCaptureHandler); } /** * Stops the forwarding of all events to the capturing element * specified by {@link org.vectomatic.dom.svg.utils.DOMHelper#setCaptureElement(OMSVGElement, LoseCaptureHandler)} */ public static void releaseCaptureElement() { impl.releaseCaptureElement(); } /** * Returns the JavaScript type of an object. * The function getType is borrowed from: * JavaScript: The Definitive Guide, 5th Edition * By David Flanagan */ public static final native String getType(JavaScriptObject x) /*-{ // If x is null, return "null" if (x == null) { return "null"; } // Next try the typeof operator var t = typeof x; // If the result is not vague, return it if (t != "object") { return t; } // Hack from Chrome48+ if ('__IsSVGPathSegList__' in x) { return 'SVGPathSegList'; } // Otherwise, x is an object. Use the default toString( ) method to // get the class value of the object. var c = Object.prototype.toString.apply(x); // Returns "[object class]" c = c.substring(8, c.length-1); // Strip off "[object" and "]" // If the class is not a vague one, return it. if (c != "Object") { return c; } // If we get here, c is "Object". Check to see if // the value x is really just a generic object. if (x.constructor == Object) { return c; // Okay the type really is "Object" } // For user-defined classes, look for a string-valued property named // classname, that is inherited from the object's prototype if ("classname" in x.constructor.prototype && // inherits classname typeof x.constructor.prototype.classname == "string") // its a string return x.constructor.prototype.classname; // If we really can't figure it out, say so. return ""; }-*/; /** * Creates a value of the formed expected by SVG * href attribtues. * @param s the identifier of the data pointed by the href. * @return a value of the formed expected by SVG * href attribtues. */ public static final String toUrl(String s) { return "url(#" + s + ")"; } /** * Tests if the underlying DOM implementation supports the specified feature * @param featureName * The name of the feature to test * @return * true if the feature is supported, false otherwise */ public static boolean hasFeature(String featureName) { if (SVGConstants.SVG_FEATURE_TOUCH_EVENTS.equals(featureName)) { return supportsSvgTouchEvents(); } if (SVGConstants.SVG_FEATURE_DND_EVENTS.equals(featureName)) { return supportsSvgDndEvents(); } else { return hasFeature_(featureName); } } private static native boolean hasFeature_(String featureName) /*-{ return $doc.implementation.hasFeature(featureName, 1.1); }-*/; /** * Evaluates the specified XPath expression and returns * a iterator for the selected {@link org.vectomatic.dom.svg.OMNode} node list. * The expression must evaluate to a node list. * @param root * The element the expression is rooted at * @param expr * The XPath expression * @param resolver * A prefix resolver if the expression has prefix * @return * A node iterator for the selected nodes. */ public static Iterator evaluateXPath(OMElement root, String expr, XPathPrefixResolver resolver) { final JavaScriptObject result = impl.evaluateNodeListXPath_(root.getElement(), expr, resolver); return new Iterator() { boolean fetched; Node next; @Override public boolean hasNext() { if (!fetched) { next = iterateNext(result); fetched = true; } return next != null; } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } fetched = false; return OMNode.convert(next); } @Override public void remove() { throw new UnsupportedOperationException(); } private native Node iterateNext(JavaScriptObject result) /*-{ return result.iterateNext(); }-*/; }; } /** * Evaluates the specified XPath expression and returns * a iterator for the selected {@link com.google.gwt.dom.client.Node} node list. * The expression must evaluate to a node list. * @param root * The element the expression is rooted at * @param expr * The XPath expression * @param resolver * A prefix resolver if the expression has prefix * @return * A node iterator for the selected nodes. */ public static Iterator evaluateNodeListXPath(Element root, String expr, XPathPrefixResolver resolver) { final JavaScriptObject result = impl.evaluateNodeListXPath_(root, expr, resolver); return new Iterator() { boolean fetched; T next; @Override public boolean hasNext() { if (!fetched) { next = iterateNext(result); fetched = true; } return next != null; } @Override public T next() { if (!hasNext()) { throw new NoSuchElementException(); } fetched = false; return next; } @Override public void remove() { throw new UnsupportedOperationException(); } private native T iterateNext(JavaScriptObject result) /*-{ return result.iterateNext(); }-*/; }; } /** * Evaluates the specified XPath expression and returns * the matching {@link com.google.gwt.dom.client.Node} node. * The expression must evaluate to a single node. * @param root * The element the expression is rooted at * @param expr * The XPath expression * @param resolver * A prefix resolver if the expression has prefix * @return * The selected node, or null if no such node exists. */ public static T evaluateNodeXPath(Element root, String expr, XPathPrefixResolver resolver) { return (T)(impl.evaluateNodeXPath_(root, expr, resolver)); } /** * Evaluates the specified XPath expression and returns * the matching {@link java.lang.String}. * The expression must evaluate to a string. * @param root * The element the expression is rooted at * @param expr * The XPath expression * @param resolver * A prefix resolver if the expression has prefix * @return * The matching string, or null if no such string exists. */ public static String evaluateStringXPath(Element root, String expr, XPathPrefixResolver resolver) { return impl.evaluateStringXPath_(root, expr, resolver); } /** * Evaluates the specified XPath expression and returns * the matching float. * The expression must evaluate to a number. * @param root * The element the expression is rooted at * @param expr * The XPath expression * @param resolver * A prefix resolver if the expression has prefix * @return * The matching float, or NaN if no such number exists. */ public static float evaluateNumberXPath(Element root, String expr, XPathPrefixResolver resolver) { return impl.evaluateNumberXPath_(root, expr, resolver); } /** * Evaluates the specified XPath expression and returns * the matching boolean. * The expression must evaluate to a boolean. * @param root * The element the expression is rooted at * @param expr * The XPath expression * @param resolver * A prefix resolver if the expression has prefix * @return * The matching boolean. */ public static boolean evaluateBooleanXPath(Element root, String expr, XPathPrefixResolver resolver) { return impl.evaluateBooleanXPath_(root, expr, resolver); } /** * Returns an XPath expression which enables reaching the specified node * from the root node * @param node * The node to reach * @param root * The root node, or null to specify the document root * @return * An XPath expression which enables reaching the specified node * from the root node */ public static String getXPath(Node node, Node root) { StringBuilder builder = new StringBuilder(); Node parentNode; while ((node != root) && (parentNode = node.getParentNode()) != null) { NodeList siblings = parentNode.getChildNodes(); int index = 0; for (int i = 0, length = siblings.getLength(); i < length; i++) { Node sibling = siblings.getItem(i); if (sibling.getNodeType() == Node.ELEMENT_NODE) { index++; if (node == sibling) { builder.insert(0, "/*[" + index + "]"); break; } } } node = parentNode; } return builder.toString(); } /** * Returns whether touch events on SVG elements are supported * on the current platform. * @return true if touch events on SVG elements are supported * on the current platform, false otherwise * @deprecated * Use the {@link #hasFeature(String)} method with the * {@link SVGConstants#SVG_FEATURE_TOUCH_EVENTS} parameter instead. */ public static native boolean supportsSvgTouchEvents() /*-{ var elem = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); elem.setAttribute('ontouchstart', 'return;'); return (typeof elem.ontouchstart) == "function"; }-*/; /*** * Returns whether drag and drop events on SVG elements are supported * on the current platform. * @return true if drag and drop events on SVG elements are supported * on the current platform, false otherwise */ private static native boolean supportsSvgDndEvents() /*-{ var elem = document.createElementNS('http://www.w3.org/2000/svg', 'circle'); return 'ondragstart' in elem; }-*/; /** * Returns a base64 encoding of the specified binary string * @param str * A binary string (obtained for instance by the FileReader API) * @return a base64 encoded string. */ public static native String base64encode(String str) /*-{ return $wnd.btoa(str); }-*/; }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy