/src/mozilla-central/dom/svg/SVGTests.cpp
Line | Count | Source (jump to first uncovered line) |
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/. */ |
6 | | |
7 | | #include "mozilla/dom/SVGTests.h" |
8 | | #include "DOMSVGStringList.h" |
9 | | #include "nsSVGFeatures.h" |
10 | | #include "mozilla/dom/SVGSwitchElement.h" |
11 | | #include "nsCharSeparatedTokenizer.h" |
12 | | #include "nsStyleUtil.h" |
13 | | #include "mozilla/Preferences.h" |
14 | | |
15 | | namespace mozilla { |
16 | | namespace dom { |
17 | | |
18 | | nsStaticAtom** SVGTests::sStringListNames[3] = |
19 | | { |
20 | | &nsGkAtoms::requiredFeatures, |
21 | | &nsGkAtoms::requiredExtensions, |
22 | | &nsGkAtoms::systemLanguage, |
23 | | }; |
24 | | |
25 | | SVGTests::SVGTests() |
26 | 0 | { |
27 | 0 | mStringListAttributes[LANGUAGE].SetIsCommaSeparated(true); |
28 | 0 | } |
29 | | |
30 | | already_AddRefed<DOMSVGStringList> |
31 | | SVGTests::RequiredFeatures() |
32 | 0 | { |
33 | 0 | return DOMSVGStringList::GetDOMWrapper( |
34 | 0 | &mStringListAttributes[FEATURES], AsSVGElement(), true, FEATURES); |
35 | 0 | } |
36 | | |
37 | | already_AddRefed<DOMSVGStringList> |
38 | | SVGTests::RequiredExtensions() |
39 | 0 | { |
40 | 0 | return DOMSVGStringList::GetDOMWrapper( |
41 | 0 | &mStringListAttributes[EXTENSIONS], AsSVGElement(), true, EXTENSIONS); |
42 | 0 | } |
43 | | |
44 | | already_AddRefed<DOMSVGStringList> |
45 | | SVGTests::SystemLanguage() |
46 | 0 | { |
47 | 0 | return DOMSVGStringList::GetDOMWrapper( |
48 | 0 | &mStringListAttributes[LANGUAGE], AsSVGElement(), true, LANGUAGE); |
49 | 0 | } |
50 | | |
51 | | bool |
52 | | SVGTests::HasExtension(const nsAString& aExtension) |
53 | 0 | { |
54 | 0 | return nsSVGFeatures::HasExtension(aExtension, |
55 | 0 | AsSVGElement()->IsInChromeDocument()); |
56 | 0 | } |
57 | | |
58 | | bool |
59 | | SVGTests::IsConditionalProcessingAttribute(const nsAtom* aAttribute) const |
60 | 0 | { |
61 | 0 | for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) { |
62 | 0 | if (aAttribute == *sStringListNames[i]) { |
63 | 0 | return true; |
64 | 0 | } |
65 | 0 | } |
66 | 0 | return false; |
67 | 0 | } |
68 | | |
69 | | int32_t |
70 | | SVGTests::GetBestLanguagePreferenceRank(const nsAString& aAcceptLangs) const |
71 | 0 | { |
72 | 0 | const nsCaseInsensitiveStringComparator caseInsensitiveComparator; |
73 | 0 |
|
74 | 0 | if (!mStringListAttributes[LANGUAGE].IsExplicitlySet()) { |
75 | 0 | return -2; |
76 | 0 | } |
77 | 0 | |
78 | 0 | int32_t lowestRank = -1; |
79 | 0 |
|
80 | 0 | for (uint32_t i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) { |
81 | 0 | nsCharSeparatedTokenizer languageTokenizer(aAcceptLangs, ','); |
82 | 0 | int32_t index = 0; |
83 | 0 | while (languageTokenizer.hasMoreTokens()) { |
84 | 0 | const nsAString& languageToken = languageTokenizer.nextToken(); |
85 | 0 | bool exactMatch = languageToken.Equals(mStringListAttributes[LANGUAGE][i], |
86 | 0 | caseInsensitiveComparator); |
87 | 0 | bool prefixOnlyMatch = |
88 | 0 | !exactMatch && |
89 | 0 | nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i], |
90 | 0 | languageTokenizer.nextToken(), |
91 | 0 | caseInsensitiveComparator); |
92 | 0 | if (index == 0 && exactMatch) { |
93 | 0 | // best possible match |
94 | 0 | return 0; |
95 | 0 | } |
96 | 0 | if ((exactMatch || prefixOnlyMatch) && |
97 | 0 | (lowestRank == -1 || 2 * index + prefixOnlyMatch < lowestRank)) { |
98 | 0 | lowestRank = 2 * index + prefixOnlyMatch; |
99 | 0 | } |
100 | 0 | ++index; |
101 | 0 | } |
102 | 0 | } |
103 | 0 | return lowestRank; |
104 | 0 | } |
105 | | |
106 | | const nsString * const SVGTests::kIgnoreSystemLanguage = (nsString *) 0x01; |
107 | | |
108 | | bool |
109 | | SVGTests::PassesConditionalProcessingTests(const nsString *aAcceptLangs) const |
110 | 0 | { |
111 | 0 | // Required Extensions |
112 | 0 | // |
113 | 0 | // The requiredExtensions attribute defines a list of required language |
114 | 0 | // extensions. Language extensions are capabilities within a user agent that |
115 | 0 | // go beyond the feature set defined in the SVG specification. |
116 | 0 | // Each extension is identified by a URI reference. |
117 | 0 | // For now, claim that mozilla's SVG implementation supports XHTML and MathML. |
118 | 0 | if (mStringListAttributes[EXTENSIONS].IsExplicitlySet()) { |
119 | 0 | if (mStringListAttributes[EXTENSIONS].IsEmpty()) { |
120 | 0 | return false; |
121 | 0 | } |
122 | 0 | for (uint32_t i = 0; i < mStringListAttributes[EXTENSIONS].Length(); i++) { |
123 | 0 | if (!nsSVGFeatures::HasExtension(mStringListAttributes[EXTENSIONS][i], |
124 | 0 | AsSVGElement()->IsInChromeDocument())) { |
125 | 0 | return false; |
126 | 0 | } |
127 | 0 | } |
128 | 0 | } |
129 | 0 |
|
130 | 0 | if (aAcceptLangs == kIgnoreSystemLanguage) { |
131 | 0 | return true; |
132 | 0 | } |
133 | 0 | |
134 | 0 | // systemLanguage |
135 | 0 | // |
136 | 0 | // Evaluates to "true" if one of the languages indicated by user preferences |
137 | 0 | // exactly equals one of the languages given in the value of this parameter, |
138 | 0 | // or if one of the languages indicated by user preferences exactly equals a |
139 | 0 | // prefix of one of the languages given in the value of this parameter such |
140 | 0 | // that the first tag character following the prefix is "-". |
141 | 0 | if (mStringListAttributes[LANGUAGE].IsExplicitlySet()) { |
142 | 0 | if (mStringListAttributes[LANGUAGE].IsEmpty()) { |
143 | 0 | return false; |
144 | 0 | } |
145 | 0 | |
146 | 0 | // Get our language preferences |
147 | 0 | nsAutoString acceptLangs; |
148 | 0 | if (aAcceptLangs) { |
149 | 0 | acceptLangs.Assign(*aAcceptLangs); |
150 | 0 | } else { |
151 | 0 | Preferences::GetLocalizedString("intl.accept_languages", acceptLangs); |
152 | 0 | } |
153 | 0 |
|
154 | 0 | if (acceptLangs.IsEmpty()) { |
155 | 0 | NS_WARNING("no default language specified for systemLanguage conditional test"); |
156 | 0 | return false; |
157 | 0 | } |
158 | 0 |
|
159 | 0 | const nsCaseInsensitiveStringComparator caseInsensitiveComparator; |
160 | 0 |
|
161 | 0 | for (uint32_t i = 0; i < mStringListAttributes[LANGUAGE].Length(); i++) { |
162 | 0 | nsCharSeparatedTokenizer languageTokenizer(acceptLangs, ','); |
163 | 0 | while (languageTokenizer.hasMoreTokens()) { |
164 | 0 | if (nsStyleUtil::DashMatchCompare(mStringListAttributes[LANGUAGE][i], |
165 | 0 | languageTokenizer.nextToken(), |
166 | 0 | caseInsensitiveComparator)) { |
167 | 0 | return true; |
168 | 0 | } |
169 | 0 | } |
170 | 0 | } |
171 | 0 | return false; |
172 | 0 | } |
173 | 0 | |
174 | 0 | return true; |
175 | 0 | } |
176 | | |
177 | | bool |
178 | | SVGTests::ParseConditionalProcessingAttribute(nsAtom* aAttribute, |
179 | | const nsAString& aValue, |
180 | | nsAttrValue& aResult) |
181 | 0 | { |
182 | 0 | for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) { |
183 | 0 | if (aAttribute == *sStringListNames[i]) { |
184 | 0 | nsresult rv = mStringListAttributes[i].SetValue(aValue); |
185 | 0 | if (NS_FAILED(rv)) { |
186 | 0 | mStringListAttributes[i].Clear(); |
187 | 0 | } |
188 | 0 | MaybeInvalidate(); |
189 | 0 | return true; |
190 | 0 | } |
191 | 0 | } |
192 | 0 | return false; |
193 | 0 | } |
194 | | |
195 | | void |
196 | | SVGTests::UnsetAttr(const nsAtom* aAttribute) |
197 | 0 | { |
198 | 0 | for (uint32_t i = 0; i < ArrayLength(sStringListNames); i++) { |
199 | 0 | if (aAttribute == *sStringListNames[i]) { |
200 | 0 | mStringListAttributes[i].Clear(); |
201 | 0 | MaybeInvalidate(); |
202 | 0 | return; |
203 | 0 | } |
204 | 0 | } |
205 | 0 | } |
206 | | |
207 | | nsAtom* |
208 | | SVGTests::GetAttrName(uint8_t aAttrEnum) const |
209 | 0 | { |
210 | 0 | return *sStringListNames[aAttrEnum]; |
211 | 0 | } |
212 | | |
213 | | void |
214 | | SVGTests::GetAttrValue(uint8_t aAttrEnum, nsAttrValue& aValue) const |
215 | 0 | { |
216 | 0 | MOZ_ASSERT(aAttrEnum < ArrayLength(sStringListNames), |
217 | 0 | "aAttrEnum out of range"); |
218 | 0 | aValue.SetTo(mStringListAttributes[aAttrEnum], nullptr); |
219 | 0 | } |
220 | | |
221 | | void |
222 | | SVGTests::MaybeInvalidate() |
223 | 0 | { |
224 | 0 | nsIContent* parent = AsSVGElement()->GetFlattenedTreeParent(); |
225 | 0 |
|
226 | 0 | if (parent && |
227 | 0 | parent->NodeInfo()->Equals(nsGkAtoms::svgSwitch, kNameSpaceID_SVG)) { |
228 | 0 | static_cast<dom::SVGSwitchElement*>(parent)->MaybeInvalidate(); |
229 | 0 | } |
230 | 0 | } |
231 | | |
232 | | } // namespace dom |
233 | | } // namespace mozilla |