Bug 181137 - part 8: Make ContentIteratorBase and its subclasses non-refcountable r=smaug

This patch makes ContentIteratorBase, PostContentIterator, PreContentIterator
and ContentSubtreeIterator classes non-refcountable because most users can
create their instances in stack and such users may be in a hot path.  So,
we can save a lot of cost of instantiation.

Unfortunately, only ScriptableContentIterator creates one of the concrete
classes and needs to destroy it properly.  Therefore, its
EnsureContentIterator(), destructor, traverse and unlink code becomes messy.
However, ScriptableContentIterator was designed for automated tests and we
need to maintain it not so many times.  Therefore, improvement of other
users must be worthwhiler than this demerit.

Differential Revision: https://phabricator.services.mozilla.com/D15928

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2019-01-10 08:50:41 +00:00
parent 91a9670801
commit 796ceb094f
19 changed files with 286 additions and 260 deletions

View File

@ -68,19 +68,6 @@ static bool NodeIsInTraversalRange(nsINode* aNode, bool aIsPreMode,
nsContentUtils::ComparePoints(aEnd, beforeNode) > 0;
}
NS_IMPL_CYCLE_COLLECTION(ContentIteratorBase, mCurNode, mFirst, mLast,
mCommonParent, mRange)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(ContentIteratorBase, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(ContentIteratorBase, Release)
void ContentIteratorBase::LastRelease() {
mCurNode = nullptr;
mFirst = nullptr;
mLast = nullptr;
mCommonParent = nullptr;
}
ContentIteratorBase::ContentIteratorBase(bool aPre)
: mIsDone(false), mPre(aPre) {}
@ -627,36 +614,7 @@ nsINode* ContentIteratorBase::GetCurrentNode() {
}
/******************************************************
* PostContentIterator
******************************************************/
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(PostContentIterator)
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE_WITH_LAST_RELEASE(PostContentIterator,
LastRelease())
/******************************************************
* PreContentIterator
******************************************************/
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(PreContentIterator)
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE_WITH_LAST_RELEASE(PreContentIterator,
LastRelease())
/******************************************************
* ContentSubtreeIterator
******************************************************/
void ContentSubtreeIterator::LastRelease() {
mRange = nullptr;
ContentIteratorBase::LastRelease();
}
NS_IMPL_CYCLE_COLLECTING_NATIVE_ADDREF(ContentSubtreeIterator)
NS_IMPL_CYCLE_COLLECTING_NATIVE_RELEASE_WITH_LAST_RELEASE(
ContentSubtreeIterator, LastRelease())
/******************************************************
* Init routines
* ContentSubtreeIterator init routines
******************************************************/
nsresult ContentSubtreeIterator::Init(nsINode* aRoot) {

View File

@ -23,17 +23,12 @@ namespace mozilla {
* by the users directly.
*/
class ContentIteratorBase {
protected:
nsCycleCollectingAutoRefCnt mRefCnt;
NS_DECL_OWNINGTHREAD
public:
ContentIteratorBase() = delete;
ContentIteratorBase(const ContentIteratorBase&) = delete;
ContentIteratorBase& operator=(const ContentIteratorBase&) = delete;
virtual ~ContentIteratorBase() = default;
NS_IMETHOD_(MozExternalRefCountType) AddRef() = 0;
NS_IMETHOD_(MozExternalRefCountType) Release() = 0;
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(ContentIteratorBase)
virtual nsresult Init(nsINode* aRoot);
@ -56,7 +51,6 @@ class ContentIteratorBase {
protected:
explicit ContentIteratorBase(bool aPre);
virtual ~ContentIteratorBase() = default;
/**
* Callers must guarantee that:
@ -85,22 +79,39 @@ class ContentIteratorBase {
void MakeEmpty();
virtual void LastRelease();
nsCOMPtr<nsINode> mCurNode;
nsCOMPtr<nsINode> mFirst;
nsCOMPtr<nsINode> mLast;
nsCOMPtr<nsINode> mCommonParent;
// Used only by ContentSubtreeIterator class but we need to put this here
// for cycle collection because macros to implement classes in cycle
// collection do not support inherited classes without nsISupports interface.
RefPtr<nsRange> mRange;
bool mIsDone;
bool mPre;
friend void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback&,
ContentIteratorBase&, const char*,
uint32_t);
friend void ImplCycleCollectionUnlink(ContentIteratorBase&);
};
// Each concreate class of ContentIteratorBase may be owned by another class
// which may be owned by JS. Therefore, all of them should be in the cycle
// collection. However, we cannot make non-refcountable classes only with the
// macros. So, we need to make them cycle collectable without the macros.
inline void ImplCycleCollectionTraverse(
nsCycleCollectionTraversalCallback& aCallback, ContentIteratorBase& aField,
const char* aName, uint32_t aFlags = 0) {
ImplCycleCollectionTraverse(aCallback, aField.mCurNode, aName, aFlags);
ImplCycleCollectionTraverse(aCallback, aField.mFirst, aName, aFlags);
ImplCycleCollectionTraverse(aCallback, aField.mLast, aName, aFlags);
ImplCycleCollectionTraverse(aCallback, aField.mCommonParent, aName, aFlags);
}
inline void ImplCycleCollectionUnlink(ContentIteratorBase& aField) {
ImplCycleCollectionUnlink(aField.mCurNode);
ImplCycleCollectionUnlink(aField.mFirst);
ImplCycleCollectionUnlink(aField.mLast);
ImplCycleCollectionUnlink(aField.mCommonParent);
}
/**
* A simple iterator class for traversing the content in "close tag" order.
*/
@ -109,14 +120,24 @@ class PostContentIterator final : public ContentIteratorBase {
PostContentIterator() : ContentIteratorBase(false) {}
PostContentIterator(const PostContentIterator&) = delete;
PostContentIterator& operator=(const PostContentIterator&) = delete;
NS_IMETHOD_(MozExternalRefCountType) AddRef() override;
NS_IMETHOD_(MozExternalRefCountType) Release() override;
protected:
virtual ~PostContentIterator() = default;
friend void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback&,
PostContentIterator&, const char*,
uint32_t);
friend void ImplCycleCollectionUnlink(PostContentIterator&);
};
inline void ImplCycleCollectionTraverse(
nsCycleCollectionTraversalCallback& aCallback, PostContentIterator& aField,
const char* aName, uint32_t aFlags = 0) {
ImplCycleCollectionTraverse(
aCallback, static_cast<ContentIteratorBase&>(aField), aName, aFlags);
}
inline void ImplCycleCollectionUnlink(PostContentIterator& aField) {
ImplCycleCollectionUnlink(static_cast<ContentIteratorBase&>(aField));
}
/**
* A simple iterator class for traversing the content in "start tag" order.
*/
@ -125,14 +146,24 @@ class PreContentIterator final : public ContentIteratorBase {
PreContentIterator() : ContentIteratorBase(true) {}
PreContentIterator(const PreContentIterator&) = delete;
PreContentIterator& operator=(const PreContentIterator&) = delete;
NS_IMETHOD_(MozExternalRefCountType) AddRef() override;
NS_IMETHOD_(MozExternalRefCountType) Release() override;
protected:
virtual ~PreContentIterator() = default;
friend void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback&,
PreContentIterator&, const char*,
uint32_t);
friend void ImplCycleCollectionUnlink(PreContentIterator&);
};
inline void ImplCycleCollectionTraverse(
nsCycleCollectionTraversalCallback& aCallback, PreContentIterator& aField,
const char* aName, uint32_t aFlags = 0) {
ImplCycleCollectionTraverse(
aCallback, static_cast<ContentIteratorBase&>(aField), aName, aFlags);
}
inline void ImplCycleCollectionUnlink(PreContentIterator& aField) {
ImplCycleCollectionUnlink(static_cast<ContentIteratorBase&>(aField));
}
/**
* A simple iterator class for traversing the content in "top subtree" order.
*/
@ -141,9 +172,7 @@ class ContentSubtreeIterator final : public ContentIteratorBase {
ContentSubtreeIterator() : ContentIteratorBase(true) {}
ContentSubtreeIterator(const ContentSubtreeIterator&) = delete;
ContentSubtreeIterator& operator=(const ContentSubtreeIterator&) = delete;
NS_IMETHOD_(MozExternalRefCountType) AddRef() override;
NS_IMETHOD_(MozExternalRefCountType) Release() override;
virtual ~ContentSubtreeIterator() = default;
virtual nsresult Init(nsINode* aRoot) override;
virtual nsresult Init(nsRange* aRange) override;
@ -161,9 +190,12 @@ class ContentSubtreeIterator final : public ContentIteratorBase {
virtual nsresult PositionAt(nsINode* aCurNode) override;
protected:
virtual ~ContentSubtreeIterator() = default;
friend void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback&,
ContentSubtreeIterator&, const char*,
uint32_t);
friend void ImplCycleCollectionUnlink(ContentSubtreeIterator&);
protected:
/**
* Callers must guarantee that mRange isn't nullptr and is positioned.
*/
@ -176,11 +208,24 @@ class ContentSubtreeIterator final : public ContentIteratorBase {
// the range's start and end nodes will never be considered "in" it.
nsIContent* GetTopAncestorInRange(nsINode* aNode);
virtual void LastRelease() override;
RefPtr<nsRange> mRange;
AutoTArray<nsIContent*, 8> mEndNodes;
};
inline void ImplCycleCollectionTraverse(
nsCycleCollectionTraversalCallback& aCallback,
ContentSubtreeIterator& aField, const char* aName, uint32_t aFlags = 0) {
ImplCycleCollectionTraverse(aCallback, aField.mRange, aName, aFlags);
ImplCycleCollectionTraverse(
aCallback, static_cast<ContentIteratorBase&>(aField), aName, aFlags);
}
inline void ImplCycleCollectionUnlink(ContentSubtreeIterator& aField) {
ImplCycleCollectionUnlink(aField.mRange);
ImplCycleCollectionUnlink(static_cast<ContentIteratorBase&>(aField));
}
} // namespace mozilla
#endif // #ifndef mozilla_ContentIterator_h

View File

@ -20,7 +20,49 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(ScriptableContentIterator)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_END
NS_IMPL_CYCLE_COLLECTION(ScriptableContentIterator, mContentIterator)
NS_IMPL_CYCLE_COLLECTION_CLASS(ScriptableContentIterator)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ScriptableContentIterator)
if (tmp->mContentIterator) {
switch (tmp->mIteratorType) {
case POST_ORDER_ITERATOR:
default:
ImplCycleCollectionUnlink(
static_cast<PostContentIterator&>(*tmp->mContentIterator));
break;
case PRE_ORDER_ITERATOR:
ImplCycleCollectionUnlink(
static_cast<PreContentIterator&>(*tmp->mContentIterator));
break;
case SUBTREE_ITERATOR:
ImplCycleCollectionUnlink(
static_cast<ContentSubtreeIterator&>(*tmp->mContentIterator));
break;
}
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(ScriptableContentIterator)
if (tmp->mContentIterator) {
switch (tmp->mIteratorType) {
case POST_ORDER_ITERATOR:
default:
ImplCycleCollectionTraverse(
cb, static_cast<PostContentIterator&>(*tmp->mContentIterator),
"mContentIterator");
break;
case PRE_ORDER_ITERATOR:
ImplCycleCollectionTraverse(
cb, static_cast<PreContentIterator&>(*tmp->mContentIterator),
"mContentIterator");
break;
case SUBTREE_ITERATOR:
ImplCycleCollectionTraverse(
cb, static_cast<ContentSubtreeIterator&>(*tmp->mContentIterator),
"mContentIterator");
break;
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
ScriptableContentIterator::ScriptableContentIterator()
: mIteratorType(NOT_INITIALIZED) {}
@ -32,13 +74,13 @@ void ScriptableContentIterator::EnsureContentIterator() {
switch (mIteratorType) {
case POST_ORDER_ITERATOR:
default:
mContentIterator = new PostContentIterator();
mContentIterator = MakeUnique<PostContentIterator>();
break;
case PRE_ORDER_ITERATOR:
mContentIterator = new PreContentIterator();
mContentIterator = MakeUnique<PreContentIterator>();
break;
case SUBTREE_ITERATOR:
mContentIterator = new ContentSubtreeIterator();
mContentIterator = MakeUnique<ContentSubtreeIterator>();
break;
}
}

View File

@ -9,6 +9,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/ContentIterator.h"
#include "mozilla/UniquePtr.h"
#include "nsCOMPtr.h"
#include "nsIScriptableContentIterator.h"
@ -26,7 +27,7 @@ class ScriptableContentIterator final : public nsIScriptableContentIterator {
void EnsureContentIterator();
IteratorType mIteratorType;
RefPtr<ContentIteratorBase> mContentIterator;
UniquePtr<ContentIteratorBase> mContentIterator;
};
} // namespace mozilla

View File

@ -1482,7 +1482,7 @@ void Selection::SelectFramesForContent(nsIContent* aContent, bool aSelected) {
// select all content children of aContent
nsresult Selection::SelectAllFramesForContent(
PostContentIterator* aPostOrderIter, nsIContent* aContent, bool aSelected) {
PostContentIterator& aPostOrderIter, nsIContent* aContent, bool aSelected) {
// If aContent doesn't have children, we should avoid to use the content
// iterator for performance reason.
if (!aContent->HasChildren()) {
@ -1490,12 +1490,12 @@ nsresult Selection::SelectAllFramesForContent(
return NS_OK;
}
if (NS_WARN_IF(NS_FAILED(aPostOrderIter->Init(aContent)))) {
if (NS_WARN_IF(NS_FAILED(aPostOrderIter.Init(aContent)))) {
return NS_ERROR_FAILURE;
}
for (; !aPostOrderIter->IsDone(); aPostOrderIter->Next()) {
nsINode* node = aPostOrderIter->GetCurrentNode();
for (; !aPostOrderIter.IsDone(); aPostOrderIter.Next()) {
nsINode* node = aPostOrderIter.GetCurrentNode();
MOZ_ASSERT(node);
nsIContent* innercontent = node->IsContent() ? node->AsContent() : nullptr;
SelectFramesForContent(innercontent, aSelected);
@ -1575,15 +1575,15 @@ nsresult Selection::SelectFrames(nsPresContext* aPresContext, nsRange* aRange,
return NS_OK;
}
RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
subtreeIter->Init(aRange);
if (isFirstContentTextNode && !subtreeIter->IsDone() &&
subtreeIter->GetCurrentNode() == startNode) {
subtreeIter->Next(); // first content has already been handled.
ContentSubtreeIterator subtreeIter;
subtreeIter.Init(aRange);
if (isFirstContentTextNode && !subtreeIter.IsDone() &&
subtreeIter.GetCurrentNode() == startNode) {
subtreeIter.Next(); // first content has already been handled.
}
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
nsINode* node = subtreeIter->GetCurrentNode();
PostContentIterator postOrderIter;
for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
nsINode* node = subtreeIter.GetCurrentNode();
MOZ_ASSERT(node);
nsIContent* content = node->IsContent() ? node->AsContent() : nullptr;
SelectAllFramesForContent(postOrderIter, content, aSelect);

View File

@ -592,7 +592,7 @@ class Selection final : public nsSupportsWeakReference,
*/
void SetAnchorFocusRange(int32_t aIndex);
void SelectFramesForContent(nsIContent* aContent, bool aSelected);
nsresult SelectAllFramesForContent(PostContentIterator* aPostOrderIter,
nsresult SelectAllFramesForContent(PostContentIterator& aPostOrderIter,
nsIContent* aContent, bool aSelected);
nsresult SelectFrames(nsPresContext* aPresContext, nsRange* aRange,
bool aSelect);

View File

@ -890,11 +890,10 @@ void nsContentList::AssertInSync() {
? mRootNode->AsDocument()->GetRootElement()
: mRootNode->AsContent();
RefPtr<PreContentIterator> preOrderIter;
PreContentIterator preOrderIter;
if (mDeep) {
preOrderIter = new PreContentIterator();
preOrderIter->Init(root);
preOrderIter->First();
preOrderIter.Init(root);
preOrderIter.First();
}
uint32_t cnt = 0, index = 0;
@ -904,7 +903,7 @@ void nsContentList::AssertInSync() {
}
nsIContent* cur =
mDeep ? preOrderIter->GetCurrentNode() : mRootNode->GetChildAt(index++);
mDeep ? preOrderIter.GetCurrentNode() : mRootNode->GetChildAt(index++);
if (!cur) {
break;
}
@ -916,7 +915,7 @@ void nsContentList::AssertInSync() {
}
if (mDeep) {
preOrderIter->Next();
preOrderIter.Next();
}
}

View File

@ -31,6 +31,7 @@
#include "mozilla/dom/Selection.h"
#include "mozilla/dom/Text.h"
#include "mozilla/Telemetry.h"
#include "mozilla/UniquePtr.h"
#include "mozilla/Likely.h"
#include "nsCSSFrameConstructor.h"
#include "nsStyleStruct.h"
@ -1500,7 +1501,7 @@ class MOZ_STACK_CLASS RangeSubtreeIterator {
private:
enum RangeSubtreeIterState { eDone = 0, eUseStart, eUseIterator, eUseEnd };
RefPtr<ContentSubtreeIterator> mSubtreeIter;
UniquePtr<ContentSubtreeIterator> mSubtreeIter;
RangeSubtreeIterState mIterState;
nsCOMPtr<nsINode> mStart;
@ -1562,7 +1563,7 @@ nsresult RangeSubtreeIterator::Init(nsRange* aRange) {
// Now create a Content Subtree Iterator to be used
// for the subtrees between the end points!
mSubtreeIter = new ContentSubtreeIterator();
mSubtreeIter = MakeUnique<ContentSubtreeIterator>();
nsresult res = mSubtreeIter->Init(aRange);
if (NS_FAILED(res)) return res;
@ -2616,8 +2617,8 @@ void nsRange::ToString(nsAString& aReturn, ErrorResult& aErr) {
tradeoffs.
*/
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
nsresult rv = postOrderIter->Init(this);
PostContentIterator postOrderIter;
nsresult rv = postOrderIter.Init(this);
if (NS_WARN_IF(NS_FAILED(rv))) {
aErr.Throw(rv);
return;
@ -2627,8 +2628,8 @@ void nsRange::ToString(nsAString& aReturn, ErrorResult& aErr) {
// loop through the content iterator, which returns nodes in the range in
// close tag order, and grab the text from any text node
for (; !postOrderIter->IsDone(); postOrderIter->Next()) {
nsINode* n = postOrderIter->GetCurrentNode();
for (; !postOrderIter.IsDone(); postOrderIter.Next()) {
nsINode* n = postOrderIter.GetCurrentNode();
#ifdef DEBUG_range
// If debug, dump it:
@ -3057,8 +3058,8 @@ void nsRange::ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges) {
nsRange* range = this;
RefPtr<nsRange> newRange;
while (range) {
RefPtr<PreContentIterator> preOrderIter = new PreContentIterator();
nsresult rv = preOrderIter->Init(range);
PreContentIterator preOrderIter;
nsresult rv = preOrderIter.Init(range);
if (NS_FAILED(rv)) {
return;
}
@ -3072,8 +3073,8 @@ void nsRange::ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges) {
nsIContent* firstNonSelectableContent = nullptr;
while (true) {
ErrorResult err;
nsINode* node = preOrderIter->GetCurrentNode();
preOrderIter->Next();
nsINode* node = preOrderIter.GetCurrentNode();
preOrderIter.Next();
bool selectable = true;
nsIContent* content =
node && node->IsContent() ? node->AsContent() : nullptr;
@ -3099,7 +3100,7 @@ void nsRange::ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges) {
if (!firstNonSelectableContent) {
firstNonSelectableContent = content;
}
if (preOrderIter->IsDone() && seenSelectable) {
if (preOrderIter.IsDone() && seenSelectable) {
// The tail end of the initial range is non-selectable - truncate the
// current range before the first non-selectable node.
range->SetEndBefore(*firstNonSelectableContent, err);
@ -3155,7 +3156,7 @@ void nsRange::ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges) {
aOutRanges->AppendElement(range);
}
}
if (preOrderIter->IsDone()) {
if (preOrderIter.IsDone()) {
return;
}
}

View File

@ -731,14 +731,14 @@ nsresult ContentEventHandler::GenerateFlatTextContent(
return NS_OK;
}
RefPtr<PreContentIterator> preOrderIter = new PreContentIterator();
PreContentIterator preOrderIter;
nsresult rv =
preOrderIter->Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
preOrderIter.Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
for (; !preOrderIter->IsDone(); preOrderIter->Next()) {
nsINode* node = preOrderIter->GetCurrentNode();
for (; !preOrderIter.IsDone(); preOrderIter.Next()) {
nsINode* node = preOrderIter.GetCurrentNode();
if (NS_WARN_IF(!node)) {
break;
}
@ -892,14 +892,14 @@ nsresult ContentEventHandler::GenerateFlatFontRanges(
// baseOffset is the flattened offset of each content node.
int32_t baseOffset = 0;
RefPtr<PreContentIterator> preOrderIter = new PreContentIterator();
PreContentIterator preOrderIter;
nsresult rv =
preOrderIter->Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
preOrderIter.Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
for (; !preOrderIter->IsDone(); preOrderIter->Next()) {
nsINode* node = preOrderIter->GetCurrentNode();
for (; !preOrderIter.IsDone(); preOrderIter.Next()) {
nsINode* node = preOrderIter.GetCurrentNode();
if (NS_WARN_IF(!node)) {
break;
}
@ -1018,8 +1018,8 @@ nsresult ContentEventHandler::SetRawRangeFromFlatTextOffset(
}
}
RefPtr<PreContentIterator> preOrderIter = new PreContentIterator();
nsresult rv = preOrderIter->Init(mRootContent);
PreContentIterator preOrderIter;
nsresult rv = preOrderIter.Init(mRootContent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -1027,8 +1027,8 @@ nsresult ContentEventHandler::SetRawRangeFromFlatTextOffset(
uint32_t offset = 0;
uint32_t endOffset = aOffset + aLength;
bool startSet = false;
for (; !preOrderIter->IsDone(); preOrderIter->Next()) {
nsINode* node = preOrderIter->GetCurrentNode();
for (; !preOrderIter.IsDone(); preOrderIter.Next()) {
nsINode* node = preOrderIter.GetCurrentNode();
if (NS_WARN_IF(!node)) {
break;
}
@ -1450,14 +1450,14 @@ ContentEventHandler::FrameAndNodeOffset
ContentEventHandler::GetFirstFrameInRangeForTextRect(
const RawRange& aRawRange) {
NodePosition nodePosition;
RefPtr<PreContentIterator> preOrderIter = new PreContentIterator();
PreContentIterator preOrderIter;
nsresult rv =
preOrderIter->Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
preOrderIter.Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
if (NS_WARN_IF(NS_FAILED(rv))) {
return FrameAndNodeOffset();
}
for (; !preOrderIter->IsDone(); preOrderIter->Next()) {
nsINode* node = preOrderIter->GetCurrentNode();
for (; !preOrderIter.IsDone(); preOrderIter.Next()) {
nsINode* node = preOrderIter.GetCurrentNode();
if (NS_WARN_IF(!node)) {
break;
}
@ -1499,9 +1499,9 @@ ContentEventHandler::GetFirstFrameInRangeForTextRect(
ContentEventHandler::FrameAndNodeOffset
ContentEventHandler::GetLastFrameInRangeForTextRect(const RawRange& aRawRange) {
NodePosition nodePosition;
RefPtr<PreContentIterator> preOrderIter = new PreContentIterator();
PreContentIterator preOrderIter;
nsresult rv =
preOrderIter->Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
preOrderIter.Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
if (NS_WARN_IF(NS_FAILED(rv))) {
return FrameAndNodeOffset();
}
@ -1538,8 +1538,8 @@ ContentEventHandler::GetLastFrameInRangeForTextRect(const RawRange& aRawRange) {
nextNodeOfRangeEnd = endPoint.GetChildAtOffset();
}
for (preOrderIter->Last(); !preOrderIter->IsDone(); preOrderIter->Prev()) {
nsINode* node = preOrderIter->GetCurrentNode();
for (preOrderIter.Last(); !preOrderIter.IsDone(); preOrderIter.Prev()) {
nsINode* node = preOrderIter.GetCurrentNode();
if (NS_WARN_IF(!node)) {
break;
}
@ -2110,8 +2110,8 @@ nsresult ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent) {
NS_ENSURE_SUCCESS(rv, rv);
// used to iterate over all contents and their frames
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
rv = postOrderIter->Init(rawRange.Start().AsRaw(), rawRange.End().AsRaw());
PostContentIterator postOrderIter;
rv = postOrderIter.Init(rawRange.Start().AsRaw(), rawRange.End().AsRaw());
if (NS_WARN_IF(NS_FAILED(rv))) {
return NS_ERROR_FAILURE;
}
@ -2298,8 +2298,8 @@ nsresult ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent) {
frame = frame->GetNextContinuation();
if (!frame) {
do {
postOrderIter->Next();
nsINode* node = postOrderIter->GetCurrentNode();
postOrderIter.Next();
nsINode* node = postOrderIter.GetCurrentNode();
if (!node) {
break;
}
@ -2319,7 +2319,7 @@ nsresult ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent) {
if (primaryFrame->IsTextFrame() || primaryFrame->IsBrFrame()) {
frame = primaryFrame;
}
} while (!frame && !postOrderIter->IsDone());
} while (!frame && !postOrderIter.IsDone());
if (!frame) {
break;
}
@ -2658,9 +2658,7 @@ nsresult ContentEventHandler::OnQueryDOMWidgetHittest(
return NS_OK;
}
// Don't create ContentIterator instance until it's really necessary since
// destroying without initializing causes unexpected NS_ASSERTION() call.
RefPtr<PreContentIterator> preOrderIter;
PreContentIterator preOrderIter;
// Working with ContentIterator, we may need to adjust the end position for
// including it forcibly.
@ -2684,8 +2682,7 @@ nsresult ContentEventHandler::OnQueryDOMWidgetHittest(
static_cast<uint32_t>(endPosition.Offset()) ==
endPosition.Container()->GetChildCount(),
"When the node is being removed, the end offset should be child count");
preOrderIter = new PreContentIterator();
nsresult rv = preOrderIter->Init(aStartPosition.Container());
nsresult rv = preOrderIter.Init(aStartPosition.Container());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2729,9 +2726,8 @@ nsresult ContentEventHandler::OnQueryDOMWidgetHittest(
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
preOrderIter = new PreContentIterator();
rv = preOrderIter->Init(prevRawRange.Start().AsRaw(),
prevRawRange.End().AsRaw());
rv = preOrderIter.Init(prevRawRange.Start().AsRaw(),
prevRawRange.End().AsRaw());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2741,16 +2737,14 @@ nsresult ContentEventHandler::OnQueryDOMWidgetHittest(
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
preOrderIter = new PreContentIterator();
rv = preOrderIter->Init(prevRawRange.Start().AsRaw(),
prevRawRange.End().AsRaw());
rv = preOrderIter.Init(prevRawRange.Start().AsRaw(),
prevRawRange.End().AsRaw());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
} else {
// Offset is past the root node; set end of range to end of root node
preOrderIter = new PreContentIterator();
rv = preOrderIter->Init(aRootContent);
rv = preOrderIter.Init(aRootContent);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -2758,8 +2752,8 @@ nsresult ContentEventHandler::OnQueryDOMWidgetHittest(
}
*aLength = 0;
for (; !preOrderIter->IsDone(); preOrderIter->Next()) {
nsINode* node = preOrderIter->GetCurrentNode();
for (; !preOrderIter.IsDone(); preOrderIter.Next()) {
nsINode* node = preOrderIter.GetCurrentNode();
if (NS_WARN_IF(!node)) {
break;
}

View File

@ -214,13 +214,12 @@ nsresult DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween(
return NS_ERROR_NOT_AVAILABLE;
}
RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
nsresult rv = subtreeIter->Init(aRangeToDelete);
ContentSubtreeIterator subtreeIter;
nsresult rv = subtreeIter.Init(aRangeToDelete);
NS_ENSURE_SUCCESS(rv, rv);
while (!subtreeIter->IsDone()) {
nsCOMPtr<nsINode> node = subtreeIter->GetCurrentNode();
while (!subtreeIter.IsDone()) {
nsCOMPtr<nsINode> node = subtreeIter.GetCurrentNode();
if (NS_WARN_IF(!node)) {
return NS_ERROR_NULL_POINTER;
}
@ -236,7 +235,7 @@ nsresult DeleteRangeTransaction::CreateTxnsToDeleteNodesBetween(
}
AppendChild(deleteNodeTransaction);
subtreeIter->Next();
subtreeIter.Next();
}
return NS_OK;
}

View File

@ -28,25 +28,22 @@ using namespace dom;
* some helper classes for iterating the dom tree
*****************************************************************************/
DOMIterator::DOMIterator(
nsINode& aNode MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL) {
DOMIterator::DOMIterator(nsINode& aNode MOZ_GUARD_OBJECT_NOTIFIER_PARAM_IN_IMPL)
: mIter(&mPostOrderIter) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
mIter = new PostContentIterator();
DebugOnly<nsresult> rv = mIter->Init(&aNode);
MOZ_ASSERT(NS_SUCCEEDED(rv));
}
nsresult DOMIterator::Init(nsRange& aRange) {
mIter = new PostContentIterator();
return mIter->Init(&aRange);
}
DOMIterator::DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL) {
DOMIterator::DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
: mIter(&mPostOrderIter) {
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
}
DOMIterator::~DOMIterator() {}
void DOMIterator::AppendList(
const BoolDomIterFunctor& functor,
nsTArray<OwningNonNull<nsINode>>& arrayOfNodes) const {
@ -62,14 +59,13 @@ void DOMIterator::AppendList(
DOMSubtreeIterator::DOMSubtreeIterator(
MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_IN_IMPL)
: DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) {}
nsresult DOMSubtreeIterator::Init(nsRange& aRange) {
mIter = new ContentSubtreeIterator();
return mIter->Init(&aRange);
: DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM_TO_PARENT) {
mIter = &mSubtreeIter;
}
DOMSubtreeIterator::~DOMSubtreeIterator() {}
nsresult DOMSubtreeIterator::Init(nsRange& aRange) {
return mIter->Init(&aRange);
}
/******************************************************************************
* some general purpose editor utils

View File

@ -450,7 +450,7 @@ class MOZ_RAII DOMIterator {
explicit DOMIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
explicit DOMIterator(nsINode& aNode MOZ_GUARD_OBJECT_NOTIFIER_PARAM);
virtual ~DOMIterator();
virtual ~DOMIterator() = default;
nsresult Init(nsRange& aRange);
@ -459,16 +459,22 @@ class MOZ_RAII DOMIterator {
nsTArray<mozilla::OwningNonNull<nsINode>>& arrayOfNodes) const;
protected:
RefPtr<ContentIteratorBase> mIter;
ContentIteratorBase* mIter;
PostContentIterator mPostOrderIter;
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
};
class MOZ_RAII DOMSubtreeIterator final : public DOMIterator {
public:
explicit DOMSubtreeIterator(MOZ_GUARD_OBJECT_NOTIFIER_ONLY_PARAM);
virtual ~DOMSubtreeIterator();
virtual ~DOMSubtreeIterator() = default;
nsresult Init(nsRange& aRange);
private:
ContentSubtreeIterator mSubtreeIter;
explicit DOMSubtreeIterator(nsINode& aNode MOZ_GUARD_OBJECT_NOTIFIER_PARAM) =
delete;
};
class TrivialFunctor final : public BoolDomIterFunctor {

View File

@ -9437,10 +9437,8 @@ nsresult HTMLEditRules::RemoveEmptyNodesInChangedRange() {
// include some children of a node while excluding others. Thus I could find
// all the _examined_ children empty, but still not have an empty parent.
// need an iterator
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
nsresult rv = postOrderIter->Init(mDocChangeRange);
PostContentIterator postOrderIter;
nsresult rv = postOrderIter.Init(mDocChangeRange);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -9449,8 +9447,8 @@ nsresult HTMLEditRules::RemoveEmptyNodesInChangedRange() {
skipList;
// Check for empty nodes
for (; !postOrderIter->IsDone(); postOrderIter->Next()) {
OwningNonNull<nsINode> node = *postOrderIter->GetCurrentNode();
for (; !postOrderIter.IsDone(); postOrderIter.Next()) {
OwningNonNull<nsINode> node = *postOrderIter.GetCurrentNode();
nsCOMPtr<nsINode> parent = node->GetParentNode();

View File

@ -1124,13 +1124,13 @@ nsresult HTMLEditor::TabInTable(bool inIsShift, bool* outHandled) {
// advance to next cell
// first create an iterator over the table
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
nsresult rv = postOrderIter->Init(table);
PostContentIterator postOrderIter;
nsresult rv = postOrderIter.Init(table);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
// position postOrderIter at block
rv = postOrderIter->PositionAt(cellElement);
rv = postOrderIter.PositionAt(cellElement);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
@ -1138,12 +1138,12 @@ nsresult HTMLEditor::TabInTable(bool inIsShift, bool* outHandled) {
nsCOMPtr<nsINode> node;
do {
if (inIsShift) {
postOrderIter->Prev();
postOrderIter.Prev();
} else {
postOrderIter->Next();
postOrderIter.Next();
}
node = postOrderIter->GetCurrentNode();
node = postOrderIter.GetCurrentNode();
if (node && HTMLEditUtils::IsTableCell(node) &&
GetEnclosingTable(node) == table) {
@ -1151,7 +1151,7 @@ nsresult HTMLEditor::TabInTable(bool inIsShift, bool* outHandled) {
*outHandled = true;
return NS_OK;
}
} while (!postOrderIter->IsDone());
} while (!postOrderIter.IsDone());
if (!(*outHandled) && !inIsShift) {
// If we haven't handled it yet, then we must have run off the end of the
@ -2786,12 +2786,12 @@ already_AddRefed<Element> HTMLEditor::GetSelectedElement(const nsAtom* aTagName,
return nullptr;
}
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
postOrderIter->Init(firstRange);
PostContentIterator postOrderIter;
postOrderIter.Init(firstRange);
RefPtr<Element> lastElementInRange;
for (nsINode* lastNodeInRange = nullptr; !postOrderIter->IsDone();
postOrderIter->Next()) {
for (nsINode* lastNodeInRange = nullptr; !postOrderIter.IsDone();
postOrderIter.Next()) {
if (lastElementInRange) {
// When any node follows an element node, not only one element is
// selected so that return nullptr.
@ -2809,7 +2809,7 @@ already_AddRefed<Element> HTMLEditor::GetSelectedElement(const nsAtom* aTagName,
// it means that the range across element boundary (open tag in HTML
// source). So, in this case, we should not say only the following
// element is selected.
nsINode* currentNode = postOrderIter->GetCurrentNode();
nsINode* currentNode = postOrderIter.GetCurrentNode();
MOZ_ASSERT(currentNode);
if (lastNodeInRange && lastNodeInRange->GetParentNode() != currentNode &&
lastNodeInRange->GetNextSibling() != currentNode) {
@ -3062,15 +3062,15 @@ HTMLEditor::GetLinkedObjects(nsIArray** aNodeList) {
return rv;
}
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
RefPtr<Document> doc = GetDocument();
NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
postOrderIter->Init(doc->GetRootElement());
PostContentIterator postOrderIter;
postOrderIter.Init(doc->GetRootElement());
// loop through the content iterator for each content node
for (; !postOrderIter->IsDone(); postOrderIter->Next()) {
nsCOMPtr<nsINode> node = postOrderIter->GetCurrentNode();
for (; !postOrderIter.IsDone(); postOrderIter.Next()) {
nsCOMPtr<nsINode> node = postOrderIter.GetCurrentNode();
if (node) {
// Let nsURIRefObject make the hard decisions:
nsCOMPtr<nsIURIRefObject> refObject;
@ -3778,18 +3778,14 @@ nsresult HTMLEditor::CollapseAdjacentTextNodes(nsRange* aInRange) {
// for the lifetime of this method
// build a list of editable text nodes
RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
subtreeIter->Init(aInRange);
while (!subtreeIter->IsDone()) {
nsINode* node = subtreeIter->GetCurrentNode();
ContentSubtreeIterator subtreeIter;
subtreeIter.Init(aInRange);
for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
nsINode* node = subtreeIter.GetCurrentNode();
if (node->NodeType() == nsINode::TEXT_NODE &&
IsEditable(node->AsContent())) {
textNodes.AppendElement(node);
}
subtreeIter->Next();
}
// now that I have a list of text nodes, collapse adjacent text nodes
@ -4440,20 +4436,18 @@ nsresult HTMLEditor::SetCSSBackgroundColorWithTransaction(
// them (since doing operations on the document during iteration would
// perturb the iterator).
RefPtr<ContentSubtreeIterator> subtreeIter =
new ContentSubtreeIterator();
nsTArray<OwningNonNull<nsINode>> arrayOfNodes;
nsCOMPtr<nsINode> node;
// Iterate range and build up array
rv = subtreeIter->Init(range);
ContentSubtreeIterator subtreeIter;
rv = subtreeIter.Init(range);
// Init returns an error if no nodes in range. This can easily happen
// with the subtree iterator if the selection doesn't contain any
// *whole* nodes.
if (NS_SUCCEEDED(rv)) {
for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
node = subtreeIter->GetCurrentNode();
for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
node = subtreeIter.GetCurrentNode();
NS_ENSURE_TRUE(node, NS_ERROR_FAILURE);
if (IsEditable(node)) {

View File

@ -175,18 +175,17 @@ nsresult HTMLEditor::SetInlinePropertyInternal(nsAtom& aProperty,
// (since doing operations on the document during iteration would perturb
// the iterator).
RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
// Iterate range and build up array
rv = subtreeIter->Init(range);
ContentSubtreeIterator subtreeIter;
rv = subtreeIter.Init(range);
// Init returns an error if there are no nodes in range. This can easily
// happen with the subtree iterator if the selection doesn't contain any
// *whole* nodes.
if (NS_SUCCEEDED(rv)) {
for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
OwningNonNull<nsINode> node = *subtreeIter->GetCurrentNode();
for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
OwningNonNull<nsINode> node = *subtreeIter.GetCurrentNode();
if (node->IsContent() && IsEditable(node)) {
arrayOfNodes.AppendElement(*node->AsContent());
@ -1041,20 +1040,22 @@ nsresult HTMLEditor::GetInlinePropertyBase(nsAtom& aProperty,
}
// Non-collapsed selection
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
nsAutoString firstValue, theValue;
nsCOMPtr<nsINode> endNode = range->GetEndContainer();
int32_t endOffset = range->EndOffset();
for (postOrderIter->Init(range); !postOrderIter->IsDone();
postOrderIter->Next()) {
if (!postOrderIter->GetCurrentNode()->IsContent()) {
PostContentIterator postOrderIter;
DebugOnly<nsresult> rvIgnored = postOrderIter.Init(range);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"Failed to initialize post-order content iterator");
for (; !postOrderIter.IsDone(); postOrderIter.Next()) {
if (!postOrderIter.GetCurrentNode()->IsContent()) {
continue;
}
nsCOMPtr<nsIContent> content =
postOrderIter->GetCurrentNode()->AsContent();
postOrderIter.GetCurrentNode()->AsContent();
if (content->IsHTMLElement(nsGkAtoms::body)) {
break;
@ -1343,15 +1344,16 @@ nsresult HTMLEditor::RemoveInlinePropertyInternal(nsAtom* aProperty,
}
} else {
// Not the easy case. Range not contained in single text node.
RefPtr<ContentSubtreeIterator> subtreeIter =
new ContentSubtreeIterator();
nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
// Iterate range and build up array
for (subtreeIter->Init(range); !subtreeIter->IsDone();
subtreeIter->Next()) {
nsCOMPtr<nsINode> node = subtreeIter->GetCurrentNode();
ContentSubtreeIterator subtreeIter;
DebugOnly<nsresult> rvIgnored = subtreeIter.Init(range);
NS_WARNING_ASSERTION(NS_SUCCEEDED(rvIgnored),
"Failed to initialize subtree iterator");
for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
nsCOMPtr<nsINode> node = subtreeIter.GetCurrentNode();
if (NS_WARN_IF(!node)) {
return NS_ERROR_FAILURE;
}
@ -1492,18 +1494,17 @@ nsresult HTMLEditor::RelativeFontChange(FontSize aDir) {
// (since doing operations on the document during iteration would perturb
// the iterator).
RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
// Iterate range and build up array
rv = subtreeIter->Init(range);
ContentSubtreeIterator subtreeIter;
rv = subtreeIter.Init(range);
if (NS_SUCCEEDED(rv)) {
nsTArray<OwningNonNull<nsIContent>> arrayOfNodes;
for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
if (NS_WARN_IF(!subtreeIter->GetCurrentNode()->IsContent())) {
for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
if (NS_WARN_IF(!subtreeIter.GetCurrentNode()->IsContent())) {
return NS_ERROR_FAILURE;
}
OwningNonNull<nsIContent> node =
*subtreeIter->GetCurrentNode()->AsContent();
*subtreeIter.GetCurrentNode()->AsContent();
if (IsEditable(node)) {
arrayOfNodes.AppendElement(node);

View File

@ -1455,12 +1455,11 @@ TextEditor::GetTextLength(int32_t* aCount) {
return NS_ERROR_FAILURE;
}
RefPtr<PostContentIterator> postOrderIter = new PostContentIterator();
uint32_t totalLength = 0;
postOrderIter->Init(rootElement);
for (; !postOrderIter->IsDone(); postOrderIter->Next()) {
nsCOMPtr<nsINode> currentNode = postOrderIter->GetCurrentNode();
PostContentIterator postOrderIter;
postOrderIter.Init(rootElement);
for (; !postOrderIter.IsDone(); postOrderIter.Next()) {
nsCOMPtr<nsINode> currentNode = postOrderIter.GetCurrentNode();
if (IsTextNode(currentNode) && IsEditable(currentNode)) {
totalLength += currentNode->Length();
}

View File

@ -25,8 +25,7 @@ namespace mozilla {
FilteredContentIterator::FilteredContentIterator(
UniquePtr<nsComposeTxtSrvFilter> aFilter)
: mPostIterator(new PostContentIterator()),
mPreIterator(new PreContentIterator()),
: mCurrentIterator(nullptr),
mFilter(std::move(aFilter)),
mDidSkip(false),
mIsOutOfRange(false),
@ -34,26 +33,24 @@ FilteredContentIterator::FilteredContentIterator(
FilteredContentIterator::~FilteredContentIterator() {}
NS_IMPL_CYCLE_COLLECTION(FilteredContentIterator, mCurrentIterator,
mPostIterator, mPreIterator, mRange)
NS_IMPL_CYCLE_COLLECTION(FilteredContentIterator, mPostIterator, mPreIterator,
mRange)
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(FilteredContentIterator, AddRef)
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(FilteredContentIterator, Release)
nsresult FilteredContentIterator::Init(nsINode* aRoot) {
NS_ENSURE_ARG_POINTER(aRoot);
NS_ENSURE_TRUE(mPreIterator, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(mPostIterator, NS_ERROR_FAILURE);
mIsOutOfRange = false;
mDirection = eForward;
mCurrentIterator = mPreIterator;
mCurrentIterator = &mPreIterator;
mRange = new nsRange(aRoot);
mRange->SelectNode(*aRoot, IgnoreErrors());
nsresult rv = mPreIterator->Init(mRange);
nsresult rv = mPreIterator.Init(mRange);
NS_ENSURE_SUCCESS(rv, rv);
return mPostIterator->Init(mRange);
return mPostIterator.Init(mRange);
}
nsresult FilteredContentIterator::Init(nsRange* aRange) {
@ -99,29 +96,25 @@ nsresult FilteredContentIterator::InitWithRange() {
MOZ_ASSERT(mRange);
MOZ_ASSERT(mRange->IsPositioned());
if (NS_WARN_IF(!mPreIterator) || NS_WARN_IF(!mPostIterator)) {
return NS_ERROR_FAILURE;
}
mIsOutOfRange = false;
mDirection = eForward;
mCurrentIterator = mPreIterator;
mCurrentIterator = &mPreIterator;
nsresult rv = mPreIterator->Init(mRange);
nsresult rv = mPreIterator.Init(mRange);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
return mPostIterator->Init(mRange);
return mPostIterator.Init(mRange);
}
nsresult FilteredContentIterator::SwitchDirections(bool aChangeToForward) {
nsINode* node = mCurrentIterator->GetCurrentNode();
if (aChangeToForward) {
mCurrentIterator = mPreIterator;
mCurrentIterator = &mPreIterator;
mDirection = eForward;
} else {
mCurrentIterator = mPostIterator;
mCurrentIterator = &mPostIterator;
mDirection = eBackward;
}
@ -145,7 +138,7 @@ void FilteredContentIterator::First() {
// If we are switching directions then
// we need to switch how we process the nodes
if (mDirection != eForward) {
mCurrentIterator = mPreIterator;
mCurrentIterator = &mPreIterator;
mDirection = eForward;
mIsOutOfRange = false;
}
@ -172,7 +165,7 @@ void FilteredContentIterator::Last() {
// If we are switching directions then
// we need to switch how we process the nodes
if (mDirection != eBackward) {
mCurrentIterator = mPostIterator;
mCurrentIterator = &mPostIterator;
mDirection = eBackward;
mIsOutOfRange = false;
}

View File

@ -61,9 +61,9 @@ class FilteredContentIterator final {
void CheckAdvNode(nsINode* aNode, bool& aDidSkip, eDirectionType aDir);
nsresult SwitchDirections(bool aChangeToForward);
RefPtr<ContentIteratorBase> mCurrentIterator;
RefPtr<PostContentIterator> mPostIterator;
RefPtr<PreContentIterator> mPreIterator;
ContentIteratorBase* MOZ_NON_OWNING_REF mCurrentIterator;
PostContentIterator mPostIterator;
PreContentIterator mPreIterator;
RefPtr<nsAtom> mBlockQuoteAtom;
RefPtr<nsAtom> mScriptAtom;

View File

@ -4664,8 +4664,8 @@ UniquePtr<RangePaintInfo> PresShell::CreateRangePaintInfo(
}
info->mBuilder.EnterPresShell(ancestorFrame);
RefPtr<ContentSubtreeIterator> subtreeIter = new ContentSubtreeIterator();
nsresult rv = subtreeIter->Init(aRange);
ContentSubtreeIterator subtreeIter;
nsresult rv = subtreeIter.Init(aRange);
if (NS_FAILED(rv)) {
return nullptr;
}
@ -4686,8 +4686,8 @@ UniquePtr<RangePaintInfo> PresShell::CreateRangePaintInfo(
if (startContainer->NodeType() == nsINode::TEXT_NODE) {
BuildDisplayListForNode(startContainer);
}
for (; !subtreeIter->IsDone(); subtreeIter->Next()) {
nsCOMPtr<nsINode> node = subtreeIter->GetCurrentNode();
for (; !subtreeIter.IsDone(); subtreeIter.Next()) {
nsCOMPtr<nsINode> node = subtreeIter.GetCurrentNode();
BuildDisplayListForNode(node);
}
if (endContainer != startContainer &&