summaryrefslogtreecommitdiff
path: root/Source/WebCore/svg/SVGTests.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/svg/SVGTests.cpp')
-rw-r--r--Source/WebCore/svg/SVGTests.cpp259
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)
+}