massive checkin for underlying implementation of key handling from javascript and home/end breakage and.. selecting around NON-text frames. like arrowing around an image for example. 16636,16655 and another i cannot find. r=kin r=hyatt a=me

git-svn-id: svn://10.0.0.236/trunk@51467 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mjudge%netscape.com 1999-10-22 00:19:18 +00:00
parent 6cb5db5eff
commit 64c9150aab
18 changed files with 896 additions and 286 deletions

View File

@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* !!Note this is for a javascriptable pres shell currently for accessing selection
* the selection refers only to that which listens to keybindings which is the "NORMAL"
* selection this will be IDLIZED LATER
*/
#ifndef nsISelectionControler_h___
#define nsISelectionControler_h___
#include "nsISupports.h"
#define NS_ISELECTIONCONTROLER_IID_STR "D2D1D179-85A7-11d3-9932-00108301233C"
#define NS_ISELECTIONCONTROLER_IID \
{ 0xd2d1d179, 0x85a7, 0x11d3, \
{ 0x99, 0x32, 0x0, 0x10, 0x83, 0x1, 0x23, 0x3c }}
class nsISelectionControler : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_ISELECTIONCONTROLER_IID; return iid; }
/** CharacterMove will move the selection one character forward/backward in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD CharacterMove(PRBool aForward, PRBool aExtend) = 0;
/** WordMove will move the selection one word forward/backward in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD WordMove(PRBool aForward, PRBool aExtend) = 0;
/** LineMove will move the selection one line forward/backward in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD LineMove(PRBool aForward, PRBool aExtend) = 0;
/** IntraLineMove will move the selection to the front of the line or end of the line
* in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD IntraLineMove(PRBool aForward, PRBool aExtend) = 0;
/** PageMove will move the selection one page forward/backward in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD PageMove(PRBool aForward, PRBool aExtend) = 0;
/** ScrollPage will scroll the page without affecting the selection.
* @param aForward scroll forward or backwards in selection
*/
NS_IMETHOD ScrollPage(PRBool aForward) = 0;
/** SelectAll will select the whole page
*/
NS_IMETHOD SelectAll() = 0;
};
#endif /* nsISelectionControler_h___ */

View File

@ -224,7 +224,7 @@ NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsPoint& outCoordinates, PRB
nsCOMPtr<nsIFrameSelection> frameSelection;
err = mPresShell->GetFrameSelection(getter_AddRefs(frameSelection));
if (NS_FAILED(err) || !frameSelection)
return err;
return err;
err = frameSelection->GetFrameForNodeOffset(contentNode, focusOffset, &theFrame);
if (NS_FAILED(err))
return err;
@ -394,6 +394,7 @@ PRBool nsCaret::SetupDrawingFrameAndOffset()
// see if we have an offset between child nodes, or an offset into a text
// node.
#if NOT_NEEDED
if (NS_SUCCEEDED(contentNode->CanContainChildren(canContainChildren)) && canContainChildren)
{
// point the caret to the start of the child node
@ -412,7 +413,7 @@ PRBool nsCaret::SetupDrawingFrameAndOffset()
// we can be in a text node, or a BR node here.
}
#endif // NOT_NEEDED
nsIFrame* theFrame = nsnull;
//get frame selection and find out what frame to use...

View File

@ -62,6 +62,7 @@ struct SelectionDetails
* @param mResultFrame resulting frame for peeking
* @param mEatingWS boolean to tell us the state of our search for Next/Prev
* @param mPreferLeft true = prev line end, false = next line begin
* @param mJumpLines if this is true then its ok to cross lines while peeking
*/
struct nsPeekOffsetStruct
{
@ -71,11 +72,12 @@ struct nsPeekOffsetStruct
nsDirection aDirection,
PRInt32 aStartOffset,
PRBool aEatingWS,
PRBool aPreferLeft)
PRBool aPreferLeft,
PRBool aJumpLines)
{
mTracker=aTracker;mDesiredX=aDesiredX;mAmount=aAmount;
mDirection=aDirection;mStartOffset=aStartOffset;mEatingWS=aEatingWS;
mPreferLeft=aPreferLeft;
mPreferLeft=aPreferLeft;mJumpLines = aJumpLines;
}
nsIFocusTracker *mTracker;
nscoord mDesiredX;
@ -88,6 +90,7 @@ struct nsPeekOffsetStruct
nsIFrame *mResultFrame;
PRBool mEatingWS;
PRBool mPreferLeft;
PRBool mJumpLines;
};
@ -216,6 +219,7 @@ public:
* @param aResultFrame will contain the return frame. MUST NOT BE NULL or will return error
*/
NS_IMETHOD GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame **aReturnFrame)=0;
};

View File

