Bug 1793826 Part 1 - Change nsFrameList::ExtractHead and ExtractTail to take nsIFrame* argument. r=emilio
This is a preparation to remove nsFrameList::FrameLinkEnumerator in the next part. Differential Revision: https://phabricator.services.mozilla.com/D158700
This commit is contained in:
@@ -11007,13 +11007,17 @@ nsIFrame* nsCSSFrameConstructor::ConstructInline(
|
||||
ConstructFramesFromItemList(aState, aItem.mChildItems, newFrame,
|
||||
/* aParentIsWrapperAnonBox = */ false, childList);
|
||||
|
||||
nsFrameList::FrameLinkEnumerator firstBlockEnumerator(childList);
|
||||
nsIFrame* firstBlock = nullptr;
|
||||
if (!aItem.mIsAllInline) {
|
||||
firstBlockEnumerator.Find(
|
||||
[](nsIFrame* aFrame) { return aFrame->IsBlockOutside(); });
|
||||
for (nsIFrame* f : childList) {
|
||||
if (f->IsBlockOutside()) {
|
||||
firstBlock = f;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (aItem.mIsAllInline || firstBlockEnumerator.AtEnd()) {
|
||||
if (aItem.mIsAllInline || !firstBlock) {
|
||||
// This part is easy. We either already know we have no non-inline kids,
|
||||
// or haven't found any when constructing actual frames (the latter can
|
||||
// happen only if out-of-flows that we thought had no containing block
|
||||
@@ -11029,7 +11033,7 @@ nsIFrame* nsCSSFrameConstructor::ConstructInline(
|
||||
// has to be chopped into several pieces, as described above.
|
||||
|
||||
// Grab the first inline's kids
|
||||
nsFrameList firstInlineKids = childList.ExtractHead(firstBlockEnumerator);
|
||||
nsFrameList firstInlineKids = childList.ExtractHead(firstBlock);
|
||||
newFrame->SetInitialChildList(kPrincipalList, firstInlineKids);
|
||||
|
||||
aFrameList.AppendFrame(nullptr, newFrame);
|
||||
|
||||
@@ -733,10 +733,8 @@ static bool RemoveFirstLine(nsLineList& aFromLines, nsFrameList& aFromFrames,
|
||||
*aOutLine = removedLine;
|
||||
nsLineList_iterator next = aFromLines.erase(removedLine);
|
||||
bool isLastLine = next == aFromLines.end();
|
||||
nsIFrame* lastFrame = isLastLine ? aFromFrames.LastChild()
|
||||
: next->mFirstChild->GetPrevSibling();
|
||||
nsFrameList::FrameLinkEnumerator linkToBreak(aFromFrames, lastFrame);
|
||||
*aOutFrames = aFromFrames.ExtractHead(linkToBreak);
|
||||
nsIFrame* firstFrameInNextLine = isLastLine ? nullptr : next->mFirstChild;
|
||||
*aOutFrames = aFromFrames.ExtractHead(firstFrameInNextLine);
|
||||
return isLastLine;
|
||||
}
|
||||
|
||||
|
||||
@@ -1421,26 +1421,21 @@ nsFrameList nsContainerFrame::StealFramesAfter(nsIFrame* aChild) {
|
||||
NS_ASSERTION(!IsBlockFrame(), "unexpected call");
|
||||
|
||||
if (!aChild) {
|
||||
nsFrameList copy(mFrames);
|
||||
mFrames.Clear();
|
||||
return copy;
|
||||
return std::move(mFrames);
|
||||
}
|
||||
|
||||
for (nsFrameList::FrameLinkEnumerator iter(mFrames); !iter.AtEnd();
|
||||
iter.Next()) {
|
||||
if (iter.PrevFrame() == aChild) {
|
||||
return mFrames.ExtractTail(iter);
|
||||
for (nsIFrame* f : mFrames) {
|
||||
if (f == aChild) {
|
||||
return mFrames.ExtractTail(f->GetNextSibling());
|
||||
}
|
||||
}
|
||||
|
||||
// We didn't find the child in the principal child list.
|
||||
// Maybe it's on the overflow list?
|
||||
nsFrameList* overflowFrames = GetOverflowFrames();
|
||||
if (overflowFrames) {
|
||||
for (nsFrameList::FrameLinkEnumerator iter(*overflowFrames); !iter.AtEnd();
|
||||
iter.Next()) {
|
||||
if (iter.PrevFrame() == aChild) {
|
||||
return overflowFrames->ExtractTail(iter);
|
||||
if (nsFrameList* overflowFrames = GetOverflowFrames()) {
|
||||
for (nsIFrame* f : *overflowFrames) {
|
||||
if (f == aChild) {
|
||||
return mFrames.ExtractTail(f->GetNextSibling());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,71 +163,50 @@ nsFrameList::Slice nsFrameList::InsertFrames(nsContainerFrame* aParent,
|
||||
return Slice(*this, firstNewFrame, nextSibling);
|
||||
}
|
||||
|
||||
nsFrameList nsFrameList::ExtractHead(FrameLinkEnumerator& aLink) {
|
||||
MOZ_ASSERT(&aLink.List() == this, "Unexpected list");
|
||||
MOZ_ASSERT(!aLink.PrevFrame() ||
|
||||
aLink.PrevFrame()->GetNextSibling() == aLink.NextFrame(),
|
||||
"Unexpected PrevFrame()");
|
||||
MOZ_ASSERT(aLink.PrevFrame() || aLink.NextFrame() == FirstChild(),
|
||||
"Unexpected NextFrame()");
|
||||
MOZ_ASSERT(!aLink.PrevFrame() || aLink.NextFrame() != FirstChild(),
|
||||
"Unexpected NextFrame()");
|
||||
MOZ_ASSERT(aLink.mEnd == nullptr,
|
||||
"Unexpected mEnd for frame link enumerator");
|
||||
nsFrameList nsFrameList::ExtractHead(nsIFrame* aFrame) {
|
||||
MOZ_ASSERT(!aFrame || ContainsFrame(aFrame), "aFrame is not on this list!");
|
||||
|
||||
if (!aFrame) {
|
||||
// We handed over the whole list.
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
if (aFrame == mFirstChild) {
|
||||
// aFrame is our first child. Nothing to extract.
|
||||
return nsFrameList();
|
||||
}
|
||||
|
||||
// Extract all previous siblings of aFrame as a new list.
|
||||
nsIFrame* prev = aFrame->GetPrevSibling();
|
||||
nsIFrame* newFirstChild = mFirstChild;
|
||||
nsIFrame* newLastChild = prev;
|
||||
|
||||
nsIFrame* prev = aLink.PrevFrame();
|
||||
nsIFrame* newFirstFrame = nullptr;
|
||||
if (prev) {
|
||||
// Truncate the list after |prev| and hand the first part to our new list.
|
||||
prev->SetNextSibling(nullptr);
|
||||
newFirstFrame = mFirstChild;
|
||||
mFirstChild = aLink.NextFrame();
|
||||
if (!mFirstChild) { // we handed over the whole list
|
||||
mLastChild = nullptr;
|
||||
mFirstChild = aFrame;
|
||||
|
||||
return nsFrameList(newFirstChild, newLastChild);
|
||||
}
|
||||
|
||||
// Now make sure aLink doesn't point to a frame we no longer have.
|
||||
aLink.mPrev = nullptr;
|
||||
}
|
||||
// else aLink is pointing to before our first frame. Nothing to do.
|
||||
nsFrameList nsFrameList::ExtractTail(nsIFrame* aFrame) {
|
||||
MOZ_ASSERT(!aFrame || ContainsFrame(aFrame), "aFrame is not on this list!");
|
||||
|
||||
return nsFrameList(newFirstFrame, prev);
|
||||
if (!aFrame) {
|
||||
return nsFrameList();
|
||||
}
|
||||
|
||||
nsFrameList nsFrameList::ExtractTail(FrameLinkEnumerator& aLink) {
|
||||
MOZ_ASSERT(&aLink.List() == this, "Unexpected list");
|
||||
MOZ_ASSERT(!aLink.PrevFrame() ||
|
||||
aLink.PrevFrame()->GetNextSibling() == aLink.NextFrame(),
|
||||
"Unexpected PrevFrame()");
|
||||
MOZ_ASSERT(aLink.PrevFrame() || aLink.NextFrame() == FirstChild(),
|
||||
"Unexpected NextFrame()");
|
||||
MOZ_ASSERT(!aLink.PrevFrame() || aLink.NextFrame() != FirstChild(),
|
||||
"Unexpected NextFrame()");
|
||||
MOZ_ASSERT(aLink.mEnd == nullptr,
|
||||
"Unexpected mEnd for frame link enumerator");
|
||||
if (aFrame == mFirstChild) {
|
||||
// We handed over the whole list.
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
nsIFrame* prev = aFrame->GetPrevSibling();
|
||||
nsIFrame* newFirstChild = aFrame;
|
||||
nsIFrame* newLastChild = mLastChild;
|
||||
|
||||
nsIFrame* prev = aLink.PrevFrame();
|
||||
nsIFrame* newFirstFrame;
|
||||
nsIFrame* newLastFrame;
|
||||
if (prev) {
|
||||
// Truncate the list after |prev| and hand the second part to our new list
|
||||
prev->SetNextSibling(nullptr);
|
||||
newFirstFrame = aLink.NextFrame();
|
||||
newLastFrame = newFirstFrame ? mLastChild : nullptr;
|
||||
mLastChild = prev;
|
||||
} else {
|
||||
// Hand the whole list over to our new list
|
||||
newFirstFrame = mFirstChild;
|
||||
newLastFrame = mLastChild;
|
||||
Clear();
|
||||
}
|
||||
|
||||
// Now make sure aLink doesn't point to a frame we no longer have.
|
||||
aLink.mFrame = nullptr;
|
||||
|
||||
MOZ_ASSERT(aLink.AtEnd(), "What's going on here?");
|
||||
|
||||
return nsFrameList(newFirstFrame, newLastFrame);
|
||||
return nsFrameList(newFirstChild, newLastChild);
|
||||
}
|
||||
|
||||
nsIFrame* nsFrameList::FrameAt(int32_t aIndex) const {
|
||||
|
||||
@@ -72,6 +72,9 @@ struct PostFrameDestroyData {
|
||||
*/
|
||||
class nsFrameList {
|
||||
public:
|
||||
class Iterator;
|
||||
class Slice;
|
||||
|
||||
nsFrameList() : mFirstChild(nullptr), mLastChild(nullptr) {}
|
||||
|
||||
nsFrameList(nsIFrame* aFirstFrame, nsIFrame* aLastFrame)
|
||||
@@ -138,8 +141,6 @@ class nsFrameList {
|
||||
aFrameList.Clear();
|
||||
}
|
||||
|
||||
class Slice;
|
||||
|
||||
/**
|
||||
* Append aFrameList to this list. If aParent is not null,
|
||||
* reparents the newly added frames. Clears out aFrameList and
|
||||
@@ -259,24 +260,29 @@ class nsFrameList {
|
||||
nsIFrame*>::value,
|
||||
"aPredicate should be of this function signature: bool(nsIFrame*)");
|
||||
|
||||
FrameLinkEnumerator link(*this);
|
||||
link.Find(aPredicate);
|
||||
return ExtractHead(link);
|
||||
for (nsIFrame* f : *this) {
|
||||
if (aPredicate(f)) {
|
||||
return ExtractHead(f);
|
||||
}
|
||||
}
|
||||
return std::move(*this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Split this frame list such that all the frames before the link pointed to
|
||||
* by aLink end up in the returned list, while the remaining frames stay in
|
||||
* this list. After this call, aLink points to the beginning of this list.
|
||||
* Split this frame list such that all the previous siblings of aFrame end up
|
||||
* in the returned list, while aFrame and all its next siblings stay in this
|
||||
* list. If aFrame is nullptr, extract the entire frame list.
|
||||
* Note: aFrame must be in this frame list!
|
||||
*/
|
||||
nsFrameList ExtractHead(FrameLinkEnumerator& aLink);
|
||||
nsFrameList ExtractHead(nsIFrame* aFrame);
|
||||
|
||||
/**
|
||||
* Split this frame list such that all the frames coming after the link
|
||||
* pointed to by aLink end up in the returned list, while the frames before
|
||||
* that link stay in this list. After this call, aLink is at end.
|
||||
* Split this frame list such that aFrame and all its next siblings end up in
|
||||
* the returned list; all the previous siblings of aFrame stay in this list.
|
||||
* If aFrame is nullptr, return an empty frame list.
|
||||
* Note: aFrame must be in this frame list!
|
||||
*/
|
||||
nsFrameList ExtractTail(FrameLinkEnumerator& aLink);
|
||||
nsFrameList ExtractTail(nsIFrame* aFrame);
|
||||
|
||||
nsIFrame* FirstChild() const { return mFirstChild; }
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "gfxContext.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "mozilla/ComputedStyle.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "nsStyleConsts.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsCellMap.h"
|
||||
@@ -2169,12 +2170,6 @@ void nsTableFrame::AppendFrames(ChildListID aListID, nsFrameList& aFrameList) {
|
||||
SetGeometryDirty();
|
||||
}
|
||||
|
||||
// Needs to be at file scope or ArrayLength fails to compile.
|
||||
struct ChildListInsertions {
|
||||
nsIFrame::ChildListID mID;
|
||||
nsFrameList mList;
|
||||
};
|
||||
|
||||
void nsTableFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
||||
const nsLineList::iterator* aPrevFrameLine,
|
||||
nsFrameList& aFrameList) {
|
||||
@@ -2196,34 +2191,28 @@ void nsTableFrame::InsertFrames(ChildListID aListID, nsIFrame* aPrevFrame,
|
||||
|
||||
// Collect ColGroupFrames into a separate list and insert those separately
|
||||
// from the other frames (bug 759249).
|
||||
ChildListInsertions insertions[2]; // ColGroup, other
|
||||
const nsStyleDisplay* display = aFrameList.FirstChild()->StyleDisplay();
|
||||
nsFrameList::FrameLinkEnumerator e(aFrameList);
|
||||
for (; !aFrameList.IsEmpty(); e.Next()) {
|
||||
nsIFrame* next = e.NextFrame();
|
||||
if (!next || next->StyleDisplay()->mDisplay != display->mDisplay) {
|
||||
nsFrameList head = aFrameList.ExtractHead(e);
|
||||
if (display->mDisplay == mozilla::StyleDisplay::TableColumnGroup) {
|
||||
insertions[0].mID = kColGroupList;
|
||||
insertions[0].mList.AppendFrames(nullptr, head);
|
||||
nsFrameList colGroupList;
|
||||
nsFrameList principalList;
|
||||
do {
|
||||
const auto display = aFrameList.FirstChild()->StyleDisplay()->mDisplay;
|
||||
nsFrameList head = aFrameList.Split([display](nsIFrame* aFrame) {
|
||||
return aFrame->StyleDisplay()->mDisplay != display;
|
||||
});
|
||||
if (display == mozilla::StyleDisplay::TableColumnGroup) {
|
||||
colGroupList.AppendFrames(nullptr, head);
|
||||
} else {
|
||||
insertions[1].mID = kPrincipalList;
|
||||
insertions[1].mList.AppendFrames(nullptr, head);
|
||||
principalList.AppendFrames(nullptr, head);
|
||||
}
|
||||
if (!next) {
|
||||
break;
|
||||
}
|
||||
display = next->StyleDisplay();
|
||||
}
|
||||
}
|
||||
for (uint32_t i = 0; i < ArrayLength(insertions); ++i) {
|
||||
} while (aFrameList.NotEmpty());
|
||||
|
||||
// We pass aPrevFrame for both ColGroup and other frames since
|
||||
// HomogenousInsertFrames will only use it if it's a suitable
|
||||
// prev-sibling for the frames in the frame list.
|
||||
if (!insertions[i].mList.IsEmpty()) {
|
||||
HomogenousInsertFrames(insertions[i].mID, aPrevFrame,
|
||||
insertions[i].mList);
|
||||
if (colGroupList.NotEmpty()) {
|
||||
HomogenousInsertFrames(kColGroupList, aPrevFrame, colGroupList);
|
||||
}
|
||||
if (principalList.NotEmpty()) {
|
||||
HomogenousInsertFrames(kPrincipalList, aPrevFrame, principalList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user