зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
f8844f0d9b
Коммит
f421d7b889
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 &&
|
||||
|
|
Загрузка…
Ссылка в новой задаче