Bug 779684: Create a stack-based nsFrameIterator class out of nsIFrameTraversal and nsIFrameEnumerator r=roc

--HG--
rename : layout/base/nsFrameTraversal.cpp => layout/base/nsFrameIterator.cpp
rename : layout/base/nsFrameTraversal.h => layout/base/nsFrameIterator.h
This commit is contained in:
David Zbarsky 2012-08-05 23:00:55 -04:00
Родитель bfbcf21932
Коммит dca3fd6326
12 изменённых файлов: 207 добавлений и 462 удалений

Просмотреть файл

@ -65,7 +65,6 @@
#include "nsCaret.h" #include "nsCaret.h"
#include "nsSubDocumentFrame.h" #include "nsSubDocumentFrame.h"
#include "nsIFrameTraversal.h"
#include "nsLayoutCID.h" #include "nsLayoutCID.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsIInterfaceRequestorUtils.h" #include "nsIInterfaceRequestorUtils.h"
@ -112,8 +111,6 @@ using namespace mozilla::dom;
#define NS_USER_INTERACTION_INTERVAL 5000 // ms #define NS_USER_INTERACTION_INTERVAL 5000 // ms
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
static bool sLeftClickOnly = true; static bool sLeftClickOnly = true;
static bool sKeyCausesActivation = true; static bool sKeyCausesActivation = true;
static PRUint32 sESMInstanceCount = 0; static PRUint32 sESMInstanceCount = 0;

Просмотреть файл

