dom/smil/nsSMILMappedAttribute.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 /* representation of a SMIL-animatable mapped attribute on an element */
michael@0 7 #include "nsSMILMappedAttribute.h"
michael@0 8 #include "nsContentUtils.h"
michael@0 9 #include "nsError.h" // For NS_PROPTABLE_PROP_OVERWRITTEN
michael@0 10 #include "nsSMILValue.h"
michael@0 11 #include "nsSMILCSSValueType.h"
michael@0 12 #include "nsIDocument.h"
michael@0 13 #include "nsIPresShell.h"
michael@0 14 #include "nsCSSProps.h"
michael@0 15 #include "mozilla/dom/Element.h"
michael@0 16
michael@0 17 // Callback function, for freeing string buffers stored in property table
michael@0 18 static void
michael@0 19 ReleaseStringBufferPropertyValue(void* aObject, /* unused */
michael@0 20 nsIAtom* aPropertyName, /* unused */
michael@0 21 void* aPropertyValue,
michael@0 22 void* aData /* unused */)
michael@0 23 {
michael@0 24 nsStringBuffer* buf = static_cast<nsStringBuffer*>(aPropertyValue);
michael@0 25 buf->Release();
michael@0 26 }
michael@0 27
michael@0 28
michael@0 29 nsresult
michael@0 30 nsSMILMappedAttribute::ValueFromString(const nsAString& aStr,
michael@0 31 const mozilla::dom::SVGAnimationElement* aSrcElement,
michael@0 32 nsSMILValue& aValue,
michael@0 33 bool& aPreventCachingOfSandwich) const
michael@0 34 {
michael@0 35 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
michael@0 36
michael@0 37 nsSMILCSSValueType::ValueFromString(mPropID, mElement, aStr, aValue,
michael@0 38 &aPreventCachingOfSandwich);
michael@0 39 return aValue.IsNull() ? NS_ERROR_FAILURE : NS_OK;
michael@0 40 }
michael@0 41
michael@0 42 nsSMILValue
michael@0 43 nsSMILMappedAttribute::GetBaseValue() const
michael@0 44 {
michael@0 45 nsAutoString baseStringValue;
michael@0 46 nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
michael@0 47 bool success = mElement->GetAttr(kNameSpaceID_None, attrName,
michael@0 48 baseStringValue);
michael@0 49 nsSMILValue baseValue;
michael@0 50 if (success) {
michael@0 51 // For base values, we don't need to worry whether the value returned is
michael@0 52 // context-sensitive or not since the compositor will take care of comparing
michael@0 53 // the returned (computed) base value and its cached value and determining
michael@0 54 // if an update is required or not.
michael@0 55 nsSMILCSSValueType::ValueFromString(mPropID, mElement,
michael@0 56 baseStringValue, baseValue, nullptr);
michael@0 57 } else {
michael@0 58 // Attribute is unset -- use computed value.
michael@0 59 // FIRST: Temporarily clear animated value, to make sure it doesn't pollute
michael@0 60 // the computed value. (We want base value, _without_ animations applied.)
michael@0 61 void* buf = mElement->UnsetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
michael@0 62 attrName, nullptr);
michael@0 63 FlushChangesToTargetAttr();
michael@0 64
michael@0 65 // SECOND: we use nsSMILCSSProperty::GetBaseValue to look up the property's
michael@0 66 // computed value. NOTE: This call will temporarily clear the SMIL
michael@0 67 // override-style for the corresponding CSS property on our target element.
michael@0 68 // This prevents any animations that target the CSS property from affecting
michael@0 69 // animations that target the mapped attribute.
michael@0 70 baseValue = nsSMILCSSProperty::GetBaseValue();
michael@0 71
michael@0 72 // FINALLY: If we originally had an animated value set, then set it again.
michael@0 73 if (buf) {
michael@0 74 mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName, buf,
michael@0 75 ReleaseStringBufferPropertyValue);
michael@0 76 FlushChangesToTargetAttr();
michael@0 77 }
michael@0 78 }
michael@0 79 return baseValue;
michael@0 80 }
michael@0 81
michael@0 82 nsresult
michael@0 83 nsSMILMappedAttribute::SetAnimValue(const nsSMILValue& aValue)
michael@0 84 {
michael@0 85 NS_ENSURE_TRUE(IsPropertyAnimatable(mPropID), NS_ERROR_FAILURE);
michael@0 86
michael@0 87 // Convert nsSMILValue to string
michael@0 88 nsAutoString valStr;
michael@0 89 if (!nsSMILCSSValueType::ValueToString(aValue, valStr)) {
michael@0 90 NS_WARNING("Failed to convert nsSMILValue for mapped attr into a string");
michael@0 91 return NS_ERROR_FAILURE;
michael@0 92 }
michael@0 93
michael@0 94 nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
michael@0 95 nsStringBuffer* oldValStrBuf = static_cast<nsStringBuffer*>
michael@0 96 (mElement->GetProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName));
michael@0 97 if (oldValStrBuf) {
michael@0 98 nsString oldValStr;
michael@0 99 nsContentUtils::PopulateStringFromStringBuffer(oldValStrBuf, oldValStr);
michael@0 100 if (valStr.Equals(oldValStr)) {
michael@0 101 // New animated value is the same as the old; nothing to do.
michael@0 102 return NS_OK;
michael@0 103 }
michael@0 104 }
michael@0 105
michael@0 106 // Set the string as this mapped attribute's animated value.
michael@0 107 nsStringBuffer* valStrBuf =
michael@0 108 nsCSSValue::BufferFromString(nsString(valStr)).take();
michael@0 109 nsresult rv = mElement->SetProperty(SMIL_MAPPED_ATTR_ANIMVAL,
michael@0 110 attrName, valStrBuf,
michael@0 111 ReleaseStringBufferPropertyValue);
michael@0 112 if (rv == NS_PROPTABLE_PROP_OVERWRITTEN) {
michael@0 113 rv = NS_OK;
michael@0 114 }
michael@0 115 FlushChangesToTargetAttr();
michael@0 116
michael@0 117 return rv;
michael@0 118 }
michael@0 119
michael@0 120 void
michael@0 121 nsSMILMappedAttribute::ClearAnimValue()
michael@0 122 {
michael@0 123 nsRefPtr<nsIAtom> attrName = GetAttrNameAtom();
michael@0 124 mElement->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL, attrName);
michael@0 125 FlushChangesToTargetAttr();
michael@0 126 }
michael@0 127
michael@0 128 void
michael@0 129 nsSMILMappedAttribute::FlushChangesToTargetAttr() const
michael@0 130 {
michael@0 131 // Clear animated content-style-rule
michael@0 132 mElement->DeleteProperty(SMIL_MAPPED_ATTR_ANIMVAL,
michael@0 133 SMIL_MAPPED_ATTR_STYLERULE_ATOM);
michael@0 134 nsIDocument* doc = mElement->GetCurrentDoc();
michael@0 135
michael@0 136 // Request animation restyle
michael@0 137 if (doc) {
michael@0 138 nsIPresShell* shell = doc->GetShell();
michael@0 139 if (shell) {
michael@0 140 shell->RestyleForAnimation(mElement, eRestyle_Self);
michael@0 141 }
michael@0 142 }
michael@0 143 }
michael@0 144
michael@0 145 already_AddRefed<nsIAtom>
michael@0 146 nsSMILMappedAttribute::GetAttrNameAtom() const
michael@0 147 {
michael@0 148 return do_GetAtom(nsCSSProps::GetStringValue(mPropID));
michael@0 149 }

mercurial