Bug 575870 - Enable the firefox button on xp themed, classic, and aero basic. r=dao...
[mozilla-central.git] / layout / style / nsDOMCSSDeclaration.cpp
blob89020d8623021fe9c759c57649da281d79943312
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is Mozilla Communicator client code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Mats Palmgren <mats.palmgren@bredband.net>
25 * Alternatively, the contents of this file may be used under the terms of
26 * either of the GNU General Public License Version 2 or later (the "GPL"),
27 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
28 * in which case the provisions of the GPL or the LGPL are applicable instead
29 * of those above. If you wish to allow use of your version of this file only
30 * under the terms of either the GPL or the LGPL, and not to allow others to
31 * use your version of this file under the terms of the MPL, indicate your
32 * decision by deleting the provisions above and replace them with the notice
33 * and other provisions required by the GPL or the LGPL. If you do not delete
34 * the provisions above, a recipient may use your version of this file under
35 * the terms of any one of the MPL, the GPL or the LGPL.
37 * ***** END LICENSE BLOCK ***** */
39 /* base class for DOM objects for element.style and cssStyleRule.style */
41 #include "nsDOMCSSDeclaration.h"
42 #include "nsIDOMCSSRule.h"
43 #include "nsCSSParser.h"
44 #include "mozilla/css/Loader.h"
45 #include "nsIStyleRule.h"
46 #include "mozilla/css/Declaration.h"
47 #include "nsCSSProps.h"
48 #include "nsCOMPtr.h"
49 #include "nsIURL.h"
50 #include "nsReadableUtils.h"
51 #include "nsIPrincipal.h"
53 #include "nsContentUtils.h"
54 #include "mozAutoDocUpdate.h"
56 namespace css = mozilla::css;
58 nsDOMCSSDeclaration::~nsDOMCSSDeclaration()
62 DOMCI_DATA(CSSStyleDeclaration, nsDOMCSSDeclaration)
64 NS_INTERFACE_TABLE_HEAD(nsDOMCSSDeclaration)
65 NS_INTERFACE_TABLE3(nsDOMCSSDeclaration,
66 nsICSSDeclaration,
67 nsIDOMCSSStyleDeclaration,
68 nsIDOMCSS2Properties)
69 NS_INTERFACE_TABLE_TO_MAP_SEGUE
70 NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(CSSStyleDeclaration)
71 NS_INTERFACE_MAP_END
73 NS_IMETHODIMP
74 nsDOMCSSDeclaration::GetPropertyValue(const nsCSSProperty aPropID,
75 nsAString& aValue)
77 NS_PRECONDITION(aPropID != eCSSProperty_UNKNOWN,
78 "Should never pass eCSSProperty_UNKNOWN around");
80 css::Declaration* decl = GetCSSDeclaration(PR_FALSE);
82 aValue.Truncate();
83 if (decl) {
84 decl->GetValue(aPropID, aValue);
86 return NS_OK;
89 NS_IMETHODIMP
90 nsDOMCSSDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
91 const nsAString& aValue)
93 if (aValue.IsEmpty()) {
94 // If the new value of the property is an empty string we remove the
95 // property.
96 return RemoveProperty(aPropID);
99 return ParsePropertyValue(aPropID, aValue, PR_FALSE);
103 NS_IMETHODIMP
104 nsDOMCSSDeclaration::GetCssText(nsAString& aCssText)
106 css::Declaration* decl = GetCSSDeclaration(PR_FALSE);
107 aCssText.Truncate();
109 if (decl) {
110 decl->ToString(aCssText);
113 return NS_OK;
116 NS_IMETHODIMP
117 nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText)
119 // We don't need to *do* anything with the old declaration, but we need
120 // to ensure that it exists, or else SetCSSDeclaration may crash.
121 css::Declaration* olddecl = GetCSSDeclaration(PR_TRUE);
122 if (!olddecl) {
123 return NS_ERROR_FAILURE;
126 nsresult result;
127 nsRefPtr<css::Loader> cssLoader;
128 nsCOMPtr<nsIURI> baseURI, sheetURI;
129 nsCOMPtr<nsIPrincipal> sheetPrincipal;
131 result = GetCSSParsingEnvironment(getter_AddRefs(sheetURI),
132 getter_AddRefs(baseURI),
133 getter_AddRefs(sheetPrincipal),
134 getter_AddRefs(cssLoader));
136 if (NS_FAILED(result)) {
137 return result;
140 // For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
141 // Attribute setting code, which leads in turn to BeginUpdate. We
142 // need to start the update now so that the old rule doesn't get used
143 // between when we mutate the declaration and when we set the new
144 // rule (see stack in bug 209575).
145 mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), PR_TRUE);
147 nsAutoPtr<css::Declaration> decl(new css::Declaration());
148 decl->InitializeEmpty();
149 nsCSSParser cssParser(cssLoader);
150 PRBool changed;
151 result = cssParser.ParseDeclarations(aCssText, sheetURI, baseURI,
152 sheetPrincipal, decl, &changed);
153 if (NS_FAILED(result) || !changed) {
154 return result;
157 return SetCSSDeclaration(decl.forget());
160 NS_IMETHODIMP
161 nsDOMCSSDeclaration::GetLength(PRUint32* aLength)
163 css::Declaration* decl = GetCSSDeclaration(PR_FALSE);
165 if (decl) {
166 *aLength = decl->Count();
167 } else {
168 *aLength = 0;
171 return NS_OK;
174 NS_IMETHODIMP
175 nsDOMCSSDeclaration::GetPropertyCSSValue(const nsAString& aPropertyName,
176 nsIDOMCSSValue** aReturn)
178 NS_ENSURE_ARG_POINTER(aReturn);
180 // We don't support CSSValue yet so we'll just return null...
181 *aReturn = nsnull;
183 return NS_OK;
186 NS_IMETHODIMP
187 nsDOMCSSDeclaration::Item(PRUint32 aIndex, nsAString& aReturn)
189 css::Declaration* decl = GetCSSDeclaration(PR_FALSE);
191 aReturn.SetLength(0);
192 if (decl) {
193 decl->GetNthProperty(aIndex, aReturn);
196 return NS_OK;
199 NS_IMETHODIMP
200 nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName,
201 nsAString& aReturn)
203 const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
204 if (propID == eCSSProperty_UNKNOWN) {
205 aReturn.Truncate();
206 return NS_OK;
209 return GetPropertyValue(propID, aReturn);
212 NS_IMETHODIMP
213 nsDOMCSSDeclaration::GetPropertyPriority(const nsAString& aPropertyName,
214 nsAString& aReturn)
216 css::Declaration* decl = GetCSSDeclaration(PR_FALSE);
218 aReturn.Truncate();
219 if (decl && decl->GetValueIsImportant(aPropertyName)) {
220 aReturn.AssignLiteral("important");
223 return NS_OK;
226 NS_IMETHODIMP
227 nsDOMCSSDeclaration::SetProperty(const nsAString& aPropertyName,
228 const nsAString& aValue,
229 const nsAString& aPriority)
231 // In the common (and fast) cases we can use the property id
232 nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
233 if (propID == eCSSProperty_UNKNOWN) {
234 return NS_OK;
237 if (aValue.IsEmpty()) {
238 // If the new value of the property is an empty string we remove the
239 // property.
240 // XXX this ignores the priority string, should it?
241 return RemoveProperty(propID);
244 if (aPriority.IsEmpty()) {
245 return ParsePropertyValue(propID, aValue, PR_FALSE);
248 if (aPriority.EqualsLiteral("important")) {
249 return ParsePropertyValue(propID, aValue, PR_TRUE);
252 // XXX silent failure?
253 return NS_OK;
256 NS_IMETHODIMP
257 nsDOMCSSDeclaration::RemoveProperty(const nsAString& aPropertyName,
258 nsAString& aReturn)
260 const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
261 if (propID == eCSSProperty_UNKNOWN) {
262 aReturn.Truncate();
263 return NS_OK;
266 nsresult rv = GetPropertyValue(propID, aReturn);
267 NS_ENSURE_SUCCESS(rv, rv);
269 return RemoveProperty(propID);
272 nsresult
273 nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID,
274 const nsAString& aPropValue,
275 PRBool aIsImportant)
277 css::Declaration* olddecl = GetCSSDeclaration(PR_TRUE);
278 if (!olddecl) {
279 return NS_ERROR_FAILURE;
282 nsresult result;
283 nsRefPtr<css::Loader> cssLoader;
284 nsCOMPtr<nsIURI> baseURI, sheetURI;
285 nsCOMPtr<nsIPrincipal> sheetPrincipal;
287 result = GetCSSParsingEnvironment(getter_AddRefs(sheetURI),
288 getter_AddRefs(baseURI),
289 getter_AddRefs(sheetPrincipal),
290 getter_AddRefs(cssLoader));
291 if (NS_FAILED(result)) {
292 return result;
295 // For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
296 // Attribute setting code, which leads in turn to BeginUpdate. We
297 // need to start the update now so that the old rule doesn't get used
298 // between when we mutate the declaration and when we set the new
299 // rule (see stack in bug 209575).
300 mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), PR_TRUE);
301 css::Declaration* decl = olddecl->EnsureMutable();
303 nsCSSParser cssParser(cssLoader);
304 PRBool changed;
305 result = cssParser.ParseProperty(aPropID, aPropValue, sheetURI, baseURI,
306 sheetPrincipal, decl, &changed,
307 aIsImportant);
308 if (NS_FAILED(result) || !changed) {
309 if (decl != olddecl) {
310 delete decl;
312 return result;
315 return SetCSSDeclaration(decl);
318 nsresult
319 nsDOMCSSDeclaration::RemoveProperty(const nsCSSProperty aPropID)
321 css::Declaration* decl = GetCSSDeclaration(PR_FALSE);
322 if (!decl) {
323 return NS_OK; // no decl, so nothing to remove
326 // For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
327 // Attribute setting code, which leads in turn to BeginUpdate. We
328 // need to start the update now so that the old rule doesn't get used
329 // between when we mutate the declaration and when we set the new
330 // rule (see stack in bug 209575).
331 mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), PR_TRUE);
333 decl = decl->EnsureMutable();
334 decl->RemoveProperty(aPropID);
335 return SetCSSDeclaration(decl);
338 // nsIDOMCSS2Properties
340 #define CSS_PROP(name_, id_, method_, flags_, datastruct_, member_, \
341 kwtable_, stylestruct_, stylestructoffset_, animtype_) \
342 NS_IMETHODIMP \
343 nsDOMCSSDeclaration::Get##method_(nsAString& aValue) \
345 return GetPropertyValue(eCSSProperty_##id_, aValue); \
348 NS_IMETHODIMP \
349 nsDOMCSSDeclaration::Set##method_(const nsAString& aValue) \
351 return SetPropertyValue(eCSSProperty_##id_, aValue); \
354 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
355 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_) \
356 CSS_PROP(name_, id_, method_, flags_, X, X, X, X, X, X)
357 #include "nsCSSPropList.h"
359 // Aliases
360 CSS_PROP(X, opacity, MozOpacity, X, X, X, X, X, X, X)
361 CSS_PROP(X, outline, MozOutline, X, X, X, X, X, X, X)
362 CSS_PROP(X, outline_color, MozOutlineColor, X, X, X, X, X, X, X)
363 CSS_PROP(X, outline_style, MozOutlineStyle, X, X, X, X, X, X, X)
364 CSS_PROP(X, outline_width, MozOutlineWidth, X, X, X, X, X, X, X)
365 CSS_PROP(X, outline_offset, MozOutlineOffset, X, X, X, X, X, X, X)
367 #undef CSS_PROP_SHORTHAND
368 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
369 #undef CSS_PROP