mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
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:
parent
bfbcf21932
commit
dca3fd6326
@ -65,7 +65,6 @@
|
||||
#include "nsCaret.h"
|
||||
|
||||
#include "nsSubDocumentFrame.h"
|
||||
#include "nsIFrameTraversal.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
@ -112,8 +111,6 @@ using namespace mozilla::dom;
|
||||
|
||||
#define NS_USER_INTERACTION_INTERVAL 5000 // ms
|
||||
|
||||
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
|
||||
|
||||
static bool sLeftClickOnly = true;
|
||||
static bool sKeyCausesActivation = true;
|
||||
static PRUint32 sESMInstanceCount = 0;
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsFrameTraversal.h"
|
||||
#include "nsFrameIterator.h"
|
||||
#include "nsObjectFrame.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsEventStateManager.h"
|
||||
@ -2271,15 +2271,8 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
|
||||
if (nodeValue.Length() == (PRUint32)startOffset && !isFormControl &&
|
||||
startContent != aDocument->GetRootElement()) {
|
||||
// Yes, indeed we were at the end of the last node
|
||||
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
|
||||
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
|
||||
presContext, startFrame,
|
||||
eLeaf,
|
||||
false, // aVisual
|
||||
false, // aLockInScrollView
|
||||
true // aFollowOOFs
|
||||
);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsFrameIterator frameTraversal(presContext, startFrame,
|
||||
eLeaf, FrameIteratorFlags::FLAG_FOLLOW_OUT_OF_FLOW);
|
||||
|
||||
nsIFrame *newCaretFrame = nullptr;
|
||||
nsCOMPtr<nsIContent> newCaretContent = startContent;
|
||||
@ -2287,11 +2280,11 @@ nsFocusManager::GetSelectionLocation(nsIDocument* aDocument,
|
||||
do {
|
||||
// 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
|
||||
frameTraversal->Next();
|
||||
newCaretFrame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||
frameTraversal.Next();
|
||||
newCaretFrame = static_cast<nsIFrame*>(frameTraversal.CurrentItem());
|
||||
if (nullptr == newCaretFrame)
|
||||
break;
|
||||
newCaretContent = newCaretFrame->GetContent();
|
||||
newCaretContent = newCaretFrame->GetContent();
|
||||
} while (!newCaretContent || newCaretContent == startContent);
|
||||
|
||||
if (newCaretFrame && newCaretContent) {
|
||||
@ -2704,21 +2697,14 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
continue;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
|
||||
nsresult rv = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
|
||||
presContext, startFrame,
|
||||
ePreOrder,
|
||||
false, // aVisual
|
||||
false, // aLockInScrollView
|
||||
true // aFollowOOFs
|
||||
);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsFrameIterator frameTraversal(presContext, startFrame,
|
||||
ePreOrder, FrameIteratorFlags::FLAG_FOLLOW_OUT_OF_FLOW);
|
||||
|
||||
if (iterStartContent == aRootContent) {
|
||||
if (!aForward) {
|
||||
frameTraversal->Last();
|
||||
frameTraversal.Last();
|
||||
} else if (aRootContent->IsFocusable()) {
|
||||
frameTraversal->Next();
|
||||
frameTraversal.Next();
|
||||
}
|
||||
}
|
||||
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
|
||||
// content nodes per frame, so don't skip over the starting frame.
|
||||
if (aForward)
|
||||
frameTraversal->Next();
|
||||
frameTraversal.Next();
|
||||
else
|
||||
frameTraversal->Prev();
|
||||
frameTraversal.Prev();
|
||||
}
|
||||
|
||||
// Walk frames to find something tabbable matching mCurrentTabIndex
|
||||
nsIFrame* frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||
nsIFrame* frame = static_cast<nsIFrame*>(frameTraversal.CurrentItem());
|
||||
while (frame) {
|
||||
// TabIndex not set defaults to 0 for form elements, anchors and other
|
||||
// elements that are normally focusable. Tabindex defaults to -1
|
||||
@ -2803,10 +2789,10 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
Element* rootElement = subdoc->GetRootElement();
|
||||
nsIPresShell* subShell = subdoc->GetShell();
|
||||
if (rootElement && subShell) {
|
||||
rv = GetNextTabbableContent(subShell, rootElement,
|
||||
aOriginalStartContent, rootElement,
|
||||
aForward, (aForward ? 1 : 0),
|
||||
false, aResultContent);
|
||||
nsresult rv = GetNextTabbableContent(subShell, rootElement,
|
||||
aOriginalStartContent, rootElement,
|
||||
aForward, (aForward ? 1 : 0),
|
||||
false, aResultContent);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (*aResultContent)
|
||||
return NS_OK;
|
||||
@ -2850,10 +2836,10 @@ nsFocusManager::GetNextTabbableContent(nsIPresShell* aPresShell,
|
||||
// again.
|
||||
do {
|
||||
if (aForward)
|
||||
frameTraversal->Next();
|
||||
frameTraversal.Next();
|
||||
else
|
||||
frameTraversal->Prev();
|
||||
frame = static_cast<nsIFrame*>(frameTraversal->CurrentItem());
|
||||
frameTraversal.Prev();
|
||||
frame = static_cast<nsIFrame*>(frameTraversal.CurrentItem());
|
||||
} while (frame && frame->GetPrevContinuation());
|
||||
}
|
||||
|
||||
|
@ -40,8 +40,7 @@ EXPORTS = \
|
||||
nsDisplayList.h \
|
||||
nsFrameManager.h \
|
||||
nsFrameManagerBase.h \
|
||||
nsFrameTraversal.h \
|
||||
nsIFrameTraversal.h \
|
||||
nsFrameIterator.h \
|
||||
nsILayoutDebugger.h \
|
||||
nsILayoutHistoryState.h \
|
||||
nsIPercentHeightObserver.h \
|
||||
@ -77,7 +76,7 @@ CPPSRCS = \
|
||||
nsDisplayList.cpp \
|
||||
nsDocumentViewer.cpp \
|
||||
nsFrameManager.cpp \
|
||||
nsFrameTraversal.cpp \
|
||||
nsFrameIterator.cpp \
|
||||
nsGenConList.cpp \
|
||||
nsImageLoader.cpp \
|
||||
nsLayoutDebugger.cpp \
|
||||
|
@ -2,215 +2,34 @@
|
||||
/* 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/. */
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsGkAtoms.h"
|
||||
|
||||
#include "nsFrameTraversal.h"
|
||||
#include "nsFrameList.h"
|
||||
#include "nsFrameIterator.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsGkAtoms.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,
|
||||
nsIteratorType aType, bool aLockInScrollView,
|
||||
bool aFollowOOFs)
|
||||
nsIteratorType aType, PRUint32 aFlags)
|
||||
: mPresContext(aPresContext)
|
||||
, mOffEdge(0)
|
||||
, mType(aType)
|
||||
{
|
||||
mOffEdge = 0;
|
||||
mPresContext = aPresContext;
|
||||
if (aFollowOOFs && aStart)
|
||||
mFollowOOFs = (aFlags & FrameIteratorFlags::FLAG_FOLLOW_OUT_OF_FLOW) != 0;
|
||||
mLockScroll = (aFlags & FrameIteratorFlags::FLAG_LOCK_SCROLL) != 0;
|
||||
mVisual = (aFlags & FrameIteratorFlags::FLAG_VISUAL) != 0;
|
||||
if (mFollowOOFs && aStart)
|
||||
aStart = nsPlaceholderFrame::GetRealFrameFor(aStart);
|
||||
setStart(aStart);
|
||||
setCurrent(aStart);
|
||||
setLast(aStart);
|
||||
mType = aType;
|
||||
SetLockInScrollView(aLockInScrollView);
|
||||
mFollowOOFs = aFollowOOFs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
nsIFrame*
|
||||
nsFrameIterator::CurrentItem()
|
||||
{
|
||||
if (mOffEdge)
|
||||
return nullptr;
|
||||
|
||||
return mCurrent;
|
||||
return mOffEdge ? nullptr : mCurrent;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
nsFrameIterator::IsDone()
|
||||
{
|
||||
@ -246,7 +65,7 @@ nsFrameIterator::Last()
|
||||
while ((result = GetLastChild(parent))) {
|
||||
parent = result;
|
||||
}
|
||||
|
||||
|
||||
setCurrent(parent);
|
||||
if (!parent)
|
||||
setOffEdge(1);
|
||||
@ -327,7 +146,7 @@ nsFrameIterator::Prev()
|
||||
if (result)
|
||||
parent = result;
|
||||
}
|
||||
|
||||
|
||||
if (parent != getCurrent()) {
|
||||
result = parent;
|
||||
} else {
|
||||
@ -370,7 +189,7 @@ nsFrameIterator::GetParentFrame(nsIFrame* aFrame)
|
||||
aFrame = GetPlaceholderFrame(aFrame);
|
||||
if (aFrame)
|
||||
return aFrame->GetParent();
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -384,7 +203,7 @@ nsFrameIterator::GetParentFrameNotPopup(nsIFrame* aFrame)
|
||||
if (!IsPopupFrame(parent))
|
||||
return parent;
|
||||
}
|
||||
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@ -396,7 +215,7 @@ nsFrameIterator::GetFirstChild(nsIFrame* aFrame)
|
||||
return nullptr;
|
||||
if (result && mFollowOOFs) {
|
||||
result = nsPlaceholderFrame::GetRealFrameFor(result);
|
||||
|
||||
|
||||
if (IsPopupFrame(result))
|
||||
result = GetNextSibling(result);
|
||||
}
|
||||
@ -411,7 +230,7 @@ nsFrameIterator::GetLastChild(nsIFrame* aFrame)
|
||||
return nullptr;
|
||||
if (result && mFollowOOFs) {
|
||||
result = nsPlaceholderFrame::GetRealFrameFor(result);
|
||||
|
||||
|
||||
if (IsPopupFrame(result))
|
||||
result = GetPrevSibling(result);
|
||||
}
|
||||
@ -456,25 +275,42 @@ nsFrameIterator::GetPrevSibling(nsIFrame* aFrame)
|
||||
|
||||
nsIFrame*
|
||||
nsFrameIterator::GetFirstChildInner(nsIFrame* aFrame) {
|
||||
if (mVisual) {
|
||||
return aFrame->PrincipalChildList().GetNextVisualFor(nullptr);
|
||||
}
|
||||
return aFrame->GetFirstPrincipalChild();
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFrameIterator::GetLastChildInner(nsIFrame* aFrame) {
|
||||
if (mVisual) {
|
||||
return aFrame->PrincipalChildList().GetPrevVisualFor(nullptr);
|
||||
}
|
||||
return aFrame->PrincipalChildList().LastChild();
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFrameIterator::GetNextSiblingInner(nsIFrame* aFrame) {
|
||||
if (mVisual) {
|
||||
nsIFrame* parent = GetParentFrame(aFrame);
|
||||
if (!parent)
|
||||
return nullptr;
|
||||
return parent->PrincipalChildList().GetNextVisualFor(aFrame);
|
||||
}
|
||||
return aFrame->GetNextSibling();
|
||||
}
|
||||
|
||||
nsIFrame*
|
||||
nsFrameIterator::GetPrevSiblingInner(nsIFrame* aFrame) {
|
||||
if (mVisual) {
|
||||
nsIFrame* parent = GetParentFrame(aFrame);
|
||||
if (!parent)
|
||||
return nullptr;
|
||||
return parent->PrincipalChildList().GetPrevVisualFor(aFrame);
|
||||
}
|
||||
return aFrame->GetPrevSibling();
|
||||
}
|
||||
|
||||
|
||||
nsIFrame*
|
||||
nsFrameIterator::GetPlaceholderFrame(nsIFrame* aFrame)
|
||||
{
|
||||
@ -499,30 +335,3 @@ nsFrameIterator::IsPopupFrame(nsIFrame* aFrame)
|
||||
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);
|
||||
}
|
107
layout/base/nsFrameIterator.h
Normal file
107
layout/base/nsFrameIterator.h
Normal file
@ -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__
|
||||
#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 */
|
||||
#define NS_LAYOUT_DEBUGGER_CID \
|
||||
{ 0xa6cf90f9, 0x15b3, 0x11d2,{0x93, 0x2e, 0x00, 0x80, 0x5f, 0x8a, 0xdd, 0x32}}
|
||||
|
@ -45,7 +45,6 @@
|
||||
#include "nsContentAreaDragDrop.h"
|
||||
#include "nsContentList.h"
|
||||
#include "nsBox.h"
|
||||
#include "nsIFrameTraversal.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsStyleSheetService.h"
|
||||
#include "nsFocusManager.h"
|
||||
@ -413,8 +412,6 @@ nsresult NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult
|
||||
nsresult NS_NewCanvasRenderingContext2DThebes(nsIDOMCanvasRenderingContext2D** aResult);
|
||||
nsresult NS_NewCanvasRenderingContextWebGL(nsIDOMWebGLRenderingContext** aResult);
|
||||
|
||||
nsresult NS_CreateFrameTraversal(nsIFrameTraversal** aResult);
|
||||
|
||||
nsresult NS_NewDomSelection(nsISelection** aResult);
|
||||
nsresult NS_NewContentViewer(nsIContentViewer** aResult);
|
||||
nsresult NS_NewGenRegularIterator(nsIContentIterator** aResult);
|
||||
@ -469,7 +466,6 @@ MAKE_CTOR(CreateNewFrameUtil, nsIFrameUtil, NS_NewFra
|
||||
MAKE_CTOR(CreateNewLayoutDebugger, nsILayoutDebugger, NS_NewLayoutDebugger)
|
||||
#endif
|
||||
|
||||
MAKE_CTOR(CreateNewFrameTraversal, nsIFrameTraversal, NS_CreateFrameTraversal)
|
||||
MAKE_CTOR(CreateNewPresShell, nsIPresShell, NS_NewPresShell)
|
||||
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_LAYOUT_DEBUGGER_CID);
|
||||
#endif
|
||||
NS_DEFINE_NAMED_CID(NS_FRAMETRAVERSAL_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PRESSHELL_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_BOXOBJECT_CID);
|
||||
#ifdef MOZ_XUL
|
||||
@ -937,7 +932,6 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
||||
{ &kNS_FRAME_UTIL_CID, false, NULL, CreateNewFrameUtil },
|
||||
{ &kNS_LAYOUT_DEBUGGER_CID, false, NULL, CreateNewLayoutDebugger },
|
||||
#endif
|
||||
{ &kNS_FRAMETRAVERSAL_CID, false, NULL, CreateNewFrameTraversal },
|
||||
{ &kNS_PRESSHELL_CID, false, NULL, CreateNewPresShell },
|
||||
{ &kNS_BOXOBJECT_CID, false, NULL, CreateNewBoxObject },
|
||||
#ifdef MOZ_XUL
|
||||
|
@ -52,7 +52,7 @@
|
||||
#include "nsCSSPseudoElements.h"
|
||||
#include "nsCSSFrameConstructor.h"
|
||||
|
||||
#include "nsFrameTraversal.h"
|
||||
#include "nsFrameIterator.h"
|
||||
#include "nsStyleChangeList.h"
|
||||
#include "nsIDOMRange.h"
|
||||
#include "nsRange.h"
|
||||
@ -5782,16 +5782,12 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
||||
//resultFrame is not a block frame
|
||||
result = NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
|
||||
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
|
||||
aPresContext, resultFrame,
|
||||
ePostOrder,
|
||||
false, // aVisual
|
||||
aPos->mScrollViewStop,
|
||||
false // aFollowOOFs
|
||||
);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
PRUint32 flags = FrameIteratorFlags::FLAG_NONE;
|
||||
if (aPos->mScrollViewStop) {
|
||||
flags |= FrameIteratorFlags::FLAG_LOCK_SCROLL;
|
||||
}
|
||||
nsFrameIterator frameTraversal(aPresContext, resultFrame,
|
||||
ePostOrder, flags);
|
||||
nsIFrame *storeOldResultFrame = resultFrame;
|
||||
while ( !found ){
|
||||
nsPoint point;
|
||||
@ -5868,21 +5864,21 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
||||
if (aPos->mDirection == eDirNext && (resultFrame == nearStoppingFrame))
|
||||
break;
|
||||
//always try previous on THAT line if that fails go the other way
|
||||
frameTraversal->Prev();
|
||||
resultFrame = frameTraversal->CurrentItem();
|
||||
frameTraversal.Prev();
|
||||
resultFrame = frameTraversal.CurrentItem();
|
||||
if (!resultFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!found){
|
||||
resultFrame = storeOldResultFrame;
|
||||
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
|
||||
aPresContext, resultFrame,
|
||||
eLeaf,
|
||||
false, // aVisual
|
||||
aPos->mScrollViewStop,
|
||||
false // aFollowOOFs
|
||||
);
|
||||
|
||||
PRUint32 flags = FrameIteratorFlags::FLAG_NONE;
|
||||
if (aPos->mScrollViewStop) {
|
||||
flags |= FrameIteratorFlags::FLAG_LOCK_SCROLL;
|
||||
}
|
||||
frameTraversal = nsFrameIterator(aPresContext, resultFrame,
|
||||
eLeaf, flags);
|
||||
}
|
||||
while ( !found ){
|
||||
nsPoint point(aPos->mDesiredX, 0);
|
||||
@ -5913,8 +5909,8 @@ nsFrame::GetNextPrevLineFromeBlockFrame(nsPresContext* aPresContext,
|
||||
if (aPos->mDirection == eDirNext && (resultFrame == farStoppingFrame))
|
||||
break;
|
||||
//previous didnt work now we try "next"
|
||||
frameTraversal->Next();
|
||||
nsIFrame *tempFrame = frameTraversal->CurrentItem();
|
||||
frameTraversal.Next();
|
||||
nsIFrame *tempFrame = frameTraversal.CurrentItem();
|
||||
if (!tempFrame)
|
||||
break;
|
||||
resultFrame = tempFrame;
|
||||
@ -6638,23 +6634,22 @@ nsIFrame::GetFrameFromDirection(nsDirection aDirection, bool aVisual,
|
||||
return NS_ERROR_FAILURE; //we are done. cannot jump lines
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
|
||||
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),
|
||||
presContext, traversedFrame,
|
||||
eLeaf,
|
||||
aVisual && presContext->BidiEnabled(),
|
||||
aScrollViewStop,
|
||||
true // aFollowOOFs
|
||||
);
|
||||
if (NS_FAILED(result))
|
||||
return result;
|
||||
PRUint32 flags = FrameIteratorFlags::FLAG_FOLLOW_OUT_OF_FLOW;
|
||||
if (aScrollViewStop) {
|
||||
flags |= FrameIteratorFlags::FLAG_LOCK_SCROLL;
|
||||
}
|
||||
if (aVisual && presContext->BidiEnabled()) {
|
||||
flags |= FrameIteratorFlags::FLAG_VISUAL;
|
||||
}
|
||||
nsFrameIterator frameTraversal(presContext, traversedFrame,
|
||||
eLeaf, flags);
|
||||
|
||||
if (aDirection == eDirNext)
|
||||
frameTraversal->Next();
|
||||
frameTraversal.Next();
|
||||
else
|
||||
frameTraversal->Prev();
|
||||
frameTraversal.Prev();
|
||||
|
||||
traversedFrame = frameTraversal->CurrentItem();
|
||||
traversedFrame = frameTraversal.CurrentItem();
|
||||
if (!traversedFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
traversedFrame->IsSelectable(&selectable, nullptr);
|
||||
|
@ -40,14 +40,12 @@
|
||||
#include "nsTextFragment.h"
|
||||
|
||||
// for IBMBIDI
|
||||
#include "nsFrameTraversal.h"
|
||||
#include "nsFrameIterator.h"
|
||||
#include "nsILineIterator.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIFrameTraversal.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsBidiPresUtils.h"
|
||||
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
|
||||
#include "nsTextFrame.h"
|
||||
|
||||
#include "nsIDOMText.h"
|
||||
@ -1229,30 +1227,17 @@ nsFrameSelection::GetFrameFromLevel(nsIFrame *aFrameIn,
|
||||
PRUint8 foundLevel = 0;
|
||||
nsIFrame *foundFrame = aFrameIn;
|
||||
|
||||
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
|
||||
nsresult result;
|
||||
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;
|
||||
nsFrameIterator frameTraversal(mShell->GetPresContext(), aFrameIn,
|
||||
eLeaf, FrameIteratorFlags::FLAG_NONE);
|
||||
|
||||
do {
|
||||
*aFrameOut = foundFrame;
|
||||
if (aDirection == eDirNext)
|
||||
frameTraversal->Next();
|
||||
else
|
||||
frameTraversal->Prev();
|
||||
frameTraversal.Next();
|
||||
else
|
||||
frameTraversal.Prev();
|
||||
|
||||
foundFrame = frameTraversal->CurrentItem();
|
||||
foundFrame = frameTraversal.CurrentItem();
|
||||
if (!foundFrame)
|
||||
return NS_ERROR_FAILURE;
|
||||
foundLevel = NS_GET_EMBEDDING_LEVEL(foundFrame);
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "nsIDOMNode.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsFrameTraversal.h"
|
||||
#include "nsFrameIterator.h"
|
||||
#include "nsIImageDocument.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
@ -63,8 +63,6 @@ NS_INTERFACE_MAP_END
|
||||
NS_IMPL_ADDREF(nsTypeAheadFind)
|
||||
NS_IMPL_RELEASE(nsTypeAheadFind)
|
||||
|
||||
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
|
||||
|
||||
#define NS_FIND_CONTRACTID "@mozilla.org/embedcomp/rangefind;1"
|
||||
|
||||
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
|
||||
// view port. Move range forward to first visible point,
|
||||
// this speeds us up a lot in long documents
|
||||
nsCOMPtr<nsIFrameEnumerator> frameTraversal;
|
||||
nsCOMPtr<nsIFrameTraversal> trav(do_CreateInstance(kFrameTraversalCID));
|
||||
if (trav)
|
||||
trav->NewFrameTraversal(getter_AddRefs(frameTraversal),
|
||||
aPresContext, frame,
|
||||
eLeaf,
|
||||
false, // aVisual
|
||||
false, // aLockInScrollView
|
||||
false // aFollowOOFs
|
||||
);
|
||||
|
||||
if (!frameTraversal)
|
||||
return false;
|
||||
nsFrameIterator frameTraversal(aPresContext, frame,
|
||||
eLeaf, FrameIteratorFlags::FLAG_NONE);
|
||||
|
||||
while (rectVisibility == nsRectVisibility_kAboveViewport) {
|
||||
frameTraversal->Next();
|
||||
frame = frameTraversal->CurrentItem();
|
||||
frameTraversal.Next();
|
||||
frame = frameTraversal.CurrentItem();
|
||||
if (!frame)
|
||||
return false;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user