mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-12 21:05:36 +00:00
Bug 1249443 - add AllChildrenIterator::GetPreviousChild, r=bz
This commit is contained in:
parent
a9d4eb0d80
commit
e74f30bbd8
@ -314,24 +314,25 @@ ExplicitChildIterator::GetPreviousChild()
|
|||||||
bool
|
bool
|
||||||
AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
||||||
{
|
{
|
||||||
if (mPhase == eNeedBeforeKid) {
|
if (mPhase == eAtBegin || mPhase == eAtBeforeKid) {
|
||||||
mPhase = eNeedExplicitKids;
|
mPhase = eAtExplicitKids;
|
||||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||||
if (frame) {
|
if (frame) {
|
||||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||||
if (beforeFrame) {
|
if (beforeFrame) {
|
||||||
if (beforeFrame->GetContent() == aChildToFind) {
|
if (beforeFrame->GetContent() == aChildToFind) {
|
||||||
|
mPhase = eAtBeforeKid;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPhase == eNeedExplicitKids) {
|
if (mPhase == eAtExplicitKids) {
|
||||||
if (ExplicitChildIterator::Seek(aChildToFind)) {
|
if (ExplicitChildIterator::Seek(aChildToFind)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
mPhase = eNeedAnonKids;
|
mPhase = eAtAnonKids;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsIContent* child = nullptr;
|
nsIContent* child = nullptr;
|
||||||
@ -345,59 +346,124 @@ AllChildrenIterator::Seek(nsIContent* aChildToFind)
|
|||||||
nsIContent*
|
nsIContent*
|
||||||
AllChildrenIterator::GetNextChild()
|
AllChildrenIterator::GetNextChild()
|
||||||
{
|
{
|
||||||
if (mPhase == eNeedBeforeKid) {
|
if (mPhase == eAtBegin) {
|
||||||
mPhase = eNeedExplicitKids;
|
mPhase = eAtExplicitKids;
|
||||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||||
if (frame) {
|
if (frame) {
|
||||||
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||||
if (beforeFrame) {
|
if (beforeFrame) {
|
||||||
|
mPhase = eAtBeforeKid;
|
||||||
return beforeFrame->GetContent();
|
return beforeFrame->GetContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPhase == eNeedExplicitKids) {
|
if (mPhase == eAtBeforeKid) {
|
||||||
|
// Advance into our explicit kids.
|
||||||
|
mPhase = eAtExplicitKids;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPhase == eAtExplicitKids) {
|
||||||
nsIContent* kid = ExplicitChildIterator::GetNextChild();
|
nsIContent* kid = ExplicitChildIterator::GetNextChild();
|
||||||
if (kid) {
|
if (kid) {
|
||||||
return kid;
|
return kid;
|
||||||
}
|
}
|
||||||
|
mPhase = eAtAnonKids;
|
||||||
mPhase = eNeedAnonKids;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mPhase == eNeedAnonKids) {
|
if (mPhase == eAtAnonKids) {
|
||||||
if (mAnonKids.IsEmpty()) {
|
if (mAnonKids.IsEmpty()) {
|
||||||
|
MOZ_ASSERT(mAnonKidsIdx == UINT32_MAX);
|
||||||
nsIAnonymousContentCreator* ac =
|
nsIAnonymousContentCreator* ac =
|
||||||
do_QueryFrame(mOriginalContent->GetPrimaryFrame());
|
do_QueryFrame(mOriginalContent->GetPrimaryFrame());
|
||||||
if (ac) {
|
if (ac) {
|
||||||
ac->AppendAnonymousContentTo(mAnonKids, mFlags);
|
ac->AppendAnonymousContentTo(mAnonKids, mFlags);
|
||||||
}
|
}
|
||||||
|
mAnonKidsIdx = 0;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
if (!mAnonKids.IsEmpty()) {
|
if (mAnonKidsIdx == UINT32_MAX) {
|
||||||
nsIContent* nextKid = mAnonKids[0];
|
mAnonKidsIdx = 0;
|
||||||
mAnonKids.RemoveElementAt(0);
|
}
|
||||||
if (mAnonKids.IsEmpty()) {
|
else {
|
||||||
mPhase = eNeedAfterKid;
|
mAnonKidsIdx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return nextKid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mPhase = eNeedAfterKid;
|
if (mAnonKidsIdx < mAnonKids.Length()) {
|
||||||
}
|
return mAnonKids[mAnonKidsIdx];
|
||||||
|
}
|
||||||
|
|
||||||
if (mPhase == eNeedAfterKid) {
|
|
||||||
mPhase = eDone;
|
|
||||||
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||||
if (frame) {
|
if (frame) {
|
||||||
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||||
if (afterFrame) {
|
if (afterFrame) {
|
||||||
|
mPhase = eAtAfterKid;
|
||||||
return afterFrame->GetContent();
|
return afterFrame->GetContent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mPhase = eAtEnd;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIContent*
|
||||||
|
AllChildrenIterator::GetPreviousChild()
|
||||||
|
{
|
||||||
|
if (mPhase == eAtEnd) {
|
||||||
|
MOZ_ASSERT(mAnonKidsIdx == mAnonKids.Length());
|
||||||
|
mPhase = eAtAnonKids;
|
||||||
|
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||||
|
if (frame) {
|
||||||
|
nsIFrame* afterFrame = nsLayoutUtils::GetAfterFrame(frame);
|
||||||
|
if (afterFrame) {
|
||||||
|
mPhase = eAtAfterKid;
|
||||||
|
return afterFrame->GetContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPhase == eAtAfterKid) {
|
||||||
|
mPhase = eAtAnonKids;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPhase == eAtAnonKids) {
|
||||||
|
if (mAnonKids.IsEmpty()) {
|
||||||
|
nsIAnonymousContentCreator* ac =
|
||||||
|
do_QueryFrame(mOriginalContent->GetPrimaryFrame());
|
||||||
|
if (ac) {
|
||||||
|
ac->AppendAnonymousContentTo(mAnonKids, mFlags);
|
||||||
|
mAnonKidsIdx = mAnonKids.Length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// If 0 then it turns into UINT32_MAX, which indicates the iterator is
|
||||||
|
// before the anonymous children.
|
||||||
|
--mAnonKidsIdx;
|
||||||
|
if (mAnonKidsIdx < mAnonKids.Length()) {
|
||||||
|
return mAnonKids[mAnonKidsIdx];
|
||||||
|
}
|
||||||
|
mPhase = eAtExplicitKids;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mPhase == eAtExplicitKids) {
|
||||||
|
nsIContent* kid = ExplicitChildIterator::GetPreviousChild();
|
||||||
|
if (kid) {
|
||||||
|
return kid;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsIFrame* frame = mOriginalContent->GetPrimaryFrame();
|
||||||
|
if (frame) {
|
||||||
|
nsIFrame* beforeFrame = nsLayoutUtils::GetBeforeFrame(frame);
|
||||||
|
if (beforeFrame) {
|
||||||
|
mPhase = eAtBeforeKid;
|
||||||
|
return beforeFrame->GetContent();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mPhase = eAtBegin;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -182,14 +182,14 @@ class AllChildrenIterator : private FlattenedChildIterator
|
|||||||
public:
|
public:
|
||||||
AllChildrenIterator(nsIContent* aNode, uint32_t aFlags, bool aStartAtBeginning = true) :
|
AllChildrenIterator(nsIContent* aNode, uint32_t aFlags, bool aStartAtBeginning = true) :
|
||||||
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
FlattenedChildIterator(aNode, aFlags, aStartAtBeginning),
|
||||||
mOriginalContent(aNode), mFlags(aFlags),
|
mOriginalContent(aNode), mAnonKidsIdx(aStartAtBeginning ? UINT32_MAX : 0),
|
||||||
mPhase(eNeedBeforeKid) {}
|
mFlags(aFlags), mPhase(aStartAtBeginning ? eAtBegin : eAtEnd) { }
|
||||||
|
|
||||||
AllChildrenIterator(AllChildrenIterator&& aOther)
|
AllChildrenIterator(AllChildrenIterator&& aOther)
|
||||||
: FlattenedChildIterator(Move(aOther)),
|
: FlattenedChildIterator(Move(aOther)),
|
||||||
mOriginalContent(aOther.mOriginalContent),
|
mOriginalContent(aOther.mOriginalContent),
|
||||||
mAnonKids(Move(aOther.mAnonKids)), mFlags(aOther.mFlags),
|
mAnonKids(Move(aOther.mAnonKids)), mAnonKidsIdx(aOther.mAnonKidsIdx),
|
||||||
mPhase(aOther.mPhase)
|
mFlags(aOther.mFlags), mPhase(aOther.mPhase)
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
, mMutationGuard(aOther.mMutationGuard)
|
, mMutationGuard(aOther.mMutationGuard)
|
||||||
#endif
|
#endif
|
||||||
@ -202,20 +202,31 @@ public:
|
|||||||
bool Seek(nsIContent* aChildToFind);
|
bool Seek(nsIContent* aChildToFind);
|
||||||
|
|
||||||
nsIContent* GetNextChild();
|
nsIContent* GetNextChild();
|
||||||
|
nsIContent* GetPreviousChild();
|
||||||
nsIContent* Parent() const { return mOriginalContent; }
|
nsIContent* Parent() const { return mOriginalContent; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum IteratorPhase
|
enum IteratorPhase
|
||||||
{
|
{
|
||||||
eNeedBeforeKid,
|
eAtBegin,
|
||||||
eNeedExplicitKids,
|
eAtBeforeKid,
|
||||||
eNeedAnonKids,
|
eAtExplicitKids,
|
||||||
eNeedAfterKid,
|
eAtAnonKids,
|
||||||
eDone
|
eAtAfterKid,
|
||||||
|
eAtEnd
|
||||||
};
|
};
|
||||||
|
|
||||||
nsIContent* mOriginalContent;
|
nsIContent* mOriginalContent;
|
||||||
|
|
||||||
|
// mAnonKids is an array of native anonymous children, mAnonKidsIdx is index
|
||||||
|
// in the array. If mAnonKidsIdx < mAnonKids.Length() and mPhase is
|
||||||
|
// eAtAnonKids then the iterator points at a child at mAnonKidsIdx index. If
|
||||||
|
// mAnonKidsIdx == mAnonKids.Length() then the iterator is somewhere after
|
||||||
|
// the last native anon child. If mAnonKidsIdx == UINT32_MAX then the iterator
|
||||||
|
// is somewhere before the first native anon child.
|
||||||
nsTArray<nsIContent*> mAnonKids;
|
nsTArray<nsIContent*> mAnonKids;
|
||||||
|
uint32_t mAnonKidsIdx;
|
||||||
|
|
||||||
uint32_t mFlags;
|
uint32_t mFlags;
|
||||||
IteratorPhase mPhase;
|
IteratorPhase mPhase;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
Loading…
Reference in New Issue
Block a user