001/********************************************** 002 * Copyright (C) 2010 Lukas Laag 003 * This file is part of lib-gwt-svg. 004 * 005 * libgwtsvg is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * libgwtsvg is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with libgwtsvg. If not, see http://www.gnu.org/licenses/ 017 **********************************************/ 018/* 019 * Copyright (c) 2004 World Wide Web Consortium, 020 * 021 * (Massachusetts Institute of Technology, European Research Consortium for 022 * Informatics and Mathematics, Keio University). All Rights Reserved. This 023 * work is distributed under the W3C(r) Software License [1] in the hope that 024 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied 025 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 026 * 027 * [1] http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 028 */ 029 030package org.vectomatic.dom.svg; 031 032import org.vectomatic.dom.svg.impl.SVGElement; 033 034import com.google.gwt.core.client.JavaScriptException; 035 036/** 037 * All of the SVG DOM interfaces that correspond directly to elements in the 038 * SVG language (such as the {@link org.vectomatic.dom.svg.OMSVGPathElement} 039 * interface for the <a href='http://www.w3.org/TR/SVG11/paths.html#PathElement' 040 * title='path element specification'>path</a> element) derive from the {@link 041 * org.vectomatic.dom.svg.OMSVGElement} interface. 042 */ 043public abstract class OMSVGElement extends OMElement { 044 protected OMSVGElement(SVGElement ot) { 045 super(ot); 046 } 047 048 // Implementation of the svg::SVGElement W3C IDL interface 049 /** 050 * Corresponds to attribute <code>xml:base</code> on the given element. 051 */ 052 public final String getXmlbase() { 053 return ((SVGElement)ot).getXmlbase(); 054 } 055 /** 056 * Corresponds to attribute <code>xml:base</code> on the given element. 057 * @throws DOMException(NO_MODIFICATION_ALLOWED_ERR) Raised on an attempt 058 * to change the value of a <a href="svgdom.html#ReadOnlyNodes">read only 059 * attribute</a>. 060 */ 061 public final void setXmlbase(java.lang.String value) throws JavaScriptException { 062 ((SVGElement)ot).setXmlbase(value); 063 } 064 /** 065 * The nearest ancestor <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' 066 * title='svg element specification'>svg</a> element. Null if the given element 067 * is the outermost <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' 068 * title='svg element specification'>svg</a> element. 069 */ 070 public final OMSVGSVGElement getOwnerSVGElement() { 071 return (OMSVGSVGElement)convert(((SVGElement)ot).getOwnerSVGElement()); 072 } 073 /** 074 * The element which established the current viewport. Often, the nearest 075 * ancestor <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' title='svg 076 * element specification'>svg</a> element. Null if the given element is the 077 * outermost <a href='http://www.w3.org/TR/SVG11/struct.html#SVGElement' title='svg 078 * element specification'>svg</a> element. 079 */ 080 public final OMSVGElement getViewportElement() { 081 return (OMSVGElement)convert(((SVGElement)ot).getViewportElement()); 082 } 083 084 /** 085 * Sets the 'id' attribute of the specified element 086 * @param value the value of the 'id' attribute 087 */ 088 public final void setId(java.lang.String value) { 089 ((SVGElement)ot).setId(value); 090 } 091 092 // Implementation of the svg::Stylable W3C IDL interface 093 /** 094 * Returns the CSS style of this element 095 */ 096 public OMSVGStyle getStyle() { 097 return ((SVGElement) ot).getStyle().cast(); 098 } 099 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}