1 /********************************************** 2 * Copyright (C) 2010 Lukas Laag 3 * This file is part of lib-gwt-svg. 4 * 5 * libgwtsvg is free software: you can redistribute it and/or modify 6 * it under the terms of the GNU Lesser General Public License as published by 7 * the Free Software Foundation, either version 3 of the License, or 8 * (at your option) any later version. 9 * 10 * libgwtsvg is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU Lesser General Public License for more details. 14 * 15 * You should have received a copy of the GNU Lesser General Public License 16 * along with libgwtsvg. If not, see http://www.gnu.org/licenses/ 17 **********************************************/ 18 /* 19 * Copyright (c) 2004 World Wide Web Consortium, 20 * 21 * (Massachusetts Institute of Technology, European Research Consortium for 22 * Informatics and Mathematics, Keio University). All Rights Reserved. This 23 * work is distributed under the W3C(r) Software License [1] in the hope that 24 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied 25 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 26 * 27 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 28 */ 29 package org.vectomatic.dom.svg; 30 31 import org.vectomatic.dom.svg.utils.DOMHelper; 32 import org.w3c.dom.DOMException; 33 34 import com.google.gwt.core.client.JavaScriptException; 35 import com.google.gwt.dom.client.Document; 36 import com.google.gwt.dom.client.Element; 37 38 /** 39 * Wrapper class for DOM Document 40 * @author laaglu 41 */ 42 public class OMDocument extends OMNode { 43 /** 44 * Constructor 45 * @param document The wrapped document 46 */ 47 protected OMDocument(Document document) { 48 super(document); 49 } 50 51 /** 52 * Returns the wrapped {@link com.google.gwt.dom.client.Document} 53 * @return the wrapped {@link com.google.gwt.dom.client.Document} 54 */ 55 public Document getDocument() { 56 return ot.cast(); 57 } 58 59 // Implementation of the dom::Document W3C IDL interface 60 61 /** 62 * Creates an {@link OMElement} of the given qualified name and namespace URI. 63 * <br>Per [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] 64 * , applications must use the value <code>null</code> as the 65 * namespaceURI parameter for methods if they wish to have no namespace. 66 * @param namespaceURI The namespace URI of the element to create. 67 * @param qualifiedName The qualified name of the element type to 68 * instantiate. 69 * @return A new {@link OMElement} object with the following 70 * attributes: 71 * <table border='1' cellpadding='3'> 72 * <tr> 73 * <th>Attribute</th> 74 * <th>Value</th> 75 * </tr> 76 * <tr> 77 * <td valign='top' rowspan='1' colspan='1'><code>Node.nodeName</code></td> 78 * <td valign='top' rowspan='1' colspan='1'> 79 * <code>qualifiedName</code></td> 80 * </tr> 81 * <tr> 82 * <td valign='top' rowspan='1' colspan='1'><code>Node.namespaceURI</code></td> 83 * <td valign='top' rowspan='1' colspan='1'> 84 * <code>namespaceURI</code></td> 85 * </tr> 86 * <tr> 87 * <td valign='top' rowspan='1' colspan='1'><code>Node.prefix</code></td> 88 * <td valign='top' rowspan='1' colspan='1'>prefix, extracted 89 * from <code>qualifiedName</code>, or <code>null</code> if there is 90 * no prefix</td> 91 * </tr> 92 * <tr> 93 * <td valign='top' rowspan='1' colspan='1'><code>Node.localName</code></td> 94 * <td valign='top' rowspan='1' colspan='1'>local name, extracted from 95 * <code>qualifiedName</code></td> 96 * </tr> 97 * <tr> 98 * <td valign='top' rowspan='1' colspan='1'><code>Element.tagName</code></td> 99 * <td valign='top' rowspan='1' colspan='1'> 100 * <code>qualifiedName</code></td> 101 * </tr> 102 * </table> 103 * @exception DOMException 104 * INVALID_CHARACTER_ERR: Raised if the specified 105 * <code>qualifiedName</code> is not an XML name according to the XML 106 * version in use specified in the <code>Document.xmlVersion</code> 107 * attribute. 108 * <br>NAMESPACE_ERR: Raised if the <code>qualifiedName</code> is a 109 * malformed qualified name, if the <code>qualifiedName</code> has a 110 * prefix and the <code>namespaceURI</code> is <code>null</code>, or 111 * if the <code>qualifiedName</code> has a prefix that is "xml" and 112 * the <code>namespaceURI</code> is different from "<a href='http://www.w3.org/XML/1998/namespace'> 113 * http://www.w3.org/XML/1998/namespace</a>" [<a href='http://www.w3.org/TR/1999/REC-xml-names-19990114/'>XML Namespaces</a>] 114 * , or if the <code>qualifiedName</code> or its prefix is "xmlns" and 115 * the <code>namespaceURI</code> is different from "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>", or if the <code>namespaceURI</code> is "<a href='http://www.w3.org/2000/xmlns/'>http://www.w3.org/2000/xmlns/</a>" and neither the <code>qualifiedName</code> nor its prefix is "xmlns". 116 * <br>NOT_SUPPORTED_ERR: Always thrown if the current document does not 117 * support the <code>"XML"</code> feature, since namespaces were 118 * defined by XML. 119 */ 120 public final OMElement createElementNS(String namespaceURI, String qualifiedName) throws JavaScriptException { 121 return OMNode.convert(DOMHelper.createElementNS(((Document)ot), namespaceURI, qualifiedName)); 122 } 123 /** 124 * Creates a new {@link OMText} node and initializes it 125 * with the specified data. The node is not attached to the 126 * DOM tree. 127 * @param data The string to initialize the text node 128 * @return The newly created {@link OMText} node 129 */ 130 public final OMText createTextNode(String data) { 131 return OMNode.convert(((Document)ot).createTextNode(data)); 132 } 133 /** 134 * Returns a <code>OMNodeList</code> of all the <code>OMElements</code> in 135 * document order with a given tag name and are contained in the 136 * document. 137 * @param tagname The name of the tag to match on. The special value "*" 138 * matches all tags. For XML, the <code>tagname</code> parameter is 139 * case-sensitive, otherwise it depends on the case-sensitivity of the 140 * markup language in use. 141 * @return A new <code>OMNodeList</code> object containing all the matched 142 * <code>Elements</code>. 143 */ 144 public final <T extends OMElement> OMNodeList<T> getElementsByTagName(String tagname) { 145 return OMNode.convertList(((Document)ot).getElementsByTagName(tagname)); 146 } 147 /** 148 * Returns a <code>OMNodeList</code> of all the <code>OMElements</code> with a 149 * given local name and namespace URI in document order. 150 * @param namespaceURI The namespace URI of the elements to match on. The 151 * special value <code>"*"</code> matches all namespaces. 152 * @param localName The local name of the elements to match on. The 153 * special value "*" matches all local names. 154 * @return A new <code>OMNodeList</code> object containing all the matched 155 * <code>Elements</code>. 156 */ 157 public final <T extends OMElement> OMNodeList<T> getElementsByTagNameNS(String namespaceURI, String localName) { 158 return OMNode.convertList(DOMHelper.getElementsByTagNameNS(((Document)ot), namespaceURI, localName)); 159 } 160 /** 161 * Returns the <code>OMElement</code> that has an ID attribute with the 162 * given value. If no such element exists, this returns <code>null</code> 163 * . If more than one element has an ID attribute with that value, what 164 * is returned is undefined. 165 * <br> The DOM implementation is expected to use the attribute 166 * <code>Attr.isId</code> to determine if an attribute is of type ID. 167 * <p ><b>Note:</b> Attributes with the name "ID" or "id" are not of type 168 * ID unless so defined. 169 * @param elementId The unique <code>id</code> value for an element. 170 * @return The matching element or <code>null</code> if there is none. 171 */ 172 public final <T extends OMElement> T getElementById(String elementId) { 173 Element elt = ((Document)ot).getElementById(elementId); 174 return elt != null ? OMNode.<T>convert(elt) : null; 175 } 176 177 /** 178 * This is a convenience attribute that allows direct access to the child 179 * node that is the document element of the document. 180 */ 181 public final OMElement getDocumentElement() { 182 return OMNode.convert(((Document)ot).getDocumentElement()); 183 } 184 185 186 /** 187 * Imports a node from another document to this document, without altering 188 * or removing the source node from the original document; this method 189 * creates a new copy of the source node. The returned node has no 190 * parent; (<code>parentNode</code> is <code>null</code>). 191 * <br>For all nodes, importing a node creates a node object owned by the 192 * importing document, with attribute values identical to the source 193 * node's <code>nodeName</code> and <code>nodeType</code>, plus the 194 * attributes related to namespaces (<code>prefix</code>, 195 * <code>localName</code>, and <code>namespaceURI</code>). As in the 196 * <code>cloneNode</code> operation, the source node is not altered. 197 * User data associated to the imported node is not carried over. 198 * However, if any <code>UserDataHandlers</code> has been specified 199 * along with the associated data these handlers will be called with the 200 * appropriate parameters before this method returns. 201 * <br>Additional information is copied as appropriate to the 202 * <code>nodeType</code>, attempting to mirror the behavior expected if 203 * a fragment of XML or HTML source was copied from one document to 204 * another, recognizing that the two documents may have different DTDs 205 * in the XML case. The following list describes the specifics for each 206 * type of node. 207 * <dl> 208 * <dt>ATTRIBUTE_NODE</dt> 209 * <dd>The <code>ownerElement</code> attribute 210 * is set to <code>null</code> and the <code>specified</code> flag is 211 * set to <code>true</code> on the generated {@link OMAttr}. The 212 * descendants of the source {@link OMAttr} are recursively imported 213 * and the resulting nodes reassembled to form the corresponding subtree. 214 * Note that the <code>deep</code> parameter has no effect on 215 * {@link OMAttr} nodes; they always carry their children with them 216 * when imported.</dd> 217 * <dt>DOCUMENT_FRAGMENT_NODE</dt> 218 * <dd>If the <code>deep</code> option 219 * was set to <code>true</code>, the descendants of the source 220 * <code>DocumentFragment</code> are recursively imported and the 221 * resulting nodes reassembled under the imported 222 * <code>DocumentFragment</code> to form the corresponding subtree. 223 * Otherwise, this simply generates an empty 224 * <code>DocumentFragment</code>.</dd> 225 * <dt>DOCUMENT_NODE</dt> 226 * <dd><code>Document</code> 227 * nodes cannot be imported.</dd> 228 * <dt>DOCUMENT_TYPE_NODE</dt> 229 * <dd><code>DocumentType</code> 230 * nodes cannot be imported.</dd> 231 * <dt>ELEMENT_NODE</dt> 232 * <dd><em>Specified</em> attribute nodes of the source element are imported, and the generated 233 * {@link OMAttr} nodes are attached to the generated 234 * {@link OMElement}. Default attributes are <em>not</em> copied, though if the document being imported into defines default 235 * attributes for this element name, those are assigned. If the 236 * <code>importNode</code> <code>deep</code> parameter was set to 237 * <code>true</code>, the descendants of the source element are 238 * recursively imported and the resulting nodes reassembled to form the 239 * corresponding subtree.</dd> 240 * <dt>ENTITY_NODE</dt> 241 * <dd><code>Entity</code> nodes can be 242 * imported, however in the current release of the DOM the 243 * <code>DocumentType</code> is readonly. Ability to add these imported 244 * nodes to a <code>DocumentType</code> will be considered for addition 245 * to a future release of the DOM.On import, the <code>publicId</code>, 246 * <code>systemId</code>, and <code>notationName</code> attributes are 247 * copied. If a <code>deep</code> import is requested, the descendants 248 * of the the source <code>Entity</code> are recursively imported and 249 * the resulting nodes reassembled to form the corresponding subtree.</dd> 250 * <dt> 251 * ENTITY_REFERENCE_NODE</dt> 252 * <dd>Only the <code>EntityReference</code> itself is 253 * copied, even if a <code>deep</code> import is requested, since the 254 * source and destination documents might have defined the entity 255 * differently. If the document being imported into provides a 256 * definition for this entity name, its value is assigned.</dd> 257 * <dt>NOTATION_NODE</dt> 258 * <dd> 259 * <code>Notation</code> nodes can be imported, however in the current 260 * release of the DOM the <code>DocumentType</code> is readonly. Ability 261 * to add these imported nodes to a <code>DocumentType</code> will be 262 * considered for addition to a future release of the DOM.On import, the 263 * <code>publicId</code> and <code>systemId</code> attributes are copied. 264 * Note that the <code>deep</code> parameter has no effect on this type 265 * of nodes since they cannot have any children.</dd> 266 * <dt> 267 * PROCESSING_INSTRUCTION_NODE</dt> 268 * <dd>The imported node copies its 269 * <code>target</code> and <code>data</code> values from those of the 270 * source node.Note that the <code>deep</code> parameter has no effect 271 * on this type of nodes since they cannot have any children.</dd> 272 * <dt>TEXT_NODE, 273 * CDATA_SECTION_NODE, COMMENT_NODE</dt> 274 * <dd>These three types of nodes inheriting 275 * from <code>CharacterData</code> copy their <code>data</code> and 276 * <code>length</code> attributes from those of the source node.Note 277 * that the <code>deep</code> parameter has no effect on these types of 278 * nodes since they cannot have any children.</dd> 279 * </dl> 280 * @param importedNode The node to import. 281 * @param deep If <code>true</code>, recursively import the subtree under 282 * the specified node; if <code>false</code>, import only the node 283 * itself, as explained above. This has no effect on nodes that cannot 284 * have any children, and on {@link OMAttr}, and 285 * <code>EntityReference</code> nodes. 286 * @return The imported node that belongs to this <code>Document</code>. 287 * @exception DOMException 288 * NOT_SUPPORTED_ERR: Raised if the type of node being imported is not 289 * supported. 290 * <br>INVALID_CHARACTER_ERR: Raised if one of the imported names is not 291 * an XML name according to the XML version in use specified in the 292 * <code>Document.xmlVersion</code> attribute. This may happen when 293 * importing an XML 1.1 [<a href='http://www.w3.org/TR/2004/REC-xml11-20040204/'>XML 1.1</a>] element 294 * into an XML 1.0 document, for instance. 295 */ 296 public final OMNode importNode(OMNode importedNode, boolean deep) { 297 return OMNode.convert(DOMHelper.importNode(((Document)ot), importedNode.getNode(), deep)); 298 } 299 }