@ -32,7 +32,7 @@
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsIPresShell.h" #include "nsIPresShell.h"
#include "nsIContentViewer.h" #include "nsIContentViewer.h"
#include "nsFrameTraversal.h" #include "nsFrameIterator.h"
#include "nsObjectFrame.h" #include "nsObjectFrame.h"
#include "nsEventDispatcher.h" #include "nsEventDispatcher.h"
#include "nsEventStateManager.h" #include "nsEventStateManager.h"
@ -2271,15 +2271,8 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
if (nodeValue.Length() == (PRUint32)startOffset && !isFormControl && if (nodeValue.Length() == (PRUint32)startOffset && !isFormControl &&
startContent != aDocument->GetRootElement()) { startContent != aDocument->GetRootElement()) {
// Yes, indeed we were at the end of the last node // Yes, indeed we were at the end of the last node
nsCOMPtr<nsIFrameEnumerator> frameTraversal; nsFrameIterator frameTraversal(presContext, startFrame,
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), eLeaf, FrameIteratorFlags::FLAG_FOLLOW_OUT_OF_FLOW);
presContext, startFrame,
eLeaf,
false, // aVisual
false, // aLockInScrollView
true // aFollowOOFs
);
NS_ENSURE_SUCCESS(rv, rv);
nsIFrame *newCaretFrame = nullptr; nsIFrame *newCaretFrame = nullptr;
nsCOMPtr<nsIContent> newCaretContent = startContent; nsCOMPtr<nsIContent> newCaretContent = startContent;
@ -2287,11 +2280,11 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
do { do {
// Continue getting the next frame until the primary content for the frame // Continue getting the next frame until the primary content for the frame
// we are on changes - we don't want to be stuck in the same place // we are on changes - we don't want to be stuck in the same place
frameTraversal->Next(); frameTraversal.Next();
newCaretFrame = static_cast<nsIFrame*>(frameTraversal->CurrentItem()); newCaretFrame = static_cast<nsIFrame*>(frameTraversal.CurrentItem());
if (nullptr == newCaretFrame) if (nullptr == newCaretFrame)
break; break;
newCaretContent = newCaretFrame->GetContent(); newCaretContent = newCaretFrame->GetContent();
} while (!newCaretContent || newCaretContent == startContent); } while (!newCaretContent || newCaretContent == startContent);
if (newCaretFrame && newCaretContent) { if (newCaretFrame && newCaretContent) {
@ -2704,21 +2697,14 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
continue; continue;
} }
nsCOMPtr<nsIFrameEnumerator> frameTraversal; nsFrameIterator frameTraversal(presContext, startFrame,
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), ePreOrder, FrameIteratorFlags::FLAG_FOLLOW_OUT_OF_FLOW);
presContext, startFrame,
ePreOrder,
false, // aVisual
false, // aLockInScrollView
true // aFollowOOFs
);
NS_ENSURE_SUCCESS(rv, rv);
if (iterStartContent == aRootContent) { if (iterStartContent == aRootContent) {
if (!aForward) { if (!aForward) {
frameTraversal->Last(); frameTraversal.Last();
} else if (aRootContent->IsFocusable()) { } else if (aRootContent->IsFocusable()) {
frameTraversal->Next(); frameTraversal.Next();
} }
} }
else if (getNextFrame && else if (getNextFrame &&
@ -2727,13 +2713,13 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
// Need to do special check in case we're in an imagemap which has multiple // Need to do special check in case we're in an imagemap which has multiple
// content nodes per frame, so don't skip over the starting frame. // content nodes per frame, so don't skip over the starting frame.
if (aForward) if (aForward)
frameTraversal->Next(); frameTraversal.Next();
else else
frameTraversal->Prev(); frameTraversal.Prev();
} }
// Walk frames to find something tabbable matching mCurrentTabIndex // Walk frames to find something tabbable matching mCurrentTabIndex
nsIFrame* frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem()); nsIFrame* frame = static_cast<nsIFrame*>(frameTraversal.CurrentItem());
while (frame) { while (frame) {
// TabIndex not set defaults to 0 for form elements, anchors and other // TabIndex not set defaults to 0 for form elements, anchors and other
// elements that are normally focusable. Tabindex defaults to -1 // elements that are normally focusable. Tabindex defaults to -1
@ -2803,10 +2789,10 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
Element* rootElement = subdoc->GetRootElement(); Element* rootElement = subdoc->GetRootElement();
nsIPresShell* subShell = subdoc->GetShell(); nsIPresShell* subShell = subdoc->GetShell();
if (rootElement && subShell) { if (rootElement && subShell) {
rv = GetNextTabbableContent(subShell, rootElement, nsresult rv = GetNextTabbableContent(subShell, rootElement,
aOriginalStartContent, rootElement, aOriginalStartContent, rootElement,
aForward, (aForward ? 1 : 0), aForward, (aForward ? 1 : 0),
false, aResultContent); false, aResultContent);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
if (*aResultContent) if (*aResultContent)
return NS_OK; return NS_OK;
@ -2850,10 +2836,10 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
// again. // again.
do { do {
if (aForward) if (aForward)
frameTraversal->Next(); frameTraversal.Next();
else else
frameTraversal->Prev(); frameTraversal.Prev();
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem()); frame = static_cast<nsIFrame*>(frameTraversal.CurrentItem());
} while (frame && frame->GetPrevContinuation()); } while (frame && frame->GetPrevContinuation());
} }

Просмотреть файл

@ -40,8 +40,7 @@ EXPORTS = \
nsDisplayList.h \ nsDisplayList.h \
nsFrameManager.h \ nsFrameManager.h \
nsFrameManagerBase.h \ nsFrameManagerBase.h \
nsFrameTraversal.h \ nsFrameIterator.h \
nsIFrameTraversal.h \
nsILayoutDebugger.h \ nsILayoutDebugger.h \
nsILayoutHistoryState.h \ nsILayoutHistoryState.h \
nsIPercentHeightObserver.h \ nsIPercentHeightObserver.h \
@ -77,7 +76,7 @@ CPPSRCS = \
nsDisplayList.cpp \ nsDisplayList.cpp \
nsDocumentViewer.cpp \ nsDocumentViewer.cpp \
nsFrameManager.cpp \ nsFrameManager.cpp \
nsFrameTraversal.cpp \ nsFrameIterator.cpp \
nsGenConList.cpp \ nsGenConList.cpp \
nsImageLoader.cpp \ nsImageLoader.cpp \
nsLayoutDebugger.cpp \ nsLayoutDebugger.cpp \

Просмотреть файл

@ -2,215 +2,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public /* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this * License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsCOMPtr.h"
#include "nsGkAtoms.h"
#include "nsFrameTraversal.h" #include "nsFrameIterator.h"
#include "nsFrameList.h" #include "nsIFrame.h"
#include "nsGkAtoms.h"
#include "nsPlaceholderFrame.h" #include "nsPlaceholderFrame.h"
class nsFrameIterator : public nsIFrameEnumerator
{
public:
typedef nsIFrame::ChildListID ChildListID;
NS_DECL_ISUPPORTS
virtual ~nsFrameIterator() {}
virtual void First();
virtual void Next();
virtual nsIFrame* CurrentItem();
virtual bool IsDone();
virtual void Last();
virtual void Prev();
nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
nsIteratorType aType, bool aLockScroll, bool aFollowOOFs);
protected:
void setCurrent(nsIFrame *aFrame){mCurrent = aFrame;}
nsIFrame *getCurrent(){return mCurrent;}
void setStart(nsIFrame *aFrame){mStart = aFrame;}
nsIFrame *getStart(){return mStart;}
nsIFrame *getLast(){return mLast;}
void setLast(nsIFrame *aFrame){mLast = aFrame;}
PRInt8 getOffEdge(){return mOffEdge;}
void setOffEdge(PRInt8 aOffEdge){mOffEdge = aOffEdge;}
void SetLockInScrollView(bool aLockScroll){mLockScroll = aLockScroll;}
/*
Our own versions of the standard frame tree navigation
methods, which, if the iterator is following out-of-flows,
apply the following rules for placeholder frames:
- If a frame HAS a placeholder frame, getting its parent
gets the placeholder's parent.
- If a frame's first child or next/prev sibling IS a
placeholder frame, then we instead return the real frame.
- If a frame HAS a placeholder frame, getting its next/prev
sibling gets the placeholder frame's next/prev sibling.
These are all applied recursively to support multiple levels of
placeholders.
*/
nsIFrame* GetParentFrame(nsIFrame* aFrame);
// like GetParentFrame but returns null once a popup frame is reached
nsIFrame* GetParentFrameNotPopup(nsIFrame* aFrame);
nsIFrame* GetFirstChild(nsIFrame* aFrame);
nsIFrame* GetLastChild(nsIFrame* aFrame);
nsIFrame* GetNextSibling(nsIFrame* aFrame);
nsIFrame* GetPrevSibling(nsIFrame* aFrame);
/*
These methods are overridden by the bidi visual iterator to have the
semantics of "get first child in visual order", "get last child in visual
order", "get next sibling in visual order" and "get previous sibling in visual
order".
*/
virtual nsIFrame* GetFirstChildInner(nsIFrame* aFrame);
virtual nsIFrame* GetLastChildInner(nsIFrame* aFrame);
virtual nsIFrame* GetNextSiblingInner(nsIFrame* aFrame);
virtual nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame);
nsIFrame* GetPlaceholderFrame(nsIFrame* aFrame);
bool IsPopupFrame(nsIFrame* aFrame);
nsPresContext* mPresContext;
bool mLockScroll;
bool mFollowOOFs;
nsIteratorType mType;
private:
nsIFrame *mStart;
nsIFrame *mCurrent;
nsIFrame *mLast; //the last one that was in current;
PRInt8 mOffEdge; //0= no -1 to far prev, 1 to far next;
};
// Bidi visual iterator
class nsVisualIterator: public nsFrameIterator
{
public:
nsVisualIterator(nsPresContext* aPresContext, nsIFrame *aStart,
nsIteratorType aType, bool aLockScroll, bool aFollowOOFs) :
nsFrameIterator(aPresContext, aStart, aType, aLockScroll, aFollowOOFs) {}
protected:
nsIFrame* GetFirstChildInner(nsIFrame* aFrame);
nsIFrame* GetLastChildInner(nsIFrame* aFrame);
nsIFrame* GetNextSiblingInner(nsIFrame* aFrame);
nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame);
};
/************IMPLEMENTATIONS**************/
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult)
{
NS_ENSURE_ARG_POINTER(aResult);
*aResult = nullptr;
nsCOMPtr<nsIFrameTraversal> t(new nsFrameTraversal());
*aResult = t;
NS_ADDREF(*aResult);
return NS_OK;
}
nsresult
NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext,
nsIFrame *aStart,
nsIteratorType aType,
bool aVisual,
bool aLockInScrollView,
bool aFollowOOFs)
{
if (!aEnumerator || !aStart)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIFrameEnumerator> trav;
if (aVisual) {
trav = new nsVisualIterator(aPresContext, aStart, aType,
aLockInScrollView, aFollowOOFs);
} else {
trav = new nsFrameIterator(aPresContext, aStart, aType,
aLockInScrollView, aFollowOOFs);
}
trav.forget(aEnumerator);
return NS_OK;
}
nsFrameTraversal::nsFrameTraversal()
{
}
nsFrameTraversal::~nsFrameTraversal()
{
}
NS_IMPL_ISUPPORTS1(nsFrameTraversal,nsIFrameTraversal)
NS_IMETHODIMP
nsFrameTraversal::NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext,
nsIFrame *aStart,
PRInt32 aType,
bool aVisual,
bool aLockInScrollView,
bool aFollowOOFs)
{
return NS_NewFrameTraversal(aEnumerator, aPresContext, aStart,
static_cast<nsIteratorType>(aType),
aVisual, aLockInScrollView, aFollowOOFs);
}
// nsFrameIterator implementation
NS_IMPL_ISUPPORTS1(nsFrameIterator, nsIFrameEnumerator)
nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart, nsFrameIterator::nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
nsIteratorType aType, bool aLockInScrollView, nsIteratorType aType, PRUint32 aFlags)
bool aFollowOOFs) : mPresContext(aPresContext)
, mOffEdge(0)
, mType(aType)
{ {
mOffEdge = 0; mFollowOOFs = (aFlags & FrameIteratorFlags::FLAG_FOLLOW_OUT_OF_FLOW) != 0;
mPresContext = aPresContext; mLockScroll = (aFlags & FrameIteratorFlags::FLAG_LOCK_SCROLL) != 0;
if (aFollowOOFs && aStart) mVisual = (aFlags & FrameIteratorFlags::FLAG_VISUAL) != 0;
if (mFollowOOFs && aStart)
aStart = nsPlaceholderFrame::GetRealFrameFor(aStart); aStart = nsPlaceholderFrame::GetRealFrameFor(aStart);
setStart(aStart); setStart(aStart);
setCurrent(aStart); setCurrent(aStart);
setLast(aStart); setLast(aStart);
mType = aType;
SetLockInScrollView(aLockInScrollView);
mFollowOOFs = aFollowOOFs;
} }
nsIFrame* nsIFrame*
nsFrameIterator::CurrentItem() nsFrameIterator::CurrentItem()
{ {
if (mOffEdge) return mOffEdge ? nullptr : mCurrent;
return nullptr;
return mCurrent;
} }
bool bool
nsFrameIterator::IsDone() nsFrameIterator::IsDone()
{ {
@ -246,7 +65,7 @@ nsFrameIterator::Last()
while ((result = GetLastChild(parent))) { while ((result = GetLastChild(parent))) {
parent = result; parent = result;
} }
setCurrent(parent); setCurrent(parent);
if (!parent) if (!parent)
setOffEdge(1); setOffEdge(1);
@ -327,7 +146,7 @@ nsFrameIterator::Prev()
if (result) if (result)
parent = result; parent = result;
} }
if (parent != getCurrent()) { if (parent != getCurrent()) {
result = parent; result = parent;
} else { } else {
@ -370,7 +189,7 @@ nsFrameIterator::GetParentFrame(nsIFrame* aFrame)
aFrame = GetPlaceholderFrame(aFrame); aFrame = GetPlaceholderFrame(aFrame);
if (aFrame) if (aFrame)
return aFrame->GetParent(); return aFrame->GetParent();
return nullptr; return nullptr;
} }
@ -384,7 +203,7 @@ nsFrameIterator::GetParentFrameNotPopup(nsIFrame* aFrame)
if (!IsPopupFrame(parent)) if (!IsPopupFrame(parent))
return parent; return parent;
} }
return nullptr; return nullptr;
} }
@ -396,7 +215,7 @@ nsFrameIterator::GetFirstChild(nsIFrame* aFrame)
return nullptr; return nullptr;
if (result && mFollowOOFs) { if (result && mFollowOOFs) {
result = nsPlaceholderFrame::GetRealFrameFor(result); result = nsPlaceholderFrame::GetRealFrameFor(result);
if (IsPopupFrame(result)) if (IsPopupFrame(result))
result = GetNextSibling(result); result = GetNextSibling(result);
} }
@ -411,7 +230,7 @@ nsFrameIterator::GetLastChild(nsIFrame* aFrame)
return nullptr; return nullptr;
if (result && mFollowOOFs) { if (result && mFollowOOFs) {
result = nsPlaceholderFrame::GetRealFrameFor(result); result = nsPlaceholderFrame::GetRealFrameFor(result);
if (IsPopupFrame(result)) if (IsPopupFrame(result))
result = GetPrevSibling(result); result = GetPrevSibling(result);
} }
@ -456,25 +275,42 @@ nsFrameIterator::GetPrevSibling(nsIFrame* aFrame)
nsIFrame* nsIFrame*
nsFrameIterator::GetFirstChildInner(nsIFrame* aFrame) { nsFrameIterator::GetFirstChildInner(nsIFrame* aFrame) {
if (mVisual) {
return aFrame->PrincipalChildList().GetNextVisualFor(nullptr);
}
return aFrame->GetFirstPrincipalChild(); return aFrame->GetFirstPrincipalChild();
} }
nsIFrame* nsIFrame*
nsFrameIterator::GetLastChildInner(nsIFrame* aFrame) { nsFrameIterator::GetLastChildInner(nsIFrame* aFrame) {
if (mVisual) {
return aFrame->PrincipalChildList().GetPrevVisualFor(nullptr);
}
return aFrame->PrincipalChildList().LastChild(); return aFrame->PrincipalChildList().LastChild();
} }
nsIFrame* nsIFrame*
nsFrameIterator::GetNextSiblingInner(nsIFrame* aFrame) { nsFrameIterator::GetNextSiblingInner(nsIFrame* aFrame) {
if (mVisual) {
nsIFrame* parent = GetParentFrame(aFrame);
if (!parent)
return nullptr;
return parent->PrincipalChildList().GetNextVisualFor(aFrame);
}
return aFrame->GetNextSibling(); return aFrame->GetNextSibling();
} }
nsIFrame* nsIFrame*
nsFrameIterator::GetPrevSiblingInner(nsIFrame* aFrame) { nsFrameIterator::GetPrevSiblingInner(nsIFrame* aFrame) {
if (mVisual) {
nsIFrame* parent = GetParentFrame(aFrame);
if (!parent)
return nullptr;
return parent->PrincipalChildList().GetPrevVisualFor(aFrame);
}
return aFrame->GetPrevSibling(); return aFrame->GetPrevSibling();
} }
nsIFrame* nsIFrame*
nsFrameIterator::GetPlaceholderFrame(nsIFrame* aFrame) nsFrameIterator::GetPlaceholderFrame(nsIFrame* aFrame)
{ {
@ -499,30 +335,3 @@ nsFrameIterator::IsPopupFrame(nsIFrame* aFrame)
aFrame->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_POPUP); aFrame->GetStyleDisplay()->mDisplay == NS_STYLE_DISPLAY_POPUP);
} }
// nsVisualIterator implementation
nsIFrame*
nsVisualIterator::GetFirstChildInner(nsIFrame* aFrame) {
return aFrame->PrincipalChildList().GetNextVisualFor(nullptr);
}
nsIFrame*
nsVisualIterator::GetLastChildInner(nsIFrame* aFrame) {
return aFrame->PrincipalChildList().GetPrevVisualFor(nullptr);
}
nsIFrame*
nsVisualIterator::GetNextSiblingInner(nsIFrame* aFrame) {
nsIFrame* parent = GetParentFrame(aFrame);
if (!parent)
return nullptr;
return parent->PrincipalChildList().GetNextVisualFor(aFrame);
}
nsIFrame*
nsVisualIterator::GetPrevSiblingInner(nsIFrame* aFrame) {
nsIFrame* parent = GetParentFrame(aFrame);
if (!parent)
return nullptr;
return parent->PrincipalChildList().GetPrevVisualFor(aFrame);
}

