Bug 1805294 [wpt PR 37463] - WebKit export of https://bugs.webkit.org/show_bug.cgi...
[gecko.git] / dom / svg / SVGTests.cpp
blobdd9f6e540c849c220bd6f2fbb05777bc3ee6f7d1
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "mozilla/dom/SVGTests.h"
8 #include "DOMSVGStringList.h"
9 #include "nsIContent.h"
10 #include "nsIContentInlines.h"
11 #include "mozilla/dom/SVGSwitchElement.h"
12 #include "nsCharSeparatedTokenizer.h"
13 #include "nsStyleUtil.h"
14 #include "mozilla/Preferences.h"
16 namespace mozilla::dom {
18 nsStaticAtom* const SVGTests::sStringListNames[2] = {
19 nsGkAtoms::requiredExtensions,
20 nsGkAtoms::systemLanguage,
23 SVGTests::SVGTests() {
24 mStringListAttributes[LANGUAGE].SetIsCommaSeparated(true);
27 already_AddRefed<DOMSVGStringList> SVGTests::RequiredExtensions() {
28 return DOMSVGStringList::GetDOMWrapper(&mStringListAttributes[EXTENSIONS],
29 AsSVGElement(), true, EXTENSIONS);
32 already_AddRefed<DOMSVGStringList> SVGTests::SystemLanguage() {
33 return DOMSVGStringList::GetDOMWrapper(&mStringListAttributes[LANGUAGE],
34 AsSVGElement(), true, LANGUAGE);
37 bool SVGTests::HasExtension(const nsAString& aExtension) const {
38 #define SVG_SUPPORTED_EXTENSION(str) \
39 if (aExtension.EqualsLiteral(str)) return true;
40 SVG_SUPPORTED_EXTENSION("http://www.w3.org/1999/xhtml")
41 nsNameSpaceManager* nameSpaceManager = nsNameSpaceManager::GetInstance();
42 if (AsSVGElement()->IsInChromeDocument() ||
43 !nameSpaceManager->mMathMLDisabled) {
44 SVG_SUPPORTED_EXTENSION("http://www.w3.org/1998/Math/MathML")
46 #undef SVG_SUPPORTED_EXTENSION
48 return false;
51 bool SVGTests::IsConditionalProcessingAttribute(
52 const nsAtom* aAttribute) const {
53 for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
54 if (aAttribute == sStringListNames[i]) {
55 return true;
58 return false;
61 int32_t SVGTests::GetBestLanguagePreferenceRank(
62 const nsAString& aAcceptLangs) const {
63 if (!mStringListAttributes[LANGUAGE].IsExplicitlySet()) {
64 return -2;
67 int32_t lowestRank = -1;
69 for (uint32_t i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
70 int32_t index = 0;
71 for (const nsAString& languageToken :
72 nsCharSeparatedTokenizer(aAcceptLangs, ',').ToRange()) {
73 bool exactMatch = languageToken.Equals(mStringListAttributes[LANGUAGE][i],
74 nsCaseInsensitiveStringComparator);
75 bool prefixOnlyMatch =
76 !exactMatch && nsStyleUtil::DashMatchCompare(
77 mStringListAttributes[LANGUAGE][i], languageToken,
78 nsCaseInsensitiveStringComparator);
79 if (index == 0 && exactMatch) {
80 // best possible match
81 return 0;
83 if ((exactMatch || prefixOnlyMatch) &&
84 (lowestRank == -1 || 2 * index + prefixOnlyMatch < lowestRank)) {
85 lowestRank = 2 * index + prefixOnlyMatch;
87 ++index;
90 return lowestRank;
93 bool SVGTests::PassesConditionalProcessingTestsIgnoringSystemLanguage() const {
94 // Required Extensions
96 // The requiredExtensions attribute defines a list of required language
97 // extensions. Language extensions are capabilities within a user agent that
98 // go beyond the feature set defined in the SVG specification.
99 // Each extension is identified by a URI reference.
100 // For now, claim that mozilla's SVG implementation supports XHTML and MathML.
101 if (mStringListAttributes[EXTENSIONS].IsExplicitlySet()) {
102 if (mStringListAttributes[EXTENSIONS].IsEmpty()) {
103 return false;
105 for (uint32_t i = 0; i < mStringListAttributes[EXTENSIONS].Length(); i++) {
106 if (!HasExtension(mStringListAttributes[EXTENSIONS][i])) {
107 return false;
111 return true;
114 bool SVGTests::PassesConditionalProcessingTests() const {
115 if (!PassesConditionalProcessingTestsIgnoringSystemLanguage()) {
116 return false;
119 // systemLanguage
121 // Evaluates to "true" if one of the languages indicated by user preferences
122 // exactly equals one of the languages given in the value of this parameter,
123 // or if one of the languages indicated by user preferences exactly equals a
124 // prefix of one of the languages given in the value of this parameter such
125 // that the first tag character following the prefix is "-".
126 if (mStringListAttributes[LANGUAGE].IsExplicitlySet()) {
127 if (mStringListAttributes[LANGUAGE].IsEmpty()) {
128 return false;
131 // Get our language preferences
132 nsAutoString acceptLangs;
133 Preferences::GetLocalizedString("intl.accept_languages", acceptLangs);
135 if (acceptLangs.IsEmpty()) {
136 NS_WARNING(
137 "no default language specified for systemLanguage conditional test");
138 return false;
141 for (uint32_t i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) {
142 nsCharSeparatedTokenizer languageTokenizer(acceptLangs, ',');
143 while (languageTokenizer.hasMoreTokens()) {
144 if (nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i],
145 languageTokenizer.nextToken(),
146 nsCaseInsensitiveStringComparator)) {
147 return true;
151 return false;
154 return true;
157 bool SVGTests::ParseConditionalProcessingAttribute(nsAtom* aAttribute,
158 const nsAString& aValue,
159 nsAttrValue& aResult) {
160 for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
161 if (aAttribute == sStringListNames[i]) {
162 nsresult rv = mStringListAttributes[i].SetValue(aValue);
163 if (NS_FAILED(rv)) {
164 mStringListAttributes[i].Clear();
166 MaybeInvalidate();
167 return true;
170 return false;
173 void SVGTests::UnsetAttr(const nsAtom* aAttribute) {
174 for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) {
175 if (aAttribute == sStringListNames[i]) {
176 mStringListAttributes[i].Clear();
177 MaybeInvalidate();
178 return;
183 nsStaticAtom* SVGTests::GetAttrName(uint8_t aAttrEnum) const {
184 return sStringListNames[aAttrEnum];
187 void SVGTests::GetAttrValue(uint8_t aAttrEnum, nsAttrValue& aValue) const {
188 MOZ_ASSERT(aAttrEnum < ArrayLength(sStringListNames),
189 "aAttrEnum out of range");
190 aValue.SetTo(mStringListAttributes[aAttrEnum], nullptr);
193 void SVGTests::MaybeInvalidate() {
194 nsIContent* parent = AsSVGElement()->GetFlattenedTreeParent();
196 if (parent &&
197 parent->NodeInfo()->Equals(nsGkAtoms::svgSwitch, kNameSpaceID_SVG)) {
198 static_cast<dom::SVGSwitchElement*>(parent)->MaybeInvalidate();
202 } // namespace mozilla::dom