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