Просмотреть файл

@ -0,0 +1,107 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef NSFRAMEITERATOR_H
#define NSFRAMEITERATOR_H
#include "prtypes.h"
class nsPresContext;
class nsIFrame;
enum nsIteratorType {
eLeaf,
ePreOrder,
ePostOrder
};
enum FrameIteratorFlags {
FLAG_NONE = 0,
FLAG_LOCK_SCROLL = 1 << 1,
FLAG_FOLLOW_OUT_OF_FLOW = 1 << 2,
FLAG_VISUAL = 1 << 3
};
class nsFrameIterator
{
public:
nsFrameIterator(nsPresContext* aPresContext, nsIFrame *aStart,
nsIteratorType aType, PRUint32 aFlags);
~nsFrameIterator() {}
void First();
void Next();
nsIFrame* CurrentItem();
bool IsDone();
void Last();
void Prev();
protected:
void setCurrent(nsIFrame *aFrame){mCurrent = aFrame;}
nsIFrame *getCurrent(){return mCurrent;}
void setStart(nsIFrame *aFrame){mStart = aFrame;}
nsIFrame *getStart(){return mStart;}
nsIFrame *getLast(){return mLast;}
void setLast(nsIFrame *aFrame){mLast = aFrame;}
PRInt8 getOffEdge(){return mOffEdge;}
void setOffEdge(PRInt8 aOffEdge){mOffEdge = aOffEdge;}
void SetLockInScrollView(bool aLockScroll){mLockScroll = aLockScroll;}
/*
Our own versions of the standard frame tree navigation
methods, which, if the iterator is following out-of-flows,
apply the following rules for placeholder frames:
- If a frame HAS a placeholder frame, getting its parent
gets the placeholder's parent.
- If a frame's first child or next/prev sibling IS a
placeholder frame, then we instead return the real frame.
- If a frame HAS a placeholder frame, getting its next/prev
sibling gets the placeholder frame's next/prev sibling.
These are all applied recursively to support multiple levels of
placeholders.
*/
nsIFrame* GetParentFrame(nsIFrame* aFrame);
// like GetParentFrame but returns null once a popup frame is reached
nsIFrame* GetParentFrameNotPopup(nsIFrame* aFrame);
nsIFrame* GetFirstChild(nsIFrame* aFrame);
nsIFrame* GetLastChild(nsIFrame* aFrame);
nsIFrame* GetNextSibling(nsIFrame* aFrame);
nsIFrame* GetPrevSibling(nsIFrame* aFrame);
/*
These methods are different in visual mode to have the
semantics of "get first child in visual order", "get last child in visual
order", "get next sibling in visual order" and "get previous sibling in visual
order".
*/
nsIFrame* GetFirstChildInner(nsIFrame* aFrame);
nsIFrame* GetLastChildInner(nsIFrame* aFrame);
nsIFrame* GetNextSiblingInner(nsIFrame* aFrame);
nsIFrame* GetPrevSiblingInner(nsIFrame* aFrame);
nsIFrame* GetPlaceholderFrame(nsIFrame* aFrame);
bool IsPopupFrame(nsIFrame* aFrame);
nsPresContext* mPresContext;
nsIFrame *mStart;
nsIFrame *mCurrent;
nsIFrame *mLast; //the last one that was in current;
PRInt8 mOffEdge; //0= no -1 to far prev, 1 to far next;
nsIteratorType mType;
bool mLockScroll;
bool mFollowOOFs;
bool mVisual;
};
#endif //NSFRAMEITERATOR_H

