diff options
Diffstat (limited to 'Source/WebCore/svg/SVGTests.cpp')
-rw-r--r-- | Source/WebCore/svg/SVGTests.cpp | 259 |
1 files changed, 151 insertions, 108 deletions
diff --git a/Source/WebCore/svg/SVGTests.cpp b/Source/WebCore/svg/SVGTests.cpp index 1daa76a6c..e44c334f1 100644 --- a/Source/WebCore/svg/SVGTests.cpp +++ b/Source/WebCore/svg/SVGTests.cpp @@ -1,6 +1,7 @@ /* * Copyright (C) 2004, 2005, 2008 Nikolas Zimmermann <zimmermann@kde.org> * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org> + * Copyright (C) 2015-2016 Apple Inc. All right reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -19,17 +20,15 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "SVGTests.h" -#include "Attribute.h" #include "DOMImplementation.h" #include "HTMLNames.h" #include "Language.h" #include "SVGElement.h" #include "SVGNames.h" #include "SVGStringList.h" +#include <wtf/NeverDestroyed.h> #if ENABLE(MATHML) #include "MathMLNames.h" @@ -37,189 +36,233 @@ namespace WebCore { -// Define custom non-animated property 'requiredFeatures'. -const SVGPropertyInfo* SVGTests::requiredFeaturesPropertyInfo() -{ - static const SVGPropertyInfo* s_propertyInfo = 0; - if (!s_propertyInfo) { - s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, - PropertyIsReadWrite, - SVGNames::requiredFeaturesAttr, - SVGNames::requiredFeaturesAttr.localName(), - &SVGElement::synchronizeRequiredFeatures, - 0); - } - return s_propertyInfo; +using namespace SVGNames; + +static const HashSet<String, ASCIICaseInsensitiveHash>& supportedSVGFeatures() +{ + static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> features = [] { + static const char* const features10[] = { +#if ENABLE(SVG_FONTS) + "dom", + "dom.svg", + "dom.svg.static", + "svg", + "svg.static", +#endif + }; + static const char* const features11[] = { + "animation", + "basegraphicsattribute", + "basicclip", + "basicfilter", + "basicpaintattribute", + "basicstructure", + "basictext", + "clip", + "conditionalprocessing", + "containerattribute", + "coreattribute", + "cursor", + "documenteventsattribute", + "extensibility", + "externalresourcesrequired", + "filter", + "gradient", + "graphicaleventsattribute", + "graphicsattribute", + "hyperlinking", + "image", + "marker", + "mask", + "opacityattribute", + "paintattribute", + "pattern", + "script", + "shape", + "structure", + "style", + "svg-animation", + "svgdom-animation", + "text", + "view", + "viewportattribute", + "xlinkattribute", +#if ENABLE(SVG_FONTS) + "basicfont", + "font", + "svg", + "svg-static", + "svgdom", + "svgdom-static", +#endif + }; + HashSet<String, ASCIICaseInsensitiveHash> set; + for (auto& feature : features10) + set.add(makeString("org.w3c.", feature)); + for (auto& feature : features11) + set.add(makeString("http://www.w3.org/tr/svg11/feature#", feature)); + return set; + }(); + return features; } -// Define custom non-animated property 'requiredExtensions'. -const SVGPropertyInfo* SVGTests::requiredExtensionsPropertyInfo() +SVGTests::SVGTests() + : m_requiredFeatures(requiredFeaturesAttr) + , m_requiredExtensions(requiredExtensionsAttr) + , m_systemLanguage(systemLanguageAttr) { - static const SVGPropertyInfo* s_propertyInfo = 0; - if (!s_propertyInfo) { - s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, - PropertyIsReadWrite, - SVGNames::requiredExtensionsAttr, - SVGNames::requiredExtensionsAttr.localName(), - &SVGElement::synchronizeRequiredExtensions, - 0); - } - return s_propertyInfo; } -// Define custom non-animated property 'systemLanguage'. -const SVGPropertyInfo* SVGTests::systemLanguagePropertyInfo() +static SVGPropertyInfo createSVGTestPropertyInfo(const QualifiedName& attributeName, SVGPropertyInfo::SynchronizeProperty synchronizeFunction) { - static const SVGPropertyInfo* s_propertyInfo = 0; - if (!s_propertyInfo) { - s_propertyInfo = new SVGPropertyInfo(AnimatedUnknown, - PropertyIsReadWrite, - SVGNames::systemLanguageAttr, - SVGNames::systemLanguageAttr.localName(), - &SVGElement::synchronizeSystemLanguage, - 0); - } - return s_propertyInfo; + return { AnimatedUnknown, PropertyIsReadWrite, attributeName, attributeName.localName(), synchronizeFunction, nullptr }; } -SVGTests::SVGTests() - : m_requiredFeatures(SVGNames::requiredFeaturesAttr) - , m_requiredExtensions(SVGNames::requiredExtensionsAttr) - , m_systemLanguage(SVGNames::systemLanguageAttr) +static SVGAttributeToPropertyMap createSVGTextAttributeToPropertyMap() { + typedef NeverDestroyed<const SVGPropertyInfo> Info; + + SVGAttributeToPropertyMap map; + + static Info requiredFeatures = createSVGTestPropertyInfo(requiredFeaturesAttr, SVGElement::synchronizeRequiredFeatures); + map.addProperty(requiredFeatures.get()); + + static Info requiredExtensions = createSVGTestPropertyInfo(requiredExtensionsAttr, SVGElement::synchronizeRequiredExtensions); + map.addProperty(requiredExtensions.get()); + + static Info systemLanguage = createSVGTestPropertyInfo(systemLanguageAttr, SVGElement::synchronizeSystemLanguage); + map.addProperty(systemLanguage.get()); + + return map; } -SVGAttributeToPropertyMap& SVGTests::attributeToPropertyMap() +const SVGAttributeToPropertyMap& SVGTests::attributeToPropertyMap() { - DEFINE_STATIC_LOCAL(SVGAttributeToPropertyMap, map, ()); - if (!map.isEmpty()) - return map; - map.addProperty(requiredFeaturesPropertyInfo()); - map.addProperty(requiredExtensionsPropertyInfo()); - map.addProperty(systemLanguagePropertyInfo()); + static NeverDestroyed<SVGAttributeToPropertyMap> map = createSVGTextAttributeToPropertyMap(); return map; } -bool SVGTests::hasExtension(const String& extension) const +bool SVGTests::hasExtension(const String& extension) { // We recognize XHTML and MathML, as implemented in Gecko and suggested in the SVG Tiny recommendation (http://www.w3.org/TR/SVG11/struct.html#RequiredExtensionsAttribute). #if ENABLE(MATHML) - return extension == HTMLNames::xhtmlNamespaceURI || extension == MathMLNames::mathmlNamespaceURI; -#else - return extension == HTMLNames::xhtmlNamespaceURI; + if (extension == MathMLNames::mathmlNamespaceURI) + return true; #endif + return extension == HTMLNames::xhtmlNamespaceURI; } bool SVGTests::isValid() const { for (auto& feature : m_requiredFeatures.value) { - if (feature.isEmpty() || !DOMImplementation::hasFeature(feature, String())) + if (feature.isEmpty() || !supportedSVGFeatures().contains(feature)) return false; } - for (auto& language : m_systemLanguage.value) { if (language != defaultLanguage().substring(0, 2)) return false; } - for (auto& extension : m_requiredExtensions.value) { if (!hasExtension(extension)) return false; } - return true; } -bool SVGTests::parseAttribute(const QualifiedName& name, const AtomicString& value) +void SVGTests::parseAttribute(const QualifiedName& attributeName, const AtomicString& value) { - if (name == SVGNames::requiredFeaturesAttr) { + if (attributeName == requiredFeaturesAttr) m_requiredFeatures.value.reset(value); - return true; - } - if (name == SVGNames::requiredExtensionsAttr) { + if (attributeName == requiredExtensionsAttr) m_requiredExtensions.value.reset(value); - return true; - } - if (name == SVGNames::systemLanguageAttr) { + if (attributeName == systemLanguageAttr) m_systemLanguage.value.reset(value); - return true; - } - - return false; } -bool SVGTests::isKnownAttribute(const QualifiedName& attrName) +bool SVGTests::isKnownAttribute(const QualifiedName& attributeName) { - return attrName == SVGNames::requiredFeaturesAttr - || attrName == SVGNames::requiredExtensionsAttr - || attrName == SVGNames::systemLanguageAttr; + return attributeName == requiredFeaturesAttr + || attributeName == requiredExtensionsAttr + || attributeName == systemLanguageAttr; } -bool SVGTests::handleAttributeChange(SVGElement* targetElement, const QualifiedName& attrName) +bool SVGTests::handleAttributeChange(SVGElement* targetElement, const QualifiedName& attributeName) { ASSERT(targetElement); - if (!isKnownAttribute(attrName)) + if (!isKnownAttribute(attributeName)) return false; - if (!targetElement->inDocument()) + if (!targetElement->isConnected()) return true; - - targetElement->setNeedsStyleRecalc(ReconstructRenderTree); - + targetElement->invalidateStyleAndRenderersForSubtree(); return true; } void SVGTests::addSupportedAttributes(HashSet<QualifiedName>& supportedAttributes) { - supportedAttributes.add(SVGNames::requiredFeaturesAttr); - supportedAttributes.add(SVGNames::requiredExtensionsAttr); - supportedAttributes.add(SVGNames::systemLanguageAttr); + supportedAttributes.add(requiredFeaturesAttr); + supportedAttributes.add(requiredExtensionsAttr); + supportedAttributes.add(systemLanguageAttr); } -void SVGTests::synchronizeRequiredFeatures(SVGElement* contextElement) +void SVGTests::synchronizeAttribute(SVGElement& contextElement, SVGSynchronizableAnimatedProperty<SVGStringListValues>& property, const QualifiedName& attributeName) { - ASSERT(contextElement); - if (!m_requiredFeatures.shouldSynchronize) + if (!property.shouldSynchronize) return; - AtomicString value(m_requiredFeatures.value.valueAsString()); - m_requiredFeatures.synchronize(contextElement, requiredFeaturesPropertyInfo()->attributeName, value); + m_requiredFeatures.synchronize(&contextElement, attributeName, property.value.valueAsString()); } -void SVGTests::synchronizeRequiredExtensions(SVGElement* contextElement) +void SVGTests::synchronizeRequiredFeatures(SVGElement& contextElement) { - ASSERT(contextElement); - if (!m_requiredExtensions.shouldSynchronize) - return; - AtomicString value(m_requiredExtensions.value.valueAsString()); - m_requiredExtensions.synchronize(contextElement, requiredExtensionsPropertyInfo()->attributeName, value); + synchronizeAttribute(contextElement, m_requiredFeatures, requiredFeaturesAttr); } -void SVGTests::synchronizeSystemLanguage(SVGElement* contextElement) +void SVGTests::synchronizeRequiredExtensions(SVGElement& contextElement) { - ASSERT(contextElement); - if (!m_systemLanguage.shouldSynchronize) - return; - AtomicString value(m_systemLanguage.value.valueAsString()); - m_systemLanguage.synchronize(contextElement, systemLanguagePropertyInfo()->attributeName, value); + synchronizeAttribute(contextElement, m_requiredExtensions, requiredExtensionsAttr); } -SVGStringList& SVGTests::requiredFeatures() +void SVGTests::synchronizeSystemLanguage(SVGElement& contextElement) +{ + synchronizeAttribute(contextElement, m_systemLanguage, systemLanguageAttr); +} + +Ref<SVGStringList> SVGTests::requiredFeatures(SVGElement& contextElement) { m_requiredFeatures.shouldSynchronize = true; - return m_requiredFeatures.value; + return SVGStringList::create(contextElement, m_requiredFeatures.value); } -SVGStringList& SVGTests::requiredExtensions() +Ref<SVGStringList> SVGTests::requiredExtensions(SVGElement& contextElement) { m_requiredExtensions.shouldSynchronize = true; - return m_requiredExtensions.value; + return SVGStringList::create(contextElement, m_requiredExtensions.value); } -SVGStringList& SVGTests::systemLanguage() +Ref<SVGStringList> SVGTests::systemLanguage(SVGElement& contextElement) { m_systemLanguage.shouldSynchronize = true; - return m_systemLanguage.value; + return SVGStringList::create(contextElement, m_systemLanguage.value); } +bool SVGTests::hasFeatureForLegacyBindings(const String& feature, const String& version) +{ + // FIXME: This function is here only to be exposed in the Objective-C and GObject bindings for both Node and DOMImplementation. + // It's likely that we can just remove this and instead have the bindings return true unconditionally. + // This is what the DOMImplementation function now does in JavaScript as is now suggested in the DOM specification. + // The behavior implemented below is quirky, but preserves what WebKit has done for at least the last few years. + + bool hasSVG10FeaturePrefix = feature.startsWith("org.w3c.dom.svg", false) || feature.startsWith("org.w3c.svg", false); + bool hasSVG11FeaturePrefix = feature.startsWith("http://www.w3.org/tr/svg", false); + + // We don't even try to handle feature names that don't look like the SVG ones, so just return true for all of those. + if (!(hasSVG10FeaturePrefix || hasSVG11FeaturePrefix)) + return true; + + // If the version number matches the style of the feature name, then use the set to see if the feature is supported. + if (version.isEmpty() || (hasSVG10FeaturePrefix && version == "1.0") || (hasSVG11FeaturePrefix && version == "1.1")) + return supportedSVGFeatures().contains(feature); + + return false; } -#endif // ENABLE(SVG) +} |