Bug 779684 - part 2: Get rid of nsFrameTraversal and nsIFrameTraversal r=emilio

The class is used only for creating `nsFrameIterator`, but it's unnecessary
so that we can get rid of it and its interface.

Differential Revision: https://phabricator.services.mozilla.com/D197143
This commit is contained in:
Masayuki Nakano 2023-12-24 06:01:19 +00:00
parent 32c9d4f8e7
commit 76826c766a
9 changed files with 87 additions and 205 deletions

View File

@ -3220,19 +3220,20 @@ nsresult nsFocusManager::GetSelectionLocation(Document* aDocument,
text && text->TextDataLength() == domRange->StartOffset() &&
domSelection->IsCollapsed()) {
nsIFrame* startFrame = start->GetPrimaryFrame();
MOZ_ASSERT(startFrame);
// Yes, indeed we were at the end of the last node
RefPtr<nsFrameIterator> frameIterator;
nsIFrame* limiter =
domSelection && domSelection->GetAncestorLimiter()
? domSelection->GetAncestorLimiter()->GetPrimaryFrame()
: nullptr;
MOZ_TRY(NS_NewFrameTraversal(getter_AddRefs(frameIterator), presContext,
startFrame, eLeaf,
false, // aVisual
false, // aLockInScrollView
true, // aFollowOOFs
false, // aSkipPopupChecks
limiter));
RefPtr<nsFrameIterator> frameIterator = nsFrameIterator::Create(
presContext, startFrame, nsFrameIterator::Type::Leaf,
false, // aVisual
false, // aLockInScrollView
true, // aFollowOOFs
false, // aSkipPopupChecks
limiter);
MOZ_ASSERT(frameIterator);
nsIFrame* newCaretFrame = nullptr;
nsIContent* newCaretContent = start;
@ -4198,14 +4199,14 @@ nsresult nsFocusManager::GetNextTabbableContent(
// For tab navigation, pass false for aSkipPopupChecks so that we don't
// iterate into or out of a popup. For document naviation pass true to
// ignore these boundaries.
nsresult rv = NS_NewFrameTraversal(
getter_AddRefs(frameIterator), presContext, frame, ePreOrder,
frameIterator = nsFrameIterator::Create(
presContext, frame, nsFrameIterator::Type::PreOrder,
false, // aVisual
false, // aLockInScrollView
true, // aFollowOOFs
aForDocumentNavigation // aSkipPopupChecks
);
NS_ENSURE_SUCCESS(rv, rv);
MOZ_ASSERT(frameIterator);
if (iterStartContent == aRootContent) {
if (!aForward) {
@ -4414,7 +4415,7 @@ nsresult nsFocusManager::GetNextTabbableContent(
currentContent->IsHTMLElement(nsGkAtoms::img) &&
currentContent->AsElement()->HasAttr(nsGkAtoms::usemap)) {
// This is an image with a map. Image map areas are not traversed by
// nsIFrameTraversal so look for the next or previous area element.
// nsFrameIterator so look for the next or previous area element.
nsIContent* areaContent = GetNextTabbableMapArea(
aForward, aCurrentTabIndex, currentContent->AsElement(),
iterStartContent);

View File

@ -48,7 +48,6 @@ EXPORTS += [
"nsFrameManager.h",
"nsFrameTraversal.h",
"nsGenConList.h",
"nsIFrameTraversal.h",
"nsIPercentBSizeObserver.h",
"nsIReflowCallback.h",
"nsLayoutUtils.h",

View File

@ -22,11 +22,11 @@ using namespace mozilla::dom;
// Bidi visual iterator
class nsVisualIterator : public nsFrameIterator {
public:
nsVisualIterator(nsPresContext* aPresContext, nsIFrame* aStart,
nsIteratorType aType, bool aLockScroll, bool aFollowOOFs,
nsVisualIterator(nsPresContext* aPresContext, nsIFrame* aStart, Type aType,
bool aLockInScrollView, bool aFollowOOFs,
bool aSkipPopupChecks, nsIFrame* aLimiter)
: nsFrameIterator(aPresContext, aStart, aType, aLockScroll, aFollowOOFs,
aSkipPopupChecks, aLimiter) {}
: nsFrameIterator(aPresContext, aStart, aType, aLockInScrollView,
aFollowOOFs, aSkipPopupChecks, aLimiter) {}
protected:
nsIFrame* GetFirstChildInner(nsIFrame* aFrame) override;
@ -38,60 +38,32 @@ class nsVisualIterator : public nsFrameIterator {
/************IMPLEMENTATIONS**************/
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult) {
NS_ENSURE_ARG_POINTER(aResult);
nsCOMPtr<nsIFrameTraversal> t = new nsFrameTraversal();
t.forget(aResult);
return NS_OK;
}
nsresult NS_NewFrameTraversal(nsFrameIterator** aEnumerator,
nsPresContext* aPresContext, nsIFrame* aStart,
nsIteratorType aType, bool aVisual,
bool aLockInScrollView, bool aFollowOOFs,
bool aSkipPopupChecks, nsIFrame* aLimiter) {
if (!aEnumerator || !aStart) return NS_ERROR_NULL_POINTER;
// static
already_AddRefed<nsFrameIterator> nsFrameIterator::Create(
nsPresContext* aPresContext, nsIFrame* aStart, Type aType, bool aVisual,
bool aLockInScrollView, bool aFollowOOFs, bool aSkipPopupChecks,
nsIFrame* aLimiter) {
MOZ_ASSERT(aStart);
if (aFollowOOFs) {
aStart = nsPlaceholderFrame::GetRealFrameFor(aStart);
}
RefPtr<nsFrameIterator> trav;
RefPtr<nsFrameIterator> iterator;
if (aVisual) {
trav = new nsVisualIterator(aPresContext, aStart, aType, aLockInScrollView,
aFollowOOFs, aSkipPopupChecks, aLimiter);
iterator =
new nsVisualIterator(aPresContext, aStart, aType, aLockInScrollView,
aFollowOOFs, aSkipPopupChecks, aLimiter);
} else {
trav = new nsFrameIterator(aPresContext, aStart, aType, aLockInScrollView,
aFollowOOFs, aSkipPopupChecks, aLimiter);
iterator =
new nsFrameIterator(aPresContext, aStart, aType, aLockInScrollView,
aFollowOOFs, aSkipPopupChecks, aLimiter);
}
trav.forget(aEnumerator);
return NS_OK;
return iterator.forget();
}
nsFrameTraversal::nsFrameTraversal() = default;
nsFrameTraversal::~nsFrameTraversal() = default;
NS_IMPL_ISUPPORTS(nsFrameTraversal, nsIFrameTraversal)
NS_IMETHODIMP
nsFrameTraversal::NewFrameTraversal(nsFrameIterator** aEnumerator,
nsPresContext* aPresContext,
nsIFrame* aStart, int32_t aType,
bool aVisual, bool aLockInScrollView,
bool aFollowOOFs, bool aSkipPopupChecks,
nsIFrame* aLimiter) {
return NS_NewFrameTraversal(
aEnumerator, aPresContext, aStart, static_cast<nsIteratorType>(aType),
aVisual, aLockInScrollView, aFollowOOFs, aSkipPopupChecks, aLimiter);
}
// nsFrameIterator implementation
nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame* aStart,
nsIteratorType aType, bool aLockInScrollView,
Type aType, bool aLockInScrollView,
bool aFollowOOFs, bool aSkipPopupChecks,
nsIFrame* aLimiter)
: mPresContext(aPresContext),
@ -144,12 +116,12 @@ void nsFrameIterator::Next() {
nsIFrame* parent = GetCurrent();
if (!parent) parent = GetLast();
if (mType == eLeaf) {
if (mType == Type::Leaf) {
// Drill down to first leaf
while ((result = GetFirstChild(parent))) {
parent = result;
}
} else if (mType == ePreOrder) {
} else if (mType == Type::PreOrder) {
result = GetFirstChild(parent);
if (result) parent = result;
}
@ -160,7 +132,7 @@ void nsFrameIterator::Next() {
while (parent) {
result = GetNextSibling(parent);
if (result) {
if (mType != ePreOrder) {
if (mType != Type::PreOrder) {
parent = result;
while ((result = GetFirstChild(parent))) {
parent = result;
@ -175,7 +147,7 @@ void nsFrameIterator::Next() {
result = nullptr;
break;
}
if (mType == ePostOrder) {
if (mType == Type::PostOrder) {
break;
}
parent = result;
@ -195,12 +167,12 @@ void nsFrameIterator::Prev() {
nsIFrame* parent = GetCurrent();
if (!parent) parent = GetLast();
if (mType == eLeaf) {
if (mType == Type::Leaf) {
// Drill down to last leaf
while ((result = GetLastChild(parent))) {
parent = result;
}
} else if (mType == ePostOrder) {
} else if (mType == Type::PostOrder) {
result = GetLastChild(parent);
if (result) parent = result;
}
@ -211,7 +183,7 @@ void nsFrameIterator::Prev() {
while (parent) {
result = GetPrevSibling(parent);
if (result) {
if (mType != ePostOrder) {
if (mType != Type::PostOrder) {
parent = result;
while ((result = GetLastChild(parent))) {
parent = result;
@ -226,7 +198,7 @@ void nsFrameIterator::Prev() {
result = nullptr;
break;
}
if (mType == ePreOrder) {
if (mType == Type::PreOrder) {
break;
}
parent = result;

View File

@ -8,9 +8,10 @@
#define NSFRAMETRAVERSAL_H
#include "mozilla/Attributes.h"
#include "nsIFrameTraversal.h"
#include "nsISupportsImpl.h"
class nsIFrame;
class nsPresContext;
class nsFrameIterator {
NS_INLINE_DECL_REFCOUNTING(nsFrameIterator)
@ -33,11 +34,23 @@ class nsFrameIterator {
return CurrentItem();
};
nsFrameIterator(nsPresContext* aPresContext, nsIFrame* aStart,
nsIteratorType aType, bool aLockScroll, bool aFollowOOFs,
bool aSkipPopupChecks, nsIFrame* aLimiter);
enum class Type : uint8_t {
// only leaf nodes
Leaf,
// "open tag" order
PreOrder,
// "close tag" order
PostOrder,
};
static already_AddRefed<nsFrameIterator> Create(
nsPresContext* aPresContext, nsIFrame* aStart, Type aType, bool aVisual,
bool aLockInScrollView, bool aFollowOOFs, bool aSkipPopupChecks,
nsIFrame* aLimiter = nullptr);
protected:
nsFrameIterator(nsPresContext* aPresContext, nsIFrame* aStart, Type aType,
bool aLockInScrollView, bool aFollowOOFs,
bool aSkipPopupChecks, nsIFrame* aLimiter);
virtual ~nsFrameIterator() = default;
void SetCurrent(nsIFrame* aFrame) { mCurrent = aFrame; }
@ -102,7 +115,7 @@ class nsFrameIterator {
const bool mLockScroll;
const bool mFollowOOFs;
const bool mSkipPopupChecks;
const nsIteratorType mType;
const Type mType;
private:
nsIFrame* const mStart;
@ -112,30 +125,4 @@ class nsFrameIterator {
int8_t mOffEdge; // 0= no -1 to far prev, 1 to far next;
};
nsresult NS_NewFrameTraversal(nsFrameIterator** aEnumerator,
nsPresContext* aPresContext, nsIFrame* aStart,
nsIteratorType aType, bool aVisual,
bool aLockInScrollView, bool aFollowOOFs,
bool aSkipPopupChecks,
nsIFrame* aLimiter = nullptr);
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
class nsFrameTraversal final : public nsIFrameTraversal {
public:
nsFrameTraversal();
NS_DECL_ISUPPORTS
NS_IMETHOD NewFrameTraversal(nsFrameIterator** aEnumerator,
nsPresContext* aPresContext, nsIFrame* aStart,
int32_t aType, bool aVisual,
bool aLockInScrollView, bool aFollowOOFs,
bool aSkipPopupChecks,
nsIFrame* aLimiter = nullptr) override;
protected:
virtual ~nsFrameTraversal();
};
#endif // NSFRAMETRAVERSAL_H

View File

@ -1,58 +0,0 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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/. */
#ifndef NSIFRAMETRAVERSAL_H
#define NSIFRAMETRAVERSAL_H
#include "nsISupports.h"
class nsFrameIterator;
class nsIFrame;
class nsPresContext;
enum nsIteratorType { eLeaf, ePreOrder, ePostOrder };
// {d33fe76c-207c-4359-a315-8eb1eecf80e5}
#define NS_IFRAMETRAVERSAL_IID \
{ \
0xd33fe76c, 0x207c, 0x4359, { \
0xa3, 0x15, 0x8e, 0xb1, 0xee, 0xcf, 0x80, 0xe5 \
} \
}
class nsIFrameTraversal : public nsISupports {
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFRAMETRAVERSAL_IID)
/**
* Create a frame iterator with the specified properties.
* @param aEnumerator [out] the created iterator
* @param aPresContext [in]
* @param aStart [in] the frame to start iterating from
* @param aType [in] the type of the iterator: leaf, pre-order, or post-order
* @param aVisual [in] whether the iterator should traverse frames in visual
* bidi order
* @param aLockInScrollView [in] whether to stop iterating when exiting a
* scroll view
* @param aFollowOOFs [in] whether the iterator should follow out-of-flows.
* If true, when reaching a placeholder frame while going down will get
* the real frame. Going back up will go on past the placeholder,
* so the placeholders are logically part of the frame tree.
* @param aSkipPopupChecks [in] if false, then don't iterate into or out of a
* popup frame. If true, skip any popup related checks.
* @param aLimiter [in] if this is non-null and an ancestor of aStart,
* iteration will be limited to just the descendants of this frame.
*/
NS_IMETHOD NewFrameTraversal(nsFrameIterator** aEnumerator,
nsPresContext* aPresContext, nsIFrame* aStart,
int32_t aType, bool aVisual,
bool aLockInScrollView, bool aFollowOOFs,
bool aSkipPopupChecks,
nsIFrame* aLimiter = nullptr) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFrameTraversal, NS_IFRAMETRAVERSAL_IID)
#endif // NSIFRAMETRAVERSAL_H

View File

@ -58,10 +58,6 @@ if defined('MOZ_WEBM'):
]
Classes = [
{
'cid': '{1691e1f4-ee41-11d4-9885-00c04fa0cf4b}',
'type': 'nsIFrameTraversal',
},
{
'cid': '{574ce83e-fe9f-4095-b85c-7909abbf7c37}',
'type': 'nsJSURI::Mutator',

View File

@ -27,7 +27,6 @@
#include "nsPlainTextSerializer.h"
#include "nsXMLContentSerializer.h"
#include "nsXHTMLContentSerializer.h"
#include "nsIFrameTraversal.h"
#include "nsLayoutCID.h"
#include "nsFocusManager.h"
#include "ThirdPartyUtil.h"
@ -119,8 +118,6 @@ void Shutdown() {
nsLayoutStatics::Release();
}
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
already_AddRefed<nsIDocumentViewer> NS_NewDocumentViewer();
nsresult NS_NewContentDocumentLoaderFactory(nsIDocumentLoaderFactory** aResult);
nsresult NS_NewContentPolicy(nsIContentPolicy** aResult);
@ -154,8 +151,6 @@ nsresult NS_NewChildProcessMessageManager(nsISupports** aResult);
#define MAKE_GENERIC_CTOR2(iface_, func_) \
NS_IMPL_COMPONENT_FACTORY(iface_) { return func_(); }
MAKE_GENERIC_CTOR(nsIFrameTraversal, NS_CreateFrameTraversal)
MAKE_GENERIC_CTOR2(nsIDocumentViewer, NS_NewDocumentViewer)
MAKE_CTOR(CreateXMLContentSerializer, nsIContentSerializer,

View File

@ -10,6 +10,7 @@
#include "nsFrameSelection.h"
#include "ErrorList.h"
#include "mozilla/intl/BidiEmbeddingLevel.h"
#include "mozilla/Attributes.h"
#include "mozilla/AutoRestore.h"
@ -49,7 +50,6 @@
#include "nsLayoutUtils.h"
#include "nsLayoutCID.h"
#include "nsBidiPresUtils.h"
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
#include "nsTextFrame.h"
#include "nsThreadUtils.h"
@ -1015,29 +1015,26 @@ nsresult nsFrameSelection::GetFrameFromLevel(
nsIFrame* aFrameIn, nsDirection aDirection,
mozilla::intl::BidiEmbeddingLevel aBidiLevel, nsIFrame** aFrameOut) const {
NS_ENSURE_STATE(mPresShell);
if (!aFrameIn) {
return NS_ERROR_NULL_POINTER;
}
mozilla::intl::BidiEmbeddingLevel foundLevel =
mozilla::intl::BidiEmbeddingLevel::LTR();
nsIFrame* foundFrame = aFrameIn;
RefPtr<nsFrameIterator> frameTraversal;
nsresult result;
nsCOMPtr<nsIFrameTraversal> trav(
do_CreateInstance(kFrameTraversalCID, &result));
if (NS_FAILED(result)) return result;
result =
trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
mPresShell->GetPresContext(), aFrameIn, eLeaf,
false, // aVisual
false, // aLockInScrollView
false, // aFollowOOFs
false // aSkipPopupChecks
);
if (NS_FAILED(result)) return result;
RefPtr<nsFrameIterator> frameIterator = nsFrameIterator::Create(
mPresShell->GetPresContext(), aFrameIn, nsFrameIterator::Type::Leaf,
false, // aVisual
false, // aLockInScrollView
false, // aFollowOOFs
false // aSkipPopupChecks
);
MOZ_ASSERT(frameIterator);
do {
*aFrameOut = foundFrame;
foundFrame = frameTraversal->Traverse(aDirection == eDirNext);
foundFrame = frameIterator->Traverse(aDirection == eDirNext);
if (!foundFrame) return NS_ERROR_FAILURE;
foundLevel = foundFrame->GetEmbeddingLevel();

View File

@ -8600,7 +8600,6 @@ static nsresult GetNextPrevLineFromBlockFrame(PeekOffsetStruct* aPos,
bool isBeforeFirstFrame, isAfterLastFrame;
bool found = false;
nsresult result = NS_OK;
while (!found) {
if (aPos->mDirection == eDirPrevious)
searchingLine--;
@ -8639,9 +8638,9 @@ static nsresult GetNextPrevLineFromBlockFrame(PeekOffsetStruct* aPos,
nsPoint newDesiredPos =
aPos->mDesiredCaretPos -
offset; // get desired position into blockframe coords
result = it->FindFrameAt(searchingLine, newDesiredPos, &resultFrame,
&isBeforeFirstFrame, &isAfterLastFrame);
if (NS_FAILED(result)) {
nsresult rv = it->FindFrameAt(searchingLine, newDesiredPos, &resultFrame,
&isBeforeFirstFrame, &isAfterLastFrame);
if (NS_FAILED(rv)) {
continue;
}
@ -8653,19 +8652,14 @@ static nsresult GetNextPrevLineFromBlockFrame(PeekOffsetStruct* aPos,
return NS_OK;
}
// resultFrame is not a block frame
result = NS_ERROR_FAILURE;
RefPtr<nsFrameIterator> frameIterator;
result = NS_NewFrameTraversal(
getter_AddRefs(frameIterator), pc, resultFrame, ePostOrder,
RefPtr<nsFrameIterator> frameIterator = nsFrameIterator::Create(
pc, resultFrame, nsFrameIterator::Type::PostOrder,
false, // aVisual
aPos->mOptions.contains(PeekOffsetOption::StopAtScroller),
false, // aFollowOOFs
false // aSkipPopupChecks
);
if (NS_FAILED(result)) {
return result;
}
MOZ_ASSERT(frameIterator);
auto FoundValidFrame = [aPos](const nsIFrame::ContentOffsets& aOffsets,
const nsIFrame* aFrame) {
@ -8731,14 +8725,14 @@ static nsresult GetNextPrevLineFromBlockFrame(PeekOffsetStruct* aPos,
if (!found) {
resultFrame = storeOldResultFrame;
result = NS_NewFrameTraversal(
getter_AddRefs(frameIterator), pc, resultFrame, eLeaf,
frameIterator = nsFrameIterator::Create(
pc, resultFrame, nsFrameIterator::Type::Leaf,
false, // aVisual
aPos->mOptions.contains(PeekOffsetOption::StopAtScroller),
false, // aFollowOOFs
false // aSkipPopupChecks
);
MOZ_ASSERT(frameIterator);
}
while (!found) {
nsPoint point = aPos->mDesiredCaretPos;
@ -9623,13 +9617,12 @@ nsIFrame::SelectablePeekReport nsIFrame::GetFrameFromDirection(
aOptions.contains(PeekOffsetOption::Visual) && presContext->BidiEnabled();
const bool followOofs =
!aOptions.contains(PeekOffsetOption::StopAtPlaceholder);
RefPtr<nsFrameIterator> frameIterator;
MOZ_TRY(NS_NewFrameTraversal(
getter_AddRefs(frameIterator), presContext, this, eLeaf,
needsVisualTraversal, aOptions.contains(PeekOffsetOption::StopAtScroller),
followOofs,
RefPtr<nsFrameIterator> frameIterator = nsFrameIterator::Create(
presContext, this, nsFrameIterator::Type::Leaf, needsVisualTraversal,
aOptions.contains(PeekOffsetOption::StopAtScroller), followOofs,
false // aSkipPopupChecks
));
);
MOZ_ASSERT(frameIterator);
// Find the prev/next selectable frame
bool selectable = false;