Просмотреть файл

@ -1,38 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef NSFRAMETRAVERSAL_H
#define NSFRAMETRAVERSAL_H
#include "nsIFrame.h"
#include "nsIFrameTraversal.h"
nsresult NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext,
nsIFrame *aStart,
nsIteratorType aType,
bool aVisual,
bool aLockInScrollView,
bool aFollowOOFs);
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
class nsFrameTraversal : public nsIFrameTraversal
{
public:
nsFrameTraversal();
virtual ~nsFrameTraversal();
NS_DECL_ISUPPORTS
NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext,
nsIFrame *aStart,
PRInt32 aType,
bool aVisual,
bool aLockInScrollView,
bool aFollowOOFs);
};
#endif //NSFRAMETRAVERSAL_H

Просмотреть файл

@ -1,72 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef NSIFRAMETRAVERSAL_H
#define NSIFRAMETRAVERSAL_H
#include "nsISupports.h"
#include "nsIFrame.h"
#define NS_IFRAMEENUMERATOR_IID \
{ 0x7c633f5d, 0x91eb, 0x494e, \
{ 0xa1, 0x40, 0x17, 0x46, 0x17, 0x4c, 0x23, 0xd3 } }
class nsIFrameEnumerator : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFRAMEENUMERATOR_IID)
virtual void First() = 0;
virtual void Next() = 0;
virtual nsIFrame* CurrentItem() = 0;
virtual bool IsDone() = 0;
virtual void Last() = 0;
virtual void Prev() = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFrameEnumerator, NS_IFRAMEENUMERATOR_IID)
enum nsIteratorType {
eLeaf,
ePreOrder,
ePostOrder
};
// {9d469828-9bf2-4151-a385-05f30219221b}
#define NS_IFRAMETRAVERSAL_IID \
{ 0x9d469828, 0x9bf2, 0x4151, { 0xa3, 0x85, 0x05, 0xf3, 0x02, 0x19, 0x22, 0x1b } }
class nsIFrameTraversal : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IFRAMETRAVERSAL_IID)
/**
* Create a frame iterator with the specified properties.
* @param aEnumerator [out] the created iterator
* @param aPresContext [in]
* @param aStart [in] the frame to start iterating from
* @param aType [in] the type of the iterator: leaf, pre-order, or post-order
* @param aVisual [in] whether the iterator should traverse frames in visual
* bidi order
* @param aLockInScrollView [in] whether to stop iterating when exiting a
* scroll view
* @param aFollowOOFs [in] whether the iterator should follow out-of-flows.
* If true, when reaching a placeholder frame while going down will get
* the real frame. Going back up will go on past the placeholder,
* so the placeholders are logically part of the frame tree.
*/
NS_IMETHOD NewFrameTraversal(nsIFrameEnumerator **aEnumerator,
nsPresContext* aPresContext,
nsIFrame *aStart,
PRInt32 aType,
bool aVisual,
bool aLockInScrollView,
bool aFollowOOFs) = 0;
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIFrameTraversal, NS_IFRAMETRAVERSAL_IID)
#endif //NSIFRAMETRAVERSAL_H

