Attach FrameProperties to each frame instead of using a shared hashtable.

This commit is contained in:
Fedor 2019-09-05 20:02:58 +03:00
parent 26016db6b3
commit a65230322e
62 changed files with 808 additions and 972 deletions

View File

@ -11943,7 +11943,8 @@ nsIDocument::DocAddSizeOfExcludingThis(nsWindowSizes* aWindowSizes) const
&aWindowSizes->mLayoutPresShellSize, &aWindowSizes->mLayoutPresShellSize,
&aWindowSizes->mLayoutStyleSetsSize, &aWindowSizes->mLayoutStyleSetsSize,
&aWindowSizes->mLayoutTextRunsSize, &aWindowSizes->mLayoutTextRunsSize,
&aWindowSizes->mLayoutPresContextSize); &aWindowSizes->mLayoutPresContextSize,
&aWindowSizes->mLayoutFramePropertiesSize);
} }
aWindowSizes->mPropertyTablesSize += aWindowSizes->mPropertyTablesSize +=

View File

@ -400,6 +400,12 @@ CollectWindowReports(nsGlobalWindow *aWindow,
aWindowTotalSizes->mLayoutPresContextSize += aWindowTotalSizes->mLayoutPresContextSize +=
windowSizes.mLayoutPresContextSize; windowSizes.mLayoutPresContextSize;
REPORT_SIZE("/layout/frame-properties", windowSizes.mLayoutFramePropertiesSize,
"Memory used for frame properties attached to frames "
"within a window.");
aWindowTotalSizes->mLayoutFramePropertiesSize +=
windowSizes.mLayoutFramePropertiesSize;
// There are many different kinds of frames, but it is very likely // There are many different kinds of frames, but it is very likely
// that only a few matter. Implement a cutoff so we don't bloat // that only a few matter. Implement a cutoff so we don't bloat
// about:memory with many uninteresting entries. // about:memory with many uninteresting entries.
@ -563,6 +569,9 @@ nsWindowMemoryReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
REPORT("window-objects/layout/pres-contexts", windowTotalSizes.mLayoutPresContextSize, REPORT("window-objects/layout/pres-contexts", windowTotalSizes.mLayoutPresContextSize,
"This is the sum of all windows' 'layout/pres-contexts' numbers."); "This is the sum of all windows' 'layout/pres-contexts' numbers.");
REPORT("window-objects/layout/frame-properties", windowTotalSizes.mLayoutFramePropertiesSize,
"This is the sum of all windows' 'layout/frame-properties' numbers.");
size_t frameTotal = 0; size_t frameTotal = 0;
#define FRAME_ID(classname) \ #define FRAME_ID(classname) \
frameTotal += windowTotalSizes.mArenaStats.FRAME_ID_STAT_FIELD(classname); frameTotal += windowTotalSizes.mArenaStats.FRAME_ID_STAT_FIELD(classname);

View File

@ -33,6 +33,7 @@ class nsWindowSizes {
macro(Style, mLayoutStyleSetsSize) \ macro(Style, mLayoutStyleSetsSize) \
macro(Other, mLayoutTextRunsSize) \ macro(Other, mLayoutTextRunsSize) \
macro(Other, mLayoutPresContextSize) \ macro(Other, mLayoutPresContextSize) \
macro(Other, mLayoutFramePropertiesSize) \
macro(Other, mPropertyTablesSize) \ macro(Other, mPropertyTablesSize) \
public: public:

View File

@ -178,7 +178,7 @@ LayerActivityTracker::NotifyExpired(LayerActivity* aObject)
f->SchedulePaint(); f->SchedulePaint();
} }
f->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY); f->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
f->Properties().Delete(LayerActivityProperty()); f->DeleteProperty(LayerActivityProperty());
} else { } else {
c->DeleteProperty(nsGkAtoms::LayerActivity); c->DeleteProperty(nsGkAtoms::LayerActivity);
} }
@ -190,15 +190,13 @@ GetLayerActivity(nsIFrame* aFrame)
if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) { if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
return nullptr; return nullptr;
} }
FrameProperties properties = aFrame->Properties(); return aFrame->GetProperty(LayerActivityProperty());
return properties.Get(LayerActivityProperty());
} }
static LayerActivity* static LayerActivity*
GetLayerActivityForUpdate(nsIFrame* aFrame) GetLayerActivityForUpdate(nsIFrame* aFrame)
{ {
FrameProperties properties = aFrame->Properties(); LayerActivity* layerActivity = aFrame->GetProperty(LayerActivityProperty());
LayerActivity* layerActivity = properties.Get(LayerActivityProperty());
if (layerActivity) { if (layerActivity) {
gLayerActivityTracker->MarkUsed(layerActivity); gLayerActivityTracker->MarkUsed(layerActivity);
} else { } else {
@ -208,7 +206,7 @@ GetLayerActivityForUpdate(nsIFrame* aFrame)
layerActivity = new LayerActivity(aFrame); layerActivity = new LayerActivity(aFrame);
gLayerActivityTracker->AddObject(layerActivity); gLayerActivityTracker->AddObject(layerActivity);
aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY); aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
properties.Set(LayerActivityProperty(), layerActivity); aFrame->SetProperty(LayerActivityProperty(), layerActivity);
} }
return layerActivity; return layerActivity;
} }
@ -225,8 +223,7 @@ ActiveLayerTracker::TransferActivityToContent(nsIFrame* aFrame, nsIContent* aCon
if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) { if (!aFrame->HasAnyStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY)) {
return; return;
} }
FrameProperties properties = aFrame->Properties(); LayerActivity* layerActivity = aFrame->RemoveProperty(LayerActivityProperty());
LayerActivity* layerActivity = properties.Remove(LayerActivityProperty());
aFrame->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY); aFrame->RemoveStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
if (!layerActivity) { if (!layerActivity) {
return; return;
@ -248,7 +245,7 @@ ActiveLayerTracker::TransferActivityToFrame(nsIContent* aContent, nsIFrame* aFra
layerActivity->mContent = nullptr; layerActivity->mContent = nullptr;
layerActivity->mFrame = aFrame; layerActivity->mFrame = aFrame;
aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY); aFrame->AddStateBits(NS_FRAME_HAS_LAYER_ACTIVITY_PROPERTY);
aFrame->Properties().Set(LayerActivityProperty(), layerActivity); aFrame->SetProperty(LayerActivityProperty(), layerActivity);
} }
static void static void

View File

