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 30 package org.vectomatic.dom.svg; 31 32 import org.vectomatic.dom.svg.impl.SVGElement; 33 34 import com.google.gwt.core.client.JavaScriptException; 35 36 /** 37 * All of the SVG DOM interfaces that correspond directly to elements in the 38 * SVG language (such as the {@link org.vectomatic.dom.svg.OMSVGPathElement} 39 * interface for the <a href='http://www.w3.org/TR/SVG11/paths.html#PathElement' 40 * title='path element specification'>path</a> element) derive from the {@link 41 * org.vectomatic.dom.svg.OMSVGElement} interface. 42 */ 43 public abstract class OMSVGElement extends OMElement { 44 protected OMSVGElement(SVGElement ot) { 45 super(ot); 46 } 47 48 // Implementation of the svg::SVGElement W3C IDL interface 49 /** 50 * Corresponds to attribute <code>xml:base</code> on the given element. 51 */ 52 public final String getXmlbase() { 53 return ((SVGElement)ot).getXmlbase(); 54 } 55 /** 56 * Corresponds to attribute <code>xml:base</code> on the given element. 57 * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) Raised on an attempt 58 * to change the value of a <a href="svgdom.html#ReadOnlyNodes">read only 59 * attribute</a>. 60 */ 61 public final void setXmlbase(java.lang.String value) throws JavaScriptException { 62 ((SVGElement)ot).setXmlbase(value); 63 } 64 /** 65 * The nearest ancestor <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' 66 * title='svg element specification'>svg</a> element. Null if the given element 67 * is the outermost <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' 68 * title='svg element specification'>svg</a> element. 69 */ 70 public final OMSVGSVGElement getOwnerSVGElement() { 71 return (OMSVGSVGElement)convert(((SVGElement)ot).getOwnerSVGElement()); 72 } 73 /** 74 * The element which established the current viewport. Often, the nearest 75 * ancestor <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' title='svg 76 * element specification'>svg</a> element. Null if the given element is the 77 * outermost <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' title='svg 78 * element specification'>svg</a> element. 79 */ 80 public final OMSVGElement getViewportElement() { 81 return (OMSVGElement)convert(((SVGElement)ot).getViewportElement()); 82 } 83 84 /** 85 * Sets the 'id' attribute of the specified element 86 * @param value the value of the 'id' attribute 87 */ 88 public final void setId(java.lang.String value) { 89 ((SVGElement)ot).setId(value); 90 } 91 92 // Implementation of the svg::Stylable W3C IDL interface 93 /** 94 * Returns the CSS style of this element 95 */ 96 public OMSVGStyle getStyle() { 97 return ((SVGElement) ot).getStyle().cast(); 98 } 99 100 /** 101 * Returns the CSS class name of this element. Note that 102 * in SVG, this class name can change over the time (there is 103 * a baseVal and an animVal). 104 * @return the CSS class name of this element 105 */ 106 public final OMSVGAnimatedString getClassName() { 107 return ((SVGElement) ot).getClassName_(); 108 } 109 110 /** 111 * Adds the specified class name to the baseVal CSS class name of this element 112 * @param className the class name to add 113 */ 114 public final void addClassNameBaseVal(String className) { 115 assert (className != null) : "Unexpectedly null class name"; 116 117 className = className.trim(); 118 assert (className.length() != 0) : "Unexpectedly empty class name"; 119 120 // Get the current style string. 121 String oldClassName = getClassName().getBaseVal(); 122 int idx = oldClassName.indexOf(className); 123 124 // Calculate matching index. 125 while (idx != -1) { 126 if (idx == 0 || oldClassName.charAt(idx - 1) == ' ') { 127 int last = idx + className.length(); 128 int lastPos = oldClassName.length(); 129 if ((last == lastPos) 130 || ((last < lastPos) && (oldClassName.charAt(last) == ' '))) { 131 break; 132 } 133 } 134 idx = oldClassName.indexOf(className, idx + 1); 135 } 136 137 // Only add the style if it's not already present. 138 if (idx == -1) { 139 if (oldClassName.length() > 0) { 140 oldClassName += " "; 141 } 142 setClassNameBaseVal(oldClassName + className); 143 } 144 } 145 146 /** 147 * Removes the specified class name from the baseVal CSS class name of this element 148 * @param className the class name to remove 149 */ 150 public final void removeClassNameBaseVal(String className) { 151 assert (className != null) : "Unexpectedly null class name"; 152 153 className = className.trim(); 154 assert (className.length() != 0) : "Unexpectedly empty class name"; 155 156 // Get the current style string. 157 String oldStyle = getClassName().getBaseVal(); 158 int idx = oldStyle.indexOf(className); 159 160 // Calculate matching index. 161 while (idx != -1) { 162 if (idx == 0 || oldStyle.charAt(idx - 1) == ' ') { 163 int last = idx + className.length(); 164 int lastPos = oldStyle.length(); 165 if ((last == lastPos) 166 || ((last < lastPos) && (oldStyle.charAt(last) == ' '))) { 167 break; 168 } 169 } 170 idx = oldStyle.indexOf(className, idx + 1); 171 } 172 173 // Don't try to remove the style if it's not there. 174 if (idx != -1) { 175 // Get the leading and trailing parts, without the removed name. 176 String begin = oldStyle.substring(0, idx).trim(); 177 String end = oldStyle.substring(idx + className.length()).trim(); 178 179 // Some contortions to make sure we don't leave extra spaces. 180 String newClassName; 181 if (begin.length() == 0) { 182 newClassName = end; 183 } else if (end.length() == 0) { 184 newClassName = begin; 185 } else { 186 newClassName = begin + " " + end; 187 } 188 189 setClassNameBaseVal(newClassName); 190 } 191 } 192 193 /** 194 * Replaces the specified class name in the baseVal CSS class name of this element 195 * with a new class name 196 * @param oldClassName the class name to replace 197 * @param newClassName the replacement class name 198 */ 199 public final void replaceClassNameBaseVal(String oldClassName, String newClassName) { 200 removeClassNameBaseVal(oldClassName); 201 addClassNameBaseVal(newClassName); 202 } 203 204 /** 205 * Sets the baseVal CSS class name of this element to the specified value 206 * @param className the class name 207 */ 208 public final void setClassNameBaseVal(String className) { 209 getClassName().setBaseVal(className); 210 } 211 212 /** 213 * Returns the XML markup which corresponds to the subtree rooted 214 * at this element 215 * @return the XML markup which corresponds to the subtree rooted 216 * at this element 217 */ 218 public final String getMarkup() { 219 return ((SVGElement) ot).getMarkup(); 220 } 221 }