Просмотреть файл

@ -6,10 +6,6 @@
#ifndef nsLayoutCID_h__ #ifndef nsLayoutCID_h__
#define nsLayoutCID_h__ #define nsLayoutCID_h__
// {1691E1F4-EE41-11d4-9885-00C04FA0CF4B}
#define NS_FRAMETRAVERSAL_CID \
{ 0x1691e1f4, 0xee41, 0x11d4, { 0x98, 0x85, 0x0, 0xc0, 0x4f, 0xa0, 0xcf, 0x4b } }
/* a6cf90f9-15b3-11d2-932e-00805f8add32 */ /* a6cf90f9-15b3-11d2-932e-00805f8add32 */
#define NS_LAYOUT_DEBUGGER_CID \ #define NS_LAYOUT_DEBUGGER_CID \
{ 0xa6cf90f9, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}} { 0xa6cf90f9, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}

Просмотреть файл

@ -45,7 +45,6 @@
#include "nsContentAreaDragDrop.h" #include "nsContentAreaDragDrop.h"
#include "nsContentList.h" #include "nsContentList.h"
#include "nsBox.h" #include "nsBox.h"
#include "nsIFrameTraversal.h"
#include "nsLayoutCID.h" #include "nsLayoutCID.h"
#include "nsStyleSheetService.h" #include "nsStyleSheetService.h"
#include "nsFocusManager.h" #include "nsFocusManager.h"
@ -413,8 +412,6 @@ nsresult NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult
nsresult NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult); nsresult NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult);
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult); nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
nsresult NS_NewDomSelection(nsISelection** aResult); nsresult NS_NewDomSelection(nsISelection** aResult);
nsresult NS_NewContentViewer(nsIContentViewer** aResult); nsresult NS_NewContentViewer(nsIContentViewer** aResult);
nsresult NS_NewGenRegularIterator(nsIContentIterator** aResult); nsresult NS_NewGenRegularIterator(nsIContentIterator** aResult);
@ -469,7 +466,6 @@ MAKE_CTOR(CreateNewFrameUtil, nsIFrameUtil, NS_NewFra
MAKE_CTOR(CreateNewLayoutDebugger, nsILayoutDebugger, NS_NewLayoutDebugger) MAKE_CTOR(CreateNewLayoutDebugger, nsILayoutDebugger, NS_NewLayoutDebugger)
#endif #endif
MAKE_CTOR(CreateNewFrameTraversal, nsIFrameTraversal, NS_CreateFrameTraversal)
MAKE_CTOR(CreateNewPresShell, nsIPresShell, NS_NewPresShell) MAKE_CTOR(CreateNewPresShell, nsIPresShell, NS_NewPresShell)
MAKE_CTOR(CreateNewBoxObject, nsIBoxObject, NS_NewBoxObject) MAKE_CTOR(CreateNewBoxObject, nsIBoxObject, NS_NewBoxObject)
@ -663,7 +659,6 @@ Construct_nsIScriptSecurityManager(nsISupports *aOuter, REFNSIID aIID,
NS_DEFINE_NAMED_CID(NS_FRAME_UTIL_CID); NS_DEFINE_NAMED_CID(NS_FRAME_UTIL_CID);
NS_DEFINE_NAMED_CID(NS_LAYOUT_DEBUGGER_CID); NS_DEFINE_NAMED_CID(NS_LAYOUT_DEBUGGER_CID);
#endif #endif
NS_DEFINE_NAMED_CID(NS_FRAMETRAVERSAL_CID);
NS_DEFINE_NAMED_CID(NS_PRESSHELL_CID); NS_DEFINE_NAMED_CID(NS_PRESSHELL_CID);
NS_DEFINE_NAMED_CID(NS_BOXOBJECT_CID); NS_DEFINE_NAMED_CID(NS_BOXOBJECT_CID);
#ifdef MOZ_XUL #ifdef MOZ_XUL
@ -937,7 +932,6 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
{ &kNS_FRAME_UTIL_CID, false, NULL, CreateNewFrameUtil }, { &kNS_FRAME_UTIL_CID, false, NULL, CreateNewFrameUtil },
{ &kNS_LAYOUT_DEBUGGER_CID, false, NULL, CreateNewLayoutDebugger }, { &kNS_LAYOUT_DEBUGGER_CID, false, NULL, CreateNewLayoutDebugger },
#endif #endif
{ &kNS_FRAMETRAVERSAL_CID, false, NULL, CreateNewFrameTraversal },
{ &kNS_PRESSHELL_CID, false, NULL, CreateNewPresShell }, { &kNS_PRESSHELL_CID, false, NULL, CreateNewPresShell },
{ &kNS_BOXOBJECT_CID, false, NULL, CreateNewBoxObject }, { &kNS_BOXOBJECT_CID, false, NULL, CreateNewBoxObject },
#ifdef MOZ_XUL #ifdef MOZ_XUL

Просмотреть файл

@ -52,7 +52,7 @@
#include "nsCSSPseudoElements.h" #include "nsCSSPseudoElements.h"
#include "nsCSSFrameConstructor.h" #include "nsCSSFrameConstructor.h"
#include "nsFrameTraversal.h" #include "nsFrameIterator.h"
#include "nsStyleChangeList.h" #include "nsStyleChangeList.h"
#include "nsIDOMRange.h" #include "nsIDOMRange.h"
#include "nsRange.h" #include "nsRange.h"
@ -5782,16 +5782,12 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
//resultFrame is not a block frame //resultFrame is not a block frame
result = NS_ERROR_FAILURE; result = NS_ERROR_FAILURE;
nsCOMPtr<nsIFrameEnumerator> frameTraversal; PRUint32 flags = FrameIteratorFlags::FLAG_NONE;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), if (aPos->mScrollViewStop) {
aPresContext, resultFrame, flags |= FrameIteratorFlags::FLAG_LOCK_SCROLL;
ePostOrder, }
false, // aVisual nsFrameIterator frameTraversal(aPresContext, resultFrame,
aPos->mScrollViewStop, ePostOrder, flags);
false // aFollowOOFs
);
if (NS_FAILED(result))
return result;
nsIFrame *storeOldResultFrame = resultFrame; nsIFrame *storeOldResultFrame = resultFrame;
while ( !found ){ while ( !found ){
nsPoint point; nsPoint point;
@ -5868,21 +5864,21 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
if (aPos->mDirection == eDirNext && (resultFrame == nearStoppingFrame)) if (aPos->mDirection == eDirNext && (resultFrame == nearStoppingFrame))
break; break;
//always try previous on THAT line if that fails go the other way //always try previous on THAT line if that fails go the other way
frameTraversal->Prev(); frameTraversal.Prev();
resultFrame = frameTraversal->CurrentItem(); resultFrame = frameTraversal.CurrentItem();
if (!resultFrame) if (!resultFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
} }
if (!found){ if (!found){
resultFrame = storeOldResultFrame; resultFrame = storeOldResultFrame;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
aPresContext, resultFrame, PRUint32 flags = FrameIteratorFlags::FLAG_NONE;
eLeaf, if (aPos->mScrollViewStop) {
false, // aVisual flags |= FrameIteratorFlags::FLAG_LOCK_SCROLL;
aPos->mScrollViewStop, }
false // aFollowOOFs frameTraversal = nsFrameIterator(aPresContext, resultFrame,
); eLeaf, flags);
} }
while ( !found ){ while ( !found ){
nsPoint point(aPos->mDesiredX, 0); nsPoint point(aPos->mDesiredX, 0);
@ -5913,8 +5909,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
if (aPos->mDirection == eDirNext && (resultFrame == farStoppingFrame)) if (aPos->mDirection == eDirNext && (resultFrame == farStoppingFrame))
break; break;
//previous didnt work now we try "next" //previous didnt work now we try "next"
frameTraversal->Next(); frameTraversal.Next();
nsIFrame *tempFrame = frameTraversal->CurrentItem(); nsIFrame *tempFrame = frameTraversal.CurrentItem();
if (!tempFrame) if (!tempFrame)
break; break;
resultFrame = tempFrame; resultFrame = tempFrame;
@ -6638,23 +6634,22 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, bool aVisual,
return NS_ERROR_FAILURE; //we are done. cannot jump lines return NS_ERROR_FAILURE; //we are done. cannot jump lines
} }
nsCOMPtr<nsIFrameEnumerator> frameTraversal; PRUint32 flags = FrameIteratorFlags::FLAG_FOLLOW_OUT_OF_FLOW;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal), if (aScrollViewStop) {
presContext, traversedFrame, flags |= FrameIteratorFlags::FLAG_LOCK_SCROLL;
eLeaf, }
aVisual && presContext->BidiEnabled(), if (aVisual && presContext->BidiEnabled()) {
aScrollViewStop, flags |= FrameIteratorFlags::FLAG_VISUAL;
true // aFollowOOFs }
); nsFrameIterator frameTraversal(presContext, traversedFrame,
if (NS_FAILED(result)) eLeaf, flags);
return result;
if (aDirection == eDirNext) if (aDirection == eDirNext)
frameTraversal->Next(); frameTraversal.Next();
else else
frameTraversal->Prev(); frameTraversal.Prev();
traversedFrame = frameTraversal->CurrentItem(); traversedFrame = frameTraversal.CurrentItem();
if (!traversedFrame) if (!traversedFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
traversedFrame->IsSelectable(&selectable, nullptr); traversedFrame->IsSelectable(&selectable, nullptr);

Просмотреть файл

@ -40,14 +40,12 @@
#include "nsTextFragment.h" #include "nsTextFragment.h"
// for IBMBIDI // for IBMBIDI
#include "nsFrameTraversal.h" #include "nsFrameIterator.h"
#include "nsILineIterator.h" #include "nsILineIterator.h"
#include "nsGkAtoms.h" #include "nsGkAtoms.h"
#include "nsIFrameTraversal.h"
#include "nsLayoutUtils.h" #include "nsLayoutUtils.h"
#include "nsLayoutCID.h" #include "nsLayoutCID.h"
#include "nsBidiPresUtils.h" #include "nsBidiPresUtils.h"
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
#include "nsTextFrame.h" #include "nsTextFrame.h"
#include "nsIDOMText.h" #include "nsIDOMText.h"
@ -1229,30 +1227,17 @@ nsFrameSelection::GetFrameFromLevel(nsIFrame *aFrameIn,
PRUint8 foundLevel = 0; PRUint8 foundLevel = 0;
nsIFrame *foundFrame = aFrameIn; nsIFrame *foundFrame = aFrameIn;
nsCOMPtr<nsIFrameEnumerator> frameTraversal; nsFrameIterator frameTraversal(mShell->GetPresContext(), aFrameIn,
nsresult result; eLeaf, FrameIteratorFlags::FLAG_NONE);
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID,&result));
if (NS_FAILED(result))
return result;
result = trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
mShell->GetPresContext(), aFrameIn,
eLeaf,
false, // aVisual
false, // aLockInScrollView
false // aFollowOOFs
);
if (NS_FAILED(result))
return result;
do { do {
*aFrameOut = foundFrame; *aFrameOut = foundFrame;
if (aDirection == eDirNext) if (aDirection == eDirNext)
frameTraversal->Next(); frameTraversal.Next();
else else
frameTraversal->Prev(); frameTraversal.Prev();
foundFrame = frameTraversal->CurrentItem(); foundFrame = frameTraversal.CurrentItem();
if (!foundFrame) if (!foundFrame)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
foundLevel = NS_GET_EMBEDDING_LEVEL(foundFrame); foundLevel = NS_GET_EMBEDDING_LEVEL(foundFrame);

Просмотреть файл

@ -25,7 +25,7 @@
#include "nsIDOMNode.h" #include "nsIDOMNode.h"
#include "mozilla/dom/Element.h" #include "mozilla/dom/Element.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsFrameTraversal.h" #include "nsFrameIterator.h"
#include "nsIImageDocument.h" #include "nsIImageDocument.h"
#include "nsIDOMHTMLDocument.h" #include "nsIDOMHTMLDocument.h"
#include "nsIDOMHTMLElement.h" #include "nsIDOMHTMLElement.h"
@ -63,8 +63,6 @@ NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsTypeAheadFind) NS_IMPL_ADDREF(nsTypeAheadFind)
NS_IMPL_RELEASE(nsTypeAheadFind) NS_IMPL_RELEASE(nsTypeAheadFind)
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
#define NS_FIND_CONTRACTID "@mozilla.org/embedcomp/rangefind;1" #define NS_FIND_CONTRACTID "@mozilla.org/embedcomp/rangefind;1"
nsTypeAheadFind::nsTypeAheadFind(): nsTypeAheadFind::nsTypeAheadFind():
@ -1116,23 +1114,12 @@ nsTypeAheadFind::IsRangeVisible(nsIPresShell *aPresShell,
// We know that the target range isn't usable because it's not in the // We know that the target range isn't usable because it's not in the
// view port. Move range forward to first visible point, // view port. Move range forward to first visible point,
// this speeds us up a lot in long documents // this speeds us up a lot in long documents
nsCOMPtr<nsIFrameEnumerator> frameTraversal; nsFrameIterator frameTraversal(aPresContext, frame,
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID)); eLeaf, FrameIteratorFlags::FLAG_NONE);
if (trav)
trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
aPresContext, frame,
eLeaf,
false, // aVisual
false, // aLockInScrollView
false // aFollowOOFs
);
if (!frameTraversal)
return false;
while (rectVisibility == nsRectVisibility_kAboveViewport) { while (rectVisibility == nsRectVisibility_kAboveViewport) {
frameTraversal->Next(); frameTraversal.Next();
frame = frameTraversal->CurrentItem(); frame = frameTraversal.CurrentItem();
if (!frame) if (!frame)
return false; return false;