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 : #include "mozilla/dom/HTMLStyleElement.h"
7 : #include "mozilla/dom/HTMLStyleElementBinding.h"
8 : #include "nsGkAtoms.h"
9 : #include "nsStyleConsts.h"
10 : #include "nsIDOMStyleSheet.h"
11 : #include "nsIDocument.h"
12 : #include "nsUnicharUtils.h"
13 : #include "nsThreadUtils.h"
14 : #include "nsContentUtils.h"
15 : #include "nsStubMutationObserver.h"
16 :
17 0 : NS_IMPL_NS_NEW_HTML_ELEMENT(Style)
18 :
19 : namespace mozilla {
20 : namespace dom {
21 :
22 0 : HTMLStyleElement::HTMLStyleElement(already_AddRefed<mozilla::dom::NodeInfo>& aNodeInfo)
23 0 : : nsGenericHTMLElement(aNodeInfo)
24 : {
25 0 : AddMutationObserver(this);
26 0 : }
27 :
28 0 : HTMLStyleElement::~HTMLStyleElement()
29 : {
30 0 : }
31 :
32 : NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLStyleElement)
33 :
34 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLStyleElement,
35 : nsGenericHTMLElement)
36 0 : tmp->nsStyleLinkElement::Traverse(cb);
37 0 : NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
38 :
39 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLStyleElement,
40 : nsGenericHTMLElement)
41 0 : tmp->nsStyleLinkElement::Unlink();
42 0 : NS_IMPL_CYCLE_COLLECTION_UNLINK_END
43 :
44 0 : NS_IMPL_ADDREF_INHERITED(HTMLStyleElement, Element)
45 0 : NS_IMPL_RELEASE_INHERITED(HTMLStyleElement, Element)
46 :
47 :
48 : // QueryInterface implementation for HTMLStyleElement
49 0 : NS_INTERFACE_TABLE_HEAD_CYCLE_COLLECTION_INHERITED(HTMLStyleElement)
50 0 : NS_INTERFACE_TABLE_INHERITED(HTMLStyleElement,
51 : nsIDOMHTMLStyleElement,
52 : nsIStyleSheetLinkingElement,
53 : nsIMutationObserver)
54 0 : NS_INTERFACE_TABLE_TAIL_INHERITING(nsGenericHTMLElement)
55 :
56 0 : NS_IMPL_ELEMENT_CLONE(HTMLStyleElement)
57 :
58 :
59 : NS_IMETHODIMP
60 0 : HTMLStyleElement::GetMozDisabled(bool* aDisabled)
61 : {
62 0 : NS_ENSURE_ARG_POINTER(aDisabled);
63 :
64 0 : *aDisabled = Disabled();
65 0 : return NS_OK;
66 : }
67 :
68 : bool
69 0 : HTMLStyleElement::Disabled()
70 : {
71 0 : StyleSheet* ss = GetSheet();
72 0 : return ss && ss->Disabled();
73 : }
74 :
75 : NS_IMETHODIMP
76 0 : HTMLStyleElement::SetMozDisabled(bool aDisabled)
77 : {
78 0 : SetDisabled(aDisabled);
79 0 : return NS_OK;
80 : }
81 :
82 : void
83 0 : HTMLStyleElement::SetDisabled(bool aDisabled)
84 : {
85 0 : if (StyleSheet* ss = GetSheet()) {
86 0 : ss->SetDisabled(aDisabled);
87 : }
88 0 : }
89 :
90 0 : NS_IMPL_STRING_ATTR(HTMLStyleElement, Media, media)
91 0 : NS_IMPL_BOOL_ATTR(HTMLStyleElement, Scoped, scoped)
92 0 : NS_IMPL_STRING_ATTR(HTMLStyleElement, Type, type)
93 :
94 : void
95 0 : HTMLStyleElement::CharacterDataChanged(nsIDocument* aDocument,
96 : nsIContent* aContent,
97 : CharacterDataChangeInfo* aInfo)
98 : {
99 0 : ContentChanged(aContent);
100 0 : }
101 :
102 : void
103 0 : HTMLStyleElement::ContentAppended(nsIDocument* aDocument,
104 : nsIContent* aContainer,
105 : nsIContent* aFirstNewContent,
106 : int32_t aNewIndexInContainer)
107 : {
108 0 : ContentChanged(aContainer);
109 0 : }
110 :
111 : void
112 0 : HTMLStyleElement::ContentInserted(nsIDocument* aDocument,
113 : nsIContent* aContainer,
114 : nsIContent* aChild,
115 : int32_t aIndexInContainer)
116 : {
117 0 : ContentChanged(aChild);
118 0 : }
119 :
120 : void
121 0 : HTMLStyleElement::ContentRemoved(nsIDocument* aDocument,
122 : nsIContent* aContainer,
123 : nsIContent* aChild,
124 : int32_t aIndexInContainer,
125 : nsIContent* aPreviousSibling)
126 : {
127 0 : ContentChanged(aChild);
128 0 : }
129 :
130 : void
131 0 : HTMLStyleElement::ContentChanged(nsIContent* aContent)
132 : {
133 0 : if (nsContentUtils::IsInSameAnonymousTree(this, aContent)) {
134 0 : UpdateStyleSheetInternal(nullptr, nullptr);
135 : }
136 0 : }
137 :
138 : nsresult
139 0 : HTMLStyleElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
140 : nsIContent* aBindingParent,
141 : bool aCompileEventHandlers)
142 : {
143 0 : nsresult rv = nsGenericHTMLElement::BindToTree(aDocument, aParent,
144 : aBindingParent,
145 0 : aCompileEventHandlers);
146 0 : NS_ENSURE_SUCCESS(rv, rv);
147 :
148 0 : void (HTMLStyleElement::*update)() = &HTMLStyleElement::UpdateStyleSheetInternal;
149 0 : nsContentUtils::AddScriptRunner(
150 0 : NewRunnableMethod("dom::HTMLStyleElement::BindToTree", this, update));
151 :
152 0 : return rv;
153 : }
154 :
155 : void
156 0 : HTMLStyleElement::UnbindFromTree(bool aDeep, bool aNullParent)
157 : {
158 0 : nsCOMPtr<nsIDocument> oldDoc = GetUncomposedDoc();
159 0 : ShadowRoot* oldShadow = GetContainingShadow();
160 :
161 0 : nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
162 :
163 0 : if (oldShadow && GetContainingShadow()) {
164 : // The style is in a shadow tree and is still in the
165 : // shadow tree. Thus the sheets in the shadow DOM
166 : // do not need to be updated.
167 0 : return;
168 : }
169 :
170 0 : UpdateStyleSheetInternal(oldDoc, oldShadow);
171 : }
172 :
173 : nsresult
174 0 : HTMLStyleElement::AfterSetAttr(int32_t aNameSpaceID, nsIAtom* aName,
175 : const nsAttrValue* aValue,
176 : const nsAttrValue* aOldValue, bool aNotify)
177 : {
178 0 : if (aNameSpaceID == kNameSpaceID_None) {
179 0 : if (aName == nsGkAtoms::title ||
180 0 : aName == nsGkAtoms::media ||
181 0 : aName == nsGkAtoms::type) {
182 0 : UpdateStyleSheetInternal(nullptr, nullptr, true);
183 0 : } else if (aName == nsGkAtoms::scoped &&
184 0 : OwnerDoc()->IsScopedStyleEnabled()) {
185 0 : bool isScoped = aValue;
186 0 : UpdateStyleSheetScopedness(isScoped);
187 : }
188 : }
189 :
190 0 : return nsGenericHTMLElement::AfterSetAttr(aNameSpaceID, aName, aValue,
191 0 : aOldValue, aNotify);
192 : }
193 :
194 : NS_IMETHODIMP
195 0 : HTMLStyleElement::GetInnerHTML(nsAString& aInnerHTML)
196 : {
197 0 : if (!nsContentUtils::GetNodeTextContent(this, false, aInnerHTML, fallible)) {
198 0 : return NS_ERROR_OUT_OF_MEMORY;
199 : }
200 0 : return NS_OK;
201 : }
202 :
203 : void
204 0 : HTMLStyleElement::SetInnerHTML(const nsAString& aInnerHTML,
205 : ErrorResult& aError)
206 : {
207 0 : SetEnableUpdates(false);
208 :
209 0 : aError = nsContentUtils::SetNodeTextContent(this, aInnerHTML, true);
210 :
211 0 : SetEnableUpdates(true);
212 :
213 0 : UpdateStyleSheetInternal(nullptr, nullptr);
214 0 : }
215 :
216 : already_AddRefed<nsIURI>
217 0 : HTMLStyleElement::GetStyleSheetURL(bool* aIsInline)
218 : {
219 0 : *aIsInline = true;
220 0 : return nullptr;
221 : }
222 :
223 : void
224 0 : HTMLStyleElement::GetStyleSheetInfo(nsAString& aTitle,
225 : nsAString& aType,
226 : nsAString& aMedia,
227 : bool* aIsScoped,
228 : bool* aIsAlternate)
229 : {
230 0 : aTitle.Truncate();
231 0 : aType.Truncate();
232 0 : aMedia.Truncate();
233 0 : *aIsAlternate = false;
234 :
235 0 : nsAutoString title;
236 0 : GetAttr(kNameSpaceID_None, nsGkAtoms::title, title);
237 0 : title.CompressWhitespace();
238 0 : aTitle.Assign(title);
239 :
240 0 : GetAttr(kNameSpaceID_None, nsGkAtoms::media, aMedia);
241 : // The HTML5 spec is formulated in terms of the CSSOM spec, which specifies
242 : // that media queries should be ASCII lowercased during serialization.
243 0 : nsContentUtils::ASCIIToLower(aMedia);
244 :
245 0 : GetAttr(kNameSpaceID_None, nsGkAtoms::type, aType);
246 :
247 0 : *aIsScoped = HasAttr(kNameSpaceID_None, nsGkAtoms::scoped) &&
248 0 : OwnerDoc()->IsScopedStyleEnabled();
249 :
250 0 : nsAutoString mimeType;
251 0 : nsAutoString notUsed;
252 0 : nsContentUtils::SplitMimeType(aType, mimeType, notUsed);
253 0 : if (!mimeType.IsEmpty() && !mimeType.LowerCaseEqualsLiteral("text/css")) {
254 0 : return;
255 : }
256 :
257 : // If we get here we assume that we're loading a css file, so set the
258 : // type to 'text/css'
259 0 : aType.AssignLiteral("text/css");
260 : }
261 :
262 : JSObject*
263 0 : HTMLStyleElement::WrapNode(JSContext *aCx, JS::Handle<JSObject*> aGivenProto)
264 : {
265 0 : return HTMLStyleElementBinding::Wrap(aCx, this, aGivenProto);
266 : }
267 :
268 : } // namespace dom
269 : } // namespace mozilla
270 :
|