1 /* 2 * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann (at) kde.org> 3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis (at) kde.org> 4 * 5 * This library is free software; you can redistribute it and/or 6 * modify it under the terms of the GNU Library General Public 7 * License as published by the Free Software Foundation; either 8 * version 2 of the License, or (at your option) any later version. 9 * 10 * This library 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 GNU 13 * Library General Public License for more details. 14 * 15 * You should have received a copy of the GNU Library General Public License 16 * along with this library; see the file COPYING.LIB. If not, write to 17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 18 * Boston, MA 02110-1301, USA. 19 */ 20 21 #include "config.h" 22 23 #include "core/svg/SVGTests.h" 24 25 #include "SVGNames.h" 26 #include "core/dom/DOMImplementation.h" 27 #include "core/platform/Language.h" 28 #include "core/svg/SVGElement.h" 29 #include "core/svg/SVGStringList.h" 30 31 namespace WebCore { 32 33 // Define custom non-animated property 'requiredFeatures'. 34 const SVGPropertyInfo* SVGTests::requiredFeaturesPropertyInfo() 35 { 36 static const SVGPropertyInfo* s_propertyInfo = 0; 37 if (!s_propertyInfo) { 38 s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, 39 PropertyIsReadWrite, 40 SVGNames::requiredFeaturesAttr, 41 SVGNames::requiredFeaturesAttr.localName(), 42 &SVGElement::synchronizeRequiredFeatures, 43 0); 44 } 45 return s_propertyInfo; 46 } 47 48 // Define custom non-animated property 'requiredExtensions'. 49 const SVGPropertyInfo* SVGTests::requiredExtensionsPropertyInfo() 50 { 51 static const SVGPropertyInfo* s_propertyInfo = 0; 52 if (!s_propertyInfo) { 53 s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, 54 PropertyIsReadWrite, 55 SVGNames::requiredExtensionsAttr, 56 SVGNames::requiredExtensionsAttr.localName(), 57 &SVGElement::synchronizeRequiredExtensions, 58 0); 59 } 60 return s_propertyInfo; 61 } 62 63 // Define custom non-animated property 'systemLanguage'. 64 const SVGPropertyInfo* SVGTests::systemLanguagePropertyInfo() 65 { 66 static const SVGPropertyInfo* s_propertyInfo = 0; 67 if (!s_propertyInfo) { 68 s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, 69 PropertyIsReadWrite, 70 SVGNames::systemLanguageAttr, 71 SVGNames::systemLanguageAttr.localName(), 72 &SVGElement::synchronizeSystemLanguage, 73 0); 74 } 75 return s_propertyInfo; 76 } 77 78 SVGTests::SVGTests() 79 : m_requiredFeatures(SVGNames::requiredFeaturesAttr) 80 , m_requiredExtensions(SVGNames::requiredExtensionsAttr) 81 , m_systemLanguage(SVGNames::systemLanguageAttr) 82 { 83 } 84 85 SVGAttributeToPropertyMap& SVGTests::attributeToPropertyMap() 86 { 87 DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, map, ()); 88 if (!map.isEmpty()) 89 return map; 90 map.addProperty(requiredFeaturesPropertyInfo()); 91 map.addProperty(requiredExtensionsPropertyInfo()); 92 map.addProperty(systemLanguagePropertyInfo()); 93 return map; 94 } 95 96 bool SVGTests::hasExtension(const String&) const 97 { 98 // FIXME: Implement me! 99 return false; 100 } 101 102 bool SVGTests::isValid() const 103 { 104 unsigned featuresSize = m_requiredFeatures.value.size(); 105 for (unsigned i = 0; i < featuresSize; ++i) { 106 String value = m_requiredFeatures.value.at(i); 107 if (value.isEmpty() || !DOMImplementation::hasFeature(value, String())) 108 return false; 109 } 110 111 unsigned systemLanguageSize = m_systemLanguage.value.size(); 112 for (unsigned i = 0; i < systemLanguageSize; ++i) { 113 String value = m_systemLanguage.value.at(i); 114 if (value != defaultLanguage().substring(0, 2)) 115 return false; 116 } 117 118 if (!m_requiredExtensions.value.isEmpty()) 119 return false; 120 121 return true; 122 } 123 124 bool SVGTests::parseAttribute(const QualifiedName& name, const AtomicString& value) 125 { 126 if (name == SVGNames::requiredFeaturesAttr) { 127 m_requiredFeatures.value.reset(value); 128 return true; 129 } 130 if (name == SVGNames::requiredExtensionsAttr) { 131 m_requiredExtensions.value.reset(value); 132 return true; 133 } 134 if (name == SVGNames::systemLanguageAttr) { 135 m_systemLanguage.value.reset(value); 136 return true; 137 } 138 139 return false; 140 } 141 142 bool SVGTests::isKnownAttribute(const QualifiedName& attrName) 143 { 144 return attrName == SVGNames::requiredFeaturesAttr 145 || attrName == SVGNames::requiredExtensionsAttr 146 || attrName == SVGNames::systemLanguageAttr; 147 } 148 149 bool SVGTests::handleAttributeChange(SVGElement* targetElement, const QualifiedName& attrName) 150 { 151 ASSERT(targetElement); 152 if (!isKnownAttribute(attrName)) 153 return false; 154 if (!targetElement->inDocument()) 155 return true; 156 157 bool valid = targetElement->isValid(); 158 if (valid && !targetElement->attached() && targetElement->parentNode()->attached()) 159 targetElement->lazyAttach(); 160 else if (!valid && targetElement->attached()) 161 targetElement->detach(); 162 163 return true; 164 } 165 166 void SVGTests::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) 167 { 168 supportedAttributes.add(SVGNames::requiredFeaturesAttr); 169 supportedAttributes.add(SVGNames::requiredExtensionsAttr); 170 supportedAttributes.add(SVGNames::systemLanguageAttr); 171 } 172 173 void SVGTests::synchronizeRequiredFeatures(SVGElement* contextElement) 174 { 175 ASSERT(contextElement); 176 if (!m_requiredFeatures.shouldSynchronize) 177 return; 178 AtomicString value(m_requiredFeatures.value.valueAsString()); 179 m_requiredFeatures.synchronize(contextElement, requiredFeaturesPropertyInfo()->attributeName, value); 180 } 181 182 void SVGTests::synchronizeRequiredExtensions(SVGElement* contextElement) 183 { 184 ASSERT(contextElement); 185 if (!m_requiredExtensions.shouldSynchronize) 186 return; 187 AtomicString value(m_requiredExtensions.value.valueAsString()); 188 m_requiredExtensions.synchronize(contextElement, requiredExtensionsPropertyInfo()->attributeName, value); 189 } 190 191 void SVGTests::synchronizeSystemLanguage(SVGElement* contextElement) 192 { 193 ASSERT(contextElement); 194 if (!m_systemLanguage.shouldSynchronize) 195 return; 196 AtomicString value(m_systemLanguage.value.valueAsString()); 197 m_systemLanguage.synchronize(contextElement, systemLanguagePropertyInfo()->attributeName, value); 198 } 199 200 SVGStringList& SVGTests::requiredFeatures() 201 { 202 m_requiredFeatures.shouldSynchronize = true; 203 return m_requiredFeatures.value; 204 } 205 206 SVGStringList& SVGTests::requiredExtensions() 207 { 208 m_requiredExtensions.shouldSynchronize = true; 209 return m_requiredExtensions.value; 210 } 211 212 SVGStringList& SVGTests::systemLanguage() 213 { 214 m_systemLanguage.shouldSynchronize = true; 215 return m_systemLanguage.value; 216 } 217 218 } 219