summaryrefslogtreecommitdiffstats
path: root/layout
diff options
context:
space:
mode:
authorwolfbeast <mcwerewolf@wolfbeast.com>2019-08-23 01:43:12 +0200
committerwolfbeast <mcwerewolf@wolfbeast.com>2019-08-23 01:43:12 +0200
commitdd33cb382321351aa3b960a6824cb9ec43bba05b (patch)
tree729b4065b2a1c849d1fb6ad28b7e0c510f1a6a67 /layout
parent6a6e4bd25d61ecf21a28ea47f2a74927553fe959 (diff)
parentab6242a93b849b0a3c7525b16bc01dd3172fc167 (diff)
downloadUXP-dd33cb382321351aa3b960a6824cb9ec43bba05b.tar
UXP-dd33cb382321351aa3b960a6824cb9ec43bba05b.tar.gz
UXP-dd33cb382321351aa3b960a6824cb9ec43bba05b.tar.lz
UXP-dd33cb382321351aa3b960a6824cb9ec43bba05b.tar.xz
UXP-dd33cb382321351aa3b960a6824cb9ec43bba05b.zip
Merge branch 'master' into Pale_Moon-release
Diffstat (limited to 'layout')
-rw-r--r--layout/base/ActiveLayerTracker.cpp15
-rw-r--r--layout/base/FrameLayerBuilder.cpp41
-rw-r--r--layout/base/FrameProperties.h (renamed from layout/base/FramePropertyTable.h)298
-rw-r--r--layout/base/FramePropertyTable.cpp239
-rw-r--r--layout/base/OverflowChangedTracker.h4
-rw-r--r--layout/base/RestyleManager.cpp10
-rw-r--r--layout/base/RestyleManagerBase.cpp88
-rw-r--r--layout/base/RestyleManagerBase.h13
-rw-r--r--layout/base/moz.build3
-rw-r--r--layout/base/nsBidiPresUtils.cpp5
-rw-r--r--layout/base/nsCSSFrameConstructor.cpp23
-rw-r--r--layout/base/nsCSSRendering.cpp10
-rw-r--r--layout/base/nsDisplayList.cpp49
-rw-r--r--layout/base/nsDisplayList.h2
-rw-r--r--layout/base/nsIPresShell.h11
-rw-r--r--layout/base/nsLayoutUtils.cpp16
-rw-r--r--layout/base/nsPresContext.cpp3
-rw-r--r--layout/base/nsPresContext.h11
-rw-r--r--layout/base/nsPresShell.cpp35
-rw-r--r--layout/base/nsPresShell.h11
-rw-r--r--layout/build/moz.build1
-rw-r--r--layout/build/nsLayoutModule.cpp9
-rw-r--r--layout/forms/nsTextControlFrame.cpp14
-rw-r--r--layout/forms/nsTextControlFrame.h2
-rw-r--r--layout/generic/ReflowInput.cpp36
-rw-r--r--layout/generic/RubyUtils.cpp6
-rw-r--r--layout/generic/StickyScrollContainer.cpp26
-rw-r--r--layout/generic/nsBlockFrame.cpp58
-rw-r--r--layout/generic/nsBlockFrame.h4
-rw-r--r--layout/generic/nsBulletFrame.cpp6
-rw-r--r--layout/generic/nsCanvasFrame.cpp4
-rw-r--r--layout/generic/nsCanvasFrame.h2
-rw-r--r--layout/generic/nsContainerFrame.cpp141
-rw-r--r--layout/generic/nsContainerFrame.h10
-rw-r--r--layout/generic/nsFlexContainerFrame.cpp22
-rw-r--r--layout/generic/nsFloatManager.cpp9
-rw-r--r--layout/generic/nsFontInflationData.cpp12
-rw-r--r--layout/generic/nsFrame.cpp177
-rw-r--r--layout/generic/nsGridContainerFrame.cpp80
-rw-r--r--layout/generic/nsGridContainerFrame.h12
-rw-r--r--layout/generic/nsIFrame.h77
-rw-r--r--layout/generic/nsLineLayout.cpp4
-rw-r--r--layout/generic/nsPlaceholderFrame.cpp2
-rw-r--r--layout/generic/nsTextFrame.cpp59
-rw-r--r--layout/mathml/nsMathMLContainerFrame.cpp7
-rw-r--r--layout/mathml/nsMathMLmtableFrame.cpp14
-rw-r--r--layout/reftests/svg/css-transform-svg-ref.html10
-rw-r--r--layout/reftests/svg/css-transform-svg.html13
-rw-r--r--layout/reftests/svg/reftest.list2
-rw-r--r--layout/reftests/svg/svg-blurry-with-subpixel-position-ref.html13
-rw-r--r--layout/reftests/svg/svg-blurry-with-subpixel-position.html13
-rw-r--r--layout/style/FontFaceSet.cpp15
-rw-r--r--layout/svg/SVGTextFrame.cpp10
-rw-r--r--layout/svg/nsSVGEffects.cpp47
-rw-r--r--layout/svg/nsSVGEffects.h2
-rw-r--r--layout/svg/nsSVGFilterFrame.cpp4
-rw-r--r--layout/svg/nsSVGGradientFrame.cpp4
-rw-r--r--layout/svg/nsSVGIntegrationUtils.cpp5
-rw-r--r--layout/svg/nsSVGOuterSVGFrame.cpp53
-rw-r--r--layout/svg/nsSVGPatternFrame.cpp4
-rw-r--r--layout/svg/nsSVGUtils.cpp5
-rw-r--r--layout/tables/nsTableFrame.cpp31
-rw-r--r--layout/tables/nsTableFrame.h3
-rw-r--r--layout/tables/nsTableRowFrame.cpp10
-rw-r--r--layout/tables/nsTableRowGroupFrame.cpp6
-rw-r--r--layout/tables/nsTableWrapperFrame.cpp4
-rw-r--r--layout/xul/nsBox.cpp7
-rw-r--r--layout/xul/nsMenuFrame.cpp6
68 files changed, 938 insertions, 1010 deletions
diff --git a/layout/base/ActiveLayerTracker.cpp b/layout/base/ActiveLayerTracker.cpp
index 4f60f82d7..ecee4897a 100644
--- a/layout/base/ActiveLayerTracker.cpp
+++ b/layout/base/ActiveLayerTracker.cpp
@@ -178,7 +178,7 @@ LayerActivityTracker::NotifyExpired(LayerActivity* aObject)
f->SchedulePaint();
}
f->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
- f->Properties().Delete(LayerActivityProperty());
+ f->DeleteProperty(LayerActivityProperty());
} else {
c->DeleteProperty(nsGkAtoms::LayerActivity);
}
@@ -190,15 +190,13 @@ GetLayerActivity(nsIFrame* aFrame)
if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
return nullptr;
}
- FrameProperties properties = aFrame->Properties();
- return properties.Get(LayerActivityProperty());
+ return aFrame->GetProperty(LayerActivityProperty());
}
static LayerActivity*
GetLayerActivityForUpdate(nsIFrame* aFrame)
{
- FrameProperties properties = aFrame->Properties();
- LayerActivity* layerActivity = properties.Get(LayerActivityProperty());
+ LayerActivity* layerActivity = aFrame->GetProperty(LayerActivityProperty());
if (layerActivity) {
gLayerActivityTracker->MarkUsed(layerActivity);
} else {
@@ -208,7 +206,7 @@ GetLayerActivityForUpdate(nsIFrame* aFrame)
layerActivity = new LayerActivity(aFrame);
gLayerActivityTracker->AddObject(layerActivity);
aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
- properties.Set(LayerActivityProperty(), layerActivity);
+ aFrame->SetProperty(LayerActivityProperty(), layerActivity);
}
return layerActivity;
}
@@ -225,8 +223,7 @@ ActiveLayerTracker::TransferActivityToContent(nsIFrame* aFrame, nsIContent* aCon
if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
return;
}
- FrameProperties properties = aFrame->Properties();
- LayerActivity* layerActivity = properties.Remove(LayerActivityProperty());
+ LayerActivity* layerActivity = aFrame->RemoveProperty(LayerActivityProperty());
aFrame->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
if (!layerActivity) {
return;
@@ -248,7 +245,7 @@ ActiveLayerTracker::TransferActivityToFrame(nsIContent* aContent, nsIFrame* aFra
layerActivity->mContent = nullptr;
layerActivity->mFrame = aFrame;
aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
- aFrame->Properties().Set(LayerActivityProperty(), layerActivity);
+ aFrame->SetProperty(LayerActivityProperty(), layerActivity);
}
static void
diff --git a/layout/base/FrameLayerBuilder.cpp b/layout/base/FrameLayerBuilder.cpp
index 9aaa28fb5..934d108e0 100644
--- a/layout/base/FrameLayerBuilder.cpp
+++ b/layout/base/FrameLayerBuilder.cpp
@@ -165,10 +165,10 @@ FrameLayerBuilder::DisplayItemData::AddFrame(nsIFrame* aFrame)
mFrameList.AppendElement(aFrame);
nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(FrameLayerBuilder::LayerManagerDataProperty());
+ aFrame->GetProperty(FrameLayerBuilder::LayerManagerDataProperty());
if (!array) {
array = new nsTArray<DisplayItemData*>();
- aFrame->Properties().Set(FrameLayerBuilder::LayerManagerDataProperty(), array);
+ aFrame->SetProperty(FrameLayerBuilder::LayerManagerDataProperty(), array);
}
array->AppendElement(this);
}
@@ -181,7 +181,7 @@ FrameLayerBuilder::DisplayItemData::RemoveFrame(nsIFrame* aFrame)
MOZ_RELEASE_ASSERT(result, "Can't remove a frame that wasn't added!");
nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(FrameLayerBuilder::LayerManagerDataProperty());
+ aFrame->GetProperty(FrameLayerBuilder::LayerManagerDataProperty());
MOZ_RELEASE_ASSERT(array, "Must be already stored on the frame!");
array->RemoveElement(this);
}
@@ -268,12 +268,17 @@ FrameLayerBuilder::DisplayItemData::~DisplayItemData()
continue;
}
nsTArray<DisplayItemData*> *array =
- reinterpret_cast<nsTArray<DisplayItemData*>*>(frame->Properties().Get(LayerManagerDataProperty()));
+ reinterpret_cast<nsTArray<DisplayItemData*>*>(frame->GetProperty(LayerManagerDataProperty()));
array->RemoveElement(this);
}
- MOZ_RELEASE_ASSERT(sAliveDisplayItemDatas && sAliveDisplayItemDatas->Contains(this));
- sAliveDisplayItemDatas->RemoveEntry(this);
+ MOZ_RELEASE_ASSERT(sAliveDisplayItemDatas);
+ nsPtrHashKey<mozilla::FrameLayerBuilder::DisplayItemData>* entry
+ = sAliveDisplayItemDatas->GetEntry(this);
+ MOZ_RELEASE_ASSERT(entry);
+
+ sAliveDisplayItemDatas->RemoveEntry(entry);
+
if (sAliveDisplayItemDatas->Count() == 0) {
delete sAliveDisplayItemDatas;
sAliveDisplayItemDatas = nullptr;
@@ -390,8 +395,7 @@ public:
/* static */ void
FrameLayerBuilder::DestroyDisplayItemDataFor(nsIFrame* aFrame)
{
- FrameProperties props = aFrame->Properties();
- props.Delete(LayerManagerDataProperty());
+ aFrame->DeleteProperty(LayerManagerDataProperty());
}
struct AssignedDisplayItem
@@ -1823,7 +1827,7 @@ FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey)
{
const nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(LayerManagerDataProperty());
+ aFrame->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
@@ -2052,7 +2056,7 @@ FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem,
LayerManager* aManager)
{
const nsTArray<DisplayItemData*>* array =
- aItem->Frame()->Properties().Get(LayerManagerDataProperty());
+ aItem->Frame()->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
@@ -2069,7 +2073,7 @@ bool
FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
{
const nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(LayerManagerDataProperty());
+ aFrame->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
if (AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) {
@@ -2084,7 +2088,7 @@ void
FrameLayerBuilder::IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback)
{
const nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(LayerManagerDataProperty());
+ aFrame->GetProperty(LayerManagerDataProperty());
if (!array) {
return;
}
@@ -2151,7 +2155,7 @@ FrameLayerBuilder::ClearCachedGeometry(nsDisplayItem* aItem)
FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
{
const nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(LayerManagerDataProperty());
+ aFrame->GetProperty(LayerManagerDataProperty());
if (!array) {
return nullptr;
@@ -2171,7 +2175,7 @@ FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKe
FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(nsIFrame* aFrame)
{
const nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(LayerManagerDataProperty());
+ aFrame->GetProperty(LayerManagerDataProperty());
if (!array) {
return nullptr;
@@ -5656,7 +5660,7 @@ FrameLayerBuilder::InvalidateAllLayers(LayerManager* aManager)
FrameLayerBuilder::InvalidateAllLayersForFrame(nsIFrame *aFrame)
{
const nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(LayerManagerDataProperty());
+ aFrame->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
AssertDisplayItemData(array->ElementAt(i))->mParent->mInvalidateAllLayers = true;
@@ -5673,7 +5677,7 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey)
// in the secondary manager
const nsTArray<DisplayItemData*>* array =
- aFrame->Properties().Get(LayerManagerDataProperty());
+ aFrame->GetProperty(LayerManagerDataProperty());
if (array) {
for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData *element = AssertDisplayItemData(array->ElementAt(i));
@@ -5729,7 +5733,7 @@ FrameLayerBuilder::GetPaintedLayerScaleForFrame(nsIFrame* aFrame)
}
const nsTArray<DisplayItemData*>* array =
- f->Properties().Get(LayerManagerDataProperty());
+ f->GetProperty(LayerManagerDataProperty());
if (!array) {
continue;
}
@@ -6165,9 +6169,8 @@ FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem)
typedef nsTArray<DisplayItemData*> DataArray;
// Retrieve the array of DisplayItemData associated with our frame.
- FrameProperties properties = aItem->Frame()->Properties();
const DataArray* dataArray =
- properties.Get(LayerManagerDataProperty());
+ aItem->Frame()->GetProperty(LayerManagerDataProperty());
if (!dataArray) {
return nullptr;
}
diff --git a/layout/base/FramePropertyTable.h b/layout/base/FrameProperties.h
index e9847efbf..3884b07bd 100644
--- a/layout/base/FramePropertyTable.h
+++ b/layout/base/FrameProperties.h
@@ -3,15 +3,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef FRAMEPROPERTYTABLE_H_
-#define FRAMEPROPERTYTABLE_H_
+#ifndef FRAMEPROPERTIES_H_
+#define FRAMEPROPERTIES_H_
+#include "mozilla/DebugOnly.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/TypeTraits.h"
#include "mozilla/Unused.h"
#include "nsTArray.h"
-#include "nsTHashtable.h"
-#include "nsHashKeys.h"
+#include "nsThreadUtils.h"
class nsIFrame;
@@ -62,7 +62,7 @@ protected:
*
* To use this class, declare a global (i.e., file, class or function-scope
* static member) FramePropertyDescriptor and pass its address as
- * aProperty in the FramePropertyTable methods.
+ * aProperty in the FrameProperties methods.
*/
template<typename T>
struct FramePropertyDescriptor : public FramePropertyDescriptorUntyped
@@ -131,7 +131,7 @@ struct FramePropertyTypeHelper<SmallValueHolder<T>>
}
/**
- * The FramePropertyTable is optimized for storing 0 or 1 properties on
+ * The FrameProperties class is optimized for storing 0 or 1 properties on
* a given frame. Storing very large numbers of properties on a single
* frame will not be efficient.
*
@@ -141,7 +141,8 @@ struct FramePropertyTypeHelper<SmallValueHolder<T>>
* Of course, the destructor function (if any) must handle such values
* correctly.
*/
-class FramePropertyTable {
+class FrameProperties
+{
public:
template<typename T>
using Descriptor = const FramePropertyDescriptor<T>*;
@@ -150,32 +151,36 @@ public:
template<typename T>
using PropertyType = typename detail::FramePropertyTypeHelper<T>::Type;
- FramePropertyTable() : mLastFrame(nullptr), mLastEntry(nullptr)
+ explicit FrameProperties()
{
}
- ~FramePropertyTable()
+
+ ~FrameProperties()
{
- DeleteAll();
+ MOZ_ASSERT(mProperties.Length() == 0, "forgot to delete properties");
}
/**
- * Set a property value on a frame. This requires one hashtable
- * lookup (using the frame as the key) and a linear search through
- * the properties of that frame. Any existing value for the property
+ * Return true if we have no properties, otherwise return false.
+ */
+ bool IsEmpty() const { return mProperties.IsEmpty(); }
+
+ /**
+ * Set a property value. This requires a linear search through
+ * the properties of the frame. Any existing value for the property
* is destroyed.
*/
template<typename T>
- void Set(const nsIFrame* aFrame, Descriptor<T> aProperty,
- PropertyType<T> aValue)
+ void Set(Descriptor<T> aProperty, PropertyType<T> aValue,
+ const nsIFrame* aFrame)
{
void* ptr = ReinterpretHelper<T>::ToPointer(aValue);
- SetInternal(aFrame, aProperty, ptr);
+ SetInternal(aProperty, ptr, aFrame);
}
/**
- * @return true if @aProperty is set for @aFrame. This requires one hashtable
- * lookup (using the frame as the key) and a linear search through the
- * properties of that frame.
+ * @return true if @aProperty is set. This requires a linear search through the
+ * properties of the frame.
*
* In most cases, this shouldn't be used outside of assertions, because if
* you're doing a lookup anyway it would be far more efficient to call Get()
@@ -190,17 +195,14 @@ public:
* an existing value for the frame property.
*/
template<typename T>
- bool Has(const nsIFrame* aFrame, Descriptor<T> aProperty)
+ bool Has(Descriptor<T> aProperty) const
{
- bool foundResult = false;
- mozilla::Unused << GetInternal(aFrame, aProperty, &foundResult);
- return foundResult;
+ return mProperties.IndexOf(aProperty, 0, PropertyComparator()) != nsTArray<PropertyValue>::NoIndex;
}
/**
- * Get a property value for a frame. This requires one hashtable
- * lookup (using the frame as the key) and a linear search through
- * the properties of that frame. If the frame has no such property,
+ * Get a property value. This requires a linear search through
+ * the properties of the frame. If the frame has no such property,
* returns zero-filled result, which means null for pointers and
* zero for integers and floating point types.
* @param aFoundResult if non-null, receives a value 'true' iff
@@ -209,16 +211,15 @@ public:
* 'property value is null'.
*/
template<typename T>
- PropertyType<T> Get(const nsIFrame* aFrame, Descriptor<T> aProperty,
- bool* aFoundResult = nullptr)
+ PropertyType<T> Get(Descriptor<T> aProperty,
+ bool* aFoundResult = nullptr) const
{
- void* ptr = GetInternal(aFrame, aProperty, aFoundResult);
+ void* ptr = GetInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr);
}
/**
- * Remove a property value for a frame. This requires one hashtable
- * lookup (using the frame as the key) and a linear search through
- * the properties of that frame. The old property value is returned
+ * Remove a property value. This requires a linear search through
+ * the properties of the frame. The old property value is returned
* (and not destroyed). If the frame has no such property,
* returns zero-filled result, which means null for pointers and
* zero for integers and floating point types.
@@ -228,46 +229,85 @@ public:
* 'property value is null'.
*/
template<typename T>
- PropertyType<T> Remove(const nsIFrame* aFrame, Descriptor<T> aProperty,
+ PropertyType<T> Remove(Descriptor<T> aProperty,
bool* aFoundResult = nullptr)
{
- void* ptr = RemoveInternal(aFrame, aProperty, aFoundResult);
+ void* ptr = RemoveInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr);
}
/**
- * Remove and destroy a property value for a frame. This requires one
- * hashtable lookup (using the frame as the key) and a linear search
- * through the properties of that frame. If the frame has no such
+ * Remove and destroy a property value. This requires a linear search
+ * through the properties of the frame. If the frame has no such
* property, nothing happens.
*/
template<typename T>
- void Delete(const nsIFrame* aFrame, Descriptor<T> aProperty)
+ void Delete(Descriptor<T> aProperty, const nsIFrame* aFrame)
{
- DeleteInternal(aFrame, aProperty);
+ DeleteInternal(aProperty, aFrame);
}
+
/**
- * Remove and destroy all property values for a frame. This requires one
- * hashtable lookup (using the frame as the key).
+ * Call @aFunction for each property or until @aFunction returns false.
*/
- void DeleteAllFor(const nsIFrame* aFrame);
+ template<class F>
+ void ForEach(F aFunction) const
+ {
+#ifdef DEBUG
+ size_t len = mProperties.Length();
+#endif
+ for (const auto& prop : mProperties) {
+ bool shouldContinue = aFunction(prop.mProperty, prop.mValue);
+#ifdef DEBUG
+ MOZ_ASSERT(len == mProperties.Length(),
+ "frame property list was modified by ForEach callback!");
+#endif
+ if (!shouldContinue) {
+ return;
+ }
+ }
+ }
+
/**
- * Remove and destroy all property values for all frames.
+ * Remove and destroy all property values for the frame.
*/
- void DeleteAll();
+ void DeleteAll(const nsIFrame* aFrame) {
+ mozilla::DebugOnly<size_t> len = mProperties.Length();
+ for (auto& prop : mProperties) {
+ prop.DestroyValueFor(aFrame);
+ MOZ_ASSERT(mProperties.Length() == len);
+ }
+ mProperties.Clear();
+ }
- size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
+ size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
+ // We currently report only the shallow size of the mProperties array.
+ // As for the PropertyValue entries: we don't need to measure the mProperty
+ // field of because it always points to static memory, and we can't measure
+ // mValue because the type is opaque.
+ // XXX Can we do better, e.g. with a method on the descriptor?
+ return mProperties.ShallowSizeOfExcludingThis(aMallocSizeOf);
+ }
-protected:
- void SetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
- void* aValue);
+private:
+ friend class ::nsIFrame;
- void* GetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
- bool* aFoundResult);
+ // Prevent copying of FrameProperties; we should always return/pass around
+ // references to it, not copies!
+ FrameProperties(const FrameProperties&) = delete;
+ FrameProperties& operator=(const FrameProperties&) = delete;
- void* RemoveInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty,
- bool* aFoundResult);
+ inline void
+ SetInternal(UntypedDescriptor aProperty, void* aValue,
+ const nsIFrame* aFrame);
- void DeleteInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty);
+ inline void*
+ GetInternal(UntypedDescriptor aProperty, bool* aFoundResult) const;
+
+ inline void*
+ RemoveInternal(UntypedDescriptor aProperty, bool* aFoundResult);
+
+ inline void
+ DeleteInternal(UntypedDescriptor aProperty, const nsIFrame* aFrame);
template<typename T>
struct ReinterpretHelper
@@ -305,21 +345,13 @@ protected:
};
/**
- * Stores a property descriptor/value pair. It can also be used to
- * store an nsTArray of PropertyValues.
+ * Stores a property descriptor/value pair.
*/
struct PropertyValue {
PropertyValue() : mProperty(nullptr), mValue(nullptr) {}
PropertyValue(UntypedDescriptor aProperty, void* aValue)
: mProperty(aProperty), mValue(aValue) {}
- bool IsArray() { return !mProperty && mValue; }
- nsTArray<PropertyValue>* ToArray()
- {
- NS_ASSERTION(IsArray(), "Must be array");
- return reinterpret_cast<nsTArray<PropertyValue>*>(&mValue);
- }
-
void DestroyValueFor(const nsIFrame* aFrame) {
if (mProperty->mDestructor) {
mProperty->mDestructor(mValue);
@@ -328,20 +360,6 @@ protected:
}
}
- size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) {
- size_t n = 0;
- // We don't need to measure mProperty because it always points to static
- // memory. As for mValue: if it's a single value we can't measure it,
- // because the type is opaque; if it's an array, we measure the array
- // storage, but we can't measure the individual values, again because
- // their types are opaque.
- if (IsArray()) {
- nsTArray<PropertyValue>* array = ToArray();
- n += array->ShallowSizeOfExcludingThis(aMallocSizeOf);
- }
- return n;
- }
-
UntypedDescriptor mProperty;
void* mValue;
};
@@ -363,80 +381,86 @@ protected:
}
};
- /**
- * Our hashtable entry. The key is an nsIFrame*, the value is a
- * PropertyValue representing one or more property/value pairs.
- */
- class Entry : public nsPtrHashKey<const nsIFrame>
- {
- public:
- explicit Entry(KeyTypePointer aKey) : nsPtrHashKey<const nsIFrame>(aKey) {}
- Entry(const Entry &toCopy) :
- nsPtrHashKey<const nsIFrame>(toCopy), mProp(toCopy.mProp) {}
-
- size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) {
- return mProp.SizeOfExcludingThis(aMallocSizeOf);
- }
-
- PropertyValue mProp;
- };
-
- static void DeleteAllForEntry(Entry* aEntry);
-
- // Note that mLastEntry points into mEntries, so we need to be careful about
- // not triggering a resize of mEntries, e.g. use RawRemoveEntry() instead of
- // RemoveEntry() in some places.
- nsTHashtable<Entry> mEntries;
- const nsIFrame* mLastFrame;
- Entry* mLastEntry;
+ nsTArray<PropertyValue> mProperties;
};
/**
* This class encapsulates the properties of a frame.
*/
-class FrameProperties {
-public:
- template<typename T> using Descriptor = FramePropertyTable::Descriptor<T>;
- template<typename T> using PropertyType = FramePropertyTable::PropertyType<T>;
-
- FrameProperties(FramePropertyTable* aTable, const nsIFrame* aFrame)
- : mTable(aTable), mFrame(aFrame) {}
+inline void*
+FrameProperties::GetInternal(UntypedDescriptor aProperty,
+ bool* aFoundResult) const
+{
+ MOZ_ASSERT(aProperty, "Null property?");
- template<typename T>
- void Set(Descriptor<T> aProperty, PropertyType<T> aValue) const
- {
- mTable->Set(mFrame, aProperty, aValue);
+ auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
+ if (index == nsTArray<PropertyValue>::NoIndex) {
+ if (aFoundResult) {
+ *aFoundResult = false;
+ }
+ return nullptr;
}
- template<typename T>
- bool Has(Descriptor<T> aProperty) const
- {
- return mTable->Has(mFrame, aProperty);
+ if (aFoundResult) {
+ *aFoundResult = true;
}
- template<typename T>
- PropertyType<T> Get(Descriptor<T> aProperty,
- bool* aFoundResult = nullptr) const
- {
- return mTable->Get(mFrame, aProperty, aFoundResult);
- }
- template<typename T>
- PropertyType<T> Remove(Descriptor<T> aProperty,
- bool* aFoundResult = nullptr) const
- {
- return mTable->Remove(mFrame, aProperty, aFoundResult);
+return mProperties.ElementAt(index).mValue;
+}
+
+inline void
+FrameProperties::SetInternal(UntypedDescriptor aProperty, void* aValue,
+ const nsIFrame* aFrame)
+{
+ MOZ_ASSERT(aProperty, "Null property?");
+
+ auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
+ if (index != nsTArray<PropertyValue>::NoIndex) {
+ PropertyValue* pv = &mProperties.ElementAt(index);
+ pv->DestroyValueFor(aFrame);
+ pv->mValue = aValue;
+ return;
}
- template<typename T>
- void Delete(Descriptor<T> aProperty)
- {
- mTable->Delete(mFrame, aProperty);
+
+ mProperties.AppendElement(PropertyValue(aProperty, aValue));
+}
+
+inline void*
+FrameProperties::RemoveInternal(UntypedDescriptor aProperty, bool* aFoundResult)
+{
+ MOZ_ASSERT(aProperty, "Null property?");
+
+ auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
+ if (index == nsTArray<PropertyValue>::NoIndex) {
+ if (aFoundResult) {
+ *aFoundResult = false;
+ }
+ return nullptr;
}
-private:
- FramePropertyTable* mTable;
- const nsIFrame* mFrame;
-};
+if (aFoundResult) {
+ *aFoundResult = true;
+}
+
+void* result = mProperties.ElementAt(index).mValue;
+mProperties.RemoveElementAt(index);
+
+return result;
+}
+
+inline void
+FrameProperties::DeleteInternal(UntypedDescriptor aProperty,
+ const nsIFrame* aFrame)
+{
+ MOZ_ASSERT(aProperty, "Null property?");
+
+ auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
+ if (index != nsTArray<PropertyValue>::NoIndex) {
+ mProperties.ElementAt(index).DestroyValueFor(aFrame);
+ mProperties.RemoveElementAt(index);
+ }
+}
} // namespace mozilla
-#endif /* FRAMEPROPERTYTABLE_H_ */
+#endif /* FRAMEPROPERTIES_H_ */
diff --git a/layout/base/FramePropertyTable.cpp b/layout/base/FramePropertyTable.cpp
deleted file mode 100644
index 0fd9b1c37..000000000
--- a/layout/base/FramePropertyTable.cpp
+++ /dev/null
@@ -1,239 +0,0 @@
-/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-#include "FramePropertyTable.h"
-
-#include "mozilla/MemoryReporting.h"
-
-namespace mozilla {
-
-void
-FramePropertyTable::SetInternal(
- const nsIFrame* aFrame, UntypedDescriptor aProperty, void* aValue)
-{
- NS_ASSERTION(aFrame, "Null frame?");
- NS_ASSERTION(aProperty, "Null property?");
-
- if (mLastFrame != aFrame || !mLastEntry) {
- mLastFrame = aFrame;
- mLastEntry = mEntries.PutEntry(aFrame);
- }
- Entry* entry = mLastEntry;
-
- if (!entry->mProp.IsArray()) {
- if (!entry->mProp.mProperty) {
- // Empty entry, so we can just store our property in the empty slot
- entry->mProp.mProperty = aProperty;
- entry->mProp.mValue = aValue;
- return;
- }
- if (entry->mProp.mProperty == aProperty) {
- // Just overwrite the current value
- entry->mProp.DestroyValueFor(aFrame);
- entry->mProp.mValue = aValue;
- return;
- }
-
- // We need to expand the single current entry to an array
- PropertyValue current = entry->mProp;
- entry->mProp.mProperty = nullptr;
- static_assert(sizeof(nsTArray<PropertyValue>) <= sizeof(void *),
- "Property array must fit entirely within entry->mProp.mValue");
- new (&entry->mProp.mValue) nsTArray<PropertyValue>(4);
- entry->mProp.ToArray()->AppendElement(current);
- }
-
- nsTArray<PropertyValue>* array = entry->mProp.ToArray();
- nsTArray<PropertyValue>::index_type index =
- array->IndexOf(aProperty, 0, PropertyComparator());
- if (index != nsTArray<PropertyValue>::NoIndex) {
- PropertyValue* pv = &array->ElementAt(index);
- pv->DestroyValueFor(aFrame);
- pv->mValue = aValue;
- return;
- }
-
- array->AppendElement(PropertyValue(aProperty, aValue));
-}
-
-void*
-FramePropertyTable::GetInternal(
- const nsIFrame* aFrame, UntypedDescriptor aProperty, bool* aFoundResult)
-{
- NS_ASSERTION(aFrame, "Null frame?");
- NS_ASSERTION(aProperty, "Null property?");
-
- if (aFoundResult) {
- *aFoundResult = false;
- }
-
- if (mLastFrame != aFrame) {
- mLastFrame = aFrame;
- mLastEntry = mEntries.GetEntry(mLastFrame);
- }
- Entry* entry = mLastEntry;
- if (!entry)
- return nullptr;
-
- if (entry->mProp.mProperty == aProperty) {
- if (aFoundResult) {
- *aFoundResult = true;
- }
- return entry->mProp.mValue;
- }
- if (!entry->mProp.IsArray()) {
- // There's just one property and it's not the one we want, bail
- return nullptr;
- }
-
- nsTArray<PropertyValue>* array = entry->mProp.ToArray();
- nsTArray<PropertyValue>::index_type index =
- array->IndexOf(aProperty, 0, PropertyComparator());
- if (index == nsTArray<PropertyValue>::NoIndex)
- return nullptr;
-
- if (aFoundResult) {
- *aFoundResult = true;
- }
-
- return array->ElementAt(index).mValue;
-}
-
-void*
-FramePropertyTable::RemoveInternal(
- const nsIFrame* aFrame, UntypedDescriptor aProperty, bool* aFoundResult)
-{
- NS_ASSERTION(aFrame, "Null frame?");
- NS_ASSERTION(aProperty, "Null property?");
-
- if (aFoundResult) {
- *aFoundResult = false;
- }
-
- if (mLastFrame != aFrame) {
- mLastFrame = aFrame;
- mLastEntry = mEntries.GetEntry(aFrame);
- }
- Entry* entry = mLastEntry;
- if (!entry)
- return nullptr;
-
- if (entry->mProp.mProperty == aProperty) {
- // There's only one entry and it's the one we want
- void* value = entry->mProp.mValue;
-
- // Here it's ok to use RemoveEntry() -- which may resize mEntries --
- // because we null mLastEntry at the same time.
- mEntries.RemoveEntry(entry);
- mLastEntry = nullptr;
- if (aFoundResult) {
- *aFoundResult = true;
- }
- return value;
- }
- if (!entry->mProp.IsArray()) {
- // There's just one property and it's not the one we want, bail
- return nullptr;
- }
-
- nsTArray<PropertyValue>* array = entry->mProp.ToArray();
- nsTArray<PropertyValue>::index_type index =
- array->IndexOf(aProperty, 0, PropertyComparator());
- if (index == nsTArray<PropertyValue>::NoIndex) {
- // No such property, bail
- return nullptr;
- }
-
- if (aFoundResult) {
- *aFoundResult = true;
- }
-
- void* result = array->ElementAt(index).mValue;
-
- uint32_t last = array->Length() - 1;
- array->ElementAt(index) = array->ElementAt(last);
- array->RemoveElementAt(last);
-
- if (last == 1) {
- PropertyValue pv = array->ElementAt(0);
- array->~nsTArray<PropertyValue>();
- entry->mProp = pv;
- }
-
- return result;
-}
-
-void
-FramePropertyTable::DeleteInternal(
- const nsIFrame* aFrame, UntypedDescriptor aProperty)
-{
- NS_ASSERTION(aFrame, "Null frame?");
- NS_ASSERTION(aProperty, "Null property?");
-
- bool found;
- void* v = RemoveInternal(aFrame, aProperty, &found);
- if (found) {
- PropertyValue pv(aProperty, v);
- pv.DestroyValueFor(aFrame);
- }
-}
-
-/* static */ void
-FramePropertyTable::DeleteAllForEntry(Entry* aEntry)
-{
- if (!aEntry->mProp.IsArray()) {
- aEntry->mProp.DestroyValueFor(aEntry->GetKey());
- return;
- }
-
- nsTArray<PropertyValue>* array = aEntry->mProp.ToArray();
- for (uint32_t i = 0; i < array->Length(); ++i) {
- array->ElementAt(i).DestroyValueFor(aEntry->GetKey());
- }
- array->~nsTArray<PropertyValue>();
-}
-
-void
-FramePropertyTable::DeleteAllFor(const nsIFrame* aFrame)
-{
- NS_ASSERTION(aFrame, "Null frame?");
-
- Entry* entry = mEntries.GetEntry(aFrame);
- if (!entry)
- return;
-
- if (mLastFrame == aFrame) {
- // Flush cache. We assume DeleteAllForEntry will be called before
- // a frame is destroyed.
- mLastFrame = nullptr;
- mLastEntry = nullptr;
- }
-
- DeleteAllForEntry(entry);
-
- // mLastEntry points into mEntries, so we use RawRemoveEntry() which will not
- // resize mEntries.
- mEntries.RawRemoveEntry(entry);
-}
-
-void
-FramePropertyTable::DeleteAll()
-{
- mLastFrame = nullptr;
- mLastEntry = nullptr;
-
- for (auto iter = mEntries.Iter(); !iter.Done(); iter.Next()) {
- DeleteAllForEntry(iter.Get());
- }
- mEntries.Clear();
-}
-
-size_t
-FramePropertyTable::SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
-{
- return mEntries.SizeOfExcludingThis(aMallocSizeOf);
-}
-
-} // namespace mozilla
diff --git a/layout/base/OverflowChangedTracker.h b/layout/base/OverflowChangedTracker.h
index a18d64b46..40145c65c 100644
--- a/layout/base/OverflowChangedTracker.h
+++ b/layout/base/OverflowChangedTracker.h
@@ -112,12 +112,12 @@ public:
// Take a faster path that doesn't require unioning the overflow areas
// of our children.
- NS_ASSERTION(frame->Properties().Get(
+ NS_ASSERTION(frame->GetProperty(
nsIFrame::DebugInitialOverflowPropertyApplied()),
"InitialOverflowProperty must be set first.");
nsOverflowAreas* overflow =
- frame->Properties().Get(nsIFrame::InitialOverflowProperty());
+ frame->GetProperty(nsIFrame::InitialOverflowProperty());
if (overflow) {
// FinishAndStoreOverflow will change the overflow areas passed in,
// so make a copy.
diff --git a/layout/base/RestyleManager.cpp b/layout/base/RestyleManager.cpp
index de8f10224..124b5535e 100644
--- a/layout/base/RestyleManager.cpp
+++ b/layout/base/RestyleManager.cpp
@@ -1122,10 +1122,10 @@ GetPrevContinuationWithPossiblySameStyle(nsIFrame* aFrame)
// We're the first continuation, so we can just get the frame
// property directly
prevContinuation =
- aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling());
+ aFrame->GetProperty(nsIFrame::IBSplitPrevSibling());
if (prevContinuation) {
prevContinuation =
- prevContinuation->Properties().Get(nsIFrame::IBSplitPrevSibling());
+ prevContinuation->GetProperty(nsIFrame::IBSplitPrevSibling());
}
}
@@ -1313,8 +1313,7 @@ RestyleManager::ReparentStyleContext(nsIFrame* aFrame)
// oldContext)" check will prevent us from redoing work.
if ((aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
!aFrame->GetPrevContinuation()) {
- nsIFrame* sib =
- aFrame->Properties().Get(nsIFrame::IBSplitSibling());
+ nsIFrame* sib = aFrame->GetProperty(nsIFrame::IBSplitSibling());
if (sib) {
ReparentStyleContext(sib);
}
@@ -3349,7 +3348,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
// line), we might restyle more than that.
nsPresContext* presContext = aFrame->PresContext();
- FramePropertyTable* propTable = presContext->PropertyTable();
TreeMatchContext treeMatchContext(true,
nsRuleWalker::eRelevantLinkUnvisited,
@@ -3363,7 +3361,7 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
nsTArray<nsIContent*> visibleKidsOfHiddenElement;
nsIFrame* nextIBSibling;
for (nsIFrame* ibSibling = aFrame; ibSibling; ibSibling = nextIBSibling) {
- nextIBSibling = RestyleManager::GetNextBlockInInlineSibling(propTable, ibSibling);
+ nextIBSibling = RestyleManager::GetNextBlockInInlineSibling(ibSibling);
if (nextIBSibling) {
// Don't allow some ib-split siblings to be processed with
diff --git a/layout/base/RestyleManagerBase.cpp b/layout/base/RestyleManagerBase.cpp
index d96d9dbbb..6770f9464 100644
--- a/layout/base/RestyleManagerBase.cpp
+++ b/layout/base/RestyleManagerBase.cpp
@@ -385,8 +385,6 @@ RestyleManagerBase::DebugVerifyStyleTree(nsIFrame* aFrame)
#endif // DEBUG
-NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ChangeListProperty, bool)
-
/**
* Sync views on aFrame and all of aFrame's descendants (following placeholders),
* if aChange has nsChangeHint_SyncFrameView.
@@ -521,10 +519,9 @@ RecomputePosition(nsIFrame* aFrame)
// normal position, go ahead and add the offsets directly.
// First, we need to ensure that the normal position is stored though.
nsPoint normalPosition = cont->GetNormalPosition();
- auto props = cont->Properties();
- const auto& prop = nsIFrame::NormalPositionProperty();
- if (!props.Get(prop)) {
- props.Set(prop, new nsPoint(normalPosition));
+ if (!cont->GetProperty(nsIFrame::NormalPositionProperty())) {
+ cont->SetProperty(nsIFrame::NormalPositionProperty(),
+ new nsPoint(normalPosition));
}
cont->SetPosition(normalPosition +
nsPoint(newOffsets.left, newOffsets.top));
@@ -739,8 +736,7 @@ RestyleManagerBase::GetNearestAncestorFrame(nsIContent* aContent)
}
/* static */ nsIFrame*
-RestyleManagerBase::GetNextBlockInInlineSibling(FramePropertyTable* aPropTable,
- nsIFrame* aFrame)
+RestyleManagerBase::GetNextBlockInInlineSibling(nsIFrame* aFrame)
{
NS_ASSERTION(!aFrame->GetPrevContinuation(),
"must start with the first continuation");
@@ -750,8 +746,7 @@ RestyleManagerBase::GetNextBlockInInlineSibling(FramePropertyTable* aPropTable,
return nullptr;
}
- return static_cast<nsIFrame*>
- (aPropTable->Get(aFrame, nsIFrame::IBSplitSibling()));
+ return aFrame->GetProperty(nsIFrame::IBSplitSibling());
}
static void
@@ -1028,10 +1023,10 @@ RestyleManagerBase::GetNextContinuationWithSameStyle(
// We're the last continuation, so we have to hop back to the first
// before getting the frame property
nextContinuation =
- aFrame->FirstContinuation()->Properties().Get(nsIFrame::IBSplitSibling());
+ aFrame->FirstContinuation()->GetProperty(nsIFrame::IBSplitSibling());
if (nextContinuation) {
nextContinuation =
- nextContinuation->Properties().Get(nsIFrame::IBSplitSibling());
+ nextContinuation->GetProperty(nsIFrame::IBSplitSibling());
}
}
@@ -1060,14 +1055,52 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
{
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot a script blocker");
- if (aChangeList.IsEmpty())
- return NS_OK;
+
+// See bug 1378219 comment 9:
+// Recursive calls here are a bit worrying, but apparently do happen in the
+// wild (although not currently in any of our automated tests). Try to get a
+// stack from Nightly/Dev channel to figure out what's going on and whether
+// it's OK.
+MOZ_DIAGNOSTIC_ASSERT(!mDestroyedFrames, "ProcessRestyledFrames recursion");
+
+if (aChangeList.IsEmpty())
+ return NS_OK;
+
+// If mDestroyedFrames is null, we want to create a new hashtable here
+// and destroy it on exit; but if it is already non-null (because we're in
+// a recursive call), we will continue to use the existing table to
+// accumulate destroyed frames, and NOT clear mDestroyedFrames on exit.
+// We use a MaybeClearDestroyedFrames helper to conditionally reset the
+// mDestroyedFrames pointer when this method returns.
+typedef decltype(mDestroyedFrames) DestroyedFramesT;
+class MOZ_RAII MaybeClearDestroyedFrames
+{
+private:
+ DestroyedFramesT& mDestroyedFramesRef; // ref to caller's mDestroyedFrames
+ const bool mResetOnDestruction;
+public:
+ explicit MaybeClearDestroyedFrames(DestroyedFramesT& aTarget)
+ : mDestroyedFramesRef(aTarget)
+ , mResetOnDestruction(!aTarget) // reset only if target starts out null
+ {
+ }
+ ~MaybeClearDestroyedFrames()
+ {
+ if (mResetOnDestruction) {
+ mDestroyedFramesRef.reset(nullptr);
+ }
+ }
+};
+
+MaybeClearDestroyedFrames maybeClear(mDestroyedFrames);
+if (!mDestroyedFrames) {
+ mDestroyedFrames = MakeUnique<nsTHashtable<nsPtrHashKey<const nsIFrame>>>();
+}
PROFILER_LABEL("RestyleManager", "ProcessRestyledFrames",
js::ProfileEntry::Category::CSS);
nsPresContext* presContext = PresContext();
- FramePropertyTable* propTable = presContext->PropertyTable();
nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor();
// Handle nsChangeHint_CSSOverflowChange, by either updating the
@@ -1135,15 +1168,6 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
// processing restyles
frameConstructor->BeginUpdate();
- // Mark frames so that we skip frames that die along the way, bug 123049.
- // A frame can be in the list multiple times with different hints. Further
- // optmization is possible if nsStyleChangeList::AppendChange could coalesce
- for (const nsStyleChangeData& data : aChangeList) {
- if (data.mFrame) {
- propTable->Set(data.mFrame, ChangeListProperty(), true);
- }
- }
-
bool didUpdateCursor = false;
for (const nsStyleChangeData& data : aChangeList) {
@@ -1157,7 +1181,7 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
"Reflow hint bits set without actually asking for a reflow");
// skip any frame that has been destroyed due to a ripple effect
- if (frame && !propTable->Get(frame, ChangeListProperty())) {
+ if (frame && mDestroyedFrames->Contains(frame)) {
continue;
}
@@ -1409,15 +1433,11 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
frameConstructor->EndUpdate();
- // cleanup references and verify the style tree. Note that the latter needs
- // to happen once we've processed the whole list, since until then the tree
- // is not in fact in a consistent state.
- for (const nsStyleChangeData& data : aChangeList) {
- if (data.mFrame) {
- propTable->Delete(data.mFrame, ChangeListProperty());
- }
-
#ifdef DEBUG
+ // Verify the style tree. Note that this needs to happen once we've
+ // processed the whole list, since until then the tree is not in fact in a
+ // consistent state.
+ for (const nsStyleChangeData& data : aChangeList) {
// reget frame from content since it may have been regenerated...
if (data.mContent) {
nsIFrame* frame = data.mContent->GetPrimaryFrame();
@@ -1429,8 +1449,8 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
NS_WARNING("Unable to test style tree integrity -- no content node "
"(and not a viewport frame)");
}
-#endif
}
+#endif
aChangeList.Clear();
return NS_OK;
diff --git a/layout/base/RestyleManagerBase.h b/layout/base/RestyleManagerBase.h
index f81f5e73f..d92c3d1f7 100644
--- a/layout/base/RestyleManagerBase.h
+++ b/layout/base/RestyleManagerBase.h
@@ -72,6 +72,11 @@ public:
// WillDestroyFrameTree hasn't been called yet.
void NotifyDestroyingFrame(nsIFrame* aFrame) {
mOverflowChangedTracker.RemoveFrame(aFrame);
+ // If ProcessRestyledFrames is tracking frames which have been
+ // destroyed (to avoid re-visiting them), add this one to its set.
+ if (mDestroyedFrames) {
+ mDestroyedFrames->PutEntry(aFrame);
+ }
}
// Note: It's the caller's responsibility to make sure to wrap a
@@ -127,6 +132,12 @@ private:
nsPresContext* mPresContext; // weak, can be null after Disconnect().
uint32_t mRestyleGeneration;
uint32_t mHoverGeneration;
+
+ // Used to keep track of frames that have been destroyed during
+ // ProcessRestyledFrames, so we don't try to touch them again even if
+ // they're referenced again later in the changelist.
+ mozilla::UniquePtr<nsTHashtable<nsPtrHashKey<const nsIFrame>>> mDestroyedFrames;
+
// True if we're already waiting for a refresh notification.
bool mObservingRefreshDriver;
@@ -146,7 +157,7 @@ protected:
GetNearestAncestorFrame(nsIContent* aContent);
static nsIFrame*
- GetNextBlockInInlineSibling(FramePropertyTable* aPropTable, nsIFrame* aFrame);
+ GetNextBlockInInlineSibling(nsIFrame* aFrame);
/**
* Get the next continuation or similar ib-split sibling (assuming
diff --git a/layout/base/moz.build b/layout/base/moz.build
index d3e417f16..4308a6e4d 100644
--- a/layout/base/moz.build
+++ b/layout/base/moz.build
@@ -61,7 +61,7 @@ EXPORTS += [
'DisplayItemScrollClip.h',
'DisplayListClipState.h',
'FrameLayerBuilder.h',
- 'FramePropertyTable.h',
+ 'FrameProperties.h',
'LayerState.h',
'LayoutLogging.h',
'nsArenaMemoryStats.h',
@@ -126,7 +126,6 @@ UNIFIED_SOURCES += [
'DisplayListClipState.cpp',
'DottedCornerFinder.cpp',
'FrameLayerBuilder.cpp',
- 'FramePropertyTable.cpp',
'GeometryUtils.cpp',
'LayoutLogging.cpp',
'MaskLayerImageCache.cpp',
diff --git a/layout/base/nsBidiPresUtils.cpp b/layout/base/nsBidiPresUtils.cpp
index b3c20aabb..887563504 100644
--- a/layout/base/nsBidiPresUtils.cpp
+++ b/layout/base/nsBidiPresUtils.cpp
@@ -753,7 +753,6 @@ nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd)
nsIContent* content = nullptr;
int32_t contentTextLength = 0;
- FramePropertyTable* propTable = aBpd->mPresContext->PropertyTable();
nsLineBox* currentLine = nullptr;
#ifdef DEBUG
@@ -809,7 +808,7 @@ nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd)
}
precedingControl = kBidiLevelNone;
lastEmbedingLevel = embeddingLevel;
- propTable->Set(frame, nsIFrame::BidiDataProperty(), bidiData);
+ frame->SetProperty(nsIFrame::BidiDataProperty(), bidiData);
};
for (; ;) {
@@ -1787,7 +1786,7 @@ nsBidiPresUtils::RemoveBidiContinuation(BidiParagraphData *aBpd,
if (frame != NS_BIDI_CONTROL_FRAME) {
// Make the frame and its continuation ancestors fluid,
// so they can be reused or deleted by normal reflow code
- frame->Properties().Set(nsIFrame::BidiDataProperty(), bidiData);
+ frame->SetProperty(nsIFrame::BidiDataProperty(), bidiData);
frame->AddStateBits(NS_FRAME_IS_BIDI);
while (frame) {
nsIFrame* prev = frame->GetPrevContinuation();
diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp
index 07a5b80e7..ec676ca92 100644
--- a/layout/base/nsCSSFrameConstructor.cpp
+++ b/layout/base/nsCSSFrameConstructor.cpp
@@ -492,9 +492,8 @@ static nsContainerFrame* GetIBSplitSibling(nsIFrame* aFrame)
// We only store the "ib-split sibling" annotation with the first
// frame in the continuation chain. Walk back to find that frame now.
- return static_cast<nsContainerFrame*>
- (aFrame->FirstContinuation()->
- Properties().Get(nsIFrame::IBSplitSibling()));
+ return aFrame->FirstContinuation()->
+ GetProperty(nsIFrame::IBSplitSibling());
}
static nsContainerFrame* GetIBSplitPrevSibling(nsIFrame* aFrame)
@@ -503,9 +502,8 @@ static nsContainerFrame* GetIBSplitPrevSibling(nsIFrame* aFrame)
// We only store the ib-split sibling annotation with the first
// frame in the continuation chain. Walk back to find that frame now.
- return static_cast<nsContainerFrame*>
- (aFrame->FirstContinuation()->
- Properties().Get(nsIFrame::IBSplitPrevSibling()));
+ return aFrame->FirstContinuation()->
+ GetProperty(nsIFrame::IBSplitPrevSibling());
}
static nsContainerFrame*
@@ -526,7 +524,7 @@ GetLastIBSplitSibling(nsIFrame* aFrame, bool aReturnEmptyTrailingInline)
}
static void
-SetFrameIsIBSplit(nsContainerFrame* aFrame, nsIFrame* aIBSplitSibling)
+SetFrameIsIBSplit(nsContainerFrame* aFrame, nsContainerFrame* aIBSplitSibling)
{
NS_PRECONDITION(aFrame, "bad args!");
@@ -547,9 +545,8 @@ SetFrameIsIBSplit(nsContainerFrame* aFrame, nsIFrame* aIBSplitSibling)
// Store the ib-split sibling (if we were given one) with the
// first frame in the flow.
- FramePropertyTable* props = aFrame->PresContext()->PropertyTable();
- props->Set(aFrame, nsIFrame::IBSplitSibling(), aIBSplitSibling);
- props->Set(aIBSplitSibling, nsIFrame::IBSplitPrevSibling(), aFrame);
+ aFrame->SetProperty(nsIFrame::IBSplitSibling(), aIBSplitSibling);
+ aIBSplitSibling->SetProperty(nsIFrame::IBSplitPrevSibling(), aFrame);
}
}
@@ -6075,11 +6072,11 @@ AddGenConPseudoToFrame(nsIFrame* aOwnerFrame, nsIContent* aContent)
NS_ASSERTION(nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aOwnerFrame),
"property should only be set on first continuation/ib-sibling");
- FrameProperties props = aOwnerFrame->Properties();
- nsIFrame::ContentArray* value = props.Get(nsIFrame::GenConProperty());
+ nsIFrame::ContentArray* value =
+ aOwnerFrame->GetProperty(nsIFrame::GenConProperty());
if (!value) {
value = new nsIFrame::ContentArray;
- props.Set(nsIFrame::GenConProperty(), value);
+ aOwnerFrame->SetProperty(nsIFrame::GenConProperty(), value);
}
value->AppendElement(aContent);
}
diff --git a/layout/base/nsCSSRendering.cpp b/layout/base/nsCSSRendering.cpp
index ff9edf742..119c6c8a2 100644
--- a/layout/base/nsCSSRendering.cpp
+++ b/layout/base/nsCSSRendering.cpp
@@ -293,13 +293,13 @@ protected:
if (!prevCont &&
(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
nsIFrame* block =
- aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling());
+ aFrame->GetProperty(nsIFrame::IBSplitPrevSibling());
if (block) {
// The {ib} properties are only stored on first continuations
NS_ASSERTION(!block->GetPrevContinuation(),
"Incorrect value for IBSplitPrevSibling");
prevCont =
- block->Properties().Get(nsIFrame::IBSplitPrevSibling());
+ block->GetProperty(nsIFrame::IBSplitPrevSibling());
NS_ASSERTION(prevCont, "How did that happen?");
}
}
@@ -313,9 +313,9 @@ protected:
(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
// The {ib} properties are only stored on first continuations
aFrame = aFrame->FirstContinuation();
- nsIFrame* block = aFrame->Properties().Get(nsIFrame::IBSplitSibling());
+ nsIFrame* block = aFrame->GetProperty(nsIFrame::IBSplitSibling());
if (block) {
- nextCont = block->Properties().Get(nsIFrame::IBSplitSibling());
+ nextCont = block->GetProperty(nsIFrame::IBSplitSibling());
NS_ASSERTION(nextCont, "How did that happen?");
}
}
@@ -842,7 +842,7 @@ static nsRect
GetOutlineInnerRect(nsIFrame* aFrame)
{
nsRect* savedOutlineInnerRect =
- aFrame->Properties().Get(nsIFrame::OutlineInnerRectProperty());
+ aFrame->GetProperty(nsIFrame::OutlineInnerRectProperty());
if (savedOutlineInnerRect)
return *savedOutlineInnerRect;
NS_NOTREACHED("we should have saved a frame property");
diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp
index a55ec1e39..e22230b41 100644
--- a/layout/base/nsDisplayList.cpp
+++ b/layout/base/nsDisplayList.cpp
@@ -666,7 +666,7 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
// EffectCompositor needs to know that we refused to run this animation
// asynchronously so that it will not throttle the main thread
// animation.
- aFrame->Properties().Set(nsIFrame::RefusedAsyncAnimationProperty(), true);
+ aFrame->SetProperty(nsIFrame::RefusedAsyncAnimationProperty(), true);
// We need to schedule another refresh driver run so that EffectCompositor
// gets a chance to unthrottle the animation.
@@ -902,15 +902,13 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants();
const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip();
OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty);
- aFrame->Properties().Set(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
+ aFrame->SetProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
MarkFrameForDisplay(aFrame, aDirtyFrame);
}
static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
- nsPresContext* presContext = aFrame->PresContext();
- presContext->PropertyTable()->
- Delete(aFrame, nsDisplayListBuilder::OutOfFlowDisplayDataProperty());
+ aFrame->DeleteProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty());
for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {
@@ -5710,7 +5708,7 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame,
}
/* Allows us to access dimension getters by index. */
- float coords[2];
+ float transformOrigin[2];
TransformReferenceBox::DimensionGetter dimensionGetter[] =
{ &TransformReferenceBox::Width, &TransformReferenceBox::Height };
TransformReferenceBox::DimensionGetter offsetGetter[] =
@@ -5720,33 +5718,33 @@ nsDisplayTransform::GetDeltaToTransformOrigin(const nsIFrame* aFrame,
/* If the transform-origin specifies a percentage, take the percentage
* of the size of the box.
*/
- const nsStyleCoord &coord = display->mTransformOrigin[index];
- if (coord.GetUnit() == eStyleUnit_Calc) {
- const nsStyleCoord::Calc *calc = coord.GetCalcValue();
- coords[index] =
+ const nsStyleCoord &originValue = display->mTransformOrigin[index];
+ if (originValue.GetUnit() == eStyleUnit_Calc) {
+ const nsStyleCoord::Calc *calc = originValue.GetCalcValue();
+ transformOrigin[index] =
NSAppUnitsToFloatPixels((refBox.*dimensionGetter[index])(), aAppUnitsPerPixel) *
calc->mPercent +
NSAppUnitsToFloatPixels(calc->mLength, aAppUnitsPerPixel);
- } else if (coord.GetUnit() == eStyleUnit_Percent) {
- coords[index] =
+ } else if (originValue.GetUnit() == eStyleUnit_Percent) {
+ transformOrigin[index] =
NSAppUnitsToFloatPixels((refBox.*dimensionGetter[index])(), aAppUnitsPerPixel) *
- coord.GetPercentValue();
+ originValue.GetPercentValue();
} else {
- MOZ_ASSERT(coord.GetUnit() == eStyleUnit_Coord, "unexpected unit");
- coords[index] =
- NSAppUnitsToFloatPixels(coord.GetCoordValue(), aAppUnitsPerPixel);
+ MOZ_ASSERT(originValue.GetUnit() == eStyleUnit_Coord, "unexpected unit");
+ transformOrigin[index] =
+ NSAppUnitsToFloatPixels(originValue.GetCoordValue(), aAppUnitsPerPixel);
}
if (aFrame->GetStateBits() & NS_FRAME_SVG_LAYOUT) {
// SVG frames (unlike other frames) have a reference box that can be (and
// typically is) offset from the TopLeft() of the frame. We need to
// account for that here.
- coords[index] +=
+ transformOrigin[index] +=
NSAppUnitsToFloatPixels((refBox.*offsetGetter[index])(), aAppUnitsPerPixel);
}
}
- return Point3D(coords[0], coords[1],
+ return Point3D(transformOrigin[0], transformOrigin[1],
NSAppUnitsToFloatPixels(display->mTransformOrigin[2].GetCoordValue(),
aAppUnitsPerPixel));
}
@@ -5919,6 +5917,17 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
frame && frame->IsSVGTransformed(&svgTransform, &transformFromSVGParent);
bool hasTransformFromSVGParent =
hasSVGTransforms && !transformFromSVGParent.IsIdentity();
+
+ bool shouldRound = true;
+
+ // An SVG frame should not have its translation rounded.
+ // Note it's possible that the SVG frame doesn't have an SVG
+ // transform but only has a CSS transform.
+ if (frame && frame->HasAnyStateBits(NS_FRAME_SVG_LAYOUT) &&
+ !(frame->GetType() == nsGkAtoms::svgOuterSVGAnonChildFrame)) {
+ shouldRound = false;
+ }
+
/* Transformed frames always have a transform, or are preserving 3d (and might still have perspective!) */
if (aProperties.mTransformList) {
result = nsStyleTransformMatrix::ReadTransforms(aProperties.mTransformList->mHead,
@@ -5996,7 +6005,7 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
// Otherwise we need to manually translate into our parent's coordinate
// space.
if (frame->IsTransformed()) {
- nsLayoutUtils::PostTranslate(result, frame->GetPosition(), aAppUnitsPerPixel, !hasSVGTransforms);
+ nsLayoutUtils::PostTranslate(result, frame->GetPosition(), aAppUnitsPerPixel, shouldRound);
}
Matrix4x4 parent =
GetResultingTransformMatrixInternal(props,
@@ -6007,7 +6016,7 @@ nsDisplayTransform::GetResultingTransformMatrixInternal(const FrameTransformProp
}
if (aFlags & OFFSET_BY_ORIGIN) {
- nsLayoutUtils::PostTranslate(result, aOrigin, aAppUnitsPerPixel, !hasSVGTransforms);
+ nsLayoutUtils::PostTranslate(result, aOrigin, aAppUnitsPerPixel, shouldRound);
}
return result;
diff --git a/layout/base/nsDisplayList.h b/layout/base/nsDisplayList.h
index fcdc9e4fc..c81d34fac 100644
--- a/layout/base/nsDisplayList.h
+++ b/layout/base/nsDisplayList.h
@@ -1003,7 +1003,7 @@ public:
static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame)
{
- return aFrame->Properties().Get(OutOfFlowDisplayDataProperty());
+ return aFrame->GetProperty(OutOfFlowDisplayDataProperty());
}
nsPresContext* CurrentPresContext() {
diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h
index 4016cc0a9..865f5534c 100644
--- a/layout/base/nsIPresShell.h
+++ b/layout/base/nsIPresShell.h
@@ -1533,11 +1533,12 @@ public:
bool aFlushOnHoverChange) = 0;
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
- nsArenaMemoryStats *aArenaObjectsSize,
- size_t *aPresShellSize,
- size_t *aStyleSetsSize,
- size_t *aTextRunsSize,
- size_t *aPresContextSize) = 0;
+ nsArenaMemoryStats* aArenaObjectsSize,
+ size_t* aPresShellSize,
+ size_t* aStyleSetsSize,
+ size_t* aTextRunsSize,
+ size_t* aPresContextSize,
+ size_t* aFramePropertiesSize) = 0;
/**
* Methods that retrieve the cached font inflation preferences.
diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp
index 07befdc81..06690b208 100644
--- a/layout/base/nsLayoutUtils.cpp
+++ b/layout/base/nsLayoutUtils.cpp
@@ -2057,13 +2057,13 @@ NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ScrollbarThumbLayerized, bool)
/* static */ void
nsLayoutUtils::SetScrollbarThumbLayerization(nsIFrame* aThumbFrame, bool aLayerize)
{
- aThumbFrame->Properties().Set(ScrollbarThumbLayerized(), aLayerize);
+ aThumbFrame->SetProperty(ScrollbarThumbLayerized(), aLayerize);
}
bool
nsLayoutUtils::IsScrollbarThumbLayerized(nsIFrame* aThumbFrame)
{
- return aThumbFrame->Properties().Get(ScrollbarThumbLayerized());
+ return aThumbFrame->GetProperty(ScrollbarThumbLayerized());
}
// static
@@ -4427,7 +4427,7 @@ nsLayoutUtils::GetNextContinuationOrIBSplitSibling(nsIFrame *aFrame)
// frame in the continuation chain. Walk back to find that frame now.
aFrame = aFrame->FirstContinuation();
- return aFrame->Properties().Get(nsIFrame::IBSplitSibling());
+ return aFrame->GetProperty(nsIFrame::IBSplitSibling());
}
return nullptr;
@@ -4440,7 +4440,7 @@ nsLayoutUtils::FirstContinuationOrIBSplitSibling(nsIFrame *aFrame)
if (result->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) {
while (true) {
nsIFrame* f =
- result->Properties().Get(nsIFrame::IBSplitPrevSibling());
+ result->GetProperty(nsIFrame::IBSplitPrevSibling());
if (!f)
break;
result = f;
@@ -4456,10 +4456,10 @@ nsLayoutUtils::LastContinuationOrIBSplitSibling(nsIFrame *aFrame)
nsIFrame *result = aFrame->FirstContinuation();
if (result->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) {
while (true) {
- nsIFrame* f =
- result->Properties().Get(nsIFrame::IBSplitSibling());
- if (!f)
+ nsIFrame* f = result->GetProperty(nsIFrame::IBSplitSibling());
+ if (!f) {
break;
+ }
result = f;
}
}
@@ -4476,7 +4476,7 @@ nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(nsIFrame *aFrame)
return false;
}
if ((aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
- aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling())) {
+ aFrame->GetProperty(nsIFrame::IBSplitPrevSibling())) {
return false;
}
diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp
index 3106ff386..befb5deb2 100644
--- a/layout/base/nsPresContext.cpp
+++ b/layout/base/nsPresContext.cpp
@@ -2741,8 +2741,7 @@ nsPresContext::GetPrimaryFrameFor(nsIContent* aContent)
size_t
nsPresContext::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{
- return mPropertyTable.SizeOfExcludingThis(aMallocSizeOf) +
- mLangGroupFontPrefs.SizeOfExcludingThis(aMallocSizeOf);
+ return mLangGroupFontPrefs.SizeOfExcludingThis(aMallocSizeOf);
// Measurement of other members may be added later if DMD finds it is
// worthwhile.
diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h
index d8f876291..a2b9bb533 100644
--- a/layout/base/nsPresContext.h
+++ b/layout/base/nsPresContext.h
@@ -22,7 +22,6 @@
#include "nsITimer.h"
#include "nsCRT.h"
#include "nsIWidgetListener.h"
-#include "FramePropertyTable.h"
#include "nsGkAtoms.h"
#include "nsCycleCollectionParticipant.h"
#include "nsChangeHint.h"
@@ -140,7 +139,6 @@ class nsRootPresContext;
class nsPresContext : public nsIObserver,
public mozilla::SupportsWeakPtr<nsPresContext> {
public:
- typedef mozilla::FramePropertyTable FramePropertyTable;
typedef mozilla::LangGroupFontPrefs LangGroupFontPrefs;
typedef mozilla::ScrollbarStyles ScrollbarStyles;
typedef mozilla::StaticPresData StaticPresData;
@@ -867,9 +865,6 @@ public:
nsIPrintSettings* GetPrintSettings() { return mPrintSettings; }
- /* Accessor for table of frame properties */
- FramePropertyTable* PropertyTable() { return &mPropertyTable; }
-
/* Helper function that ensures that this prescontext is shown in its
docshell if it's the most recent prescontext for the docshell. Returns
whether the prescontext is now being shown.
@@ -1064,11 +1059,6 @@ public:
*/
nsIFrame* GetPrimaryFrameFor(nsIContent* aContent);
- void NotifyDestroyingFrame(nsIFrame* aFrame)
- {
- PropertyTable()->DeleteAllFor(aFrame);
- }
-
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
@@ -1294,7 +1284,6 @@ protected:
nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsITimer> mPrefChangedTimer;
- FramePropertyTable mPropertyTable;
nsInvalidateRequestList mInvalidateRequestsSinceLastPaint;
nsInvalidateRequestList mUndeliveredInvalidateRequestsBeforeLastPaint;
diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp
index 5dfbb8dba..264b52b18 100644
--- a/layout/base/nsPresShell.cpp
+++ b/layout/base/nsPresShell.cpp
@@ -1306,19 +1306,6 @@ PresShell::Destroy()
// Destroy the frame manager. This will destroy the frame hierarchy
mFrameConstructor->WillDestroyFrameTree();
- // Destroy all frame properties (whose destruction was suppressed
- // while destroying the frame tree, but which might contain more
- // frames within the properties.
- if (mPresContext) {
- // Clear out the prescontext's property table -- since our frame tree is
- // now dead, we shouldn't be looking up any more properties in that table.
- // We want to do this before we call DetachShell() on the prescontext, so
- // property destructors can usefully call GetPresShell() on the
- // prescontext.
- mPresContext->PropertyTable()->DeleteAll();
- }
-
-
NS_WARNING_ASSERTION(!mWeakFrames,
"Weak frames alive after destroying FrameManager");
while (mWeakFrames) {
@@ -2047,7 +2034,7 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
}
// Remove frame properties
- mPresContext->NotifyDestroyingFrame(aFrame);
+ aFrame->DeleteAllProperties();
if (aFrame == mCurrentEventFrame) {
mCurrentEventContent = aFrame->GetContent();
@@ -2076,8 +2063,7 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
// frame from FrameLayerBuilder::DisplayItemData::mFrameList -- otherwise
// the DisplayItemData destructor will use the destroyed frame when it
// tries to remove it from the (array) value of this property.
- mPresContext->PropertyTable()->
- Delete(aFrame, FrameLayerBuilder::LayerManagerDataProperty());
+ aFrame->DeleteProperty( FrameLayerBuilder::LayerManagerDataProperty());
}
}
@@ -10917,11 +10903,12 @@ PresShell::GetRootPresShell()
void
PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
- nsArenaMemoryStats *aArenaObjectsSize,
- size_t *aPresShellSize,
- size_t *aStyleSetsSize,
- size_t *aTextRunsSize,
- size_t *aPresContextSize)
+ nsArenaMemoryStats* aArenaObjectsSize,
+ size_t* aPresShellSize,
+ size_t* aStyleSetsSize,
+ size_t* aTextRunsSize,
+ size_t* aPresContextSize,
+ size_t* aFramePropertiesSize)
{
mFrameArena.AddSizeOfExcludingThis(aMallocSizeOf, aArenaObjectsSize);
*aPresShellSize += aMallocSizeOf(this);
@@ -10941,6 +10928,12 @@ PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
*aTextRunsSize += SizeOfTextRuns(aMallocSizeOf);
*aPresContextSize += mPresContext->SizeOfIncludingThis(aMallocSizeOf);
+
+ nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
+ if (rootFrame) {
+ *aFramePropertiesSize +=
+ rootFrame->SizeOfFramePropertiesForTree(aMallocSizeOf);
+ }
}
size_t
diff --git a/layout/base/nsPresShell.h b/layout/base/nsPresShell.h
index 7a9056a38..f20370d73 100644
--- a/layout/base/nsPresShell.h
+++ b/layout/base/nsPresShell.h
@@ -384,11 +384,12 @@ public:
virtual void LoadComplete() override;
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
- nsArenaMemoryStats *aArenaObjectsSize,
- size_t *aPresShellSize,
- size_t *aStyleSetsSize,
- size_t *aTextRunsSize,
- size_t *aPresContextSize) override;
+ nsArenaMemoryStats* aArenaObjectsSize,
+ size_t* aPresShellSize,
+ size_t* aStyleSetsSize,
+ size_t* aTextRunsSize,
+ size_t* aPresContextSize,
+ size_t* aFramePropertiesSize) override;
size_t SizeOfTextRuns(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual void AddInvalidateHiddenPresShellObserver(nsRefreshDriver *aDriver) override;
diff --git a/layout/build/moz.build b/layout/build/moz.build
index 5b607c171..ecf180d78 100644
--- a/layout/build/moz.build
+++ b/layout/build/moz.build
@@ -31,6 +31,7 @@ LOCAL_INCLUDES += [
'/docshell/base',
'/dom/audiochannel',
'/dom/base',
+ '/dom/bindings',
'/dom/canvas',
'/dom/filesystem',
'/dom/geolocation',
diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp
index 8bb70f85c..9313b8e45 100644
--- a/layout/build/nsLayoutModule.cpp
+++ b/layout/build/nsLayoutModule.cpp
@@ -35,6 +35,7 @@
#include "nsIObserver.h"
#include "nsIObserverService.h"
#include "nsIScriptNameSpaceManager.h"
+#include "nsIScriptError.h"
#include "nsISelection.h"
#include "nsCaret.h"
#include "nsPlainTextSerializer.h"
@@ -192,6 +193,8 @@ static void Shutdown();
#include "mozilla/dom/PresentationDeviceManager.h"
#include "mozilla/dom/PresentationTCPSessionTransport.h"
+#include "nsScriptError.h"
+
#include "mozilla/TextInputProcessor.h"
using namespace mozilla;
@@ -560,6 +563,8 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(UDPSocketChild)
NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(GeckoMediaPluginService, GeckoMediaPluginService::GetGeckoMediaPluginService)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsScriptError)
+
#ifdef ACCESSIBILITY
#include "xpcAccessibilityService.h"
@@ -720,6 +725,8 @@ NS_DEFINE_NAMED_CID(PRESENTATION_TCP_SESSION_TRANSPORT_CID);
NS_DEFINE_NAMED_CID(TEXT_INPUT_PROCESSOR_CID);
+NS_DEFINE_NAMED_CID(NS_SCRIPTERROR_CID);
+
static nsresult
CreateWindowCommandTableConstructor(nsISupports *aOuter,
REFNSIID aIID, void **aResult)
@@ -978,6 +985,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kPRESENTATION_DEVICE_MANAGER_CID, false, nullptr, PresentationDeviceManagerConstructor },
{ &kPRESENTATION_TCP_SESSION_TRANSPORT_CID, false, nullptr, PresentationTCPSessionTransportConstructor },
{ &kTEXT_INPUT_PROCESSOR_CID, false, nullptr, TextInputProcessorConstructor },
+ { &kNS_SCRIPTERROR_CID, false, nullptr, nsScriptErrorConstructor },
{ nullptr }
};
@@ -1109,6 +1117,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
{ PRESENTATION_DEVICE_MANAGER_CONTRACTID, &kPRESENTATION_DEVICE_MANAGER_CID },
{ PRESENTATION_TCP_SESSION_TRANSPORT_CONTRACTID, &kPRESENTATION_TCP_SESSION_TRANSPORT_CID },
{ "@mozilla.org/text-input-processor;1", &kTEXT_INPUT_PROCESSOR_CID },
+ { NS_SCRIPTERROR_CONTRACTID, &kNS_SCRIPTERROR_CID },
{ nullptr }
};
diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp
index a7f7d40a8..f8fdf3420 100644
--- a/layout/forms/nsTextControlFrame.cpp
+++ b/layout/forms/nsTextControlFrame.cpp
@@ -124,10 +124,10 @@ nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
{
mScrollEvent.Revoke();
- EditorInitializer* initializer = Properties().Get(TextControlInitializer());
+ EditorInitializer* initializer = GetProperty(TextControlInitializer());
if (initializer) {
initializer->Revoke();
- Properties().Delete(TextControlInitializer());
+ DeleteProperty(TextControlInitializer());
}
// Unbind the text editor state object from the frame. The editor will live
@@ -410,12 +410,12 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
if (initEagerly) {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot a script blocker?");
- EditorInitializer* initializer = Properties().Get(TextControlInitializer());
+ EditorInitializer* initializer = GetProperty(TextControlInitializer());
if (initializer) {
initializer->Revoke();
}
initializer = new EditorInitializer(this);
- Properties().Set(TextControlInitializer(),initializer);
+ SetProperty(TextControlInitializer(),initializer);
nsContentUtils::AddScriptRunner(initializer);
}
@@ -1262,7 +1262,7 @@ nsTextControlFrame::SetInitialChildList(ChildListID aListID,
NS_ASSERTION(txtCtrl, "Content not a text control element");
txtCtrl->InitializeKeyboardEventListeners();
- nsPoint* contentScrollPos = Properties().Get(ContentScrollPos());
+ nsPoint* contentScrollPos = GetProperty(ContentScrollPos());
if (contentScrollPos) {
// If we have a scroll pos stored to be passed to our anonymous
// div, do it here!
@@ -1271,7 +1271,7 @@ nsTextControlFrame::SetInitialChildList(ChildListID aListID,
nsPresState fakePresState;
fakePresState.SetScrollState(*contentScrollPos);
statefulFrame->RestoreState(&fakePresState);
- Properties().Remove(ContentScrollPos());
+ RemoveProperty(ContentScrollPos());
delete contentScrollPos;
}
}
@@ -1421,7 +1421,7 @@ nsTextControlFrame::RestoreState(nsPresState* aState)
// Most likely, we don't have our anonymous content constructed yet, which
// would cause us to end up here. In this case, we'll just store the scroll
// pos ourselves, and forward it to the scroll frame later when it's created.
- Properties().Set(ContentScrollPos(), new nsPoint(aState->GetScrollPosition()));
+ SetProperty(ContentScrollPos(), new nsPoint(aState->GetScrollPosition()));
return NS_OK;
}
diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h
index 9d4d0b77c..7fa39c5fb 100644
--- a/layout/forms/nsTextControlFrame.h
+++ b/layout/forms/nsTextControlFrame.h
@@ -327,7 +327,7 @@ private:
nsresult GetRootNodeAndInitializeEditor(nsIDOMElement **aRootElement);
void FinishedInitializer() {
- Properties().Delete(TextControlInitializer());
+ DeleteProperty(TextControlInitializer());
}
private:
diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp
index bbff77ad4..78eca8c6c 100644
--- a/layout/generic/ReflowInput.cpp
+++ b/layout/generic/ReflowInput.cpp
@@ -999,13 +999,13 @@ ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
// Convert the offsets to physical coordinates and store them on the frame
aComputedOffsets = offsets.GetPhysicalMargin(aWM);
- FrameProperties props = aFrame->Properties();
- nsMargin* physicalOffsets = props.Get(nsIFrame::ComputedOffsetProperty());
+ nsMargin* physicalOffsets =
+ aFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
if (physicalOffsets) {
*physicalOffsets = aComputedOffsets;
} else {
- props.Set(nsIFrame::ComputedOffsetProperty(),
- new nsMargin(aComputedOffsets));
+ aFrame->SetProperty(nsIFrame::ComputedOffsetProperty(),
+ new nsMargin(aComputedOffsets));
}
}
@@ -1015,21 +1015,22 @@ ReflowInput::ApplyRelativePositioning(nsIFrame* aFrame,
nsPoint* aPosition)
{
if (!aFrame->IsRelativelyPositioned()) {
- NS_ASSERTION(!aFrame->Properties().Get(nsIFrame::NormalPositionProperty()),
+ NS_ASSERTION(!aFrame->GetProperty(nsIFrame::NormalPositionProperty()),
"We assume that changing the 'position' property causes "
"frame reconstruction. If that ever changes, this code "
"should call "
- "props.Delete(nsIFrame::NormalPositionProperty())");
+ "aFrame->DeleteProperty(nsIFrame::NormalPositionProperty())");
return;
}
// Store the normal position
- FrameProperties props = aFrame->Properties();
- nsPoint* normalPosition = props.Get(nsIFrame::NormalPositionProperty());
+ nsPoint* normalPosition =
+ aFrame->GetProperty(nsIFrame::NormalPositionProperty());
if (normalPosition) {
*normalPosition = *aPosition;
} else {
- props.Set(nsIFrame::NormalPositionProperty(), new nsPoint(*aPosition));
+ aFrame->SetProperty(nsIFrame::NormalPositionProperty(),
+ new nsPoint(*aPosition));
}
const nsStyleDisplay* display = aFrame->StyleDisplay();
@@ -2452,20 +2453,20 @@ ReflowInput::InitConstraints(nsPresContext* aPresContext,
}
static void
-UpdateProp(FrameProperties& aProps,
+UpdateProp(nsIFrame* aFrame,
const FramePropertyDescriptor<nsMargin>* aProperty,
bool aNeeded,
nsMargin& aNewValue)
{
if (aNeeded) {
- nsMargin* propValue = aProps.Get(aProperty);
+ nsMargin* propValue = aFrame->GetProperty(aProperty);
if (propValue) {
*propValue = aNewValue;
} else {
- aProps.Set(aProperty, new nsMargin(aNewValue));
+ aFrame->SetProperty(aProperty, new nsMargin(aNewValue));
}
} else {
- aProps.Delete(aProperty);
+ aFrame->DeleteProperty(aProperty);
}
}
@@ -2482,8 +2483,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM,
// Since we are in reflow, we don't need to store these properties anymore
// unless they are dependent on width, in which case we store the new value.
nsPresContext *presContext = mFrame->PresContext();
- FrameProperties props(presContext->PropertyTable(), mFrame);
- props.Delete(nsIFrame::UsedBorderProperty());
+ mFrame->DeleteProperty(nsIFrame::UsedBorderProperty());
// Compute margins from the specified margin style information. These
// become the default computed values, and may be adjusted below
@@ -2494,7 +2494,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM,
// ... but if we did that, we'd need to fix nsFrame::GetUsedMargin
// to use it even when the margins are all zero (since sometimes
// they get treated as auto)
- ::UpdateProp(props, nsIFrame::UsedMarginProperty(), needMarginProp,
+ ::UpdateProp(mFrame, nsIFrame::UsedMarginProperty(), needMarginProp,
ComputedPhysicalMargin());
@@ -2530,7 +2530,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM,
auto ApplyBaselinePadding = [this, &needPaddingProp]
(LogicalAxis aAxis, Prop aProp) {
bool found;
- nscoord val = mFrame->Properties().Get(aProp, &found);
+ nscoord val = mFrame->GetProperty(aProp, &found);
if (found) {
NS_ASSERTION(val != nscoord(0), "zero in this property is useless");
WritingMode wm = GetWritingMode();
@@ -2603,7 +2603,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM,
ComputedPhysicalBorderPadding().SizeTo(0,0,0,0);
}
}
- ::UpdateProp(props, nsIFrame::UsedPaddingProperty(), needPaddingProp,
+ ::UpdateProp(mFrame, nsIFrame::UsedPaddingProperty(), needPaddingProp,
ComputedPhysicalPadding());
}
diff --git a/layout/generic/RubyUtils.cpp b/layout/generic/RubyUtils.cpp
index f340663bc..05dd25413 100644
--- a/layout/generic/RubyUtils.cpp
+++ b/layout/generic/RubyUtils.cpp
@@ -19,21 +19,21 @@ NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ReservedISize, nscoord)
RubyUtils::SetReservedISize(nsIFrame* aFrame, nscoord aISize)
{
MOZ_ASSERT(IsExpandableRubyBox(aFrame));
- aFrame->Properties().Set(ReservedISize(), aISize);
+ aFrame->SetProperty(ReservedISize(), aISize);
}
/* static */ void
RubyUtils::ClearReservedISize(nsIFrame* aFrame)
{
MOZ_ASSERT(IsExpandableRubyBox(aFrame));
- aFrame->Properties().Remove(ReservedISize());
+ aFrame->RemoveProperty(ReservedISize());
}
/* static */ nscoord
RubyUtils::GetReservedISize(nsIFrame* aFrame)
{
MOZ_ASSERT(IsExpandableRubyBox(aFrame));
- return aFrame->Properties().Get(ReservedISize());
+ return aFrame->GetProperty(ReservedISize());
}
AutoRubyTextContainerArray::AutoRubyTextContainerArray(
diff --git a/layout/generic/StickyScrollContainer.cpp b/layout/generic/StickyScrollContainer.cpp
index d61a7e042..ca68992c3 100644
--- a/layout/generic/StickyScrollContainer.cpp
+++ b/layout/generic/StickyScrollContainer.cpp
@@ -45,12 +45,12 @@ StickyScrollContainer::GetStickyScrollContainerForFrame(nsIFrame* aFrame)
// <html style="position: fixed">
return nullptr;
}
- FrameProperties props = static_cast<nsIFrame*>(do_QueryFrame(scrollFrame))->
- Properties();
- StickyScrollContainer* s = props.Get(StickyScrollContainerProperty());
+ auto frame = static_cast<nsIFrame*>(do_QueryFrame(scrollFrame));
+ StickyScrollContainer* s =
+ frame->GetProperty(StickyScrollContainerProperty());
if (!s) {
s = new StickyScrollContainer(scrollFrame);
- props.Set(StickyScrollContainerProperty(), s);
+ frame->SetProperty(StickyScrollContainerProperty(), s);
}
return s;
}
@@ -69,9 +69,9 @@ StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary(nsIFrame*
// we aren't going to handle that.
return;
}
- FrameProperties props = static_cast<nsIFrame*>(do_QueryFrame(oldScrollFrame))->
- Properties();
- StickyScrollContainer* oldSSC = props.Get(StickyScrollContainerProperty());
+ StickyScrollContainer* oldSSC =
+ static_cast<nsIFrame*>(do_QueryFrame(oldScrollFrame))->
+ GetProperty(StickyScrollContainerProperty());
if (!oldSSC) {
// aOldParent had no sticky descendants, so aFrame doesn't have any sticky
// descendants, and we're done here.
@@ -95,8 +95,7 @@ StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary(nsIFrame*
StickyScrollContainer*
StickyScrollContainer::GetStickyScrollContainerForScrollFrame(nsIFrame* aFrame)
{
- FrameProperties props = aFrame->Properties();
- return props.Get(StickyScrollContainerProperty());
+ return aFrame->GetProperty(StickyScrollContainerProperty());
}
static nscoord
@@ -141,13 +140,12 @@ StickyScrollContainer::ComputeStickyOffsets(nsIFrame* aFrame)
scrollContainerSize.height);
// Store the offset
- FrameProperties props = aFrame->Properties();
- nsMargin* offsets = props.Get(nsIFrame::ComputedOffsetProperty());
+ nsMargin* offsets = aFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
if (offsets) {
*offsets = computedOffsets;
} else {
- props.Set(nsIFrame::ComputedOffsetProperty(),
- new nsMargin(computedOffsets));
+ aFrame->SetProperty(nsIFrame::ComputedOffsetProperty(),
+ new nsMargin(computedOffsets));
}
}
@@ -162,7 +160,7 @@ StickyScrollContainer::ComputeStickyLimits(nsIFrame* aFrame, nsRect* aStick,
aContain->SetRect(nscoord_MIN/2, nscoord_MIN/2, nscoord_MAX, nscoord_MAX);
const nsMargin* computedOffsets =
- aFrame->Properties().Get(nsIFrame::ComputedOffsetProperty());
+ aFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
if (!computedOffsets) {
// We haven't reflowed the scroll frame yet, so offsets haven't been
// computed. Bail.
diff --git a/layout/generic/nsBlockFrame.cpp b/layout/generic/nsBlockFrame.cpp
index 851e3406c..a37bfc06b 100644
--- a/layout/generic/nsBlockFrame.cpp
+++ b/layout/generic/nsBlockFrame.cpp
@@ -326,10 +326,8 @@ nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsLineBox::DeleteLineList(presContext, mLines, aDestructRoot,
&mFrames);
- FramePropertyTable* props = presContext->PropertyTable();
-
if (HasPushedFloats()) {
- SafelyDestroyFrameListProp(aDestructRoot, shell, props,
+ SafelyDestroyFrameListProp(aDestructRoot, shell,
PushedFloatProperty());
RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
}
@@ -343,13 +341,13 @@ nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
}
if (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) {
- SafelyDestroyFrameListProp(aDestructRoot, shell, props,
+ SafelyDestroyFrameListProp(aDestructRoot, shell,
OverflowOutOfFlowsProperty());
RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
}
if (HasOutsideBullet()) {
- SafelyDestroyFrameListProp(aDestructRoot, shell, props,
+ SafelyDestroyFrameListProp(aDestructRoot, shell,
OutsideBulletProperty());
RemoveStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
}
@@ -1669,7 +1667,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
// our computed size due to overflowing their containing block. (E.g. this
// ensures we fill the last row when a multi-row grid item is fragmented).
bool found;
- nscoord bSize = Properties().Get(FragStretchBSizeProperty(), &found);
+ nscoord bSize = GetProperty(FragStretchBSizeProperty(), &found);
if (found) {
finalSize.BSize(wm) = std::max(bSize, finalSize.BSize(wm));
}
@@ -1679,7 +1677,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
if (MOZ_UNLIKELY(aReflowInput.mFlags.mBClampMarginBoxMinSize) &&
NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
bool found;
- nscoord cbSize = Properties().Get(BClampMarginBoxMinSizeProperty(), &found);
+ nscoord cbSize = GetProperty(BClampMarginBoxMinSizeProperty(), &found);
if (found) {
auto marginBoxBSize = finalSize.BSize(wm) +
aReflowInput.ComputedLogicalMargin().BStartEnd(wm);
@@ -1697,11 +1695,10 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
finalSize.BSize(wm) = std::max(0, finalSize.BSize(wm));
*aBEndEdgeOfChildren = blockEndEdgeOfChildren;
- FrameProperties properties = Properties();
if (blockEndEdgeOfChildren != finalSize.BSize(wm) - borderPadding.BEnd(wm)) {
- properties.Set(BlockEndEdgeOfChildrenProperty(), blockEndEdgeOfChildren);
+ SetProperty(BlockEndEdgeOfChildrenProperty(), blockEndEdgeOfChildren);
} else {
- properties.Delete(BlockEndEdgeOfChildrenProperty());
+ DeleteProperty(BlockEndEdgeOfChildrenProperty());
}
aMetrics.SetSize(wm, finalSize);
@@ -1834,7 +1831,7 @@ nsBlockFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas)
{
bool found;
nscoord blockEndEdgeOfChildren =
- Properties().Get(BlockEndEdgeOfChildrenProperty(), &found);
+ GetProperty(BlockEndEdgeOfChildrenProperty(), &found);
if (found) {
ConsiderBlockEndEdgeOfChildren(GetWritingMode(),
blockEndEdgeOfChildren, aOverflowAreas);
@@ -4985,7 +4982,7 @@ nsBlockFrame::GetOverflowLines() const
if (!HasOverflowLines()) {
return nullptr;
}
- FrameLines* prop = Properties().Get(OverflowLinesProperty());
+ FrameLines* prop = GetProperty(OverflowLinesProperty());
NS_ASSERTION(prop && !prop->mLines.empty() &&
prop->mLines.front()->GetChildCount() == 0 ? prop->mFrames.IsEmpty() :
prop->mLines.front()->mFirstChild == prop->mFrames.FirstChild(),
@@ -4999,7 +4996,7 @@ nsBlockFrame::RemoveOverflowLines()
if (!HasOverflowLines()) {
return nullptr;
}
- FrameLines* prop = Properties().Remove(OverflowLinesProperty());
+ FrameLines* prop = RemoveProperty(OverflowLinesProperty());
NS_ASSERTION(prop && !prop->mLines.empty() &&
prop->mLines.front()->GetChildCount() == 0 ? prop->mFrames.IsEmpty() :
prop->mLines.front()->mFirstChild == prop->mFrames.FirstChild(),
@@ -5012,7 +5009,7 @@ void
nsBlockFrame::DestroyOverflowLines()
{
NS_ASSERTION(HasOverflowLines(), "huh?");
- FrameLines* prop = Properties().Remove(OverflowLinesProperty());
+ FrameLines* prop = RemoveProperty(OverflowLinesProperty());
NS_ASSERTION(prop && prop->mLines.empty(),
"value should always be stored but empty when destroying");
RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_LINES);
@@ -5032,10 +5029,9 @@ nsBlockFrame::SetOverflowLines(FrameLines* aOverflowLines)
NS_ASSERTION(!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_LINES),
"Overwriting existing overflow lines");
- FrameProperties props = Properties();
// Verify that we won't overwrite an existing overflow list
- NS_ASSERTION(!props.Get(OverflowLinesProperty()), "existing overflow list");
- props.Set(OverflowLinesProperty(), aOverflowLines);
+ NS_ASSERTION(!GetProperty(OverflowLinesProperty()), "existing overflow list");
+ SetProperty(OverflowLinesProperty(), aOverflowLines);
AddStateBits(NS_BLOCK_HAS_OVERFLOW_LINES);
}
@@ -5088,7 +5084,7 @@ nsBlockFrame::GetInsideBullet() const
return nullptr;
}
NS_ASSERTION(!HasOutsideBullet(), "invalid bullet state");
- nsBulletFrame* frame = Properties().Get(InsideBulletProperty());
+ nsBulletFrame* frame = GetProperty(InsideBulletProperty());
NS_ASSERTION(frame && frame->GetType() == nsGkAtoms::bulletFrame,
"bogus inside bullet frame");
return frame;
@@ -5109,8 +5105,7 @@ nsBlockFrame::GetOutsideBulletList() const
return nullptr;
}
NS_ASSERTION(!HasInsideBullet(), "invalid bullet state");
- nsFrameList* list =
- Properties().Get(OutsideBulletProperty());
+ nsFrameList* list = GetProperty(OutsideBulletProperty());
NS_ASSERTION(list && list->GetLength() == 1 &&
list->FirstChild()->GetType() == nsGkAtoms::bulletFrame,
"bogus outside bullet list");
@@ -5123,8 +5118,7 @@ nsBlockFrame::GetPushedFloats() const
if (!HasPushedFloats()) {
return nullptr;
}
- nsFrameList* result =
- Properties().Get(PushedFloatProperty());
+ nsFrameList* result = GetProperty(PushedFloatProperty());
NS_ASSERTION(result, "value should always be non-empty when state set");
return result;
}
@@ -5137,7 +5131,7 @@ nsBlockFrame::EnsurePushedFloats()
return result;
result = new (PresContext()->PresShell()) nsFrameList;
- Properties().Set(PushedFloatProperty(), result);
+ SetProperty(PushedFloatProperty(), result);
AddStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
return result;
@@ -5149,7 +5143,7 @@ nsBlockFrame::RemovePushedFloats()
if (!HasPushedFloats()) {
return nullptr;
}
- nsFrameList *result = Properties().Remove(PushedFloatProperty());
+ nsFrameList *result = RemoveProperty(PushedFloatProperty());
RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
NS_ASSERTION(result, "value should always be non-empty when state set");
return result;
@@ -5619,7 +5613,7 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
if (mLine != line_end) {
*aFoundValidLine = true;
if (mLine != cursor) {
- aFrame->Properties().Set(nsBlockFrame::LineCursorProperty(), mLine);
+ aFrame->SetProperty(nsBlockFrame::LineCursorProperty(), mLine);
}
return;
}
@@ -6769,7 +6763,7 @@ void nsBlockFrame::ClearLineCursor()
return;
}
- Properties().Delete(LineCursorProperty());
+ DeleteProperty(LineCursorProperty());
RemoveStateBits(NS_BLOCK_HAS_LINE_CURSOR);
}
@@ -6780,7 +6774,7 @@ void nsBlockFrame::SetupLineCursor()
return;
}
- Properties().Set(LineCursorProperty(), mLines.front());
+ SetProperty(LineCursorProperty(), mLines.front());
AddStateBits(NS_BLOCK_HAS_LINE_CURSOR);
}
@@ -6790,9 +6784,7 @@ nsLineBox* nsBlockFrame::GetFirstLineContaining(nscoord y)
return nullptr;
}
- FrameProperties props = Properties();
-
- nsLineBox* property = props.Get(LineCursorProperty());
+ nsLineBox* property = GetProperty(LineCursorProperty());
LineIterator cursor = mLines.begin(property);
nsRect cursorArea = cursor->GetVisualOverflowArea();
@@ -6808,7 +6800,7 @@ nsLineBox* nsBlockFrame::GetFirstLineContaining(nscoord y)
}
if (cursor.get() != property) {
- props.Set(LineCursorProperty(), cursor.get());
+ SetProperty(LineCursorProperty(), cursor.get());
}
return cursor.get();
@@ -7021,11 +7013,11 @@ nsBlockFrame::CreateBulletFrameForListItem(bool aCreateBulletList,
if (aListStylePositionInside) {
nsFrameList bulletList(bullet, bullet);
AddFrames(bulletList, nullptr);
- Properties().Set(InsideBulletProperty(), bullet);
+ SetProperty(InsideBulletProperty(), bullet);
AddStateBits(NS_BLOCK_FRAME_HAS_INSIDE_BULLET);
} else {
nsFrameList* bulletList = new (shell) nsFrameList(bullet, bullet);
- Properties().Set(OutsideBulletProperty(), bulletList);
+ SetProperty(OutsideBulletProperty(), bulletList);
AddStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
}
}
diff --git a/layout/generic/nsBlockFrame.h b/layout/generic/nsBlockFrame.h
index bb41a6e99..f515cc26f 100644
--- a/layout/generic/nsBlockFrame.h
+++ b/layout/generic/nsBlockFrame.h
@@ -215,7 +215,7 @@ public:
~AutoLineCursorSetup()
{
if (mOrigCursor) {
- mFrame->Properties().Set(LineCursorProperty(), mOrigCursor);
+ mFrame->SetProperty(LineCursorProperty(), mOrigCursor);
} else {
mFrame->ClearLineCursor();
}
@@ -416,7 +416,7 @@ protected:
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(LineCursorProperty, nsLineBox)
bool HasLineCursor() { return GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR; }
nsLineBox* GetLineCursor() {
- return HasLineCursor() ? Properties().Get(LineCursorProperty()) : nullptr;
+ return HasLineCursor() ? GetProperty(LineCursorProperty()) : nullptr;
}
nsLineBox* NewLineBox(nsIFrame* aFrame, bool aIsBlock) {
diff --git a/layout/generic/nsBulletFrame.cpp b/layout/generic/nsBulletFrame.cpp
index aa8794321..f6595e8f6 100644
--- a/layout/generic/nsBulletFrame.cpp
+++ b/layout/generic/nsBulletFrame.cpp
@@ -903,7 +903,7 @@ nsBulletFrame::GetFontSizeInflation() const
if (!HasFontSizeInflation()) {
return 1.0f;
}
- return Properties().Get(FontSizeInflationProperty());
+ return GetProperty(FontSizeInflationProperty());
}
void
@@ -912,13 +912,13 @@ nsBulletFrame::SetFontSizeInflation(float aInflation)
if (aInflation == 1.0f) {
if (HasFontSizeInflation()) {
RemoveStateBits(BULLET_FRAME_HAS_FONT_INFLATION);
- Properties().Delete(FontSizeInflationProperty());
+ DeleteProperty(FontSizeInflationProperty());
}
return;
}
AddStateBits(BULLET_FRAME_HAS_FONT_INFLATION);
- Properties().Set(FontSizeInflationProperty(), aInflation);
+ SetProperty(FontSizeInflationProperty(), aInflation);
}
already_AddRefed<imgIContainer>
diff --git a/layout/generic/nsCanvasFrame.cpp b/layout/generic/nsCanvasFrame.cpp
index 70a2117cf..1a8812fb7 100644
--- a/layout/generic/nsCanvasFrame.cpp
+++ b/layout/generic/nsCanvasFrame.cpp
@@ -300,7 +300,7 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
// above.
destRect.Round();
RefPtr<DrawTarget> dt =
- Frame()->Properties().Get(nsIFrame::CachedBackgroundImageDT());
+ Frame()->GetProperty(nsIFrame::CachedBackgroundImageDT());
DrawTarget* destDT = dest->GetDrawTarget();
if (dt) {
BlitSurface(destDT, destRect, dt);
@@ -317,7 +317,7 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext context(ctx);
PaintInternal(aBuilder, &context, bgClipRect, &bgClipRect);
BlitSurface(dest->GetDrawTarget(), destRect, dt);
- frame->Properties().Set(nsIFrame::CachedBackgroundImageDT(),
+ frame->SetProperty(nsIFrame::CachedBackgroundImageDT(),
dt.forget().take());
return;
}
diff --git a/layout/generic/nsCanvasFrame.h b/layout/generic/nsCanvasFrame.h
index 236ffb9c7..8bd9dbf79 100644
--- a/layout/generic/nsCanvasFrame.h
+++ b/layout/generic/nsCanvasFrame.h
@@ -201,7 +201,7 @@ public:
virtual void NotifyRenderingChanged() override
{
- mFrame->Properties().Delete(nsIFrame::CachedBackgroundImageDT());
+ mFrame->DeleteProperty(nsIFrame::CachedBackgroundImageDT());
}
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override
diff --git a/layout/generic/nsContainerFrame.cpp b/layout/generic/nsContainerFrame.cpp
index 813d19dfe..abf687c9b 100644
--- a/layout/generic/nsContainerFrame.cpp
+++ b/layout/generic/nsContainerFrame.cpp
@@ -78,7 +78,7 @@ nsContainerFrame::SetInitialChildList(ChildListID aListID,
"Only top layer frames should have backdrop");
MOZ_ASSERT(GetStateBits() & NS_FRAME_OUT_OF_FLOW,
"Top layer frames should be out-of-flow");
- MOZ_ASSERT(!Properties().Get(BackdropProperty()),
+ MOZ_ASSERT(!GetProperty(BackdropProperty()),
"We shouldn't have setup backdrop frame list before");
#ifdef DEBUG
{
@@ -93,7 +93,7 @@ nsContainerFrame::SetInitialChildList(ChildListID aListID,
#endif
nsFrameList* list =
new (PresContext()->PresShell()) nsFrameList(aChildList);
- Properties().Set(BackdropProperty(), list);
+ SetProperty(BackdropProperty(), list);
} else {
MOZ_ASSERT_UNREACHABLE("Unexpected child list");
}
@@ -189,18 +189,17 @@ nsContainerFrame::DestroyAbsoluteFrames(nsIFrame* aDestructRoot)
void
nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell,
- FramePropertyTable* aPropTable,
FrameListPropertyDescriptor aProp)
{
// Note that the last frame can be removed through another route and thus
// delete the property -- that's why we fetch the property again before
// removing each frame rather than fetching it once and iterating the list.
- while (nsFrameList* frameList = aPropTable->Get(this, aProp)) {
+ while (nsFrameList* frameList = GetProperty(aProp)) {
nsIFrame* frame = frameList->RemoveFirstChild();
if (MOZ_LIKELY(frame)) {
frame->DestroyFrom(aDestructRoot);
} else {
- aPropTable->Remove(this, aProp);
+ RemoveProperty(aProp);
frameList->Delete(aPresShell);
return;
}
@@ -220,25 +219,49 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot)
// Destroy frames on the principal child list.
mFrames.DestroyFramesFrom(aDestructRoot);
+
+ if (MOZ_UNLIKELY(!mProperties.IsEmpty())) {
+ using T = mozilla::FrameProperties::UntypedDescriptor;
+ bool hasO = false, hasOC = false, hasEOC = false, hasBackdrop = false;
+ mProperties.ForEach([&] (const T& aProp, void*) {
+ if (aProp == OverflowProperty()) {
+ hasO = true;
+ } else if (aProp == OverflowContainersProperty()) {
+ hasOC = true;
+ } else if (aProp == ExcessOverflowContainersProperty()) {
+ hasEOC = true;
+ } else if (aProp == BackdropProperty()) {
+ hasBackdrop = true;
+ }
+ return true;
+ });
+
// Destroy frames on the auxiliary frame lists and delete the lists.
nsPresContext* pc = PresContext();
nsIPresShell* shell = pc->PresShell();
- FramePropertyTable* props = pc->PropertyTable();
- SafelyDestroyFrameListProp(aDestructRoot, shell, props, OverflowProperty());
-
- MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers) ||
- !(props->Get(this, nsContainerFrame::OverflowContainersProperty()) ||
- props->Get(this, nsContainerFrame::ExcessOverflowContainersProperty())),
- "this type of frame should't have overflow containers");
- SafelyDestroyFrameListProp(aDestructRoot, shell, props,
- OverflowContainersProperty());
- SafelyDestroyFrameListProp(aDestructRoot, shell, props,
- ExcessOverflowContainersProperty());
-
- MOZ_ASSERT(!props->Get(this, BackdropProperty()) ||
+ if (hasO) {
+ SafelyDestroyFrameListProp(aDestructRoot, shell, OverflowProperty());
+ }
+
+ MOZ_ASSERT(IsFrameOfType(eCanContainOverflowContainers) ||
+ !(hasOC || hasEOC),
+ "this type of frame shouldn't have overflow containers");
+ if (hasOC) {
+ SafelyDestroyFrameListProp(aDestructRoot, shell,
+ OverflowContainersProperty());
+ }
+ if (hasEOC) {
+ SafelyDestroyFrameListProp(aDestructRoot, shell,
+ ExcessOverflowContainersProperty());
+ }
+
+ MOZ_ASSERT(!GetProperty(BackdropProperty()) ||
StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE,
"only top layer frame may have backdrop");
- SafelyDestroyFrameListProp(aDestructRoot, shell, props, BackdropProperty());
+ if (hasBackdrop) {
+ SafelyDestroyFrameListProp(aDestructRoot, shell, BackdropProperty());
+ }
+}
nsSplittableFrame::DestroyFrom(aDestructRoot);
}
@@ -276,38 +299,28 @@ nsContainerFrame::GetChildList(ChildListID aListID) const
}
}
-static void
-AppendIfNonempty(const nsIFrame* aFrame,
- FramePropertyTable* aPropTable,
- nsContainerFrame::FrameListPropertyDescriptor aProperty,
- nsTArray<nsIFrame::ChildList>* aLists,
- nsIFrame::ChildListID aListID)
-{
- if (nsFrameList* list = aPropTable->Get(aFrame, aProperty)) {
- list->AppendIfNonempty(aLists, aListID);
- }
-}
-
void
nsContainerFrame::GetChildLists(nsTArray<ChildList>* aLists) const
{
mFrames.AppendIfNonempty(aLists, kPrincipalList);
- FramePropertyTable* propTable = PresContext()->PropertyTable();
- ::AppendIfNonempty(this, propTable, OverflowProperty(),
- aLists, kOverflowList);
- if (IsFrameOfType(nsIFrame::eCanContainOverflowContainers)) {
- ::AppendIfNonempty(this, propTable, OverflowContainersProperty(),
- aLists, kOverflowContainersList);
- ::AppendIfNonempty(this, propTable, ExcessOverflowContainersProperty(),
- aLists, kExcessOverflowContainersList);
- }
- // Bypass BackdropProperty hashtable lookup for any in-flow frames
- // since frames in the top layer (only which can have backdrop) are
- // definitely out-of-flow.
- if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) {
- ::AppendIfNonempty(this, propTable, BackdropProperty(),
- aLists, kBackdropList);
- }
+ using T = mozilla::FrameProperties::UntypedDescriptor;
+ mProperties.ForEach([this, aLists] (const T& aProp, void* aValue) {
+ typedef const nsFrameList* L;
+ if (aProp == OverflowProperty()) {
+ L(aValue)->AppendIfNonempty(aLists, kOverflowList);
+ } else if (aProp == OverflowContainersProperty()) {
+ MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
+ "found unexpected OverflowContainersProperty");
+ L(aValue)->AppendIfNonempty(aLists, kOverflowContainersList);
+ } else if (aProp == ExcessOverflowContainersProperty()) {
+ MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
+ "found unexpected ExcessOverflowContainersProperty");
+ L(aValue)->AppendIfNonempty(aLists, kExcessOverflowContainersList);
+ } else if (aProp == BackdropProperty()) {
+ L(aValue)->AppendIfNonempty(aLists, kBackdropList);
+ }
+ return true;
+ });
nsSplittableFrame::GetChildLists(aLists);
}
@@ -1335,15 +1348,15 @@ nsContainerFrame::DisplayOverflowContainers(nsDisplayListBuilder* aBuilder,
}
static bool
-TryRemoveFrame(nsIFrame* aFrame, FramePropertyTable* aPropTable,
+TryRemoveFrame(nsIFrame* aFrame,
nsContainerFrame::FrameListPropertyDescriptor aProp,
nsIFrame* aChildToRemove)
{
- nsFrameList* list = aPropTable->Get(aFrame, aProp);
+ nsFrameList* list = aFrame->GetProperty(aProp);
if (list && list->StartRemoveFrame(aChildToRemove)) {
// aChildToRemove *may* have been removed from this list.
if (list->IsEmpty()) {
- aPropTable->Remove(aFrame, aProp);
+ aFrame->RemoveProperty(aProp);
list->Delete(aFrame->PresContext()->PresShell());
}
return true;
@@ -1356,13 +1369,12 @@ nsContainerFrame::MaybeStealOverflowContainerFrame(nsIFrame* aChild)
{
bool removed = false;
if (MOZ_UNLIKELY(aChild->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
- FramePropertyTable* propTable = PresContext()->PropertyTable();
// Try removing from the overflow container list.
- removed = ::TryRemoveFrame(this, propTable, OverflowContainersProperty(),
+ removed = ::TryRemoveFrame(this, OverflowContainersProperty(),
aChild);
if (!removed) {
// It might be in the excess overflow container list.
- removed = ::TryRemoveFrame(this, propTable,
+ removed = ::TryRemoveFrame(this,
ExcessOverflowContainersProperty(),
aChild);
}
@@ -1377,10 +1389,9 @@ nsContainerFrame::StealFrame(nsIFrame* aChild)
if (!mFrames.ContainsFrame(aChild)) {
nsFrameList* list = GetOverflowFrames();
if (!list || !list->ContainsFrame(aChild)) {
- FramePropertyTable* propTable = PresContext()->PropertyTable();
- list = propTable->Get(this, OverflowContainersProperty());
+ list = GetProperty(OverflowContainersProperty());
if (!list || !list->ContainsFrame(aChild)) {
- list = propTable->Get(this, ExcessOverflowContainersProperty());
+ list = GetProperty(ExcessOverflowContainersProperty());
MOZ_ASSERT(list && list->ContainsFrame(aChild), "aChild isn't our child"
" or on a frame list not supported by StealFrame");
}
@@ -1536,20 +1547,20 @@ nsContainerFrame::SetOverflowFrames(const nsFrameList& aOverflowFrames)
nsPresContext* pc = PresContext();
nsFrameList* newList = new (pc->PresShell()) nsFrameList(aOverflowFrames);
- pc->PropertyTable()->Set(this, OverflowProperty(), newList);
+ SetProperty(OverflowProperty(), newList);
}
nsFrameList*
nsContainerFrame::GetPropTableFrames(
FrameListPropertyDescriptor aProperty) const
{
- return PresContext()->PropertyTable()->Get(this, aProperty);
+ return GetProperty(aProperty);
}
nsFrameList*
nsContainerFrame::RemovePropTableFrames(FrameListPropertyDescriptor aProperty)
{
- return PresContext()->PropertyTable()->Remove(this, aProperty);
+ return RemoveProperty(aProperty);
}
void
@@ -1563,7 +1574,7 @@ nsContainerFrame::SetPropTableFrames(nsFrameList* aFrameList,
IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
"this type of frame can't have overflow containers");
MOZ_ASSERT(!GetPropTableFrames(aProperty));
- PresContext()->PropertyTable()->Set(this, aProperty, aFrameList);
+ SetProperty(aProperty, aFrameList);
}
/**
@@ -2253,13 +2264,11 @@ nsOverflowContinuationTracker::EndFinish(nsIFrame* aChild)
return;
}
// Forget mOverflowContList if it was deleted.
- nsPresContext* pc = aChild->PresContext();
- FramePropertyTable* propTable = pc->PropertyTable();
- nsFrameList* eoc = propTable->Get(
- mParent, nsContainerFrame::ExcessOverflowContainersProperty());
+ nsFrameList* eoc = mParent->GetProperty
+ (nsContainerFrame::ExcessOverflowContainersProperty());
if (eoc != mOverflowContList) {
- nsFrameList* oc = static_cast<nsFrameList*>(propTable->Get(mParent,
- nsContainerFrame::OverflowContainersProperty()));
+ nsFrameList* oc = static_cast<nsFrameList*>(mParent->GetProperty
+ (nsContainerFrame::OverflowContainersProperty()));
if (oc != mOverflowContList) {
// mOverflowContList was deleted
mPrevOverflowCont = nullptr;
diff --git a/layout/generic/nsContainerFrame.h b/layout/generic/nsContainerFrame.h
index a9f6d52df..ddf993d91 100644
--- a/layout/generic/nsContainerFrame.h
+++ b/layout/generic/nsContainerFrame.h
@@ -24,9 +24,6 @@
#define NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD 0x0010
class nsOverflowContinuationTracker;
-namespace mozilla {
-class FramePropertyTable;
-} // namespace mozilla
// Some macros for container classes to do sanity checking on
// width/height/x/y values computed during reflow.
@@ -548,7 +545,7 @@ public:
// Use this to suppress the CRAZY_SIZE assertions.
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugReflowingWithInfiniteISize, bool)
bool IsCrazySizeAssertSuppressed() const {
- return Properties().Get(DebugReflowingWithInfiniteISize());
+ return GetProperty(DebugReflowingWithInfiniteISize());
}
#endif
@@ -716,7 +713,6 @@ protected:
*/
void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell,
- mozilla::FramePropertyTable* aPropTable,
FrameListPropertyDescriptor aProp);
// ==========================================================================
@@ -898,7 +894,7 @@ inline
nsFrameList*
nsContainerFrame::GetOverflowFrames() const
{
- nsFrameList* list = Properties().Get(OverflowProperty());
+ nsFrameList* list = GetProperty(OverflowProperty());
NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
return list;
}
@@ -907,7 +903,7 @@ inline
nsFrameList*
nsContainerFrame::StealOverflowFrames()
{
- nsFrameList* list = Properties().Remove(OverflowProperty());
+ nsFrameList* list = RemoveProperty(OverflowProperty());
NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
return list;
}
diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp
index 3818d3cb7..94bce1e7a 100644
--- a/layout/generic/nsFlexContainerFrame.cpp
+++ b/layout/generic/nsFlexContainerFrame.cpp
@@ -1816,8 +1816,8 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem(
nsPresContext* aPresContext,
ReflowInput& aChildReflowInput)
{
- const FrameProperties props = aItem.Frame()->Properties();
- if (const auto* cachedResult = props.Get(CachedFlexMeasuringReflow())) {
+ if (const auto* cachedResult =
+ aItem.Frame()->GetProperty(CachedFlexMeasuringReflow())) {
if (cachedResult->IsValidFor(aChildReflowInput)) {
return *cachedResult;
}
@@ -1847,7 +1847,7 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem(
auto result =
new CachedMeasuringReflowResult(aChildReflowInput, childDesiredSize);
- props.Set(CachedFlexMeasuringReflow(), result);
+ aItem.Frame()->SetProperty(CachedFlexMeasuringReflow(), result);
return *result;
}
@@ -1855,7 +1855,7 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem(
nsFlexContainerFrame::MarkIntrinsicISizesDirty()
{
for (nsIFrame* childFrame : mFrames) {
- childFrame->Properties().Delete(CachedFlexMeasuringReflow());
+ childFrame->DeleteProperty(CachedFlexMeasuringReflow());
}
nsContainerFrame::MarkIntrinsicISizesDirty();
}
@@ -4236,25 +4236,26 @@ class MOZ_RAII AutoFlexItemMainSizeOverride final
public:
explicit AutoFlexItemMainSizeOverride(FlexItem& aItem
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
- : mItemProps(aItem.Frame()->Properties())
+ : mItemFrame(aItem.Frame())
{
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
- MOZ_ASSERT(!mItemProps.Has(nsIFrame::FlexItemMainSizeOverride()),
+ MOZ_ASSERT(!mItemFrame->HasProperty(nsIFrame::FlexItemMainSizeOverride()),
"FlexItemMainSizeOverride prop shouldn't be set already; "
"it should only be set temporarily (& not recursively)");
NS_ASSERTION(aItem.HasIntrinsicRatio(),
"This should only be needed for items with an aspect ratio");
- mItemProps.Set(nsIFrame::FlexItemMainSizeOverride(), aItem.GetMainSize());
+ mItemFrame->SetProperty(nsIFrame::FlexItemMainSizeOverride(),
+ aItem.GetMainSize());
}
~AutoFlexItemMainSizeOverride() {
- mItemProps.Remove(nsIFrame::FlexItemMainSizeOverride());
+ mItemFrame->RemoveProperty(nsIFrame::FlexItemMainSizeOverride());
}
private:
- const FrameProperties mItemProps;
+ nsIFrame* mItemFrame;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
@@ -4668,8 +4669,7 @@ nsFlexContainerFrame::MoveFlexItemToFinalPosition(
// If item is relpos, look up its offsets (cached from prev reflow)
LogicalMargin logicalOffsets(outerWM);
if (NS_STYLE_POSITION_RELATIVE == aItem.Frame()->StyleDisplay()->mPosition) {
- FrameProperties props = aItem.Frame()->Properties();
- nsMargin* cachedOffsets = props.Get(nsIFrame::ComputedOffsetProperty());
+ nsMargin* cachedOffsets = aItem.Frame()->GetProperty(nsIFrame::ComputedOffsetProperty());
MOZ_ASSERT(cachedOffsets,
"relpos previously-reflowed frame should've cached its offsets");
logicalOffsets = LogicalMargin(outerWM, *cachedOffsets);
diff --git a/layout/generic/nsFloatManager.cpp b/layout/generic/nsFloatManager.cpp
index 2c0ff1f38..4e7e7ff91 100644
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -331,7 +331,7 @@ nsFloatManager::GetRegionFor(WritingMode aWM, nsIFrame* aFloat,
const nsSize& aContainerSize)
{
LogicalRect region = aFloat->GetLogicalRect(aWM, aContainerSize);
- void* storedRegion = aFloat->Properties().Get(FloatRegionProperty());
+ void* storedRegion = aFloat->GetProperty(FloatRegionProperty());
if (storedRegion) {
nsMargin margin = *static_cast<nsMargin*>(storedRegion);
region.Inflate(aWM, LogicalMargin(aWM, margin));
@@ -346,15 +346,14 @@ nsFloatManager::StoreRegionFor(WritingMode aWM, nsIFrame* aFloat,
{
nsRect region = aRegion.GetPhysicalRect(aWM, aContainerSize);
nsRect rect = aFloat->GetRect();
- FrameProperties props = aFloat->Properties();
if (region.IsEqualEdges(rect)) {
- props.Delete(FloatRegionProperty());
+ aFloat->DeleteProperty(FloatRegionProperty());
}
else {
- nsMargin* storedMargin = props.Get(FloatRegionProperty());
+ nsMargin* storedMargin = aFloat->GetProperty(FloatRegionProperty());
if (!storedMargin) {
storedMargin = new nsMargin();
- props.Set(FloatRegionProperty(), storedMargin);
+ aFloat->SetProperty(FloatRegionProperty(), storedMargin);
}
*storedMargin = region - rect;
}
diff --git a/layout/generic/nsFontInflationData.cpp b/layout/generic/nsFontInflationData.cpp
index 9e9a51999..831658c9e 100644
--- a/layout/generic/nsFontInflationData.cpp
+++ b/layout/generic/nsFontInflationData.cpp
@@ -6,7 +6,7 @@
/* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */
#include "nsFontInflationData.h"
-#include "FramePropertyTable.h"
+#include "FrameProperties.h"
#include "nsTextControlFrame.h"
#include "nsListControlFrame.h"
#include "nsComboboxControlFrame.h"
@@ -27,7 +27,7 @@ nsFontInflationData::FindFontInflationDataFor(const nsIFrame *aFrame)
NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT,
"should have found a flow root");
- return bfc->Properties().Get(FontInflationDataProperty());
+ return bfc->GetProperty(FontInflationDataProperty());
}
/* static */ bool
@@ -36,8 +36,7 @@ nsFontInflationData::UpdateFontInflationDataISizeFor(const ReflowInput& aReflowI
nsIFrame *bfc = aReflowInput.mFrame;
NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT,
"should have been given a flow root");
- FrameProperties bfcProps(bfc->Properties());
- nsFontInflationData *data = bfcProps.Get(FontInflationDataProperty());
+ nsFontInflationData *data = bfc->GetProperty(FontInflationDataProperty());
bool oldInflationEnabled;
nscoord oldNCAISize;
if (data) {
@@ -45,7 +44,7 @@ nsFontInflationData::UpdateFontInflationDataISizeFor(const ReflowInput& aReflowI
oldInflationEnabled = data->mInflationEnabled;
} else {
data = new nsFontInflationData(bfc);
- bfcProps.Set(FontInflationDataProperty(), data);
+ bfc->SetProperty(FontInflationDataProperty(), data);
oldNCAISize = -1;
oldInflationEnabled = true; /* not relevant */
}
@@ -65,8 +64,7 @@ nsFontInflationData::MarkFontInflationDataTextDirty(nsIFrame *aBFCFrame)
NS_ASSERTION(aBFCFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT,
"should have been given a flow root");
- FrameProperties bfcProps(aBFCFrame->Properties());
- nsFontInflationData *data = bfcProps.Get(FontInflationDataProperty());
+ nsFontInflationData *data = aBFCFrame->GetProperty(FontInflationDataProperty());
if (data) {
data->MarkTextDirty();
}
diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp
index fa5b24d40..bd96f213b 100644
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -168,13 +168,12 @@ NS_DECLARE_FRAME_PROPERTY_DELETABLE(BoxMetricsProperty, nsBoxLayoutMetrics)
static void
InitBoxMetrics(nsIFrame* aFrame, bool aClear)
{
- FrameProperties props = aFrame->Properties();
if (aClear) {
- props.Delete(BoxMetricsProperty());
+ aFrame->DeleteProperty(BoxMetricsProperty());
}
nsBoxLayoutMetrics* metrics = new nsBoxLayoutMetrics();
- props.Set(BoxMetricsProperty(), metrics);
+ aFrame->SetProperty(BoxMetricsProperty(), metrics);
static_cast<nsFrame*>(aFrame)->nsFrame::MarkIntrinsicISizesDirty();
metrics->mBlockAscent = 0;
@@ -254,7 +253,7 @@ nsIFrame::HasAbsolutelyPositionedChildren() const {
nsAbsoluteContainingBlock*
nsIFrame::GetAbsoluteContainingBlock() const {
NS_ASSERTION(IsAbsoluteContainer(), "The frame is not marked as an abspos container correctly");
- nsAbsoluteContainingBlock* absCB = Properties().Get(AbsoluteContainingBlockProperty());
+ nsAbsoluteContainingBlock* absCB = GetProperty(AbsoluteContainingBlockProperty());
NS_ASSERTION(absCB, "The frame is marked as an abspos container but doesn't have the property");
return absCB;
}
@@ -263,25 +262,25 @@ void
nsIFrame::MarkAsAbsoluteContainingBlock()
{
MOZ_ASSERT(GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN);
- NS_ASSERTION(!Properties().Get(AbsoluteContainingBlockProperty()),
+ NS_ASSERTION(!GetProperty(AbsoluteContainingBlockProperty()),
"Already has an abs-pos containing block property?");
NS_ASSERTION(!HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN),
"Already has NS_FRAME_HAS_ABSPOS_CHILDREN state bit?");
AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
- Properties().Set(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID()));
+ SetProperty(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID()));
}
void
nsIFrame::MarkAsNotAbsoluteContainingBlock()
{
NS_ASSERTION(!HasAbsolutelyPositionedChildren(), "Think of the children!");
- NS_ASSERTION(Properties().Get(AbsoluteContainingBlockProperty()),
+ NS_ASSERTION(GetProperty(AbsoluteContainingBlockProperty()),
"Should have an abs-pos containing block property");
NS_ASSERTION(HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN),
"Should have NS_FRAME_HAS_ABSPOS_CHILDREN state bit");
MOZ_ASSERT(HasAnyStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN));
RemoveStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
- Properties().Delete(AbsoluteContainingBlockProperty());
+ DeleteProperty(AbsoluteContainingBlockProperty());
}
bool
@@ -652,32 +651,30 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
}
// If we have any IB split siblings, clear their references to us.
- // (Note: This has to happen before we call shell->NotifyDestroyingFrame,
- // because that clears our Properties() table.)
+ // (Note: This has to happen before we clear our Properties() table.)
if (mState & NS_FRAME_PART_OF_IBSPLIT) {
// Delete previous sibling's reference to me.
- nsIFrame* prevSib = Properties().Get(nsIFrame::IBSplitPrevSibling());
+ nsIFrame* prevSib = GetProperty(nsIFrame::IBSplitPrevSibling());
if (prevSib) {
NS_WARNING_ASSERTION(
- this == prevSib->Properties().Get(nsIFrame::IBSplitSibling()),
+ this == prevSib->GetProperty(nsIFrame::IBSplitSibling()),
"IB sibling chain is inconsistent");
- prevSib->Properties().Delete(nsIFrame::IBSplitSibling());
+ prevSib->DeleteProperty(nsIFrame::IBSplitSibling());
}
// Delete next sibling's reference to me.
- nsIFrame* nextSib = Properties().Get(nsIFrame::IBSplitSibling());
+ nsIFrame* nextSib = GetProperty(nsIFrame::IBSplitSibling());
if (nextSib) {
NS_WARNING_ASSERTION(
- this == nextSib->Properties().Get(nsIFrame::IBSplitPrevSibling()),
+ this == nextSib->GetProperty(nsIFrame::IBSplitPrevSibling()),
"IB sibling chain is inconsistent");
- nextSib->Properties().Delete(nsIFrame::IBSplitPrevSibling());
+ nextSib->DeleteProperty(nsIFrame::IBSplitPrevSibling());
}
}
bool isPrimaryFrame = (mContent && mContent->GetPrimaryFrame() == this);
if (isPrimaryFrame) {
- // This needs to happen before shell->NotifyDestroyingFrame because
- // that clears our Properties() table.
+ // This needs to happen before we clear our Properties() table.
ActiveLayerTracker::TransferActivityToContent(this, mContent);
// Unfortunately, we need to do this for all frames being reframed
@@ -712,9 +709,8 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
}
}
- // Disable visibility tracking. Note that we have to do this before calling
- // NotifyDestroyingFrame(), which will clear frame properties and make us lose
- // track of whether we were previously visible or not.
+ // Disable visibility tracking. Note that we have to do this before we clear
+ // frame properties and lose track of whether we were previously visible.
// XXX(seth): It'd be ideal to assert that we're already marked nonvisible
// here, but it's unfortunately tricky to guarantee in the face of things like
// frame reconstruction induced by style changes.
@@ -742,6 +738,10 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
mContent->SetPrimaryFrame(nullptr);
}
+ // Delete all properties attached to the frame, to ensure any property
+ // destructors that need the frame pointer are handled properly.
+ DeleteAllProperties();
+
// Must retrieve the object ID before calling destructors, so the
// vtable is still valid.
//
@@ -860,22 +860,21 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
// calls GetUsed(Margin|Border|Padding)() before the next reflow, we
// can give an accurate answer.
// We don't want to set the property if one already exists.
- FrameProperties props = Properties();
nsMargin oldValue(0, 0, 0, 0);
nsMargin newValue(0, 0, 0, 0);
const nsStyleMargin* oldMargin = aOldStyleContext->PeekStyleMargin();
if (oldMargin && oldMargin->GetMargin(oldValue)) {
if ((!StyleMargin()->GetMargin(newValue) || oldValue != newValue) &&
- !props.Get(UsedMarginProperty())) {
- props.Set(UsedMarginProperty(), new nsMargin(oldValue));
+ !GetProperty(UsedMarginProperty())) {
+ SetProperty(UsedMarginProperty(), new nsMargin(oldValue));
}
}
const nsStylePadding* oldPadding = aOldStyleContext->PeekStylePadding();
if (oldPadding && oldPadding->GetPadding(oldValue)) {
if ((!StylePadding()->GetPadding(newValue) || oldValue != newValue) &&
- !props.Get(UsedPaddingProperty())) {
- props.Set(UsedPaddingProperty(), new nsMargin(oldValue));
+ !GetProperty(UsedPaddingProperty())) {
+ SetProperty(UsedPaddingProperty(), new nsMargin(oldValue));
}
}
@@ -884,8 +883,8 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
oldValue = oldBorder->GetComputedBorder();
newValue = StyleBorder()->GetComputedBorder();
if (oldValue != newValue &&
- !props.Get(UsedBorderProperty())) {
- props.Set(UsedBorderProperty(), new nsMargin(oldValue));
+ !GetProperty(UsedBorderProperty())) {
+ SetProperty(UsedBorderProperty(), new nsMargin(oldValue));
}
}
}
@@ -961,7 +960,7 @@ nsIFrame::GetUsedMargin() const
IsSVGText())
return margin;
- nsMargin *m = Properties().Get(UsedMarginProperty());
+ nsMargin *m = GetProperty(UsedMarginProperty());
if (m) {
margin = *m;
} else {
@@ -1000,7 +999,7 @@ nsIFrame::GetUsedBorder() const
return border;
}
- nsMargin *b = Properties().Get(UsedBorderProperty());
+ nsMargin *b = GetProperty(UsedBorderProperty());
if (b) {
border = *b;
} else {
@@ -1037,7 +1036,7 @@ nsIFrame::GetUsedPadding() const
}
}
- nsMargin *p = Properties().Get(UsedPaddingProperty());
+ nsMargin *p = GetProperty(UsedPaddingProperty());
if (p) {
padding = *p;
} else {
@@ -1478,8 +1477,7 @@ nsIFrame::GetVisibility() const
}
bool isSet = false;
- FrameProperties props = Properties();
- uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
+ uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is set");
@@ -1552,15 +1550,14 @@ nsIFrame::EnableVisibilityTracking()
return; // Nothing to do.
}
- FrameProperties props = Properties();
- MOZ_ASSERT(!props.Has(VisibilityStateProperty()),
+ MOZ_ASSERT(!HasProperty(VisibilityStateProperty()),
"Shouldn't have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is not set");
// Add the state bit so we know to track visibility for this frame, and
// initialize the frame property.
AddStateBits(NS_FRAME_VISIBILITY_IS_TRACKED);
- props.Set(VisibilityStateProperty(), 0);
+ SetProperty(VisibilityStateProperty(), 0);
nsIPresShell* presShell = PresContext()->PresShell();
if (!presShell) {
@@ -1582,8 +1579,7 @@ nsIFrame::DisableVisibilityTracking()
}
bool isSet = false;
- FrameProperties props = Properties();
- uint32_t visibleCount = props.Remove(VisibilityStateProperty(), &isSet);
+ uint32_t visibleCount = RemoveProperty(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is set");
@@ -1605,8 +1601,7 @@ nsIFrame::DecApproximateVisibleCount(Maybe<OnNonvisible> aNonvisibleAction
MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED);
bool isSet = false;
- FrameProperties props = Properties();
- uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
+ uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is set");
@@ -1614,7 +1609,7 @@ nsIFrame::DecApproximateVisibleCount(Maybe<OnNonvisible> aNonvisibleAction
"decrementing its visible count?");
visibleCount--;
- props.Set(VisibilityStateProperty(), visibleCount);
+ SetProperty(VisibilityStateProperty(), visibleCount);
if (visibleCount > 0) {
return;
}
@@ -1629,14 +1624,13 @@ nsIFrame::IncApproximateVisibleCount()
MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED);
bool isSet = false;
- FrameProperties props = Properties();
- uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
+ uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is set");
visibleCount++;
- props.Set(VisibilityStateProperty(), visibleCount);
+ SetProperty(VisibilityStateProperty(), visibleCount);
if (visibleCount > 1) {
return;
}
@@ -4943,10 +4937,9 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
// If FlexItemMainSizeOverride frame-property is set, then that means the
// flex container is imposing a main-size on this flex item for it to use
// as its size in the container's main axis.
- FrameProperties props = Properties();
bool didImposeMainSize;
nscoord imposedMainSize =
- props.Get(nsIFrame::FlexItemMainSizeOverride(), &didImposeMainSize);
+ GetProperty(nsIFrame::FlexItemMainSizeOverride(), &didImposeMainSize);
if (didImposeMainSize) {
imposedMainSizeStyleCoord.emplace(imposedMainSize,
nsStyleCoord::CoordConstructor);
@@ -5686,7 +5679,7 @@ nsIFrame::GetView() const
return nullptr;
// Check for a property on the frame
- nsView* value = Properties().Get(ViewProperty());
+ nsView* value = GetProperty(ViewProperty());
NS_ASSERTION(value, "frame state bit was set but frame has no view");
return value;
}
@@ -5709,7 +5702,7 @@ nsIFrame::SetView(nsView* aView)
#endif
// Set a property on the frame
- Properties().Set(ViewProperty(), aView);
+ SetProperty(ViewProperty(), aView);
// Set the frame state bit that says the frame has a view
AddStateBits(NS_FRAME_HAS_VIEW);
@@ -6098,7 +6091,7 @@ static void InvalidateFrameInternal(nsIFrame *aFrame, bool aHasDisplayItem = tru
SchedulePaintInternal(aFrame);
}
if (aFrame->HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) {
- aFrame->Properties().Delete(nsIFrame::InvalidationRect());
+ aFrame->DeleteProperty(nsIFrame::InvalidationRect());
aFrame->RemoveStateBits(NS_FRAME_HAS_INVALID_RECT);
}
}
@@ -6173,13 +6166,13 @@ nsIFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey)
return;
}
- nsRect* rect = Properties().Get(InvalidationRect());
+ nsRect* rect = GetProperty(InvalidationRect());
if (!rect) {
if (alreadyInvalid) {
return;
}
rect = new nsRect();
- Properties().Set(InvalidationRect(), rect);
+ SetProperty(InvalidationRect(), rect);
AddStateBits(NS_FRAME_HAS_INVALID_RECT);
}
@@ -6280,7 +6273,7 @@ nsIFrame::IsInvalid(nsRect& aRect)
}
if (HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) {
- nsRect* rect = Properties().Get(InvalidationRect());
+ nsRect* rect = GetProperty(InvalidationRect());
NS_ASSERTION(rect, "Must have an invalid rect if NS_FRAME_HAS_INVALID_RECT is set!");
aRect = *rect;
} else {
@@ -6368,8 +6361,8 @@ ComputeEffectsRect(nsIFrame* aFrame, const nsRect& aOverflowRect,
// TODO: We could also take account of clipPath and mask to reduce the
// visual overflow, but that's not essential.
if (aFrame->StyleEffects()->HasFilters()) {
- aFrame->Properties().
- Set(nsIFrame::PreEffectsBBoxProperty(), new nsRect(r));
+ aFrame->SetProperty
+ (nsIFrame::PreEffectsBBoxProperty(), new nsRect(r));
r = nsSVGUtils::GetPostFilterVisualOverflowRect(aFrame, aOverflowRect);
}
return r;
@@ -6407,8 +6400,8 @@ ComputeEffectsRect(nsIFrame* aFrame, const nsRect& aOverflowRect,
// the frame dies.
if (nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame)) {
- aFrame->Properties().
- Set(nsIFrame::PreEffectsBBoxProperty(), new nsRect(r));
+ aFrame->SetProperty
+ (nsIFrame::PreEffectsBBoxProperty(), new nsRect(r));
r = nsSVGIntegrationUtils::ComputePostEffectsVisualOverflowRect(aFrame, r);
}
@@ -6422,7 +6415,7 @@ nsIFrame::MovePositionBy(const nsPoint& aTranslation)
const nsMargin* computedOffsets = nullptr;
if (IsRelativelyPositioned()) {
- computedOffsets = Properties().Get(nsIFrame::ComputedOffsetProperty());
+ computedOffsets = GetProperty(nsIFrame::ComputedOffsetProperty());
}
ReflowInput::ApplyRelativePositioning(this, computedOffsets ?
*computedOffsets : nsMargin(),
@@ -6435,7 +6428,7 @@ nsIFrame::GetNormalRect() const
{
// It might be faster to first check
// StyleDisplay()->IsRelativelyPositionedStyle().
- nsPoint* normalPosition = Properties().Get(NormalPositionProperty());
+ nsPoint* normalPosition = GetProperty(NormalPositionProperty());
if (normalPosition) {
return nsRect(*normalPosition, GetSize());
}
@@ -6447,7 +6440,7 @@ nsIFrame::GetNormalPosition() const
{
// It might be faster to first check
// StyleDisplay()->IsRelativelyPositionedStyle().
- nsPoint* normalPosition = Properties().Get(NormalPositionProperty());
+ nsPoint* normalPosition = GetProperty(NormalPositionProperty());
if (normalPosition) {
return *normalPosition;
}
@@ -6506,7 +6499,7 @@ nsIFrame::GetOverflowAreasRelativeToSelf() const
{
if (IsTransformed()) {
nsOverflowAreas* preTransformOverflows =
- Properties().Get(PreTransformOverflowAreasProperty());
+ GetProperty(PreTransformOverflowAreasProperty());
if (preTransformOverflows) {
return nsOverflowAreas(preTransformOverflows->VisualOverflow(),
preTransformOverflows->ScrollableOverflow());
@@ -6533,7 +6526,7 @@ nsIFrame::GetScrollableOverflowRectRelativeToSelf() const
{
if (IsTransformed()) {
nsOverflowAreas* preTransformOverflows =
- Properties().Get(PreTransformOverflowAreasProperty());
+ GetProperty(PreTransformOverflowAreasProperty());
if (preTransformOverflows)
return preTransformOverflows->ScrollableOverflow();
}
@@ -6545,7 +6538,7 @@ nsIFrame::GetVisualOverflowRectRelativeToSelf() const
{
if (IsTransformed()) {
nsOverflowAreas* preTransformOverflows =
- Properties().Get(PreTransformOverflowAreasProperty());
+ GetProperty(PreTransformOverflowAreasProperty());
if (preTransformOverflows)
return preTransformOverflows->VisualOverflow();
}
@@ -6555,7 +6548,7 @@ nsIFrame::GetVisualOverflowRectRelativeToSelf() const
nsRect
nsIFrame::GetPreEffectsVisualOverflowRect() const
{
- nsRect* r = Properties().Get(nsIFrame::PreEffectsBBoxProperty());
+ nsRect* r = GetProperty(nsIFrame::PreEffectsBBoxProperty());
return r ? *r : GetVisualOverflowRectRelativeToSelf();
}
@@ -6758,11 +6751,11 @@ nsIFrame::ListGeneric(nsACString& aTo, const char* aPrefix, uint32_t aFlags) con
aTo += nsPrintfCString(" next-%s=%p", fluid?"in-flow":"continuation",
static_cast<void*>(GetNextContinuation()));
}
- void* IBsibling = Properties().Get(IBSplitSibling());
+ void* IBsibling = GetProperty(IBSplitSibling());
if (IBsibling) {
aTo += nsPrintfCString(" IBSplitSibling=%p", IBsibling);
}
- void* IBprevsibling = Properties().Get(IBSplitPrevSibling());
+ void* IBprevsibling = GetProperty(IBSplitPrevSibling());
if (IBprevsibling) {
aTo += nsPrintfCString(" IBSplitPrevSibling=%p", IBprevsibling);
}
@@ -7164,8 +7157,7 @@ nsFrame::GetPointFromOffset(int32_t inOffset, nsPoint* outPoint)
// If the embedding level isn't set, just use the CSS direction
// property.
bool hasBidiData;
- FrameBidiData bidiData =
- Properties().Get(BidiDataProperty(), &hasBidiData);
+ FrameBidiData bidiData = GetProperty(BidiDataProperty(), &hasBidiData);
bool isRTL = hasBidiData
? IS_LEVEL_RTL(bidiData.embeddingLevel)
: StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
@@ -8315,7 +8307,7 @@ nsIFrame::ClearOverflowRects()
return false;
}
if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) {
- Properties().Delete(OverflowAreasProperty());
+ DeleteProperty(OverflowAreasProperty());
}
mOverflow.mType = NS_FRAME_OVERFLOW_NONE;
return true;
@@ -8328,8 +8320,7 @@ nsIFrame::ClearOverflowRects()
nsOverflowAreas*
nsIFrame::GetOverflowAreasProperty()
{
- FrameProperties props = Properties();
- nsOverflowAreas* overflow = props.Get(OverflowAreasProperty());
+ nsOverflowAreas* overflow = GetProperty(OverflowAreasProperty());
if (overflow) {
return overflow; // the property already exists
@@ -8338,7 +8329,7 @@ nsIFrame::GetOverflowAreasProperty()
// The property isn't set yet, so allocate a new rect, set the property,
// and return the newly allocated rect
overflow = new nsOverflowAreas;
- props.Set(OverflowAreasProperty(), overflow);
+ SetProperty(OverflowAreasProperty(), overflow);
return overflow;
}
@@ -8349,7 +8340,7 @@ bool
nsIFrame::SetOverflowAreas(const nsOverflowAreas& aOverflowAreas)
{
if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) {
- nsOverflowAreas* overflow = Properties().Get(OverflowAreasProperty());
+ nsOverflowAreas* overflow = GetProperty(OverflowAreasProperty());
bool changed = *overflow != aOverflowAreas;
*overflow = aOverflowAreas;
@@ -8593,7 +8584,7 @@ ComputeAndIncludeOutlineArea(nsIFrame* aFrame, nsOverflowAreas& aOverflowAreas,
}
// Keep this code in sync with GetOutlineInnerRect in nsCSSRendering.cpp.
- aFrame->Properties().Set(nsIFrame::OutlineInnerRectProperty(),
+ aFrame->SetProperty(nsIFrame::OutlineInnerRectProperty(),
new nsRect(innerRect));
const nscoord offset = outline->mOutlineOffset;
nsRect outerRect(innerRect);
@@ -8635,22 +8626,22 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
if (!aOverflowAreas.VisualOverflow().IsEqualEdges(bounds) ||
!aOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds)) {
nsOverflowAreas* initial =
- Properties().Get(nsIFrame::InitialOverflowProperty());
+ GetProperty(nsIFrame::InitialOverflowProperty());
if (!initial) {
- Properties().Set(nsIFrame::InitialOverflowProperty(),
+ SetProperty(nsIFrame::InitialOverflowProperty(),
new nsOverflowAreas(aOverflowAreas));
} else if (initial != &aOverflowAreas) {
*initial = aOverflowAreas;
}
} else {
- Properties().Delete(nsIFrame::InitialOverflowProperty());
+ DeleteProperty(nsIFrame::InitialOverflowProperty());
}
#ifdef DEBUG
- Properties().Set(nsIFrame::DebugInitialOverflowPropertyApplied(), true);
+ SetProperty(nsIFrame::DebugInitialOverflowPropertyApplied(), true);
#endif
} else {
#ifdef DEBUG
- Properties().Delete(nsIFrame::DebugInitialOverflowPropertyApplied());
+ DeleteProperty(nsIFrame::DebugInitialOverflowPropertyApplied());
#endif
}
@@ -8745,8 +8736,8 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
}
if (hasTransform) {
- Properties().Set(nsIFrame::PreTransformOverflowAreasProperty(),
- new nsOverflowAreas(aOverflowAreas));
+ SetProperty(nsIFrame::PreTransformOverflowAreasProperty(),
+ new nsOverflowAreas(aOverflowAreas));
if (Combines3DTransformWithAncestors()) {
/* If we're a preserve-3d leaf frame, then our pre-transform overflow should be correct. Our
@@ -8771,7 +8762,7 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
}
}
} else {
- Properties().Delete(nsIFrame::PreTransformOverflowAreasProperty());
+ DeleteProperty(nsIFrame::PreTransformOverflowAreasProperty());
}
/* Revert the size change in case some caller is depending on this. */
@@ -8803,7 +8794,7 @@ nsIFrame::RecomputePerspectiveChildrenOverflow(const nsIFrame* aStartFrame)
}
if (child->HasPerspective()) {
nsOverflowAreas* overflow =
- child->Properties().Get(nsIFrame::InitialOverflowProperty());
+ child->GetProperty(nsIFrame::InitialOverflowProperty());
nsRect bounds(nsPoint(0, 0), child->GetSize());
if (overflow) {
nsOverflowAreas overflowCopy = *overflow;
@@ -8915,7 +8906,7 @@ GetIBSplitSiblingForAnonymousBlock(const nsIFrame* aFrame)
* property.
*/
nsIFrame *ibSplitSibling =
- aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling());
+ aFrame->GetProperty(nsIFrame::IBSplitPrevSibling());
NS_ASSERTION(ibSplitSibling, "Broken frame tree?");
return ibSplitSibling;
}
@@ -9825,7 +9816,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
nsBoxLayoutMetrics*
nsFrame::BoxMetrics() const
{
- nsBoxLayoutMetrics* metrics = Properties().Get(BoxMetricsProperty());
+ nsBoxLayoutMetrics* metrics = GetProperty(BoxMetricsProperty());
NS_ASSERTION(metrics, "A box layout method was called but InitBoxMetrics was never called");
return metrics;
}
@@ -10069,6 +10060,24 @@ nsFrame::HasCSSTransitions()
return collection && collection->mAnimations.Length() > 0;
}
+size_t
+nsIFrame::SizeOfFramePropertiesForTree(MallocSizeOf aMallocSizeOf) const
+{
+ size_t result = 0;
+
+ result += mProperties.SizeOfExcludingThis(aMallocSizeOf);
+
+ FrameChildListIterator iter(this);
+ while (!iter.IsDone()) {
+ for (const nsIFrame* f : iter.CurrentList()) {
+ result += f->SizeOfFramePropertiesForTree(aMallocSizeOf);
+ }
+ iter.Next();
+ }
+
+ return result;
+}
+
// Box layout debugging
#ifdef DEBUG_REFLOW
int32_t gIndent2 = 0;
diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp
index fbd61f783..3a2d5ad1d 100644
--- a/layout/generic/nsGridContainerFrame.cpp
+++ b/layout/generic/nsGridContainerFrame.cpp
@@ -2000,7 +2000,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput
++fragment;
firstInFlow = pif;
}
- mSharedGridData = firstInFlow->Properties().Get(SharedGridData::Prop());
+ mSharedGridData = firstInFlow->GetProperty(SharedGridData::Prop());
MOZ_ASSERT(mSharedGridData, "first-in-flow must have SharedGridData");
// Find the start row for this fragment and undo breaks after that row
@@ -2809,7 +2809,7 @@ nsGridContainerFrame::GridItemCB(nsIFrame* aChild)
{
MOZ_ASSERT((aChild->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
aChild->IsAbsolutelyPositioned());
- nsRect* cb = aChild->Properties().Get(GridItemContainingBlockRect());
+ nsRect* cb = aChild->GetProperty(GridItemContainingBlockRect());
MOZ_ASSERT(cb, "this method must only be called on grid items, and the grid "
"container should've reflowed this item by now and set up cb");
return *cb;
@@ -2836,7 +2836,7 @@ nsGridContainerFrame::AddImplicitNamedAreas(
// Lazily create the ImplicitNamedAreas.
if (!areas) {
areas = new ImplicitNamedAreas;
- Properties().Set(ImplicitNamedAreasProperty(), areas);
+ SetProperty(ImplicitNamedAreasProperty(), areas);
}
mozilla::css::GridNamedArea area;
@@ -2868,7 +2868,7 @@ nsGridContainerFrame::InitImplicitNamedAreas(const nsStylePosition* aStyle)
AddImplicitNamedAreas(aStyle->mGridTemplateColumns.mLineNameLists);
AddImplicitNamedAreas(aStyle->mGridTemplateRows.mLineNameLists);
if (areas && areas->Count() == 0) {
- Properties().Delete(ImplicitNamedAreasProperty());
+ DeleteProperty(ImplicitNamedAreasProperty());
}
}
@@ -3711,7 +3711,7 @@ MeasuringReflow(nsIFrame* aChild,
}
#ifdef DEBUG
// This will suppress various CRAZY_SIZE warnings for this reflow.
- parent->Properties().Set(
+ parent->SetProperty(
nsContainerFrame::DebugReflowingWithInfiniteISize(), true);
#endif
auto wm = aChild->GetWritingMode();
@@ -3724,10 +3724,10 @@ MeasuringReflow(nsIFrame* aChild,
}
if (aBMinSizeClamp != NS_MAXSIZE) {
riFlags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE;
- aChild->Properties().Set(nsIFrame::BClampMarginBoxMinSizeProperty(),
+ aChild->SetProperty(nsIFrame::BClampMarginBoxMinSizeProperty(),
aBMinSizeClamp);
} else {
- aChild->Properties().Delete(nsIFrame::BClampMarginBoxMinSizeProperty());
+ aChild->DeleteProperty(nsIFrame::BClampMarginBoxMinSizeProperty());
}
ReflowInput childRI(pc, *rs, aChild, aAvailableSize, &aCBSize, riFlags);
ReflowOutput childSize(childRI);
@@ -3738,7 +3738,7 @@ MeasuringReflow(nsIFrame* aChild,
parent->FinishReflowChild(aChild, pc, childSize, &childRI, wm,
LogicalPoint(wm), nsSize(), flags);
#ifdef DEBUG
- parent->Properties().Delete(nsContainerFrame::DebugReflowingWithInfiniteISize());
+ parent->DeleteProperty(nsContainerFrame::DebugReflowingWithInfiniteISize());
#endif
return childSize.BSize(wm);
}
@@ -5253,9 +5253,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
baselineAdjust = -baselineAdjust;
}
if (baselineAdjust != nscoord(0)) {
- aChild->Properties().Set(aProp, baselineAdjust);
+ aChild->SetProperty(aProp, baselineAdjust);
} else {
- aChild->Properties().Delete(aProp);
+ aChild->DeleteProperty(aProp);
}
};
SetProp(eLogicalAxisBlock, isOrthogonal ? IBaselinePadProperty() :
@@ -5292,10 +5292,10 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
auto childBAxis = GetOrthogonalAxis(childIAxis);
if (aGridItemInfo->mState[childBAxis] & ItemState::eClampMarginBoxMinSize) {
flags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE;
- aChild->Properties().Set(BClampMarginBoxMinSizeProperty(),
- childCBSize.BSize(childWM));
+ aChild->SetProperty(BClampMarginBoxMinSizeProperty(),
+ childCBSize.BSize(childWM));
} else {
- aChild->Properties().Delete(BClampMarginBoxMinSizeProperty());
+ aChild->DeleteProperty(BClampMarginBoxMinSizeProperty());
}
if ((aGridItemInfo->mState[childIAxis] & ItemState::eApplyAutoMinSize)) {
flags |= ReflowInput::I_APPLY_AUTO_MIN_SIZE;
@@ -5313,11 +5313,11 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
// A table-wrapper needs to propagate the CB size we give it to its
// inner table frame later. @see nsTableWrapperFrame::InitChildReflowInput.
if (childType == nsGkAtoms::tableWrapperFrame) {
- const auto& props = aChild->Properties();
- LogicalSize* cb = props.Get(nsTableWrapperFrame::GridItemCBSizeProperty());
+ LogicalSize* cb =
+ aChild->GetProperty(nsTableWrapperFrame::GridItemCBSizeProperty());
if (!cb) {
cb = new LogicalSize(childWM);
- props.Set(nsTableWrapperFrame::GridItemCBSizeProperty(), cb);
+ aChild->SetProperty(nsTableWrapperFrame::GridItemCBSizeProperty(), cb);
}
*cb = percentBasis;
}
@@ -5337,9 +5337,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
}
}
if (stretch) {
- aChild->Properties().Set(FragStretchBSizeProperty(), *aStretchBSize);
+ aChild->SetProperty(FragStretchBSizeProperty(), *aStretchBSize);
} else {
- aChild->Properties().Delete(FragStretchBSizeProperty());
+ aChild->DeleteProperty(FragStretchBSizeProperty());
}
}
@@ -5951,10 +5951,10 @@ nsGridContainerFrame::ReflowChildren(GridReflowInput& aState,
LogicalRect itemCB =
aState.ContainingBlockForAbsPos(area, gridOrigin, gridCB);
// nsAbsoluteContainingBlock::Reflow uses physical coordinates.
- nsRect* cb = child->Properties().Get(GridItemContainingBlockRect());
+ nsRect* cb = child->GetProperty(GridItemContainingBlockRect());
if (!cb) {
cb = new nsRect;
- child->Properties().Set(GridItemContainingBlockRect(), cb);
+ child->SetProperty(GridItemContainingBlockRect(), cb);
}
*cb = itemCB.GetPhysicalRect(wm, gridCBPhysicalSize);
}
@@ -6044,7 +6044,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
f = next;
}
if (overflowContainers->IsEmpty()) {
- Properties().Delete(OverflowContainersProperty());
+ DeleteProperty(OverflowContainersProperty());
}
MergeSortedExcessOverflowContainers(moveToEOC);
}
@@ -6355,7 +6355,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(colTrackStates),
Move(colRemovedRepeatTracks),
gridReflowInput.mColFunctions.mRepeatAutoStart);
- Properties().Set(GridColTrackInfo(), colInfo);
+ SetProperty(GridColTrackInfo(), colInfo);
uint32_t rowTrackCount = gridReflowInput.mRows.mSizes.Length();
nsTArray<nscoord> rowTrackPositions(rowTrackCount);
@@ -6390,7 +6390,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(rowTrackStates),
Move(rowRemovedRepeatTracks),
gridReflowInput.mRowFunctions.mRepeatAutoStart);
- Properties().Set(GridRowTrackInfo(), rowInfo);
+ SetProperty(GridRowTrackInfo(), rowInfo);
if (prevInFlow) {
// This frame is fragmenting rows from a previous frame, so patch up
@@ -6399,7 +6399,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
// FIXME: This can be streamlined and/or removed when bug 1151204 lands.
ComputedGridTrackInfo* priorRowInfo =
- prevInFlow->Properties().Get(GridRowTrackInfo());
+ prevInFlow->GetProperty(GridRowTrackInfo());
// Adjust track positions based on the first track in this fragment.
if (priorRowInfo->mPositions.Length() >
@@ -6421,7 +6421,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(priorRowInfo->mStates),
Move(priorRowInfo->mRemovedRepeatTracks),
priorRowInfo->mRepeatFirstTrack);
- prevInFlow->Properties().Set(GridRowTrackInfo(), revisedPriorRowInfo);
+ prevInFlow->SetProperty(GridRowTrackInfo(), revisedPriorRowInfo);
}
// Generate the line info properties. We need to provide the number of
@@ -6448,7 +6448,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(columnLineNames),
gridColTemplate.mRepeatAutoLineNameListBefore,
gridColTemplate.mRepeatAutoLineNameListAfter);
- Properties().Set(GridColumnLineInfo(), columnLineInfo);
+ SetProperty(GridColumnLineInfo(), columnLineInfo);
// Generate row lines next.
capacity = gridReflowInput.mRows.mSizes.Length();
@@ -6469,25 +6469,25 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(rowLineNames),
gridRowTemplate.mRepeatAutoLineNameListBefore,
gridRowTemplate.mRepeatAutoLineNameListAfter);
- Properties().Set(GridRowLineInfo(), rowLineInfo);
+ SetProperty(GridRowLineInfo(), rowLineInfo);
// Generate area info for explicit areas. Implicit areas are handled
// elsewhere.
if (gridReflowInput.mGridStyle->mGridTemplateAreas) {
nsTArray<css::GridNamedArea>* areas = new nsTArray<css::GridNamedArea>(
gridReflowInput.mGridStyle->mGridTemplateAreas->mNamedAreas);
- Properties().Set(ExplicitNamedAreasProperty(), areas);
+ SetProperty(ExplicitNamedAreasProperty(), areas);
} else {
- Properties().Delete(ExplicitNamedAreasProperty());
+ DeleteProperty(ExplicitNamedAreasProperty());
}
}
if (!prevInFlow) {
- SharedGridData* sharedGridData = Properties().Get(SharedGridData::Prop());
+ SharedGridData* sharedGridData = GetProperty(SharedGridData::Prop());
if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
if (!sharedGridData) {
sharedGridData = new SharedGridData;
- Properties().Set(SharedGridData::Prop(), sharedGridData);
+ SetProperty(SharedGridData::Prop(), sharedGridData);
}
sharedGridData->mCols.mSizes.Clear();
sharedGridData->mCols.mSizes.SwapElements(gridReflowInput.mCols.mSizes);
@@ -6522,7 +6522,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
sharedGridData->mGenerateComputedGridInfo =
HasAnyStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES);
} else if (sharedGridData && !GetNextInFlow()) {
- Properties().Delete(SharedGridData::Prop());
+ DeleteProperty(SharedGridData::Prop());
}
}
@@ -7142,10 +7142,10 @@ nsGridContainerFrame::GetGridFrameWithComputedInfo(nsIFrame* aFrame)
nsGridContainerFrame* gridFrame = GetGridContainerFrame(aFrame);
if (gridFrame) {
// if any of our properties are missing, generate them
- bool reflowNeeded = (!gridFrame->Properties().Has(GridColTrackInfo()) ||
- !gridFrame->Properties().Has(GridRowTrackInfo()) ||
- !gridFrame->Properties().Has(GridColumnLineInfo()) ||
- !gridFrame->Properties().Has(GridRowLineInfo()));
+ bool reflowNeeded = (!gridFrame->HasProperty(GridColTrackInfo()) ||
+ !gridFrame->HasProperty(GridRowTrackInfo()) ||
+ !gridFrame->HasProperty(GridColumnLineInfo()) ||
+ !gridFrame->HasProperty(GridRowLineInfo()));
if (reflowNeeded) {
// Trigger a reflow that generates additional grid property data.
@@ -7161,13 +7161,13 @@ nsGridContainerFrame::GetGridFrameWithComputedInfo(nsIFrame* aFrame)
// Assert the grid properties are present
MOZ_ASSERT(!gridFrame ||
- gridFrame->Properties().Has(GridColTrackInfo()));
+ gridFrame->HasProperty(GridColTrackInfo()));
MOZ_ASSERT(!gridFrame ||
- gridFrame->Properties().Has(GridRowTrackInfo()));
+ gridFrame->HasProperty(GridRowTrackInfo()));
MOZ_ASSERT(!gridFrame ||
- gridFrame->Properties().Has(GridColumnLineInfo()));
+ gridFrame->HasProperty(GridColumnLineInfo()));
MOZ_ASSERT(!gridFrame ||
- gridFrame->Properties().Has(GridRowLineInfo()));
+ gridFrame->HasProperty(GridRowLineInfo()));
}
}
diff --git a/layout/generic/nsGridContainerFrame.h b/layout/generic/nsGridContainerFrame.h
index e610dfa0b..960558421 100644
--- a/layout/generic/nsGridContainerFrame.h
+++ b/layout/generic/nsGridContainerFrame.h
@@ -164,7 +164,7 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColTrackInfo, ComputedGridTrackInfo)
const ComputedGridTrackInfo* GetComputedTemplateColumns()
{
- const ComputedGridTrackInfo* info = Properties().Get(GridColTrackInfo());
+ const ComputedGridTrackInfo* info = GetProperty(GridColTrackInfo());
MOZ_ASSERT(info, "Property generation wasn't requested.");
return info;
}
@@ -172,7 +172,7 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowTrackInfo, ComputedGridTrackInfo)
const ComputedGridTrackInfo* GetComputedTemplateRows()
{
- const ComputedGridTrackInfo* info = Properties().Get(GridRowTrackInfo());
+ const ComputedGridTrackInfo* info = GetProperty(GridRowTrackInfo());
MOZ_ASSERT(info, "Property generation wasn't requested.");
return info;
}
@@ -180,7 +180,7 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColumnLineInfo, ComputedGridLineInfo)
const ComputedGridLineInfo* GetComputedTemplateColumnLines()
{
- const ComputedGridLineInfo* info = Properties().Get(GridColumnLineInfo());
+ const ComputedGridLineInfo* info = GetProperty(GridColumnLineInfo());
MOZ_ASSERT(info, "Property generation wasn't requested.");
return info;
}
@@ -188,7 +188,7 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowLineInfo, ComputedGridLineInfo)
const ComputedGridLineInfo* GetComputedTemplateRowLines()
{
- const ComputedGridLineInfo* info = Properties().Get(GridRowLineInfo());
+ const ComputedGridLineInfo* info = GetProperty(GridRowLineInfo());
MOZ_ASSERT(info, "Property generation wasn't requested.");
return info;
}
@@ -199,14 +199,14 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(ImplicitNamedAreasProperty,
ImplicitNamedAreas)
ImplicitNamedAreas* GetImplicitNamedAreas() const {
- return Properties().Get(ImplicitNamedAreasProperty());
+ return GetProperty(ImplicitNamedAreasProperty());
}
typedef nsTArray<mozilla::css::GridNamedArea> ExplicitNamedAreas;
NS_DECLARE_FRAME_PROPERTY_DELETABLE(ExplicitNamedAreasProperty,
ExplicitNamedAreas)
ExplicitNamedAreas* GetExplicitNamedAreas() const {
- return Properties().Get(ExplicitNamedAreasProperty());
+ return GetProperty(ExplicitNamedAreasProperty());
}
/**
diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h
index 2acafa882..ec3568483 100644
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -24,7 +24,7 @@
#include <stdio.h>
#include "CaretAssociationHint.h"
-#include "FramePropertyTable.h"
+#include "FrameProperties.h"
#include "mozilla/layout/FrameChildList.h"
#include "mozilla/Maybe.h"
#include "mozilla/WritingModes.h"
@@ -997,7 +997,7 @@ public:
#define NS_DECLARE_FRAME_PROPERTY_WITH_DTOR_NEVER_CALLED(prop, type) \
static void AssertOnDestroyingProperty##prop(type*) { \
MOZ_ASSERT_UNREACHABLE("Frame property " #prop " should never " \
- "be destroyed by the FramePropertyTable"); \
+ "be destroyed by the FrameProperties class"); \
} \
NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(prop, type, \
AssertOnDestroyingProperty##prop)
@@ -1005,8 +1005,8 @@ public:
#define NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(prop, type) \
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(prop, mozilla::SmallValueHolder<type>)
- NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitSibling, nsIFrame)
- NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitPrevSibling, nsIFrame)
+ NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitSibling, nsContainerFrame)
+ NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitPrevSibling, nsContainerFrame)
NS_DECLARE_FRAME_PROPERTY_DELETABLE(NormalPositionProperty, nsPoint)
NS_DECLARE_FRAME_PROPERTY_DELETABLE(ComputedOffsetProperty, nsMargin)
@@ -1059,7 +1059,7 @@ public:
mozilla::FrameBidiData GetBidiData()
{
- return Properties().Get(BidiDataProperty());
+ return GetProperty(BidiDataProperty());
}
nsBidiLevel GetBaseLevel()
@@ -1073,7 +1073,7 @@ public:
}
nsTArray<nsIContent*>* GetGenConPseudos() {
- return Properties().Get(GenConProperty());
+ return GetProperty(GenConProperty());
}
/**
@@ -1534,7 +1534,7 @@ public:
bool RefusedAsyncAnimation() const
{
- return Properties().Get(RefusedAsyncAnimationProperty());
+ return GetProperty(RefusedAsyncAnimationProperty());
}
/**
@@ -3061,9 +3061,53 @@ public:
return mContent == aParentContent;
}
- FrameProperties Properties() const {
- return FrameProperties(PresContext()->PropertyTable(), this);
- }
+/**
+ * Support for reading and writing properties on the frame.
+ * These call through to the frame's FrameProperties object, if it
+ * exists, but avoid creating it if no property is ever set.
+ */
+template<typename T>
+FrameProperties::PropertyType<T>
+GetProperty(FrameProperties::Descriptor<T> aProperty,
+ bool* aFoundResult = nullptr) const
+{
+ return mProperties.Get(aProperty, aFoundResult);
+}
+
+template<typename T>
+bool HasProperty(FrameProperties::Descriptor<T> aProperty) const
+{
+ return mProperties.Has(aProperty);
+}
+
+template<typename T>
+void SetProperty(FrameProperties::Descriptor<T> aProperty,
+ FrameProperties::PropertyType<T> aValue)
+{
+ mProperties.Set(aProperty, aValue, this);
+}
+
+template<typename T>
+FrameProperties::PropertyType<T>
+RemoveProperty(FrameProperties::Descriptor<T> aProperty,
+ bool* aFoundResult = nullptr)
+{
+ return mProperties.Remove(aProperty, aFoundResult);
+}
+
+template<typename T>
+void DeleteProperty(FrameProperties::Descriptor<T> aProperty)
+{
+ mProperties.Delete(aProperty, this);
+}
+
+void DeleteAllProperties()
+{
+ mProperties.DeleteAll(this);
+}
+
+// Reports size of the FrameProperties for this frame and its descendants
+size_t SizeOfFramePropertiesForTree(mozilla::MallocSizeOf aMallocSizeOf) const;
/**
* Return true if and only if this frame obeys visibility:hidden.
@@ -3423,7 +3467,7 @@ public:
*/
bool FrameIsNonFirstInIBSplit() const {
return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
- FirstContinuation()->Properties().Get(nsIFrame::IBSplitPrevSibling());
+ FirstContinuation()->GetProperty(nsIFrame::IBSplitPrevSibling());
}
/**
@@ -3432,7 +3476,7 @@ public:
*/
bool FrameIsNonLastInIBSplit() const {
return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
- FirstContinuation()->Properties().Get(nsIFrame::IBSplitSibling());
+ FirstContinuation()->GetProperty(nsIFrame::IBSplitSibling());
}
/**
@@ -3514,11 +3558,11 @@ private:
DestroyPaintedPresShellList)
nsTArray<nsWeakPtr>* PaintedPresShellList() {
- nsTArray<nsWeakPtr>* list = Properties().Get(PaintedPresShellsProperty());
+ nsTArray<nsWeakPtr>* list = GetProperty(PaintedPresShellsProperty());
if (!list) {
list = new nsTArray<nsWeakPtr>();
- Properties().Set(PaintedPresShellsProperty(), list);
+ SetProperty(PaintedPresShellsProperty(), list);
}
return list;
@@ -3535,6 +3579,11 @@ protected:
nsFrameState mState;
+ /**
+ * List of properties attached to the frame.
+ */
+ FrameProperties mProperties;
+
// When there is an overflow area only slightly larger than mRect,
// we store a set of four 1-byte deltas from the edges of mRect
// rather than allocating a whole separate rectangle property.
diff --git a/layout/generic/nsLineLayout.cpp b/layout/generic/nsLineLayout.cpp
index 138d0b871..6a15a9cfa 100644
--- a/layout/generic/nsLineLayout.cpp
+++ b/layout/generic/nsLineLayout.cpp
@@ -819,11 +819,11 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
#endif
if (mCurrentSpan == mRootSpan) {
- pfd->mFrame->Properties().Remove(nsIFrame::LineBaselineOffset());
+ pfd->mFrame->RemoveProperty(nsIFrame::LineBaselineOffset());
} else {
#ifdef DEBUG
bool hasLineOffset;
- pfd->mFrame->Properties().Get(nsIFrame::LineBaselineOffset(), &hasLineOffset);
+ pfd->mFrame->GetProperty(nsIFrame::LineBaselineOffset(), &hasLineOffset);
NS_ASSERTION(!hasLineOffset, "LineBaselineOffset was set but was not expected");
#endif
}
diff --git a/layout/generic/nsPlaceholderFrame.cpp b/layout/generic/nsPlaceholderFrame.cpp
index 2b6799f48..bd380a2d9 100644
--- a/layout/generic/nsPlaceholderFrame.cpp
+++ b/layout/generic/nsPlaceholderFrame.cpp
@@ -128,7 +128,7 @@ nsPlaceholderFrame::Reflow(nsPresContext* aPresContext,
nsIFrame* ancestor = this;
while ((ancestor = ancestor->GetParent())) {
if (ancestor->GetPrevContinuation() ||
- ancestor->Properties().Get(IBSplitPrevSibling())) {
+ ancestor->GetProperty(IBSplitPrevSibling())) {
isInContinuationOrIBSplit = true;
break;
}
diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp
index 3288d3f2e..0641c7439 100644
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -2838,9 +2838,9 @@ nsTextFrame::EnsureTextRun(TextRunType aWhichTextRun,
return gfxSkipCharsIterator(gfxPlatform::
GetPlatform()->EmptySkipChars(), 0);
}
- TabWidthStore* tabWidths = Properties().Get(TabWidthProperty());
+ TabWidthStore* tabWidths = GetProperty(TabWidthProperty());
if (tabWidths && tabWidths->mValidForContentOffset != GetContentOffset()) {
- Properties().Delete(TabWidthProperty());
+ DeleteProperty(TabWidthProperty());
}
}
@@ -3478,7 +3478,7 @@ PropertyProvider::CalcTabWidths(Range aRange)
return;
}
if (!mReflowing) {
- mTabWidths = mFrame->Properties().Get(TabWidthProperty());
+ mTabWidths = mFrame->GetProperty(TabWidthProperty());
#ifdef DEBUG
// If we're not reflowing, we should have already computed the
// tab widths; check that they're available as far as the last
@@ -3524,7 +3524,7 @@ PropertyProvider::CalcTabWidths(Range aRange)
} else {
if (!mTabWidths) {
mTabWidths = new TabWidthStore(mFrame->GetContentOffset());
- mFrame->Properties().Set(TabWidthProperty(), mTabWidths);
+ mFrame->SetProperty(TabWidthProperty(), mTabWidths);
}
double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs,
mFrame, mTextRun, &tabWidth);
@@ -3543,7 +3543,7 @@ PropertyProvider::CalcTabWidths(Range aRange)
if (!mTabWidths) {
// Delete any stale property that may be left on the frame
- mFrame->Properties().Delete(TabWidthProperty());
+ mFrame->DeleteProperty(TabWidthProperty());
mTabWidthsAnalyzedLimit = std::max(mTabWidthsAnalyzedLimit,
aRange.end - startOffset);
}
@@ -4249,7 +4249,7 @@ nsTextFrame::ClearFrameOffsetCache()
// just destroys the frames in order, which means that the primary frame is already
// dead if we're a continuing text frame, in which case, all of its properties are
// gone, and we don't need to worry about deleting this property here.
- primaryFrame->Properties().Delete(OffsetToFrameProperty());
+ primaryFrame->DeleteProperty(OffsetToFrameProperty());
}
RemoveStateBits(TEXT_IN_OFFSET_CACHE);
}
@@ -4358,7 +4358,7 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
if (aPrevInFlow->GetStateBits() & NS_FRAME_IS_BIDI) {
FrameBidiData bidiData = aPrevInFlow->GetBidiData();
bidiData.precedingControl = kBidiLevelNone;
- Properties().Set(BidiDataProperty(), bidiData);
+ SetProperty(BidiDataProperty(), bidiData);
if (nextContinuation) {
SetNextContinuation(nextContinuation);
@@ -4622,7 +4622,7 @@ nsTextFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemK
gfxTextRun*
nsTextFrame::GetUninflatedTextRun()
{
- return Properties().Get(UninflatedTextRunProperty());
+ return GetProperty(UninflatedTextRunProperty());
}
void
@@ -4648,7 +4648,7 @@ nsTextFrame::SetTextRun(gfxTextRun* aTextRun, TextRunType aWhichTextRun,
// Setting the property will not automatically increment the textrun's
// reference count, so we need to do it here.
aTextRun->AddRef();
- Properties().Set(UninflatedTextRunProperty(), aTextRun);
+ SetProperty(UninflatedTextRunProperty(), aTextRun);
return;
}
// fall through to setting mTextRun
@@ -4668,10 +4668,9 @@ nsTextFrame::RemoveTextRun(gfxTextRun* aTextRun)
mTextRun = nullptr;
return true;
}
- FrameProperties props = Properties();
if ((GetStateBits() & TEXT_HAS_FONT_INFLATION) &&
- props.Get(UninflatedTextRunProperty()) == aTextRun) {
- props.Delete(UninflatedTextRunProperty());
+ GetProperty(UninflatedTextRunProperty()) == aTextRun) {
+ DeleteProperty(UninflatedTextRunProperty());
return true;
}
return false;
@@ -4689,7 +4688,7 @@ nsTextFrame::ClearTextRun(nsTextFrame* aStartContinuation,
DebugOnly<bool> checkmTextrun = textRun == mTextRun;
UnhookTextRunFromFrames(textRun, aStartContinuation);
MOZ_ASSERT(checkmTextrun ? !mTextRun
- : !Properties().Get(UninflatedTextRunProperty()));
+ : !GetProperty(UninflatedTextRunProperty()));
}
void
@@ -4699,7 +4698,7 @@ nsTextFrame::DisconnectTextRuns()
"Textrun mentions this frame in its user data so we can't just disconnect");
mTextRun = nullptr;
if ((GetStateBits() & TEXT_HAS_FONT_INFLATION)) {
- Properties().Delete(UninflatedTextRunProperty());
+ DeleteProperty(UninflatedTextRunProperty());
}
}
@@ -4929,7 +4928,7 @@ NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(TextCombineScaleFactorProperty, float)
static float
GetTextCombineScaleFactor(nsTextFrame* aFrame)
{
- float factor = aFrame->Properties().Get(TextCombineScaleFactorProperty());
+ float factor = aFrame->GetProperty(TextCombineScaleFactorProperty());
return factor ? factor : 1.0f;
}
@@ -5105,7 +5104,7 @@ static nscoord
LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame)
{
bool offsetFound;
- nscoord offset = aChildFrame->Properties().Get(
+ nscoord offset = aChildFrame->GetProperty(
nsIFrame::LineBaselineOffset(), &offsetFound);
if (!offsetFound) {
@@ -5118,11 +5117,11 @@ LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame)
for (nsIFrame* lineFrame = line->mFirstChild;
n > 0; lineFrame = lineFrame->GetNextSibling(), --n) {
offset = lineBaseline - lineFrame->GetNormalPosition().y;
- lineFrame->Properties().Set(nsIFrame::LineBaselineOffset(), offset);
+ lineFrame->SetProperty(nsIFrame::LineBaselineOffset(), offset);
}
}
}
- return aChildFrame->Properties().Get(
+ return aChildFrame->GetProperty(
nsIFrame::LineBaselineOffset(), &offsetFound);
} else {
return offset;
@@ -5367,7 +5366,7 @@ nsTextFrame::UpdateTextEmphasis(WritingMode aWM, PropertyProvider& aProvider)
{
const nsStyleText* styleText = StyleText();
if (!styleText->HasTextEmphasis()) {
- Properties().Delete(EmphasisMarkProperty());
+ DeleteProperty(EmphasisMarkProperty());
return nsRect();
}
@@ -5419,7 +5418,7 @@ nsTextFrame::UpdateTextEmphasis(WritingMode aWM, PropertyProvider& aProvider)
overflowRect.BStart(aWM) += gap * (side == eLogicalSideBStart ? -1 : 1);
}
- Properties().Set(EmphasisMarkProperty(), info);
+ SetProperty(EmphasisMarkProperty(), info);
return overflowRect.GetPhysicalRect(aWM, frameSize.GetPhysicalSize(aWM));
}
@@ -6432,7 +6431,7 @@ nsTextFrame::DrawEmphasisMarks(gfxContext* aContext, WritingMode aWM,
const nscolor* aDecorationOverrideColor,
PropertyProvider* aProvider)
{
- const EmphasisMarkInfo* info = Properties().Get(EmphasisMarkProperty());
+ const EmphasisMarkInfo* info = GetProperty(EmphasisMarkProperty());
if (!info) {
return;
}
@@ -7584,7 +7583,7 @@ nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset,
int32_t offset = mContentOffset;
// Try to look up the offset to frame property
- nsTextFrame* cachedFrame = Properties().Get(OffsetToFrameProperty());
+ nsTextFrame* cachedFrame = GetProperty(OffsetToFrameProperty());
if (cachedFrame) {
f = cachedFrame;
@@ -7632,7 +7631,7 @@ nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset,
*aOutFrame = f;
// cache the frame we found
- Properties().Set(OffsetToFrameProperty(), f);
+ SetProperty(OffsetToFrameProperty(), f);
f->AddStateBits(TEXT_IN_OFFSET_CACHE);
return NS_OK;
@@ -8169,7 +8168,7 @@ nsTextFrame::GetFontSizeInflation() const
if (!HasFontSizeInflation()) {
return 1.0f;
}
- return Properties().Get(FontSizeInflationProperty());
+ return GetProperty(FontSizeInflationProperty());
}
void
@@ -8178,13 +8177,13 @@ nsTextFrame::SetFontSizeInflation(float aInflation)
if (aInflation == 1.0f) {
if (HasFontSizeInflation()) {
RemoveStateBits(TEXT_HAS_FONT_INFLATION);
- Properties().Delete(FontSizeInflationProperty());
+ DeleteProperty(FontSizeInflationProperty());
}
return;
}
AddStateBits(TEXT_HAS_FONT_INFLATION);
- Properties().Set(FontSizeInflationProperty(), aInflation);
+ SetProperty(FontSizeInflationProperty(), aInflation);
}
/* virtual */
@@ -9319,9 +9318,9 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
gfxFloat em = fm->EmHeight();
// Compress the characters in horizontal axis if necessary.
if (width <= em) {
- Properties().Remove(TextCombineScaleFactorProperty());
+ RemoveProperty(TextCombineScaleFactorProperty());
} else {
- Properties().Set(TextCombineScaleFactorProperty(), em / width);
+ SetProperty(TextCombineScaleFactorProperty(), em / width);
finalSize.ISize(wm) = em;
}
// Make the characters be in an 1em square.
@@ -10049,13 +10048,13 @@ nsTextFrame::AssignJustificationGaps(
static_assert(sizeof(aAssign) == 1,
"The encoding might be broken if JustificationAssignment "
"is larger than 1 byte");
- Properties().Set(JustificationAssignmentProperty(), encoded);
+ SetProperty(JustificationAssignmentProperty(), encoded);
}
mozilla::JustificationAssignment
nsTextFrame::GetJustificationAssignment() const
{
- int32_t encoded = Properties().Get(JustificationAssignmentProperty());
+ int32_t encoded = GetProperty(JustificationAssignmentProperty());
mozilla::JustificationAssignment result;
result.mGapsAtStart = encoded >> 8;
result.mGapsAtEnd = encoded & 0xFF;
diff --git a/layout/mathml/nsMathMLContainerFrame.cpp b/layout/mathml/nsMathMLContainerFrame.cpp
index ad1b13efd..93b631c9d 100644
--- a/layout/mathml/nsMathMLContainerFrame.cpp
+++ b/layout/mathml/nsMathMLContainerFrame.cpp
@@ -134,7 +134,7 @@ nsMathMLContainerFrame::SaveReflowAndBoundingMetricsFor(nsIFrame*
{
ReflowOutput* reflowOutput = new ReflowOutput(aReflowOutput);
reflowOutput->mBoundingMetrics = aBoundingMetrics;
- aFrame->Properties().Set(HTMLReflowOutputProperty(), reflowOutput);
+ aFrame->SetProperty(HTMLReflowOutputProperty(), reflowOutput);
}
// helper method to facilitate getting the reflow and bounding metrics
@@ -147,7 +147,7 @@ nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFra
NS_PRECONDITION(aFrame, "null arg");
ReflowOutput* reflowOutput =
- aFrame->Properties().Get(HTMLReflowOutputProperty());
+ aFrame->GetProperty(HTMLReflowOutputProperty());
// IMPORTANT: This function is only meant to be called in Place() methods
// where it is assumed that SaveReflowAndBoundingMetricsFor has recorded the
@@ -175,9 +175,8 @@ void
nsMathMLContainerFrame::ClearSavedChildMetrics()
{
nsIFrame* childFrame = mFrames.FirstChild();
- FramePropertyTable* props = PresContext()->PropertyTable();
while (childFrame) {
- props->Delete(childFrame, HTMLReflowOutputProperty());
+ childFrame->DeleteProperty(HTMLReflowOutputProperty());
childFrame = childFrame->GetNextSibling();
}
}
diff --git a/layout/mathml/nsMathMLmtableFrame.cpp b/layout/mathml/nsMathMLmtableFrame.cpp
index a706fb483..fd184e637 100644
--- a/layout/mathml/nsMathMLmtableFrame.cpp
+++ b/layout/mathml/nsMathMLmtableFrame.cpp
@@ -167,8 +167,7 @@ FindCellProperty(const nsIFrame* aCellFrame,
nsTArray<int8_t>* propertyData = nullptr;
while (currentFrame) {
- FrameProperties props = currentFrame->Properties();
- propertyData = props.Get(aFrameProperty);
+ propertyData = currentFrame->GetProperty(aFrameProperty);
bool frameIsTable = (currentFrame->GetType() == nsGkAtoms::tableFrame);
if (propertyData || frameIsTable)
@@ -361,8 +360,7 @@ ParseFrameAttribute(nsIFrame* aFrame,
if (valueList) {
// The code reading the property assumes that this list is nonempty.
NS_ASSERTION(valueList->Length() >= 1, "valueList should not be empty!");
- FrameProperties props = aFrame->Properties();
- props.Set(AttributeToProperty(aAttribute), valueList);
+ aFrame->SetProperty(AttributeToProperty(aAttribute), valueList);
} else {
ReportParseError(aFrame, aAttribute->GetUTF16String(), attrValue.get());
}
@@ -769,8 +767,7 @@ nsMathMLmtableWrapperFrame::AttributeChanged(int32_t aNameSpaceID,
aAttribute == nsGkAtoms::columnalign_ ||
aAttribute == nsGkAtoms::columnlines_) {
// clear any cached property list for this table
- presContext->PropertyTable()->
- Delete(tableFrame, AttributeToProperty(aAttribute));
+ tableFrame->DeleteProperty(AttributeToProperty(aAttribute));
// Reparse the new attribute on the table.
ParseFrameAttribute(tableFrame, aAttribute, true);
} else {
@@ -1120,7 +1117,7 @@ nsMathMLmtrFrame::AttributeChanged(int32_t aNameSpaceID,
return NS_OK;
}
- presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute));
+ DeleteProperty(AttributeToProperty(aAttribute));
bool allowMultiValues = (aAttribute == nsGkAtoms::columnalign_);
@@ -1219,8 +1216,7 @@ nsMathMLmtdFrame::AttributeChanged(int32_t aNameSpaceID,
if (aAttribute == nsGkAtoms::rowalign_ ||
aAttribute == nsGkAtoms::columnalign_) {
- nsPresContext* presContext = PresContext();
- presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute));
+ DeleteProperty(AttributeToProperty(aAttribute));
// Reparse the attribute.
ParseFrameAttribute(this, aAttribute, false);
diff --git a/layout/reftests/svg/css-transform-svg-ref.html b/layout/reftests/svg/css-transform-svg-ref.html
new file mode 100644
index 000000000..6167442e7
--- /dev/null
+++ b/layout/reftests/svg/css-transform-svg-ref.html
@@ -0,0 +1,10 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<style>
+</style>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+ <rect id="a" x="0.49" y="0.51" width="2.5" height="2.5"/>
+ <rect id="b" x="3.5" y="3.5" width="2.5" height="2.5"/>
+</svg>
diff --git a/layout/reftests/svg/css-transform-svg.html b/layout/reftests/svg/css-transform-svg.html
new file mode 100644
index 000000000..c1c63a839
--- /dev/null
+++ b/layout/reftests/svg/css-transform-svg.html
@@ -0,0 +1,13 @@
+<!--
+ Any copyright is dedicated to the Public Domain.
+ http://creativecommons.org/publicdomain/zero/1.0/
+-->
+<style>
+#a {
+ transform: scaleY(1);
+}
+</style>
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20">
+ <rect id="a" x="0.49" y="0.51" width="2.5" height="2.5"/>
+ <rect id="b" x="3.5" y="3.5" width="2.5" height="2.5"/>
+</svg>
diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list
index 096628681..21e1c68a1 100644
--- a/layout/reftests/svg/reftest.list
+++ b/layout/reftests/svg/reftest.list
@@ -140,6 +140,7 @@ random == dynamic-use-nested-01b.svg dynamic-use-nested-01-ref.svg
== fragmentIdentifier-01.xhtml pass.svg
== linked-filter-01.svg pass.svg
== linked-pattern-01.svg pass.svg
+pref(layout.css.devPixelsPerPx,"1.0") == svg-blurry-with-subpixel-position.html svg-blurry-with-subpixel-position-ref.html
== use-01.svg pass.svg
== use-01-extref.svg pass.svg
== use-02-extref.svg use-02-extref-ref.svg
@@ -371,6 +372,7 @@ fuzzy-if(skiaContent,1,610) == textPath-03.svg pass.svg
== text-white-space-01.svg text-white-space-01-ref.svg
== thin-stroke-01.svg pass.svg
== zero-stroke-01.svg pass.svg
+== css-transform-svg.html css-transform-svg-ref.html
== tspan-dxdy-01.svg tspan-dxdy-ref.svg
== tspan-dxdy-02.svg tspan-dxdy-ref.svg
== tspan-dxdy-03.svg tspan-dxdy-ref.svg
diff --git a/layout/reftests/svg/svg-blurry-with-subpixel-position-ref.html b/layout/reftests/svg/svg-blurry-with-subpixel-position-ref.html
new file mode 100644
index 000000000..c315509d7
--- /dev/null
+++ b/layout/reftests/svg/svg-blurry-with-subpixel-position-ref.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<style>
+ svg {
+ width:750px;
+ height:750px;
+ margin:3px;
+ }
+</style>
+
+<svg viewBox="0.5 0.5 750 750">
+ <path d="M3,6L277,6M3,12L277,12M3,18L277,18M3,24L277,24M3,30L277,30M3,36L277,36M3,42L277,42M3,48L277,48M3,54L277,54M3,60L277,60M3,66L277,66M3,72L277,72M3,78L277,78M3,84L277,84M3,90L277,90M3,96L277,96M3,102L277,102M3,108L277,108M3,114L277,114" style="stroke-width:1; stroke:black;" />
+ <path d="M6,3L6,277M12,3L12,277M18,3L18,277M24,3L24,277M30,3L30,277M36,3L36,277M42,3L42,277M48,3L48,277M54,3L54,277M60,3L60,277M66,3L66,277M72,3L72,277M78,3L78,277M84,3L84,277M90,3L90,277M96,3L96,277M102,3L102,277M108,3L108,277M114,3L114,277" style="stroke-width:1; stroke:black;" />
+</svg>
diff --git a/layout/reftests/svg/svg-blurry-with-subpixel-position.html b/layout/reftests/svg/svg-blurry-with-subpixel-position.html
new file mode 100644
index 000000000..20bca7174
--- /dev/null
+++ b/layout/reftests/svg/svg-blurry-with-subpixel-position.html
@@ -0,0 +1,13 @@
+<!doctype html>
+<style>
+ svg {
+ width:750px;
+ height:750px;
+ margin:2.5px;
+ }
+</style>
+
+<svg viewBox="0.5 0.5 750 750">
+ <path d="M3,6L277,6M3,12L277,12M3,18L277,18M3,24L277,24M3,30L277,30M3,36L277,36M3,42L277,42M3,48L277,48M3,54L277,54M3,60L277,60M3,66L277,66M3,72L277,72M3,78L277,78M3,84L277,84M3,90L277,90M3,96L277,96M3,102L277,102M3,108L277,108M3,114L277,114" style="stroke-width:1; stroke:black;" />
+ <path d="M6,3L6,277M12,3L12,277M18,3L18,277M24,3L24,277M30,3L30,277M36,3L36,277M42,3L42,277M48,3L48,277M54,3L54,277M60,3L60,277M66,3L66,277M72,3L72,277M78,3L78,277M84,3L84,277M90,3L90,277M96,3L96,277M102,3L102,277M108,3L108,277M114,3L114,277" style="stroke-width:1; stroke:black;" />
+</svg>
diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp
index 1645adfef..81c5ede0e 100644
--- a/layout/style/FontFaceSet.cpp
+++ b/layout/style/FontFaceSet.cpp
@@ -583,6 +583,19 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
nsCOMPtr<nsIStreamLoader> streamLoader;
nsCOMPtr<nsILoadGroup> loadGroup(mDocument->GetDocumentLoadGroup());
+ // We're determining the security flags for font loading here based on
+ // scheme, because we want to allow fonts to be loaded using file:
+ // even if unique origins for file: access is enforced (allow CORS
+ // bypass in this case).
+ uint32_t securityFlags = 0;
+ bool isFile = false;
+ if (NS_SUCCEEDED(aFontFaceSrc->mURI->SchemeIs("file", &isFile)) &&
+ isFile) {
+ securityFlags = nsILoadInfo::SEC_ALLOW_CROSS_ORIGIN_DATA_INHERITS;
+ } else {
+ securityFlags = nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS;
+ }
+
nsCOMPtr<nsIChannel> channel;
// Note we are calling NS_NewChannelWithTriggeringPrincipal() with both a
// node and a principal. This is because the document where the font is
@@ -592,7 +605,7 @@ FontFaceSet::StartLoad(gfxUserFontEntry* aUserFontEntry,
aFontFaceSrc->mURI,
mDocument,
aUserFontEntry->GetPrincipal(),
- nsILoadInfo::SEC_REQUIRE_CORS_DATA_INHERITS,
+ securityFlags,
nsIContentPolicy::TYPE_FONT,
loadGroup);
NS_ENSURE_SUCCESS(rv, rv);
diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp
index e5a03333f..6ba267ee8 100644
--- a/layout/svg/SVGTextFrame.cpp
+++ b/layout/svg/SVGTextFrame.cpp
@@ -1328,7 +1328,7 @@ NS_DECLARE_FRAME_PROPERTY_DELETABLE(TextNodeCorrespondenceProperty,
static uint32_t
GetUndisplayedCharactersBeforeFrame(nsTextFrame* aFrame)
{
- void* value = aFrame->Properties().Get(TextNodeCorrespondenceProperty());
+ void* value = aFrame->GetProperty(TextNodeCorrespondenceProperty());
TextNodeCorrespondence* correspondence =
static_cast<TextNodeCorrespondence*>(value);
if (!correspondence) {
@@ -1517,8 +1517,8 @@ TextNodeCorrespondenceRecorder::TraverseAndRecord(nsIFrame* aFrame)
}
// Set the frame property.
- frame->Properties().Set(TextNodeCorrespondenceProperty(),
- new TextNodeCorrespondence(undisplayed));
+ frame->SetProperty(TextNodeCorrespondenceProperty(),
+ new TextNodeCorrespondence(undisplayed));
// Remember how far into the current nsTextNode we are.
mNodeCharIndex = frame->GetContentEnd();
@@ -3391,7 +3391,7 @@ SVGTextFrame::HandleAttributeChangeInDescendant(Element* aElement,
// Blow away our reference, if any
nsIFrame* childElementFrame = aElement->GetPrimaryFrame();
if (childElementFrame) {
- childElementFrame->Properties().Delete(
+ childElementFrame->DeleteProperty(
nsSVGEffects::HrefAsTextPathProperty());
NotifyGlyphMetricsChange();
}
@@ -4817,7 +4817,7 @@ SVGPathElement*
SVGTextFrame::GetTextPathPathElement(nsIFrame* aTextPathFrame)
{
nsSVGTextPathProperty *property =
- aTextPathFrame->Properties().Get(nsSVGEffects::HrefAsTextPathProperty());
+ aTextPathFrame->GetProperty(nsSVGEffects::HrefAsTextPathProperty());
if (!property) {
nsIContent* content = aTextPathFrame->GetContent();
diff --git a/layout/svg/nsSVGEffects.cpp b/layout/svg/nsSVGEffects.cpp
index e75c973c8..ca4c5778c 100644
--- a/layout/svg/nsSVGEffects.cpp
+++ b/layout/svg/nsSVGEffects.cpp
@@ -480,27 +480,26 @@ GetOrCreateFilterProperty(nsIFrame* aFrame)
if (!effects->HasFilters())
return nullptr;
- FrameProperties props = aFrame->Properties();
- nsSVGFilterProperty *prop = props.Get(nsSVGEffects::FilterProperty());
+ nsSVGFilterProperty *prop =
+ aFrame->GetProperty(nsSVGEffects::FilterProperty());
if (prop)
return prop;
prop = new nsSVGFilterProperty(effects->mFilters, aFrame);
NS_ADDREF(prop);
- props.Set(nsSVGEffects::FilterProperty(), prop);
+ aFrame->SetProperty(nsSVGEffects::FilterProperty(), prop);
return prop;
}
static nsSVGMaskProperty*
GetOrCreateMaskProperty(nsIFrame* aFrame)
{
- FrameProperties props = aFrame->Properties();
- nsSVGMaskProperty *prop = props.Get(nsSVGEffects::MaskProperty());
+ nsSVGMaskProperty *prop = aFrame->GetProperty(nsSVGEffects::MaskProperty());
if (prop)
return prop;
prop = new nsSVGMaskProperty(aFrame);
NS_ADDREF(prop);
- props.Set(nsSVGEffects::MaskProperty(), prop);
+ aFrame->SetProperty(nsSVGEffects::MaskProperty(), prop);
return prop;
}
@@ -512,13 +511,12 @@ GetEffectProperty(nsIURI* aURI, nsIFrame* aFrame,
if (!aURI)
return nullptr;
- FrameProperties props = aFrame->Properties();
- T* prop = props.Get(aProperty);
+ T* prop = aFrame->GetProperty(aProperty);
if (prop)
return prop;
prop = new T(aURI, aFrame, false);
NS_ADDREF(prop);
- props.Set(aProperty, prop);
+ aFrame->SetProperty(aProperty, prop);
return prop;
}
@@ -553,11 +551,11 @@ nsSVGEffects::GetPaintingPropertyForURI(nsIURI* aURI, nsIFrame* aFrame,
if (!aURI)
return nullptr;
- FrameProperties props = aFrame->Properties();
- nsSVGEffects::URIObserverHashtable *hashtable = props.Get(aProperty);
+ nsSVGEffects::URIObserverHashtable *hashtable =
+ aFrame->GetProperty(aProperty);
if (!hashtable) {
hashtable = new nsSVGEffects::URIObserverHashtable();
- props.Set(aProperty, hashtable);
+ aFrame->SetProperty(aProperty, hashtable);
}
nsSVGPaintingProperty* prop =
static_cast<nsSVGPaintingProperty*>(hashtable->GetWeak(aURI));
@@ -689,16 +687,15 @@ nsSVGEffects::UpdateEffects(nsIFrame* aFrame)
NS_ASSERTION(aFrame->GetContent()->IsElement(),
"aFrame's content should be an element");
- FrameProperties props = aFrame->Properties();
- props.Delete(FilterProperty());
- props.Delete(MaskProperty());
- props.Delete(ClipPathProperty());
- props.Delete(MarkerBeginProperty());
- props.Delete(MarkerMiddleProperty());
- props.Delete(MarkerEndProperty());
- props.Delete(FillProperty());
- props.Delete(StrokeProperty());
- props.Delete(BackgroundImageProperty());
+ aFrame->DeleteProperty(FilterProperty());
+ aFrame->DeleteProperty(MaskProperty());
+ aFrame->DeleteProperty(ClipPathProperty());
+ aFrame->DeleteProperty(MarkerBeginProperty());
+ aFrame->DeleteProperty(MarkerMiddleProperty());
+ aFrame->DeleteProperty(MarkerEndProperty());
+ aFrame->DeleteProperty(FillProperty());
+ aFrame->DeleteProperty(StrokeProperty());
+ aFrame->DeleteProperty(BackgroundImageProperty());
// Ensure that the filter is repainted correctly
// We can't do that in DoUpdate as the referenced frame may not be valid
@@ -725,7 +722,7 @@ nsSVGEffects::GetFilterProperty(nsIFrame* aFrame)
if (!aFrame->StyleEffects()->HasFilters())
return nullptr;
- return aFrame->Properties().Get(FilterProperty());
+ return aFrame->GetProperty(FilterProperty());
}
void
@@ -835,7 +832,7 @@ nsSVGEffects::InvalidateRenderingObservers(nsIFrame* aFrame)
return;
// If the rendering has changed, the bounds may well have changed too:
- aFrame->Properties().Delete(nsSVGUtils::ObjectBoundingBoxProperty());
+ aFrame->DeleteProperty(nsSVGUtils::ObjectBoundingBoxProperty());
nsSVGRenderingObserverList *observerList =
GetObserverList(content->AsElement());
@@ -864,7 +861,7 @@ nsSVGEffects::InvalidateDirectRenderingObservers(Element* aElement, uint32_t aFl
nsIFrame* frame = aElement->GetPrimaryFrame();
if (frame) {
// If the rendering has changed, the bounds may well have changed too:
- frame->Properties().Delete(nsSVGUtils::ObjectBoundingBoxProperty());
+ frame->DeleteProperty(nsSVGUtils::ObjectBoundingBoxProperty());
}
if (aElement->HasRenderingObservers()) {
diff --git a/layout/svg/nsSVGEffects.h b/layout/svg/nsSVGEffects.h
index 0cf9b1500..b8b2e53c1 100644
--- a/layout/svg/nsSVGEffects.h
+++ b/layout/svg/nsSVGEffects.h
@@ -7,7 +7,7 @@
#define NSSVGEFFECTS_H_
#include "mozilla/Attributes.h"
-#include "FramePropertyTable.h"
+#include "FrameProperties.h"
#include "mozilla/dom/Element.h"
#include "nsHashKeys.h"
#include "nsID.h"
diff --git a/layout/svg/nsSVGFilterFrame.cpp b/layout/svg/nsSVGFilterFrame.cpp
index 13ce16993..3b99f413e 100644
--- a/layout/svg/nsSVGFilterFrame.cpp
+++ b/layout/svg/nsSVGFilterFrame.cpp
@@ -107,7 +107,7 @@ nsSVGFilterFrame::GetReferencedFilter()
return nullptr;
nsSVGPaintingProperty *property =
- Properties().Get(nsSVGEffects::HrefAsPaintingProperty());
+ GetProperty(nsSVGEffects::HrefAsPaintingProperty());
if (!property) {
// Fetch our Filter element's href or xlink:href attribute
@@ -183,7 +183,7 @@ nsSVGFilterFrame::AttributeChanged(int32_t aNameSpaceID,
aNameSpaceID == kNameSpaceID_None) &&
aAttribute == nsGkAtoms::href) {
// Blow away our reference, if any
- Properties().Delete(nsSVGEffects::HrefAsPaintingProperty());
+ DeleteProperty(nsSVGEffects::HrefAsPaintingProperty());
mNoHRefURI = false;
// And update whoever references us
nsSVGEffects::InvalidateDirectRenderingObservers(this);
diff --git a/layout/svg/nsSVGGradientFrame.cpp b/layout/svg/nsSVGGradientFrame.cpp
index 2d7684f5a..340cfa881 100644
--- a/layout/svg/nsSVGGradientFrame.cpp
+++ b/layout/svg/nsSVGGradientFrame.cpp
@@ -72,7 +72,7 @@ nsSVGGradientFrame::AttributeChanged(int32_t aNameSpaceID,
aNameSpaceID == kNameSpaceID_None) &&
aAttribute == nsGkAtoms::href) {
// Blow away our reference, if any
- Properties().Delete(nsSVGEffects::HrefAsPaintingProperty());
+ DeleteProperty(nsSVGEffects::HrefAsPaintingProperty());
mNoHRefURI = false;
// And update whoever references us
nsSVGEffects::InvalidateDirectRenderingObservers(this);
@@ -316,7 +316,7 @@ nsSVGGradientFrame::GetReferencedGradient()
return nullptr;
nsSVGPaintingProperty *property =
- Properties().Get(nsSVGEffects::HrefAsPaintingProperty());
+ GetProperty(nsSVGEffects::HrefAsPaintingProperty());
if (!property) {
// Fetch our gradient element's href or xlink:href attribute
diff --git a/layout/svg/nsSVGIntegrationUtils.cpp b/layout/svg/nsSVGIntegrationUtils.cpp
index 0003e1a73..4ce2941d4 100644
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -75,7 +75,7 @@ public:
private:
static nsRect GetPreEffectsVisualOverflowRect(nsIFrame* aFrame) {
- nsRect* r = aFrame->Properties().Get(nsIFrame::PreEffectsBBoxProperty());
+ nsRect* r = aFrame->GetProperty(nsIFrame::PreEffectsBBoxProperty());
if (r) {
return *r;
}
@@ -113,8 +113,7 @@ private:
NS_ASSERTION(aFrame->GetParent()->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::mozAnonymousBlock,
"How did we getting here, then?");
- NS_ASSERTION(!aFrame->Properties().Get(
- aFrame->PreTransformOverflowAreasProperty()),
+ NS_ASSERTION(!aFrame->GetProperty(aFrame->PreTransformOverflowAreasProperty()),
"GetVisualOverflowRect() won't return the pre-effects rect!");
return aFrame->GetVisualOverflowRect();
}
diff --git a/layout/svg/nsSVGOuterSVGFrame.cpp b/layout/svg/nsSVGOuterSVGFrame.cpp
index e1b97bb40..b1ee54eb9 100644
--- a/layout/svg/nsSVGOuterSVGFrame.cpp
+++ b/layout/svg/nsSVGOuterSVGFrame.cpp
@@ -979,43 +979,56 @@ nsSVGOuterSVGAnonChildFrame::GetType() const
return nsGkAtoms::svgOuterSVGAnonChildFrame;
}
-bool
-nsSVGOuterSVGAnonChildFrame::IsSVGTransformed(Matrix* aOwnTransform,
- Matrix* aFromParentTransform) const
+static Matrix
+ComputeOuterSVGAnonChildFrameTransform(const nsSVGOuterSVGAnonChildFrame* aFrame)
{
// Our elements 'transform' attribute is applied to our nsSVGOuterSVGFrame
// parent, and the element's children-only transforms are applied to us, the
// anonymous child frame. Since we are the child frame, we apply the
// children-only transforms as if they are our own transform.
- SVGSVGElement* content = static_cast<SVGSVGElement*>(mContent);
+ SVGSVGElement* content = static_cast<SVGSVGElement*>(aFrame->GetContent());
if (!content->HasChildrenOnlyTransform()) {
- return false;
+ return Matrix();
}
// Outer-<svg> doesn't use x/y, so we can pass eChildToUserSpace here.
gfxMatrix ownMatrix =
content->PrependLocalTransformsTo(gfxMatrix(), eChildToUserSpace);
- if (ownMatrix.IsIdentity()) {
- return false;
+ if (ownMatrix.HasNonTranslation()) {
+ // viewBox, currentScale and currentTranslate should only produce a
+ // rectilinear transform.
+ MOZ_ASSERT(ownMatrix.IsRectilinear(),
+ "Non-rectilinear transform will break the following logic");
+
+ // The nsDisplayTransform code will apply this transform to our frame,
+ // including to our frame position. We don't want our frame position to
+ // be scaled though, so we need to correct for that in the transform.
+ CSSPoint pos = CSSPixel::FromAppUnits(aFrame->GetPosition());
+ CSSPoint scaledPos = CSSPoint(ownMatrix._11 * pos.x, ownMatrix._22 * pos.y);
+ CSSPoint deltaPos = scaledPos - pos;
+ ownMatrix *= gfxMatrix::Translation(-deltaPos.x, -deltaPos.y);
}
- if (aOwnTransform) {
- if (ownMatrix.HasNonTranslation()) {
- // Note: viewBox, currentScale and currentTranslate should only
- // produce a rectilinear transform.
- // The nsDisplayTransform code will apply this transform to our frame,
- // including to our frame position. We don't want our frame position to
- // be scaled though, so we need to correct for that in the transform.
- CSSPoint pos = CSSPixel::FromAppUnits(GetPosition());
- CSSPoint scaledPos = CSSPoint(ownMatrix._11 * pos.x, ownMatrix._22 * pos.y);
- CSSPoint deltaPos = scaledPos - pos;
- ownMatrix *= gfxMatrix::Translation(-deltaPos.x, -deltaPos.y);
- }
+ return gfx::ToMatrix(ownMatrix);
+}
- *aOwnTransform = gfx::ToMatrix(ownMatrix);
+// We want this frame to be a reference frame. An easy way to achieve that is
+// to always return true from this method, even for identity transforms.
+// This frame being a reference frame ensures that the offset between this
+// <svg> element and the parent reference frame is completely absorbed by the
+// nsDisplayTransform that's created for this frame, and that this offset does
+// not affect our descendants' transforms. Consequently, if the <svg> element
+// moves, e.g. during scrolling, the transform matrices of our contents are
+// unaffected. This simplifies invalidation.
+bool
+nsSVGOuterSVGAnonChildFrame::IsSVGTransformed(Matrix* aOwnTransform,
+ Matrix* aFromParentTransform) const
+{
+ if (aOwnTransform) {
+ *aOwnTransform = ComputeOuterSVGAnonChildFrameTransform(this);
}
return true;
diff --git a/layout/svg/nsSVGPatternFrame.cpp b/layout/svg/nsSVGPatternFrame.cpp
index 198163d7f..2cd7eeaad 100644
--- a/layout/svg/nsSVGPatternFrame.cpp
+++ b/layout/svg/nsSVGPatternFrame.cpp
@@ -89,7 +89,7 @@ nsSVGPatternFrame::AttributeChanged(int32_t aNameSpaceID,
aNameSpaceID == kNameSpaceID_None) &&
aAttribute == nsGkAtoms::href) {
// Blow away our reference, if any
- Properties().Delete(nsSVGEffects::HrefAsPaintingProperty());
+ DeleteProperty(nsSVGEffects::HrefAsPaintingProperty());
mNoHRefURI = false;
// And update whoever references us
nsSVGEffects::InvalidateDirectRenderingObservers(this);
@@ -548,7 +548,7 @@ nsSVGPatternFrame::GetReferencedPattern()
return nullptr;
nsSVGPaintingProperty *property =
- Properties().Get(nsSVGEffects::HrefAsPaintingProperty());
+ GetProperty(nsSVGEffects::HrefAsPaintingProperty());
if (!property) {
// Fetch our pattern element's href or xlink:href attribute
diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp
index 98e5f9b5f..c3394e292 100644
--- a/layout/svg/nsSVGUtils.cpp
+++ b/layout/svg/nsSVGUtils.cpp
@@ -1060,10 +1060,9 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags)
return bbox;
}
- FrameProperties props = aFrame->Properties();
if (aFlags == eBBoxIncludeFillGeometry) {
- gfxRect* prop = props.Get(ObjectBoundingBoxProperty());
+ gfxRect* prop = aFrame->GetProperty(ObjectBoundingBoxProperty());
if (prop) {
return *prop;
}
@@ -1139,7 +1138,7 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags)
if (aFlags == eBBoxIncludeFillGeometry) {
// Obtaining the bbox for objectBoundingBox calculations is common so we
// cache the result for future calls, since calculation can be expensive:
- props.Set(ObjectBoundingBoxProperty(), new gfxRect(bbox));
+ aFrame->SetProperty(ObjectBoundingBoxProperty(), new gfxRect(bbox));
}
return bbox;
diff --git a/layout/tables/nsTableFrame.cpp b/layout/tables/nsTableFrame.cpp
index 4c11d2704..b9b6ca5fe 100644
--- a/layout/tables/nsTableFrame.cpp
+++ b/layout/tables/nsTableFrame.cpp
@@ -272,13 +272,12 @@ nsTableFrame::RegisterPositionedTablePart(nsIFrame* aFrame)
tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation());
// Retrieve the positioned parts array for this table.
- FrameProperties props = tableFrame->Properties();
- FrameTArray* positionedParts = props.Get(PositionedTablePartArray());
+ FrameTArray* positionedParts = tableFrame->GetProperty(PositionedTablePartArray());
// Lazily create the array if it doesn't exist yet.
if (!positionedParts) {
positionedParts = new FrameTArray;
- props.Set(PositionedTablePartArray(), positionedParts);
+ tableFrame->SetProperty(PositionedTablePartArray(), positionedParts);
}
// Add this frame to the list.
@@ -302,8 +301,7 @@ nsTableFrame::UnregisterPositionedTablePart(nsIFrame* aFrame,
tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation());
// Retrieve the positioned parts array for this table.
- FrameProperties props = tableFrame->Properties();
- FrameTArray* positionedParts = props.Get(PositionedTablePartArray());
+ FrameTArray* positionedParts = tableFrame->GetProperty(PositionedTablePartArray());
// Remove the frame.
MOZ_ASSERT(positionedParts && positionedParts->Contains(aFrame),
@@ -1992,7 +1990,7 @@ nsTableFrame::FixupPositionedTableParts(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput)
{
- FrameTArray* positionedParts = Properties().Get(PositionedTablePartArray());
+ FrameTArray* positionedParts = GetProperty(PositionedTablePartArray());
if (!positionedParts) {
return;
}
@@ -2653,13 +2651,18 @@ nsTableFrame::GetUsedMargin() const
NS_DECLARE_FRAME_PROPERTY_DELETABLE(TableBCProperty, BCPropertyData)
BCPropertyData*
-nsTableFrame::GetBCProperty(bool aCreateIfNecessary) const
+nsTableFrame::GetBCProperty() const
{
- FrameProperties props = Properties();
- BCPropertyData* value = props.Get(TableBCProperty());
- if (!value && aCreateIfNecessary) {
+ return GetProperty(TableBCProperty());
+}
+
+BCPropertyData*
+nsTableFrame::GetOrCreateBCProperty()
+{
+ BCPropertyData* value = GetProperty(TableBCProperty());
+ if (!value) {
value = new BCPropertyData();
- props.Set(TableBCProperty(), value);
+ SetProperty(TableBCProperty(), value);
}
return value;
@@ -4103,7 +4106,7 @@ nsTableFrame::AddBCDamageArea(const TableArea& aValue)
SetNeedToCalcBCBorders(true);
// Get the property
- BCPropertyData* value = GetBCProperty(true);
+ BCPropertyData* value = GetOrCreateBCProperty();
if (value) {
#ifdef DEBUG
VerifyNonNegativeDamageRect(value->mDamageArea);
@@ -4143,7 +4146,7 @@ nsTableFrame::SetFullBCDamageArea()
SetNeedToCalcBCBorders(true);
- BCPropertyData* value = GetBCProperty(true);
+ BCPropertyData* value = GetOrCreateBCProperty();
if (value) {
value->mDamageArea = TableArea(0, 0, GetColCount(), GetRowCount());
}
@@ -4310,7 +4313,7 @@ BCMapCellInfo::BCMapCellInfo(nsTableFrame* aTableFrame)
: mTableFrame(aTableFrame)
, mNumTableRows(aTableFrame->GetRowCount())
, mNumTableCols(aTableFrame->GetColCount())
- , mTableBCData(mTableFrame->Properties().Get(TableBCProperty()))
+ , mTableBCData(mTableFrame->GetProperty(TableBCProperty()))
, mTableWM(aTableFrame->StyleContext())
{
ResetCellInfo();
diff --git a/layout/tables/nsTableFrame.h b/layout/tables/nsTableFrame.h
index a78625339..7e56c28c1 100644
--- a/layout/tables/nsTableFrame.h
+++ b/layout/tables/nsTableFrame.h
@@ -809,7 +809,8 @@ protected:
void SetBorderCollapse(bool aValue);
- BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const;
+ BCPropertyData* GetBCProperty() const;
+ BCPropertyData* GetOrCreateBCProperty();
void SetFullBCDamageArea();
void CalcBCBorders();
diff --git a/layout/tables/nsTableRowFrame.cpp b/layout/tables/nsTableRowFrame.cpp
index 81b5d6699..1b6051ef2 100644
--- a/layout/tables/nsTableRowFrame.cpp
+++ b/layout/tables/nsTableRowFrame.cpp
@@ -978,7 +978,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
// MovePositionBy does internally. (This codepath should really
// be merged into the else below if we can.)
nsMargin* computedOffsetProp =
- kidFrame->Properties().Get(nsIFrame::ComputedOffsetProperty());
+ kidFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
// Bug 975644: a position:sticky kid can end up with a null
// property value here.
LogicalMargin computedOffsets(wm, computedOffsetProp ?
@@ -1417,16 +1417,14 @@ nsTableRowFrame::SetUnpaginatedBSize(nsPresContext* aPresContext,
nscoord aValue)
{
NS_ASSERTION(!GetPrevInFlow(), "program error");
- // Get the property
- aPresContext->PropertyTable()->
- Set(this, RowUnpaginatedHeightProperty(), aValue);
+ // Set the property
+ SetProperty(RowUnpaginatedHeightProperty(), aValue);
}
nscoord
nsTableRowFrame::GetUnpaginatedBSize()
{
- FrameProperties props = FirstInFlow()->Properties();
- return props.Get(RowUnpaginatedHeightProperty());
+ return GetProperty(RowUnpaginatedHeightProperty());
}
void nsTableRowFrame::SetContinuousBCBorderWidth(LogicalSide aForSide,
diff --git a/layout/tables/nsTableRowGroupFrame.cpp b/layout/tables/nsTableRowGroupFrame.cpp
index 60596f12b..8f014b204 100644
--- a/layout/tables/nsTableRowGroupFrame.cpp
+++ b/layout/tables/nsTableRowGroupFrame.cpp
@@ -1910,7 +1910,7 @@ nsTableRowGroupFrame::ClearRowCursor()
}
RemoveStateBits(NS_ROWGROUP_HAS_ROW_CURSOR);
- Properties().Delete(RowCursorProperty());
+ DeleteProperty(RowCursorProperty());
}
nsTableRowGroupFrame::FrameCursorData*
@@ -1934,7 +1934,7 @@ nsTableRowGroupFrame::SetupRowCursor()
FrameCursorData* data = new FrameCursorData();
if (!data)
return nullptr;
- Properties().Set(RowCursorProperty(), data);
+ SetProperty(RowCursorProperty(), data);
AddStateBits(NS_ROWGROUP_HAS_ROW_CURSOR);
return data;
}
@@ -1946,7 +1946,7 @@ nsTableRowGroupFrame::GetFirstRowContaining(nscoord aY, nscoord* aOverflowAbove)
return nullptr;
}
- FrameCursorData* property = Properties().Get(RowCursorProperty());
+ FrameCursorData* property = GetProperty(RowCursorProperty());
uint32_t cursorIndex = property->mCursorIndex;
uint32_t frameCount = property->mFrames.Length();
if (cursorIndex >= frameCount)
diff --git a/layout/tables/nsTableWrapperFrame.cpp b/layout/tables/nsTableWrapperFrame.cpp
index e44652a73..f0b6d1512 100644
--- a/layout/tables/nsTableWrapperFrame.cpp
+++ b/layout/tables/nsTableWrapperFrame.cpp
@@ -246,7 +246,7 @@ nsTableWrapperFrame::InitChildReflowInput(nsPresContext& aPresContext,
}
// Propagate our stored CB size if present, minus any margins.
if (!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
- LogicalSize* cb = Properties().Get(GridItemCBSizeProperty());
+ LogicalSize* cb = GetProperty(GridItemCBSizeProperty());
if (cb) {
cbSize.emplace(*cb);
*cbSize -= aReflowInput.ComputedLogicalMargin().Size(wm);
@@ -953,7 +953,7 @@ nsTableWrapperFrame::Reflow(nsPresContext* aPresContext,
// for the table frame if we are bsize constrained and the caption is above
// or below the inner table. Also reduce the CB size that we store for
// our children in case we're a grid item, by the same amount.
- LogicalSize* cbSize = Properties().Get(GridItemCBSizeProperty());
+ LogicalSize* cbSize = GetProperty(GridItemCBSizeProperty());
if (NS_UNCONSTRAINEDSIZE != aOuterRI.AvailableBSize() || cbSize) {
nscoord captionBSize = 0;
nscoord captionISize = 0;
diff --git a/layout/xul/nsBox.cpp b/layout/xul/nsBox.cpp
index f7ec5fead..787758b15 100644
--- a/layout/xul/nsBox.cpp
+++ b/layout/xul/nsBox.cpp
@@ -144,10 +144,9 @@ nsBox::BeginXULLayout(nsBoxLayoutState& aState)
// Another copy-over from ReflowInput.
// Since we are in reflow, we don't need to store these properties anymore.
- FrameProperties props = Properties();
- props.Delete(UsedBorderProperty());
- props.Delete(UsedPaddingProperty());
- props.Delete(UsedMarginProperty());
+ DeleteProperty(UsedBorderProperty());
+ DeleteProperty(UsedPaddingProperty());
+ DeleteProperty(UsedMarginProperty());
#ifdef DEBUG_LAYOUT
PropagateDebug(aState);
diff --git a/layout/xul/nsMenuFrame.cpp b/layout/xul/nsMenuFrame.cpp
index ea968fab5..67fcdbe43 100644
--- a/layout/xul/nsMenuFrame.cpp
+++ b/layout/xul/nsMenuFrame.cpp
@@ -273,7 +273,7 @@ nsMenuFrame::GetPopupList() const
if (!HasPopup()) {
return nullptr;
}
- nsFrameList* prop = Properties().Get(PopupListProperty());
+ nsFrameList* prop = GetProperty(PopupListProperty());
NS_ASSERTION(prop && prop->GetLength() == 1 &&
prop->FirstChild()->GetType() == nsGkAtoms::menuPopupFrame,
"popup list should have exactly one nsMenuPopupFrame");
@@ -284,7 +284,7 @@ void
nsMenuFrame::DestroyPopupList()
{
NS_ASSERTION(HasPopup(), "huh?");
- nsFrameList* prop = Properties().Remove(PopupListProperty());
+ nsFrameList* prop = RemoveProperty(PopupListProperty());
NS_ASSERTION(prop && prop->IsEmpty(),
"popup list must exist and be empty when destroying");
RemoveStateBits(NS_STATE_MENU_HAS_POPUP_LIST);
@@ -300,7 +300,7 @@ nsMenuFrame::SetPopupFrame(nsFrameList& aFrameList)
// Remove the frame from the list and store it in a nsFrameList* property.
aFrameList.RemoveFrame(popupFrame);
nsFrameList* popupList = new (PresContext()->PresShell()) nsFrameList(popupFrame, popupFrame);
- Properties().Set(PopupListProperty(), popupList);
+ SetProperty(PopupListProperty(), popupList);
AddStateBits(NS_STATE_MENU_HAS_POPUP_LIST);
break;
}