@ -165,10 +165,10 @@ FrameLayerBuilder::DisplayItemData::AddFrame(nsIFrame* aFrame)
mFrameList.AppendElement(aFrame); mFrameList.AppendElement(aFrame);
nsTArray<DisplayItemData*>* array = nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(FrameLayerBuilder::LayerManagerDataProperty()); aFrame->GetProperty(FrameLayerBuilder::LayerManagerDataProperty());
if (!array) { if (!array) {
array = new nsTArray<DisplayItemData*>(); array = new nsTArray<DisplayItemData*>();
aFrame->Properties().Set(FrameLayerBuilder::LayerManagerDataProperty(), array); aFrame->SetProperty(FrameLayerBuilder::LayerManagerDataProperty(), array);
} }
array->AppendElement(this); 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!"); MOZ_RELEASE_ASSERT(result, "Can't remove a frame that wasn't added!");
nsTArray<DisplayItemData*>* array = nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(FrameLayerBuilder::LayerManagerDataProperty()); aFrame->GetProperty(FrameLayerBuilder::LayerManagerDataProperty());
MOZ_RELEASE_ASSERT(array, "Must be already stored on the frame!"); MOZ_RELEASE_ASSERT(array, "Must be already stored on the frame!");
array->RemoveElement(this); array->RemoveElement(this);
} }
@ -268,7 +268,7 @@ FrameLayerBuilder::DisplayItemData::~DisplayItemData()
continue; continue;
} }
nsTArray<DisplayItemData*> *array = nsTArray<DisplayItemData*> *array =
reinterpret_cast<nsTArray<DisplayItemData*>*>(frame->Properties().Get(LayerManagerDataProperty())); reinterpret_cast<nsTArray<DisplayItemData*>*>(frame->GetProperty(LayerManagerDataProperty()));
array->RemoveElement(this); array->RemoveElement(this);
} }
@ -390,8 +390,7 @@ public:
/* static */ void /* static */ void
FrameLayerBuilder::DestroyDisplayItemDataFor(nsIFrame* aFrame) FrameLayerBuilder::DestroyDisplayItemDataFor(nsIFrame* aFrame)
{ {
FrameProperties props = aFrame->Properties(); aFrame->DeleteProperty(LayerManagerDataProperty());
props.Delete(LayerManagerDataProperty());
} }
struct AssignedDisplayItem struct AssignedDisplayItem
@ -1823,7 +1822,7 @@ FrameLayerBuilder::DisplayItemData*
FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey) FrameLayerBuilder::GetDisplayItemData(nsIFrame* aFrame, uint32_t aKey)
{ {
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty()); aFrame->GetProperty(LayerManagerDataProperty());
if (array) { if (array) {
for (uint32_t i = 0; i < array->Length(); i++) { for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i)); DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
@ -2052,7 +2051,7 @@ FrameLayerBuilder::GetDisplayItemDataForManager(nsDisplayItem* aItem,
LayerManager* aManager) LayerManager* aManager)
{ {
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
aItem->Frame()->Properties().Get(LayerManagerDataProperty()); aItem->Frame()->GetProperty(LayerManagerDataProperty());
if (array) { if (array) {
for (uint32_t i = 0; i < array->Length(); i++) { for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i)); DisplayItemData* item = AssertDisplayItemData(array->ElementAt(i));
@ -2069,7 +2068,7 @@ bool
FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey) FrameLayerBuilder::HasRetainedDataFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
{ {
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty()); aFrame->GetProperty(LayerManagerDataProperty());
if (array) { if (array) {
for (uint32_t i = 0; i < array->Length(); i++) { for (uint32_t i = 0; i < array->Length(); i++) {
if (AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) { if (AssertDisplayItemData(array->ElementAt(i))->mDisplayItemKey == aDisplayItemKey) {
@ -2084,7 +2083,7 @@ void
FrameLayerBuilder::IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback) FrameLayerBuilder::IterateRetainedDataFor(nsIFrame* aFrame, DisplayItemDataCallback aCallback)
{ {
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty()); aFrame->GetProperty(LayerManagerDataProperty());
if (!array) { if (!array) {
return; return;
} }
@ -2151,7 +2150,7 @@ FrameLayerBuilder::ClearCachedGeometry(nsDisplayItem* aItem)
FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey) FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKey)
{ {
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty()); aFrame->GetProperty(LayerManagerDataProperty());
if (!array) { if (!array) {
return nullptr; return nullptr;
@ -2171,7 +2170,7 @@ FrameLayerBuilder::GetDebugOldLayerFor(nsIFrame* aFrame, uint32_t aDisplayItemKe
FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(nsIFrame* aFrame) FrameLayerBuilder::GetDebugSingleOldPaintedLayerForFrame(nsIFrame* aFrame)
{ {
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty()); aFrame->GetProperty(LayerManagerDataProperty());
if (!array) { if (!array) {
return nullptr; return nullptr;
@ -5656,7 +5655,7 @@ FrameLayerBuilder::InvalidateAllLayers(LayerManager* aManager)
FrameLayerBuilder::InvalidateAllLayersForFrame(nsIFrame *aFrame) FrameLayerBuilder::InvalidateAllLayersForFrame(nsIFrame *aFrame)
{ {
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty()); aFrame->GetProperty(LayerManagerDataProperty());
if (array) { if (array) {
for (uint32_t i = 0; i < array->Length(); i++) { for (uint32_t i = 0; i < array->Length(); i++) {
AssertDisplayItemData(array->ElementAt(i))->mParent->mInvalidateAllLayers = true; AssertDisplayItemData(array->ElementAt(i))->mParent->mInvalidateAllLayers = true;
@ -5673,7 +5672,7 @@ FrameLayerBuilder::GetDedicatedLayer(nsIFrame* aFrame, uint32_t aDisplayItemKey)
// in the secondary manager // in the secondary manager
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
aFrame->Properties().Get(LayerManagerDataProperty()); aFrame->GetProperty(LayerManagerDataProperty());
if (array) { if (array) {
for (uint32_t i = 0; i < array->Length(); i++) { for (uint32_t i = 0; i < array->Length(); i++) {
DisplayItemData *element = AssertDisplayItemData(array->ElementAt(i)); DisplayItemData *element = AssertDisplayItemData(array->ElementAt(i));
@ -5729,7 +5728,7 @@ FrameLayerBuilder::GetPaintedLayerScaleForFrame(nsIFrame* aFrame)
} }
const nsTArray<DisplayItemData*>* array = const nsTArray<DisplayItemData*>* array =
f->Properties().Get(LayerManagerDataProperty()); f->GetProperty(LayerManagerDataProperty());
if (!array) { if (!array) {
continue; continue;
} }
@ -6165,9 +6164,8 @@ FrameLayerBuilder::GetMostRecentGeometry(nsDisplayItem* aItem)
typedef nsTArray<DisplayItemData*> DataArray; typedef nsTArray<DisplayItemData*> DataArray;
// Retrieve the array of DisplayItemData associated with our frame. // Retrieve the array of DisplayItemData associated with our frame.
FrameProperties properties = aItem->Frame()->Properties();
const DataArray* dataArray = const DataArray* dataArray =
properties.Get(LayerManagerDataProperty()); aItem->Frame()->GetProperty(LayerManagerDataProperty());
if (!dataArray) { if (!dataArray) {
return nullptr; return nullptr;
} }

View File

@ -3,15 +3,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef FRAMEPROPERTYTABLE_H_ #ifndef FRAMEPROPERTIES_H_
#define FRAMEPROPERTYTABLE_H_ #define FRAMEPROPERTIES_H_
#include "mozilla/DebugOnly.h"
#include "mozilla/MemoryReporting.h" #include "mozilla/MemoryReporting.h"
#include "mozilla/TypeTraits.h" #include "mozilla/TypeTraits.h"
#include "mozilla/Unused.h" #include "mozilla/Unused.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsTHashtable.h" #include "nsThreadUtils.h"
#include "nsHashKeys.h"
class nsIFrame; class nsIFrame;
@ -62,7 +62,7 @@ protected:
* *
* To use this class, declare a global (i.e., file, class or function-scope * To use this class, declare a global (i.e., file, class or function-scope
* static member) FramePropertyDescriptor and pass its address as * static member) FramePropertyDescriptor and pass its address as
* aProperty in the FramePropertyTable methods. * aProperty in the FrameProperties methods.
*/ */
template<typename T> template<typename T>
struct FramePropertyDescriptor : public FramePropertyDescriptorUntyped 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 * a given frame. Storing very large numbers of properties on a single
* frame will not be efficient. * frame will not be efficient.
* *
@ -141,7 +141,8 @@ struct FramePropertyTypeHelper<SmallValueHolder<T>>
* Of course, the destructor function (if any) must handle such values * Of course, the destructor function (if any) must handle such values
* correctly. * correctly.
*/ */
class FramePropertyTable { class FrameProperties
{
public: public:
template<typename T> template<typename T>
using Descriptor = const FramePropertyDescriptor<T>*; using Descriptor = const FramePropertyDescriptor<T>*;
@ -150,32 +151,36 @@ public:
template<typename T> template<typename T>
using PropertyType = typename detail::FramePropertyTypeHelper<T>::Type; 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 * Return true if we have no properties, otherwise return false.
* lookup (using the frame as the key) and a linear search through */
* the properties of that frame. Any existing value for the property 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. * is destroyed.
*/ */
template<typename T> template<typename T>
void Set(const nsIFrame* aFrame, Descriptor<T> aProperty, void Set(Descriptor<T> aProperty, PropertyType<T> aValue,
PropertyType<T> aValue) const nsIFrame* aFrame)
{ {
void* ptr = ReinterpretHelper<T>::ToPointer(aValue); 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 * @return true if @aProperty is set. This requires a linear search through the
* lookup (using the frame as the key) and a linear search through the * properties of the frame.
* properties of that frame.
* *
* In most cases, this shouldn't be used outside of assertions, because if * 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() * 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. * an existing value for the frame property.
*/ */
template<typename T> template<typename T>
bool Has(const nsIFrame* aFrame, Descriptor<T> aProperty) bool Has(Descriptor<T> aProperty) const
{ {
bool foundResult = false; return mProperties.IndexOf(aProperty, 0, PropertyComparator()) != nsTArray<PropertyValue>::NoIndex;
mozilla::Unused << GetInternal(aFrame, aProperty, &foundResult);
return foundResult;
} }
/** /**
* Get a property value for a frame. This requires one hashtable * Get a property value. This requires a linear search through
* lookup (using the frame as the key) and a linear search through * the properties of the frame. If the frame has no such property,
* the properties of that frame. If the frame has no such property,
* returns zero-filled result, which means null for pointers and * returns zero-filled result, which means null for pointers and
* zero for integers and floating point types. * zero for integers and floating point types.
* @param aFoundResult if non-null, receives a value 'true' iff * @param aFoundResult if non-null, receives a value 'true' iff
@ -209,16 +211,15 @@ public:
* 'property value is null'. * 'property value is null'.
*/ */
template<typename T> template<typename T>
PropertyType<T> Get(const nsIFrame* aFrame, Descriptor<T> aProperty, PropertyType<T> Get(Descriptor<T> aProperty,
bool* aFoundResult = nullptr) bool* aFoundResult = nullptr) const
{ {
void* ptr = GetInternal(aFrame, aProperty, aFoundResult); void* ptr = GetInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr); return ReinterpretHelper<T>::FromPointer(ptr);
} }
/** /**
* Remove a property value for a frame. This requires one hashtable * Remove a property value. This requires a linear search through
* lookup (using the frame as the key) and a linear search through * the properties of the frame. The old property value is returned
* the properties of that frame. The old property value is returned
* (and not destroyed). If the frame has no such property, * (and not destroyed). If the frame has no such property,
* returns zero-filled result, which means null for pointers and * returns zero-filled result, which means null for pointers and
* zero for integers and floating point types. * zero for integers and floating point types.
@ -228,46 +229,85 @@ public:
* 'property value is null'. * 'property value is null'.
*/ */
template<typename T> template<typename T>
PropertyType<T> Remove(const nsIFrame* aFrame, Descriptor<T> aProperty, PropertyType<T> Remove(Descriptor<T> aProperty,
bool* aFoundResult = nullptr) bool* aFoundResult = nullptr)
{ {
void* ptr = RemoveInternal(aFrame, aProperty, aFoundResult); void* ptr = RemoveInternal(aProperty, aFoundResult);
return ReinterpretHelper<T>::FromPointer(ptr); return ReinterpretHelper<T>::FromPointer(ptr);
} }
/** /**
* Remove and destroy a property value for a frame. This requires one * Remove and destroy a property value. This requires a linear search
* hashtable lookup (using the frame as the key) and a linear search * through the properties of the frame. If the frame has no such
* through the properties of that frame. If the frame has no such
* property, nothing happens. * property, nothing happens.
*/ */
template<typename T> 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 * Call @aFunction for each property or until @aFunction returns false.
* hashtable lookup (using the frame as the key).
*/ */
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: private:
void SetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty, friend class ::nsIFrame;
void* aValue);
void* GetInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty, // Prevent copying of FrameProperties; we should always return/pass around
bool* aFoundResult); // references to it, not copies!
FrameProperties(const FrameProperties&) = delete;
FrameProperties& operator=(const FrameProperties&) = delete;
void* RemoveInternal(const nsIFrame* aFrame, UntypedDescriptor aProperty, inline void
bool* aFoundResult); 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> template<typename T>
struct ReinterpretHelper struct ReinterpretHelper
@ -305,21 +345,13 @@ protected:
}; };
/** /**
* Stores a property descriptor/value pair. It can also be used to * Stores a property descriptor/value pair.
* store an nsTArray of PropertyValues.
*/ */
struct PropertyValue { struct PropertyValue {
PropertyValue() : mProperty(nullptr), mValue(nullptr) {} PropertyValue() : mProperty(nullptr), mValue(nullptr) {}
PropertyValue(UntypedDescriptor aProperty, void* aValue) PropertyValue(UntypedDescriptor aProperty, void* aValue)
: mProperty(aProperty), mValue(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) { void DestroyValueFor(const nsIFrame* aFrame) {
if (mProperty->mDestructor) { if (mProperty->mDestructor) {
mProperty->mDestructor(mValue); 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; UntypedDescriptor mProperty;
void* mValue; void* mValue;
}; };
@ -363,80 +381,86 @@ protected:
} }
}; };
/** nsTArray<PropertyValue> mProperties;
* 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;
}; };
/** /**
* This class encapsulates the properties of a frame. * This class encapsulates the properties of a frame.
*/ */
class FrameProperties { inline void*
public: FrameProperties::GetInternal(UntypedDescriptor aProperty,
template<typename T> using Descriptor = FramePropertyTable::Descriptor<T>; bool* aFoundResult) const
template<typename T> using PropertyType = FramePropertyTable::PropertyType<T>; {
MOZ_ASSERT(aProperty, "Null property?");
FrameProperties(FramePropertyTable* aTable, const nsIFrame* aFrame) auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
: mTable(aTable), mFrame(aFrame) {} if (index == nsTArray<PropertyValue>::NoIndex) {
if (aFoundResult) {
template<typename T> *aFoundResult = false;
void Set(Descriptor<T> aProperty, PropertyType<T> aValue) const }
{ return nullptr;
mTable->Set(mFrame, aProperty, aValue);
} }
template<typename T> if (aFoundResult) {
bool Has(Descriptor<T> aProperty) const *aFoundResult = true;
{
return mTable->Has(mFrame, aProperty);
} }
template<typename T> return mProperties.ElementAt(index).mValue;
PropertyType<T> Get(Descriptor<T> aProperty, }
bool* aFoundResult = nullptr) const
{ inline void
return mTable->Get(mFrame, aProperty, aFoundResult); FrameProperties::SetInternal(UntypedDescriptor aProperty, void* aValue,
} const nsIFrame* aFrame)
template<typename T> {
PropertyType<T> Remove(Descriptor<T> aProperty, MOZ_ASSERT(aProperty, "Null property?");
bool* aFoundResult = nullptr) const
{ auto index = mProperties.IndexOf(aProperty, 0, PropertyComparator());
return mTable->Remove(mFrame, aProperty, aFoundResult); if (index != nsTArray<PropertyValue>::NoIndex) {
} PropertyValue* pv = &mProperties.ElementAt(index);
template<typename T> pv->DestroyValueFor(aFrame);
void Delete(Descriptor<T> aProperty) pv->mValue = aValue;
{ return;
mTable->Delete(mFrame, aProperty);
} }
private: mProperties.AppendElement(PropertyValue(aProperty, aValue));
FramePropertyTable* mTable; }
const nsIFrame* mFrame;
}; 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;
}
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 } // namespace mozilla
#endif /* FRAMEPROPERTYTABLE_H_ */ #endif /* FRAMEPROPERTIES_H_ */

View File

@ -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

View File

@ -112,12 +112,12 @@ public:
// Take a faster path that doesn't require unioning the overflow areas // Take a faster path that doesn't require unioning the overflow areas
// of our children. // of our children.
NS_ASSERTION(frame->Properties().Get( NS_ASSERTION(frame->GetProperty(
nsIFrame::DebugInitialOverflowPropertyApplied()), nsIFrame::DebugInitialOverflowPropertyApplied()),
"InitialOverflowProperty must be set first."); "InitialOverflowProperty must be set first.");
nsOverflowAreas* overflow = nsOverflowAreas* overflow =
frame->Properties().Get(nsIFrame::InitialOverflowProperty()); frame->GetProperty(nsIFrame::InitialOverflowProperty());
if (overflow) { if (overflow) {
// FinishAndStoreOverflow will change the overflow areas passed in, // FinishAndStoreOverflow will change the overflow areas passed in,
// so make a copy. // so make a copy.

View File

@ -1122,10 +1122,10 @@ GetPrevContinuationWithPossiblySameStyle(nsIFrame* aFrame)
// We're the first continuation, so we can just get the frame // We're the first continuation, so we can just get the frame
// property directly // property directly
prevContinuation = prevContinuation =
aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling()); aFrame->GetProperty(nsIFrame::IBSplitPrevSibling());
if (prevContinuation) { if (prevContinuation) {
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. // oldContext)" check will prevent us from redoing work.
if ((aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) && if ((aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
!aFrame->GetPrevContinuation()) { !aFrame->GetPrevContinuation()) {
nsIFrame* sib = nsIFrame* sib = aFrame->GetProperty(nsIFrame::IBSplitSibling());
aFrame->Properties().Get(nsIFrame::IBSplitSibling());
if (sib) { if (sib) {
ReparentStyleContext(sib); ReparentStyleContext(sib);
} }
@ -3349,7 +3348,6 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
// line), we might restyle more than that. // line), we might restyle more than that.
nsPresContext* presContext = aFrame->PresContext(); nsPresContext* presContext = aFrame->PresContext();
FramePropertyTable* propTable = presContext->PropertyTable();
TreeMatchContext treeMatchContext(true, TreeMatchContext treeMatchContext(true,
nsRuleWalker::eRelevantLinkUnvisited, nsRuleWalker::eRelevantLinkUnvisited,
@ -3363,7 +3361,7 @@ ElementRestyler::ComputeStyleChangeFor(nsIFrame* aFrame,
nsTArray<nsIContent*> visibleKidsOfHiddenElement; nsTArray<nsIContent*> visibleKidsOfHiddenElement;
nsIFrame* nextIBSibling; nsIFrame* nextIBSibling;
for (nsIFrame* ibSibling = aFrame; ibSibling; ibSibling = nextIBSibling) { for (nsIFrame* ibSibling = aFrame; ibSibling; ibSibling = nextIBSibling) {
nextIBSibling = RestyleManager::GetNextBlockInInlineSibling(propTable, ibSibling); nextIBSibling = RestyleManager::GetNextBlockInInlineSibling(ibSibling);
if (nextIBSibling) { if (nextIBSibling) {
// Don't allow some ib-split siblings to be processed with // Don't allow some ib-split siblings to be processed with

View File

@ -385,8 +385,6 @@ RestyleManagerBase::DebugVerifyStyleTree(nsIFrame* aFrame)
#endif // DEBUG #endif // DEBUG
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ChangeListProperty, bool)
/** /**
* Sync views on aFrame and all of aFrame's descendants (following placeholders), * Sync views on aFrame and all of aFrame's descendants (following placeholders),
* if aChange has nsChangeHint_SyncFrameView. * if aChange has nsChangeHint_SyncFrameView.
@ -521,10 +519,9 @@ RecomputePosition(nsIFrame* aFrame)
// normal position, go ahead and add the offsets directly. // normal position, go ahead and add the offsets directly.
// First, we need to ensure that the normal position is stored though. // First, we need to ensure that the normal position is stored though.
nsPoint normalPosition = cont->GetNormalPosition(); nsPoint normalPosition = cont->GetNormalPosition();
auto props = cont->Properties(); if (!cont->GetProperty(nsIFrame::NormalPositionProperty())) {
const auto& prop = nsIFrame::NormalPositionProperty(); cont->SetProperty(nsIFrame::NormalPositionProperty(),
if (!props.Get(prop)) { new nsPoint(normalPosition));
props.Set(prop, new nsPoint(normalPosition));
} }
cont->SetPosition(normalPosition + cont->SetPosition(normalPosition +
nsPoint(newOffsets.left, newOffsets.top)); nsPoint(newOffsets.left, newOffsets.top));
@ -739,8 +736,7 @@ RestyleManagerBase::GetNearestAncestorFrame(nsIContent* aContent)
} }
/* static */ nsIFrame* /* static */ nsIFrame*
RestyleManagerBase::GetNextBlockInInlineSibling(FramePropertyTable* aPropTable, RestyleManagerBase::GetNextBlockInInlineSibling(nsIFrame* aFrame)
nsIFrame* aFrame)
{ {
NS_ASSERTION(!aFrame->GetPrevContinuation(), NS_ASSERTION(!aFrame->GetPrevContinuation(),
"must start with the first continuation"); "must start with the first continuation");
@ -750,8 +746,7 @@ RestyleManagerBase::GetNextBlockInInlineSibling(FramePropertyTable* aPropTable,
return nullptr; return nullptr;
} }
return static_cast<nsIFrame*> return aFrame->GetProperty(nsIFrame::IBSplitSibling());
(aPropTable->Get(aFrame, nsIFrame::IBSplitSibling()));
} }
static void static void
@ -1028,10 +1023,10 @@ RestyleManagerBase::GetNextContinuationWithSameStyle(
// We're the last continuation, so we have to hop back to the first // We're the last continuation, so we have to hop back to the first
// before getting the frame property // before getting the frame property
nextContinuation = nextContinuation =
aFrame->FirstContinuation()->Properties().Get(nsIFrame::IBSplitSibling()); aFrame->FirstContinuation()->GetProperty(nsIFrame::IBSplitSibling());
if (nextContinuation) { if (nextContinuation) {
nextContinuation = nextContinuation =
nextContinuation->Properties().Get(nsIFrame::IBSplitSibling()); nextContinuation->GetProperty(nsIFrame::IBSplitSibling());
} }
} }
@ -1060,14 +1055,52 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
{ {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot a script blocker"); "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", PROFILER_LABEL("RestyleManager", "ProcessRestyledFrames",
js::ProfileEntry::Category::CSS); js::ProfileEntry::Category::CSS);
nsPresContext* presContext = PresContext(); nsPresContext* presContext = PresContext();
FramePropertyTable* propTable = presContext->PropertyTable();
nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor(); nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor();
// Handle nsChangeHint_CSSOverflowChange, by either updating the // Handle nsChangeHint_CSSOverflowChange, by either updating the
@ -1135,15 +1168,6 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
// processing restyles // processing restyles
frameConstructor->BeginUpdate(); 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; bool didUpdateCursor = false;
for (const nsStyleChangeData& data : aChangeList) { for (const nsStyleChangeData& data : aChangeList) {
@ -1157,7 +1181,7 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
"Reflow hint bits set without actually asking for a reflow"); "Reflow hint bits set without actually asking for a reflow");
// skip any frame that has been destroyed due to a ripple effect // skip any frame that has been destroyed due to a ripple effect
if (frame && !propTable->Get(frame, ChangeListProperty())) { if (frame && mDestroyedFrames->Contains(frame)) {
continue; continue;
} }
@ -1409,15 +1433,11 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
frameConstructor->EndUpdate(); 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 #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... // reget frame from content since it may have been regenerated...
if (data.mContent) { if (data.mContent) {
nsIFrame* frame = data.mContent->GetPrimaryFrame(); nsIFrame* frame = data.mContent->GetPrimaryFrame();
@ -1429,8 +1449,8 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList)
NS_WARNING("Unable to test style tree integrity -- no content node " NS_WARNING("Unable to test style tree integrity -- no content node "
"(and not a viewport frame)"); "(and not a viewport frame)");
} }
#endif
} }
#endif
aChangeList.Clear(); aChangeList.Clear();
return NS_OK; return NS_OK;

View File

@ -72,6 +72,11 @@ public:
// WillDestroyFrameTree hasn't been called yet. // WillDestroyFrameTree hasn't been called yet.
void NotifyDestroyingFrame(nsIFrame* aFrame) { void NotifyDestroyingFrame(nsIFrame* aFrame) {
mOverflowChangedTracker.RemoveFrame(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 // 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(). nsPresContext* mPresContext; // weak, can be null after Disconnect().
uint32_t mRestyleGeneration; uint32_t mRestyleGeneration;
uint32_t mHoverGeneration; 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. // True if we're already waiting for a refresh notification.
bool mObservingRefreshDriver; bool mObservingRefreshDriver;
@ -146,7 +157,7 @@ protected:
GetNearestAncestorFrame(nsIContent* aContent); GetNearestAncestorFrame(nsIContent* aContent);
static nsIFrame* static nsIFrame*
GetNextBlockInInlineSibling(FramePropertyTable* aPropTable, nsIFrame* aFrame); GetNextBlockInInlineSibling(nsIFrame* aFrame);
/** /**
* Get the next continuation or similar ib-split sibling (assuming * Get the next continuation or similar ib-split sibling (assuming

View File

@ -61,7 +61,7 @@ EXPORTS += [
'DisplayItemScrollClip.h', 'DisplayItemScrollClip.h',
'DisplayListClipState.h', 'DisplayListClipState.h',
'FrameLayerBuilder.h', 'FrameLayerBuilder.h',
'FramePropertyTable.h', 'FrameProperties.h',
'LayerState.h', 'LayerState.h',
'LayoutLogging.h', 'LayoutLogging.h',
'nsArenaMemoryStats.h', 'nsArenaMemoryStats.h',
@ -126,7 +126,6 @@ UNIFIED_SOURCES += [
'DisplayListClipState.cpp', 'DisplayListClipState.cpp',
'DottedCornerFinder.cpp', 'DottedCornerFinder.cpp',
'FrameLayerBuilder.cpp', 'FrameLayerBuilder.cpp',
'FramePropertyTable.cpp',
'GeometryUtils.cpp', 'GeometryUtils.cpp',
'LayoutLogging.cpp', 'LayoutLogging.cpp',
'MaskLayerImageCache.cpp', 'MaskLayerImageCache.cpp',

View File

@ -753,7 +753,6 @@ nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd)
nsIContent* content = nullptr; nsIContent* content = nullptr;
int32_t contentTextLength = 0; int32_t contentTextLength = 0;
FramePropertyTable* propTable = aBpd->mPresContext->PropertyTable();
nsLineBox* currentLine = nullptr; nsLineBox* currentLine = nullptr;
#ifdef DEBUG #ifdef DEBUG
@ -809,7 +808,7 @@ nsBidiPresUtils::ResolveParagraph(BidiParagraphData* aBpd)
} }
precedingControl = kBidiLevelNone; precedingControl = kBidiLevelNone;
lastEmbedingLevel = embeddingLevel; lastEmbedingLevel = embeddingLevel;
propTable->Set(frame, nsIFrame::BidiDataProperty(), bidiData); frame->SetProperty(nsIFrame::BidiDataProperty(), bidiData);
}; };
for (; ;) { for (; ;) {
@ -1787,7 +1786,7 @@ nsBidiPresUtils::RemoveBidiContinuation(BidiParagraphData *aBpd,
if (frame != NS_BIDI_CONTROL_FRAME) { if (frame != NS_BIDI_CONTROL_FRAME) {
// Make the frame and its continuation ancestors fluid, // Make the frame and its continuation ancestors fluid,
// so they can be reused or deleted by normal reflow code // 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); frame->AddStateBits(NS_FRAME_IS_BIDI);
while (frame) { while (frame) {
nsIFrame* prev = frame->GetPrevContinuation(); nsIFrame* prev = frame->GetPrevContinuation();

View File

@ -492,9 +492,8 @@ static nsContainerFrame* GetIBSplitSibling(nsIFrame* aFrame)
// We only store the "ib-split sibling" annotation with the first // We only store the "ib-split sibling" annotation with the first
// frame in the continuation chain. Walk back to find that frame now. // frame in the continuation chain. Walk back to find that frame now.
return static_cast<nsContainerFrame*> return aFrame->FirstContinuation()->
(aFrame->FirstContinuation()-> GetProperty(nsIFrame::IBSplitSibling());
Properties().Get(nsIFrame::IBSplitSibling()));
} }
static nsContainerFrame* GetIBSplitPrevSibling(nsIFrame* aFrame) 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 // We only store the ib-split sibling annotation with the first
// frame in the continuation chain. Walk back to find that frame now. // frame in the continuation chain. Walk back to find that frame now.
return static_cast<nsContainerFrame*> return aFrame->FirstContinuation()->
(aFrame->FirstContinuation()-> GetProperty(nsIFrame::IBSplitPrevSibling());
Properties().Get(nsIFrame::IBSplitPrevSibling()));
} }
static nsContainerFrame* static nsContainerFrame*
@ -526,7 +524,7 @@ GetLastIBSplitSibling(nsIFrame* aFrame, bool aReturnEmptyTrailingInline)
} }
static void static void
SetFrameIsIBSplit(nsContainerFrame* aFrame, nsIFrame* aIBSplitSibling) SetFrameIsIBSplit(nsContainerFrame* aFrame, nsContainerFrame* aIBSplitSibling)
{ {
NS_PRECONDITION(aFrame, "bad args!"); 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 // Store the ib-split sibling (if we were given one) with the
// first frame in the flow. // first frame in the flow.
FramePropertyTable* props = aFrame->PresContext()->PropertyTable(); aFrame->SetProperty(nsIFrame::IBSplitSibling(), aIBSplitSibling);
props->Set(aFrame, nsIFrame::IBSplitSibling(), aIBSplitSibling); aIBSplitSibling->SetProperty(nsIFrame::IBSplitPrevSibling(), aFrame);
props->Set(aIBSplitSibling, nsIFrame::IBSplitPrevSibling(), aFrame);
} }
} }
@ -6075,11 +6072,11 @@ AddGenConPseudoToFrame(nsIFrame* aOwnerFrame, nsIContent* aContent)
NS_ASSERTION(nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aOwnerFrame), NS_ASSERTION(nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(aOwnerFrame),
"property should only be set on first continuation/ib-sibling"); "property should only be set on first continuation/ib-sibling");
FrameProperties props = aOwnerFrame->Properties(); nsIFrame::ContentArray* value =
nsIFrame::ContentArray* value = props.Get(nsIFrame::GenConProperty()); aOwnerFrame->GetProperty(nsIFrame::GenConProperty());
if (!value) { if (!value) {
value = new nsIFrame::ContentArray; value = new nsIFrame::ContentArray;
props.Set(nsIFrame::GenConProperty(), value); aOwnerFrame->SetProperty(nsIFrame::GenConProperty(), value);
} }
value->AppendElement(aContent); value->AppendElement(aContent);
} }

View File

@ -293,13 +293,13 @@ protected:
if (!prevCont && if (!prevCont &&
(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) { (aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
nsIFrame* block = nsIFrame* block =
aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling()); aFrame->GetProperty(nsIFrame::IBSplitPrevSibling());
if (block) { if (block) {
// The {ib} properties are only stored on first continuations // The {ib} properties are only stored on first continuations
NS_ASSERTION(!block->GetPrevContinuation(), NS_ASSERTION(!block->GetPrevContinuation(),
"Incorrect value for IBSplitPrevSibling"); "Incorrect value for IBSplitPrevSibling");
prevCont = prevCont =
block->Properties().Get(nsIFrame::IBSplitPrevSibling()); block->GetProperty(nsIFrame::IBSplitPrevSibling());
NS_ASSERTION(prevCont, "How did that happen?"); NS_ASSERTION(prevCont, "How did that happen?");
} }
} }
@ -313,9 +313,9 @@ protected:
(aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) { (aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT)) {
// The {ib} properties are only stored on first continuations // The {ib} properties are only stored on first continuations
aFrame = aFrame->FirstContinuation(); aFrame = aFrame->FirstContinuation();
nsIFrame* block = aFrame->Properties().Get(nsIFrame::IBSplitSibling()); nsIFrame* block = aFrame->GetProperty(nsIFrame::IBSplitSibling());
if (block) { if (block) {
nextCont = block->Properties().Get(nsIFrame::IBSplitSibling()); nextCont = block->GetProperty(nsIFrame::IBSplitSibling());
NS_ASSERTION(nextCont, "How did that happen?"); NS_ASSERTION(nextCont, "How did that happen?");
} }
} }
@ -842,7 +842,7 @@ static nsRect
GetOutlineInnerRect(nsIFrame* aFrame) GetOutlineInnerRect(nsIFrame* aFrame)
{ {
nsRect* savedOutlineInnerRect = nsRect* savedOutlineInnerRect =
aFrame->Properties().Get(nsIFrame::OutlineInnerRectProperty()); aFrame->GetProperty(nsIFrame::OutlineInnerRectProperty());
if (savedOutlineInnerRect) if (savedOutlineInnerRect)
return *savedOutlineInnerRect; return *savedOutlineInnerRect;
NS_NOTREACHED("we should have saved a frame property"); NS_NOTREACHED("we should have saved a frame property");

View File

@ -666,7 +666,7 @@ nsDisplayListBuilder::AddAnimationsAndTransitionsToLayer(Layer* aLayer,
// EffectCompositor needs to know that we refused to run this animation // EffectCompositor needs to know that we refused to run this animation
// asynchronously so that it will not throttle the main thread // asynchronously so that it will not throttle the main thread
// animation. // animation.
aFrame->Properties().Set(nsIFrame::RefusedAsyncAnimationProperty(), true); aFrame->SetProperty(nsIFrame::RefusedAsyncAnimationProperty(), true);
// We need to schedule another refresh driver run so that EffectCompositor // We need to schedule another refresh driver run so that EffectCompositor
// gets a chance to unthrottle the animation. // gets a chance to unthrottle the animation.
@ -902,15 +902,13 @@ void nsDisplayListBuilder::MarkOutOfFlowFrameForDisplay(nsIFrame* aDirtyFrame,
const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants(); const DisplayItemClip* oldClip = mClipState.GetClipForContainingBlockDescendants();
const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip(); const DisplayItemScrollClip* sc = mClipState.GetCurrentInnermostScrollClip();
OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty); OutOfFlowDisplayData* data = new OutOfFlowDisplayData(oldClip, sc, dirty);
aFrame->Properties().Set(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data); aFrame->SetProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty(), data);
MarkFrameForDisplay(aFrame, aDirtyFrame); MarkFrameForDisplay(aFrame, aDirtyFrame);
} }
static void UnmarkFrameForDisplay(nsIFrame* aFrame) { static void UnmarkFrameForDisplay(nsIFrame* aFrame) {
nsPresContext* presContext = aFrame->PresContext(); aFrame->DeleteProperty(nsDisplayListBuilder::OutOfFlowDisplayDataProperty());
presContext->PropertyTable()->
Delete(aFrame, nsDisplayListBuilder::OutOfFlowDisplayDataProperty());
for (nsIFrame* f = aFrame; f; for (nsIFrame* f = aFrame; f;
f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) { f = nsLayoutUtils::GetParentOrPlaceholderFor(f)) {

View File

@ -1003,7 +1003,7 @@ public:
static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame) static OutOfFlowDisplayData* GetOutOfFlowData(nsIFrame* aFrame)
{ {
return aFrame->Properties().Get(OutOfFlowDisplayDataProperty()); return aFrame->GetProperty(OutOfFlowDisplayDataProperty());
} }
nsPresContext* CurrentPresContext() { nsPresContext* CurrentPresContext() {

View File

@ -1533,11 +1533,12 @@ public:
bool aFlushOnHoverChange) = 0; bool aFlushOnHoverChange) = 0;
virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, virtual void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
nsArenaMemoryStats *aArenaObjectsSize, nsArenaMemoryStats* aArenaObjectsSize,
size_t *aPresShellSize, size_t* aPresShellSize,
size_t *aStyleSetsSize, size_t* aStyleSetsSize,
size_t *aTextRunsSize, size_t* aTextRunsSize,
size_t *aPresContextSize) = 0; size_t* aPresContextSize,
size_t* aFramePropertiesSize) = 0;
/** /**
* Methods that retrieve the cached font inflation preferences. * Methods that retrieve the cached font inflation preferences.

View File

@ -2057,13 +2057,13 @@ NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ScrollbarThumbLayerized, bool)
/* static */ void /* static */ void
nsLayoutUtils::SetScrollbarThumbLayerization(nsIFrame* aThumbFrame, bool aLayerize) nsLayoutUtils::SetScrollbarThumbLayerization(nsIFrame* aThumbFrame, bool aLayerize)
{ {
aThumbFrame->Properties().Set(ScrollbarThumbLayerized(), aLayerize); aThumbFrame->SetProperty(ScrollbarThumbLayerized(), aLayerize);
} }
bool bool
nsLayoutUtils::IsScrollbarThumbLayerized(nsIFrame* aThumbFrame) nsLayoutUtils::IsScrollbarThumbLayerized(nsIFrame* aThumbFrame)
{ {
return aThumbFrame->Properties().Get(ScrollbarThumbLayerized()); return aThumbFrame->GetProperty(ScrollbarThumbLayerized());
} }
// static // static
@ -4427,7 +4427,7 @@ nsLayoutUtils::GetNextContinuationOrIBSplitSibling(nsIFrame *aFrame)
// frame in the continuation chain. Walk back to find that frame now. // frame in the continuation chain. Walk back to find that frame now.
aFrame = aFrame->FirstContinuation(); aFrame = aFrame->FirstContinuation();
return aFrame->Properties().Get(nsIFrame::IBSplitSibling()); return aFrame->GetProperty(nsIFrame::IBSplitSibling());
} }
return nullptr; return nullptr;
@ -4440,7 +4440,7 @@ nsLayoutUtils::FirstContinuationOrIBSplitSibling(nsIFrame *aFrame)
if (result->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) { if (result->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) {
while (true) { while (true) {
nsIFrame* f = nsIFrame* f =
result->Properties().Get(nsIFrame::IBSplitPrevSibling()); result->GetProperty(nsIFrame::IBSplitPrevSibling());
if (!f) if (!f)
break; break;
result = f; result = f;
@ -4456,10 +4456,10 @@ nsLayoutUtils::LastContinuationOrIBSplitSibling(nsIFrame *aFrame)
nsIFrame *result = aFrame->FirstContinuation(); nsIFrame *result = aFrame->FirstContinuation();
if (result->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) { if (result->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) {
while (true) { while (true) {
nsIFrame* f = nsIFrame* f = result->GetProperty(nsIFrame::IBSplitSibling());
result->Properties().Get(nsIFrame::IBSplitSibling()); if (!f) {
if (!f)
break; break;
}
result = f; result = f;
} }
} }
@ -4476,7 +4476,7 @@ nsLayoutUtils::IsFirstContinuationOrIBSplitSibling(nsIFrame *aFrame)
return false; return false;
} }
if ((aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) && if ((aFrame->GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling())) { aFrame->GetProperty(nsIFrame::IBSplitPrevSibling())) {
return false; return false;
} }

View File

@ -2741,8 +2741,7 @@ nsPresContext::GetPrimaryFrameFor(nsIContent* aContent)
size_t size_t
nsPresContext::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const nsPresContext::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const
{ {
return mPropertyTable.SizeOfExcludingThis(aMallocSizeOf) + return mLangGroupFontPrefs.SizeOfExcludingThis(aMallocSizeOf);
mLangGroupFontPrefs.SizeOfExcludingThis(aMallocSizeOf);
// Measurement of other members may be added later if DMD finds it is // Measurement of other members may be added later if DMD finds it is
// worthwhile. // worthwhile.

View File

@ -22,7 +22,6 @@
#include "nsITimer.h" #include "nsITimer.h"
#include "nsCRT.h" #include "nsCRT.h"
#include "nsIWidgetListener.h" #include "nsIWidgetListener.h"
#include "FramePropertyTable.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsChangeHint.h" #include "nsChangeHint.h"
@ -140,7 +139,6 @@ class nsRootPresContext;
class nsPresContext : public nsIObserver, class nsPresContext : public nsIObserver,
public mozilla::SupportsWeakPtr<nsPresContext> { public mozilla::SupportsWeakPtr<nsPresContext> {
public: public:
typedef mozilla::FramePropertyTable FramePropertyTable;
typedef mozilla::LangGroupFontPrefs LangGroupFontPrefs; typedef mozilla::LangGroupFontPrefs LangGroupFontPrefs;
typedef mozilla::ScrollbarStyles ScrollbarStyles; typedef mozilla::ScrollbarStyles ScrollbarStyles;
typedef mozilla::StaticPresData StaticPresData; typedef mozilla::StaticPresData StaticPresData;
@ -867,9 +865,6 @@ public:
nsIPrintSettings* GetPrintSettings() { return mPrintSettings; } 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 /* Helper function that ensures that this prescontext is shown in its
docshell if it's the most recent prescontext for the docshell. Returns docshell if it's the most recent prescontext for the docshell. Returns
whether the prescontext is now being shown. whether the prescontext is now being shown.
@ -1064,11 +1059,6 @@ public:
*/ */
nsIFrame* GetPrimaryFrameFor(nsIContent* aContent); nsIFrame* GetPrimaryFrameFor(nsIContent* aContent);
void NotifyDestroyingFrame(nsIFrame* aFrame)
{
PropertyTable()->DeleteAllFor(aFrame);
}
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const {
return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf); return aMallocSizeOf(this) + SizeOfExcludingThis(aMallocSizeOf);
@ -1294,7 +1284,6 @@ protected:
nsCOMPtr<nsIPrintSettings> mPrintSettings; nsCOMPtr<nsIPrintSettings> mPrintSettings;
nsCOMPtr<nsITimer> mPrefChangedTimer; nsCOMPtr<nsITimer> mPrefChangedTimer;
FramePropertyTable mPropertyTable;
nsInvalidateRequestList mInvalidateRequestsSinceLastPaint; nsInvalidateRequestList mInvalidateRequestsSinceLastPaint;
nsInvalidateRequestList mUndeliveredInvalidateRequestsBeforeLastPaint; nsInvalidateRequestList mUndeliveredInvalidateRequestsBeforeLastPaint;

View File

@ -1306,19 +1306,6 @@ PresShell::Destroy()
// Destroy the frame manager. This will destroy the frame hierarchy // Destroy the frame manager. This will destroy the frame hierarchy
mFrameConstructor->WillDestroyFrameTree(); 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, NS_WARNING_ASSERTION(!mWeakFrames,
"Weak frames alive after destroying FrameManager"); "Weak frames alive after destroying FrameManager");
while (mWeakFrames) { while (mWeakFrames) {
@ -2047,7 +2034,7 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
} }
// Remove frame properties // Remove frame properties
mPresContext->NotifyDestroyingFrame(aFrame); aFrame->DeleteAllProperties();
if (aFrame == mCurrentEventFrame) { if (aFrame == mCurrentEventFrame) {
mCurrentEventContent = aFrame->GetContent(); mCurrentEventContent = aFrame->GetContent();
@ -2076,8 +2063,7 @@ PresShell::NotifyDestroyingFrame(nsIFrame* aFrame)
// frame from FrameLayerBuilder::DisplayItemData::mFrameList -- otherwise // frame from FrameLayerBuilder::DisplayItemData::mFrameList -- otherwise
// the DisplayItemData destructor will use the destroyed frame when it // the DisplayItemData destructor will use the destroyed frame when it
// tries to remove it from the (array) value of this property. // tries to remove it from the (array) value of this property.
mPresContext->PropertyTable()-> aFrame->DeleteProperty( FrameLayerBuilder::LayerManagerDataProperty());
Delete(aFrame, FrameLayerBuilder::LayerManagerDataProperty());
} }
} }
@ -10929,11 +10915,12 @@ PresShell::GetRootPresShell()
void void
PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
nsArenaMemoryStats *aArenaObjectsSize, nsArenaMemoryStats* aArenaObjectsSize,
size_t *aPresShellSize, size_t* aPresShellSize,
size_t *aStyleSetsSize, size_t* aStyleSetsSize,
size_t *aTextRunsSize, size_t* aTextRunsSize,
size_t *aPresContextSize) size_t* aPresContextSize,
size_t* aFramePropertiesSize)
{ {
mFrameArena.AddSizeOfExcludingThis(aMallocSizeOf, aArenaObjectsSize); mFrameArena.AddSizeOfExcludingThis(aMallocSizeOf, aArenaObjectsSize);
*aPresShellSize += aMallocSizeOf(this); *aPresShellSize += aMallocSizeOf(this);
@ -10953,6 +10940,12 @@ PresShell::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf,
*aTextRunsSize += SizeOfTextRuns(aMallocSizeOf); *aTextRunsSize += SizeOfTextRuns(aMallocSizeOf);
*aPresContextSize += mPresContext->SizeOfIncludingThis(aMallocSizeOf); *aPresContextSize += mPresContext->SizeOfIncludingThis(aMallocSizeOf);
nsIFrame* rootFrame = mFrameConstructor->GetRootFrame();
if (rootFrame) {
*aFramePropertiesSize +=
rootFrame->SizeOfFramePropertiesForTree(aMallocSizeOf);
}
} }
size_t size_t

View File

@ -384,11 +384,12 @@ public:
virtual void LoadComplete() override; virtual void LoadComplete() override;
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf, void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
nsArenaMemoryStats *aArenaObjectsSize, nsArenaMemoryStats* aArenaObjectsSize,
size_t *aPresShellSize, size_t* aPresShellSize,
size_t *aStyleSetsSize, size_t* aStyleSetsSize,
size_t *aTextRunsSize, size_t* aTextRunsSize,
size_t *aPresContextSize) override; size_t* aPresContextSize,
size_t* aFramePropertiesSize) override;
size_t SizeOfTextRuns(mozilla::MallocSizeOf aMallocSizeOf) const; size_t SizeOfTextRuns(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual void AddInvalidateHiddenPresShellObserver(nsRefreshDriver *aDriver) override; virtual void AddInvalidateHiddenPresShellObserver(nsRefreshDriver *aDriver) override;

View File

@ -124,10 +124,10 @@ nsTextControlFrame::DestroyFrom(nsIFrame* aDestructRoot)
{ {
mScrollEvent.Revoke(); mScrollEvent.Revoke();
EditorInitializer* initializer = Properties().Get(TextControlInitializer()); EditorInitializer* initializer = GetProperty(TextControlInitializer());
if (initializer) { if (initializer) {
initializer->Revoke(); initializer->Revoke();
Properties().Delete(TextControlInitializer()); DeleteProperty(TextControlInitializer());
} }
// Unbind the text editor state object from the frame. The editor will live // Unbind the text editor state object from the frame. The editor will live
@ -410,12 +410,12 @@ nsTextControlFrame::CreateAnonymousContent(nsTArray<ContentInfo>& aElements)
if (initEagerly) { if (initEagerly) {
NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(), NS_ASSERTION(!nsContentUtils::IsSafeToRunScript(),
"Someone forgot a script blocker?"); "Someone forgot a script blocker?");
EditorInitializer* initializer = Properties().Get(TextControlInitializer()); EditorInitializer* initializer = GetProperty(TextControlInitializer());
if (initializer) { if (initializer) {
initializer->Revoke(); initializer->Revoke();
} }
initializer = new EditorInitializer(this); initializer = new EditorInitializer(this);
Properties().Set(TextControlInitializer(),initializer); SetProperty(TextControlInitializer(),initializer);
nsContentUtils::AddScriptRunner(initializer); nsContentUtils::AddScriptRunner(initializer);
} }
@ -1262,7 +1262,7 @@ nsTextControlFrame::SetInitialChildList(ChildListID aListID,
NS_ASSERTION(txtCtrl, "Content not a text control element"); NS_ASSERTION(txtCtrl, "Content not a text control element");
txtCtrl->InitializeKeyboardEventListeners(); txtCtrl->InitializeKeyboardEventListeners();
nsPoint* contentScrollPos = Properties().Get(ContentScrollPos()); nsPoint* contentScrollPos = GetProperty(ContentScrollPos());
if (contentScrollPos) { if (contentScrollPos) {
// If we have a scroll pos stored to be passed to our anonymous // If we have a scroll pos stored to be passed to our anonymous
// div, do it here! // div, do it here!
@ -1271,7 +1271,7 @@ nsTextControlFrame::SetInitialChildList(ChildListID aListID,
nsPresState fakePresState; nsPresState fakePresState;
fakePresState.SetScrollState(*contentScrollPos); fakePresState.SetScrollState(*contentScrollPos);
statefulFrame->RestoreState(&fakePresState); statefulFrame->RestoreState(&fakePresState);
Properties().Remove(ContentScrollPos()); RemoveProperty(ContentScrollPos());
delete contentScrollPos; delete contentScrollPos;
} }
} }
@ -1421,7 +1421,7 @@ nsTextControlFrame::RestoreState(nsPresState* aState)
// Most likely, we don't have our anonymous content constructed yet, which // 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 // 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. // 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; return NS_OK;
} }

View File

@ -327,7 +327,7 @@ private:
nsresult GetRootNodeAndInitializeEditor(nsIDOMElement **aRootElement); nsresult GetRootNodeAndInitializeEditor(nsIDOMElement **aRootElement);
void FinishedInitializer() { void FinishedInitializer() {
Properties().Delete(TextControlInitializer()); DeleteProperty(TextControlInitializer());
} }
private: private:

View File

@ -999,13 +999,13 @@ ReflowInput::ComputeRelativeOffsets(WritingMode aWM,
// Convert the offsets to physical coordinates and store them on the frame // Convert the offsets to physical coordinates and store them on the frame
aComputedOffsets = offsets.GetPhysicalMargin(aWM); aComputedOffsets = offsets.GetPhysicalMargin(aWM);
FrameProperties props = aFrame->Properties(); nsMargin* physicalOffsets =
nsMargin* physicalOffsets = props.Get(nsIFrame::ComputedOffsetProperty()); aFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
if (physicalOffsets) { if (physicalOffsets) {
*physicalOffsets = aComputedOffsets; *physicalOffsets = aComputedOffsets;
} else { } else {
props.Set(nsIFrame::ComputedOffsetProperty(), aFrame->SetProperty(nsIFrame::ComputedOffsetProperty(),
new nsMargin(aComputedOffsets)); new nsMargin(aComputedOffsets));
} }
} }
@ -1015,21 +1015,22 @@ ReflowInput::ApplyRelativePositioning(nsIFrame* aFrame,
nsPoint* aPosition) nsPoint* aPosition)
{ {
if (!aFrame->IsRelativelyPositioned()) { if (!aFrame->IsRelativelyPositioned()) {
NS_ASSERTION(!aFrame->Properties().Get(nsIFrame::NormalPositionProperty()), NS_ASSERTION(!aFrame->GetProperty(nsIFrame::NormalPositionProperty()),
"We assume that changing the 'position' property causes " "We assume that changing the 'position' property causes "
"frame reconstruction. If that ever changes, this code " "frame reconstruction. If that ever changes, this code "
"should call " "should call "
"props.Delete(nsIFrame::NormalPositionProperty())"); "aFrame->DeleteProperty(nsIFrame::NormalPositionProperty())");
return; return;
} }
// Store the normal position // Store the normal position
FrameProperties props = aFrame->Properties(); nsPoint* normalPosition =
nsPoint* normalPosition = props.Get(nsIFrame::NormalPositionProperty()); aFrame->GetProperty(nsIFrame::NormalPositionProperty());
if (normalPosition) { if (normalPosition) {
*normalPosition = *aPosition; *normalPosition = *aPosition;
} else { } else {
props.Set(nsIFrame::NormalPositionProperty(), new nsPoint(*aPosition)); aFrame->SetProperty(nsIFrame::NormalPositionProperty(),
new nsPoint(*aPosition));
} }
const nsStyleDisplay* display = aFrame->StyleDisplay(); const nsStyleDisplay* display = aFrame->StyleDisplay();
@ -2452,20 +2453,20 @@ ReflowInput::InitConstraints(nsPresContext* aPresContext,
} }
static void static void
UpdateProp(FrameProperties& aProps, UpdateProp(nsIFrame* aFrame,
const FramePropertyDescriptor<nsMargin>* aProperty, const FramePropertyDescriptor<nsMargin>* aProperty,
bool aNeeded, bool aNeeded,
nsMargin& aNewValue) nsMargin& aNewValue)
{ {
if (aNeeded) { if (aNeeded) {
nsMargin* propValue = aProps.Get(aProperty); nsMargin* propValue = aFrame->GetProperty(aProperty);
if (propValue) { if (propValue) {
*propValue = aNewValue; *propValue = aNewValue;
} else { } else {
aProps.Set(aProperty, new nsMargin(aNewValue)); aFrame->SetProperty(aProperty, new nsMargin(aNewValue));
} }
} else { } 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 // 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. // unless they are dependent on width, in which case we store the new value.
nsPresContext *presContext = mFrame->PresContext(); nsPresContext *presContext = mFrame->PresContext();
FrameProperties props(presContext->PropertyTable(), mFrame); mFrame->DeleteProperty(nsIFrame::UsedBorderProperty());
props.Delete(nsIFrame::UsedBorderProperty());
// Compute margins from the specified margin style information. These // Compute margins from the specified margin style information. These
// become the default computed values, and may be adjusted below // 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 // ... but if we did that, we'd need to fix nsFrame::GetUsedMargin
// to use it even when the margins are all zero (since sometimes // to use it even when the margins are all zero (since sometimes
// they get treated as auto) // they get treated as auto)
::UpdateProp(props, nsIFrame::UsedMarginProperty(), needMarginProp, ::UpdateProp(mFrame, nsIFrame::UsedMarginProperty(), needMarginProp,
ComputedPhysicalMargin()); ComputedPhysicalMargin());
@ -2530,7 +2530,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM,
auto ApplyBaselinePadding = [this, &needPaddingProp] auto ApplyBaselinePadding = [this, &needPaddingProp]
(LogicalAxis aAxis, Prop aProp) { (LogicalAxis aAxis, Prop aProp) {
bool found; bool found;
nscoord val = mFrame->Properties().Get(aProp, &found); nscoord val = mFrame->GetProperty(aProp, &found);
if (found) { if (found) {
NS_ASSERTION(val != nscoord(0), "zero in this property is useless"); NS_ASSERTION(val != nscoord(0), "zero in this property is useless");
WritingMode wm = GetWritingMode(); WritingMode wm = GetWritingMode();
@ -2603,7 +2603,7 @@ SizeComputationInput::InitOffsets(WritingMode aWM,
ComputedPhysicalBorderPadding().SizeTo(0,0,0,0); ComputedPhysicalBorderPadding().SizeTo(0,0,0,0);
} }
} }
::UpdateProp(props, nsIFrame::UsedPaddingProperty(), needPaddingProp, ::UpdateProp(mFrame, nsIFrame::UsedPaddingProperty(), needPaddingProp,
ComputedPhysicalPadding()); ComputedPhysicalPadding());
} }

View File

@ -19,21 +19,21 @@ NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(ReservedISize, nscoord)
RubyUtils::SetReservedISize(nsIFrame* aFrame, nscoord aISize) RubyUtils::SetReservedISize(nsIFrame* aFrame, nscoord aISize)
{ {
MOZ_ASSERT(IsExpandableRubyBox(aFrame)); MOZ_ASSERT(IsExpandableRubyBox(aFrame));
aFrame->Properties().Set(ReservedISize(), aISize); aFrame->SetProperty(ReservedISize(), aISize);
} }
/* static */ void /* static */ void
RubyUtils::ClearReservedISize(nsIFrame* aFrame) RubyUtils::ClearReservedISize(nsIFrame* aFrame)
{ {
MOZ_ASSERT(IsExpandableRubyBox(aFrame)); MOZ_ASSERT(IsExpandableRubyBox(aFrame));
aFrame->Properties().Remove(ReservedISize()); aFrame->RemoveProperty(ReservedISize());
} }
/* static */ nscoord /* static */ nscoord
RubyUtils::GetReservedISize(nsIFrame* aFrame) RubyUtils::GetReservedISize(nsIFrame* aFrame)
{ {
MOZ_ASSERT(IsExpandableRubyBox(aFrame)); MOZ_ASSERT(IsExpandableRubyBox(aFrame));
return aFrame->Properties().Get(ReservedISize()); return aFrame->GetProperty(ReservedISize());
} }
AutoRubyTextContainerArray::AutoRubyTextContainerArray( AutoRubyTextContainerArray::AutoRubyTextContainerArray(

View File

@ -45,12 +45,12 @@ StickyScrollContainer::GetStickyScrollContainerForFrame(nsIFrame* aFrame)
// <html style="position: fixed"> // <html style="position: fixed">
return nullptr; return nullptr;
} }
FrameProperties props = static_cast<nsIFrame*>(do_QueryFrame(scrollFrame))-> auto frame = static_cast<nsIFrame*>(do_QueryFrame(scrollFrame));
Properties(); StickyScrollContainer* s =
StickyScrollContainer* s = props.Get(StickyScrollContainerProperty()); frame->GetProperty(StickyScrollContainerProperty());
if (!s) { if (!s) {
s = new StickyScrollContainer(scrollFrame); s = new StickyScrollContainer(scrollFrame);
props.Set(StickyScrollContainerProperty(), s); frame->SetProperty(StickyScrollContainerProperty(), s);
} }
return s; return s;
} }
@ -69,9 +69,9 @@ StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary(nsIFrame*
// we aren't going to handle that. // we aren't going to handle that.
return; return;
} }
FrameProperties props = static_cast<nsIFrame*>(do_QueryFrame(oldScrollFrame))-> StickyScrollContainer* oldSSC =
Properties(); static_cast<nsIFrame*>(do_QueryFrame(oldScrollFrame))->
StickyScrollContainer* oldSSC = props.Get(StickyScrollContainerProperty()); GetProperty(StickyScrollContainerProperty());
if (!oldSSC) { if (!oldSSC) {
// aOldParent had no sticky descendants, so aFrame doesn't have any sticky // aOldParent had no sticky descendants, so aFrame doesn't have any sticky
// descendants, and we're done here. // descendants, and we're done here.
@ -95,8 +95,7 @@ StickyScrollContainer::NotifyReparentedFrameAcrossScrollFrameBoundary(nsIFrame*
StickyScrollContainer* StickyScrollContainer*
StickyScrollContainer::GetStickyScrollContainerForScrollFrame(nsIFrame* aFrame) StickyScrollContainer::GetStickyScrollContainerForScrollFrame(nsIFrame* aFrame)
{ {
FrameProperties props = aFrame->Properties(); return aFrame->GetProperty(StickyScrollContainerProperty());
return props.Get(StickyScrollContainerProperty());
} }
static nscoord static nscoord
@ -141,13 +140,12 @@ StickyScrollContainer::ComputeStickyOffsets(nsIFrame* aFrame)
scrollContainerSize.height); scrollContainerSize.height);
// Store the offset // Store the offset
FrameProperties props = aFrame->Properties(); nsMargin* offsets = aFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
nsMargin* offsets = props.Get(nsIFrame::ComputedOffsetProperty());
if (offsets) { if (offsets) {
*offsets = computedOffsets; *offsets = computedOffsets;
} else { } else {
props.Set(nsIFrame::ComputedOffsetProperty(), aFrame->SetProperty(nsIFrame::ComputedOffsetProperty(),
new nsMargin(computedOffsets)); 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); aContain->SetRect(nscoord_MIN/2, nscoord_MIN/2, nscoord_MAX, nscoord_MAX);
const nsMargin* computedOffsets = const nsMargin* computedOffsets =
aFrame->Properties().Get(nsIFrame::ComputedOffsetProperty()); aFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
if (!computedOffsets) { if (!computedOffsets) {
// We haven't reflowed the scroll frame yet, so offsets haven't been // We haven't reflowed the scroll frame yet, so offsets haven't been
// computed. Bail. // computed. Bail.

View File

@ -326,10 +326,8 @@ nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
nsLineBox::DeleteLineList(presContext, mLines, aDestructRoot, nsLineBox::DeleteLineList(presContext, mLines, aDestructRoot,
&mFrames); &mFrames);
FramePropertyTable* props = presContext->PropertyTable();
if (HasPushedFloats()) { if (HasPushedFloats()) {
SafelyDestroyFrameListProp(aDestructRoot, shell, props, SafelyDestroyFrameListProp(aDestructRoot, shell,
PushedFloatProperty()); PushedFloatProperty());
RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS); RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
} }
@ -343,13 +341,13 @@ nsBlockFrame::DestroyFrom(nsIFrame* aDestructRoot)
} }
if (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) { if (GetStateBits() & NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS) {
SafelyDestroyFrameListProp(aDestructRoot, shell, props, SafelyDestroyFrameListProp(aDestructRoot, shell,
OverflowOutOfFlowsProperty()); OverflowOutOfFlowsProperty());
RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS); RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS);
} }
if (HasOutsideBullet()) { if (HasOutsideBullet()) {
SafelyDestroyFrameListProp(aDestructRoot, shell, props, SafelyDestroyFrameListProp(aDestructRoot, shell,
OutsideBulletProperty()); OutsideBulletProperty());
RemoveStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET); 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 // 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). // ensures we fill the last row when a multi-row grid item is fragmented).
bool found; bool found;
nscoord bSize = Properties().Get(FragStretchBSizeProperty(), &found); nscoord bSize = GetProperty(FragStretchBSizeProperty(), &found);
if (found) { if (found) {
finalSize.BSize(wm) = std::max(bSize, finalSize.BSize(wm)); finalSize.BSize(wm) = std::max(bSize, finalSize.BSize(wm));
} }
@ -1679,7 +1677,7 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
if (MOZ_UNLIKELY(aReflowInput.mFlags.mBClampMarginBoxMinSize) && if (MOZ_UNLIKELY(aReflowInput.mFlags.mBClampMarginBoxMinSize) &&
NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) { NS_FRAME_IS_COMPLETE(aState.mReflowStatus)) {
bool found; bool found;
nscoord cbSize = Properties().Get(BClampMarginBoxMinSizeProperty(), &found); nscoord cbSize = GetProperty(BClampMarginBoxMinSizeProperty(), &found);
if (found) { if (found) {
auto marginBoxBSize = finalSize.BSize(wm) + auto marginBoxBSize = finalSize.BSize(wm) +
aReflowInput.ComputedLogicalMargin().BStartEnd(wm); aReflowInput.ComputedLogicalMargin().BStartEnd(wm);
@ -1697,11 +1695,10 @@ nsBlockFrame::ComputeFinalSize(const ReflowInput& aReflowInput,
finalSize.BSize(wm) = std::max(0, finalSize.BSize(wm)); finalSize.BSize(wm) = std::max(0, finalSize.BSize(wm));
*aBEndEdgeOfChildren = blockEndEdgeOfChildren; *aBEndEdgeOfChildren = blockEndEdgeOfChildren;
FrameProperties properties = Properties();
if (blockEndEdgeOfChildren != finalSize.BSize(wm) - borderPadding.BEnd(wm)) { if (blockEndEdgeOfChildren != finalSize.BSize(wm) - borderPadding.BEnd(wm)) {
properties.Set(BlockEndEdgeOfChildrenProperty(), blockEndEdgeOfChildren); SetProperty(BlockEndEdgeOfChildrenProperty(), blockEndEdgeOfChildren);
} else { } else {
properties.Delete(BlockEndEdgeOfChildrenProperty()); DeleteProperty(BlockEndEdgeOfChildrenProperty());
} }
aMetrics.SetSize(wm, finalSize); aMetrics.SetSize(wm, finalSize);
@ -1834,7 +1831,7 @@ nsBlockFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas)
{ {
bool found; bool found;
nscoord blockEndEdgeOfChildren = nscoord blockEndEdgeOfChildren =
Properties().Get(BlockEndEdgeOfChildrenProperty(), &found); GetProperty(BlockEndEdgeOfChildrenProperty(), &found);
if (found) { if (found) {
ConsiderBlockEndEdgeOfChildren(GetWritingMode(), ConsiderBlockEndEdgeOfChildren(GetWritingMode(),
blockEndEdgeOfChildren, aOverflowAreas); blockEndEdgeOfChildren, aOverflowAreas);
@ -4985,7 +4982,7 @@ nsBlockFrame::GetOverflowLines() const
if (!HasOverflowLines()) { if (!HasOverflowLines()) {
return nullptr; return nullptr;
} }
FrameLines* prop = Properties().Get(OverflowLinesProperty()); FrameLines* prop = GetProperty(OverflowLinesProperty());
NS_ASSERTION(prop && !prop->mLines.empty() && NS_ASSERTION(prop && !prop->mLines.empty() &&
prop->mLines.front()->GetChildCount() == 0 ? prop->mFrames.IsEmpty() : prop->mLines.front()->GetChildCount() == 0 ? prop->mFrames.IsEmpty() :
prop->mLines.front()->mFirstChild == prop->mFrames.FirstChild(), prop->mLines.front()->mFirstChild == prop->mFrames.FirstChild(),
@ -4999,7 +4996,7 @@ nsBlockFrame::RemoveOverflowLines()
if (!HasOverflowLines()) { if (!HasOverflowLines()) {
return nullptr; return nullptr;
} }
FrameLines* prop = Properties().Remove(OverflowLinesProperty()); FrameLines* prop = RemoveProperty(OverflowLinesProperty());
NS_ASSERTION(prop && !prop->mLines.empty() && NS_ASSERTION(prop && !prop->mLines.empty() &&
prop->mLines.front()->GetChildCount() == 0 ? prop->mFrames.IsEmpty() : prop->mLines.front()->GetChildCount() == 0 ? prop->mFrames.IsEmpty() :
prop->mLines.front()->mFirstChild == prop->mFrames.FirstChild(), prop->mLines.front()->mFirstChild == prop->mFrames.FirstChild(),
@ -5012,7 +5009,7 @@ void
nsBlockFrame::DestroyOverflowLines() nsBlockFrame::DestroyOverflowLines()
{ {
NS_ASSERTION(HasOverflowLines(), "huh?"); NS_ASSERTION(HasOverflowLines(), "huh?");
FrameLines* prop = Properties().Remove(OverflowLinesProperty()); FrameLines* prop = RemoveProperty(OverflowLinesProperty());
NS_ASSERTION(prop && prop->mLines.empty(), NS_ASSERTION(prop && prop->mLines.empty(),
"value should always be stored but empty when destroying"); "value should always be stored but empty when destroying");
RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_LINES); RemoveStateBits(NS_BLOCK_HAS_OVERFLOW_LINES);
@ -5032,10 +5029,9 @@ nsBlockFrame::SetOverflowLines(FrameLines* aOverflowLines)
NS_ASSERTION(!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_LINES), NS_ASSERTION(!(GetStateBits() & NS_BLOCK_HAS_OVERFLOW_LINES),
"Overwriting existing overflow lines"); "Overwriting existing overflow lines");
FrameProperties props = Properties();
// Verify that we won't overwrite an existing overflow list // Verify that we won't overwrite an existing overflow list
NS_ASSERTION(!props.Get(OverflowLinesProperty()), "existing overflow list"); NS_ASSERTION(!GetProperty(OverflowLinesProperty()), "existing overflow list");
props.Set(OverflowLinesProperty(), aOverflowLines); SetProperty(OverflowLinesProperty(), aOverflowLines);
AddStateBits(NS_BLOCK_HAS_OVERFLOW_LINES); AddStateBits(NS_BLOCK_HAS_OVERFLOW_LINES);
} }
@ -5088,7 +5084,7 @@ nsBlockFrame::GetInsideBullet() const
return nullptr; return nullptr;
} }
NS_ASSERTION(!HasOutsideBullet(), "invalid bullet state"); NS_ASSERTION(!HasOutsideBullet(), "invalid bullet state");
nsBulletFrame* frame = Properties().Get(InsideBulletProperty()); nsBulletFrame* frame = GetProperty(InsideBulletProperty());
NS_ASSERTION(frame && frame->GetType() == nsGkAtoms::bulletFrame, NS_ASSERTION(frame && frame->GetType() == nsGkAtoms::bulletFrame,
"bogus inside bullet frame"); "bogus inside bullet frame");
return frame; return frame;
@ -5109,8 +5105,7 @@ nsBlockFrame::GetOutsideBulletList() const
return nullptr; return nullptr;
} }
NS_ASSERTION(!HasInsideBullet(), "invalid bullet state"); NS_ASSERTION(!HasInsideBullet(), "invalid bullet state");
nsFrameList* list = nsFrameList* list = GetProperty(OutsideBulletProperty());
Properties().Get(OutsideBulletProperty());
NS_ASSERTION(list && list->GetLength() == 1 && NS_ASSERTION(list && list->GetLength() == 1 &&
list->FirstChild()->GetType() == nsGkAtoms::bulletFrame, list->FirstChild()->GetType() == nsGkAtoms::bulletFrame,
"bogus outside bullet list"); "bogus outside bullet list");
@ -5123,8 +5118,7 @@ nsBlockFrame::GetPushedFloats() const
if (!HasPushedFloats()) { if (!HasPushedFloats()) {
return nullptr; return nullptr;
} }
nsFrameList* result = nsFrameList* result = GetProperty(PushedFloatProperty());
Properties().Get(PushedFloatProperty());
NS_ASSERTION(result, "value should always be non-empty when state set"); NS_ASSERTION(result, "value should always be non-empty when state set");
return result; return result;
} }
@ -5137,7 +5131,7 @@ nsBlockFrame::EnsurePushedFloats()
return result; return result;
result = new (PresContext()->PresShell()) nsFrameList; result = new (PresContext()->PresShell()) nsFrameList;
Properties().Set(PushedFloatProperty(), result); SetProperty(PushedFloatProperty(), result);
AddStateBits(NS_BLOCK_HAS_PUSHED_FLOATS); AddStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
return result; return result;
@ -5149,7 +5143,7 @@ nsBlockFrame::RemovePushedFloats()
if (!HasPushedFloats()) { if (!HasPushedFloats()) {
return nullptr; return nullptr;
} }
nsFrameList *result = Properties().Remove(PushedFloatProperty()); nsFrameList *result = RemoveProperty(PushedFloatProperty());
RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS); RemoveStateBits(NS_BLOCK_HAS_PUSHED_FLOATS);
NS_ASSERTION(result, "value should always be non-empty when state set"); NS_ASSERTION(result, "value should always be non-empty when state set");
return result; return result;
@ -5619,7 +5613,7 @@ nsBlockInFlowLineIterator::nsBlockInFlowLineIterator(nsBlockFrame* aFrame,
if (mLine != line_end) { if (mLine != line_end) {
*aFoundValidLine = true; *aFoundValidLine = true;
if (mLine != cursor) { if (mLine != cursor) {
aFrame->Properties().Set(nsBlockFrame::LineCursorProperty(), mLine); aFrame->SetProperty(nsBlockFrame::LineCursorProperty(), mLine);
} }
return; return;
} }
@ -6769,7 +6763,7 @@ void nsBlockFrame::ClearLineCursor()
return; return;
} }
Properties().Delete(LineCursorProperty()); DeleteProperty(LineCursorProperty());
RemoveStateBits(NS_BLOCK_HAS_LINE_CURSOR); RemoveStateBits(NS_BLOCK_HAS_LINE_CURSOR);
} }
@ -6780,7 +6774,7 @@ void nsBlockFrame::SetupLineCursor()
return; return;
} }
Properties().Set(LineCursorProperty(), mLines.front()); SetProperty(LineCursorProperty(), mLines.front());
AddStateBits(NS_BLOCK_HAS_LINE_CURSOR); AddStateBits(NS_BLOCK_HAS_LINE_CURSOR);
} }
@ -6790,9 +6784,7 @@ nsLineBox* nsBlockFrame::GetFirstLineContaining(nscoord y)
return nullptr; return nullptr;
} }
FrameProperties props = Properties(); nsLineBox* property = GetProperty(LineCursorProperty());
nsLineBox* property = props.Get(LineCursorProperty());
LineIterator cursor = mLines.begin(property); LineIterator cursor = mLines.begin(property);
nsRect cursorArea = cursor->GetVisualOverflowArea(); nsRect cursorArea = cursor->GetVisualOverflowArea();
@ -6808,7 +6800,7 @@ nsLineBox* nsBlockFrame::GetFirstLineContaining(nscoord y)
} }
if (cursor.get() != property) { if (cursor.get() != property) {
props.Set(LineCursorProperty(), cursor.get()); SetProperty(LineCursorProperty(), cursor.get());
} }
return cursor.get(); return cursor.get();
@ -7021,11 +7013,11 @@ nsBlockFrame::CreateBulletFrameForListItem(bool aCreateBulletList,
if (aListStylePositionInside) { if (aListStylePositionInside) {
nsFrameList bulletList(bullet, bullet); nsFrameList bulletList(bullet, bullet);
AddFrames(bulletList, nullptr); AddFrames(bulletList, nullptr);
Properties().Set(InsideBulletProperty(), bullet); SetProperty(InsideBulletProperty(), bullet);
AddStateBits(NS_BLOCK_FRAME_HAS_INSIDE_BULLET); AddStateBits(NS_BLOCK_FRAME_HAS_INSIDE_BULLET);
} else { } else {
nsFrameList* bulletList = new (shell) nsFrameList(bullet, bullet); nsFrameList* bulletList = new (shell) nsFrameList(bullet, bullet);
Properties().Set(OutsideBulletProperty(), bulletList); SetProperty(OutsideBulletProperty(), bulletList);
AddStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET); AddStateBits(NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET);
} }
} }

View File

@ -215,7 +215,7 @@ public:
~AutoLineCursorSetup() ~AutoLineCursorSetup()
{ {
if (mOrigCursor) { if (mOrigCursor) {
mFrame->Properties().Set(LineCursorProperty(), mOrigCursor); mFrame->SetProperty(LineCursorProperty(), mOrigCursor);
} else { } else {
mFrame->ClearLineCursor(); mFrame->ClearLineCursor();
} }
@ -416,7 +416,7 @@ protected:
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(LineCursorProperty, nsLineBox) NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(LineCursorProperty, nsLineBox)
bool HasLineCursor() { return GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR; } bool HasLineCursor() { return GetStateBits() & NS_BLOCK_HAS_LINE_CURSOR; }
nsLineBox* GetLineCursor() { nsLineBox* GetLineCursor() {
return HasLineCursor() ? Properties().Get(LineCursorProperty()) : nullptr; return HasLineCursor() ? GetProperty(LineCursorProperty()) : nullptr;
} }
nsLineBox* NewLineBox(nsIFrame* aFrame, bool aIsBlock) { nsLineBox* NewLineBox(nsIFrame* aFrame, bool aIsBlock) {

View File

@ -903,7 +903,7 @@ nsBulletFrame::GetFontSizeInflation() const
if (!HasFontSizeInflation()) { if (!HasFontSizeInflation()) {
return 1.0f; return 1.0f;
} }
return Properties().Get(FontSizeInflationProperty()); return GetProperty(FontSizeInflationProperty());
} }
void void
@ -912,13 +912,13 @@ nsBulletFrame::SetFontSizeInflation(float aInflation)
if (aInflation == 1.0f) { if (aInflation == 1.0f) {
if (HasFontSizeInflation()) { if (HasFontSizeInflation()) {
RemoveStateBits(BULLET_FRAME_HAS_FONT_INFLATION); RemoveStateBits(BULLET_FRAME_HAS_FONT_INFLATION);
Properties().Delete(FontSizeInflationProperty()); DeleteProperty(FontSizeInflationProperty());
} }
return; return;
} }
AddStateBits(BULLET_FRAME_HAS_FONT_INFLATION); AddStateBits(BULLET_FRAME_HAS_FONT_INFLATION);
Properties().Set(FontSizeInflationProperty(), aInflation); SetProperty(FontSizeInflationProperty(), aInflation);
} }
already_AddRefed<imgIContainer> already_AddRefed<imgIContainer>

View File

@ -300,7 +300,7 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
// above. // above.
destRect.Round(); destRect.Round();
RefPtr<DrawTarget> dt = RefPtr<DrawTarget> dt =
Frame()->Properties().Get(nsIFrame::CachedBackgroundImageDT()); Frame()->GetProperty(nsIFrame::CachedBackgroundImageDT());
DrawTarget* destDT = dest->GetDrawTarget(); DrawTarget* destDT = dest->GetDrawTarget();
if (dt) { if (dt) {
BlitSurface(destDT, destRect, dt); BlitSurface(destDT, destRect, dt);
@ -317,7 +317,7 @@ nsDisplayCanvasBackgroundImage::Paint(nsDisplayListBuilder* aBuilder,
nsRenderingContext context(ctx); nsRenderingContext context(ctx);
PaintInternal(aBuilder, &context, bgClipRect, &bgClipRect); PaintInternal(aBuilder, &context, bgClipRect, &bgClipRect);
BlitSurface(dest->GetDrawTarget(), destRect, dt); BlitSurface(dest->GetDrawTarget(), destRect, dt);
frame->Properties().Set(nsIFrame::CachedBackgroundImageDT(), frame->SetProperty(nsIFrame::CachedBackgroundImageDT(),
dt.forget().take()); dt.forget().take());
return; return;
} }

View File

@ -201,7 +201,7 @@ public:
virtual void NotifyRenderingChanged() override virtual void NotifyRenderingChanged() override
{ {
mFrame->Properties().Delete(nsIFrame::CachedBackgroundImageDT()); mFrame->DeleteProperty(nsIFrame::CachedBackgroundImageDT());
} }
virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override virtual bool ShouldFixToViewport(nsDisplayListBuilder* aBuilder) override

View File

@ -78,7 +78,7 @@ nsContainerFrame::SetInitialChildList(ChildListID aListID,
"Only top layer frames should have backdrop"); "Only top layer frames should have backdrop");
MOZ_ASSERT(GetStateBits() & NS_FRAME_OUT_OF_FLOW, MOZ_ASSERT(GetStateBits() & NS_FRAME_OUT_OF_FLOW,
"Top layer frames should be 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"); "We shouldn't have setup backdrop frame list before");
#ifdef DEBUG #ifdef DEBUG
{ {
@ -93,7 +93,7 @@ nsContainerFrame::SetInitialChildList(ChildListID aListID,
#endif #endif
nsFrameList* list = nsFrameList* list =
new (PresContext()->PresShell()) nsFrameList(aChildList); new (PresContext()->PresShell()) nsFrameList(aChildList);
Properties().Set(BackdropProperty(), list); SetProperty(BackdropProperty(), list);
} else { } else {
MOZ_ASSERT_UNREACHABLE("Unexpected child list"); MOZ_ASSERT_UNREACHABLE("Unexpected child list");
} }
@ -189,18 +189,17 @@ nsContainerFrame::DestroyAbsoluteFrames(nsIFrame* aDestructRoot)
void void
nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot, nsContainerFrame::SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell, nsIPresShell* aPresShell,
FramePropertyTable* aPropTable,
FrameListPropertyDescriptor aProp) FrameListPropertyDescriptor aProp)
{ {
// Note that the last frame can be removed through another route and thus // 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 // delete the property -- that's why we fetch the property again before
// removing each frame rather than fetching it once and iterating the list. // 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(); nsIFrame* frame = frameList->RemoveFirstChild();
if (MOZ_LIKELY(frame)) { if (MOZ_LIKELY(frame)) {
frame->DestroyFrom(aDestructRoot); frame->DestroyFrom(aDestructRoot);
} else { } else {
aPropTable->Remove(this, aProp); RemoveProperty(aProp);
frameList->Delete(aPresShell); frameList->Delete(aPresShell);
return; return;
} }
@ -220,25 +219,49 @@ nsContainerFrame::DestroyFrom(nsIFrame* aDestructRoot)
// Destroy frames on the principal child list. // Destroy frames on the principal child list.
mFrames.DestroyFramesFrom(aDestructRoot); 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. // Destroy frames on the auxiliary frame lists and delete the lists.
nsPresContext* pc = PresContext(); nsPresContext* pc = PresContext();
nsIPresShell* shell = pc->PresShell(); nsIPresShell* shell = pc->PresShell();
FramePropertyTable* props = pc->PropertyTable(); if (hasO) {
SafelyDestroyFrameListProp(aDestructRoot, shell, props, OverflowProperty()); SafelyDestroyFrameListProp(aDestructRoot, shell, OverflowProperty());
}
MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers) || MOZ_ASSERT(IsFrameOfType(eCanContainOverflowContainers) ||
!(props->Get(this, nsContainerFrame::OverflowContainersProperty()) || !(hasOC || hasEOC),
props->Get(this, nsContainerFrame::ExcessOverflowContainersProperty())), "this type of frame shouldn't have overflow containers");
"this type of frame should't have overflow containers"); if (hasOC) {
SafelyDestroyFrameListProp(aDestructRoot, shell, props, SafelyDestroyFrameListProp(aDestructRoot, shell,
OverflowContainersProperty()); OverflowContainersProperty());
SafelyDestroyFrameListProp(aDestructRoot, shell, props, }
ExcessOverflowContainersProperty()); if (hasEOC) {
SafelyDestroyFrameListProp(aDestructRoot, shell,
ExcessOverflowContainersProperty());
}
MOZ_ASSERT(!props->Get(this, BackdropProperty()) || MOZ_ASSERT(!GetProperty(BackdropProperty()) ||
StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE, StyleDisplay()->mTopLayer != NS_STYLE_TOP_LAYER_NONE,
"only top layer frame may have backdrop"); "only top layer frame may have backdrop");
SafelyDestroyFrameListProp(aDestructRoot, shell, props, BackdropProperty()); if (hasBackdrop) {
SafelyDestroyFrameListProp(aDestructRoot, shell, BackdropProperty());
}
}
nsSplittableFrame::DestroyFrom(aDestructRoot); 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 void
nsContainerFrame::GetChildLists(nsTArray<ChildList>* aLists) const nsContainerFrame::GetChildLists(nsTArray<ChildList>* aLists) const
{ {
mFrames.AppendIfNonempty(aLists, kPrincipalList); mFrames.AppendIfNonempty(aLists, kPrincipalList);
FramePropertyTable* propTable = PresContext()->PropertyTable(); using T = mozilla::FrameProperties::UntypedDescriptor;
::AppendIfNonempty(this, propTable, OverflowProperty(), mProperties.ForEach([this, aLists] (const T& aProp, void* aValue) {
aLists, kOverflowList); typedef const nsFrameList* L;
if (IsFrameOfType(nsIFrame::eCanContainOverflowContainers)) { if (aProp == OverflowProperty()) {
::AppendIfNonempty(this, propTable, OverflowContainersProperty(), L(aValue)->AppendIfNonempty(aLists, kOverflowList);
aLists, kOverflowContainersList); } else if (aProp == OverflowContainersProperty()) {
::AppendIfNonempty(this, propTable, ExcessOverflowContainersProperty(), MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
aLists, kExcessOverflowContainersList); "found unexpected OverflowContainersProperty");
} L(aValue)->AppendIfNonempty(aLists, kOverflowContainersList);
// Bypass BackdropProperty hashtable lookup for any in-flow frames } else if (aProp == ExcessOverflowContainersProperty()) {
// since frames in the top layer (only which can have backdrop) are MOZ_ASSERT(IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
// definitely out-of-flow. "found unexpected ExcessOverflowContainersProperty");
if (GetStateBits() & NS_FRAME_OUT_OF_FLOW) { L(aValue)->AppendIfNonempty(aLists, kExcessOverflowContainersList);
::AppendIfNonempty(this, propTable, BackdropProperty(), } else if (aProp == BackdropProperty()) {
aLists, kBackdropList); L(aValue)->AppendIfNonempty(aLists, kBackdropList);
} }
return true;
});
nsSplittableFrame::GetChildLists(aLists); nsSplittableFrame::GetChildLists(aLists);
} }
@ -1335,15 +1348,15 @@ nsContainerFrame::DisplayOverflowContainers(nsDisplayListBuilder* aBuilder,
} }
static bool static bool
TryRemoveFrame(nsIFrame* aFrame, FramePropertyTable* aPropTable, TryRemoveFrame(nsIFrame* aFrame,
nsContainerFrame::FrameListPropertyDescriptor aProp, nsContainerFrame::FrameListPropertyDescriptor aProp,
nsIFrame* aChildToRemove) nsIFrame* aChildToRemove)
{ {
nsFrameList* list = aPropTable->Get(aFrame, aProp); nsFrameList* list = aFrame->GetProperty(aProp);
if (list && list->StartRemoveFrame(aChildToRemove)) { if (list && list->StartRemoveFrame(aChildToRemove)) {
// aChildToRemove *may* have been removed from this list. // aChildToRemove *may* have been removed from this list.
if (list->IsEmpty()) { if (list->IsEmpty()) {
aPropTable->Remove(aFrame, aProp); aFrame->RemoveProperty(aProp);
list->Delete(aFrame->PresContext()->PresShell()); list->Delete(aFrame->PresContext()->PresShell());
} }
return true; return true;
@ -1356,13 +1369,12 @@ nsContainerFrame::MaybeStealOverflowContainerFrame(nsIFrame* aChild)
{ {
bool removed = false; bool removed = false;
if (MOZ_UNLIKELY(aChild->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) { if (MOZ_UNLIKELY(aChild->GetStateBits() & NS_FRAME_IS_OVERFLOW_CONTAINER)) {
FramePropertyTable* propTable = PresContext()->PropertyTable();
// Try removing from the overflow container list. // Try removing from the overflow container list.
removed = ::TryRemoveFrame(this, propTable, OverflowContainersProperty(), removed = ::TryRemoveFrame(this, OverflowContainersProperty(),
aChild); aChild);
if (!removed) { if (!removed) {
// It might be in the excess overflow container list. // It might be in the excess overflow container list.
removed = ::TryRemoveFrame(this, propTable, removed = ::TryRemoveFrame(this,
ExcessOverflowContainersProperty(), ExcessOverflowContainersProperty(),
aChild); aChild);
} }
@ -1377,10 +1389,9 @@ nsContainerFrame::StealFrame(nsIFrame* aChild)
if (!mFrames.ContainsFrame(aChild)) { if (!mFrames.ContainsFrame(aChild)) {
nsFrameList* list = GetOverflowFrames(); nsFrameList* list = GetOverflowFrames();
if (!list || !list->ContainsFrame(aChild)) { if (!list || !list->ContainsFrame(aChild)) {
FramePropertyTable* propTable = PresContext()->PropertyTable(); list = GetProperty(OverflowContainersProperty());
list = propTable->Get(this, OverflowContainersProperty());
if (!list || !list->ContainsFrame(aChild)) { if (!list || !list->ContainsFrame(aChild)) {
list = propTable->Get(this, ExcessOverflowContainersProperty()); list = GetProperty(ExcessOverflowContainersProperty());
MOZ_ASSERT(list && list->ContainsFrame(aChild), "aChild isn't our child" MOZ_ASSERT(list && list->ContainsFrame(aChild), "aChild isn't our child"
" or on a frame list not supported by StealFrame"); " or on a frame list not supported by StealFrame");
} }
@ -1536,20 +1547,20 @@ nsContainerFrame::SetOverflowFrames(const nsFrameList& aOverflowFrames)
nsPresContext* pc = PresContext(); nsPresContext* pc = PresContext();
nsFrameList* newList = new (pc->PresShell()) nsFrameList(aOverflowFrames); nsFrameList* newList = new (pc->PresShell()) nsFrameList(aOverflowFrames);
pc->PropertyTable()->Set(this, OverflowProperty(), newList); SetProperty(OverflowProperty(), newList);
} }
nsFrameList* nsFrameList*
nsContainerFrame::GetPropTableFrames( nsContainerFrame::GetPropTableFrames(
FrameListPropertyDescriptor aProperty) const FrameListPropertyDescriptor aProperty) const
{ {
return PresContext()->PropertyTable()->Get(this, aProperty); return GetProperty(aProperty);
} }
nsFrameList* nsFrameList*
nsContainerFrame::RemovePropTableFrames(FrameListPropertyDescriptor aProperty) nsContainerFrame::RemovePropTableFrames(FrameListPropertyDescriptor aProperty)
{ {
return PresContext()->PropertyTable()->Remove(this, aProperty); return RemoveProperty(aProperty);
} }
void void
@ -1563,7 +1574,7 @@ nsContainerFrame::SetPropTableFrames(nsFrameList* aFrameList,
IsFrameOfType(nsIFrame::eCanContainOverflowContainers), IsFrameOfType(nsIFrame::eCanContainOverflowContainers),
"this type of frame can't have overflow containers"); "this type of frame can't have overflow containers");
MOZ_ASSERT(!GetPropTableFrames(aProperty)); MOZ_ASSERT(!GetPropTableFrames(aProperty));
PresContext()->PropertyTable()->Set(this, aProperty, aFrameList); SetProperty(aProperty, aFrameList);
} }
/** /**
@ -2253,13 +2264,11 @@ nsOverflowContinuationTracker::EndFinish(nsIFrame* aChild)
return; return;
} }
// Forget mOverflowContList if it was deleted. // Forget mOverflowContList if it was deleted.
nsPresContext* pc = aChild->PresContext(); nsFrameList* eoc = mParent->GetProperty
FramePropertyTable* propTable = pc->PropertyTable(); (nsContainerFrame::ExcessOverflowContainersProperty());
nsFrameList* eoc = propTable->Get(
mParent, nsContainerFrame::ExcessOverflowContainersProperty());
if (eoc != mOverflowContList) { if (eoc != mOverflowContList) {
nsFrameList* oc = static_cast<nsFrameList*>(propTable->Get(mParent, nsFrameList* oc = static_cast<nsFrameList*>(mParent->GetProperty
nsContainerFrame::OverflowContainersProperty())); (nsContainerFrame::OverflowContainersProperty()));
if (oc != mOverflowContList) { if (oc != mOverflowContList) {
// mOverflowContList was deleted // mOverflowContList was deleted
mPrevOverflowCont = nullptr; mPrevOverflowCont = nullptr;

View File

@ -24,9 +24,6 @@
#define NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD 0x0010 #define NS_FRAME_NO_DELETE_NEXT_IN_FLOW_CHILD 0x0010
class nsOverflowContinuationTracker; class nsOverflowContinuationTracker;
namespace mozilla {
class FramePropertyTable;
} // namespace mozilla
// Some macros for container classes to do sanity checking on // Some macros for container classes to do sanity checking on
// width/height/x/y values computed during reflow. // width/height/x/y values computed during reflow.
@ -548,7 +545,7 @@ public:
// Use this to suppress the CRAZY_SIZE assertions. // Use this to suppress the CRAZY_SIZE assertions.
NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugReflowingWithInfiniteISize, bool) NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(DebugReflowingWithInfiniteISize, bool)
bool IsCrazySizeAssertSuppressed() const { bool IsCrazySizeAssertSuppressed() const {
return Properties().Get(DebugReflowingWithInfiniteISize()); return GetProperty(DebugReflowingWithInfiniteISize());
} }
#endif #endif
@ -716,7 +713,6 @@ protected:
*/ */
void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot, void SafelyDestroyFrameListProp(nsIFrame* aDestructRoot,
nsIPresShell* aPresShell, nsIPresShell* aPresShell,
mozilla::FramePropertyTable* aPropTable,
FrameListPropertyDescriptor aProp); FrameListPropertyDescriptor aProp);
// ========================================================================== // ==========================================================================
@ -898,7 +894,7 @@ inline
nsFrameList* nsFrameList*
nsContainerFrame::GetOverflowFrames() const nsContainerFrame::GetOverflowFrames() const
{ {
nsFrameList* list = Properties().Get(OverflowProperty()); nsFrameList* list = GetProperty(OverflowProperty());
NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list"); NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
return list; return list;
} }
@ -907,7 +903,7 @@ inline
nsFrameList* nsFrameList*
nsContainerFrame::StealOverflowFrames() nsContainerFrame::StealOverflowFrames()
{ {
nsFrameList* list = Properties().Remove(OverflowProperty()); nsFrameList* list = RemoveProperty(OverflowProperty());
NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list"); NS_ASSERTION(!list || !list->IsEmpty(), "Unexpected empty overflow list");
return list; return list;
} }

View File

@ -1816,8 +1816,8 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem(
nsPresContext* aPresContext, nsPresContext* aPresContext,
ReflowInput& aChildReflowInput) ReflowInput& aChildReflowInput)
{ {
const FrameProperties props = aItem.Frame()->Properties(); if (const auto* cachedResult =
if (const auto* cachedResult = props.Get(CachedFlexMeasuringReflow())) { aItem.Frame()->GetProperty(CachedFlexMeasuringReflow())) {
if (cachedResult->IsValidFor(aChildReflowInput)) { if (cachedResult->IsValidFor(aChildReflowInput)) {
return *cachedResult; return *cachedResult;
} }
@ -1847,7 +1847,7 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem(
auto result = auto result =
new CachedMeasuringReflowResult(aChildReflowInput, childDesiredSize); new CachedMeasuringReflowResult(aChildReflowInput, childDesiredSize);
props.Set(CachedFlexMeasuringReflow(), result); aItem.Frame()->SetProperty(CachedFlexMeasuringReflow(), result);
return *result; return *result;
} }
@ -1855,7 +1855,7 @@ nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem(
nsFlexContainerFrame::MarkIntrinsicISizesDirty() nsFlexContainerFrame::MarkIntrinsicISizesDirty()
{ {
for (nsIFrame* childFrame : mFrames) { for (nsIFrame* childFrame : mFrames) {
childFrame->Properties().Delete(CachedFlexMeasuringReflow()); childFrame->DeleteProperty(CachedFlexMeasuringReflow());
} }
nsContainerFrame::MarkIntrinsicISizesDirty(); nsContainerFrame::MarkIntrinsicISizesDirty();
} }
@ -4236,25 +4236,26 @@ class MOZ_RAII AutoFlexItemMainSizeOverride final
public: public:
explicit AutoFlexItemMainSizeOverride(FlexItem& aItem explicit AutoFlexItemMainSizeOverride(FlexItem& aItem
MOZ_GUARD_OBJECT_NOTIFIER_PARAM) MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
: mItemProps(aItem.Frame()->Properties()) : mItemFrame(aItem.Frame())
{ {
MOZ_GUARD_OBJECT_NOTIFIER_INIT; MOZ_GUARD_OBJECT_NOTIFIER_INIT;
MOZ_ASSERT(!mItemProps.Has(nsIFrame::FlexItemMainSizeOverride()), MOZ_ASSERT(!mItemFrame->HasProperty(nsIFrame::FlexItemMainSizeOverride()),
"FlexItemMainSizeOverride prop shouldn't be set already; " "FlexItemMainSizeOverride prop shouldn't be set already; "
"it should only be set temporarily (& not recursively)"); "it should only be set temporarily (& not recursively)");
NS_ASSERTION(aItem.HasIntrinsicRatio(), NS_ASSERTION(aItem.HasIntrinsicRatio(),
"This should only be needed for items with an aspect ratio"); "This should only be needed for items with an aspect ratio");
mItemProps.Set(nsIFrame::FlexItemMainSizeOverride(), aItem.GetMainSize()); mItemFrame->SetProperty(nsIFrame::FlexItemMainSizeOverride(),
aItem.GetMainSize());
} }
~AutoFlexItemMainSizeOverride() { ~AutoFlexItemMainSizeOverride() {
mItemProps.Remove(nsIFrame::FlexItemMainSizeOverride()); mItemFrame->RemoveProperty(nsIFrame::FlexItemMainSizeOverride());
} }
private: private:
const FrameProperties mItemProps; nsIFrame* mItemFrame;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
}; };
@ -4668,8 +4669,7 @@ nsFlexContainerFrame::MoveFlexItemToFinalPosition(
// If item is relpos, look up its offsets (cached from prev reflow) // If item is relpos, look up its offsets (cached from prev reflow)
LogicalMargin logicalOffsets(outerWM); LogicalMargin logicalOffsets(outerWM);
if (NS_STYLE_POSITION_RELATIVE == aItem.Frame()->StyleDisplay()->mPosition) { if (NS_STYLE_POSITION_RELATIVE == aItem.Frame()->StyleDisplay()->mPosition) {
FrameProperties props = aItem.Frame()->Properties(); nsMargin* cachedOffsets = aItem.Frame()->GetProperty(nsIFrame::ComputedOffsetProperty());
nsMargin* cachedOffsets = props.Get(nsIFrame::ComputedOffsetProperty());
MOZ_ASSERT(cachedOffsets, MOZ_ASSERT(cachedOffsets,
"relpos previously-reflowed frame should've cached its offsets"); "relpos previously-reflowed frame should've cached its offsets");
logicalOffsets = LogicalMargin(outerWM, *cachedOffsets); logicalOffsets = LogicalMargin(outerWM, *cachedOffsets);

View File

@ -331,7 +331,7 @@ nsFloatManager::GetRegionFor(WritingMode aWM, nsIFrame* aFloat,
const nsSize& aContainerSize) const nsSize& aContainerSize)
{ {
LogicalRect region = aFloat->GetLogicalRect(aWM, aContainerSize); LogicalRect region = aFloat->GetLogicalRect(aWM, aContainerSize);
void* storedRegion = aFloat->Properties().Get(FloatRegionProperty()); void* storedRegion = aFloat->GetProperty(FloatRegionProperty());
if (storedRegion) { if (storedRegion) {
nsMargin margin = *static_cast<nsMargin*>(storedRegion); nsMargin margin = *static_cast<nsMargin*>(storedRegion);
region.Inflate(aWM, LogicalMargin(aWM, margin)); region.Inflate(aWM, LogicalMargin(aWM, margin));
@ -346,15 +346,14 @@ nsFloatManager::StoreRegionFor(WritingMode aWM, nsIFrame* aFloat,
{ {
nsRect region = aRegion.GetPhysicalRect(aWM, aContainerSize); nsRect region = aRegion.GetPhysicalRect(aWM, aContainerSize);
nsRect rect = aFloat->GetRect(); nsRect rect = aFloat->GetRect();
FrameProperties props = aFloat->Properties();
if (region.IsEqualEdges(rect)) { if (region.IsEqualEdges(rect)) {
props.Delete(FloatRegionProperty()); aFloat->DeleteProperty(FloatRegionProperty());
} }
else { else {
nsMargin* storedMargin = props.Get(FloatRegionProperty()); nsMargin* storedMargin = aFloat->GetProperty(FloatRegionProperty());
if (!storedMargin) { if (!storedMargin) {
storedMargin = new nsMargin(); storedMargin = new nsMargin();
props.Set(FloatRegionProperty(), storedMargin); aFloat->SetProperty(FloatRegionProperty(), storedMargin);
} }
*storedMargin = region - rect; *storedMargin = region - rect;
} }

View File

@ -6,7 +6,7 @@
/* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */ /* Per-block-formatting-context manager of font size inflation for pan and zoom UI. */
#include "nsFontInflationData.h" #include "nsFontInflationData.h"
#include "FramePropertyTable.h" #include "FrameProperties.h"
#include "nsTextControlFrame.h" #include "nsTextControlFrame.h"
#include "nsListControlFrame.h" #include "nsListControlFrame.h"
#include "nsComboboxControlFrame.h" #include "nsComboboxControlFrame.h"
@ -27,7 +27,7 @@ nsFontInflationData::FindFontInflationDataFor(const nsIFrame *aFrame)
NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT, NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT,
"should have found a flow root"); "should have found a flow root");
return bfc->Properties().Get(FontInflationDataProperty()); return bfc->GetProperty(FontInflationDataProperty());
} }
/* static */ bool /* static */ bool
@ -36,8 +36,7 @@ nsFontInflationData::UpdateFontInflationDataISizeFor(const ReflowInput& aReflowI
nsIFrame *bfc = aReflowInput.mFrame; nsIFrame *bfc = aReflowInput.mFrame;
NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT, NS_ASSERTION(bfc->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT,
"should have been given a flow root"); "should have been given a flow root");
FrameProperties bfcProps(bfc->Properties()); nsFontInflationData *data = bfc->GetProperty(FontInflationDataProperty());
nsFontInflationData *data = bfcProps.Get(FontInflationDataProperty());
bool oldInflationEnabled; bool oldInflationEnabled;
nscoord oldNCAISize; nscoord oldNCAISize;
if (data) { if (data) {
@ -45,7 +44,7 @@ nsFontInflationData::UpdateFontInflationDataISizeFor(const ReflowInput& aReflowI
oldInflationEnabled = data->mInflationEnabled; oldInflationEnabled = data->mInflationEnabled;
} else { } else {
data = new nsFontInflationData(bfc); data = new nsFontInflationData(bfc);
bfcProps.Set(FontInflationDataProperty(), data); bfc->SetProperty(FontInflationDataProperty(), data);
oldNCAISize = -1; oldNCAISize = -1;
oldInflationEnabled = true; /* not relevant */ oldInflationEnabled = true; /* not relevant */
} }
@ -65,8 +64,7 @@ nsFontInflationData::MarkFontInflationDataTextDirty(nsIFrame *aBFCFrame)
NS_ASSERTION(aBFCFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT, NS_ASSERTION(aBFCFrame->GetStateBits() & NS_FRAME_FONT_INFLATION_FLOW_ROOT,
"should have been given a flow root"); "should have been given a flow root");
FrameProperties bfcProps(aBFCFrame->Properties()); nsFontInflationData *data = aBFCFrame->GetProperty(FontInflationDataProperty());
nsFontInflationData *data = bfcProps.Get(FontInflationDataProperty());
if (data) { if (data) {
data->MarkTextDirty(); data->MarkTextDirty();
} }

View File

@ -168,13 +168,12 @@ NS_DECLARE_FRAME_PROPERTY_DELETABLE(BoxMetricsProperty, nsBoxLayoutMetrics)
static void static void
InitBoxMetrics(nsIFrame* aFrame, bool aClear) InitBoxMetrics(nsIFrame* aFrame, bool aClear)
{ {
FrameProperties props = aFrame->Properties();
if (aClear) { if (aClear) {
props.Delete(BoxMetricsProperty()); aFrame->DeleteProperty(BoxMetricsProperty());
} }
nsBoxLayoutMetrics* metrics = new nsBoxLayoutMetrics(); nsBoxLayoutMetrics* metrics = new nsBoxLayoutMetrics();
props.Set(BoxMetricsProperty(), metrics); aFrame->SetProperty(BoxMetricsProperty(), metrics);
static_cast<nsFrame*>(aFrame)->nsFrame::MarkIntrinsicISizesDirty(); static_cast<nsFrame*>(aFrame)->nsFrame::MarkIntrinsicISizesDirty();
metrics->mBlockAscent = 0; metrics->mBlockAscent = 0;
@ -254,7 +253,7 @@ nsIFrame::HasAbsolutelyPositionedChildren() const {
nsAbsoluteContainingBlock* nsAbsoluteContainingBlock*
nsIFrame::GetAbsoluteContainingBlock() const { nsIFrame::GetAbsoluteContainingBlock() const {
NS_ASSERTION(IsAbsoluteContainer(), "The frame is not marked as an abspos container correctly"); 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"); NS_ASSERTION(absCB, "The frame is marked as an abspos container but doesn't have the property");
return absCB; return absCB;
} }
@ -263,25 +262,25 @@ void
nsIFrame::MarkAsAbsoluteContainingBlock() nsIFrame::MarkAsAbsoluteContainingBlock()
{ {
MOZ_ASSERT(GetStateBits() & NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN); 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?"); "Already has an abs-pos containing block property?");
NS_ASSERTION(!HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN), NS_ASSERTION(!HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN),
"Already has NS_FRAME_HAS_ABSPOS_CHILDREN state bit?"); "Already has NS_FRAME_HAS_ABSPOS_CHILDREN state bit?");
AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN); AddStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
Properties().Set(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID())); SetProperty(AbsoluteContainingBlockProperty(), new nsAbsoluteContainingBlock(GetAbsoluteListID()));
} }
void void
nsIFrame::MarkAsNotAbsoluteContainingBlock() nsIFrame::MarkAsNotAbsoluteContainingBlock()
{ {
NS_ASSERTION(!HasAbsolutelyPositionedChildren(), "Think of the children!"); NS_ASSERTION(!HasAbsolutelyPositionedChildren(), "Think of the children!");
NS_ASSERTION(Properties().Get(AbsoluteContainingBlockProperty()), NS_ASSERTION(GetProperty(AbsoluteContainingBlockProperty()),
"Should have an abs-pos containing block property"); "Should have an abs-pos containing block property");
NS_ASSERTION(HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN), NS_ASSERTION(HasAnyStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN),
"Should have NS_FRAME_HAS_ABSPOS_CHILDREN state bit"); "Should have NS_FRAME_HAS_ABSPOS_CHILDREN state bit");
MOZ_ASSERT(HasAnyStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN)); MOZ_ASSERT(HasAnyStateBits(NS_FRAME_CAN_HAVE_ABSPOS_CHILDREN));
RemoveStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN); RemoveStateBits(NS_FRAME_HAS_ABSPOS_CHILDREN);
Properties().Delete(AbsoluteContainingBlockProperty()); DeleteProperty(AbsoluteContainingBlockProperty());
} }
bool bool
@ -652,32 +651,30 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
} }
// If we have any IB split siblings, clear their references to us. // If we have any IB split siblings, clear their references to us.
// (Note: This has to happen before we call shell->NotifyDestroyingFrame, // (Note: This has to happen before we clear our Properties() table.)
// because that clears our Properties() table.)
if (mState & NS_FRAME_PART_OF_IBSPLIT) { if (mState & NS_FRAME_PART_OF_IBSPLIT) {
// Delete previous sibling's reference to me. // Delete previous sibling's reference to me.
nsIFrame* prevSib = Properties().Get(nsIFrame::IBSplitPrevSibling()); nsIFrame* prevSib = GetProperty(nsIFrame::IBSplitPrevSibling());
if (prevSib) { if (prevSib) {
NS_WARNING_ASSERTION( NS_WARNING_ASSERTION(
this == prevSib->Properties().Get(nsIFrame::IBSplitSibling()), this == prevSib->GetProperty(nsIFrame::IBSplitSibling()),
"IB sibling chain is inconsistent"); "IB sibling chain is inconsistent");
prevSib->Properties().Delete(nsIFrame::IBSplitSibling()); prevSib->DeleteProperty(nsIFrame::IBSplitSibling());
} }
// Delete next sibling's reference to me. // Delete next sibling's reference to me.
nsIFrame* nextSib = Properties().Get(nsIFrame::IBSplitSibling()); nsIFrame* nextSib = GetProperty(nsIFrame::IBSplitSibling());
if (nextSib) { if (nextSib) {
NS_WARNING_ASSERTION( NS_WARNING_ASSERTION(
this == nextSib->Properties().Get(nsIFrame::IBSplitPrevSibling()), this == nextSib->GetProperty(nsIFrame::IBSplitPrevSibling()),
"IB sibling chain is inconsistent"); "IB sibling chain is inconsistent");
nextSib->Properties().Delete(nsIFrame::IBSplitPrevSibling()); nextSib->DeleteProperty(nsIFrame::IBSplitPrevSibling());
} }
} }
bool isPrimaryFrame = (mContent && mContent->GetPrimaryFrame() == this); bool isPrimaryFrame = (mContent && mContent->GetPrimaryFrame() == this);
if (isPrimaryFrame) { if (isPrimaryFrame) {
// This needs to happen before shell->NotifyDestroyingFrame because // This needs to happen before we clear our Properties() table.
// that clears our Properties() table.
ActiveLayerTracker::TransferActivityToContent(this, mContent); ActiveLayerTracker::TransferActivityToContent(this, mContent);
// Unfortunately, we need to do this for all frames being reframed // 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 // Disable visibility tracking. Note that we have to do this before we clear
// NotifyDestroyingFrame(), which will clear frame properties and make us lose // frame properties and lose track of whether we were previously visible.
// track of whether we were previously visible or not.
// XXX(seth): It'd be ideal to assert that we're already marked nonvisible // 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 // here, but it's unfortunately tricky to guarantee in the face of things like
// frame reconstruction induced by style changes. // frame reconstruction induced by style changes.
@ -742,6 +738,10 @@ nsFrame::DestroyFrom(nsIFrame* aDestructRoot)
mContent->SetPrimaryFrame(nullptr); 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 // Must retrieve the object ID before calling destructors, so the
// vtable is still valid. // vtable is still valid.
// //
@ -860,22 +860,21 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
// calls GetUsed(Margin|Border|Padding)() before the next reflow, we // calls GetUsed(Margin|Border|Padding)() before the next reflow, we
// can give an accurate answer. // can give an accurate answer.
// We don't want to set the property if one already exists. // We don't want to set the property if one already exists.
FrameProperties props = Properties();
nsMargin oldValue(0, 0, 0, 0); nsMargin oldValue(0, 0, 0, 0);
nsMargin newValue(0, 0, 0, 0); nsMargin newValue(0, 0, 0, 0);
const nsStyleMargin* oldMargin = aOldStyleContext->PeekStyleMargin(); const nsStyleMargin* oldMargin = aOldStyleContext->PeekStyleMargin();
if (oldMargin && oldMargin->GetMargin(oldValue)) { if (oldMargin && oldMargin->GetMargin(oldValue)) {
if ((!StyleMargin()->GetMargin(newValue) || oldValue != newValue) && if ((!StyleMargin()->GetMargin(newValue) || oldValue != newValue) &&
!props.Get(UsedMarginProperty())) { !GetProperty(UsedMarginProperty())) {
props.Set(UsedMarginProperty(), new nsMargin(oldValue)); SetProperty(UsedMarginProperty(), new nsMargin(oldValue));
} }
} }
const nsStylePadding* oldPadding = aOldStyleContext->PeekStylePadding(); const nsStylePadding* oldPadding = aOldStyleContext->PeekStylePadding();
if (oldPadding && oldPadding->GetPadding(oldValue)) { if (oldPadding && oldPadding->GetPadding(oldValue)) {
if ((!StylePadding()->GetPadding(newValue) || oldValue != newValue) && if ((!StylePadding()->GetPadding(newValue) || oldValue != newValue) &&
!props.Get(UsedPaddingProperty())) { !GetProperty(UsedPaddingProperty())) {
props.Set(UsedPaddingProperty(), new nsMargin(oldValue)); SetProperty(UsedPaddingProperty(), new nsMargin(oldValue));
} }
} }
@ -884,8 +883,8 @@ nsFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
oldValue = oldBorder->GetComputedBorder(); oldValue = oldBorder->GetComputedBorder();
newValue = StyleBorder()->GetComputedBorder(); newValue = StyleBorder()->GetComputedBorder();
if (oldValue != newValue && if (oldValue != newValue &&
!props.Get(UsedBorderProperty())) { !GetProperty(UsedBorderProperty())) {
props.Set(UsedBorderProperty(), new nsMargin(oldValue)); SetProperty(UsedBorderProperty(), new nsMargin(oldValue));
} }
} }
} }
@ -961,7 +960,7 @@ nsIFrame::GetUsedMargin() const
IsSVGText()) IsSVGText())
return margin; return margin;
nsMargin *m = Properties().Get(UsedMarginProperty()); nsMargin *m = GetProperty(UsedMarginProperty());
if (m) { if (m) {
margin = *m; margin = *m;
} else { } else {
@ -1000,7 +999,7 @@ nsIFrame::GetUsedBorder() const
return border; return border;
} }
nsMargin *b = Properties().Get(UsedBorderProperty()); nsMargin *b = GetProperty(UsedBorderProperty());
if (b) { if (b) {
border = *b; border = *b;
} else { } else {
@ -1037,7 +1036,7 @@ nsIFrame::GetUsedPadding() const
} }
} }
nsMargin *p = Properties().Get(UsedPaddingProperty()); nsMargin *p = GetProperty(UsedPaddingProperty());
if (p) { if (p) {
padding = *p; padding = *p;
} else { } else {
@ -1478,8 +1477,7 @@ nsIFrame::GetVisibility() const
} }
bool isSet = false; bool isSet = false;
FrameProperties props = Properties(); uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet);
uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value " MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is set"); "if NS_FRAME_VISIBILITY_IS_TRACKED is set");
@ -1552,15 +1550,14 @@ nsIFrame::EnableVisibilityTracking()
return; // Nothing to do. return; // Nothing to do.
} }
FrameProperties props = Properties(); MOZ_ASSERT(!HasProperty(VisibilityStateProperty()),
MOZ_ASSERT(!props.Has(VisibilityStateProperty()),
"Shouldn't have a VisibilityStateProperty value " "Shouldn't have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is not set"); "if NS_FRAME_VISIBILITY_IS_TRACKED is not set");
// Add the state bit so we know to track visibility for this frame, and // Add the state bit so we know to track visibility for this frame, and
// initialize the frame property. // initialize the frame property.
AddStateBits(NS_FRAME_VISIBILITY_IS_TRACKED); AddStateBits(NS_FRAME_VISIBILITY_IS_TRACKED);
props.Set(VisibilityStateProperty(), 0); SetProperty(VisibilityStateProperty(), 0);
nsIPresShell* presShell = PresContext()->PresShell(); nsIPresShell* presShell = PresContext()->PresShell();
if (!presShell) { if (!presShell) {
@ -1582,8 +1579,7 @@ nsIFrame::DisableVisibilityTracking()
} }
bool isSet = false; bool isSet = false;
FrameProperties props = Properties(); uint32_t visibleCount = RemoveProperty(VisibilityStateProperty(), &isSet);
uint32_t visibleCount = props.Remove(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value " MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is set"); "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); MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED);
bool isSet = false; bool isSet = false;
FrameProperties props = Properties(); uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet);
uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value " MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is set"); "if NS_FRAME_VISIBILITY_IS_TRACKED is set");
@ -1614,7 +1609,7 @@ nsIFrame::DecApproximateVisibleCount(Maybe<OnNonvisible> aNonvisibleAction
"decrementing its visible count?"); "decrementing its visible count?");
visibleCount--; visibleCount--;
props.Set(VisibilityStateProperty(), visibleCount); SetProperty(VisibilityStateProperty(), visibleCount);
if (visibleCount > 0) { if (visibleCount > 0) {
return; return;
} }
@ -1629,14 +1624,13 @@ nsIFrame::IncApproximateVisibleCount()
MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED); MOZ_ASSERT(GetStateBits() & NS_FRAME_VISIBILITY_IS_TRACKED);
bool isSet = false; bool isSet = false;
FrameProperties props = Properties(); uint32_t visibleCount = GetProperty(VisibilityStateProperty(), &isSet);
uint32_t visibleCount = props.Get(VisibilityStateProperty(), &isSet);
MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value " MOZ_ASSERT(isSet, "Should have a VisibilityStateProperty value "
"if NS_FRAME_VISIBILITY_IS_TRACKED is set"); "if NS_FRAME_VISIBILITY_IS_TRACKED is set");
visibleCount++; visibleCount++;
props.Set(VisibilityStateProperty(), visibleCount); SetProperty(VisibilityStateProperty(), visibleCount);
if (visibleCount > 1) { if (visibleCount > 1) {
return; return;
} }
@ -4943,10 +4937,9 @@ nsFrame::ComputeSizeWithIntrinsicDimensions(nsRenderingContext* aRenderingConte
// If FlexItemMainSizeOverride frame-property is set, then that means the // 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 // flex container is imposing a main-size on this flex item for it to use
// as its size in the container's main axis. // as its size in the container's main axis.
FrameProperties props = Properties();
bool didImposeMainSize; bool didImposeMainSize;
nscoord imposedMainSize = nscoord imposedMainSize =
props.Get(nsIFrame::FlexItemMainSizeOverride(), &didImposeMainSize); GetProperty(nsIFrame::FlexItemMainSizeOverride(), &didImposeMainSize);
if (didImposeMainSize) { if (didImposeMainSize) {
imposedMainSizeStyleCoord.emplace(imposedMainSize, imposedMainSizeStyleCoord.emplace(imposedMainSize,
nsStyleCoord::CoordConstructor); nsStyleCoord::CoordConstructor);
@ -5686,7 +5679,7 @@ nsIFrame::GetView() const
return nullptr; return nullptr;
// Check for a property on the frame // 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"); NS_ASSERTION(value, "frame state bit was set but frame has no view");
return value; return value;
} }
@ -5709,7 +5702,7 @@ nsIFrame::SetView(nsView* aView)
#endif #endif
// Set a property on the frame // 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 // Set the frame state bit that says the frame has a view
AddStateBits(NS_FRAME_HAS_VIEW); AddStateBits(NS_FRAME_HAS_VIEW);
@ -6098,7 +6091,7 @@ static void InvalidateFrameInternal(nsIFrame *aFrame, bool aHasDisplayItem = tru
SchedulePaintInternal(aFrame); SchedulePaintInternal(aFrame);
} }
if (aFrame->HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) { if (aFrame->HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) {
aFrame->Properties().Delete(nsIFrame::InvalidationRect()); aFrame->DeleteProperty(nsIFrame::InvalidationRect());
aFrame->RemoveStateBits(NS_FRAME_HAS_INVALID_RECT); aFrame->RemoveStateBits(NS_FRAME_HAS_INVALID_RECT);
} }
} }
@ -6173,13 +6166,13 @@ nsIFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemKey)
return; return;
} }
nsRect* rect = Properties().Get(InvalidationRect()); nsRect* rect = GetProperty(InvalidationRect());
if (!rect) { if (!rect) {
if (alreadyInvalid) { if (alreadyInvalid) {
return; return;
} }
rect = new nsRect(); rect = new nsRect();
Properties().Set(InvalidationRect(), rect); SetProperty(InvalidationRect(), rect);
AddStateBits(NS_FRAME_HAS_INVALID_RECT); AddStateBits(NS_FRAME_HAS_INVALID_RECT);
} }
@ -6280,7 +6273,7 @@ nsIFrame::IsInvalid(nsRect& aRect)
} }
if (HasAnyStateBits(NS_FRAME_HAS_INVALID_RECT)) { 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!"); NS_ASSERTION(rect, "Must have an invalid rect if NS_FRAME_HAS_INVALID_RECT is set!");
aRect = *rect; aRect = *rect;
} else { } else {
@ -6368,8 +6361,8 @@ ComputeEffectsRect(nsIFrame* aFrame, const nsRect& aOverflowRect,
// TODO: We could also take account of clipPath and mask to reduce the // TODO: We could also take account of clipPath and mask to reduce the
// visual overflow, but that's not essential. // visual overflow, but that's not essential.
if (aFrame->StyleEffects()->HasFilters()) { if (aFrame->StyleEffects()->HasFilters()) {
aFrame->Properties(). aFrame->SetProperty
Set(nsIFrame::PreEffectsBBoxProperty(), new nsRect(r)); (nsIFrame::PreEffectsBBoxProperty(), new nsRect(r));
r = nsSVGUtils::GetPostFilterVisualOverflowRect(aFrame, aOverflowRect); r = nsSVGUtils::GetPostFilterVisualOverflowRect(aFrame, aOverflowRect);
} }
return r; return r;
@ -6407,8 +6400,8 @@ ComputeEffectsRect(nsIFrame* aFrame, const nsRect& aOverflowRect,
// the frame dies. // the frame dies.
if (nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame)) { if (nsSVGIntegrationUtils::UsingEffectsForFrame(aFrame)) {
aFrame->Properties(). aFrame->SetProperty
Set(nsIFrame::PreEffectsBBoxProperty(), new nsRect(r)); (nsIFrame::PreEffectsBBoxProperty(), new nsRect(r));
r = nsSVGIntegrationUtils::ComputePostEffectsVisualOverflowRect(aFrame, r); r = nsSVGIntegrationUtils::ComputePostEffectsVisualOverflowRect(aFrame, r);
} }
@ -6422,7 +6415,7 @@ nsIFrame::MovePositionBy(const nsPoint& aTranslation)
const nsMargin* computedOffsets = nullptr; const nsMargin* computedOffsets = nullptr;
if (IsRelativelyPositioned()) { if (IsRelativelyPositioned()) {
computedOffsets = Properties().Get(nsIFrame::ComputedOffsetProperty()); computedOffsets = GetProperty(nsIFrame::ComputedOffsetProperty());
} }
ReflowInput::ApplyRelativePositioning(this, computedOffsets ? ReflowInput::ApplyRelativePositioning(this, computedOffsets ?
*computedOffsets : nsMargin(), *computedOffsets : nsMargin(),
@ -6435,7 +6428,7 @@ nsIFrame::GetNormalRect() const
{ {
// It might be faster to first check // It might be faster to first check
// StyleDisplay()->IsRelativelyPositionedStyle(). // StyleDisplay()->IsRelativelyPositionedStyle().
nsPoint* normalPosition = Properties().Get(NormalPositionProperty()); nsPoint* normalPosition = GetProperty(NormalPositionProperty());
if (normalPosition) { if (normalPosition) {
return nsRect(*normalPosition, GetSize()); return nsRect(*normalPosition, GetSize());
} }
@ -6447,7 +6440,7 @@ nsIFrame::GetNormalPosition() const
{ {
// It might be faster to first check // It might be faster to first check
// StyleDisplay()->IsRelativelyPositionedStyle(). // StyleDisplay()->IsRelativelyPositionedStyle().
nsPoint* normalPosition = Properties().Get(NormalPositionProperty()); nsPoint* normalPosition = GetProperty(NormalPositionProperty());
if (normalPosition) { if (normalPosition) {
return *normalPosition; return *normalPosition;
} }
@ -6506,7 +6499,7 @@ nsIFrame::GetOverflowAreasRelativeToSelf() const
{ {
if (IsTransformed()) { if (IsTransformed()) {
nsOverflowAreas* preTransformOverflows = nsOverflowAreas* preTransformOverflows =
Properties().Get(PreTransformOverflowAreasProperty()); GetProperty(PreTransformOverflowAreasProperty());
if (preTransformOverflows) { if (preTransformOverflows) {
return nsOverflowAreas(preTransformOverflows->VisualOverflow(), return nsOverflowAreas(preTransformOverflows->VisualOverflow(),
preTransformOverflows->ScrollableOverflow()); preTransformOverflows->ScrollableOverflow());
@ -6533,7 +6526,7 @@ nsIFrame::GetScrollableOverflowRectRelativeToSelf() const
{ {
if (IsTransformed()) { if (IsTransformed()) {
nsOverflowAreas* preTransformOverflows = nsOverflowAreas* preTransformOverflows =
Properties().Get(PreTransformOverflowAreasProperty()); GetProperty(PreTransformOverflowAreasProperty());
if (preTransformOverflows) if (preTransformOverflows)
return preTransformOverflows->ScrollableOverflow(); return preTransformOverflows->ScrollableOverflow();
} }
@ -6545,7 +6538,7 @@ nsIFrame::GetVisualOverflowRectRelativeToSelf() const
{ {
if (IsTransformed()) { if (IsTransformed()) {
nsOverflowAreas* preTransformOverflows = nsOverflowAreas* preTransformOverflows =
Properties().Get(PreTransformOverflowAreasProperty()); GetProperty(PreTransformOverflowAreasProperty());
if (preTransformOverflows) if (preTransformOverflows)
return preTransformOverflows->VisualOverflow(); return preTransformOverflows->VisualOverflow();
} }
@ -6555,7 +6548,7 @@ nsIFrame::GetVisualOverflowRectRelativeToSelf() const
nsRect nsRect
nsIFrame::GetPreEffectsVisualOverflowRect() const nsIFrame::GetPreEffectsVisualOverflowRect() const
{ {
nsRect* r = Properties().Get(nsIFrame::PreEffectsBBoxProperty()); nsRect* r = GetProperty(nsIFrame::PreEffectsBBoxProperty());
return r ? *r : GetVisualOverflowRectRelativeToSelf(); 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", aTo += nsPrintfCString(" next-%s=%p", fluid?"in-flow":"continuation",
static_cast<void*>(GetNextContinuation())); static_cast<void*>(GetNextContinuation()));
} }
void* IBsibling = Properties().Get(IBSplitSibling()); void* IBsibling = GetProperty(IBSplitSibling());
if (IBsibling) { if (IBsibling) {
aTo += nsPrintfCString(" IBSplitSibling=%p", IBsibling); aTo += nsPrintfCString(" IBSplitSibling=%p", IBsibling);
} }
void* IBprevsibling = Properties().Get(IBSplitPrevSibling()); void* IBprevsibling = GetProperty(IBSplitPrevSibling());
if (IBprevsibling) { if (IBprevsibling) {
aTo += nsPrintfCString(" IBSplitPrevSibling=%p", 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 // If the embedding level isn't set, just use the CSS direction
// property. // property.
bool hasBidiData; bool hasBidiData;
FrameBidiData bidiData = FrameBidiData bidiData = GetProperty(BidiDataProperty(), &hasBidiData);
Properties().Get(BidiDataProperty(), &hasBidiData);
bool isRTL = hasBidiData bool isRTL = hasBidiData
? IS_LEVEL_RTL(bidiData.embeddingLevel) ? IS_LEVEL_RTL(bidiData.embeddingLevel)
: StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL; : StyleVisibility()->mDirection == NS_STYLE_DIRECTION_RTL;
@ -8315,7 +8307,7 @@ nsIFrame::ClearOverflowRects()
return false; return false;
} }
if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) { if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) {
Properties().Delete(OverflowAreasProperty()); DeleteProperty(OverflowAreasProperty());
} }
mOverflow.mType = NS_FRAME_OVERFLOW_NONE; mOverflow.mType = NS_FRAME_OVERFLOW_NONE;
return true; return true;
@ -8328,8 +8320,7 @@ nsIFrame::ClearOverflowRects()
nsOverflowAreas* nsOverflowAreas*
nsIFrame::GetOverflowAreasProperty() nsIFrame::GetOverflowAreasProperty()
{ {
FrameProperties props = Properties(); nsOverflowAreas* overflow = GetProperty(OverflowAreasProperty());
nsOverflowAreas* overflow = props.Get(OverflowAreasProperty());
if (overflow) { if (overflow) {
return overflow; // the property already exists 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, // The property isn't set yet, so allocate a new rect, set the property,
// and return the newly allocated rect // and return the newly allocated rect
overflow = new nsOverflowAreas; overflow = new nsOverflowAreas;
props.Set(OverflowAreasProperty(), overflow); SetProperty(OverflowAreasProperty(), overflow);
return overflow; return overflow;
} }
@ -8349,7 +8340,7 @@ bool
nsIFrame::SetOverflowAreas(const nsOverflowAreas& aOverflowAreas) nsIFrame::SetOverflowAreas(const nsOverflowAreas& aOverflowAreas)
{ {
if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) { if (mOverflow.mType == NS_FRAME_OVERFLOW_LARGE) {
nsOverflowAreas* overflow = Properties().Get(OverflowAreasProperty()); nsOverflowAreas* overflow = GetProperty(OverflowAreasProperty());
bool changed = *overflow != aOverflowAreas; bool changed = *overflow != aOverflowAreas;
*overflow = aOverflowAreas; *overflow = aOverflowAreas;
@ -8593,7 +8584,7 @@ ComputeAndIncludeOutlineArea(nsIFrame* aFrame, nsOverflowAreas& aOverflowAreas,
} }
// Keep this code in sync with GetOutlineInnerRect in nsCSSRendering.cpp. // Keep this code in sync with GetOutlineInnerRect in nsCSSRendering.cpp.
aFrame->Properties().Set(nsIFrame::OutlineInnerRectProperty(), aFrame->SetProperty(nsIFrame::OutlineInnerRectProperty(),
new nsRect(innerRect)); new nsRect(innerRect));
const nscoord offset = outline->mOutlineOffset; const nscoord offset = outline->mOutlineOffset;
nsRect outerRect(innerRect); nsRect outerRect(innerRect);
@ -8635,22 +8626,22 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
if (!aOverflowAreas.VisualOverflow().IsEqualEdges(bounds) || if (!aOverflowAreas.VisualOverflow().IsEqualEdges(bounds) ||
!aOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds)) { !aOverflowAreas.ScrollableOverflow().IsEqualEdges(bounds)) {
nsOverflowAreas* initial = nsOverflowAreas* initial =
Properties().Get(nsIFrame::InitialOverflowProperty()); GetProperty(nsIFrame::InitialOverflowProperty());
if (!initial) { if (!initial) {
Properties().Set(nsIFrame::InitialOverflowProperty(), SetProperty(nsIFrame::InitialOverflowProperty(),
new nsOverflowAreas(aOverflowAreas)); new nsOverflowAreas(aOverflowAreas));
} else if (initial != &aOverflowAreas) { } else if (initial != &aOverflowAreas) {
*initial = aOverflowAreas; *initial = aOverflowAreas;
} }
} else { } else {
Properties().Delete(nsIFrame::InitialOverflowProperty()); DeleteProperty(nsIFrame::InitialOverflowProperty());
} }
#ifdef DEBUG #ifdef DEBUG
Properties().Set(nsIFrame::DebugInitialOverflowPropertyApplied(), true); SetProperty(nsIFrame::DebugInitialOverflowPropertyApplied(), true);
#endif #endif
} else { } else {
#ifdef DEBUG #ifdef DEBUG
Properties().Delete(nsIFrame::DebugInitialOverflowPropertyApplied()); DeleteProperty(nsIFrame::DebugInitialOverflowPropertyApplied());
#endif #endif
} }
@ -8745,8 +8736,8 @@ nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
} }
if (hasTransform) { if (hasTransform) {
Properties().Set(nsIFrame::PreTransformOverflowAreasProperty(), SetProperty(nsIFrame::PreTransformOverflowAreasProperty(),
new nsOverflowAreas(aOverflowAreas)); new nsOverflowAreas(aOverflowAreas));
if (Combines3DTransformWithAncestors()) { if (Combines3DTransformWithAncestors()) {
/* If we're a preserve-3d leaf frame, then our pre-transform overflow should be correct. Our /* 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 { } else {
Properties().Delete(nsIFrame::PreTransformOverflowAreasProperty()); DeleteProperty(nsIFrame::PreTransformOverflowAreasProperty());
} }
/* Revert the size change in case some caller is depending on this. */ /* Revert the size change in case some caller is depending on this. */
@ -8803,7 +8794,7 @@ nsIFrame::RecomputePerspectiveChildrenOverflow(const nsIFrame* aStartFrame)
} }
if (child->HasPerspective()) { if (child->HasPerspective()) {
nsOverflowAreas* overflow = nsOverflowAreas* overflow =
child->Properties().Get(nsIFrame::InitialOverflowProperty()); child->GetProperty(nsIFrame::InitialOverflowProperty());
nsRect bounds(nsPoint(0, 0), child->GetSize()); nsRect bounds(nsPoint(0, 0), child->GetSize());
if (overflow) { if (overflow) {
nsOverflowAreas overflowCopy = *overflow; nsOverflowAreas overflowCopy = *overflow;
@ -8915,7 +8906,7 @@ GetIBSplitSiblingForAnonymousBlock(const nsIFrame* aFrame)
* property. * property.
*/ */
nsIFrame *ibSplitSibling = nsIFrame *ibSplitSibling =
aFrame->Properties().Get(nsIFrame::IBSplitPrevSibling()); aFrame->GetProperty(nsIFrame::IBSplitPrevSibling());
NS_ASSERTION(ibSplitSibling, "Broken frame tree?"); NS_ASSERTION(ibSplitSibling, "Broken frame tree?");
return ibSplitSibling; return ibSplitSibling;
} }
@ -9825,7 +9816,7 @@ nsFrame::BoxReflow(nsBoxLayoutState& aState,
nsBoxLayoutMetrics* nsBoxLayoutMetrics*
nsFrame::BoxMetrics() const 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"); NS_ASSERTION(metrics, "A box layout method was called but InitBoxMetrics was never called");
return metrics; return metrics;
} }
@ -10069,6 +10060,24 @@ nsFrame::HasCSSTransitions()
return collection && collection->mAnimations.Length() > 0; 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 // Box layout debugging
#ifdef DEBUG_REFLOW #ifdef DEBUG_REFLOW
int32_t gIndent2 = 0; int32_t gIndent2 = 0;

View File

@ -2000,7 +2000,7 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput
++fragment; ++fragment;
firstInFlow = pif; firstInFlow = pif;
} }
mSharedGridData = firstInFlow->Properties().Get(SharedGridData::Prop()); mSharedGridData = firstInFlow->GetProperty(SharedGridData::Prop());
MOZ_ASSERT(mSharedGridData, "first-in-flow must have SharedGridData"); MOZ_ASSERT(mSharedGridData, "first-in-flow must have SharedGridData");
// Find the start row for this fragment and undo breaks after that row // 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) && MOZ_ASSERT((aChild->GetStateBits() & NS_FRAME_OUT_OF_FLOW) &&
aChild->IsAbsolutelyPositioned()); 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 " 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"); "container should've reflowed this item by now and set up cb");
return *cb; return *cb;
@ -2836,7 +2836,7 @@ nsGridContainerFrame::AddImplicitNamedAreas(
// Lazily create the ImplicitNamedAreas. // Lazily create the ImplicitNamedAreas.
if (!areas) { if (!areas) {
areas = new ImplicitNamedAreas; areas = new ImplicitNamedAreas;
Properties().Set(ImplicitNamedAreasProperty(), areas); SetProperty(ImplicitNamedAreasProperty(), areas);
} }
mozilla::css::GridNamedArea area; mozilla::css::GridNamedArea area;
@ -2868,7 +2868,7 @@ nsGridContainerFrame::InitImplicitNamedAreas(const nsStylePosition* aStyle)
AddImplicitNamedAreas(aStyle->mGridTemplateColumns.mLineNameLists); AddImplicitNamedAreas(aStyle->mGridTemplateColumns.mLineNameLists);
AddImplicitNamedAreas(aStyle->mGridTemplateRows.mLineNameLists); AddImplicitNamedAreas(aStyle->mGridTemplateRows.mLineNameLists);
if (areas && areas->Count() == 0) { if (areas && areas->Count() == 0) {
Properties().Delete(ImplicitNamedAreasProperty()); DeleteProperty(ImplicitNamedAreasProperty());
} }
} }
@ -3711,7 +3711,7 @@ MeasuringReflow(nsIFrame* aChild,
} }
#ifdef DEBUG #ifdef DEBUG
// This will suppress various CRAZY_SIZE warnings for this reflow. // This will suppress various CRAZY_SIZE warnings for this reflow.
parent->Properties().Set( parent->SetProperty(
nsContainerFrame::DebugReflowingWithInfiniteISize(), true); nsContainerFrame::DebugReflowingWithInfiniteISize(), true);
#endif #endif
auto wm = aChild->GetWritingMode(); auto wm = aChild->GetWritingMode();
@ -3724,10 +3724,10 @@ MeasuringReflow(nsIFrame* aChild,
} }
if (aBMinSizeClamp != NS_MAXSIZE) { if (aBMinSizeClamp != NS_MAXSIZE) {
riFlags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE; riFlags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE;
aChild->Properties().Set(nsIFrame::BClampMarginBoxMinSizeProperty(), aChild->SetProperty(nsIFrame::BClampMarginBoxMinSizeProperty(),
aBMinSizeClamp); aBMinSizeClamp);
} else { } else {
aChild->Properties().Delete(nsIFrame::BClampMarginBoxMinSizeProperty()); aChild->DeleteProperty(nsIFrame::BClampMarginBoxMinSizeProperty());
} }
ReflowInput childRI(pc, *rs, aChild, aAvailableSize, &aCBSize, riFlags); ReflowInput childRI(pc, *rs, aChild, aAvailableSize, &aCBSize, riFlags);
ReflowOutput childSize(childRI); ReflowOutput childSize(childRI);
@ -3738,7 +3738,7 @@ MeasuringReflow(nsIFrame* aChild,
parent->FinishReflowChild(aChild, pc, childSize, &childRI, wm, parent->FinishReflowChild(aChild, pc, childSize, &childRI, wm,
LogicalPoint(wm), nsSize(), flags); LogicalPoint(wm), nsSize(), flags);
#ifdef DEBUG #ifdef DEBUG
parent->Properties().Delete(nsContainerFrame::DebugReflowingWithInfiniteISize()); parent->DeleteProperty(nsContainerFrame::DebugReflowingWithInfiniteISize());
#endif #endif
return childSize.BSize(wm); return childSize.BSize(wm);
} }
@ -5253,9 +5253,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
baselineAdjust = -baselineAdjust; baselineAdjust = -baselineAdjust;
} }
if (baselineAdjust != nscoord(0)) { if (baselineAdjust != nscoord(0)) {
aChild->Properties().Set(aProp, baselineAdjust); aChild->SetProperty(aProp, baselineAdjust);
} else { } else {
aChild->Properties().Delete(aProp); aChild->DeleteProperty(aProp);
} }
}; };
SetProp(eLogicalAxisBlock, isOrthogonal ? IBaselinePadProperty() : SetProp(eLogicalAxisBlock, isOrthogonal ? IBaselinePadProperty() :
@ -5292,10 +5292,10 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
auto childBAxis = GetOrthogonalAxis(childIAxis); auto childBAxis = GetOrthogonalAxis(childIAxis);
if (aGridItemInfo->mState[childBAxis] & ItemState::eClampMarginBoxMinSize) { if (aGridItemInfo->mState[childBAxis] & ItemState::eClampMarginBoxMinSize) {
flags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE; flags |= ReflowInput::B_CLAMP_MARGIN_BOX_MIN_SIZE;
aChild->Properties().Set(BClampMarginBoxMinSizeProperty(), aChild->SetProperty(BClampMarginBoxMinSizeProperty(),
childCBSize.BSize(childWM)); childCBSize.BSize(childWM));
} else { } else {
aChild->Properties().Delete(BClampMarginBoxMinSizeProperty()); aChild->DeleteProperty(BClampMarginBoxMinSizeProperty());
} }
if ((aGridItemInfo->mState[childIAxis] & ItemState::eApplyAutoMinSize)) { if ((aGridItemInfo->mState[childIAxis] & ItemState::eApplyAutoMinSize)) {
flags |= ReflowInput::I_APPLY_AUTO_MIN_SIZE; 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 // A table-wrapper needs to propagate the CB size we give it to its
// inner table frame later. @see nsTableWrapperFrame::InitChildReflowInput. // inner table frame later. @see nsTableWrapperFrame::InitChildReflowInput.
if (childType == nsGkAtoms::tableWrapperFrame) { if (childType == nsGkAtoms::tableWrapperFrame) {
const auto& props = aChild->Properties(); LogicalSize* cb =
LogicalSize* cb = props.Get(nsTableWrapperFrame::GridItemCBSizeProperty()); aChild->GetProperty(nsTableWrapperFrame::GridItemCBSizeProperty());
if (!cb) { if (!cb) {
cb = new LogicalSize(childWM); cb = new LogicalSize(childWM);
props.Set(nsTableWrapperFrame::GridItemCBSizeProperty(), cb); aChild->SetProperty(nsTableWrapperFrame::GridItemCBSizeProperty(), cb);
} }
*cb = percentBasis; *cb = percentBasis;
} }
@ -5337,9 +5337,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild,
} }
} }
if (stretch) { if (stretch) {
aChild->Properties().Set(FragStretchBSizeProperty(), *aStretchBSize); aChild->SetProperty(FragStretchBSizeProperty(), *aStretchBSize);
} else { } else {
aChild->Properties().Delete(FragStretchBSizeProperty()); aChild->DeleteProperty(FragStretchBSizeProperty());
} }
} }
@ -5951,10 +5951,10 @@ nsGridContainerFrame::ReflowChildren(GridReflowInput& aState,
LogicalRect itemCB = LogicalRect itemCB =
aState.ContainingBlockForAbsPos(area, gridOrigin, gridCB); aState.ContainingBlockForAbsPos(area, gridOrigin, gridCB);
// nsAbsoluteContainingBlock::Reflow uses physical coordinates. // nsAbsoluteContainingBlock::Reflow uses physical coordinates.
nsRect* cb = child->Properties().Get(GridItemContainingBlockRect()); nsRect* cb = child->GetProperty(GridItemContainingBlockRect());
if (!cb) { if (!cb) {
cb = new nsRect; cb = new nsRect;
child->Properties().Set(GridItemContainingBlockRect(), cb); child->SetProperty(GridItemContainingBlockRect(), cb);
} }
*cb = itemCB.GetPhysicalRect(wm, gridCBPhysicalSize); *cb = itemCB.GetPhysicalRect(wm, gridCBPhysicalSize);
} }
@ -6044,7 +6044,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
f = next; f = next;
} }
if (overflowContainers->IsEmpty()) { if (overflowContainers->IsEmpty()) {
Properties().Delete(OverflowContainersProperty()); DeleteProperty(OverflowContainersProperty());
} }
MergeSortedExcessOverflowContainers(moveToEOC); MergeSortedExcessOverflowContainers(moveToEOC);
} }
@ -6355,7 +6355,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(colTrackStates), Move(colTrackStates),
Move(colRemovedRepeatTracks), Move(colRemovedRepeatTracks),
gridReflowInput.mColFunctions.mRepeatAutoStart); gridReflowInput.mColFunctions.mRepeatAutoStart);
Properties().Set(GridColTrackInfo(), colInfo); SetProperty(GridColTrackInfo(), colInfo);
uint32_t rowTrackCount = gridReflowInput.mRows.mSizes.Length(); uint32_t rowTrackCount = gridReflowInput.mRows.mSizes.Length();
nsTArray<nscoord> rowTrackPositions(rowTrackCount); nsTArray<nscoord> rowTrackPositions(rowTrackCount);
@ -6390,7 +6390,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(rowTrackStates), Move(rowTrackStates),
Move(rowRemovedRepeatTracks), Move(rowRemovedRepeatTracks),
gridReflowInput.mRowFunctions.mRepeatAutoStart); gridReflowInput.mRowFunctions.mRepeatAutoStart);
Properties().Set(GridRowTrackInfo(), rowInfo); SetProperty(GridRowTrackInfo(), rowInfo);
if (prevInFlow) { if (prevInFlow) {
// This frame is fragmenting rows from a previous frame, so patch up // 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. // FIXME: This can be streamlined and/or removed when bug 1151204 lands.
ComputedGridTrackInfo* priorRowInfo = ComputedGridTrackInfo* priorRowInfo =
prevInFlow->Properties().Get(GridRowTrackInfo()); prevInFlow->GetProperty(GridRowTrackInfo());
// Adjust track positions based on the first track in this fragment. // Adjust track positions based on the first track in this fragment.
if (priorRowInfo->mPositions.Length() > if (priorRowInfo->mPositions.Length() >
@ -6421,7 +6421,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(priorRowInfo->mStates), Move(priorRowInfo->mStates),
Move(priorRowInfo->mRemovedRepeatTracks), Move(priorRowInfo->mRemovedRepeatTracks),
priorRowInfo->mRepeatFirstTrack); priorRowInfo->mRepeatFirstTrack);
prevInFlow->Properties().Set(GridRowTrackInfo(), revisedPriorRowInfo); prevInFlow->SetProperty(GridRowTrackInfo(), revisedPriorRowInfo);
} }
// Generate the line info properties. We need to provide the number of // Generate the line info properties. We need to provide the number of
@ -6448,7 +6448,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(columnLineNames), Move(columnLineNames),
gridColTemplate.mRepeatAutoLineNameListBefore, gridColTemplate.mRepeatAutoLineNameListBefore,
gridColTemplate.mRepeatAutoLineNameListAfter); gridColTemplate.mRepeatAutoLineNameListAfter);
Properties().Set(GridColumnLineInfo(), columnLineInfo); SetProperty(GridColumnLineInfo(), columnLineInfo);
// Generate row lines next. // Generate row lines next.
capacity = gridReflowInput.mRows.mSizes.Length(); capacity = gridReflowInput.mRows.mSizes.Length();
@ -6469,25 +6469,25 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
Move(rowLineNames), Move(rowLineNames),
gridRowTemplate.mRepeatAutoLineNameListBefore, gridRowTemplate.mRepeatAutoLineNameListBefore,
gridRowTemplate.mRepeatAutoLineNameListAfter); gridRowTemplate.mRepeatAutoLineNameListAfter);
Properties().Set(GridRowLineInfo(), rowLineInfo); SetProperty(GridRowLineInfo(), rowLineInfo);
// Generate area info for explicit areas. Implicit areas are handled // Generate area info for explicit areas. Implicit areas are handled
// elsewhere. // elsewhere.
if (gridReflowInput.mGridStyle->mGridTemplateAreas) { if (gridReflowInput.mGridStyle->mGridTemplateAreas) {
nsTArray<css::GridNamedArea>* areas = new nsTArray<css::GridNamedArea>( nsTArray<css::GridNamedArea>* areas = new nsTArray<css::GridNamedArea>(
gridReflowInput.mGridStyle->mGridTemplateAreas->mNamedAreas); gridReflowInput.mGridStyle->mGridTemplateAreas->mNamedAreas);
Properties().Set(ExplicitNamedAreasProperty(), areas); SetProperty(ExplicitNamedAreasProperty(), areas);
} else { } else {
Properties().Delete(ExplicitNamedAreasProperty()); DeleteProperty(ExplicitNamedAreasProperty());
} }
} }
if (!prevInFlow) { if (!prevInFlow) {
SharedGridData* sharedGridData = Properties().Get(SharedGridData::Prop()); SharedGridData* sharedGridData = GetProperty(SharedGridData::Prop());
if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) { if (!NS_FRAME_IS_FULLY_COMPLETE(aStatus)) {
if (!sharedGridData) { if (!sharedGridData) {
sharedGridData = new SharedGridData; sharedGridData = new SharedGridData;
Properties().Set(SharedGridData::Prop(), sharedGridData); SetProperty(SharedGridData::Prop(), sharedGridData);
} }
sharedGridData->mCols.mSizes.Clear(); sharedGridData->mCols.mSizes.Clear();
sharedGridData->mCols.mSizes.SwapElements(gridReflowInput.mCols.mSizes); sharedGridData->mCols.mSizes.SwapElements(gridReflowInput.mCols.mSizes);
@ -6522,7 +6522,7 @@ nsGridContainerFrame::Reflow(nsPresContext* aPresContext,
sharedGridData->mGenerateComputedGridInfo = sharedGridData->mGenerateComputedGridInfo =
HasAnyStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES); HasAnyStateBits(NS_STATE_GRID_GENERATE_COMPUTED_VALUES);
} else if (sharedGridData && !GetNextInFlow()) { } else if (sharedGridData && !GetNextInFlow()) {
Properties().Delete(SharedGridData::Prop()); DeleteProperty(SharedGridData::Prop());
} }
} }
@ -7142,10 +7142,10 @@ nsGridContainerFrame::GetGridFrameWithComputedInfo(nsIFrame* aFrame)
nsGridContainerFrame* gridFrame = GetGridContainerFrame(aFrame); nsGridContainerFrame* gridFrame = GetGridContainerFrame(aFrame);
if (gridFrame) { if (gridFrame) {
// if any of our properties are missing, generate them // if any of our properties are missing, generate them
bool reflowNeeded = (!gridFrame->Properties().Has(GridColTrackInfo()) || bool reflowNeeded = (!gridFrame->HasProperty(GridColTrackInfo()) ||
!gridFrame->Properties().Has(GridRowTrackInfo()) || !gridFrame->HasProperty(GridRowTrackInfo()) ||
!gridFrame->Properties().Has(GridColumnLineInfo()) || !gridFrame->HasProperty(GridColumnLineInfo()) ||
!gridFrame->Properties().Has(GridRowLineInfo())); !gridFrame->HasProperty(GridRowLineInfo()));
if (reflowNeeded) { if (reflowNeeded) {
// Trigger a reflow that generates additional grid property data. // Trigger a reflow that generates additional grid property data.
@ -7161,13 +7161,13 @@ nsGridContainerFrame::GetGridFrameWithComputedInfo(nsIFrame* aFrame)
// Assert the grid properties are present // Assert the grid properties are present
MOZ_ASSERT(!gridFrame || MOZ_ASSERT(!gridFrame ||
gridFrame->Properties().Has(GridColTrackInfo())); gridFrame->HasProperty(GridColTrackInfo()));
MOZ_ASSERT(!gridFrame || MOZ_ASSERT(!gridFrame ||
gridFrame->Properties().Has(GridRowTrackInfo())); gridFrame->HasProperty(GridRowTrackInfo()));
MOZ_ASSERT(!gridFrame || MOZ_ASSERT(!gridFrame ||
gridFrame->Properties().Has(GridColumnLineInfo())); gridFrame->HasProperty(GridColumnLineInfo()));
MOZ_ASSERT(!gridFrame || MOZ_ASSERT(!gridFrame ||
gridFrame->Properties().Has(GridRowLineInfo())); gridFrame->HasProperty(GridRowLineInfo()));
} }
} }

