1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 /* DOM object for element.style */
8 #include "nsDOMCSSAttrDeclaration.h"
10 #include "mozilla/css/Declaration.h"
11 #include "mozilla/css/StyleRule.h"
12 #include "mozilla/dom/Element.h"
13 #include "nsIDocument.h"
14 #include "nsIDOMMutationEvent.h"
16 #include "nsNodeUtils.h"
17 #include "xpcpublic.h"
18 #include "nsWrapperCacheInlines.h"
20 namespace css
= mozilla::css
;
21 namespace dom
= mozilla::dom
;
23 nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(dom::Element
* aElement
,
26 , mIsSMILOverride(aIsSMILOverride
)
28 MOZ_COUNT_CTOR(nsDOMCSSAttributeDeclaration
);
30 NS_ASSERTION(aElement
, "Inline style for a NULL element?");
33 nsDOMCSSAttributeDeclaration::~nsDOMCSSAttributeDeclaration()
35 MOZ_COUNT_DTOR(nsDOMCSSAttributeDeclaration
);
38 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsDOMCSSAttributeDeclaration
, mElement
)
40 // mElement holds a strong ref to us, so if it's going to be
41 // skipped, the attribute declaration can't be part of a garbage
43 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDOMCSSAttributeDeclaration
)
44 if (tmp
->mElement
&& Element::CanSkip(tmp
->mElement
, true)) {
45 if (tmp
->PreservingWrapper()) {
46 // Not relying on GetWrapper to unmark us gray because the
47 // side-effect thing is pretty weird.
48 JSObject
* o
= tmp
->GetWrapperPreserveColor();
49 xpc_UnmarkGrayObject(o
);
53 return tmp
->IsBlack();
54 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
56 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsDOMCSSAttributeDeclaration
)
57 return tmp
->IsBlack() ||
58 (tmp
->mElement
&& Element::CanSkipInCC(tmp
->mElement
));
59 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
61 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDOMCSSAttributeDeclaration
)
62 return tmp
->IsBlack() ||
63 (tmp
->mElement
&& Element::CanSkipThis(tmp
->mElement
));
64 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
66 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCSSAttributeDeclaration
)
67 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
68 NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration
)
70 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCSSAttributeDeclaration
)
71 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCSSAttributeDeclaration
)
74 nsDOMCSSAttributeDeclaration::SetCSSDeclaration(css::Declaration
* aDecl
)
76 NS_ASSERTION(mElement
, "Must have Element to set the declaration!");
77 css::StyleRule
* oldRule
=
78 mIsSMILOverride
? mElement
->GetSMILOverrideStyleRule() :
79 mElement
->GetInlineStyleRule();
80 NS_ASSERTION(oldRule
, "Element must have rule");
82 nsRefPtr
<css::StyleRule
> newRule
=
83 oldRule
->DeclarationChanged(aDecl
, false);
85 return NS_ERROR_OUT_OF_MEMORY
;
89 mIsSMILOverride
? mElement
->SetSMILOverrideStyleRule(newRule
, true) :
90 mElement
->SetInlineStyleRule(newRule
, nullptr, true);
94 nsDOMCSSAttributeDeclaration::DocToUpdate()
96 // XXXbz this is a bit of a hack, especially doing it before the
97 // BeginUpdate(), but this is a good chokepoint where we know we
98 // plan to modify the CSSDeclaration, so need to notify
99 // AttributeWillChange if this is inline style.
100 if (!mIsSMILOverride
) {
101 nsNodeUtils::AttributeWillChange(mElement
, kNameSpaceID_None
,
103 nsIDOMMutationEvent::MODIFICATION
);
106 // We need OwnerDoc() rather than GetCurrentDoc() because it might
107 // be the BeginUpdate call that inserts mElement into the document.
108 return mElement
->OwnerDoc();
112 nsDOMCSSAttributeDeclaration::GetCSSDeclaration(bool aAllocate
)
117 css::StyleRule
* cssRule
;
119 cssRule
= mElement
->GetSMILOverrideStyleRule();
121 cssRule
= mElement
->GetInlineStyleRule();
124 return cssRule
->GetDeclaration();
131 css::Declaration
*decl
= new css::Declaration();
132 decl
->InitializeEmpty();
133 nsRefPtr
<css::StyleRule
> newRule
= new css::StyleRule(nullptr, decl
);
135 // this *can* fail (inside SetAttrAndNotify, at least).
138 rv
= mElement
->SetSMILOverrideStyleRule(newRule
, false);
140 rv
= mElement
->SetInlineStyleRule(newRule
, nullptr, false);
143 return nullptr; // the decl will be destroyed along with the style rule
150 nsDOMCSSAttributeDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment
& aCSSParseEnv
)
152 NS_ASSERTION(mElement
, "Something is severely broken -- there should be an Element here!");
154 nsIDocument
* doc
= mElement
->OwnerDoc();
155 aCSSParseEnv
.mSheetURI
= doc
->GetDocumentURI();
156 aCSSParseEnv
.mBaseURI
= mElement
->GetBaseURI();
157 aCSSParseEnv
.mPrincipal
= mElement
->NodePrincipal();
158 aCSSParseEnv
.mCSSLoader
= doc
->CSSLoader();
162 nsDOMCSSAttributeDeclaration::GetParentRule(nsIDOMCSSRule
**aParent
)
164 NS_ENSURE_ARG_POINTER(aParent
);
170 /* virtual */ nsINode
*
171 nsDOMCSSAttributeDeclaration::GetParentObject()