Line data Source code
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/Element.h"
8 : #include "mozilla/dom/SVGStyleElement.h"
9 : #include "nsContentUtils.h"
10 : #include "mozilla/dom/SVGStyleElementBinding.h"
11 :
12 10 : NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(Style)
13 :
14 : namespace mozilla {
15 : namespace dom {
16 :
17 : JSObject*
18 0 : SVGStyleElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
19 : {
20 0 : return SVGStyleElementBinding::Wrap(aCx, this, aGivenProto);
21 : }
22 :
23 : //----------------------------------------------------------------------
24 : // nsISupports methods
25 :
26 220 : NS_IMPL_ADDREF_INHERITED(SVGStyleElement, SVGStyleElementBase)
27 205 : NS_IMPL_RELEASE_INHERITED(SVGStyleElement, SVGStyleElementBase)
28 :
29 140 : NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(SVGStyleElement)
30 135 : NS_INTERFACE_TABLE_INHERITED(SVGStyleElement,
31 : nsIStyleSheetLinkingElement,
32 : nsIMutationObserver)
33 135 : NS_INTERFACE_TABLE_TAIL_INHERITING(SVGStyleElementBase)
34 :
35 : NS_IMPL_CYCLE_COLLECTION_CLASS(SVGStyleElement)
36 :
37 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(SVGStyleElement,
38 : SVGStyleElementBase)
39 0 : tmp->nsStyleLinkElement::Traverse(cb);
40 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
41 :
42 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(SVGStyleElement,
43 : SVGStyleElementBase)
44 0 : tmp->nsStyleLinkElement::Unlink();
45 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
46 :
47 : //----------------------------------------------------------------------
48 : // Implementation
49 :
50 5 : SVGStyleElement::SVGStyleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
51 5 : : SVGStyleElementBase(aNodeInfo)
52 : {
53 5 : AddMutationObserver(this);
54 5 : }
55 :
56 0 : SVGStyleElement::~SVGStyleElement()
57 : {
58 0 : }
59 :
60 : //----------------------------------------------------------------------
61 : // nsIDOMNode methods
62 :
63 :
64 0 : NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGStyleElement)
65 :
66 :
67 : //----------------------------------------------------------------------
68 : // nsIContent methods
69 :
70 : nsresult
71 5 : SVGStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
72 : nsIContent* aBindingParent,
73 : bool aCompileEventHandlers)
74 : {
75 5 : nsresult rv = SVGStyleElementBase::BindToTree(aDocument, aParent,
76 : aBindingParent,
77 5 : aCompileEventHandlers);
78 5 : NS_ENSURE_SUCCESS(rv, rv);
79 :
80 5 : void (SVGStyleElement::*update)() = &SVGStyleElement::UpdateStyleSheetInternal;
81 10 : nsContentUtils::AddScriptRunner(
82 15 : NewRunnableMethod("dom::SVGStyleElement::BindToTree", this, update));
83 :
84 5 : return rv;
85 : }
86 :
87 : void
88 0 : SVGStyleElement::UnbindFromTree(bool aDeep, bool aNullParent)
89 : {
90 0 : nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
91 0 : ShadowRoot* oldShadow = GetContainingShadow();
92 0 : SVGStyleElementBase::UnbindFromTree(aDeep, aNullParent);
93 0 : UpdateStyleSheetInternal(oldDoc, oldShadow);
94 0 : }
95 :
96 : nsresult
97 0 : SVGStyleElement::SetAttr(int32_t aNameSpaceID, nsIAtom* aName,
98 : nsIAtom* aPrefix, const nsAString& aValue,
99 : bool aNotify)
100 : {
101 0 : nsresult rv = SVGStyleElementBase::SetAttr(aNameSpaceID, aName, aPrefix,
102 0 : aValue, aNotify);
103 0 : if (NS_SUCCEEDED(rv) && aNameSpaceID == kNameSpaceID_None) {
104 0 : if (aName == nsGkAtoms::title ||
105 0 : aName == nsGkAtoms::media ||
106 0 : aName == nsGkAtoms::type) {
107 0 : UpdateStyleSheetInternal(nullptr, nullptr, true);
108 0 : } else if (aName == nsGkAtoms::scoped &&
109 0 : OwnerDoc()->IsScopedStyleEnabled()) {
110 0 : UpdateStyleSheetScopedness(true);
111 : }
112 : }
113 :
114 0 : return rv;
115 : }
116 :
117 : nsresult
118 0 : SVGStyleElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
119 : bool aNotify)
120 : {
121 0 : nsresult rv = SVGStyleElementBase::UnsetAttr(aNameSpaceID, aAttribute,
122 0 : aNotify);
123 0 : if (NS_SUCCEEDED(rv) && aNameSpaceID == kNameSpaceID_None) {
124 0 : if (aAttribute == nsGkAtoms::title ||
125 0 : aAttribute == nsGkAtoms::media ||
126 0 : aAttribute == nsGkAtoms::type) {
127 0 : UpdateStyleSheetInternal(nullptr, nullptr, true);
128 0 : } else if (aAttribute == nsGkAtoms::scoped &&
129 0 : OwnerDoc()->IsScopedStyleEnabled()) {
130 0 : UpdateStyleSheetScopedness(false);
131 : }
132 : }
133 :
134 0 : return rv;
135 : }
136 :
137 : bool
138 0 : SVGStyleElement::ParseAttribute(int32_t aNamespaceID,
139 : nsIAtom* aAttribute,
140 : const nsAString& aValue,
141 : nsAttrValue& aResult)
142 : {
143 0 : if (aNamespaceID == kNameSpaceID_None &&
144 0 : aAttribute == nsGkAtoms::crossorigin) {
145 0 : ParseCORSValue(aValue, aResult);
146 0 : return true;
147 : }
148 :
149 0 : return SVGStyleElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
150 0 : aResult);
151 : }
152 :
153 : //----------------------------------------------------------------------
154 : // nsIMutationObserver methods
155 :
156 : void
157 0 : SVGStyleElement::CharacterDataChanged(nsIDocument* aDocument,
158 : nsIContent* aContent,
159 : CharacterDataChangeInfo* aInfo)
160 : {
161 0 : ContentChanged(aContent);
162 0 : }
163 :
164 : void
165 0 : SVGStyleElement::ContentAppended(nsIDocument* aDocument,
166 : nsIContent* aContainer,
167 : nsIContent* aFirstNewContent,
168 : int32_t aNewIndexInContainer)
169 : {
170 0 : ContentChanged(aContainer);
171 0 : }
172 :
173 : void
174 0 : SVGStyleElement::ContentInserted(nsIDocument* aDocument,
175 : nsIContent* aContainer,
176 : nsIContent* aChild,
177 : int32_t aIndexInContainer)
178 : {
179 0 : ContentChanged(aChild);
180 0 : }
181 :
182 : void
183 0 : SVGStyleElement::ContentRemoved(nsIDocument* aDocument,
184 : nsIContent* aContainer,
185 : nsIContent* aChild,
186 : int32_t aIndexInContainer,
187 : nsIContent* aPreviousSibling)
188 : {
189 0 : ContentChanged(aChild);
190 0 : }
191 :
192 : void
193 0 : SVGStyleElement::ContentChanged(nsIContent* aContent)
194 : {
195 0 : if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
196 0 : UpdateStyleSheetInternal(nullptr, nullptr);
197 : }
198 0 : }
199 :
200 : //----------------------------------------------------------------------
201 :
202 : void
203 0 : SVGStyleElement::GetXmlspace(nsAString & aXmlspace)
204 : {
205 0 : GetAttr(kNameSpaceID_XML, nsGkAtoms::space, aXmlspace);
206 0 : }
207 :
208 : void
209 0 : SVGStyleElement::SetXmlspace(const nsAString & aXmlspace, ErrorResult& rv)
210 : {
211 0 : rv = SetAttr(kNameSpaceID_XML, nsGkAtoms::space, aXmlspace, true);
212 0 : }
213 :
214 : void
215 0 : SVGStyleElement::GetMedia(nsAString & aMedia)
216 : {
217 0 : GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
218 0 : }
219 :
220 : void
221 0 : SVGStyleElement::SetMedia(const nsAString& aMedia, ErrorResult& rv)
222 : {
223 0 : rv = SetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia, true);
224 0 : }
225 :
226 : bool
227 0 : SVGStyleElement::Scoped() const
228 : {
229 0 : return GetBoolAttr(nsGkAtoms::scoped);
230 : }
231 :
232 : void
233 0 : SVGStyleElement::SetScoped(bool aScoped, ErrorResult& rv)
234 : {
235 0 : rv = SetBoolAttr(nsGkAtoms::scoped, aScoped);
236 0 : }
237 :
238 : void
239 0 : SVGStyleElement::GetType(nsAString & aType)
240 : {
241 0 : GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
242 0 : }
243 :
244 : void
245 0 : SVGStyleElement::SetType(const nsAString& aType, ErrorResult& rv)
246 : {
247 0 : rv = SetAttr(kNameSpaceID_None, nsGkAtoms::type, aType, true);
248 0 : }
249 :
250 : void
251 0 : SVGStyleElement::GetTitle(nsAString & aTitle)
252 : {
253 0 : GetAttr(kNameSpaceID_None, nsGkAtoms::title, aTitle);
254 0 : }
255 :
256 : void
257 0 : SVGStyleElement::SetTitle(const nsAString& aTitle, ErrorResult& rv)
258 : {
259 0 : rv = SetAttr(kNameSpaceID_None, nsGkAtoms::title, aTitle, true);
260 0 : }
261 :
262 : //----------------------------------------------------------------------
263 : // nsStyleLinkElement methods
264 :
265 : already_AddRefed<nsIURI>
266 5 : SVGStyleElement::GetStyleSheetURL(bool* aIsInline)
267 : {
268 5 : *aIsInline = true;
269 5 : return nullptr;
270 : }
271 :
272 : void
273 5 : SVGStyleElement::GetStyleSheetInfo(nsAString& aTitle,
274 : nsAString& aType,
275 : nsAString& aMedia,
276 : bool* aIsScoped,
277 : bool* aIsAlternate)
278 : {
279 5 : *aIsAlternate = false;
280 :
281 10 : nsAutoString title;
282 5 : GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
283 5 : title.CompressWhitespace();
284 5 : aTitle.Assign(title);
285 :
286 5 : GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
287 : // The SVG spec is formulated in terms of the CSS2 spec,
288 : // which specifies that media queries are case insensitive.
289 5 : nsContentUtils::ASCIIToLower(aMedia);
290 :
291 5 : GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
292 5 : if (aType.IsEmpty()) {
293 5 : aType.AssignLiteral("text/css");
294 : }
295 :
296 5 : *aIsScoped = HasAttr(kNameSpaceID_None, nsGkAtoms::scoped) &&
297 0 : OwnerDoc()->IsScopedStyleEnabled();
298 :
299 10 : return;
300 : }
301 :
302 : CORSMode
303 0 : SVGStyleElement::GetCORSMode() const
304 : {
305 0 : return AttrValueToCORSMode(GetParsedAttr(nsGkAtoms::crossorigin));
306 : }
307 :
308 : } // namespace dom
309 : } // namespace mozilla
310 :
|