layout/style/nsDOMCSSAttrDeclaration.cpp

Tue, 06 Jan 2015 21:39:09 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Tue, 06 Jan 2015 21:39:09 +0100
branch
TOR_BUG_9701
changeset 8
97036ab72558
permissions
-rw-r--r--

Conditionally force memory storage according to privacy.thirdparty.isolate;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 /* DOM object for element.style */
michael@0 7
michael@0 8 #include "nsDOMCSSAttrDeclaration.h"
michael@0 9
michael@0 10 #include "mozilla/css/Declaration.h"
michael@0 11 #include "mozilla/css/StyleRule.h"
michael@0 12 #include "mozilla/dom/Element.h"
michael@0 13 #include "nsIDocument.h"
michael@0 14 #include "nsIDOMMutationEvent.h"
michael@0 15 #include "nsIURI.h"
michael@0 16 #include "nsNodeUtils.h"
michael@0 17 #include "nsWrapperCacheInlines.h"
michael@0 18 #include "nsIFrame.h"
michael@0 19 #include "ActiveLayerTracker.h"
michael@0 20
michael@0 21 using namespace mozilla;
michael@0 22
michael@0 23 nsDOMCSSAttributeDeclaration::nsDOMCSSAttributeDeclaration(dom::Element* aElement,
michael@0 24 bool aIsSMILOverride)
michael@0 25 : mElement(aElement)
michael@0 26 , mIsSMILOverride(aIsSMILOverride)
michael@0 27 {
michael@0 28 MOZ_COUNT_CTOR(nsDOMCSSAttributeDeclaration);
michael@0 29
michael@0 30 NS_ASSERTION(aElement, "Inline style for a NULL element?");
michael@0 31 }
michael@0 32
michael@0 33 nsDOMCSSAttributeDeclaration::~nsDOMCSSAttributeDeclaration()
michael@0 34 {
michael@0 35 MOZ_COUNT_DTOR(nsDOMCSSAttributeDeclaration);
michael@0 36 }
michael@0 37
michael@0 38 NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsDOMCSSAttributeDeclaration, mElement)
michael@0 39
michael@0 40 // mElement holds a strong ref to us, so if it's going to be
michael@0 41 // skipped, the attribute declaration can't be part of a garbage
michael@0 42 // cycle.
michael@0 43 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsDOMCSSAttributeDeclaration)
michael@0 44 if (tmp->mElement && Element::CanSkip(tmp->mElement, true)) {
michael@0 45 if (tmp->PreservingWrapper()) {
michael@0 46 // This marks the wrapper black.
michael@0 47 tmp->GetWrapper();
michael@0 48 }
michael@0 49 return true;
michael@0 50 }
michael@0 51 return tmp->IsBlack();
michael@0 52 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
michael@0 53
michael@0 54 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsDOMCSSAttributeDeclaration)
michael@0 55 return tmp->IsBlack() ||
michael@0 56 (tmp->mElement && Element::CanSkipInCC(tmp->mElement));
michael@0 57 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
michael@0 58
michael@0 59 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsDOMCSSAttributeDeclaration)
michael@0 60 return tmp->IsBlack() ||
michael@0 61 (tmp->mElement && Element::CanSkipThis(tmp->mElement));
michael@0 62 NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
michael@0 63
michael@0 64 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMCSSAttributeDeclaration)
michael@0 65 NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
michael@0 66 NS_IMPL_QUERY_TAIL_INHERITING(nsDOMCSSDeclaration)
michael@0 67
michael@0 68 NS_IMPL_CYCLE_COLLECTING_ADDREF(nsDOMCSSAttributeDeclaration)
michael@0 69 NS_IMPL_CYCLE_COLLECTING_RELEASE(nsDOMCSSAttributeDeclaration)
michael@0 70
michael@0 71 nsresult
michael@0 72 nsDOMCSSAttributeDeclaration::SetCSSDeclaration(css::Declaration* aDecl)
michael@0 73 {
michael@0 74 NS_ASSERTION(mElement, "Must have Element to set the declaration!");
michael@0 75 css::StyleRule* oldRule =
michael@0 76 mIsSMILOverride ? mElement->GetSMILOverrideStyleRule() :
michael@0 77 mElement->GetInlineStyleRule();
michael@0 78 NS_ASSERTION(oldRule, "Element must have rule");
michael@0 79
michael@0 80 nsRefPtr<css::StyleRule> newRule =
michael@0 81 oldRule->DeclarationChanged(aDecl, false);
michael@0 82 if (!newRule) {
michael@0 83 return NS_ERROR_OUT_OF_MEMORY;
michael@0 84 }
michael@0 85
michael@0 86 return
michael@0 87 mIsSMILOverride ? mElement->SetSMILOverrideStyleRule(newRule, true) :
michael@0 88 mElement->SetInlineStyleRule(newRule, nullptr, true);
michael@0 89 }
michael@0 90
michael@0 91 nsIDocument*
michael@0 92 nsDOMCSSAttributeDeclaration::DocToUpdate()
michael@0 93 {
michael@0 94 // XXXbz this is a bit of a hack, especially doing it before the
michael@0 95 // BeginUpdate(), but this is a good chokepoint where we know we
michael@0 96 // plan to modify the CSSDeclaration, so need to notify
michael@0 97 // AttributeWillChange if this is inline style.
michael@0 98 if (!mIsSMILOverride) {
michael@0 99 nsNodeUtils::AttributeWillChange(mElement, kNameSpaceID_None,
michael@0 100 nsGkAtoms::style,
michael@0 101 nsIDOMMutationEvent::MODIFICATION);
michael@0 102 }
michael@0 103
michael@0 104 // We need OwnerDoc() rather than GetCurrentDoc() because it might
michael@0 105 // be the BeginUpdate call that inserts mElement into the document.
michael@0 106 return mElement->OwnerDoc();
michael@0 107 }
michael@0 108
michael@0 109 css::Declaration*
michael@0 110 nsDOMCSSAttributeDeclaration::GetCSSDeclaration(bool aAllocate)
michael@0 111 {
michael@0 112 if (!mElement)
michael@0 113 return nullptr;
michael@0 114
michael@0 115 css::StyleRule* cssRule;
michael@0 116 if (mIsSMILOverride)
michael@0 117 cssRule = mElement->GetSMILOverrideStyleRule();
michael@0 118 else
michael@0 119 cssRule = mElement->GetInlineStyleRule();
michael@0 120
michael@0 121 if (cssRule) {
michael@0 122 return cssRule->GetDeclaration();
michael@0 123 }
michael@0 124 if (!aAllocate) {
michael@0 125 return nullptr;
michael@0 126 }
michael@0 127
michael@0 128 // cannot fail
michael@0 129 css::Declaration *decl = new css::Declaration();
michael@0 130 decl->InitializeEmpty();
michael@0 131 nsRefPtr<css::StyleRule> newRule = new css::StyleRule(nullptr, decl);
michael@0 132
michael@0 133 // this *can* fail (inside SetAttrAndNotify, at least).
michael@0 134 nsresult rv;
michael@0 135 if (mIsSMILOverride)
michael@0 136 rv = mElement->SetSMILOverrideStyleRule(newRule, false);
michael@0 137 else
michael@0 138 rv = mElement->SetInlineStyleRule(newRule, nullptr, false);
michael@0 139
michael@0 140 if (NS_FAILED(rv)) {
michael@0 141 return nullptr; // the decl will be destroyed along with the style rule
michael@0 142 }
michael@0 143
michael@0 144 return decl;
michael@0 145 }
michael@0 146
michael@0 147 void
michael@0 148 nsDOMCSSAttributeDeclaration::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv)
michael@0 149 {
michael@0 150 NS_ASSERTION(mElement, "Something is severely broken -- there should be an Element here!");
michael@0 151
michael@0 152 nsIDocument* doc = mElement->OwnerDoc();
michael@0 153 aCSSParseEnv.mSheetURI = doc->GetDocumentURI();
michael@0 154 aCSSParseEnv.mBaseURI = mElement->GetBaseURI();
michael@0 155 aCSSParseEnv.mPrincipal = mElement->NodePrincipal();
michael@0 156 aCSSParseEnv.mCSSLoader = doc->CSSLoader();
michael@0 157 }
michael@0 158
michael@0 159 NS_IMETHODIMP
michael@0 160 nsDOMCSSAttributeDeclaration::GetParentRule(nsIDOMCSSRule **aParent)
michael@0 161 {
michael@0 162 NS_ENSURE_ARG_POINTER(aParent);
michael@0 163
michael@0 164 *aParent = nullptr;
michael@0 165 return NS_OK;
michael@0 166 }
michael@0 167
michael@0 168 /* virtual */ nsINode*
michael@0 169 nsDOMCSSAttributeDeclaration::GetParentObject()
michael@0 170 {
michael@0 171 return mElement;
michael@0 172 }
michael@0 173
michael@0 174 NS_IMETHODIMP
michael@0 175 nsDOMCSSAttributeDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
michael@0 176 const nsAString& aValue)
michael@0 177 {
michael@0 178 // Scripted modifications to style.opacity or style.transform
michael@0 179 // could immediately force us into the animated state if heuristics suggest
michael@0 180 // this is scripted animation.
michael@0 181 if (aPropID == eCSSProperty_opacity || aPropID == eCSSProperty_transform ||
michael@0 182 aPropID == eCSSProperty_left || aPropID == eCSSProperty_top ||
michael@0 183 aPropID == eCSSProperty_right || aPropID == eCSSProperty_bottom ||
michael@0 184 aPropID == eCSSProperty_margin_left || aPropID == eCSSProperty_margin_top ||
michael@0 185 aPropID == eCSSProperty_margin_right || aPropID == eCSSProperty_margin_bottom) {
michael@0 186 nsIFrame* frame = mElement->GetPrimaryFrame();
michael@0 187 if (frame) {
michael@0 188 ActiveLayerTracker::NotifyInlineStyleRuleModified(frame, aPropID);
michael@0 189 }
michael@0 190 }
michael@0 191 return nsDOMCSSDeclaration::SetPropertyValue(aPropID, aValue);
michael@0 192 }

mercurial