View File

@ -164,7 +164,7 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColTrackInfo, ComputedGridTrackInfo) NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColTrackInfo, ComputedGridTrackInfo)
const ComputedGridTrackInfo* GetComputedTemplateColumns() const ComputedGridTrackInfo* GetComputedTemplateColumns()
{ {
const ComputedGridTrackInfo* info = Properties().Get(GridColTrackInfo()); const ComputedGridTrackInfo* info = GetProperty(GridColTrackInfo());
MOZ_ASSERT(info, "Property generation wasn't requested."); MOZ_ASSERT(info, "Property generation wasn't requested.");
return info; return info;
} }
@ -172,7 +172,7 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowTrackInfo, ComputedGridTrackInfo) NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowTrackInfo, ComputedGridTrackInfo)
const ComputedGridTrackInfo* GetComputedTemplateRows() const ComputedGridTrackInfo* GetComputedTemplateRows()
{ {
const ComputedGridTrackInfo* info = Properties().Get(GridRowTrackInfo()); const ComputedGridTrackInfo* info = GetProperty(GridRowTrackInfo());
MOZ_ASSERT(info, "Property generation wasn't requested."); MOZ_ASSERT(info, "Property generation wasn't requested.");
return info; return info;
} }
@ -180,7 +180,7 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColumnLineInfo, ComputedGridLineInfo) NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridColumnLineInfo, ComputedGridLineInfo)
const ComputedGridLineInfo* GetComputedTemplateColumnLines() const ComputedGridLineInfo* GetComputedTemplateColumnLines()
{ {
const ComputedGridLineInfo* info = Properties().Get(GridColumnLineInfo()); const ComputedGridLineInfo* info = GetProperty(GridColumnLineInfo());
MOZ_ASSERT(info, "Property generation wasn't requested."); MOZ_ASSERT(info, "Property generation wasn't requested.");
return info; return info;
} }
@ -188,7 +188,7 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowLineInfo, ComputedGridLineInfo) NS_DECLARE_FRAME_PROPERTY_DELETABLE(GridRowLineInfo, ComputedGridLineInfo)
const ComputedGridLineInfo* GetComputedTemplateRowLines() const ComputedGridLineInfo* GetComputedTemplateRowLines()
{ {
const ComputedGridLineInfo* info = Properties().Get(GridRowLineInfo()); const ComputedGridLineInfo* info = GetProperty(GridRowLineInfo());
MOZ_ASSERT(info, "Property generation wasn't requested."); MOZ_ASSERT(info, "Property generation wasn't requested.");
return info; return info;
} }
@ -199,14 +199,14 @@ public:
NS_DECLARE_FRAME_PROPERTY_DELETABLE(ImplicitNamedAreasProperty, NS_DECLARE_FRAME_PROPERTY_DELETABLE(ImplicitNamedAreasProperty,
ImplicitNamedAreas) ImplicitNamedAreas)
ImplicitNamedAreas* GetImplicitNamedAreas() const { ImplicitNamedAreas* GetImplicitNamedAreas() const {
return Properties().Get(ImplicitNamedAreasProperty()); return GetProperty(ImplicitNamedAreasProperty());
} }
typedef nsTArray<mozilla::css::GridNamedArea> ExplicitNamedAreas; typedef nsTArray<mozilla::css::GridNamedArea> ExplicitNamedAreas;
NS_DECLARE_FRAME_PROPERTY_DELETABLE(ExplicitNamedAreasProperty, NS_DECLARE_FRAME_PROPERTY_DELETABLE(ExplicitNamedAreasProperty,
ExplicitNamedAreas) ExplicitNamedAreas)
ExplicitNamedAreas* GetExplicitNamedAreas() const { ExplicitNamedAreas* GetExplicitNamedAreas() const {
return Properties().Get(ExplicitNamedAreasProperty()); return GetProperty(ExplicitNamedAreasProperty());
} }
/** /**

View File

@ -24,7 +24,7 @@
#include <stdio.h> #include <stdio.h>
#include "CaretAssociationHint.h" #include "CaretAssociationHint.h"
#include "FramePropertyTable.h" #include "FrameProperties.h"
#include "mozilla/layout/FrameChildList.h" #include "mozilla/layout/FrameChildList.h"
#include "mozilla/Maybe.h" #include "mozilla/Maybe.h"
#include "mozilla/WritingModes.h" #include "mozilla/WritingModes.h"
@ -997,7 +997,7 @@ public:
#define NS_DECLARE_FRAME_PROPERTY_WITH_DTOR_NEVER_CALLED(prop, type) \ #define NS_DECLARE_FRAME_PROPERTY_WITH_DTOR_NEVER_CALLED(prop, type) \
static void AssertOnDestroyingProperty##prop(type*) { \ static void AssertOnDestroyingProperty##prop(type*) { \
MOZ_ASSERT_UNREACHABLE("Frame property " #prop " should never " \ 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, \ NS_DECLARE_FRAME_PROPERTY_WITH_DTOR(prop, type, \
AssertOnDestroyingProperty##prop) AssertOnDestroyingProperty##prop)
@ -1005,8 +1005,8 @@ public:
#define NS_DECLARE_FRAME_PROPERTY_SMALL_VALUE(prop, type) \ #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(prop, mozilla::SmallValueHolder<type>)
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitSibling, nsIFrame) NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitSibling, nsContainerFrame)
NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitPrevSibling, nsIFrame) NS_DECLARE_FRAME_PROPERTY_WITHOUT_DTOR(IBSplitPrevSibling, nsContainerFrame)
NS_DECLARE_FRAME_PROPERTY_DELETABLE(NormalPositionProperty, nsPoint) NS_DECLARE_FRAME_PROPERTY_DELETABLE(NormalPositionProperty, nsPoint)
NS_DECLARE_FRAME_PROPERTY_DELETABLE(ComputedOffsetProperty, nsMargin) NS_DECLARE_FRAME_PROPERTY_DELETABLE(ComputedOffsetProperty, nsMargin)
@ -1059,7 +1059,7 @@ public:
mozilla::FrameBidiData GetBidiData() mozilla::FrameBidiData GetBidiData()
{ {
return Properties().Get(BidiDataProperty()); return GetProperty(BidiDataProperty());
} }
nsBidiLevel GetBaseLevel() nsBidiLevel GetBaseLevel()
@ -1073,7 +1073,7 @@ public:
} }
nsTArray<nsIContent*>* GetGenConPseudos() { nsTArray<nsIContent*>* GetGenConPseudos() {
return Properties().Get(GenConProperty()); return GetProperty(GenConProperty());
} }
/** /**
@ -1534,7 +1534,7 @@ public:
bool RefusedAsyncAnimation() const bool RefusedAsyncAnimation() const
{ {
return Properties().Get(RefusedAsyncAnimationProperty()); return GetProperty(RefusedAsyncAnimationProperty());
} }
/** /**
@ -3061,9 +3061,53 @@ public:
return mContent == aParentContent; 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. * Return true if and only if this frame obeys visibility:hidden.
@ -3423,7 +3467,7 @@ public:
*/ */
bool FrameIsNonFirstInIBSplit() const { bool FrameIsNonFirstInIBSplit() const {
return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) && return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
FirstContinuation()->Properties().Get(nsIFrame::IBSplitPrevSibling()); FirstContinuation()->GetProperty(nsIFrame::IBSplitPrevSibling());
} }
/** /**
@ -3432,7 +3476,7 @@ public:
*/ */
bool FrameIsNonLastInIBSplit() const { bool FrameIsNonLastInIBSplit() const {
return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) && return (GetStateBits() & NS_FRAME_PART_OF_IBSPLIT) &&
FirstContinuation()->Properties().Get(nsIFrame::IBSplitSibling()); FirstContinuation()->GetProperty(nsIFrame::IBSplitSibling());
} }
/** /**
@ -3514,11 +3558,11 @@ private:
DestroyPaintedPresShellList) DestroyPaintedPresShellList)
nsTArray<nsWeakPtr>* PaintedPresShellList() { nsTArray<nsWeakPtr>* PaintedPresShellList() {
nsTArray<nsWeakPtr>* list = Properties().Get(PaintedPresShellsProperty()); nsTArray<nsWeakPtr>* list = GetProperty(PaintedPresShellsProperty());
if (!list) { if (!list) {
list = new nsTArray<nsWeakPtr>(); list = new nsTArray<nsWeakPtr>();
Properties().Set(PaintedPresShellsProperty(), list); SetProperty(PaintedPresShellsProperty(), list);
} }
return list; return list;
@ -3535,6 +3579,11 @@ protected:
nsFrameState mState; nsFrameState mState;
/**
* List of properties attached to the frame.
*/
FrameProperties mProperties;
// When there is an overflow area only slightly larger than mRect, // 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 // we store a set of four 1-byte deltas from the edges of mRect
// rather than allocating a whole separate rectangle property. // rather than allocating a whole separate rectangle property.