@ -40,6 +40,7 @@
#include "nsDOMEvent.h"
#include "nsHTMLParts.h"
#include "nsIDOMSelection.h"
#include "nsISelectionControler.h"
#include "nsLayoutCID.h"
#include "nsIDOMRange.h"
#include "nsIDOMDocument.h"
@ -52,7 +53,6 @@
#include "nsIDOMHTMLDocument.h"
#include "nsIXMLDocument.h"
#include "nsIScrollableView.h"
#include "nsIDOMSelectionListener.h"
#include "nsIParser.h"
#include "nsParserCIID.h"
#include "nsHTMLContentSinkStream.h"
@ -105,7 +105,7 @@ static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIDOMRangeIID, NS_IDOMRANGE_IID);
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
static NS_DEFINE_IID(kIFocusTrackerIID, NS_IFOCUSTRACKER_IID);
static NS_DEFINE_IID(kIDomSelectionListenerIID, NS_IDOMSELECTIONLISTENER_IID);
static NS_DEFINE_IID(kISelectionControlerIID, NS_ISELECTIONCONTROLER_IID);
static NS_DEFINE_IID(kICaretIID, NS_ICARET_IID);
static NS_DEFINE_IID(kICaretID, NS_ICARET_IID);
static NS_DEFINE_IID(kIDOMHTMLDocumentIID, NS_IDOMHTMLDOCUMENT_IID);
@ -167,7 +167,8 @@ private:
class PresShell : public nsIPresShell, public nsIViewObserver,
private nsIDocumentObserver, public nsIFocusTracker,
public nsIDOMSelectionListener, public nsSupportsWeakReference
public nsISelectionControler,
public nsSupportsWeakReference
{
public:
PresShell();
@ -255,8 +256,15 @@ public:
NS_IMETHOD SetDisplayNonTextSelection(PRBool aaInEnable);
NS_IMETHOD GetDisplayNonTextSelection(PRBool *aOutEnable);
// nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
// nsISelectionControler
NS_IMETHOD CharacterMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD WordMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD LineMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD IntraLineMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD PageMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD ScrollPage(PRBool aForward);
NS_IMETHOD SelectAll();
// nsIDocumentObserver
NS_IMETHOD BeginUpdate(nsIDocument *aDocument);
@ -501,8 +509,8 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDomSelectionListenerIID)) {
nsIDOMSelectionListener* tmp = this;
if (aIID.Equals(kISelectionControlerIID)) {
nsISelectionControler* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
@ -612,10 +620,6 @@ PresShell::Init(nsIDocument* aDocument,
return result;
}
nsCOMPtr<nsIDOMSelection> domSelection;
mSelection->GetSelection(SELECTION_NORMAL, getter_AddRefs(domSelection));
domSelection->AddSelectionListener(this);//possible circular reference
result = mSelection->Init((nsIFocusTracker *) this);
if (!NS_SUCCEEDED(result))
return result;
@ -865,7 +869,6 @@ PresShell::EndObservingDocument()
return result;
if (!domselection)
return NS_ERROR_UNEXPECTED;
domselection->RemoveSelectionListener(this);
mSelection->ShutDown();
}
return NS_OK;
@ -1126,17 +1129,54 @@ NS_IMETHODIMP PresShell::GetDisplayNonTextSelection(PRBool *aOutEnable)
return NS_OK;
}
//implementation of nsISelectionControler
/*implementation of the nsIDOMSelectionListener
it will invoke the resetselection to update the presentation shell's frames
*/
NS_IMETHODIMP PresShell::NotifySelectionChanged()
NS_IMETHODIMP
PresShell::CharacterMove(PRBool aForward, PRBool aExtend)
{
if (!mSelection)
return NS_ERROR_NULL_POINTER;
return NS_ERROR_NULL_POINTER;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::WordMove(PRBool aForward, PRBool aExtend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::LineMove(PRBool aForward, PRBool aExtend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::IntraLineMove(PRBool aForward, PRBool aExtend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::PageMove(PRBool aForward, PRBool aExtend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::ScrollPage(PRBool aForward)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::SelectAll()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//end implementations nsISelectionControler
NS_IMETHODIMP
PresShell::StyleChangeReflow()
{
@ -2109,14 +2149,10 @@ PresShell::HandleEvent(nsIView *aView,
if (mSelection && aEvent->eventStructType == NS_KEY_EVENT)
{//KEY HANDLERS WILL GET RID OF THIS
mSelection->EnableFrameNotification(PR_FALSE);
if (mDisplayNonTextSelection && NS_SUCCEEDED(mSelection->HandleKeyEvent(aEvent)))
{
mSelection->EnableFrameNotification(PR_TRUE); //prevents secondary reset selection called since
return NS_OK;
}
mSelection->EnableFrameNotification(PR_TRUE); //prevents secondary reset selection called since
//we are a listener now.
}
if (nsnull != frame) {

View File

@ -18,6 +18,7 @@ nsIFrameUtil.h
nsIFrameImageLoader.h
nsIFrameManager.h
nsIFrameReflow.h
nsISelectionControler.h
nsILayoutDebugger.h
nsINameSpace.h
nsINameSpaceManager.h

View File

@ -44,6 +44,7 @@ nsINameSpace.h \
nsINameSpaceManager.h \
nsIFrameReflow.h \
nsIFrameUtil.h \
nsISelectionControler.h \
nsIPageSequenceFrame.h \
nsIPresContext.h \
nsIPresShell.h \

View File

@ -32,6 +32,7 @@ EXPORTS = \
nsIFrame.h \
nsIFrameImageLoader.h \
nsIFrameManager.h \
nsISelectionControler.h \
nsILayoutDebugger.h \
nsINameSpace.h \
nsINameSpaceManager.h \

View File

@ -62,6 +62,7 @@ struct SelectionDetails
* @param mResultFrame resulting frame for peeking
* @param mEatingWS boolean to tell us the state of our search for Next/Prev
* @param mPreferLeft true = prev line end, false = next line begin
* @param mJumpLines if this is true then its ok to cross lines while peeking
*/
struct nsPeekOffsetStruct
{
@ -71,11 +72,12 @@ struct nsPeekOffsetStruct
nsDirection aDirection,
PRInt32 aStartOffset,
PRBool aEatingWS,
PRBool aPreferLeft)
PRBool aPreferLeft,
PRBool aJumpLines)
{
mTracker=aTracker;mDesiredX=aDesiredX;mAmount=aAmount;
mDirection=aDirection;mStartOffset=aStartOffset;mEatingWS=aEatingWS;
mPreferLeft=aPreferLeft;
mPreferLeft=aPreferLeft;mJumpLines = aJumpLines;
}
nsIFocusTracker *mTracker;
nscoord mDesiredX;
@ -88,6 +90,7 @@ struct nsPeekOffsetStruct
nsIFrame *mResultFrame;
PRBool mEatingWS;
PRBool mPreferLeft;
PRBool mJumpLines;
};
@ -216,6 +219,7 @@ public:
* @param aResultFrame will contain the return frame. MUST NOT BE NULL or will return error
*/
NS_IMETHOD GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame **aReturnFrame)=0;
};

View File

@ -0,0 +1,100 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/*
* !!Note this is for a javascriptable pres shell currently for accessing selection
* the selection refers only to that which listens to keybindings which is the "NORMAL"
* selection this will be IDLIZED LATER
*/
#ifndef nsISelectionControler_h___
#define nsISelectionControler_h___
#include "nsISupports.h"
#define NS_ISELECTIONCONTROLER_IID_STR "D2D1D179-85A7-11d3-9932-00108301233C"
#define NS_ISELECTIONCONTROLER_IID \
{ 0xd2d1d179, 0x85a7, 0x11d3, \
{ 0x99, 0x32, 0x0, 0x10, 0x83, 0x1, 0x23, 0x3c }}
class nsISelectionControler : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_ISELECTIONCONTROLER_IID; return iid; }
/** CharacterMove will move the selection one character forward/backward in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD CharacterMove(PRBool aForward, PRBool aExtend) = 0;
/** WordMove will move the selection one word forward/backward in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD WordMove(PRBool aForward, PRBool aExtend) = 0;
/** LineMove will move the selection one line forward/backward in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD LineMove(PRBool aForward, PRBool aExtend) = 0;
/** IntraLineMove will move the selection to the front of the line or end of the line
* in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD IntraLineMove(PRBool aForward, PRBool aExtend) = 0;
/** PageMove will move the selection one page forward/backward in the document.
* this will also have the effect of collapsing the selection if the aExtend = PR_FALSE
* the "point" of selection that is extended is considered the "focus" point.
* or the last point adjusted by the selection.
* @param aForward forward or backward if PR_FALSE
* @param aExtend should it collapse the selection of extend it?
*/
NS_IMETHOD PageMove(PRBool aForward, PRBool aExtend) = 0;
/** ScrollPage will scroll the page without affecting the selection.
* @param aForward scroll forward or backwards in selection
*/
NS_IMETHOD ScrollPage(PRBool aForward) = 0;
/** SelectAll will select the whole page
*/
NS_IMETHOD SelectAll() = 0;
};
#endif /* nsISelectionControler_h___ */

View File

@ -224,7 +224,7 @@ NS_IMETHODIMP nsCaret::GetWindowRelativeCoordinates(nsPoint& outCoordinates, PRB
nsCOMPtr<nsIFrameSelection> frameSelection;
err = mPresShell->GetFrameSelection(getter_AddRefs(frameSelection));
if (NS_FAILED(err) || !frameSelection)
return err;
return err;
err = frameSelection->GetFrameForNodeOffset(contentNode, focusOffset, &theFrame);
if (NS_FAILED(err))
return err;
@ -394,6 +394,7 @@ PRBool nsCaret::SetupDrawingFrameAndOffset()
// see if we have an offset between child nodes, or an offset into a text
// node.
#if NOT_NEEDED
if (NS_SUCCEEDED(contentNode->CanContainChildren(canContainChildren)) && canContainChildren)
{
// point the caret to the start of the child node
@ -412,7 +413,7 @@ PRBool nsCaret::SetupDrawingFrameAndOffset()
// we can be in a text node, or a BR node here.
}
#endif // NOT_NEEDED
nsIFrame* theFrame = nsnull;
//get frame selection and find out what frame to use...

View File

@ -924,7 +924,7 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent)
if (NS_FAILED(result))
return result;
nsPeekOffsetStruct pos;
pos.SetData(mTracker, desiredX, amount, eDirPrevious, offsetused, PR_FALSE,PR_TRUE);
pos.SetData(mTracker, desiredX, amount, eDirPrevious, offsetused, PR_FALSE,PR_TRUE, PR_TRUE);
switch (keyEvent->keyCode){
case nsIDOMUIEvent::DOM_VK_RIGHT :
InvalidateDesiredX();
@ -1223,7 +1223,10 @@ nsRangeList::GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame
{
if (aOffset >= 0)
{
result = aNode->ChildAt(aOffset, aNode);
if (mHint == HINTLEFT && aOffset >0)//we should back up a little
result = aNode->ChildAt(aOffset-1, aNode);
else
result = aNode->ChildAt(aOffset, aNode);
if (NS_FAILED(result))
return result;
if (!aNode) //out of bounds?
@ -1243,6 +1246,8 @@ nsRangeList::GetFrameForNodeOffset(nsIContent *aNode, PRInt32 aOffset, nsIFrame
return result;
}
//////////END FRAMESELECTION
NS_METHOD
nsRangeList::AddSelectionListener(nsIDOMSelectionListener* inNewListener)

View File

@ -79,9 +79,7 @@ static NS_DEFINE_IID(kCTransferableCID, NS_TRANSFERABLE_CID);
// [HACK] Foward Declarations
void ForceDrawFrame(nsFrame * aFrame);
//non Hack prototypes
static void GetLastLeaf(nsIFrame **aFrame);
#if 0
static void GetFirstLeaf(nsIFrame **aFrame);
static void RefreshContentFrames(nsIPresContext& aPresContext, nsIContent * aStartContent, nsIContent * aEndContent);
#endif
@ -865,6 +863,7 @@ nsFrame::HandleMultiplePress(nsIPresContext& aPresContext,
eDirPrevious,
startPos,
PR_FALSE,
PR_TRUE,
PR_TRUE);
rv = PeekOffset(&startpos);
if (NS_FAILED(rv))
@ -876,7 +875,8 @@ nsFrame::HandleMultiplePress(nsIPresContext& aPresContext,
eDirNext,
startPos,
PR_FALSE,
PR_FALSE);
PR_FALSE,
PR_TRUE);
rv = PeekOffset(&endpos);
if (NS_FAILED(rv))
return rv;
@ -1073,6 +1073,14 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsIPresContext& aCX,
if (!mContent)
return NS_ERROR_NULL_POINTER;
nsRect thisRect;
result = GetRect(thisRect);
if (NS_FAILED(result))
return result;
nsPoint offsetPoint;
GetOffsetFromView(offsetPoint, &view);
thisRect.x = offsetPoint.x;
thisRect.y = offsetPoint.y;
result = mContent->GetParent(*aNewContent);
if (*aNewContent){
@ -1081,9 +1089,19 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsIPresContext& aCX,
{
return result;
}
aContentOffsetEnd = aContentOffset +1;
aBeginFrameContent = PR_TRUE;
if (thisRect.Contains(aPoint))
aContentOffsetEnd = aContentOffset +1;
else
{
if ((thisRect.x + thisRect.width) < aPoint.x || thisRect.y > aPoint.y)
{
aBeginFrameContent = PR_FALSE;
aContentOffset++;
}
aContentOffsetEnd = aContentOffset;
}
}
aBeginFrameContent = PR_FALSE;
return result;
}
@ -1911,6 +1929,27 @@ nsFrame::GetPointFromOffset(nsIPresContext* inPresContext, nsIRenderingContext*
{
NS_PRECONDITION(outPoint != nsnull, "Null parameter");
nsPoint bottomLeft(0, 0);
if (mContent)
{
nsCOMPtr<nsIContent> newContent;
PRInt32 newOffset;
nsresult result = mContent->GetParent(*getter_AddRefs(newContent));
if (newContent){
result = newContent->IndexOf(mContent, newOffset);
if (NS_FAILED(result))
{
return result;
}
nsRect rect;
result = GetRect(rect);
if (NS_FAILED(result))
{
return result;
}
if (inOffset > newOffset)
bottomLeft.x = rect.width;
}
}
*outPoint = bottomLeft;
return NS_OK;
}
@ -2124,16 +2163,53 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos)
return NS_ERROR_NULL_POINTER;
nsresult result = NS_ERROR_FAILURE;
PRInt32 endoffset;
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
switch (aPos->mAmount){
case eSelectCharacter : case eSelectWord:
{
if (mContent)
{
nsCOMPtr<nsIContent> newContent;
PRInt32 newOffset;
result = mContent->GetParent(*getter_AddRefs(newContent));
if (newContent){
aPos->mResultContent = newContent;
result = newContent->IndexOf(mContent, newOffset);
if (aPos->mStartOffset < 0)//start at "end"
aPos->mStartOffset = newOffset + 1;
if (NS_FAILED(result))
{
return result;
}
if ((aPos->mDirection == eDirNext && newOffset < aPos->mStartOffset) || //need to go to next one
(aPos->mDirection == eDirPrevious && newOffset >= aPos->mStartOffset))
{
result = GetFrameFromDirection(aPos);
if (NS_FAILED(result) || !aPos->mResultFrame)
{
return result?result:NS_ERROR_FAILURE;
}
return aPos->mResultFrame->PeekOffset(aPos);
}
else
{
if (aPos->mDirection == eDirNext)
aPos->mContentOffset = newOffset +1;
else
aPos->mContentOffset = newOffset;//to beginning of frame
}
}
}
break;
}//drop into no amount
case eSelectNoAmount:
{
nsCOMPtr<nsIPresContext> context;
result = aPos->mTracker->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(result) || !context)
return result;
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
result = GetContentAndOffsetsFromPoint(*(context.get()),point,
getter_AddRefs(aPos->mResultContent),
aPos->mContentOffset,
@ -2250,8 +2326,12 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos)
if (firstFrame)
{
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
nsPoint offsetPoint; //used for offset of result frame
nsIView * view; //used for call of get offset from view
firstFrame->GetOffsetFromView(offsetPoint, &view);
point.x = 0;//all the way to the left
point.y = offsetPoint.y;
result = firstFrame->GetContentAndOffsetsFromPoint(*(context.get()),point,
getter_AddRefs(aPos->mResultContent),
aPos->mContentOffset,
@ -2273,11 +2353,9 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos)
nsPoint offsetPoint; //used for offset of result frame
nsIView * view; //used for call of get offset from view
nextFrame->GetOffsetFromView(offsetPoint, &view);
usedRect.x = offsetPoint.x;
usedRect.y = offsetPoint.y;
nsPoint point;
point.x = 2* offsetPoint.x; //2* just to be sure we are off the edge
point.x = 2* usedRect.width; //2* just to be sure we are off the edge
point.y = offsetPoint.y;
result = nextFrame->GetContentAndOffsetsFromPoint(*(context.get()),
@ -2298,105 +2376,144 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos)
}
}
}break;
default:
{
//this will use the nsFrameTraversal as the default peek method.
//this should change to use geometry and also look to ALL the child lists
//we need to set up line information to make sure we dont jump across line boundaries
nsIFrame *blockFrame = this;
nsIFrame *thisBlock;
PRInt32 thisLine;
nsCOMPtr<nsILineIterator> it;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
}
else
blockFrame = nsnull;
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return result;
nsIFrame *firstFrame;
nsIFrame *lastFrame;
nsRect nonUsedRect;
PRInt32 lineFrameCount;
PRUint32 lineFlags;
result = it->GetLine(thisLine, &firstFrame, &lineFrameCount,nonUsedRect,
&lineFlags);
if (NS_FAILED(result))
return result;
lastFrame = firstFrame;
for (;lineFrameCount > 1;lineFrameCount --){
result = lastFrame->GetNextSibling(&lastFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsFrame\n");
return NS_ERROR_FAILURE;
}
}
//END LINE DATA CODE
if ((aPos->mDirection == eDirNext && lastFrame == this)
||(aPos->mDirection == eDirPrevious && firstFrame == this))
{
if (aPos->mAmount != eSelectWord)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
aPos->mAmount = eSelectNoAmount;
}
else{
if (aPos->mEatingWS)//done finding what we wanted
return NS_OK;
if (aPos->mDirection == eDirNext)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
aPos->mAmount = eSelectNoAmount;
}
}
}
if (aPos->mAmount == eSelectDir)
aPos->mAmount = eSelectNoAmount;//just get to next frame.
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
if (aPos->mDirection == eDirNext)
result = frameTraversal->Next();
else
result = frameTraversal->Prev();
if (NS_FAILED(result))
return result;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result))
return result;
if (!isupports)
return NS_ERROR_NULL_POINTER;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
//for speed reasons
nsIFrame *newFrame = (nsIFrame *)isupports;
if (aPos->mDirection == eDirNext)
aPos->mStartOffset = 0;
else
aPos->mStartOffset = -1;
return newFrame->PeekOffset(aPos);
if (NS_SUCCEEDED(result))
result = aPos->mResultFrame->PeekOffset(aPos);
}
}
return result;
}
PRInt32
nsFrame::GetLineNumber(nsIFrame *aFrame)
{
nsIFrame *blockFrame = aFrame;
nsIFrame *thisBlock;
PRInt32 thisLine;
nsCOMPtr<nsILineIterator> it;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
}
else
blockFrame = nsnull;
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return -1;
return thisLine;
}
//this will use the nsFrameTraversal as the default peek method.
//this should change to use geometry and also look to ALL the child lists
//we need to set up line information to make sure we dont jump across line boundaries
NS_IMETHODIMP
nsFrame::GetFrameFromDirection(nsPeekOffsetStruct *aPos)
{
nsIFrame *blockFrame = this;
nsIFrame *thisBlock;
PRInt32 thisLine;
nsCOMPtr<nsILineIterator> it;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
}
else
blockFrame = nsnull;
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return result;
nsIFrame *firstFrame;
nsIFrame *lastFrame;
nsRect nonUsedRect;
PRInt32 lineFrameCount;
PRUint32 lineFlags;
result = it->GetLine(thisLine, &firstFrame, &lineFrameCount,nonUsedRect,
&lineFlags);
if (NS_FAILED(result))
return result;
lastFrame = firstFrame;
for (;lineFrameCount > 1;lineFrameCount --){
result = lastFrame->GetNextSibling(&lastFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsFrame\n");
return NS_ERROR_FAILURE;
}
}
GetFirstLeaf( &firstFrame);
GetLastLeaf(&lastFrame);
//END LINE DATA CODE
if ((aPos->mDirection == eDirNext && lastFrame == this)
||(aPos->mDirection == eDirPrevious && firstFrame == this))
{
if (aPos->mJumpLines != PR_TRUE)
return NS_ERROR_FAILURE;//we are done. cannot jump lines
if (aPos->mAmount != eSelectWord)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
aPos->mAmount = eSelectNoAmount;
}
else{
if (aPos->mEatingWS)//done finding what we wanted
return NS_ERROR_FAILURE;
if (aPos->mDirection == eDirNext)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
aPos->mAmount = eSelectNoAmount;
}
}
}
if (aPos->mAmount == eSelectDir)
aPos->mAmount = eSelectNoAmount;//just get to next frame.
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
if (aPos->mDirection == eDirNext)
result = frameTraversal->Next();
else
result = frameTraversal->Prev();
if (NS_FAILED(result))
return result;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result))
return result;
if (!isupports)
return NS_ERROR_NULL_POINTER;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
//for speed reasons
nsIFrame *newFrame = (nsIFrame *)isupports;
if (aPos->mDirection == eDirNext)
aPos->mStartOffset = 0;
else
aPos->mStartOffset = -1;
aPos->mResultFrame = newFrame;
return NS_OK;
}
nsresult nsFrame::GetClosestViewForFrame(nsIFrame *aFrame, nsIView **aView)
{
if (!aView)
@ -2480,8 +2597,8 @@ void ForceDrawFrame(nsFrame * aFrame)//, PRBool)
}
static void
GetLastLeaf(nsIFrame **aFrame)
void
nsFrame::GetLastLeaf(nsIFrame **aFrame)
{
if (!aFrame || !*aFrame)
return;
@ -2500,6 +2617,24 @@ GetLastLeaf(nsIFrame **aFrame)
*aFrame = child;
}
void
nsFrame::GetFirstLeaf(nsIFrame **aFrame)
{
if (!aFrame || !*aFrame)
return;
nsIFrame *child = *aFrame;
nsIFrame *lookahead;
nsresult result;
while (1){
result = child->FirstChild(nsnull, &lookahead);
if (NS_FAILED(result) || !lookahead)
return;//nothing to do
child = lookahead;
*aFrame = child;
}
}
#ifdef NS_DEBUG
static void
GetTagName(nsFrame* aFrame, nsIContent* aContent, PRIntn aResultSize,

View File

@ -332,9 +332,18 @@ protected:
PRBool DisplaySelection(nsIPresContext& aPresContext, PRBool isOkToTurnOn = PR_FALSE);
//this will modify aPos and return the next frame ect.
NS_IMETHOD GetFrameFromDirection(nsPeekOffsetStruct *aPos);
// Style post processing hook
NS_IMETHOD DidSetStyleContext(nsIPresContext* aPresContext);
//return the line number of the aFrame
static PRInt32 GetLineNumber(nsIFrame *aFrame);
//given a frame five me the first/last leaf available
static void GetLastLeaf(nsIFrame **aFrame);
static void GetFirstLeaf(nsIFrame **aFrame);
/**
* Dump out the "base classes" regression data. This should dump
* out the interior data, not the "frame" XML container. And it

View File

@ -2200,7 +2200,11 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
}
if (!found)
result = nsFrame::PeekOffset(aPos);
{
result = GetFrameFromDirection(aPos);
if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
result = aPos->mResultFrame->PeekOffset(aPos);
}
else
aPos->mResultContent = mContent;
}
@ -2233,7 +2237,7 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
if (aPos->mDirection == eDirPrevious){
keepSearching = PR_TRUE;
tx.Init(this, mContent, aPos->mStartOffset);
aPos->mContentOffset = mContentOffset;//initialize
if (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace,
PR_FALSE) &&
(aPos->mStartOffset - contentLen >= mContentOffset) ){
@ -2270,6 +2274,7 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
}
else if (aPos->mDirection == eDirNext) {
tx.Init(this, mContent, aPos->mStartOffset );
aPos->mContentOffset = mContentOffset + mContentLength;//initialize
#ifdef DEBUGWORDJUMP
printf("Next- Start=%d aPos->mEatingWS=%s\n", aPos->mStartOffset, aPos->mEatingWS ? "TRUE" : "FALSE");
@ -2304,7 +2309,7 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
}
else if (!keepSearching) //we have found the "whole" word so just looking for WS
aPos->mEatingWS = PR_TRUE;
}
}
frameUsed = GetNextInFlow();
start = 0;
}
@ -2315,11 +2320,19 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
{
aPos->mContentOffset = PR_MIN(aPos->mContentOffset, mContentOffset + mContentLength);
aPos->mContentOffset = PR_MAX(aPos->mContentOffset, mContentOffset);
result = nsFrame::PeekOffset(aPos);
result = GetFrameFromDirection(aPos);
if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
{
if (NS_SUCCEEDED(result = aPos->mResultFrame->PeekOffset(aPos)))
return NS_OK;//else fall through
}
else
aPos->mResultContent = mContent;
}
else
{
aPos->mResultContent = mContent;
}
}
break;
default:
@ -2365,6 +2378,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
if (NS_SUCCEEDED(mPrefs->GetIntPref("browser.triple_click_style", &prefInt)) && prefInt)
return nsFrame::HandleMultiplePress(aPresContext, aEvent, aEventStatus);
}
//THIS NEXT CODE IS FOR PARAGRAPH
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
@ -2437,9 +2451,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
PRInt32 contentOffsetEnd = 0;
nsCOMPtr<nsIContent> newContent;
//find which word needs to be selected! use peek offset one way then the other
nsCOMPtr<nsIContent> startContent;
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIContent> endContent;
nsCOMPtr<nsIDOMNode> endNode;
if (NS_SUCCEEDED(GetPosition(aPresContext, aEvent->point.x,
getter_AddRefs(newContent), startPos, contentOffsetEnd))){
@ -2451,7 +2463,8 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
eDirPrevious,
startPos,
PR_FALSE,
PR_TRUE);
PR_TRUE,
PR_FALSE);
rv = PeekOffset(&startpos);
if (NS_FAILED(rv))
return rv;
@ -2462,6 +2475,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
eDirNext,
startPos,
PR_FALSE,
PR_FALSE,
PR_FALSE);
rv = PeekOffset(&endpos);
if (NS_FAILED(rv))
@ -2473,6 +2487,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
startNode = do_QueryInterface(startpos.mResultContent,&rv);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(shell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection)))){
rv = selection->Collapse(startNode,startpos.mContentOffset);
@ -2490,6 +2505,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
}
NS_IMETHODIMP
nsTextFrame::GetOffsets(PRInt32 &start, PRInt32 &end) const
{

View File

@ -79,9 +79,7 @@ static NS_DEFINE_IID(kCTransferableCID, NS_TRANSFERABLE_CID);
// [HACK] Foward Declarations
void ForceDrawFrame(nsFrame * aFrame);
//non Hack prototypes
static void GetLastLeaf(nsIFrame **aFrame);
#if 0
static void GetFirstLeaf(nsIFrame **aFrame);
static void RefreshContentFrames(nsIPresContext& aPresContext, nsIContent * aStartContent, nsIContent * aEndContent);
#endif
@ -865,6 +863,7 @@ nsFrame::HandleMultiplePress(nsIPresContext& aPresContext,
eDirPrevious,
startPos,
PR_FALSE,
PR_TRUE,
PR_TRUE);
rv = PeekOffset(&startpos);
if (NS_FAILED(rv))
@ -876,7 +875,8 @@ nsFrame::HandleMultiplePress(nsIPresContext& aPresContext,
eDirNext,
startPos,
PR_FALSE,
PR_FALSE);
PR_FALSE,
PR_TRUE);
rv = PeekOffset(&endpos);
if (NS_FAILED(rv))
return rv;
@ -1073,6 +1073,14 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsIPresContext& aCX,
if (!mContent)
return NS_ERROR_NULL_POINTER;
nsRect thisRect;
result = GetRect(thisRect);
if (NS_FAILED(result))
return result;
nsPoint offsetPoint;
GetOffsetFromView(offsetPoint, &view);
thisRect.x = offsetPoint.x;
thisRect.y = offsetPoint.y;
result = mContent->GetParent(*aNewContent);
if (*aNewContent){
@ -1081,9 +1089,19 @@ nsresult nsFrame::GetContentAndOffsetsFromPoint(nsIPresContext& aCX,
{
return result;
}
aContentOffsetEnd = aContentOffset +1;
aBeginFrameContent = PR_TRUE;
if (thisRect.Contains(aPoint))
aContentOffsetEnd = aContentOffset +1;
else
{
if ((thisRect.x + thisRect.width) < aPoint.x || thisRect.y > aPoint.y)
{
aBeginFrameContent = PR_FALSE;
aContentOffset++;
}
aContentOffsetEnd = aContentOffset;
}
}
aBeginFrameContent = PR_FALSE;
return result;
}
@ -1911,6 +1929,27 @@ nsFrame::GetPointFromOffset(nsIPresContext* inPresContext, nsIRenderingContext*
{
NS_PRECONDITION(outPoint != nsnull, "Null parameter");
nsPoint bottomLeft(0, 0);
if (mContent)
{
nsCOMPtr<nsIContent> newContent;
PRInt32 newOffset;
nsresult result = mContent->GetParent(*getter_AddRefs(newContent));
if (newContent){
result = newContent->IndexOf(mContent, newOffset);
if (NS_FAILED(result))
{
return result;
}
nsRect rect;
result = GetRect(rect);
if (NS_FAILED(result))
{
return result;
}
if (inOffset > newOffset)
bottomLeft.x = rect.width;
}
}
*outPoint = bottomLeft;
return NS_OK;
}
@ -2124,16 +2163,53 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos)
return NS_ERROR_NULL_POINTER;
nsresult result = NS_ERROR_FAILURE;
PRInt32 endoffset;
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
switch (aPos->mAmount){
case eSelectCharacter : case eSelectWord:
{
if (mContent)
{
nsCOMPtr<nsIContent> newContent;
PRInt32 newOffset;
result = mContent->GetParent(*getter_AddRefs(newContent));
if (newContent){
aPos->mResultContent = newContent;
result = newContent->IndexOf(mContent, newOffset);
if (aPos->mStartOffset < 0)//start at "end"
aPos->mStartOffset = newOffset + 1;
if (NS_FAILED(result))
{
return result;
}
if ((aPos->mDirection == eDirNext && newOffset < aPos->mStartOffset) || //need to go to next one
(aPos->mDirection == eDirPrevious && newOffset >= aPos->mStartOffset))
{
result = GetFrameFromDirection(aPos);
if (NS_FAILED(result) || !aPos->mResultFrame)
{
return result?result:NS_ERROR_FAILURE;
}
return aPos->mResultFrame->PeekOffset(aPos);
}
else
{
if (aPos->mDirection == eDirNext)
aPos->mContentOffset = newOffset +1;
else
aPos->mContentOffset = newOffset;//to beginning of frame
}
}
}
break;
}//drop into no amount
case eSelectNoAmount:
{
nsCOMPtr<nsIPresContext> context;
result = aPos->mTracker->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(result) || !context)
return result;
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
result = GetContentAndOffsetsFromPoint(*(context.get()),point,
getter_AddRefs(aPos->mResultContent),
aPos->mContentOffset,
@ -2250,8 +2326,12 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos)
if (firstFrame)
{
nsPoint point;
point.x = aPos->mDesiredX;
point.y = 0;
nsPoint offsetPoint; //used for offset of result frame
nsIView * view; //used for call of get offset from view
firstFrame->GetOffsetFromView(offsetPoint, &view);
point.x = 0;//all the way to the left
point.y = offsetPoint.y;
result = firstFrame->GetContentAndOffsetsFromPoint(*(context.get()),point,
getter_AddRefs(aPos->mResultContent),
aPos->mContentOffset,
@ -2273,11 +2353,9 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos)
nsPoint offsetPoint; //used for offset of result frame
nsIView * view; //used for call of get offset from view
nextFrame->GetOffsetFromView(offsetPoint, &view);
usedRect.x = offsetPoint.x;
usedRect.y = offsetPoint.y;
nsPoint point;
point.x = 2* offsetPoint.x; //2* just to be sure we are off the edge
point.x = 2* usedRect.width; //2* just to be sure we are off the edge
point.y = offsetPoint.y;
result = nextFrame->GetContentAndOffsetsFromPoint(*(context.get()),
@ -2298,105 +2376,144 @@ nsFrame::PeekOffset(nsPeekOffsetStruct *aPos)
}
}
}break;
default:
{
//this will use the nsFrameTraversal as the default peek method.
//this should change to use geometry and also look to ALL the child lists
//we need to set up line information to make sure we dont jump across line boundaries
nsIFrame *blockFrame = this;
nsIFrame *thisBlock;
PRInt32 thisLine;
nsCOMPtr<nsILineIterator> it;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
}
else
blockFrame = nsnull;
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return result;
nsIFrame *firstFrame;
nsIFrame *lastFrame;
nsRect nonUsedRect;
PRInt32 lineFrameCount;
PRUint32 lineFlags;
result = it->GetLine(thisLine, &firstFrame, &lineFrameCount,nonUsedRect,
&lineFlags);
if (NS_FAILED(result))
return result;
lastFrame = firstFrame;
for (;lineFrameCount > 1;lineFrameCount --){
result = lastFrame->GetNextSibling(&lastFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsFrame\n");
return NS_ERROR_FAILURE;
}
}
//END LINE DATA CODE
if ((aPos->mDirection == eDirNext && lastFrame == this)
||(aPos->mDirection == eDirPrevious && firstFrame == this))
{
if (aPos->mAmount != eSelectWord)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
aPos->mAmount = eSelectNoAmount;
}
else{
if (aPos->mEatingWS)//done finding what we wanted
return NS_OK;
if (aPos->mDirection == eDirNext)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
aPos->mAmount = eSelectNoAmount;
}
}
}
if (aPos->mAmount == eSelectDir)
aPos->mAmount = eSelectNoAmount;//just get to next frame.
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
if (aPos->mDirection == eDirNext)
result = frameTraversal->Next();
else
result = frameTraversal->Prev();
if (NS_FAILED(result))
return result;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result))
return result;
if (!isupports)
return NS_ERROR_NULL_POINTER;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
//for speed reasons
nsIFrame *newFrame = (nsIFrame *)isupports;
if (aPos->mDirection == eDirNext)
aPos->mStartOffset = 0;
else
aPos->mStartOffset = -1;
return newFrame->PeekOffset(aPos);
if (NS_SUCCEEDED(result))
result = aPos->mResultFrame->PeekOffset(aPos);
}
}
return result;
}
PRInt32
nsFrame::GetLineNumber(nsIFrame *aFrame)
{
nsIFrame *blockFrame = aFrame;
nsIFrame *thisBlock;
PRInt32 thisLine;
nsCOMPtr<nsILineIterator> it;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
}
else
blockFrame = nsnull;
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return -1;
return thisLine;
}
//this will use the nsFrameTraversal as the default peek method.
//this should change to use geometry and also look to ALL the child lists
//we need to set up line information to make sure we dont jump across line boundaries
NS_IMETHODIMP
nsFrame::GetFrameFromDirection(nsPeekOffsetStruct *aPos)
{
nsIFrame *blockFrame = this;
nsIFrame *thisBlock;
PRInt32 thisLine;
nsCOMPtr<nsILineIterator> it;
nsresult result = NS_ERROR_FAILURE;
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
}
else
blockFrame = nsnull;
}
if (!blockFrame || !it)
return NS_ERROR_FAILURE;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result))
return result;
nsIFrame *firstFrame;
nsIFrame *lastFrame;
nsRect nonUsedRect;
PRInt32 lineFrameCount;
PRUint32 lineFlags;
result = it->GetLine(thisLine, &firstFrame, &lineFrameCount,nonUsedRect,
&lineFlags);
if (NS_FAILED(result))
return result;
lastFrame = firstFrame;
for (;lineFrameCount > 1;lineFrameCount --){
result = lastFrame->GetNextSibling(&lastFrame);
if (NS_FAILED(result)){
NS_ASSERTION(0,"should not be reached nsFrame\n");
return NS_ERROR_FAILURE;
}
}
GetFirstLeaf( &firstFrame);
GetLastLeaf(&lastFrame);
//END LINE DATA CODE
if ((aPos->mDirection == eDirNext && lastFrame == this)
||(aPos->mDirection == eDirPrevious && firstFrame == this))
{
if (aPos->mJumpLines != PR_TRUE)
return NS_ERROR_FAILURE;//we are done. cannot jump lines
if (aPos->mAmount != eSelectWord)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
aPos->mAmount = eSelectNoAmount;
}
else{
if (aPos->mEatingWS)//done finding what we wanted
return NS_ERROR_FAILURE;
if (aPos->mDirection == eDirNext)
{
aPos->mPreferLeft = (PRBool)!(aPos->mPreferLeft);//drift to other side
aPos->mAmount = eSelectNoAmount;
}
}
}
if (aPos->mAmount == eSelectDir)
aPos->mAmount = eSelectNoAmount;//just get to next frame.
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
if (aPos->mDirection == eDirNext)
result = frameTraversal->Next();
else
result = frameTraversal->Prev();
if (NS_FAILED(result))
return result;
result = frameTraversal->CurrentItem(&isupports);
if (NS_FAILED(result))
return result;
if (!isupports)
return NS_ERROR_NULL_POINTER;
//we must CAST here to an nsIFrame. nsIFrame doesnt really follow the rules
//for speed reasons
nsIFrame *newFrame = (nsIFrame *)isupports;
if (aPos->mDirection == eDirNext)
aPos->mStartOffset = 0;
else
aPos->mStartOffset = -1;
aPos->mResultFrame = newFrame;
return NS_OK;
}
nsresult nsFrame::GetClosestViewForFrame(nsIFrame *aFrame, nsIView **aView)
{
if (!aView)
@ -2480,8 +2597,8 @@ void ForceDrawFrame(nsFrame * aFrame)//, PRBool)
}
static void
GetLastLeaf(nsIFrame **aFrame)
void
nsFrame::GetLastLeaf(nsIFrame **aFrame)
{
if (!aFrame || !*aFrame)
return;
@ -2500,6 +2617,24 @@ GetLastLeaf(nsIFrame **aFrame)
*aFrame = child;
}
void
nsFrame::GetFirstLeaf(nsIFrame **aFrame)
{
if (!aFrame || !*aFrame)
return;
nsIFrame *child = *aFrame;
nsIFrame *lookahead;
nsresult result;
while (1){
result = child->FirstChild(nsnull, &lookahead);
if (NS_FAILED(result) || !lookahead)
return;//nothing to do
child = lookahead;
*aFrame = child;
}
}
#ifdef NS_DEBUG
static void
GetTagName(nsFrame* aFrame, nsIContent* aContent, PRIntn aResultSize,

View File

@ -332,9 +332,18 @@ protected:
PRBool DisplaySelection(nsIPresContext& aPresContext, PRBool isOkToTurnOn = PR_FALSE);
//this will modify aPos and return the next frame ect.
NS_IMETHOD GetFrameFromDirection(nsPeekOffsetStruct *aPos);
// Style post processing hook
NS_IMETHOD DidSetStyleContext(nsIPresContext* aPresContext);
//return the line number of the aFrame
static PRInt32 GetLineNumber(nsIFrame *aFrame);
//given a frame five me the first/last leaf available
static void GetLastLeaf(nsIFrame **aFrame);
static void GetFirstLeaf(nsIFrame **aFrame);
/**
* Dump out the "base classes" regression data. This should dump
* out the interior data, not the "frame" XML container. And it

View File

@ -40,6 +40,7 @@
#include "nsDOMEvent.h"
#include "nsHTMLParts.h"
#include "nsIDOMSelection.h"
#include "nsISelectionControler.h"
#include "nsLayoutCID.h"
#include "nsIDOMRange.h"
#include "nsIDOMDocument.h"
@ -52,7 +53,6 @@
#include "nsIDOMHTMLDocument.h"
#include "nsIXMLDocument.h"
#include "nsIScrollableView.h"
#include "nsIDOMSelectionListener.h"
#include "nsIParser.h"
#include "nsParserCIID.h"
#include "nsHTMLContentSinkStream.h"
@ -105,7 +105,7 @@ static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kIDOMRangeIID, NS_IDOMRANGE_IID);
static NS_DEFINE_IID(kIDOMDocumentIID, NS_IDOMDOCUMENT_IID);
static NS_DEFINE_IID(kIFocusTrackerIID, NS_IFOCUSTRACKER_IID);
static NS_DEFINE_IID(kIDomSelectionListenerIID, NS_IDOMSELECTIONLISTENER_IID);
static NS_DEFINE_IID(kISelectionControlerIID, NS_ISELECTIONCONTROLER_IID);
static NS_DEFINE_IID(kICaretIID, NS_ICARET_IID);
static NS_DEFINE_IID(kICaretID, NS_ICARET_IID);
static NS_DEFINE_IID(kIDOMHTMLDocumentIID, NS_IDOMHTMLDOCUMENT_IID);
@ -167,7 +167,8 @@ private:
class PresShell : public nsIPresShell, public nsIViewObserver,
private nsIDocumentObserver, public nsIFocusTracker,
public nsIDOMSelectionListener, public nsSupportsWeakReference
public nsISelectionControler,
public nsSupportsWeakReference
{
public:
PresShell();
@ -255,8 +256,15 @@ public:
NS_IMETHOD SetDisplayNonTextSelection(PRBool aaInEnable);
NS_IMETHOD GetDisplayNonTextSelection(PRBool *aOutEnable);
// nsIDOMSelectionListener interface
NS_IMETHOD NotifySelectionChanged();
// nsISelectionControler
NS_IMETHOD CharacterMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD WordMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD LineMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD IntraLineMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD PageMove(PRBool aForward, PRBool aExtend);
NS_IMETHOD ScrollPage(PRBool aForward);
NS_IMETHOD SelectAll();
// nsIDocumentObserver
NS_IMETHOD BeginUpdate(nsIDocument *aDocument);
@ -501,8 +509,8 @@ PresShell::QueryInterface(const nsIID& aIID, void** aInstancePtr)
NS_ADDREF_THIS();
return NS_OK;
}
if (aIID.Equals(kIDomSelectionListenerIID)) {
nsIDOMSelectionListener* tmp = this;
if (aIID.Equals(kISelectionControlerIID)) {
nsISelectionControler* tmp = this;
*aInstancePtr = (void*) tmp;
NS_ADDREF_THIS();
return NS_OK;
@ -612,10 +620,6 @@ PresShell::Init(nsIDocument* aDocument,
return result;
}
nsCOMPtr<nsIDOMSelection> domSelection;
mSelection->GetSelection(SELECTION_NORMAL, getter_AddRefs(domSelection));
domSelection->AddSelectionListener(this);//possible circular reference
result = mSelection->Init((nsIFocusTracker *) this);
if (!NS_SUCCEEDED(result))
return result;
@ -865,7 +869,6 @@ PresShell::EndObservingDocument()
return result;
if (!domselection)
return NS_ERROR_UNEXPECTED;
domselection->RemoveSelectionListener(this);
mSelection->ShutDown();
}
return NS_OK;
@ -1126,17 +1129,54 @@ NS_IMETHODIMP PresShell::GetDisplayNonTextSelection(PRBool *aOutEnable)
return NS_OK;
}
//implementation of nsISelectionControler
/*implementation of the nsIDOMSelectionListener
it will invoke the resetselection to update the presentation shell's frames
*/
NS_IMETHODIMP PresShell::NotifySelectionChanged()
NS_IMETHODIMP
PresShell::CharacterMove(PRBool aForward, PRBool aExtend)
{
if (!mSelection)
return NS_ERROR_NULL_POINTER;
return NS_ERROR_NULL_POINTER;
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::WordMove(PRBool aForward, PRBool aExtend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::LineMove(PRBool aForward, PRBool aExtend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::IntraLineMove(PRBool aForward, PRBool aExtend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::PageMove(PRBool aForward, PRBool aExtend)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::ScrollPage(PRBool aForward)
{
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
PresShell::SelectAll()
{
return NS_ERROR_NOT_IMPLEMENTED;
}
//end implementations nsISelectionControler
NS_IMETHODIMP
PresShell::StyleChangeReflow()
{
@ -2109,14 +2149,10 @@ PresShell::HandleEvent(nsIView *aView,
if (mSelection && aEvent->eventStructType == NS_KEY_EVENT)
{//KEY HANDLERS WILL GET RID OF THIS
mSelection->EnableFrameNotification(PR_FALSE);
if (mDisplayNonTextSelection && NS_SUCCEEDED(mSelection->HandleKeyEvent(aEvent)))
{
mSelection->EnableFrameNotification(PR_TRUE); //prevents secondary reset selection called since
return NS_OK;
}
mSelection->EnableFrameNotification(PR_TRUE); //prevents secondary reset selection called since
//we are a listener now.
}
if (nsnull != frame) {

View File

@ -2200,7 +2200,11 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
}
if (!found)
result = nsFrame::PeekOffset(aPos);
{
result = GetFrameFromDirection(aPos);
if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
result = aPos->mResultFrame->PeekOffset(aPos);
}
else
aPos->mResultContent = mContent;
}
@ -2233,7 +2237,7 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
if (aPos->mDirection == eDirPrevious){
keepSearching = PR_TRUE;
tx.Init(this, mContent, aPos->mStartOffset);
aPos->mContentOffset = mContentOffset;//initialize
if (tx.GetPrevWord(PR_FALSE, &wordLen, &contentLen, &isWhitespace,
PR_FALSE) &&
(aPos->mStartOffset - contentLen >= mContentOffset) ){
@ -2270,6 +2274,7 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
}
else if (aPos->mDirection == eDirNext) {
tx.Init(this, mContent, aPos->mStartOffset );
aPos->mContentOffset = mContentOffset + mContentLength;//initialize
#ifdef DEBUGWORDJUMP
printf("Next- Start=%d aPos->mEatingWS=%s\n", aPos->mStartOffset, aPos->mEatingWS ? "TRUE" : "FALSE");
@ -2304,7 +2309,7 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
}
else if (!keepSearching) //we have found the "whole" word so just looking for WS
aPos->mEatingWS = PR_TRUE;
}
}
frameUsed = GetNextInFlow();
start = 0;
}
@ -2315,11 +2320,19 @@ nsTextFrame::PeekOffset(nsPeekOffsetStruct *aPos)
{
aPos->mContentOffset = PR_MIN(aPos->mContentOffset, mContentOffset + mContentLength);
aPos->mContentOffset = PR_MAX(aPos->mContentOffset, mContentOffset);
result = nsFrame::PeekOffset(aPos);
result = GetFrameFromDirection(aPos);
if (NS_SUCCEEDED(result) && aPos->mResultFrame && aPos->mResultFrame!= this)
{
if (NS_SUCCEEDED(result = aPos->mResultFrame->PeekOffset(aPos)))
return NS_OK;//else fall through
}
else
aPos->mResultContent = mContent;
}
else
{
aPos->mResultContent = mContent;
}
}
break;
default:
@ -2365,6 +2378,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
if (NS_SUCCEEDED(mPrefs->GetIntPref("browser.triple_click_style", &prefInt)) && prefInt)
return nsFrame::HandleMultiplePress(aPresContext, aEvent, aEventStatus);
}
//THIS NEXT CODE IS FOR PARAGRAPH
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
@ -2437,9 +2451,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
PRInt32 contentOffsetEnd = 0;
nsCOMPtr<nsIContent> newContent;
//find which word needs to be selected! use peek offset one way then the other
nsCOMPtr<nsIContent> startContent;
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIContent> endContent;
nsCOMPtr<nsIDOMNode> endNode;
if (NS_SUCCEEDED(GetPosition(aPresContext, aEvent->point.x,
getter_AddRefs(newContent), startPos, contentOffsetEnd))){
@ -2451,7 +2463,8 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
eDirPrevious,
startPos,
PR_FALSE,
PR_TRUE);
PR_TRUE,
PR_FALSE);
rv = PeekOffset(&startpos);
if (NS_FAILED(rv))
return rv;
@ -2462,6 +2475,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
eDirNext,
startPos,
PR_FALSE,
PR_FALSE,
PR_FALSE);
rv = PeekOffset(&endpos);
if (NS_FAILED(rv))
@ -2473,6 +2487,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
startNode = do_QueryInterface(startpos.mResultContent,&rv);
if (NS_FAILED(rv))
return rv;
nsCOMPtr<nsIDOMSelection> selection;
if (NS_SUCCEEDED(shell->GetSelection(SELECTION_NORMAL, getter_AddRefs(selection)))){
rv = selection->Collapse(startNode,startpos.mContentOffset);
@ -2490,6 +2505,7 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
}
NS_IMETHODIMP
nsTextFrame::GetOffsets(PRInt32 &start, PRInt32 &end) const
{