Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / layout / style / nsDOMCSSDeclaration.cpp
blob3c7da82381e4277f16da22a26b205fa87fd06048
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 "nsICSSParser.h"
44 #include "nsICSSLoader.h"
45 #include "nsIStyleRule.h"
46 #include "nsCSSDeclaration.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"
56 nsDOMCSSDeclaration::nsDOMCSSDeclaration()
57 : mInner(this)
61 nsDOMCSSDeclaration::~nsDOMCSSDeclaration()
66 // QueryInterface implementation for nsDOMCSSDeclaration
67 NS_INTERFACE_MAP_BEGIN(nsDOMCSSDeclaration)
68 NS_INTERFACE_MAP_ENTRY(nsICSSDeclaration)
69 NS_INTERFACE_MAP_ENTRY(nsIDOMCSSStyleDeclaration)
70 NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIDOMCSS2Properties, &mInner)
71 NS_INTERFACE_MAP_ENTRY_AGGREGATED(nsIDOMNSCSS2Properties, &mInner)
72 NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMCSSStyleDeclaration)
73 NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(CSSStyleDeclaration)
74 NS_INTERFACE_MAP_END
76 NS_IMETHODIMP
77 nsDOMCSSDeclaration::GetPropertyValue(const nsCSSProperty aPropID,
78 nsAString& aValue)
80 NS_PRECONDITION(aPropID != eCSSProperty_UNKNOWN,
81 "Should never pass eCSSProperty_UNKNOWN around");
83 nsCSSDeclaration *decl;
84 nsresult result = GetCSSDeclaration(&decl, PR_FALSE);
86 aValue.Truncate();
87 if (decl) {
88 result = decl->GetValue(aPropID, aValue);
91 return result;
94 NS_IMETHODIMP
95 nsDOMCSSDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
96 const nsAString& aValue)
98 if (aValue.IsEmpty()) {
99 // If the new value of the property is an empty string we remove the
100 // property.
101 return RemoveProperty(aPropID);
104 return ParsePropertyValue(aPropID, aValue);
108 NS_IMETHODIMP
109 nsDOMCSSDeclaration::GetCssText(nsAString& aCssText)
111 nsCSSDeclaration* decl;
112 aCssText.Truncate();
113 GetCSSDeclaration(&decl, PR_FALSE);
115 if (decl) {
116 decl->ToString(aCssText);
119 return NS_OK;
122 NS_IMETHODIMP
123 nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText)
125 return ParseDeclaration(aCssText, PR_FALSE, PR_TRUE);
128 NS_IMETHODIMP
129 nsDOMCSSDeclaration::GetLength(PRUint32* aLength)
131 nsCSSDeclaration *decl;
132 nsresult result = GetCSSDeclaration(&decl, PR_FALSE);
134 if (decl) {
135 *aLength = decl->Count();
136 } else {
137 *aLength = 0;
140 return result;
143 NS_IMETHODIMP
144 nsDOMCSSDeclaration::GetPropertyCSSValue(const nsAString& aPropertyName,
145 nsIDOMCSSValue** aReturn)
147 NS_ENSURE_ARG_POINTER(aReturn);
149 // We don't support CSSValue yet so we'll just return null...
150 *aReturn = nsnull;
152 return NS_OK;
155 NS_IMETHODIMP
156 nsDOMCSSDeclaration::Item(PRUint32 aIndex, nsAString& aReturn)
158 nsCSSDeclaration *decl;
159 nsresult result = GetCSSDeclaration(&decl, PR_FALSE);
161 aReturn.SetLength(0);
162 if (decl) {
163 result = decl->GetNthProperty(aIndex, aReturn);
166 return result;
169 NS_IMETHODIMP
170 nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName,
171 nsAString& aReturn)
173 const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
174 if (propID == eCSSProperty_UNKNOWN) {
175 aReturn.Truncate();
176 return NS_OK;
179 return GetPropertyValue(propID, aReturn);
182 NS_IMETHODIMP
183 nsDOMCSSDeclaration::GetPropertyPriority(const nsAString& aPropertyName,
184 nsAString& aReturn)
186 nsCSSDeclaration *decl;
187 nsresult result = GetCSSDeclaration(&decl, PR_FALSE);
189 aReturn.Truncate();
190 if (decl && decl->GetValueIsImportant(aPropertyName)) {
191 aReturn.AssignLiteral("important");
194 return result;
197 NS_IMETHODIMP
198 nsDOMCSSDeclaration::SetProperty(const nsAString& aPropertyName,
199 const nsAString& aValue,
200 const nsAString& aPriority)
202 // In the common (and fast) cases we can use the property id
203 nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
204 if (propID == eCSSProperty_UNKNOWN) {
205 return NS_OK;
208 if (aValue.IsEmpty()) {
209 // If the new value of the property is an empty string we remove the
210 // property.
211 return RemoveProperty(propID);
214 if (aPriority.IsEmpty()) {
215 return ParsePropertyValue(propID, aValue);
218 // ParsePropertyValue does not handle priorities correctly -- it's
219 // optimized for speed. And the priority is not part of the
220 // property value anyway.... So we have to use the full-blown
221 // ParseDeclaration()
222 return ParseDeclaration(aPropertyName + NS_LITERAL_STRING(":") +
223 aValue + NS_LITERAL_STRING("!") + aPriority,
224 PR_TRUE, PR_FALSE);
227 NS_IMETHODIMP
228 nsDOMCSSDeclaration::RemoveProperty(const nsAString& aPropertyName,
229 nsAString& aReturn)
231 const nsCSSProperty propID = nsCSSProps::LookupProperty(aPropertyName);
232 if (propID == eCSSProperty_UNKNOWN) {
233 aReturn.Truncate();
234 return NS_OK;
237 nsresult rv = GetPropertyValue(propID, aReturn);
238 NS_ENSURE_SUCCESS(rv, rv);
240 rv = RemoveProperty(propID);
241 return rv;
244 nsresult
245 nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID,
246 const nsAString& aPropValue)
248 nsCSSDeclaration* decl;
249 nsresult result = GetCSSDeclaration(&decl, PR_TRUE);
250 if (!decl) {
251 return result;
254 nsCOMPtr<nsICSSLoader> cssLoader;
255 nsCOMPtr<nsICSSParser> cssParser;
256 nsCOMPtr<nsIURI> baseURI, sheetURI;
257 nsCOMPtr<nsIPrincipal> sheetPrincipal;
259 result = GetCSSParsingEnvironment(getter_AddRefs(sheetURI),
260 getter_AddRefs(baseURI),
261 getter_AddRefs(sheetPrincipal),
262 getter_AddRefs(cssLoader),
263 getter_AddRefs(cssParser));
264 if (NS_FAILED(result)) {
265 return result;
268 PRBool changed;
269 result = cssParser->ParseProperty(aPropID, aPropValue, sheetURI, baseURI,
270 sheetPrincipal, decl, &changed);
271 if (NS_SUCCEEDED(result) && changed) {
272 result = DeclarationChanged();
275 if (cssLoader) {
276 cssLoader->RecycleParser(cssParser);
279 return result;
282 nsresult
283 nsDOMCSSDeclaration::ParseDeclaration(const nsAString& aDecl,
284 PRBool aParseOnlyOneDecl,
285 PRBool aClearOldDecl)
287 nsCSSDeclaration* decl;
288 nsresult result = GetCSSDeclaration(&decl, PR_TRUE);
289 if (!decl) {
290 return result;
293 nsCOMPtr<nsICSSLoader> cssLoader;
294 nsCOMPtr<nsICSSParser> cssParser;
295 nsCOMPtr<nsIURI> baseURI, sheetURI;
296 nsCOMPtr<nsIPrincipal> sheetPrincipal;
298 result = GetCSSParsingEnvironment(getter_AddRefs(sheetURI),
299 getter_AddRefs(baseURI),
300 getter_AddRefs(sheetPrincipal),
301 getter_AddRefs(cssLoader),
302 getter_AddRefs(cssParser));
304 if (NS_FAILED(result)) {
305 return result;
308 PRBool changed;
309 result = cssParser->ParseAndAppendDeclaration(aDecl, sheetURI, baseURI,
310 sheetPrincipal, decl,
311 aParseOnlyOneDecl,
312 &changed,
313 aClearOldDecl);
315 if (NS_SUCCEEDED(result) && changed) {
316 result = DeclarationChanged();
319 if (cssLoader) {
320 cssLoader->RecycleParser(cssParser);
323 return result;
326 nsresult
327 nsDOMCSSDeclaration::RemoveProperty(const nsCSSProperty aPropID)
329 nsCSSDeclaration* decl;
330 nsresult rv = GetCSSDeclaration(&decl, PR_FALSE);
331 if (!decl) {
332 return rv;
335 rv = decl->RemoveProperty(aPropID);
337 if (NS_SUCCEEDED(rv)) {
338 rv = DeclarationChanged();
339 } else {
340 // RemoveProperty used to throw in all sorts of situations -- e.g.
341 // if the property was a shorthand one. Do not propagate its return
342 // value to callers. (XXX or should we propagate it again now?)
343 rv = NS_OK;
346 return rv;
349 //////////////////////////////////////////////////////////////////////////////
351 CSS2PropertiesTearoff::CSS2PropertiesTearoff(nsICSSDeclaration *aOuter)
352 : mOuter(aOuter)
354 NS_ASSERTION(mOuter, "must have outer");
357 CSS2PropertiesTearoff::~CSS2PropertiesTearoff()
361 NS_IMETHODIMP_(nsrefcnt)
362 CSS2PropertiesTearoff::AddRef(void)
364 return mOuter->AddRef();
367 NS_IMETHODIMP_(nsrefcnt)
368 CSS2PropertiesTearoff::Release(void)
370 return mOuter->Release();
373 NS_IMETHODIMP
374 CSS2PropertiesTearoff::QueryInterface(REFNSIID aIID, void** aInstancePtr)
376 return mOuter->QueryInterface(aIID, aInstancePtr);
379 // nsIDOMCSS2Properties
380 // nsIDOMNSCSS2Properties
382 #define CSS_PROP(name_, id_, method_, flags_, datastruct_, member_, type_, kwtable_) \
383 NS_IMETHODIMP \
384 CSS2PropertiesTearoff::Get##method_(nsAString& aValue) \
386 return mOuter->GetPropertyValue(eCSSProperty_##id_, aValue); \
389 NS_IMETHODIMP \
390 CSS2PropertiesTearoff::Set##method_(const nsAString& aValue) \
392 return mOuter->SetPropertyValue(eCSSProperty_##id_, aValue); \
395 #define CSS_PROP_NOTIMPLEMENTED(name_, id_, method_, flags_) \
396 NS_IMETHODIMP \
397 CSS2PropertiesTearoff::Get##method_(nsAString& aValue) \
399 aValue.Truncate(); \
400 return NS_OK; \
403 NS_IMETHODIMP \
404 CSS2PropertiesTearoff::Set##method_(const nsAString& aValue) \
406 return NS_OK; \
409 #define CSS_PROP_LIST_EXCLUDE_INTERNAL
410 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_) \
411 CSS_PROP(name_, id_, method_, flags_, X, X, X, X)
412 #include "nsCSSPropList.h"
414 // Aliases
415 CSS_PROP(X, opacity, MozOpacity, 0, X, X, X, X)
416 CSS_PROP(X, outline, MozOutline, 0, X, X, X, X)
417 CSS_PROP(X, outline_color, MozOutlineColor, 0, X, X, X, X)
418 CSS_PROP(X, outline_style, MozOutlineStyle, 0, X, X, X, X)
419 CSS_PROP(X, outline_width, MozOutlineWidth, 0, X, X, X, X)
420 CSS_PROP(X, outline_offset, MozOutlineOffset, 0, X, X, X, X)
422 #undef CSS_PROP_SHORTHAND
423 #undef CSS_PROP_NOTIMPLEMENTED
424 #undef CSS_PROP_LIST_EXCLUDE_INTERNAL
425 #undef CSS_PROP