View File

@ -819,11 +819,11 @@ nsLineLayout::ReflowFrame(nsIFrame* aFrame,
#endif #endif
if (mCurrentSpan == mRootSpan) { if (mCurrentSpan == mRootSpan) {
pfd->mFrame->Properties().Remove(nsIFrame::LineBaselineOffset()); pfd->mFrame->RemoveProperty(nsIFrame::LineBaselineOffset());
} else { } else {
#ifdef DEBUG #ifdef DEBUG
bool hasLineOffset; 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"); NS_ASSERTION(!hasLineOffset, "LineBaselineOffset was set but was not expected");
#endif #endif
} }

View File

@ -128,7 +128,7 @@ nsPlaceholderFrame::Reflow(nsPresContext* aPresContext,
nsIFrame* ancestor = this; nsIFrame* ancestor = this;
while ((ancestor = ancestor->GetParent())) { while ((ancestor = ancestor->GetParent())) {
if (ancestor->GetPrevContinuation() || if (ancestor->GetPrevContinuation() ||
ancestor->Properties().Get(IBSplitPrevSibling())) { ancestor->GetProperty(IBSplitPrevSibling())) {
isInContinuationOrIBSplit = true; isInContinuationOrIBSplit = true;
break; break;
} }

View File

@ -2838,9 +2838,9 @@ nsTextFrame::EnsureTextRun(TextRunType aWhichTextRun,
return gfxSkipCharsIterator(gfxPlatform:: return gfxSkipCharsIterator(gfxPlatform::
GetPlatform()->EmptySkipChars(), 0); GetPlatform()->EmptySkipChars(), 0);
} }
TabWidthStore* tabWidths = Properties().Get(TabWidthProperty()); TabWidthStore* tabWidths = GetProperty(TabWidthProperty());
if (tabWidths && tabWidths->mValidForContentOffset != GetContentOffset()) { if (tabWidths && tabWidths->mValidForContentOffset != GetContentOffset()) {
Properties().Delete(TabWidthProperty()); DeleteProperty(TabWidthProperty());
} }
} }
@ -3478,7 +3478,7 @@ PropertyProvider::CalcTabWidths(Range aRange)
return; return;
} }
if (!mReflowing) { if (!mReflowing) {
mTabWidths = mFrame->Properties().Get(TabWidthProperty()); mTabWidths = mFrame->GetProperty(TabWidthProperty());
#ifdef DEBUG #ifdef DEBUG
// If we're not reflowing, we should have already computed the // If we're not reflowing, we should have already computed the
// tab widths; check that they're available as far as the last // tab widths; check that they're available as far as the last
@ -3524,7 +3524,7 @@ PropertyProvider::CalcTabWidths(Range aRange)
} else { } else {
if (!mTabWidths) { if (!mTabWidths) {
mTabWidths = new TabWidthStore(mFrame->GetContentOffset()); mTabWidths = new TabWidthStore(mFrame->GetContentOffset());
mFrame->Properties().Set(TabWidthProperty(), mTabWidths); mFrame->SetProperty(TabWidthProperty(), mTabWidths);
} }
double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs, double nextTab = AdvanceToNextTab(mOffsetFromBlockOriginForTabs,
mFrame, mTextRun, &tabWidth); mFrame, mTextRun, &tabWidth);
@ -3543,7 +3543,7 @@ PropertyProvider::CalcTabWidths(Range aRange)
if (!mTabWidths) { if (!mTabWidths) {
// Delete any stale property that may be left on the frame // Delete any stale property that may be left on the frame
mFrame->Properties().Delete(TabWidthProperty()); mFrame->DeleteProperty(TabWidthProperty());
mTabWidthsAnalyzedLimit = std::max(mTabWidthsAnalyzedLimit, mTabWidthsAnalyzedLimit = std::max(mTabWidthsAnalyzedLimit,
aRange.end - startOffset); aRange.end - startOffset);
} }
@ -4249,7 +4249,7 @@ nsTextFrame::ClearFrameOffsetCache()
// just destroys the frames in order, which means that the primary frame is already // 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 // 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. // 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); RemoveStateBits(TEXT_IN_OFFSET_CACHE);
} }
@ -4358,7 +4358,7 @@ nsContinuingTextFrame::Init(nsIContent* aContent,
if (aPrevInFlow->GetStateBits() & NS_FRAME_IS_BIDI) { if (aPrevInFlow->GetStateBits() & NS_FRAME_IS_BIDI) {
FrameBidiData bidiData = aPrevInFlow->GetBidiData(); FrameBidiData bidiData = aPrevInFlow->GetBidiData();
bidiData.precedingControl = kBidiLevelNone; bidiData.precedingControl = kBidiLevelNone;
Properties().Set(BidiDataProperty(), bidiData); SetProperty(BidiDataProperty(), bidiData);
if (nextContinuation) { if (nextContinuation) {
SetNextContinuation(nextContinuation); SetNextContinuation(nextContinuation);
@ -4622,7 +4622,7 @@ nsTextFrame::InvalidateFrameWithRect(const nsRect& aRect, uint32_t aDisplayItemK
gfxTextRun* gfxTextRun*
nsTextFrame::GetUninflatedTextRun() nsTextFrame::GetUninflatedTextRun()
{ {
return Properties().Get(UninflatedTextRunProperty()); return GetProperty(UninflatedTextRunProperty());
} }
void void
@ -4648,7 +4648,7 @@ nsTextFrame::SetTextRun(gfxTextRun* aTextRun, TextRunType aWhichTextRun,
// Setting the property will not automatically increment the textrun's // Setting the property will not automatically increment the textrun's
// reference count, so we need to do it here. // reference count, so we need to do it here.
aTextRun->AddRef(); aTextRun->AddRef();
Properties().Set(UninflatedTextRunProperty(), aTextRun); SetProperty(UninflatedTextRunProperty(), aTextRun);
return; return;
} }
// fall through to setting mTextRun // fall through to setting mTextRun
@ -4668,10 +4668,9 @@ nsTextFrame::RemoveTextRun(gfxTextRun* aTextRun)
mTextRun = nullptr; mTextRun = nullptr;
return true; return true;
} }
FrameProperties props = Properties();
if ((GetStateBits() & TEXT_HAS_FONT_INFLATION) && if ((GetStateBits() & TEXT_HAS_FONT_INFLATION) &&
props.Get(UninflatedTextRunProperty()) == aTextRun) { GetProperty(UninflatedTextRunProperty()) == aTextRun) {
props.Delete(UninflatedTextRunProperty()); DeleteProperty(UninflatedTextRunProperty());
return true; return true;
} }
return false; return false;
@ -4689,7 +4688,7 @@ nsTextFrame::ClearTextRun(nsTextFrame* aStartContinuation,
DebugOnly<bool> checkmTextrun = textRun == mTextRun; DebugOnly<bool> checkmTextrun = textRun == mTextRun;
UnhookTextRunFromFrames(textRun, aStartContinuation); UnhookTextRunFromFrames(textRun, aStartContinuation);
MOZ_ASSERT(checkmTextrun ? !mTextRun MOZ_ASSERT(checkmTextrun ? !mTextRun
: !Properties().Get(UninflatedTextRunProperty())); : !GetProperty(UninflatedTextRunProperty()));
} }
void void
@ -4699,7 +4698,7 @@ nsTextFrame::DisconnectTextRuns()
"Textrun mentions this frame in its user data so we can't just disconnect"); "Textrun mentions this frame in its user data so we can't just disconnect");
mTextRun = nullptr; mTextRun = nullptr;
if ((GetStateBits() & TEXT_HAS_FONT_INFLATION)) { 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 static float
GetTextCombineScaleFactor(nsTextFrame* aFrame) GetTextCombineScaleFactor(nsTextFrame* aFrame)
{ {
float factor = aFrame->Properties().Get(TextCombineScaleFactorProperty()); float factor = aFrame->GetProperty(TextCombineScaleFactorProperty());
return factor ? factor : 1.0f; return factor ? factor : 1.0f;
} }
@ -5105,7 +5104,7 @@ static nscoord
LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame) LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame)
{ {
bool offsetFound; bool offsetFound;
nscoord offset = aChildFrame->Properties().Get( nscoord offset = aChildFrame->GetProperty(
nsIFrame::LineBaselineOffset(), &offsetFound); nsIFrame::LineBaselineOffset(), &offsetFound);
if (!offsetFound) { if (!offsetFound) {
@ -5118,11 +5117,11 @@ LazyGetLineBaselineOffset(nsIFrame* aChildFrame, nsBlockFrame* aBlockFrame)
for (nsIFrame* lineFrame = line->mFirstChild; for (nsIFrame* lineFrame = line->mFirstChild;
n > 0; lineFrame = lineFrame->GetNextSibling(), --n) { n > 0; lineFrame = lineFrame->GetNextSibling(), --n) {
offset = lineBaseline - lineFrame->GetNormalPosition().y; 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); nsIFrame::LineBaselineOffset(), &offsetFound);
} else { } else {
return offset; return offset;
@ -5367,7 +5366,7 @@ nsTextFrame::UpdateTextEmphasis(WritingMode aWM, PropertyProvider& aProvider)
{ {
const nsStyleText* styleText = StyleText(); const nsStyleText* styleText = StyleText();
if (!styleText->HasTextEmphasis()) { if (!styleText->HasTextEmphasis()) {
Properties().Delete(EmphasisMarkProperty()); DeleteProperty(EmphasisMarkProperty());
return nsRect(); return nsRect();
} }
@ -5419,7 +5418,7 @@ nsTextFrame::UpdateTextEmphasis(WritingMode aWM, PropertyProvider& aProvider)
overflowRect.BStart(aWM) += gap * (side == eLogicalSideBStart ? -1 : 1); overflowRect.BStart(aWM) += gap * (side == eLogicalSideBStart ? -1 : 1);
} }
Properties().Set(EmphasisMarkProperty(), info); SetProperty(EmphasisMarkProperty(), info);
return overflowRect.GetPhysicalRect(aWM, frameSize.GetPhysicalSize(aWM)); return overflowRect.GetPhysicalRect(aWM, frameSize.GetPhysicalSize(aWM));
} }
@ -6432,7 +6431,7 @@ nsTextFrame::DrawEmphasisMarks(gfxContext* aContext, WritingMode aWM,
const nscolor* aDecorationOverrideColor, const nscolor* aDecorationOverrideColor,
PropertyProvider* aProvider) PropertyProvider* aProvider)
{ {
const EmphasisMarkInfo* info = Properties().Get(EmphasisMarkProperty()); const EmphasisMarkInfo* info = GetProperty(EmphasisMarkProperty());
if (!info) { if (!info) {
return; return;
} }
@ -7584,7 +7583,7 @@ nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset,
int32_t offset = mContentOffset; int32_t offset = mContentOffset;
// Try to look up the offset to frame property // Try to look up the offset to frame property
nsTextFrame* cachedFrame = Properties().Get(OffsetToFrameProperty()); nsTextFrame* cachedFrame = GetProperty(OffsetToFrameProperty());
if (cachedFrame) { if (cachedFrame) {
f = cachedFrame; f = cachedFrame;
@ -7632,7 +7631,7 @@ nsTextFrame::GetChildFrameContainingOffset(int32_t aContentOffset,
*aOutFrame = f; *aOutFrame = f;
// cache the frame we found // cache the frame we found
Properties().Set(OffsetToFrameProperty(), f); SetProperty(OffsetToFrameProperty(), f);
f->AddStateBits(TEXT_IN_OFFSET_CACHE); f->AddStateBits(TEXT_IN_OFFSET_CACHE);
return NS_OK; return NS_OK;
@ -8169,7 +8168,7 @@ nsTextFrame::GetFontSizeInflation() const
if (!HasFontSizeInflation()) { if (!HasFontSizeInflation()) {
return 1.0f; return 1.0f;
} }
return Properties().Get(FontSizeInflationProperty()); return GetProperty(FontSizeInflationProperty());
} }
void void
@ -8178,13 +8177,13 @@ nsTextFrame::SetFontSizeInflation(float aInflation)
if (aInflation == 1.0f) { if (aInflation == 1.0f) {
if (HasFontSizeInflation()) { if (HasFontSizeInflation()) {
RemoveStateBits(TEXT_HAS_FONT_INFLATION); RemoveStateBits(TEXT_HAS_FONT_INFLATION);
Properties().Delete(FontSizeInflationProperty()); DeleteProperty(FontSizeInflationProperty());
} }
return; return;
} }
AddStateBits(TEXT_HAS_FONT_INFLATION); AddStateBits(TEXT_HAS_FONT_INFLATION);
Properties().Set(FontSizeInflationProperty(), aInflation); SetProperty(FontSizeInflationProperty(), aInflation);
} }
/* virtual */ /* virtual */
@ -9319,9 +9318,9 @@ nsTextFrame::ReflowText(nsLineLayout& aLineLayout, nscoord aAvailableWidth,
gfxFloat em = fm->EmHeight(); gfxFloat em = fm->EmHeight();
// Compress the characters in horizontal axis if necessary. // Compress the characters in horizontal axis if necessary.
if (width <= em) { if (width <= em) {
Properties().Remove(TextCombineScaleFactorProperty()); RemoveProperty(TextCombineScaleFactorProperty());
} else { } else {
Properties().Set(TextCombineScaleFactorProperty(), em / width); SetProperty(TextCombineScaleFactorProperty(), em / width);
finalSize.ISize(wm) = em; finalSize.ISize(wm) = em;
} }
// Make the characters be in an 1em square. // Make the characters be in an 1em square.
@ -10049,13 +10048,13 @@ nsTextFrame::AssignJustificationGaps(
static_assert(sizeof(aAssign) == 1, static_assert(sizeof(aAssign) == 1,
"The encoding might be broken if JustificationAssignment " "The encoding might be broken if JustificationAssignment "
"is larger than 1 byte"); "is larger than 1 byte");
Properties().Set(JustificationAssignmentProperty(), encoded); SetProperty(JustificationAssignmentProperty(), encoded);
} }
mozilla::JustificationAssignment mozilla::JustificationAssignment
nsTextFrame::GetJustificationAssignment() const nsTextFrame::GetJustificationAssignment() const
{ {
int32_t encoded = Properties().Get(JustificationAssignmentProperty()); int32_t encoded = GetProperty(JustificationAssignmentProperty());
mozilla::JustificationAssignment result; mozilla::JustificationAssignment result;
result.mGapsAtStart = encoded >> 8; result.mGapsAtStart = encoded >> 8;
result.mGapsAtEnd = encoded & 0xFF; result.mGapsAtEnd = encoded & 0xFF;

View File

@ -134,7 +134,7 @@ nsMathMLContainerFrame::SaveReflowAndBoundingMetricsFor(nsIFrame*
{ {
ReflowOutput* reflowOutput = new ReflowOutput(aReflowOutput); ReflowOutput* reflowOutput = new ReflowOutput(aReflowOutput);
reflowOutput->mBoundingMetrics = aBoundingMetrics; reflowOutput->mBoundingMetrics = aBoundingMetrics;
aFrame->Properties().Set(HTMLReflowOutputProperty(), reflowOutput); aFrame->SetProperty(HTMLReflowOutputProperty(), reflowOutput);
} }
// helper method to facilitate getting the reflow and bounding metrics // helper method to facilitate getting the reflow and bounding metrics
@ -147,7 +147,7 @@ nsMathMLContainerFrame::GetReflowAndBoundingMetricsFor(nsIFrame* aFra
NS_PRECONDITION(aFrame, "null arg"); NS_PRECONDITION(aFrame, "null arg");
ReflowOutput* reflowOutput = ReflowOutput* reflowOutput =
aFrame->Properties().Get(HTMLReflowOutputProperty()); aFrame->GetProperty(HTMLReflowOutputProperty());
// IMPORTANT: This function is only meant to be called in Place() methods // IMPORTANT: This function is only meant to be called in Place() methods
// where it is assumed that SaveReflowAndBoundingMetricsFor has recorded the // where it is assumed that SaveReflowAndBoundingMetricsFor has recorded the
@ -175,9 +175,8 @@ void
nsMathMLContainerFrame::ClearSavedChildMetrics() nsMathMLContainerFrame::ClearSavedChildMetrics()
{ {
nsIFrame* childFrame = mFrames.FirstChild(); nsIFrame* childFrame = mFrames.FirstChild();
FramePropertyTable* props = PresContext()->PropertyTable();
while (childFrame) { while (childFrame) {
props->Delete(childFrame, HTMLReflowOutputProperty()); childFrame->DeleteProperty(HTMLReflowOutputProperty());
childFrame = childFrame->GetNextSibling(); childFrame = childFrame->GetNextSibling();
} }
} }

View File

@ -167,8 +167,7 @@ FindCellProperty(const nsIFrame* aCellFrame,
nsTArray<int8_t>* propertyData = nullptr; nsTArray<int8_t>* propertyData = nullptr;
while (currentFrame) { while (currentFrame) {
FrameProperties props = currentFrame->Properties(); propertyData = currentFrame->GetProperty(aFrameProperty);
propertyData = props.Get(aFrameProperty);
bool frameIsTable = (currentFrame->GetType() == nsGkAtoms::tableFrame); bool frameIsTable = (currentFrame->GetType() == nsGkAtoms::tableFrame);
if (propertyData || frameIsTable) if (propertyData || frameIsTable)
@ -361,8 +360,7 @@ ParseFrameAttribute(nsIFrame* aFrame,
if (valueList) { if (valueList) {
// The code reading the property assumes that this list is nonempty. // The code reading the property assumes that this list is nonempty.
NS_ASSERTION(valueList->Length() >= 1, "valueList should not be empty!"); NS_ASSERTION(valueList->Length() >= 1, "valueList should not be empty!");
FrameProperties props = aFrame->Properties(); aFrame->SetProperty(AttributeToProperty(aAttribute), valueList);
props.Set(AttributeToProperty(aAttribute), valueList);
} else { } else {
ReportParseError(aFrame, aAttribute->GetUTF16String(), attrValue.get()); ReportParseError(aFrame, aAttribute->GetUTF16String(), attrValue.get());
} }
@ -769,8 +767,7 @@ nsMathMLmtableWrapperFrame::AttributeChanged(int32_t aNameSpaceID,
aAttribute == nsGkAtoms::columnalign_ || aAttribute == nsGkAtoms::columnalign_ ||
aAttribute == nsGkAtoms::columnlines_) { aAttribute == nsGkAtoms::columnlines_) {
// clear any cached property list for this table // clear any cached property list for this table
presContext->PropertyTable()-> tableFrame->DeleteProperty(AttributeToProperty(aAttribute));
Delete(tableFrame, AttributeToProperty(aAttribute));
// Reparse the new attribute on the table. // Reparse the new attribute on the table.
ParseFrameAttribute(tableFrame, aAttribute, true); ParseFrameAttribute(tableFrame, aAttribute, true);
} else { } else {
@ -1120,7 +1117,7 @@ nsMathMLmtrFrame::AttributeChanged(int32_t aNameSpaceID,
return NS_OK; return NS_OK;
} }
presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute)); DeleteProperty(AttributeToProperty(aAttribute));
bool allowMultiValues = (aAttribute == nsGkAtoms::columnalign_); bool allowMultiValues = (aAttribute == nsGkAtoms::columnalign_);
@ -1219,8 +1216,7 @@ nsMathMLmtdFrame::AttributeChanged(int32_t aNameSpaceID,
if (aAttribute == nsGkAtoms::rowalign_ || if (aAttribute == nsGkAtoms::rowalign_ ||
aAttribute == nsGkAtoms::columnalign_) { aAttribute == nsGkAtoms::columnalign_) {
nsPresContext* presContext = PresContext(); DeleteProperty(AttributeToProperty(aAttribute));
presContext->PropertyTable()->Delete(this, AttributeToProperty(aAttribute));
// Reparse the attribute. // Reparse the attribute.
ParseFrameAttribute(this, aAttribute, false); ParseFrameAttribute(this, aAttribute, false);

View File

@ -1328,7 +1328,7 @@ NS_DECLARE_FRAME_PROPERTY_DELETABLE(TextNodeCorrespondenceProperty,
static uint32_t static uint32_t
GetUndisplayedCharactersBeforeFrame(nsTextFrame* aFrame) GetUndisplayedCharactersBeforeFrame(nsTextFrame* aFrame)
{ {
void* value = aFrame->Properties().Get(TextNodeCorrespondenceProperty()); void* value = aFrame->GetProperty(TextNodeCorrespondenceProperty());
TextNodeCorrespondence* correspondence = TextNodeCorrespondence* correspondence =
static_cast<TextNodeCorrespondence*>(value); static_cast<TextNodeCorrespondence*>(value);
if (!correspondence) { if (!correspondence) {
@ -1517,8 +1517,8 @@ TextNodeCorrespondenceRecorder::TraverseAndRecord(nsIFrame* aFrame)
} }
// Set the frame property. // Set the frame property.
frame->Properties().Set(TextNodeCorrespondenceProperty(), frame->SetProperty(TextNodeCorrespondenceProperty(),
new TextNodeCorrespondence(undisplayed)); new TextNodeCorrespondence(undisplayed));
// Remember how far into the current nsTextNode we are. // Remember how far into the current nsTextNode we are.
mNodeCharIndex = frame->GetContentEnd(); mNodeCharIndex = frame->GetContentEnd();
@ -3391,7 +3391,7 @@ SVGTextFrame::HandleAttributeChangeInDescendant(Element* aElement,
// Blow away our reference, if any // Blow away our reference, if any
nsIFrame* childElementFrame = aElement->GetPrimaryFrame(); nsIFrame* childElementFrame = aElement->GetPrimaryFrame();
if (childElementFrame) { if (childElementFrame) {
childElementFrame->Properties().Delete( childElementFrame->DeleteProperty(
nsSVGEffects::HrefAsTextPathProperty()); nsSVGEffects::HrefAsTextPathProperty());
NotifyGlyphMetricsChange(); NotifyGlyphMetricsChange();
} }
@ -4817,7 +4817,7 @@ SVGPathElement*
SVGTextFrame::GetTextPathPathElement(nsIFrame* aTextPathFrame) SVGTextFrame::GetTextPathPathElement(nsIFrame* aTextPathFrame)
{ {
nsSVGTextPathProperty *property = nsSVGTextPathProperty *property =
aTextPathFrame->Properties().Get(nsSVGEffects::HrefAsTextPathProperty()); aTextPathFrame->GetProperty(nsSVGEffects::HrefAsTextPathProperty());
if (!property) { if (!property) {
nsIContent* content = aTextPathFrame->GetContent(); nsIContent* content = aTextPathFrame->GetContent();

View File

@ -480,27 +480,26 @@ GetOrCreateFilterProperty(nsIFrame* aFrame)
if (!effects->HasFilters()) if (!effects->HasFilters())
return nullptr; return nullptr;
FrameProperties props = aFrame->Properties(); nsSVGFilterProperty *prop =
nsSVGFilterProperty *prop = props.Get(nsSVGEffects::FilterProperty()); aFrame->GetProperty(nsSVGEffects::FilterProperty());
if (prop) if (prop)
return prop; return prop;
prop = new nsSVGFilterProperty(effects->mFilters, aFrame); prop = new nsSVGFilterProperty(effects->mFilters, aFrame);
NS_ADDREF(prop); NS_ADDREF(prop);
props.Set(nsSVGEffects::FilterProperty(), prop); aFrame->SetProperty(nsSVGEffects::FilterProperty(), prop);
return prop; return prop;
} }
static nsSVGMaskProperty* static nsSVGMaskProperty*
GetOrCreateMaskProperty(nsIFrame* aFrame) GetOrCreateMaskProperty(nsIFrame* aFrame)
{ {
FrameProperties props = aFrame->Properties(); nsSVGMaskProperty *prop = aFrame->GetProperty(nsSVGEffects::MaskProperty());
nsSVGMaskProperty *prop = props.Get(nsSVGEffects::MaskProperty());
if (prop) if (prop)
return prop; return prop;
prop = new nsSVGMaskProperty(aFrame); prop = new nsSVGMaskProperty(aFrame);
NS_ADDREF(prop); NS_ADDREF(prop);
props.Set(nsSVGEffects::MaskProperty(), prop); aFrame->SetProperty(nsSVGEffects::MaskProperty(), prop);
return prop; return prop;
} }
@ -512,13 +511,12 @@ GetEffectProperty(nsIURI* aURI, nsIFrame* aFrame,
if (!aURI) if (!aURI)
return nullptr; return nullptr;
FrameProperties props = aFrame->Properties(); T* prop = aFrame->GetProperty(aProperty);
T* prop = props.Get(aProperty);
if (prop) if (prop)
return prop; return prop;
prop = new T(aURI, aFrame, false); prop = new T(aURI, aFrame, false);
NS_ADDREF(prop); NS_ADDREF(prop);
props.Set(aProperty, prop); aFrame->SetProperty(aProperty, prop);
return prop; return prop;
} }
@ -553,11 +551,11 @@ nsSVGEffects::GetPaintingPropertyForURI(nsIURI* aURI, nsIFrame* aFrame,
if (!aURI) if (!aURI)
return nullptr; return nullptr;
FrameProperties props = aFrame->Properties(); nsSVGEffects::URIObserverHashtable *hashtable =
nsSVGEffects::URIObserverHashtable *hashtable = props.Get(aProperty); aFrame->GetProperty(aProperty);
if (!hashtable) { if (!hashtable) {
hashtable = new nsSVGEffects::URIObserverHashtable(); hashtable = new nsSVGEffects::URIObserverHashtable();
props.Set(aProperty, hashtable); aFrame->SetProperty(aProperty, hashtable);
} }
nsSVGPaintingProperty* prop = nsSVGPaintingProperty* prop =
static_cast<nsSVGPaintingProperty*>(hashtable->GetWeak(aURI)); static_cast<nsSVGPaintingProperty*>(hashtable->GetWeak(aURI));
@ -689,16 +687,15 @@ nsSVGEffects::UpdateEffects(nsIFrame* aFrame)
NS_ASSERTION(aFrame->GetContent()->IsElement(), NS_ASSERTION(aFrame->GetContent()->IsElement(),
"aFrame's content should be an element"); "aFrame's content should be an element");
FrameProperties props = aFrame->Properties(); aFrame->DeleteProperty(FilterProperty());
props.Delete(FilterProperty()); aFrame->DeleteProperty(MaskProperty());
props.Delete(MaskProperty()); aFrame->DeleteProperty(ClipPathProperty());
props.Delete(ClipPathProperty()); aFrame->DeleteProperty(MarkerBeginProperty());
props.Delete(MarkerBeginProperty()); aFrame->DeleteProperty(MarkerMiddleProperty());
props.Delete(MarkerMiddleProperty()); aFrame->DeleteProperty(MarkerEndProperty());
props.Delete(MarkerEndProperty()); aFrame->DeleteProperty(FillProperty());
props.Delete(FillProperty()); aFrame->DeleteProperty(StrokeProperty());
props.Delete(StrokeProperty()); aFrame->DeleteProperty(BackgroundImageProperty());
props.Delete(BackgroundImageProperty());
// Ensure that the filter is repainted correctly // Ensure that the filter is repainted correctly
// We can't do that in DoUpdate as the referenced frame may not be valid // 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()) if (!aFrame->StyleEffects()->HasFilters())
return nullptr; return nullptr;
return aFrame->Properties().Get(FilterProperty()); return aFrame->GetProperty(FilterProperty());
} }
void void
@ -835,7 +832,7 @@ nsSVGEffects::InvalidateRenderingObservers(nsIFrame* aFrame)
return; return;
// If the rendering has changed, the bounds may well have changed too: // If the rendering has changed, the bounds may well have changed too:
aFrame->Properties().Delete(nsSVGUtils::ObjectBoundingBoxProperty()); aFrame->DeleteProperty(nsSVGUtils::ObjectBoundingBoxProperty());
nsSVGRenderingObserverList *observerList = nsSVGRenderingObserverList *observerList =
GetObserverList(content->AsElement()); GetObserverList(content->AsElement());
@ -864,7 +861,7 @@ nsSVGEffects::InvalidateDirectRenderingObservers(Element* aElement, uint32_t aFl
nsIFrame* frame = aElement->GetPrimaryFrame(); nsIFrame* frame = aElement->GetPrimaryFrame();
if (frame) { if (frame) {
// If the rendering has changed, the bounds may well have changed too: // If the rendering has changed, the bounds may well have changed too:
frame->Properties().Delete(nsSVGUtils::ObjectBoundingBoxProperty()); frame->DeleteProperty(nsSVGUtils::ObjectBoundingBoxProperty());
} }
if (aElement->HasRenderingObservers()) { if (aElement->HasRenderingObservers()) {

View File

@ -7,7 +7,7 @@
#define NSSVGEFFECTS_H_ #define NSSVGEFFECTS_H_
#include "mozilla/Attributes.h" #include "mozilla/Attributes.h"
#include "FramePropertyTable.h" #include "FrameProperties.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "nsHashKeys.h" #include "nsHashKeys.h"
#include "nsID.h" #include "nsID.h"

View File

@ -107,7 +107,7 @@ nsSVGFilterFrame::GetReferencedFilter()
return nullptr; return nullptr;
nsSVGPaintingProperty *property = nsSVGPaintingProperty *property =
Properties().Get(nsSVGEffects::HrefAsPaintingProperty()); GetProperty(nsSVGEffects::HrefAsPaintingProperty());
if (!property) { if (!property) {
// Fetch our Filter element's href or xlink:href attribute // Fetch our Filter element's href or xlink:href attribute
@ -183,7 +183,7 @@ nsSVGFilterFrame::AttributeChanged(int32_t aNameSpaceID,
aNameSpaceID == kNameSpaceID_None) && aNameSpaceID == kNameSpaceID_None) &&
aAttribute == nsGkAtoms::href) { aAttribute == nsGkAtoms::href) {
// Blow away our reference, if any // Blow away our reference, if any
Properties().Delete(nsSVGEffects::HrefAsPaintingProperty()); DeleteProperty(nsSVGEffects::HrefAsPaintingProperty());
mNoHRefURI = false; mNoHRefURI = false;
// And update whoever references us // And update whoever references us
nsSVGEffects::InvalidateDirectRenderingObservers(this); nsSVGEffects::InvalidateDirectRenderingObservers(this);

View File

@ -72,7 +72,7 @@ nsSVGGradientFrame::AttributeChanged(int32_t aNameSpaceID,
aNameSpaceID == kNameSpaceID_None) && aNameSpaceID == kNameSpaceID_None) &&
aAttribute == nsGkAtoms::href) { aAttribute == nsGkAtoms::href) {
// Blow away our reference, if any // Blow away our reference, if any
Properties().Delete(nsSVGEffects::HrefAsPaintingProperty()); DeleteProperty(nsSVGEffects::HrefAsPaintingProperty());
mNoHRefURI = false; mNoHRefURI = false;
// And update whoever references us // And update whoever references us
nsSVGEffects::InvalidateDirectRenderingObservers(this); nsSVGEffects::InvalidateDirectRenderingObservers(this);
@ -316,7 +316,7 @@ nsSVGGradientFrame::GetReferencedGradient()
return nullptr; return nullptr;
nsSVGPaintingProperty *property = nsSVGPaintingProperty *property =
Properties().Get(nsSVGEffects::HrefAsPaintingProperty()); GetProperty(nsSVGEffects::HrefAsPaintingProperty());
if (!property) { if (!property) {
// Fetch our gradient element's href or xlink:href attribute // Fetch our gradient element's href or xlink:href attribute

View File

@ -75,7 +75,7 @@ public:
private: private:
static nsRect GetPreEffectsVisualOverflowRect(nsIFrame* aFrame) { static nsRect GetPreEffectsVisualOverflowRect(nsIFrame* aFrame) {
nsRect* r = aFrame->Properties().Get(nsIFrame::PreEffectsBBoxProperty()); nsRect* r = aFrame->GetProperty(nsIFrame::PreEffectsBBoxProperty());
if (r) { if (r) {
return *r; return *r;
} }
@ -113,8 +113,7 @@ private:
NS_ASSERTION(aFrame->GetParent()->StyleContext()->GetPseudo() == NS_ASSERTION(aFrame->GetParent()->StyleContext()->GetPseudo() ==
nsCSSAnonBoxes::mozAnonymousBlock, nsCSSAnonBoxes::mozAnonymousBlock,
"How did we getting here, then?"); "How did we getting here, then?");
NS_ASSERTION(!aFrame->Properties().Get( NS_ASSERTION(!aFrame->GetProperty(aFrame->PreTransformOverflowAreasProperty()),
aFrame->PreTransformOverflowAreasProperty()),
"GetVisualOverflowRect() won't return the pre-effects rect!"); "GetVisualOverflowRect() won't return the pre-effects rect!");
return aFrame->GetVisualOverflowRect(); return aFrame->GetVisualOverflowRect();
} }

View File

@ -89,7 +89,7 @@ nsSVGPatternFrame::AttributeChanged(int32_t aNameSpaceID,
aNameSpaceID == kNameSpaceID_None) && aNameSpaceID == kNameSpaceID_None) &&
aAttribute == nsGkAtoms::href) { aAttribute == nsGkAtoms::href) {
// Blow away our reference, if any // Blow away our reference, if any
Properties().Delete(nsSVGEffects::HrefAsPaintingProperty()); DeleteProperty(nsSVGEffects::HrefAsPaintingProperty());
mNoHRefURI = false; mNoHRefURI = false;
// And update whoever references us // And update whoever references us
nsSVGEffects::InvalidateDirectRenderingObservers(this); nsSVGEffects::InvalidateDirectRenderingObservers(this);
@ -548,7 +548,7 @@ nsSVGPatternFrame::GetReferencedPattern()
return nullptr; return nullptr;
nsSVGPaintingProperty *property = nsSVGPaintingProperty *property =
Properties().Get(nsSVGEffects::HrefAsPaintingProperty()); GetProperty(nsSVGEffects::HrefAsPaintingProperty());
if (!property) { if (!property) {
// Fetch our pattern element's href or xlink:href attribute // Fetch our pattern element's href or xlink:href attribute

View File

@ -1060,10 +1060,9 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags)
return bbox; return bbox;
} }
FrameProperties props = aFrame->Properties();
if (aFlags == eBBoxIncludeFillGeometry) { if (aFlags == eBBoxIncludeFillGeometry) {
gfxRect* prop = props.Get(ObjectBoundingBoxProperty()); gfxRect* prop = aFrame->GetProperty(ObjectBoundingBoxProperty());
if (prop) { if (prop) {
return *prop; return *prop;
} }
@ -1139,7 +1138,7 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags)
if (aFlags == eBBoxIncludeFillGeometry) { if (aFlags == eBBoxIncludeFillGeometry) {
// Obtaining the bbox for objectBoundingBox calculations is common so we // Obtaining the bbox for objectBoundingBox calculations is common so we
// cache the result for future calls, since calculation can be expensive: // 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; return bbox;

View File

@ -272,13 +272,12 @@ nsTableFrame::RegisterPositionedTablePart(nsIFrame* aFrame)
tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation()); tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation());
// Retrieve the positioned parts array for this table. // Retrieve the positioned parts array for this table.
FrameProperties props = tableFrame->Properties(); FrameTArray* positionedParts = tableFrame->GetProperty(PositionedTablePartArray());
FrameTArray* positionedParts = props.Get(PositionedTablePartArray());
// Lazily create the array if it doesn't exist yet. // Lazily create the array if it doesn't exist yet.
if (!positionedParts) { if (!positionedParts) {
positionedParts = new FrameTArray; positionedParts = new FrameTArray;
props.Set(PositionedTablePartArray(), positionedParts); tableFrame->SetProperty(PositionedTablePartArray(), positionedParts);
} }
// Add this frame to the list. // Add this frame to the list.
@ -302,8 +301,7 @@ nsTableFrame::UnregisterPositionedTablePart(nsIFrame* aFrame,
tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation()); tableFrame = static_cast<nsTableFrame*>(tableFrame->FirstContinuation());
// Retrieve the positioned parts array for this table. // Retrieve the positioned parts array for this table.
FrameProperties props = tableFrame->Properties(); FrameTArray* positionedParts = tableFrame->GetProperty(PositionedTablePartArray());
FrameTArray* positionedParts = props.Get(PositionedTablePartArray());
// Remove the frame. // Remove the frame.
MOZ_ASSERT(positionedParts && positionedParts->Contains(aFrame), MOZ_ASSERT(positionedParts && positionedParts->Contains(aFrame),
@ -1992,7 +1990,7 @@ nsTableFrame::FixupPositionedTableParts(nsPresContext* aPresContext,
ReflowOutput& aDesiredSize, ReflowOutput& aDesiredSize,
const ReflowInput& aReflowInput) const ReflowInput& aReflowInput)
{ {
FrameTArray* positionedParts = Properties().Get(PositionedTablePartArray()); FrameTArray* positionedParts = GetProperty(PositionedTablePartArray());
if (!positionedParts) { if (!positionedParts) {
return; return;
} }
@ -2653,13 +2651,18 @@ nsTableFrame::GetUsedMargin() const
NS_DECLARE_FRAME_PROPERTY_DELETABLE(TableBCProperty, BCPropertyData) NS_DECLARE_FRAME_PROPERTY_DELETABLE(TableBCProperty, BCPropertyData)
BCPropertyData* BCPropertyData*
nsTableFrame::GetBCProperty(bool aCreateIfNecessary) const nsTableFrame::GetBCProperty() const
{ {
FrameProperties props = Properties(); return GetProperty(TableBCProperty());
BCPropertyData* value = props.Get(TableBCProperty()); }
if (!value && aCreateIfNecessary) {
BCPropertyData*
nsTableFrame::GetOrCreateBCProperty()
{
BCPropertyData* value = GetProperty(TableBCProperty());
if (!value) {
value = new BCPropertyData(); value = new BCPropertyData();
props.Set(TableBCProperty(), value); SetProperty(TableBCProperty(), value);
} }
return value; return value;
@ -4103,7 +4106,7 @@ nsTableFrame::AddBCDamageArea(const TableArea& aValue)
SetNeedToCalcBCBorders(true); SetNeedToCalcBCBorders(true);
// Get the property // Get the property
BCPropertyData* value = GetBCProperty(true); BCPropertyData* value = GetOrCreateBCProperty();
if (value) { if (value) {
#ifdef DEBUG #ifdef DEBUG
VerifyNonNegativeDamageRect(value->mDamageArea); VerifyNonNegativeDamageRect(value->mDamageArea);
@ -4143,7 +4146,7 @@ nsTableFrame::SetFullBCDamageArea()
SetNeedToCalcBCBorders(true); SetNeedToCalcBCBorders(true);
BCPropertyData* value = GetBCProperty(true); BCPropertyData* value = GetOrCreateBCProperty();
if (value) { if (value) {
value->mDamageArea = TableArea(0, 0, GetColCount(), GetRowCount()); value->mDamageArea = TableArea(0, 0, GetColCount(), GetRowCount());
} }
@ -4310,7 +4313,7 @@ BCMapCellInfo::BCMapCellInfo(nsTableFrame* aTableFrame)
: mTableFrame(aTableFrame) : mTableFrame(aTableFrame)
, mNumTableRows(aTableFrame->GetRowCount()) , mNumTableRows(aTableFrame->GetRowCount())
, mNumTableCols(aTableFrame->GetColCount()) , mNumTableCols(aTableFrame->GetColCount())
, mTableBCData(mTableFrame->Properties().Get(TableBCProperty())) , mTableBCData(mTableFrame->GetProperty(TableBCProperty()))
, mTableWM(aTableFrame->StyleContext()) , mTableWM(aTableFrame->StyleContext())
{ {
ResetCellInfo(); ResetCellInfo();

View File

@ -809,7 +809,8 @@ protected:
void SetBorderCollapse(bool aValue); void SetBorderCollapse(bool aValue);
BCPropertyData* GetBCProperty(bool aCreateIfNecessary = false) const; BCPropertyData* GetBCProperty() const;
BCPropertyData* GetOrCreateBCProperty();
void SetFullBCDamageArea(); void SetFullBCDamageArea();
void CalcBCBorders(); void CalcBCBorders();

View File

@ -978,7 +978,7 @@ nsTableRowFrame::ReflowChildren(nsPresContext* aPresContext,
// MovePositionBy does internally. (This codepath should really // MovePositionBy does internally. (This codepath should really
// be merged into the else below if we can.) // be merged into the else below if we can.)
nsMargin* computedOffsetProp = nsMargin* computedOffsetProp =
kidFrame->Properties().Get(nsIFrame::ComputedOffsetProperty()); kidFrame->GetProperty(nsIFrame::ComputedOffsetProperty());
// Bug 975644: a position:sticky kid can end up with a null // Bug 975644: a position:sticky kid can end up with a null
// property value here. // property value here.
LogicalMargin computedOffsets(wm, computedOffsetProp ? LogicalMargin computedOffsets(wm, computedOffsetProp ?
@ -1417,16 +1417,14 @@ nsTableRowFrame::SetUnpaginatedBSize(nsPresContext* aPresContext,
nscoord aValue) nscoord aValue)
{ {
NS_ASSERTION(!GetPrevInFlow(), "program error"); NS_ASSERTION(!GetPrevInFlow(), "program error");
// Get the property // Set the property
aPresContext->PropertyTable()-> SetProperty(RowUnpaginatedHeightProperty(), aValue);
Set(this, RowUnpaginatedHeightProperty(), aValue);
} }
nscoord nscoord
nsTableRowFrame::GetUnpaginatedBSize() nsTableRowFrame::GetUnpaginatedBSize()
{ {
FrameProperties props = FirstInFlow()->Properties(); return GetProperty(RowUnpaginatedHeightProperty());
return props.Get(RowUnpaginatedHeightProperty());
} }
void nsTableRowFrame::SetContinuousBCBorderWidth(LogicalSide aForSide, void nsTableRowFrame::SetContinuousBCBorderWidth(LogicalSide aForSide,

View File

@ -1910,7 +1910,7 @@ nsTableRowGroupFrame::ClearRowCursor()
} }
RemoveStateBits(NS_ROWGROUP_HAS_ROW_CURSOR); RemoveStateBits(NS_ROWGROUP_HAS_ROW_CURSOR);
Properties().Delete(RowCursorProperty()); DeleteProperty(RowCursorProperty());
} }
nsTableRowGroupFrame::FrameCursorData* nsTableRowGroupFrame::FrameCursorData*
@ -1934,7 +1934,7 @@ nsTableRowGroupFrame::SetupRowCursor()
FrameCursorData* data = new FrameCursorData(); FrameCursorData* data = new FrameCursorData();
if (!data) if (!data)
return nullptr; return nullptr;
Properties().Set(RowCursorProperty(), data); SetProperty(RowCursorProperty(), data);
AddStateBits(NS_ROWGROUP_HAS_ROW_CURSOR); AddStateBits(NS_ROWGROUP_HAS_ROW_CURSOR);
return data; return data;
} }
@ -1946,7 +1946,7 @@ nsTableRowGroupFrame::GetFirstRowContaining(nscoord aY, nscoord* aOverflowAbove)
return nullptr; return nullptr;
} }
FrameCursorData* property = Properties().Get(RowCursorProperty()); FrameCursorData* property = GetProperty(RowCursorProperty());
uint32_t cursorIndex = property->mCursorIndex; uint32_t cursorIndex = property->mCursorIndex;
uint32_t frameCount = property->mFrames.Length(); uint32_t frameCount = property->mFrames.Length();
if (cursorIndex >= frameCount) if (cursorIndex >= frameCount)

View File

@ -246,7 +246,7 @@ nsTableWrapperFrame::InitChildReflowInput(nsPresContext& aPresContext,
} }
// Propagate our stored CB size if present, minus any margins. // Propagate our stored CB size if present, minus any margins.
if (!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) { if (!HasAnyStateBits(NS_FRAME_OUT_OF_FLOW)) {
LogicalSize* cb = Properties().Get(GridItemCBSizeProperty()); LogicalSize* cb = GetProperty(GridItemCBSizeProperty());
if (cb) { if (cb) {
cbSize.emplace(*cb); cbSize.emplace(*cb);
*cbSize -= aReflowInput.ComputedLogicalMargin().Size(wm); *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 // 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 // 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. // 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) { if (NS_UNCONSTRAINEDSIZE != aOuterRI.AvailableBSize() || cbSize) {
nscoord captionBSize = 0; nscoord captionBSize = 0;
nscoord captionISize = 0; nscoord captionISize = 0;

View File

@ -144,10 +144,9 @@ nsBox::BeginXULLayout(nsBoxLayoutState& aState)
// Another copy-over from ReflowInput. // Another copy-over from ReflowInput.
// Since we are in reflow, we don't need to store these properties anymore. // Since we are in reflow, we don't need to store these properties anymore.
FrameProperties props = Properties(); DeleteProperty(UsedBorderProperty());
props.Delete(UsedBorderProperty()); DeleteProperty(UsedPaddingProperty());
props.Delete(UsedPaddingProperty()); DeleteProperty(UsedMarginProperty());
props.Delete(UsedMarginProperty());
#ifdef DEBUG_LAYOUT #ifdef DEBUG_LAYOUT
PropagateDebug(aState); PropagateDebug(aState);

View File

@ -273,7 +273,7 @@ nsMenuFrame::GetPopupList() const
if (!HasPopup()) { if (!HasPopup()) {
return nullptr; return nullptr;
} }
nsFrameList* prop = Properties().Get(PopupListProperty()); nsFrameList* prop = GetProperty(PopupListProperty());
NS_ASSERTION(prop && prop->GetLength() == 1 && NS_ASSERTION(prop && prop->GetLength() == 1 &&
prop->FirstChild()->GetType() == nsGkAtoms::menuPopupFrame, prop->FirstChild()->GetType() == nsGkAtoms::menuPopupFrame,
"popup list should have exactly one nsMenuPopupFrame"); "popup list should have exactly one nsMenuPopupFrame");
@ -284,7 +284,7 @@ void
nsMenuFrame::DestroyPopupList() nsMenuFrame::DestroyPopupList()
{ {
NS_ASSERTION(HasPopup(), "huh?"); NS_ASSERTION(HasPopup(), "huh?");
nsFrameList* prop = Properties().Remove(PopupListProperty()); nsFrameList* prop = RemoveProperty(PopupListProperty());
NS_ASSERTION(prop && prop->IsEmpty(), NS_ASSERTION(prop && prop->IsEmpty(),
"popup list must exist and be empty when destroying"); "popup list must exist and be empty when destroying");
RemoveStateBits(NS_STATE_MENU_HAS_POPUP_LIST); 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. // Remove the frame from the list and store it in a nsFrameList* property.
aFrameList.RemoveFrame(popupFrame); aFrameList.RemoveFrame(popupFrame);
nsFrameList* popupList = new (PresContext()->PresShell()) nsFrameList(popupFrame, popupFrame); nsFrameList* popupList = new (PresContext()->PresShell()) nsFrameList(popupFrame, popupFrame);
Properties().Set(PopupListProperty(), popupList); SetProperty(PopupListProperty(), popupList);
AddStateBits(NS_STATE_MENU_HAS_POPUP_LIST); AddStateBits(NS_STATE_MENU_HAS_POPUP_LIST);
break; break;
} }