selection changes for new model of content only. frames no longer contain variables referring to selection state outside of 1 bit. keyboard selection will now be disabled until i can get it working in the new selection world order.

This commit is contained in:
mjudge%netscape.com 1999-04-26 04:02:04 +00:00
parent ba2a8f56ee
commit f302ca2537
15 changed files with 1147 additions and 1433 deletions

View File

@ -35,22 +35,6 @@
{ 0xf46e4171, 0xdeaa, 0x11d1, \
{ 0x97, 0xfc, 0x0, 0x60, 0x97, 0x3, 0xc1, 0x4e } }
/** nsSelectionStruct is used to pass structured parameters to the SelectionCalls.
*/
struct nsSelectionStruct
{
enum {SELON = 1,SELALL = 2,SELTOEND = 4,SELTOBEGIN = 8,CHECKANCHOR=16,CHECKFOCUS=32};//this is not a bit flag
PRUint32 mType;
PRUint32 mStartContent;//in content offsets.
PRUint32 mEndContent;
PRUint32 mStartFrame;
PRUint32 mEndFrame;
PRUint32 mAnchorOffset;
PRUint32 mFocusOffset;
nsDirection mDir; //tells you if you have to swap the begin and end points.
PRBool mForceRedraw;
};
//----------------------------------------------------------------------
@ -59,44 +43,61 @@ class nsIFrameSelection : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IFRAMESELECTION_IID; return iid; }
/** HandleKeyEvent will accept an event and frame and
* will return NS_OK if it handles the event or NS_COMFALSE if not.
* <P>DOES NOT ADDREF<P>
* @param tracker to ask where the current focus is and to set the new anchor ect.
* @param aGuiEvent is the event that should be dealt with by aFocusFrame
* @param aFrame is the frame that MAY handle the event
/** Init will initialize the frame selector with the necessary focus tracker to
* be used by most of the methods
* @param aTracker is the parameter to be used for most of the other calls for callbacks ect
*/
NS_IMETHOD HandleTextEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent) = 0;
NS_IMETHOD Init(nsIFocusTracker *aTracker) = 0;
/** ShutDown will be called when the owner of the frame selection is shutting down
* this should be the time to release all member variable interfaces. all methods
* called after ShutDown should return NS_ERROR_FAILURE
*/
NS_IMETHOD ShutDown() = 0;
/** HandleKeyEvent will accept an event and frame and
* will return NS_OK if it handles the event or NS_COMFALSE if not.
* <P>DOES NOT ADDREF<P>
* @param tracker to ask where the current focus is and to set the new anchor ect.
* @param aGuiEvent is the event that should be dealt with by aFocusFrame
* @param aFrame is the frame that MAY handle the event
*/
NS_IMETHOD HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent) = 0;
NS_IMETHOD HandleTextEvent(nsGUIEvent *aGuiEvent) = 0;
/** HandleKeyEvent will accept an event and frame and
* will return NS_OK if it handles the event or NS_COMFALSE if not.
* <P>DOES NOT ADDREF<P>
* @param aGuiEvent is the event that should be dealt with by aFocusFrame
* @param aFrame is the frame that MAY handle the event
*/
NS_IMETHOD HandleKeyEvent(nsGUIEvent *aGuiEvent) = 0;
/** TakeFocus will take the focus to the new frame at the new offset and
* will either extend the selection from the old anchor, or replace the old anchor.
* the old anchor and focus position may also be used to deselect things
* @param aTracker we need a focus tracker to get the old focus ect.
* @param aFrame is the frame that wants the focus
* @param aOffset is the offset in the aFrame that will get the focus point
* @param aContentOffset is the offset in the node of the aFrame that is reflected be aOffset
* @param aNewfocus is the content that wants the focus
* @param aContentOffset is the content offset of the parent aNewFocus
* @param aContinueSelection is the flag that tells the selection to keep the old anchor point or not.
*/
NS_IMETHOD TakeFocus(nsIFocusTracker *aTracker, nsIFrame *aFrame, PRInt32 aOffset, PRInt32 aContentOffset, PRBool aContinueSelection) = 0;
/** ResetSelection will top down search for frames that need selection
*/
NS_IMETHOD ResetSelection(nsIFocusTracker *aTracker, nsIFrame *aStartFrame) = 0;
NS_IMETHOD TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, PRBool aContinueSelection) = 0;
/** EnableFrameNotification
* mutch like start batching, except all dirty calls are ignored. no notifications will go
* out until enableNotifications with a PR_TRUE is called
*/
NS_IMETHOD EnableFrameNotification(PRBool aEnable) = 0;
/** Lookup Selection
* returns in frame coordinates the selection beginning and ending with the type of selection given
* @param aContent is the content asking
* @param aContentOffset is the starting content boundary
* @param aContentLength is the length of the content piece asking
* @param aStart start return frame indexed value
* @param aEnd end return frame indexed value
* @param aDrawSelected return value if this offset,length has anything in the selected area
* @param aFlag what type of selection not used now
*/
NS_IMETHOD LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
PRInt32 *aStart, PRInt32 *aEnd, PRBool *aDrawSelected, PRUint32 aFlag/*not used*/) = 0;
};

View File

@ -597,35 +597,16 @@ PresShell::Init(nsIDocument* aDocument,
getter_AddRefs(domselection));
if (!NS_SUCCEEDED(result))
return result;
result = domselection->QueryInterface(kIFrameSelectionIID,
getter_AddRefs(mSelection));
getter_AddRefs(mSelection));
if (!NS_SUCCEEDED(result))
return result;
domselection->AddSelectionListener(this);//possible circular reference
// XXX This code causes the document object (and the entire content model) to be leaked...
#if 0
nsCOMPtr<nsIDOMRange>range;
if (NS_SUCCEEDED(nsComponentManager::CreateInstance(kCRangeCID, nsnull, kIDOMRangeIID, getter_AddRefs(range)))){ //create an irange
nsCOMPtr<nsIDocument>doc(GetDocument());
nsCOMPtr<nsIDOMDocument>domDoc(doc);
if (domDoc){
nsCOMPtr<nsIDOMElement> domElement;
if (NS_SUCCEEDED(domDoc->GetDocumentElement(getter_AddRefs(domElement)))) {//get the first element from the dom
nsCOMPtr<nsIDOMNode>domNode(domElement);
if (domNode) {//get the node interface for the range object
range->SetStart(domNode,0);
range->SetEnd(domNode,0);
nsCOMPtr<nsISupports>rangeISupports(range);
if (rangeISupports) {
selection->AddItem(rangeISupports);
}
}
}
}
}
#endif
result = mSelection->Init((nsIFocusTracker *) this);
if (!NS_SUCCEEDED(result))
return result;
// Important: this has to happen after the selection has been set up
#ifdef SHOW_CARET
nsCaretProperties *caretProperties = NewCaretProperties();
@ -836,6 +817,7 @@ PresShell::EndObservingDocument()
if (!domselection)
return NS_ERROR_UNEXPECTED;
domselection->RemoveSelectionListener(this);
mSelection->ShutDown();
}
return NS_OK;
}
@ -958,12 +940,6 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
NS_IF_RELEASE(rcx);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::ResizeReflow"));
if (mSelection){
DisableScrolling();
mSelection->ResetSelection(this, mRootFrame);
EnableScrolling();
}
// XXX if debugging then we should assert that the cache is empty
} else {
#ifdef NOISY
@ -1049,7 +1025,6 @@ NS_IMETHODIMP PresShell::NotifySelectionChanged()
{
if (!mSelection)
return NS_ERROR_NULL_POINTER;
mSelection->ResetSelection(this, mRootFrame);
return NS_ERROR_NULL_POINTER;
}
@ -1636,8 +1611,6 @@ PresShell::ContentChanged(nsIDocument *aDocument,
EnterReflowLock();
nsresult rv = mStyleSet->ContentChanged(mPresContext, aContent, aSubContent);
ExitReflowLock();
if (mSelection)
mSelection->ResetSelection(this, mRootFrame);
return rv;
}
@ -1652,8 +1625,6 @@ PresShell::ContentStatesChanged(nsIDocument* aDocument,
EnterReflowLock();
nsresult rv = mStyleSet->ContentStatesChanged(mPresContext, aContent1, aContent2);
ExitReflowLock();
//if (mSelection)
//mSelection->ResetSelection(this, mRootFrame);
return rv;
}
@ -2019,7 +1990,7 @@ PresShell::HandleEvent(nsIView *aView,
if (mSelection && mFocusEventFrame && aEvent->eventStructType == NS_KEY_EVENT)
{
mSelection->EnableFrameNotification(PR_FALSE);
mSelection->HandleKeyEvent((nsIFocusTracker *)this, aEvent);
mSelection->HandleKeyEvent(aEvent);
mSelection->EnableFrameNotification(PR_TRUE); //prevents secondary reset selection called since
//we are a listener now.
}

View File

@ -44,7 +44,7 @@ class nsStyleChangeList;
struct nsPoint;
struct nsRect;
struct nsStyleStruct;
struct nsSelectionStruct;
class nsIDOMRange;
struct PRLogModuleInfo;
@ -127,6 +127,9 @@ typedef PRUint32 nsFrameState;
// e.g., it is absolutely positioned or floated
#define NS_FRAME_OUT_OF_FLOW 0x00000100
// If this bit is set, then the frame reflects content that may be selected
#define NS_FRAME_SELECTED_CONTENT 0x00000200
// The low 16 bits of the frame state word are reserved by this API.
#define NS_FRAME_RESERVED 0x0000FFFF
@ -579,21 +582,13 @@ public:
* Called to set the selection of the frame based on frame offsets. you can FORCE the frame
* to redraw event if aSelected == the frame selection with the last parameter.
* data in struct may be changed when passed in.
* @param nsSelectionStruct will hold the data pertinant to the Selection, Selected or not ect.
* @param aRange is the range that will dictate if the frames need to be redrawn null means the whole content needs to be redrawn
* @param aSelected is it selected
* @param aSpread should is spread selection to flow elements around it?
*/
NS_IMETHOD SetSelected(nsSelectionStruct *) = 0;
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread) = 0;
/**
* Called to start a selection with this frame content.
* @param aSS is the struct that holds the data instead of passing in so many parameters
* @param aFocusTracker will allow the frame to set the focus to what it needs.
* @param return value of which frame (maybe not this one, maybe one of its siblings)
*/
NS_IMETHOD SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected)=0;
NS_IMETHOD GetSelected(PRBool *aSelected, PRInt32 *aBeginOffset, PRInt32 *aEndOffset, PRInt32 *aBeginContentOffset) = 0;
NS_IMETHOD GetSelected(PRBool *aSelected) const = 0;
/**
* called to find the previous/next character, word, or line returns the actual
@ -609,7 +604,7 @@ public:
* @param aEatingWS boolean to tell us the state of our search for Next/Prev
*/
NS_IMETHOD PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset, PRBool aEatingWS) = 0;
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset, PRBool aEatingWS) const = 0;
/**
* See if tree verification is enabled. To enable tree verification add

View File

@ -35,22 +35,6 @@
{ 0xf46e4171, 0xdeaa, 0x11d1, \
{ 0x97, 0xfc, 0x0, 0x60, 0x97, 0x3, 0xc1, 0x4e } }
/** nsSelectionStruct is used to pass structured parameters to the SelectionCalls.
*/
struct nsSelectionStruct
{
enum {SELON = 1,SELALL = 2,SELTOEND = 4,SELTOBEGIN = 8,CHECKANCHOR=16,CHECKFOCUS=32};//this is not a bit flag
PRUint32 mType;
PRUint32 mStartContent;//in content offsets.
PRUint32 mEndContent;
PRUint32 mStartFrame;
PRUint32 mEndFrame;
PRUint32 mAnchorOffset;
PRUint32 mFocusOffset;
nsDirection mDir; //tells you if you have to swap the begin and end points.
PRBool mForceRedraw;
};
//----------------------------------------------------------------------
@ -59,44 +43,61 @@ class nsIFrameSelection : public nsISupports {
public:
static const nsIID& GetIID() { static nsIID iid = NS_IFRAMESELECTION_IID; return iid; }
/** HandleKeyEvent will accept an event and frame and
* will return NS_OK if it handles the event or NS_COMFALSE if not.
* <P>DOES NOT ADDREF<P>
* @param tracker to ask where the current focus is and to set the new anchor ect.
* @param aGuiEvent is the event that should be dealt with by aFocusFrame
* @param aFrame is the frame that MAY handle the event
/** Init will initialize the frame selector with the necessary focus tracker to
* be used by most of the methods
* @param aTracker is the parameter to be used for most of the other calls for callbacks ect
*/
NS_IMETHOD HandleTextEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent) = 0;
NS_IMETHOD Init(nsIFocusTracker *aTracker) = 0;
/** ShutDown will be called when the owner of the frame selection is shutting down
* this should be the time to release all member variable interfaces. all methods
* called after ShutDown should return NS_ERROR_FAILURE
*/
NS_IMETHOD ShutDown() = 0;
/** HandleKeyEvent will accept an event and frame and
* will return NS_OK if it handles the event or NS_COMFALSE if not.
* <P>DOES NOT ADDREF<P>
* @param tracker to ask where the current focus is and to set the new anchor ect.
* @param aGuiEvent is the event that should be dealt with by aFocusFrame
* @param aFrame is the frame that MAY handle the event
*/
NS_IMETHOD HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent) = 0;
NS_IMETHOD HandleTextEvent(nsGUIEvent *aGuiEvent) = 0;
/** HandleKeyEvent will accept an event and frame and
* will return NS_OK if it handles the event or NS_COMFALSE if not.
* <P>DOES NOT ADDREF<P>
* @param aGuiEvent is the event that should be dealt with by aFocusFrame
* @param aFrame is the frame that MAY handle the event
*/
NS_IMETHOD HandleKeyEvent(nsGUIEvent *aGuiEvent) = 0;
/** TakeFocus will take the focus to the new frame at the new offset and
* will either extend the selection from the old anchor, or replace the old anchor.
* the old anchor and focus position may also be used to deselect things
* @param aTracker we need a focus tracker to get the old focus ect.
* @param aFrame is the frame that wants the focus
* @param aOffset is the offset in the aFrame that will get the focus point
* @param aContentOffset is the offset in the node of the aFrame that is reflected be aOffset
* @param aNewfocus is the content that wants the focus
* @param aContentOffset is the content offset of the parent aNewFocus
* @param aContinueSelection is the flag that tells the selection to keep the old anchor point or not.
*/
NS_IMETHOD TakeFocus(nsIFocusTracker *aTracker, nsIFrame *aFrame, PRInt32 aOffset, PRInt32 aContentOffset, PRBool aContinueSelection) = 0;
/** ResetSelection will top down search for frames that need selection
*/
NS_IMETHOD ResetSelection(nsIFocusTracker *aTracker, nsIFrame *aStartFrame) = 0;
NS_IMETHOD TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, PRBool aContinueSelection) = 0;
/** EnableFrameNotification
* mutch like start batching, except all dirty calls are ignored. no notifications will go
* out until enableNotifications with a PR_TRUE is called
*/
NS_IMETHOD EnableFrameNotification(PRBool aEnable) = 0;
/** Lookup Selection
* returns in frame coordinates the selection beginning and ending with the type of selection given
* @param aContent is the content asking
* @param aContentOffset is the starting content boundary
* @param aContentLength is the length of the content piece asking
* @param aStart start return frame indexed value
* @param aEnd end return frame indexed value
* @param aDrawSelected return value if this offset,length has anything in the selected area
* @param aFlag what type of selection not used now
*/
NS_IMETHOD LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
PRInt32 *aStart, PRInt32 *aEnd, PRBool *aDrawSelected, PRUint32 aFlag/*not used*/) = 0;
};

View File

@ -36,9 +36,18 @@
#include "nsISupportsArray.h"
#include "nsIDOMEvent.h"
#include "nsIDOMSelectionListener.h"
#include "nsIContentIterator.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#define STATUS_CHECK_RETURN_MACRO() {if (!mTracker) return NS_ERROR_FAILURE;}
static NS_DEFINE_IID(kIEnumeratorIID, NS_IENUMERATOR_IID);
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
static NS_DEFINE_IID(kIFrameSelectionIID, NS_IFRAMESELECTION_IID);
@ -47,16 +56,12 @@ static NS_DEFINE_IID(kIDOMSelectionIID, NS_IDOMSELECTION_IID);
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
static NS_DEFINE_IID(kIDOMRangeIID, NS_IDOMRANGE_IID);
static NS_DEFINE_IID(kIDOMNodeIID, NS_IDOMNODE_IID);
static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
static NS_DEFINE_IID(kIContentIteratorIID, NS_ICONTENTITERTOR_IID);
//PROTOTYPES
static void selectFrames(nsIFrame *aBegin, PRUint32 aBeginOffset, nsIFrame *aEnd, PRUint32 aEndOffset, nsDirection aDir, PRUint32 aFlags);
static void unselectFrames(nsIFrame *aRootFrame);
static PRInt32 compareFrames(nsIFrame *aBegin, nsIFrame *aEnd);
static nsIFrame * getNextFrame(nsIFrame *aStart);
static void printRange(nsIDOMRange *aDomRange);
//static nsIFrame *findFrameFromContent(nsIFrame *aParent, nsIContent *aContent, PRBool aTurnOff);
enum {FORWARD =1, BACKWARD = 0};
#if 1
#define DEBUG_OUT_RANGE(x) printRange(x)
@ -79,11 +84,14 @@ public:
NS_DECL_ISUPPORTS
/*BEGIN nsIFrameSelection interfaces*/
NS_IMETHOD HandleTextEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGUIEvent);
NS_IMETHOD HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent);
NS_IMETHOD TakeFocus(nsIFocusTracker *aTracker, nsIFrame *aFrame, PRInt32 aOffset, PRInt32 aContentOffset, PRBool aContinueSelection);
NS_IMETHOD ResetSelection(nsIFocusTracker *aTracker, nsIFrame *aStartFrame);
NS_IMETHOD Init(nsIFocusTracker *aTracker);
NS_IMETHOD ShutDown();
NS_IMETHOD HandleTextEvent(nsGUIEvent *aGUIEvent);
NS_IMETHOD HandleKeyEvent(nsGUIEvent *aGuiEvent);
NS_IMETHOD TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, PRBool aContinueSelection);
NS_IMETHOD EnableFrameNotification(PRBool aEnable){mNotifyFrames = aEnable; return NS_OK;}
NS_IMETHOD LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
PRInt32 *aStart, PRInt32 *aEnd, PRBool *aDrawSelected , PRUint32 aFlag/*not used*/);
/*END nsIFrameSelection interfacse*/
/*BEGIN nsIDOMSelection interface implementations*/
@ -120,7 +128,7 @@ private:
nsresult RemoveItem(nsISupports *aRange);
nsresult Clear();
NS_IMETHOD ScrollIntoView(nsIFocusTracker *aTracker);
NS_IMETHOD ScrollIntoView();
friend class nsRangeListIterator;
@ -146,6 +154,8 @@ private:
nsresult NotifySelectionListeners(); // add parameters to say collapsed etc?
NS_IMETHOD selectFrames(nsIDOMRange *aRange, PRBool aSelect);
nsCOMPtr<nsISupportsArray> mRangeArray;
nsCOMPtr<nsIDOMNode> mAnchorNode; //where did the selection begin
@ -162,6 +172,7 @@ private:
// for nsIScriptContextOwner
void* mScriptObject;
nsCOMPtr<nsIFocusTracker> mTracker;
};
class nsRangeListIterator : public nsIBidirectionalEnumerator
@ -553,11 +564,17 @@ nsRangeList::Clear()
setAnchor(nsnull,0);
if (!mRangeArray)
return NS_ERROR_FAILURE;
for (PRUint32 i = 0; i < mRangeArray->Count();i++)
// Get an iterator
while ( mRangeArray->Count())
{
mRangeArray->RemoveElementAt(i);
nsCOMPtr<nsIDOMRange> range;
nsCOMPtr<nsISupports> isupportsindex = dont_AddRef(mRangeArray->ElementAt(0));
range = do_QueryInterface(isupportsindex);
mRangeArray->RemoveElementAt(0);
selectFrames(range, 0);
// Does RemoveElementAt also delete the elements?
}
return NS_OK;
}
@ -592,51 +609,61 @@ void printRange(nsIDOMRange *aDomRange)
*/
}
NS_IMETHODIMP
nsRangeList::HandleTextEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGUIEvent)
nsRangeList::Init(nsIFocusTracker *aTracker)
{
if (!aGUIEvent || !aTracker)
mTracker = dont_QueryInterface(aTracker);
return NS_OK;
}
NS_IMETHODIMP
nsRangeList::ShutDown()
{
nsCOMPtr<nsIFocusTracker> x;
mTracker = x;
return NS_OK;
}
NS_IMETHODIMP
nsRangeList::HandleTextEvent(nsGUIEvent *aGUIEvent)
{
if (!aGUIEvent)
return NS_ERROR_NULL_POINTER;
#ifdef DEBUG_TAGUE
printf("nsRangeList: HandleTextEvent\n");
#endif
nsIFrame *anchor;
nsIFrame *frame;
nsresult result = aTracker->GetFocus(&frame, &anchor);
if (NS_FAILED(result))
return result;
nsresult result(NS_OK);
if (NS_TEXT_EVENT == aGUIEvent->message) {
PRBool selected;
PRInt32 beginoffset = 0;
PRInt32 endoffset;
PRInt32 contentoffset;
nsresult result = NS_OK;
nsTextEvent *textEvent = (nsTextEvent *)aGUIEvent; //this is ok. It really is a textevent
PRInt32 offsetused = beginoffset;
nsSelectionAmount amount = eSelectCharacter; // for now
result = frame->GetSelected(&selected,&beginoffset,&endoffset, &contentoffset);
result = ScrollIntoView(aTracker);
result = ScrollIntoView();
}
return NS_OK;
return result;
}
/** This raises a question, if this method is called and the aFrame does not reflect the current
* focus DomNode, it is invalid? The answer now is yes.
*/
NS_IMETHODIMP
nsRangeList::HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent)
nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent)
{
if (!aGuiEvent ||!aTracker)
if (!aGuiEvent)
return NS_ERROR_NULL_POINTER;
STATUS_CHECK_RETURN_MACRO();
return NS_OK;
#if 0
nsIFrame *anchor;
nsIFrame *frame;
nsresult result = aTracker->GetFocus(&frame, &anchor);
nsresult result = mTracker->GetFocus(&frame, &anchor);
if (NS_FAILED(result))
return result;
if (NS_KEY_DOWN == aGuiEvent->message) {
@ -654,7 +681,7 @@ nsRangeList::HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent)
PRInt32 offsetused = beginoffset;
nsIFrame *frameused;
nsSelectionAmount amount = eSelectCharacter;
result = frame->GetSelected(&selected,&beginoffset,&endoffset, &contentoffset);
result = frame->GetSelected(&selected);
if (NS_FAILED(result)){
return result;
}
@ -679,9 +706,9 @@ nsRangeList::HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent)
frameused = anchor;
}
if (NS_SUCCEEDED(frameused->PeekOffset(amount, eDirPrevious, offsetused, &resultFrame, &frameOffset, &contentOffset, PR_FALSE)) && resultFrame){
result = TakeFocus(aTracker, resultFrame, frameOffset, contentOffset, keyEvent->isShift);
result = TakeFocus(resultFrame, frameOffset, contentOffset, keyEvent->isShift);
}
result = ScrollIntoView(aTracker);
result = ScrollIntoView();
break;
case nsIDOMEvent::VK_RIGHT :
//we need to look for the next PAINTED location to move the cursor to.
@ -701,9 +728,9 @@ nsRangeList::HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent)
frameused = frame;
}
if (NS_SUCCEEDED(frameused->PeekOffset(amount, eDirNext, offsetused, &resultFrame, &frameOffset, &contentOffset, PR_FALSE)) && resultFrame){
result = TakeFocus(aTracker, resultFrame, frameOffset, contentOffset, keyEvent->isShift);
result = TakeFocus(resultFrame, frameOffset, contentOffset, keyEvent->isShift);
}
result = ScrollIntoView(aTracker);
result = ScrollIntoView();
break;
case nsIDOMEvent::VK_UP :
#ifdef DEBUG_NAVIGATION
@ -714,6 +741,7 @@ nsRangeList::HandleKeyEvent(nsIFocusTracker *aTracker, nsGUIEvent *aGuiEvent)
}
}
return result;
#endif
}
#ifdef DEBUG
@ -754,398 +782,230 @@ void nsRangeList::printSelection()
//recursive-oid method to get next frame
nsIFrame *
getNextFrame(nsIFrame *aStart)
{
nsIFrame *result;
nsIFrame *parent = aStart;
if (parent && NS_SUCCEEDED(parent->FirstChild(nsnull, &result)) && result){
return result;
}
while(parent){
if (NS_SUCCEEDED(parent->GetNextSibling(&result)) && result){
parent = result;
return result;
}
else
if (NS_FAILED(parent->GetParent(&result)) || !result)
return nsnull;
else
parent = result;
}
return nsnull;
}
//compare the 2 passed in frames -1 first is smaller 1 second is smaller 0 they are the same
PRInt32
compareFrames(nsIFrame *aBegin, nsIFrame *aEnd)
{
if (!aBegin || !aEnd)
return 0;
if (aBegin == aEnd)
return 0;
nsCOMPtr<nsIContent> beginContent;
if (NS_SUCCEEDED(aBegin->GetContent(getter_AddRefs(beginContent))) && beginContent){
nsCOMPtr<nsIDOMNode>beginNode (do_QueryInterface(beginContent));
nsCOMPtr<nsIContent> endContent;
if (NS_SUCCEEDED(aEnd->GetContent(getter_AddRefs(endContent))) && endContent){
nsCOMPtr<nsIDOMNode>endNode (do_QueryInterface(endContent));
PRBool storage;
PRInt32 int1;
PRInt32 int2;
PRInt32 contentOffset1;
PRInt32 contentOffset2;
aBegin->GetSelected(&storage,&int1,&int2,&contentOffset1);
aEnd->GetSelected(&storage,&int1,&int2,&contentOffset2);
return ComparePoints(beginNode, contentOffset1, endNode, contentOffset2);
}
}
return 0;
}
//the idea of this helper method is to select, deselect "top to bottom" traversing through the frames
void
selectFrames(nsIFrame *aBegin, PRUint32 aBeginOffset, nsIFrame *aEnd, PRUint32 aEndOffset, nsDirection aDir, PRUint32 aFlags)
NS_IMETHODIMP
nsRangeList::selectFrames(nsIDOMRange *aRange, PRBool aFlags)
{
if (!aBegin || !aEnd)
return;
PRBool done = PR_FALSE;
while (!done)
if (!aRange)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIContentIterator> iter;
nsresult result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull,
kIContentIteratorIID,
getter_AddRefs(iter));
if ((NS_SUCCEEDED(result)) && iter)
{
PRUint32 type(aFlags);
nsSelectionStruct ss = {0};
if (aBegin == aEnd)
iter->Init(aRange);
// loop through the content iterator for each content node
// for each text node:
// get the frame for the content, and from it the style context
// ask the style context about the property
nsCOMPtr<nsIContent> content;
PRBool drawWholeContent = PR_FALSE;
result = iter->First();
if (NS_FAILED(result))
return result;
nsIFrame *frame;
while (NS_COMFALSE == iter->IsDone())
{
ss.mType = type;
ss.mStartFrame = aBeginOffset;
ss.mEndFrame = aEndOffset;
ss.mDir = aDir;
aBegin->SetSelected(&ss);
done = PR_TRUE;
}
else {
//else we neeed to select from begin to end
type |= nsSelectionStruct::SELTOEND;
ss.mType = type;
ss.mStartFrame = aBeginOffset;
ss.mEndFrame = aEndOffset;
ss.mDir = aDir;
aBegin->SetSelected(&ss);
aBeginOffset = 0;
if (!(aBegin = getNextFrame(aBegin)))
{
done = PR_TRUE;
}
result = iter->CurrentNode(getter_AddRefs(content));
if (NS_FAILED(result))
return result;
result = mTracker->GetPrimaryFrameFor(content, &frame);
if (NS_SUCCEEDED(result) && frame)
frame->SetSelected(aRange,aFlags,PR_TRUE);//spread from here to hit all frames in flow
iter->Next();
}
}
return result;
}
// unselect all frames under the root frame
void
unselectFrames(nsIFrame *aRootFrame)
{
nsIFrame *theFrame = aRootFrame;
nsSelectionStruct ss = {0}; // all that's important is that the selection_on flag is not lit.
while (theFrame)
{
theFrame->SetSelected(&ss);
theFrame = getNextFrame(theFrame);
}
}
/**
hard to go from nodes to frames, easy the other way!
*/
NS_IMETHODIMP
nsRangeList::TakeFocus(nsIFocusTracker *aTracker, nsIFrame *aFrame, PRInt32 aOffset, PRInt32 aContentOffset, PRBool aContinueSelection)
nsRangeList::TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset, PRBool aContinueSelection)
{
if (!aTracker || !aFrame)
if (!aNewFocus)
return NS_ERROR_NULL_POINTER;
if (GetBatching())
return NS_ERROR_FAILURE;
STATUS_CHECK_RETURN_MACRO();
//HACKHACKHACK
nsCOMPtr<nsIContent> content;
nsCOMPtr<nsIDOMNode> domNode;
if (NS_SUCCEEDED(aFrame->GetContent(getter_AddRefs(content))) && content){
nsCOMPtr<nsIContent> parent;
nsCOMPtr<nsIContent> parent2;
if (NS_FAILED(content->GetParent(*getter_AddRefs(parent))) || !parent)
return NS_ERROR_FAILURE;
if (NS_FAILED(parent->GetParent(*getter_AddRefs(parent2))) || !parent2)
return NS_ERROR_FAILURE;
domNode = do_QueryInterface(content);
parent = nsCOMPtr<nsIContent>();//just force a release now even though we dont have to.
parent2 = nsCOMPtr<nsIContent>();
nsCOMPtr<nsIContent> parent;
nsCOMPtr<nsIContent> parent2;
if (NS_FAILED(aNewFocus->GetParent(*getter_AddRefs(parent))) || !parent)
return NS_ERROR_FAILURE;
if (NS_FAILED(parent->GetParent(*getter_AddRefs(parent2))) || !parent2)
return NS_ERROR_FAILURE;
domNode = do_QueryInterface(aNewFocus);
//traverse through document and unselect crap here
if (!aContinueSelection){ //single click? setting cursor down
PRUint32 batching = mBatching;//hack to use the collapse code.
PRBool changes = mChangesDuringBatching;
mBatching = 1;
Collapse(domNode, aContentOffset);
mBatching = batching;
mChangesDuringBatching = changes;
}
else {
//compare anchor to old cursor.
nsCOMPtr<nsIDOMNode> anchorNode;
nsCOMPtr<nsIDOMNode> focusNode;
PRInt32 anchorOffset;
PRInt32 focusOffset;
nsresult result = NS_OK;
result = GetAnchorNode(getter_AddRefs(anchorNode));
result |= GetAnchorOffset(&anchorOffset);
result |= GetFocusNode(getter_AddRefs(focusNode));
result |= GetFocusOffset(&focusOffset);
nsIFrame *frame;
nsIFrame *anchor;
PRBool direction(BACKWARD);//true == left to right
if (domNode && NS_SUCCEEDED(aTracker->GetFocus(&frame, &anchor))){
//traverse through document and unselect crap here
if (!aContinueSelection){ //single click? setting cursor down
if (anchor && frame && anchor != frame ){
//selected across frames, must "deselect" frames between in correct order
PRInt32 compareResult = compareFrames(anchor,frame);
if ( compareResult < 0 )
selectFrames(anchor,0,frame, 0, eDirNext, nsSelectionStruct::SELTOEND); //unselect all between
else if (compareResult > 0 )
selectFrames(frame,0,anchor, 0, eDirPrevious, nsSelectionStruct::SELTOEND); //unselect all between
// else real bad put in assert here
}
else if (frame && frame != aFrame){
nsSelectionStruct ss={nsSelectionStruct::SELTOEND, 0,0, 0,0, 0,0, eDirNext, PR_FALSE};
frame->SetSelected(&ss);
}
nsSelectionStruct ss={nsSelectionStruct::SELON, 0,0, aOffset, aOffset, 0,0, eDirNext, PR_FALSE};
aFrame->SetSelected(&ss);
aTracker->SetFocus(aFrame,aFrame);
PRUint32 batching = mBatching;//hack to use the collapse code.
PRBool changes = mChangesDuringBatching;
mBatching = 1;
Collapse(domNode, aContentOffset + aOffset);
mBatching = batching;
mChangesDuringBatching = changes;
if (NS_FAILED(result))
return result;
PRInt32 result1 = ComparePoints(anchorNode, anchorOffset
,focusNode, focusOffset);
//compare old cursor to new cursor
PRInt32 result2 = ComparePoints(focusNode, focusOffset,
domNode, aContentOffset );
//compare anchor to new cursor
PRInt32 result3 = ComparePoints(anchorNode, anchorOffset,
domNode , aContentOffset );
if (result1 == 0 && result3 < 0){
//selectFrames(anchor,anchorFrameOffsetBegin, aFrame, aOffset , eDirNext, nsSelectionStruct::SELON);
}
else if (result1 == 0 && result3 > 0){
//selectFrames(aFrame, aOffset , anchor,anchorFrameOffsetBegin, eDirPrevious,nsSelectionStruct::SELON);
}
else if (result1 <= 0 && result2 <= 0) {//a,1,2 or a1,2 or a,12 or a12
//continue selection from 1 to 2
//selectFrames(frame,PR_MIN(focusFrameOffsetEnd,focusFrameOffsetBegin), aFrame, aOffset, eDirNext, nsSelectionStruct::SELON);
}
else{
nsCOMPtr<nsIDOMRange> range;
result = nsComponentManager::CreateInstance(kRangeCID, nsnull,
kIDOMRangeIID,
getter_AddRefs(range));
if (NS_FAILED(result))
return result;
if (result3 <= 0 && result2 >= 0) {//a,2,1 or a2,1 or a,21 or a21
//deselect from 2 to 1
result = range->SetEnd(focusNode, focusOffset);
result |= range->SetStart(domNode, aContentOffset);
if (NS_FAILED(result))
return result;
selectFrames(range, 0);
}
else {
if (aFrame == frame){ //drag to same frame
PRInt32 beginoffset = 0;
PRInt32 begincontentoffset = 0;
PRInt32 endoffset = 0;
PRBool selected = PR_FALSE;
if (NS_SUCCEEDED(aFrame->GetSelected(&selected,&beginoffset,&endoffset, &begincontentoffset))){
nsSelectionStruct ss={nsSelectionStruct::SELON, 0,0, beginoffset, aOffset, 0,0, eDirNext, PR_FALSE};
aFrame->SetSelected(&ss);
//PR_ASSERT(beginoffset == GetAnchorOffset());
aTracker->SetFocus(aFrame,anchor);
if (beginoffset <= aOffset)
direction = FORWARD; //selecting "english" right if true
}
else return NS_ERROR_FAILURE;
}
else if (frame){ //we need to check to see what the order is.
nsCOMPtr<nsIContent>oldContent;
if (NS_SUCCEEDED(frame->GetContent(getter_AddRefs(oldContent))) && oldContent){
nsCOMPtr<nsIDOMNode> oldDomNode(do_QueryInterface(oldContent));
if (oldDomNode && (oldDomNode.get() == FetchFocusNode())) {
nsCOMPtr<nsIContent> anchorContent;
if (NS_SUCCEEDED(anchor->GetContent(getter_AddRefs(anchorContent))) && anchorContent){
nsCOMPtr<nsIDOMNode>anchorDomNode(do_QueryInterface(anchorContent));
if (anchorDomNode && anchorDomNode.get() == FetchAnchorNode()) {
//get offsets
PRBool selected = PR_FALSE;
PRInt32 anchorFrameOffsetBegin = 0;
PRInt32 anchorFrameOffsetEnd = 0;
PRInt32 anchorFrameContentOffset = 0;
if (NS_FAILED(anchor->GetSelected(&selected, &anchorFrameOffsetBegin, &anchorFrameOffsetEnd, &anchorFrameContentOffset)) || !selected)
return NS_ERROR_FAILURE;
selected = PR_FALSE;
PRInt32 focusFrameOffsetBegin = 0;
PRInt32 focusFrameOffsetEnd = 0;
PRInt32 focusFrameContentOffset = 0;
if (NS_FAILED(frame->GetSelected(&selected, &focusFrameOffsetBegin, &focusFrameOffsetEnd, &focusFrameContentOffset)) || !selected)
return NS_ERROR_FAILURE;
//compare anchor to old cursor.
PRInt32 result1 = compareFrames(anchor,frame); //nothing else matters. if they are the same frame.
//compare old cursor to new cursor
PRInt32 result2 = compareFrames(frame,aFrame);
if (result2 == 0)
result2 = ComparePoints(FetchFocusNode(), FetchFocusOffset(),
domNode, aOffset );
//compare anchor to new cursor
PRInt32 result3 = compareFrames(anchor,aFrame);
if (result3 == 0)
result3 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset(),
domNode , aOffset );
if (result1 == 0 && result3 < 0)
{
selectFrames(anchor,anchorFrameOffsetBegin, aFrame, aOffset , eDirNext, nsSelectionStruct::SELON);
}
else if (result1 == 0 && result3 > 0)
{
selectFrames(aFrame, aOffset , anchor,anchorFrameOffsetBegin, eDirPrevious,nsSelectionStruct::SELON);
}
else if (result1 <= 0 && result2 <= 0) {//a,1,2 or a1,2 or a,12 or a12
//continue selection from 1 to 2
selectFrames(frame,PR_MIN(focusFrameOffsetEnd,focusFrameOffsetBegin), aFrame, aOffset, eDirNext, nsSelectionStruct::SELON);
}
else if (result3 <= 0 && result2 >= 0) {//a,2,1 or a2,1 or a,21 or a21
//deselect from 2 to 1
selectFrames(aFrame, aOffset, frame,focusFrameOffsetEnd, eDirNext, 0);
if (anchor != aFrame)
selectFrames(aFrame, 0, aFrame,aOffset, eDirNext, nsSelectionStruct::SELON);
else
selectFrames(anchor, anchorFrameOffsetBegin, aFrame, aOffset, eDirNext, nsSelectionStruct::SELON);
}
else if (result1 >= 0 && result3 <= 0) {//1,a,2 or 1a,2 or 1,a2 or 1a2
//deselect from 1 to a
selectFrames(frame, focusFrameOffsetEnd, anchor, anchorFrameOffsetBegin, eDirPrevious, 0);
//select from a to 2
selectFrames(anchor, anchorFrameOffsetBegin, aFrame, aOffset, eDirNext, nsSelectionStruct::SELON);
}
else if (result2 <= 0 && result3 >= 0) {//1,2,a or 12,a or 1,2a or 12a
//deselect from 1 to 2
selectFrames(frame, focusFrameOffsetEnd, aFrame, aOffset, eDirPrevious, 0);
if (anchor != aFrame)
selectFrames(aFrame, aOffset, aFrame, -1, eDirPrevious, nsSelectionStruct::SELON);
else
selectFrames(aFrame, aOffset, anchor, anchorFrameOffsetBegin, eDirPrevious, nsSelectionStruct::SELON);
}
else if (result3 >= 0 && result1 <= 0) {//2,a,1 or 2a,1 or 2,a1 or 2a1
//deselect from a to 1
selectFrames(anchor, anchorFrameOffsetBegin, frame, focusFrameOffsetEnd, eDirNext, 0);
//select from 2 to a
selectFrames(aFrame, aOffset, anchor, anchorFrameOffsetBegin, eDirPrevious, nsSelectionStruct::SELON);
}
else if (result2 >= 0 && result1 >= 0) {//2,1,a or 21,a or 2,1a or 21a
//continue selection from 2 to 1
selectFrames(aFrame, aOffset, frame,PR_MAX(focusFrameOffsetEnd,focusFrameOffsetBegin), eDirPrevious, nsSelectionStruct::SELON);
}
if (result3 <= 0)
direction = FORWARD;
}
aTracker->SetFocus(aFrame,anchor);
}
}
}
}
else if (result1 >= 0 && result3 <= 0) {//1,a,2 or 1a,2 or 1,a2 or 1a2
result = range->SetStart(focusNode, focusOffset);
result |= range->SetEnd(anchorNode, anchorOffset);
if (NS_FAILED(result))
return result;
//deselect from 1 to a
selectFrames(range, 0);
}
// Now update the range list:
if (aContinueSelection && domNode)
{
Extend(domNode, aOffset + aContentOffset);
else if (result2 <= 0 && result3 >= 0) {//1,2,a or 12,a or 1,2a or 12a
//deselect from 1 to 2
result = range->SetEnd(domNode, aContentOffset);
result |= range->SetStart(focusNode, focusOffset);
if (NS_FAILED(result))
return result;
selectFrames(range, 0);
}
else if (result3 >= 0 && result1 <= 0) {//2,a,1 or 2a,1 or 2,a1 or 2a1
//deselect from a to 1
result = range->SetStart(anchorNode, anchorOffset);
result |= range->SetEnd(focusNode, focusOffset);
if (NS_FAILED(result))
return result;
selectFrames(range, 0);
}
else if (result2 >= 0 && result1 >= 0) {//2,1,a or 21,a or 2,1a or 21a
}
}
// Now update the range list:
if (aContinueSelection && domNode)
{
Extend(domNode, aContentOffset);
}
}
else
return NS_ERROR_FAILURE;
return NotifySelectionListeners();
}
//the start frame is the "root" of the tree. we need to traverse the tree to look for the content we want
NS_IMETHODIMP
nsRangeList::ResetSelection(nsIFocusTracker *aTracker, nsIFrame *aStartFrame)
NS_METHOD
nsRangeList::LookUpSelection(nsIContent *aContent, PRInt32 aContentOffset, PRInt32 aContentLength,
PRInt32 *aStart, PRInt32 *aEnd, PRBool *aDrawSelected, PRUint32 aFlag/*not used*/)
{
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
PRInt32 startOffset;
PRInt32 endOffset;
nsIFrame *result;
nsresult res;
nsCOMPtr<nsIDOMRange> range;
if (!GetNotifyFrames())
return NS_OK;
if (GetBatching()){
SetDirty();
return NS_OK;
}
//we will need to check if any "side" is the anchor and send a direction order to the frames.
if (!mRangeArray)
if (!aContent || !aStart || !aEnd || !aDrawSelected)
return NS_ERROR_NULL_POINTER;
if (aFlag)
return NS_ERROR_NOT_IMPLEMENTED;
STATUS_CHECK_RETURN_MACRO();
//THIS WILL NOT WORK FOR MULTIPLE SELECTIONS YET!!!
nsCOMPtr<nsIDOMNode> passedInNode;
passedInNode = do_QueryInterface(aContent);
if (!passedInNode)
return NS_ERROR_FAILURE;
//reset the focus and anchor points.
nsCOMPtr<nsIContent> anchorContent;
nsCOMPtr<nsIContent> frameContent;
if (FetchAnchorNode() && FetchFocusNode()){
anchorContent = do_QueryInterface(FetchAnchorNode(),&res);
if (NS_SUCCEEDED(res))
frameContent = do_QueryInterface(FetchFocusNode(),&res);
}
else
res = NS_OK;
if (NS_SUCCEEDED(res)){
// hack - joe 3/16/99: first tell all frames to unselect
unselectFrames(aStartFrame);
for (PRUint32 i =0; i<mRangeArray->Count(); i++){
//end content and start content do NOT necessarily mean anchor and focus frame respectively
PRInt32 anchorOffset = -1; //the frames themselves can talk to the presentation manager. we will tell them
PRInt32 frameOffset = -1; // where we would "like" to have the anchor pt. actually we count on it.
nsCOMPtr<nsISupports> isupportsindex = dont_AddRef(mRangeArray->ElementAt(i));
range = do_QueryInterface(isupportsindex);
DEBUG_OUT_RANGE(range);
*aDrawSelected = PR_FALSE;
for (PRUint32 i =0; i<mRangeArray->Count() && i < 1; i++){
nsCOMPtr<nsIDOMRange> range;
nsCOMPtr<nsISupports> isupportsindex = dont_AddRef(mRangeArray->ElementAt(i));
range = do_QueryInterface(isupportsindex);
if (range){
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
PRInt32 startOffset;
PRInt32 endOffset;
range->GetStartParent(getter_AddRefs(startNode));
range->GetStartOffset(&startOffset);
range->GetEndParent(getter_AddRefs(endNode));
range->GetEndOffset(&endOffset);
nsCOMPtr<nsIContent> startContent;
startContent = do_QueryInterface(startNode,&res);
if (startContent){
res = aTracker->GetPrimaryFrameFor(startContent,&result);
//findFrameFromContent(aStartFrame, startContent,PR_TRUE);
}
if (result && NS_SUCCEEDED(res)){
nsCOMPtr<nsIContent> endContent(do_QueryInterface(endNode));
if (endContent == startContent){
if (startContent == frameContent)
frameOffset = FetchFocusOffset();
if ( startContent == anchorContent )
anchorOffset = FetchAnchorOffset();
nsSelectionStruct ss={nsSelectionStruct::SELON|nsSelectionStruct::CHECKANCHOR|nsSelectionStruct::CHECKFOCUS
, startOffset, endOffset, 0,0, anchorOffset,frameOffset, eDirNext, PR_FALSE};
if (anchorOffset> frameOffset)
ss.mDir = eDirPrevious;
result->SetSelectedContentOffsets(&ss,
aTracker, &result);
}
else{
if (startContent == frameContent)
frameOffset = FetchFocusOffset();
if ( startContent == anchorContent )
anchorOffset = FetchAnchorOffset();
nsSelectionStruct ss={nsSelectionStruct::SELON|nsSelectionStruct::SELTOEND|nsSelectionStruct::CHECKANCHOR|nsSelectionStruct::CHECKFOCUS
, startOffset, 0, 0,0, anchorOffset,frameOffset, eDirNext, PR_FALSE};
result->SetSelectedContentOffsets(&ss, aTracker, &result);//select from start to end
//now we keep selecting until we hit the last content, or the end of the page.
anchorOffset = -1;
frameOffset = -1;
while((result = getNextFrame(result)) != nsnull){
nsCOMPtr<nsIContent> content;
result->GetContent(getter_AddRefs(content));
if (content == endContent){
if (endContent == frameContent)
frameOffset = FetchFocusOffset();
if ( endContent == anchorContent )
anchorOffset = FetchAnchorOffset();
nsSelectionStruct ss={nsSelectionStruct::SELON|nsSelectionStruct::CHECKANCHOR|nsSelectionStruct::CHECKFOCUS
, 0, endOffset, 0,0, anchorOffset,frameOffset, eDirNext, PR_FALSE};
result->SetSelectedContentOffsets(&ss, aTracker, &result);//select from beginning to endOffset
break;
}
else{
nsSelectionStruct ss={nsSelectionStruct::SELON|nsSelectionStruct::SELTOEND, 0,0, 0,0, 0,0, eDirNext, PR_FALSE};
result->SetSelected(&ss);
}
}
if (passedInNode == startNode && passedInNode == endNode){
if (startOffset < (aContentOffset + aContentLength) &&
endOffset > aContentOffset){
*aDrawSelected = PR_TRUE;
*aStart = PR_MAX(0,startOffset - aContentOffset);
*aEnd = PR_MIN(aContentLength, endOffset - aContentOffset);
}
}
res = ScrollIntoView(aTracker);
else if (passedInNode == startNode){
if (startOffset < (aContentOffset + aContentLength)){
*aDrawSelected = PR_TRUE;
*aStart = PR_MAX(0,startOffset - aContentOffset);
*aEnd = aContentLength;
}
}
else if (passedInNode == endNode){
if (endOffset > aContentOffset){
*aDrawSelected = PR_TRUE;
*aStart = 0;
*aEnd = PR_MIN(aContentLength, endOffset - aContentOffset);
}
}
else {
*aDrawSelected = PR_TRUE;
*aStart = 0;
*aEnd = aContentLength;
}
}
else
return NS_ERROR_FAILURE;
}
//printf("debug reset selection has been called\n");
return res;
return NS_OK;
}
NS_METHOD
nsRangeList::AddSelectionListener(nsIDOMSelectionListener* inNewListener)
{
@ -1198,18 +1058,15 @@ nsRangeList::EndBatchChanges()
NS_IMETHODIMP
nsRangeList::ScrollIntoView(nsIFocusTracker *aTracker)
nsRangeList::ScrollIntoView()
{
if (!aTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
nsIFrame *anchor;
nsIFrame *frame;
result = aTracker->GetFocus(&frame, &anchor);
result = mTracker->GetFocus(&frame, &anchor);
if (NS_FAILED(result))
return result;
result = aTracker->ScrollFrameIntoView(frame);
result = mTracker->ScrollFrameIntoView(frame);
return result;
}
@ -1333,6 +1190,7 @@ nsRangeList::Collapse(nsIDOMNode* aParentNode, PRInt32 aOffset)
result = AddItem(range);
selectFrames(range,PR_TRUE);
if (NS_FAILED(result))
return result;
@ -1481,6 +1339,10 @@ nsRangeList::Extend(nsIDOMNode* aParentNode, PRInt32 aOffset)
setFocus(aParentNode, aOffset);
if (NS_FAILED(res)) return res;
res = selectFrames(range , PR_TRUE);
if (NS_FAILED(res)) return res;
#ifdef DEBUG_SELECTION
nsCOMPtr<nsIContent>content;
content = do_QueryInterface(aParentNode);
@ -1506,6 +1368,10 @@ nsRangeList::Extend(nsIDOMNode* aParentNode, PRInt32 aOffset)
}
if (NS_SUCCEEDED(res))
setFocus(aParentNode, aOffset);
if (NS_FAILED(res)) return res;
res = selectFrames(range , PR_TRUE);
if (NS_FAILED(res)) return res;
#ifdef DEBUG_SELECTION

View File

@ -44,7 +44,6 @@
#include "nsIEventStateManager.h"
#include "nsIDOMSelection.h"
#include "nsIFrameSelection.h"
#include "nsIFocusTracker.h"
#include "nsHTMLParts.h"
#include "nsLayoutAtoms.h"
@ -143,7 +142,6 @@ nsIFrame::GetLogModuleInfo()
//----------------------------------------------------------------------
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
static NS_DEFINE_IID(kIFocusTracker, NS_IFOCUSTRACKER_IID);
static NS_DEFINE_IID(kIFrameSelection, NS_IFRAMESELECTION_IID);
nsresult
NS_NewEmptyFrame(nsIFrame** aInstancePtrResult)
@ -165,7 +163,6 @@ NS_IMPL_ZEROING_OPERATOR_NEW(nsFrame)
nsFrame::nsFrame()
{
mState = NS_FRAME_FIRST_REFLOW | NS_FRAME_SYNC_FRAME_AND_VIEW;
mSelected = PR_FALSE;
}
nsFrame::~nsFrame()
@ -359,7 +356,8 @@ nsFrame::RemoveFrame(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsFrame::DeleteFrame(nsIPresContext& aPresContext)
{
if (mState & NS_FRAME_EXTERNAL_REFERENCE || mSelected) {
PRBool isGeneratedContent = (mState & NS_FRAME_GENERATED_CONTENT) == NS_FRAME_GENERATED_CONTENT;
if (mState & NS_FRAME_EXTERNAL_REFERENCE || mState & NS_FRAME_SELECTED_CONTENT) {
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext.GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell) {
@ -696,7 +694,12 @@ nsFrame::Paint(nsIPresContext& aPresContext,
PRInt32 n;
content->ChildCount(n);
if ((n == 0) && mSelected) {
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if ((n == 0) && isSelected) {
nsRect rect;
GetRect(rect);
rect.width--;
@ -784,17 +787,16 @@ nsFrame::HandlePress(nsIPresContext& aPresContext,
if (NS_SUCCEEDED(GetPosition(aPresContext, acx, aEvent, this, contentOffset, startPos))){
nsIDOMSelection *selection = nsnull;
if (NS_SUCCEEDED(shell->GetSelection(&selection))){
nsIFocusTracker *tracker;
if (NS_SUCCEEDED(shell->QueryInterface(kIFocusTracker,(void **)&tracker))){
nsIFrameSelection *frameselection = nsnull;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection,
(void **)&frameselection))) {
nsIFrameSelection *frameselection = nsnull;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection, (void **)&frameselection))) {
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED( rv )){
frameselection->EnableFrameNotification(PR_FALSE);
frameselection->TakeFocus(tracker, this, startPos, contentOffset, inputEvent->isShift);
frameselection->TakeFocus(content, startPos + contentOffset, inputEvent->isShift);
frameselection->EnableFrameNotification(PR_TRUE);//prevent cyclic call to reset selection.
NS_RELEASE(frameselection);
}
NS_RELEASE(tracker);
NS_RELEASE(frameselection);
}
NS_RELEASE(selection);
}
@ -827,16 +829,16 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext& aPresContext,
if (NS_SUCCEEDED(GetPosition(aPresContext, acx, aEvent, this, contentOffset, startPos))){
nsIDOMSelection *selection = nsnull;
if (NS_SUCCEEDED(shell->GetSelection(&selection))){
nsIFocusTracker *tracker;
if (NS_SUCCEEDED(shell->QueryInterface(kIFocusTracker,(void **)&tracker))) {
nsIFrameSelection* frameselection;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection, (void **)&frameselection))) {
nsIFrameSelection* frameselection;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection, (void **)&frameselection))) {
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED( rv )){
frameselection->EnableFrameNotification(PR_FALSE);
frameselection->TakeFocus(tracker, this, startPos, contentOffset, PR_TRUE); //TRUE IS THE DIFFERENCE
frameselection->TakeFocus(content, startPos + contentOffset, PR_TRUE); //TRUE IS THE DIFFERENCE
frameselection->EnableFrameNotification(PR_TRUE);//prevent cyclic call to reset selection.
NS_RELEASE(frameselection);
}
NS_RELEASE(tracker);
NS_RELEASE(frameselection);
}
NS_RELEASE(selection);
}
@ -1561,68 +1563,28 @@ nsFrame::VerifyTree() const
/*this method may.. invalidate if the state was changed or if aForceRedraw is PR_TRUE
it will not update immediately.*/
NS_IMETHODIMP
nsFrame::SetSelected(nsSelectionStruct *aSelStruct)
nsFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread)
{
if (!aSelStruct)
return NS_ERROR_NULL_POINTER;
if (mSelected != (PRBool)(aSelStruct->mType & nsSelectionStruct::SELON ) || aSelStruct->mForceRedraw)
{
mSelected = aSelStruct->mType & nsSelectionStruct::SELON ;
/* nsRect rect;
GetRect(rect);
nsIFrame *frame = this;
nsIFrame *firstframe = nsnull;
while (NS_SUCCEEDED(frame->GetPrevInFlow(&frame)) && frame){
firstframe = frame;
}
if (firstframe){
nsRect rect2;
firstframe->GetRect(rect2);
rect.y-= rect.y-rect2.y;
}
*/
ForceDrawFrame(this);//invalidate does not work in all cases.
//Invalidate(rect,PR_FALSE); //false is for not immediate
}
nsFrameState frameState;
GetFrameState(&frameState);
if ( aSelected )
frameState |= NS_FRAME_SELECTED_CONTENT;
else
frameState &= ~NS_FRAME_SELECTED_CONTENT;
SetFrameState(frameState);
nsRect frameRect;
GetRect(frameRect);
nsRect rect(0, 0, frameRect.width, frameRect.height);
Invalidate(rect, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsFrame::SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected)
{
if (!aActualSelected || !aSS)
return NS_ERROR_NULL_POINTER;
nsIFrame *child = nsnull;
nsresult result = FirstChild(nsnull, &child);
if (NS_FAILED(result)){
*aActualSelected = this;
if (aSS->mAnchorOffset > 0)
aTracker->SetFocus(nsnull,this);
if (aSS->mFocusOffset > 0)
aTracker->SetFocus(this,nsnull);
return SetSelected(aSS);
}
*aActualSelected = nsnull;
//wont actually bother with selection here on "this" frame
while (child && NS_SUCCEEDED(result)){
result |= child->SetSelectedContentOffsets(aSS, aTracker, aActualSelected);
if (NS_SUCCEEDED(result) && aActualSelected)
return result; //done.
result |= child->GetNextSibling(&child);
}
return result;
}
NS_IMETHODIMP
nsFrame::GetSelected(PRBool *aSelected, PRInt32 *aBeginOffset, PRInt32 *aEndOffset, PRInt32 *aBeginContentOffset)
nsFrame::GetSelected(PRBool *aSelected) const
{
if (!aSelected )
return NS_ERROR_NULL_POINTER;
*aSelected = mSelected;
*aSelected = (PRBool)(mState & NS_FRAME_SELECTED_CONTENT);
return NS_OK;
}
@ -1647,9 +1609,9 @@ nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFram
NS_IMETHODIMP
nsFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset,
PRBool aEatingWS)
PRBool aEatingWS) const
{
//this will use the nsFrameTraversal as the default peek method.
/* //this will use the nsFrameTraversal as the default peek method.
//this should change to use geometry and also look to ALL the child lists
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
nsresult result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
@ -1673,6 +1635,8 @@ nsFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 a
nsIFrame *newFrame = (nsIFrame *)isupports;
return newFrame->PeekOffset(aAmount, aDirection, aStartOffset, aResultFrame,
aFrameOffset, aContentOffset, aEatingWS);
*/
return NS_OK;
}
//-----------------------------------------------------------------------------------

View File

@ -208,14 +208,11 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
NS_IMETHOD DumpRegressionData(FILE* out, PRInt32 aIndent);
NS_IMETHOD VerifyTree() const;
NS_IMETHOD SetSelected(nsSelectionStruct *);
NS_IMETHOD SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected);
NS_IMETHOD GetSelected(PRBool *aSelected, PRInt32 *aBeginOffset, PRInt32 *aEndOffset, PRInt32 *aBeginContentOffset);
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread);
NS_IMETHOD GetSelected(PRBool *aSelected) const;
NS_IMETHOD PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset,
PRBool aEatingWS);
PRBool aEatingWS)const;
NS_IMETHOD GetOffsets(PRInt32 &aStart, PRInt32 &aEnd) const;
@ -352,7 +349,6 @@ protected:
nsIFrame* mParent;
nsIFrame* mNextSibling; // singly linked list of frames
nsFrameState mState;
PRBool mSelected;
///////////////////////////////////
// Important Selection Variables

View File

@ -44,7 +44,7 @@ class nsStyleChangeList;
struct nsPoint;
struct nsRect;
struct nsStyleStruct;
struct nsSelectionStruct;
class nsIDOMRange;
struct PRLogModuleInfo;
@ -127,6 +127,9 @@ typedef PRUint32 nsFrameState;
// e.g., it is absolutely positioned or floated
#define NS_FRAME_OUT_OF_FLOW 0x00000100
// If this bit is set, then the frame reflects content that may be selected
#define NS_FRAME_SELECTED_CONTENT 0x00000200
// The low 16 bits of the frame state word are reserved by this API.
#define NS_FRAME_RESERVED 0x0000FFFF
@ -579,21 +582,13 @@ public:
* Called to set the selection of the frame based on frame offsets. you can FORCE the frame
* to redraw event if aSelected == the frame selection with the last parameter.
* data in struct may be changed when passed in.
* @param nsSelectionStruct will hold the data pertinant to the Selection, Selected or not ect.
* @param aRange is the range that will dictate if the frames need to be redrawn null means the whole content needs to be redrawn
* @param aSelected is it selected
* @param aSpread should is spread selection to flow elements around it?
*/
NS_IMETHOD SetSelected(nsSelectionStruct *) = 0;
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread) = 0;
/**
* Called to start a selection with this frame content.
* @param aSS is the struct that holds the data instead of passing in so many parameters
* @param aFocusTracker will allow the frame to set the focus to what it needs.
* @param return value of which frame (maybe not this one, maybe one of its siblings)
*/
NS_IMETHOD SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected)=0;
NS_IMETHOD GetSelected(PRBool *aSelected, PRInt32 *aBeginOffset, PRInt32 *aEndOffset, PRInt32 *aBeginContentOffset) = 0;
NS_IMETHOD GetSelected(PRBool *aSelected) const = 0;
/**
* called to find the previous/next character, word, or line returns the actual
@ -609,7 +604,7 @@ public:
* @param aEatingWS boolean to tell us the state of our search for Next/Prev
*/
NS_IMETHOD PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset, PRBool aEatingWS) = 0;
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset, PRBool aEatingWS) const = 0;
/**
* See if tree verification is enabled. To enable tree verification add

View File

@ -45,6 +45,9 @@ nsSplittableFrame::Init(nsIPresContext& aPresContext,
if (state & NS_FRAME_REPLACED_ELEMENT) {
mState |= NS_FRAME_REPLACED_ELEMENT;
}
if (state & NS_FRAME_SELECTED_CONTENT) {
mState |= NS_FRAME_SELECTED_CONTENT;
}
}
return rv;

View File

@ -52,6 +52,8 @@
#include "nsTextTransformer.h"
#include "nsLayoutAtoms.h"
#include "nsIFrameSelection.h"
#include "nsIDOMSelection.h"
#include "nsIDOMRange.h"
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
@ -229,14 +231,19 @@ public:
PRUint32& aActualContentOffset,
PRInt32& aOffset);
NS_IMETHOD SetSelected(nsSelectionStruct *aSS);
NS_IMETHOD SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected);
NS_IMETHOD GetSelected(PRBool *aSelected, PRInt32 *aBeginOffset, PRInt32 *aEndOffset, PRInt32 *aBeginContentOffset);
NS_IMETHOD GetPositionSlowly(nsIPresContext& aCX,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aActualContentOffset,
PRInt32& aOffset);
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread);
NS_IMETHOD PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset,
PRBool aEatingWS);
PRBool aEatingWS)const;
NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end)const;
@ -337,13 +344,6 @@ public:
nsIDocument* GetDocument(nsIPresContext* aPresContext);
nsresult GetPositionSlowly(nsIPresContext* aCX,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32* aActualContentOffset,
PRInt32* aOffset);
PRIntn PrepareUnicodeText(nsTextTransformer& aTransformer,
PRInt32* aIndicies,
PRUnichar* aBuffer,
@ -415,8 +415,6 @@ protected:
PRInt32 mColumn;
nscoord mComputedWidth;
PRUint32 mSelectionOffset;
PRUint32 mSelectionEnd;
};
// Flag information used by rendering code. This information is
@ -458,8 +456,6 @@ nsTextFrame::nsTextFrame()
// Create text timer the first time out
gTextBlinker = new nsBlinkTimer();
}
mSelectionOffset = PRUint32(-1);
mSelectionEnd = PRUint32(-1);
NS_ADDREF(gTextBlinker);
}
@ -835,10 +831,13 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
PrepareUnicodeText(tx, (displaySelection ? ip : nsnull),
paintBuf, &textLength);
PRUnichar* text = paintBuf;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength) {
if (!displaySelection || !mSelected ||
(mSelectionOffset > PRUint32(mContentLength))) {
//if selection is > content length then selection has "slid off"
if (!displaySelection || !isSelected ) {
// When there is no selection showing, use the fastest and
// simplest rendering approach
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
@ -851,89 +850,98 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
//must set up last one for selection beyond edge if in boundary
ip[mContentLength]++;
}
PRInt32 textWidth;
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
PRBool drawSelected = PR_FALSE;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
rv = shell->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(rv) && selection){
frameSelection = do_QueryInterface(selection);
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected,0);// last param notused
}
}
}
nscoord textWidth;
if (mSelectionOffset < 0)
mSelectionOffset = 0;
if (mSelectionEnd < 0)
mSelectionEnd = mContentLength;
if (mSelectionEnd > PRUint32(mContentLength))
mSelectionEnd = PRUint32(mContentLength);
if (mSelectionOffset > PRUint32(mContentLength))
mSelectionOffset = PRUint32(mContentLength);
PRInt32 selectionEnd = mSelectionEnd;
PRInt32 selectionOffset = mSelectionOffset;
if (mSelectionEnd < mSelectionOffset)
{
selectionEnd = mSelectionOffset;
selectionOffset = mSelectionEnd;
}
//where are the selection points "really"
selectionOffset = ip[selectionOffset] - mContentOffset;
selectionEnd = ip[selectionEnd] - mContentOffset;
if (selectionOffset == selectionEnd) {
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
//shell->RefreshCaret();
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionOffset),//si.mStartOffset),
textWidth);
aRenderingContext.DrawString(text, PRUint32(selectionOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
if (frameSelection ){
//where are the selection points "really"
if (drawSelected){
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
}
PRInt32 secondLen = selectionEnd - selectionOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionOffset,
PRUint32(secondLen), textWidth);
if (!drawSelected || (selectionStartOffset == selectionEndOffset)) {
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
if (textLength != selectionEnd) {
PRInt32 thirdLen = textLength - selectionEnd;
else {
nscoord x = dx;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEnd, PRUint32(thirdLen),
if (selectionStartOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset),//si.mStartOffset),
textWidth);
aRenderingContext.DrawString(text + selectionEnd,
PRUint32(thirdLen), x, dy);
aRenderingContext.DrawString(text, PRUint32(selectionStartOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionStartOffset,
PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionStartOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEndOffset, PRUint32(thirdLen),
textWidth);
aRenderingContext.DrawString(text + selectionEndOffset,
PRUint32(thirdLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
}
}
}
}
}
}
// Cleanup
if (paintBuf != paintBufMem) {
delete [] paintBuf;
@ -945,24 +953,24 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
//measure Spaced Textvoid
nsresult
nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
nsTextFrame::GetPositionSlowly(nsIPresContext& aPresContext,
nsIRenderingContext* aRendContext,
nsGUIEvent* aEvent,
nsIFrame* aNewFrame,
PRUint32* aAcutalContentOffset,
PRInt32* aOffset)
PRUint32& aAcutalContentOffset,
PRInt32& aOffset)
{
if (!aRendContext || !aEvent || !aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
TextStyle ts(aPresContext, *aRendContext, mStyleContext);
TextStyle ts(&aPresContext, *aRendContext, mStyleContext);
if (!ts.mSmallCaps && !ts.mWordSpacing && !ts.mLetterSpacing) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIDocument> doc(getter_AddRefs(GetDocument(aPresContext)));
nsCOMPtr<nsIDocument> doc(getter_AddRefs(GetDocument(&aPresContext)));
// Make enough space to transform
PRUnichar paintBufMem[TEXT_BUF_SIZE];
@ -1026,12 +1034,12 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
}
if ((aEvent->point.x - origin.x) >= widthsofar && (aEvent->point.x - origin.x) <= (widthsofar + glyphWidth)){
if ( ((aEvent->point.x - origin.x) - widthsofar) <= (glyphWidth /2)){
*aOffset = index;
aOffset = index;
found = PR_TRUE;
break;
}
else{
*aOffset = index+1;
aOffset = index+1;
found = PR_TRUE;
break;
}
@ -1044,13 +1052,13 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
}
paintBuf = startBuf;
if (!found){
*aOffset = textLength;
aOffset = textLength;
}
*aAcutalContentOffset = mContentOffset;//offset;//((nsTextFrame *)aNewFrame)->mContentOffset;
aAcutalContentOffset = mContentOffset;//offset;//((nsTextFrame *)aNewFrame)->mContentOffset;
PRInt32 i;
for (i = 0;i <= mContentLength; i ++){
if (ip[i] == *aOffset + mContentOffset){ //reverse mapping
*aOffset = i;
if (ip[i] == aOffset + mContentOffset){ //reverse mapping
aOffset = i;
break;
}
}
@ -1319,9 +1327,12 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
}
PRUnichar* text = paintBuf;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength) {
if (!displaySelection || !mSelected ||
(mSelectionOffset > PRUint32(mContentLength))) {
if (!displaySelection || !isSelected) {
// When there is no selection showing, use the fastest and
// simplest rendering approach
RenderString(aRenderingContext, aStyleContext, aTextStyle,
@ -1329,89 +1340,99 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
}
else {
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength)//must set up last one for selection beyond edge if in boundary
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
ip[mContentLength]++;
nscoord textWidth;
if (mSelectionOffset < 0)
mSelectionOffset = 0;
if (mSelectionEnd < 0)
mSelectionEnd = PRUint32(mContentLength);
if (mSelectionEnd > PRUint32(mContentLength))
mSelectionEnd = PRUint32(mContentLength);
if (mSelectionOffset > PRUint32(mContentLength))
mSelectionOffset = PRUint32(mContentLength);
PRInt32 selectionEnd = mSelectionEnd;
PRInt32 selectionOffset = mSelectionOffset;
if (mSelectionEnd < mSelectionOffset)
{
selectionEnd = mSelectionOffset;
selectionOffset = mSelectionEnd;
}
//where are the selection points "really"
selectionOffset = ip[selectionOffset] - mContentOffset;
selectionEnd = ip[selectionEnd] - mContentOffset;
if (selectionOffset == selectionEnd){
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, textLength, dx, dy, width);
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
PRInt32 textWidth;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
PRBool drawSelected = PR_FALSE;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
rv = shell->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(rv) && selection){
frameSelection = do_QueryInterface(selection);
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected, 0);// last param notused
}
}
}
//shell->RefreshCaret();
if (frameSelection){
//where are the selection points "really"
if (drawSelected) {
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
}
if (!drawSelected || (selectionStartOffset == selectionEndOffset)){
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, textLength, dx, dy, width);
#ifdef SHOW_SELECTION_CURSOR
GetWidth(aRenderingContext, aTextStyle,
text, PRUint32(selectionOffset), &textWidth);
text, PRUint32(selectionStartOffset), &textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionOffset) {
// Render first (unselected) section
GetWidth(aRenderingContext, aTextStyle,
text, PRUint32(selectionOffset),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, selectionOffset,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEnd - selectionOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
GetWidth(aRenderingContext, aTextStyle,
text + selectionOffset,
PRUint32(secondLen), &textWidth);
else {
nscoord x = dx;
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionOffset, secondLen,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEnd) {
PRInt32 thirdLen = textLength - selectionEnd;
// Render third (unselected) section
if (thirdLen > 0) //Text length is not negative or zero
{
if (selectionStartOffset) {
// Render first (unselected) section
GetWidth(aRenderingContext, aTextStyle,
text + selectionOffset, PRUint32(thirdLen),
text, PRUint32(selectionStartOffset),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionEnd,
thirdLen, x, dy, textWidth);
text, selectionStartOffset,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
GetWidth(aRenderingContext, aTextStyle,
text + selectionStartOffset,
PRUint32(secondLen), &textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionStartOffset, secondLen,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
// Render third (unselected) section
if (thirdLen > 0) //Text length is not negative or zero
{
GetWidth(aRenderingContext, aTextStyle,
text + selectionStartOffset, PRUint32(thirdLen),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionEndOffset,
thirdLen, x, dy, textWidth);
}
}
}
}
}
}
// Cleanup
if (paintBuf != paintBufMem) {
delete [] paintBuf;
@ -1466,9 +1487,13 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
char* text = paintBuf;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength) {
if (!displaySelection || !mSelected ||
(mSelectionOffset > PRUint32(mContentLength))) {
if (!displaySelection || !isSelected) {
//if selection is > content length then selection has "slid off"
// When there is no selection showing, use the fastest and
// simplest rendering approach
@ -1478,85 +1503,97 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
else {
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength)//must set up last one for selection beyond edge if in boundary
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
ip[mContentLength]++;
nscoord textWidth;
if (mSelectionOffset < 0)
mSelectionOffset = 0;
if (mSelectionEnd < 0)
mSelectionEnd = mContentLength;
if (mSelectionEnd > PRUint32(mContentLength))
mSelectionEnd = PRUint32(mContentLength);
if (mSelectionOffset > PRUint32(mContentLength))
mSelectionOffset = PRUint32(mContentLength);
PRInt32 selectionEnd = mSelectionEnd;
PRInt32 selectionOffset = mSelectionOffset;
if (mSelectionEnd < mSelectionOffset)
{
selectionEnd = mSelectionOffset;
selectionOffset = mSelectionEnd;
}
//where are the selection points "really"
selectionOffset = ip[selectionOffset] - mContentOffset;
selectionEnd = ip[selectionEnd] - mContentOffset;
if (selectionOffset == selectionEnd){
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
//shell->RefreshCaret();
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
PRInt32 textWidth;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
PRBool drawSelected = PR_FALSE;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
rv = shell->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(rv) && selection){
frameSelection = do_QueryInterface(selection);
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected, 0);// last param notused
}
}
}
else
{
nscoord x = dx;
if (selectionOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionOffset),//si.mStartOffset),
textWidth);
aRenderingContext.DrawString(text, PRUint32(selectionOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
if (frameSelection){
//where are the selection points "really"
if (drawSelected) {
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
}
PRInt32 secondLen = selectionEnd - selectionOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionOffset,
PRUint32(secondLen), textWidth);
if (!drawSelected || (selectionStartOffset == selectionEndOffset)){
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
//shell->RefreshCaret();
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
if (textLength != selectionEnd) {
PRInt32 thirdLen = textLength - selectionEnd;
else {
nscoord x = dx;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEnd, PRUint32(thirdLen),
if (selectionStartOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset),//si.mStartOffset),
textWidth);
aRenderingContext.DrawString(text + selectionEnd,
PRUint32(thirdLen), x, dy);
aRenderingContext.DrawString(text, PRUint32(selectionStartOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionStartOffset,
PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionStartOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEndOffset, PRUint32(thirdLen),
textWidth);
aRenderingContext.DrawString(text + selectionEndOffset,
PRUint32(thirdLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
}
}
}
}
@ -1611,7 +1648,7 @@ BinarySearchForPosition(nsIRenderingContext* acx,
}
PRInt32 inx = aStartInx + (range / 2);
PRInt32 textWidth;
PRInt32 textWidth = 0;
acx->GetWidth(aText, inx, textWidth);
PRInt32 fullWidth = aBaseWidth + textWidth;
@ -1648,8 +1685,8 @@ nsTextFrame::GetPosition(nsIPresContext& aPresContext,
{
TextStyle ts(&aPresContext, *aRendContext, mStyleContext);
if (ts.mSmallCaps || ts.mWordSpacing || ts.mLetterSpacing) {
return GetPositionSlowly(&aPresContext, aRendContext, aEvent, aNewFrame,
&aActualContentOffset, &aOffset);
return GetPositionSlowly(aPresContext, aRendContext, aEvent, aNewFrame,
aActualContentOffset, aOffset);
}
PRUnichar wordBufMem[WORD_BUF_SIZE];
@ -1690,7 +1727,7 @@ nsTextFrame::GetPosition(nsIPresContext& aPresContext,
}
PRInt32 index;
PRInt32 textWidth;
PRInt32 textWidth = 0;
PRUnichar* text = paintBuf;
nsPoint origin;
nsIView * view;
@ -1742,129 +1779,83 @@ nsTextFrame::GetPosition(nsIPresContext& aPresContext,
return NS_OK;
}
NS_IMETHODIMP
nsTextFrame::SetSelected(nsSelectionStruct *aSelStruct)
{
if (!aSelStruct)
return NS_ERROR_NULL_POINTER;
if (aSelStruct->mType & nsSelectionStruct::SELON){
aSelStruct->mEndFrame = PR_MIN(aSelStruct->mEndFrame, (PRUint32) mContentLength);
aSelStruct->mStartFrame= PR_MIN(aSelStruct->mStartFrame, (PRUint32) mContentLength);
if (aSelStruct->mType & nsSelectionStruct::SELTOEND)
aSelStruct->mEndFrame = mContentLength;
if (aSelStruct->mType & nsSelectionStruct::SELTOBEGIN)
aSelStruct->mStartFrame = 0;
PRUint32 trueBegin(aSelStruct->mStartFrame);
PRUint32 trueEnd(aSelStruct->mEndFrame);
if (aSelStruct->mDir == eDirPrevious){//change the settings around,
//the frame doesnt track direction it only tracks begin and end.
trueBegin = aSelStruct->mEndFrame;
trueEnd = aSelStruct->mStartFrame;
}
if (mSelectionOffset != trueBegin || mSelectionEnd != trueEnd)
{
//XXX PRBool wasCollapsed = (mSelectionOffset == mSelectionEnd);
mSelectionOffset = trueBegin;
mSelectionEnd = trueEnd;
// XXX when we no longer rely on the blue triangle to show the selection
// position (using the caret instead), then we can uncomment this to reduce
// redrawing. sfraser
aSelStruct->mForceRedraw = PR_TRUE; //!wasCollapsed || (trueBegin != trueEnd);
}
}
return nsFrame::SetSelected(aSelStruct);//this will do the actual
//turning on of the mSelected flag in the nsframe header.
}
// [HACK] Foward Declarations
void ForceDrawFrame(nsFrame * aFrame);
NS_IMETHODIMP
nsTextFrame::SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected)
nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread)
{
if (!aActualSelected || !aSS)
if (!aRange)
return NS_ERROR_NULL_POINTER;
nsresult result;
if (aSpread){
nsIFrame *frame = GetPrevInFlow();
while(frame){
frame->SetSelected(aRange,aSelected,PR_FALSE);
result = frame->GetPrevInFlow(&frame);
if (NS_FAILED(result))
break;
}
frame = GetNextInFlow();
while(frame){
frame->SetSelected(aRange,aSelected,PR_FALSE);
result = frame->GetNextInFlow(&frame);
if (NS_FAILED(result))
break;
}
}
//lets see if the range contains us, if so we must redraw!
nsCOMPtr<nsIDOMNode> endNode;
PRInt32 endOffset;
nsCOMPtr<nsIDOMNode> startNode;
PRInt32 startOffset;
aRange->GetEndParent(getter_AddRefs(endNode));
aRange->GetEndOffset(&endOffset);
aRange->GetStartParent(getter_AddRefs(startNode));
aRange->GetStartOffset(&startOffset);
nsCOMPtr<nsIContent> content;
result = GetContent(getter_AddRefs(content));
nsCOMPtr<nsIDOMNode> thisNode;
thisNode = do_QueryInterface(content);
PRInt32 beginOffset(aSS->mStartContent - mContentOffset);
if (beginOffset > mContentLength){
//this is not the droid we are looking for. keep looking
nsSelectionStruct ss = {0};//turn it ALL off
ss.mForceRedraw = aSS->mForceRedraw;
SetSelected(&ss);
nsIFrame *nextInFlow =GetNextInFlow();
if (nextInFlow)
return nextInFlow->SetSelectedContentOffsets(aSS, aTracker, aActualSelected);
else
return NS_ERROR_FAILURE;
}
if (aSS->mType & nsSelectionStruct::CHECKANCHOR && aSS->mAnchorOffset == aSS->mStartContent ){
aTracker->SetFocus(nsnull, this);
aSS->mType = aSS->mType-nsSelectionStruct::CHECKANCHOR;
}
if (aSS->mType & nsSelectionStruct::CHECKFOCUS && aSS->mFocusOffset == aSS->mStartContent ){
aTracker->SetFocus(this, nsnull);
aSS->mType = aSS->mType-nsSelectionStruct::CHECKFOCUS;
}
*aActualSelected = this;
nsIFrame *nextInFlow = GetNextInFlow();
if (nextInFlow){
if (aSS->mType & nsSelectionStruct::SELTOEND || aSS->mEndContent > PRUint32(mContentLength + mContentOffset)){
nextInFlow->SetSelectedContentOffsets(aSS, aTracker ,aActualSelected);
}
else if (aSS->mType & nsSelectionStruct::SELON) { //we must shut off all folowing selected frames if we are selecting frames
if (aSS->mType & nsSelectionStruct::CHECKANCHOR && aSS->mAnchorOffset == aSS->mEndContent ){
aTracker->SetFocus(nsnull, this);
aSS->mType = aSS->mType - nsSelectionStruct::CHECKANCHOR;
PRBool found = PR_FALSE;
if (thisNode == startNode){
if ((mContentOffset + mContentLength) >= startOffset){
found = PR_TRUE;
if (thisNode == endNode){ //special case
/*#ifndef SHOW_SELECTION_CURSOR
if (aSelected && (endOffset == startOffset)) //no need to redraw since drawing takes place with cursor
found = PR_FALSE;
#endif
*/
if (mContentOffset > endOffset)
found = PR_FALSE;
}
if (aSS->mType & nsSelectionStruct::CHECKFOCUS && aSS->mFocusOffset == aSS->mEndContent ){
aTracker->SetFocus(this, nsnull);
aSS->mType = aSS->mType - nsSelectionStruct::CHECKFOCUS;
}
nsSelectionStruct ss={0, 0,0, 0,0, 0,0, eDirNext, aSS->mForceRedraw};
do {
nextInFlow->SetSelected(&ss);
}
while (NS_SUCCEEDED(nextInFlow->GetNextInFlow(&nextInFlow)) && nextInFlow);//this is ok because frames arent reference counted this is not a leak!
}
}
else {
if (aSS->mType & nsSelectionStruct::CHECKANCHOR && aSS->mAnchorOffset == aSS->mEndContent ){
aTracker->SetFocus(nsnull, this);
aSS->mType = aSS->mType - nsSelectionStruct::CHECKANCHOR;
}
if (aSS->mType & nsSelectionStruct::CHECKFOCUS && aSS->mFocusOffset == aSS->mEndContent ){
aTracker->SetFocus(this, nsnull);
aSS->mType = aSS->mType - nsSelectionStruct::CHECKFOCUS;
}
}
if (PRUint32(mContentOffset) > aSS->mStartContent){
aSS->mStartFrame = 0;
}
else
aSS->mStartFrame = aSS->mStartContent - mContentOffset;
aSS->mEndFrame = aSS->mEndContent - mContentOffset;
return SetSelected(aSS);
}
NS_IMETHODIMP
nsTextFrame::GetSelected(PRBool *aSelected,
PRInt32 *aBeginOffset,
PRInt32 *aEndOffset,
PRInt32 *aBeginContentOffset)
{
if (!aSelected || !aBeginOffset || !aEndOffset || !aBeginContentOffset)
return NS_ERROR_NULL_POINTER;
*aBeginOffset = mSelectionOffset;
*aEndOffset = mSelectionEnd;
*aSelected = mSelected;
*aBeginContentOffset = mContentOffset;
//should we check for whitespace here? dont think so.
if (thisNode == endNode){
if (mContentOffset < endOffset)
found = PR_TRUE;
}
if (found){ //if range contains this frame...
/* nsRect frameRect;
GetRect(frameRect);
nsRect rect(0, 0, frameRect.width, frameRect.height);
Invalidate(rect, PR_FALSE);
*/ ForceDrawFrame(this);
}
nsFrameState frameState;
GetFrameState(&frameState);
if ( aSelected )
frameState |= NS_FRAME_SELECTED_CONTENT;
else
frameState &= ~NS_FRAME_SELECTED_CONTENT;
SetFrameState(frameState);
return NS_OK;
}
NS_IMETHODIMP
nsTextFrame::GetPointFromOffset(nsIPresContext* aPresContext,
nsIRenderingContext* inRendContext,
@ -1968,8 +1959,9 @@ nsTextFrame::PeekOffset(nsSelectionAmount aAmount,
nsIFrame **aResultFrame,
PRInt32 *aFrameOffset,
PRInt32 *aContentOffset,
PRBool aEatingWS)
PRBool aEatingWS) const
{
/*
//default, no matter what grab next/ previous sibling.
if (!aResultFrame || !aFrameOffset || !aContentOffset)
return NS_ERROR_NULL_POINTER;
@ -2163,6 +2155,8 @@ nsTextFrame::PeekOffset(nsSelectionAmount aAmount,
result = NS_OK;
}
return result;
*/
return NS_OK;
}
NS_IMETHODIMP

View File

@ -44,7 +44,6 @@
#include "nsIEventStateManager.h"
#include "nsIDOMSelection.h"
#include "nsIFrameSelection.h"
#include "nsIFocusTracker.h"
#include "nsHTMLParts.h"
#include "nsLayoutAtoms.h"
@ -143,7 +142,6 @@ nsIFrame::GetLogModuleInfo()
//----------------------------------------------------------------------
static NS_DEFINE_IID(kIFrameIID, NS_IFRAME_IID);
static NS_DEFINE_IID(kIFocusTracker, NS_IFOCUSTRACKER_IID);
static NS_DEFINE_IID(kIFrameSelection, NS_IFRAMESELECTION_IID);
nsresult
NS_NewEmptyFrame(nsIFrame** aInstancePtrResult)
@ -165,7 +163,6 @@ NS_IMPL_ZEROING_OPERATOR_NEW(nsFrame)
nsFrame::nsFrame()
{
mState = NS_FRAME_FIRST_REFLOW | NS_FRAME_SYNC_FRAME_AND_VIEW;
mSelected = PR_FALSE;
}
nsFrame::~nsFrame()
@ -359,7 +356,8 @@ nsFrame::RemoveFrame(nsIPresContext& aPresContext,
NS_IMETHODIMP
nsFrame::DeleteFrame(nsIPresContext& aPresContext)
{
if (mState & NS_FRAME_EXTERNAL_REFERENCE || mSelected) {
PRBool isGeneratedContent = (mState & NS_FRAME_GENERATED_CONTENT) == NS_FRAME_GENERATED_CONTENT;
if (mState & NS_FRAME_EXTERNAL_REFERENCE || mState & NS_FRAME_SELECTED_CONTENT) {
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext.GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell) {
@ -696,7 +694,12 @@ nsFrame::Paint(nsIPresContext& aPresContext,
PRInt32 n;
content->ChildCount(n);
if ((n == 0) && mSelected) {
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if ((n == 0) && isSelected) {
nsRect rect;
GetRect(rect);
rect.width--;
@ -784,17 +787,16 @@ nsFrame::HandlePress(nsIPresContext& aPresContext,
if (NS_SUCCEEDED(GetPosition(aPresContext, acx, aEvent, this, contentOffset, startPos))){
nsIDOMSelection *selection = nsnull;
if (NS_SUCCEEDED(shell->GetSelection(&selection))){
nsIFocusTracker *tracker;
if (NS_SUCCEEDED(shell->QueryInterface(kIFocusTracker,(void **)&tracker))){
nsIFrameSelection *frameselection = nsnull;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection,
(void **)&frameselection))) {
nsIFrameSelection *frameselection = nsnull;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection, (void **)&frameselection))) {
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED( rv )){
frameselection->EnableFrameNotification(PR_FALSE);
frameselection->TakeFocus(tracker, this, startPos, contentOffset, inputEvent->isShift);
frameselection->TakeFocus(content, startPos + contentOffset, inputEvent->isShift);
frameselection->EnableFrameNotification(PR_TRUE);//prevent cyclic call to reset selection.
NS_RELEASE(frameselection);
}
NS_RELEASE(tracker);
NS_RELEASE(frameselection);
}
NS_RELEASE(selection);
}
@ -827,16 +829,16 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext& aPresContext,
if (NS_SUCCEEDED(GetPosition(aPresContext, acx, aEvent, this, contentOffset, startPos))){
nsIDOMSelection *selection = nsnull;
if (NS_SUCCEEDED(shell->GetSelection(&selection))){
nsIFocusTracker *tracker;
if (NS_SUCCEEDED(shell->QueryInterface(kIFocusTracker,(void **)&tracker))) {
nsIFrameSelection* frameselection;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection, (void **)&frameselection))) {
nsIFrameSelection* frameselection;
if (NS_SUCCEEDED(selection->QueryInterface(kIFrameSelection, (void **)&frameselection))) {
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED( rv )){
frameselection->EnableFrameNotification(PR_FALSE);
frameselection->TakeFocus(tracker, this, startPos, contentOffset, PR_TRUE); //TRUE IS THE DIFFERENCE
frameselection->TakeFocus(content, startPos + contentOffset, PR_TRUE); //TRUE IS THE DIFFERENCE
frameselection->EnableFrameNotification(PR_TRUE);//prevent cyclic call to reset selection.
NS_RELEASE(frameselection);
}
NS_RELEASE(tracker);
NS_RELEASE(frameselection);
}
NS_RELEASE(selection);
}
@ -1561,68 +1563,28 @@ nsFrame::VerifyTree() const
/*this method may.. invalidate if the state was changed or if aForceRedraw is PR_TRUE
it will not update immediately.*/
NS_IMETHODIMP
nsFrame::SetSelected(nsSelectionStruct *aSelStruct)
nsFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread)
{
if (!aSelStruct)
return NS_ERROR_NULL_POINTER;
if (mSelected != (PRBool)(aSelStruct->mType & nsSelectionStruct::SELON ) || aSelStruct->mForceRedraw)
{
mSelected = aSelStruct->mType & nsSelectionStruct::SELON ;
/* nsRect rect;
GetRect(rect);
nsIFrame *frame = this;
nsIFrame *firstframe = nsnull;
while (NS_SUCCEEDED(frame->GetPrevInFlow(&frame)) && frame){
firstframe = frame;
}
if (firstframe){
nsRect rect2;
firstframe->GetRect(rect2);
rect.y-= rect.y-rect2.y;
}
*/
ForceDrawFrame(this);//invalidate does not work in all cases.
//Invalidate(rect,PR_FALSE); //false is for not immediate
}
nsFrameState frameState;
GetFrameState(&frameState);
if ( aSelected )
frameState |= NS_FRAME_SELECTED_CONTENT;
else
frameState &= ~NS_FRAME_SELECTED_CONTENT;
SetFrameState(frameState);
nsRect frameRect;
GetRect(frameRect);
nsRect rect(0, 0, frameRect.width, frameRect.height);
Invalidate(rect, PR_TRUE);
return NS_OK;
}
NS_IMETHODIMP
nsFrame::SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected)
{
if (!aActualSelected || !aSS)
return NS_ERROR_NULL_POINTER;
nsIFrame *child = nsnull;
nsresult result = FirstChild(nsnull, &child);
if (NS_FAILED(result)){
*aActualSelected = this;
if (aSS->mAnchorOffset > 0)
aTracker->SetFocus(nsnull,this);
if (aSS->mFocusOffset > 0)
aTracker->SetFocus(this,nsnull);
return SetSelected(aSS);
}
*aActualSelected = nsnull;
//wont actually bother with selection here on "this" frame
while (child && NS_SUCCEEDED(result)){
result |= child->SetSelectedContentOffsets(aSS, aTracker, aActualSelected);
if (NS_SUCCEEDED(result) && aActualSelected)
return result; //done.
result |= child->GetNextSibling(&child);
}
return result;
}
NS_IMETHODIMP
nsFrame::GetSelected(PRBool *aSelected, PRInt32 *aBeginOffset, PRInt32 *aEndOffset, PRInt32 *aBeginContentOffset)
nsFrame::GetSelected(PRBool *aSelected) const
{
if (!aSelected )
return NS_ERROR_NULL_POINTER;
*aSelected = mSelected;
*aSelected = (PRBool)(mState & NS_FRAME_SELECTED_CONTENT);
return NS_OK;
}
@ -1647,9 +1609,9 @@ nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFram
NS_IMETHODIMP
nsFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset,
PRBool aEatingWS)
PRBool aEatingWS) const
{
//this will use the nsFrameTraversal as the default peek method.
/* //this will use the nsFrameTraversal as the default peek method.
//this should change to use geometry and also look to ALL the child lists
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
nsresult result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
@ -1673,6 +1635,8 @@ nsFrame::PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 a
nsIFrame *newFrame = (nsIFrame *)isupports;
return newFrame->PeekOffset(aAmount, aDirection, aStartOffset, aResultFrame,
aFrameOffset, aContentOffset, aEatingWS);
*/
return NS_OK;
}
//-----------------------------------------------------------------------------------

View File

@ -208,14 +208,11 @@ public:
NS_IMETHOD GetFrameName(nsString& aResult) const;
NS_IMETHOD DumpRegressionData(FILE* out, PRInt32 aIndent);
NS_IMETHOD VerifyTree() const;
NS_IMETHOD SetSelected(nsSelectionStruct *);
NS_IMETHOD SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected);
NS_IMETHOD GetSelected(PRBool *aSelected, PRInt32 *aBeginOffset, PRInt32 *aEndOffset, PRInt32 *aBeginContentOffset);
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread);
NS_IMETHOD GetSelected(PRBool *aSelected) const;
NS_IMETHOD PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset,
PRBool aEatingWS);
PRBool aEatingWS)const;
NS_IMETHOD GetOffsets(PRInt32 &aStart, PRInt32 &aEnd) const;
@ -352,7 +349,6 @@ protected:
nsIFrame* mParent;
nsIFrame* mNextSibling; // singly linked list of frames
nsFrameState mState;
PRBool mSelected;
///////////////////////////////////
// Important Selection Variables

View File

@ -597,35 +597,16 @@ PresShell::Init(nsIDocument* aDocument,
getter_AddRefs(domselection));
if (!NS_SUCCEEDED(result))
return result;
result = domselection->QueryInterface(kIFrameSelectionIID,
getter_AddRefs(mSelection));
getter_AddRefs(mSelection));
if (!NS_SUCCEEDED(result))
return result;
domselection->AddSelectionListener(this);//possible circular reference
// XXX This code causes the document object (and the entire content model) to be leaked...
#if 0
nsCOMPtr<nsIDOMRange>range;
if (NS_SUCCEEDED(nsComponentManager::CreateInstance(kCRangeCID, nsnull, kIDOMRangeIID, getter_AddRefs(range)))){ //create an irange
nsCOMPtr<nsIDocument>doc(GetDocument());
nsCOMPtr<nsIDOMDocument>domDoc(doc);
if (domDoc){
nsCOMPtr<nsIDOMElement> domElement;
if (NS_SUCCEEDED(domDoc->GetDocumentElement(getter_AddRefs(domElement)))) {//get the first element from the dom
nsCOMPtr<nsIDOMNode>domNode(domElement);
if (domNode) {//get the node interface for the range object
range->SetStart(domNode,0);
range->SetEnd(domNode,0);
nsCOMPtr<nsISupports>rangeISupports(range);
if (rangeISupports) {
selection->AddItem(rangeISupports);
}
}
}
}
}
#endif
result = mSelection->Init((nsIFocusTracker *) this);
if (!NS_SUCCEEDED(result))
return result;
// Important: this has to happen after the selection has been set up
#ifdef SHOW_CARET
nsCaretProperties *caretProperties = NewCaretProperties();
@ -836,6 +817,7 @@ PresShell::EndObservingDocument()
if (!domselection)
return NS_ERROR_UNEXPECTED;
domselection->RemoveSelectionListener(this);
mSelection->ShutDown();
}
return NS_OK;
}
@ -958,12 +940,6 @@ PresShell::ResizeReflow(nscoord aWidth, nscoord aHeight)
NS_IF_RELEASE(rcx);
NS_FRAME_LOG(NS_FRAME_TRACE_CALLS, ("exit nsPresShell::ResizeReflow"));
if (mSelection){
DisableScrolling();
mSelection->ResetSelection(this, mRootFrame);
EnableScrolling();
}
// XXX if debugging then we should assert that the cache is empty
} else {
#ifdef NOISY
@ -1049,7 +1025,6 @@ NS_IMETHODIMP PresShell::NotifySelectionChanged()
{
if (!mSelection)
return NS_ERROR_NULL_POINTER;
mSelection->ResetSelection(this, mRootFrame);
return NS_ERROR_NULL_POINTER;
}
@ -1636,8 +1611,6 @@ PresShell::ContentChanged(nsIDocument *aDocument,
EnterReflowLock();
nsresult rv = mStyleSet->ContentChanged(mPresContext, aContent, aSubContent);
ExitReflowLock();
if (mSelection)
mSelection->ResetSelection(this, mRootFrame);
return rv;
}
@ -1652,8 +1625,6 @@ PresShell::ContentStatesChanged(nsIDocument* aDocument,
EnterReflowLock();
nsresult rv = mStyleSet->ContentStatesChanged(mPresContext, aContent1, aContent2);
ExitReflowLock();
//if (mSelection)
//mSelection->ResetSelection(this, mRootFrame);
return rv;
}
@ -2019,7 +1990,7 @@ PresShell::HandleEvent(nsIView *aView,
if (mSelection && mFocusEventFrame && aEvent->eventStructType == NS_KEY_EVENT)
{
mSelection->EnableFrameNotification(PR_FALSE);
mSelection->HandleKeyEvent((nsIFocusTracker *)this, aEvent);
mSelection->HandleKeyEvent(aEvent);
mSelection->EnableFrameNotification(PR_TRUE); //prevents secondary reset selection called since
//we are a listener now.
}

View File

@ -45,6 +45,9 @@ nsSplittableFrame::Init(nsIPresContext& aPresContext,
if (state & NS_FRAME_REPLACED_ELEMENT) {
mState |= NS_FRAME_REPLACED_ELEMENT;
}
if (state & NS_FRAME_SELECTED_CONTENT) {
mState |= NS_FRAME_SELECTED_CONTENT;
}
}
return rv;

View File

@ -52,6 +52,8 @@
#include "nsTextTransformer.h"
#include "nsLayoutAtoms.h"
#include "nsIFrameSelection.h"
#include "nsIDOMSelection.h"
#include "nsIDOMRange.h"
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
@ -229,14 +231,19 @@ public:
PRUint32& aActualContentOffset,
PRInt32& aOffset);
NS_IMETHOD SetSelected(nsSelectionStruct *aSS);
NS_IMETHOD SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected);
NS_IMETHOD GetSelected(PRBool *aSelected, PRInt32 *aBeginOffset, PRInt32 *aEndOffset, PRInt32 *aBeginContentOffset);
NS_IMETHOD GetPositionSlowly(nsIPresContext& aCX,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32& aActualContentOffset,
PRInt32& aOffset);
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread);
NS_IMETHOD PeekOffset(nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIFrame **aResultFrame, PRInt32 *aFrameOffset, PRInt32 *aContentOffset,
PRBool aEatingWS);
PRBool aEatingWS)const;
NS_IMETHOD GetOffsets(PRInt32 &start, PRInt32 &end)const;
@ -337,13 +344,6 @@ public:
nsIDocument* GetDocument(nsIPresContext* aPresContext);
nsresult GetPositionSlowly(nsIPresContext* aCX,
nsIRenderingContext * aRendContext,
nsGUIEvent* aEvent,
nsIFrame * aNewFrame,
PRUint32* aActualContentOffset,
PRInt32* aOffset);
PRIntn PrepareUnicodeText(nsTextTransformer& aTransformer,
PRInt32* aIndicies,
PRUnichar* aBuffer,
@ -415,8 +415,6 @@ protected:
PRInt32 mColumn;
nscoord mComputedWidth;
PRUint32 mSelectionOffset;
PRUint32 mSelectionEnd;
};
// Flag information used by rendering code. This information is
@ -458,8 +456,6 @@ nsTextFrame::nsTextFrame()
// Create text timer the first time out
gTextBlinker = new nsBlinkTimer();
}
mSelectionOffset = PRUint32(-1);
mSelectionEnd = PRUint32(-1);
NS_ADDREF(gTextBlinker);
}
@ -835,10 +831,13 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
PrepareUnicodeText(tx, (displaySelection ? ip : nsnull),
paintBuf, &textLength);
PRUnichar* text = paintBuf;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength) {
if (!displaySelection || !mSelected ||
(mSelectionOffset > PRUint32(mContentLength))) {
//if selection is > content length then selection has "slid off"
if (!displaySelection || !isSelected ) {
// When there is no selection showing, use the fastest and
// simplest rendering approach
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
@ -851,89 +850,98 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
//must set up last one for selection beyond edge if in boundary
ip[mContentLength]++;
}
PRInt32 textWidth;
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
PRBool drawSelected = PR_FALSE;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
rv = shell->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(rv) && selection){
frameSelection = do_QueryInterface(selection);
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected,0);// last param notused
}
}
}
nscoord textWidth;
if (mSelectionOffset < 0)
mSelectionOffset = 0;
if (mSelectionEnd < 0)
mSelectionEnd = mContentLength;
if (mSelectionEnd > PRUint32(mContentLength))
mSelectionEnd = PRUint32(mContentLength);
if (mSelectionOffset > PRUint32(mContentLength))
mSelectionOffset = PRUint32(mContentLength);
PRInt32 selectionEnd = mSelectionEnd;
PRInt32 selectionOffset = mSelectionOffset;
if (mSelectionEnd < mSelectionOffset)
{
selectionEnd = mSelectionOffset;
selectionOffset = mSelectionEnd;
}
//where are the selection points "really"
selectionOffset = ip[selectionOffset] - mContentOffset;
selectionEnd = ip[selectionEnd] - mContentOffset;
if (selectionOffset == selectionEnd) {
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
//shell->RefreshCaret();
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionOffset),//si.mStartOffset),
textWidth);
aRenderingContext.DrawString(text, PRUint32(selectionOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
if (frameSelection ){
//where are the selection points "really"
if (drawSelected){
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
}
PRInt32 secondLen = selectionEnd - selectionOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionOffset,
PRUint32(secondLen), textWidth);
if (!drawSelected || (selectionStartOffset == selectionEndOffset)) {
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
if (textLength != selectionEnd) {
PRInt32 thirdLen = textLength - selectionEnd;
else {
nscoord x = dx;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEnd, PRUint32(thirdLen),
if (selectionStartOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset),//si.mStartOffset),
textWidth);
aRenderingContext.DrawString(text + selectionEnd,
PRUint32(thirdLen), x, dy);
aRenderingContext.DrawString(text, PRUint32(selectionStartOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionStartOffset,
PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionStartOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEndOffset, PRUint32(thirdLen),
textWidth);
aRenderingContext.DrawString(text + selectionEndOffset,
PRUint32(thirdLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
}
}
}
}
}
}
// Cleanup
if (paintBuf != paintBufMem) {
delete [] paintBuf;
@ -945,24 +953,24 @@ nsTextFrame::PaintUnicodeText(nsIPresContext* aPresContext,
//measure Spaced Textvoid
nsresult
nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
nsTextFrame::GetPositionSlowly(nsIPresContext& aPresContext,
nsIRenderingContext* aRendContext,
nsGUIEvent* aEvent,
nsIFrame* aNewFrame,
PRUint32* aAcutalContentOffset,
PRInt32* aOffset)
PRUint32& aAcutalContentOffset,
PRInt32& aOffset)
{
if (!aRendContext || !aEvent || !aNewFrame) {
return NS_ERROR_NULL_POINTER;
}
TextStyle ts(aPresContext, *aRendContext, mStyleContext);
TextStyle ts(&aPresContext, *aRendContext, mStyleContext);
if (!ts.mSmallCaps && !ts.mWordSpacing && !ts.mLetterSpacing) {
return NS_ERROR_INVALID_ARG;
}
nsCOMPtr<nsIDocument> doc(getter_AddRefs(GetDocument(aPresContext)));
nsCOMPtr<nsIDocument> doc(getter_AddRefs(GetDocument(&aPresContext)));
// Make enough space to transform
PRUnichar paintBufMem[TEXT_BUF_SIZE];
@ -1026,12 +1034,12 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
}
if ((aEvent->point.x - origin.x) >= widthsofar && (aEvent->point.x - origin.x) <= (widthsofar + glyphWidth)){
if ( ((aEvent->point.x - origin.x) - widthsofar) <= (glyphWidth /2)){
*aOffset = index;
aOffset = index;
found = PR_TRUE;
break;
}
else{
*aOffset = index+1;
aOffset = index+1;
found = PR_TRUE;
break;
}
@ -1044,13 +1052,13 @@ nsTextFrame::GetPositionSlowly(nsIPresContext* aPresContext,
}
paintBuf = startBuf;
if (!found){
*aOffset = textLength;
aOffset = textLength;
}
*aAcutalContentOffset = mContentOffset;//offset;//((nsTextFrame *)aNewFrame)->mContentOffset;
aAcutalContentOffset = mContentOffset;//offset;//((nsTextFrame *)aNewFrame)->mContentOffset;
PRInt32 i;
for (i = 0;i <= mContentLength; i ++){
if (ip[i] == *aOffset + mContentOffset){ //reverse mapping
*aOffset = i;
if (ip[i] == aOffset + mContentOffset){ //reverse mapping
aOffset = i;
break;
}
}
@ -1319,9 +1327,12 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
}
PRUnichar* text = paintBuf;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength) {
if (!displaySelection || !mSelected ||
(mSelectionOffset > PRUint32(mContentLength))) {
if (!displaySelection || !isSelected) {
// When there is no selection showing, use the fastest and
// simplest rendering approach
RenderString(aRenderingContext, aStyleContext, aTextStyle,
@ -1329,89 +1340,99 @@ nsTextFrame::PaintTextSlowly(nsIPresContext* aPresContext,
}
else {
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength)//must set up last one for selection beyond edge if in boundary
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
ip[mContentLength]++;
nscoord textWidth;
if (mSelectionOffset < 0)
mSelectionOffset = 0;
if (mSelectionEnd < 0)
mSelectionEnd = PRUint32(mContentLength);
if (mSelectionEnd > PRUint32(mContentLength))
mSelectionEnd = PRUint32(mContentLength);
if (mSelectionOffset > PRUint32(mContentLength))
mSelectionOffset = PRUint32(mContentLength);
PRInt32 selectionEnd = mSelectionEnd;
PRInt32 selectionOffset = mSelectionOffset;
if (mSelectionEnd < mSelectionOffset)
{
selectionEnd = mSelectionOffset;
selectionOffset = mSelectionEnd;
}
//where are the selection points "really"
selectionOffset = ip[selectionOffset] - mContentOffset;
selectionEnd = ip[selectionEnd] - mContentOffset;
if (selectionOffset == selectionEnd){
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, textLength, dx, dy, width);
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
PRInt32 textWidth;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
PRBool drawSelected = PR_FALSE;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
rv = shell->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(rv) && selection){
frameSelection = do_QueryInterface(selection);
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected, 0);// last param notused
}
}
}
//shell->RefreshCaret();
if (frameSelection){
//where are the selection points "really"
if (drawSelected) {
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
}
if (!drawSelected || (selectionStartOffset == selectionEndOffset)){
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, textLength, dx, dy, width);
#ifdef SHOW_SELECTION_CURSOR
GetWidth(aRenderingContext, aTextStyle,
text, PRUint32(selectionOffset), &textWidth);
text, PRUint32(selectionStartOffset), &textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
else {
nscoord x = dx;
if (selectionOffset) {
// Render first (unselected) section
GetWidth(aRenderingContext, aTextStyle,
text, PRUint32(selectionOffset),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text, selectionOffset,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEnd - selectionOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
GetWidth(aRenderingContext, aTextStyle,
text + selectionOffset,
PRUint32(secondLen), &textWidth);
else {
nscoord x = dx;
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionOffset, secondLen,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEnd) {
PRInt32 thirdLen = textLength - selectionEnd;
// Render third (unselected) section
if (thirdLen > 0) //Text length is not negative or zero
{
if (selectionStartOffset) {
// Render first (unselected) section
GetWidth(aRenderingContext, aTextStyle,
text + selectionOffset, PRUint32(thirdLen),
text, PRUint32(selectionStartOffset),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionEnd,
thirdLen, x, dy, textWidth);
text, selectionStartOffset,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
GetWidth(aRenderingContext, aTextStyle,
text + selectionStartOffset,
PRUint32(secondLen), &textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionStartOffset, secondLen,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
// Render third (unselected) section
if (thirdLen > 0) //Text length is not negative or zero
{
GetWidth(aRenderingContext, aTextStyle,
text + selectionStartOffset, PRUint32(thirdLen),
&textWidth);
RenderString(aRenderingContext, aStyleContext, aTextStyle,
text + selectionEndOffset,
thirdLen, x, dy, textWidth);
}
}
}
}
}
}
// Cleanup
if (paintBuf != paintBufMem) {
delete [] paintBuf;
@ -1466,9 +1487,13 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
char* text = paintBuf;
nsFrameState frameState;
PRBool isSelected;
GetFrameState(&frameState);
isSelected = (frameState & NS_FRAME_SELECTED_CONTENT) == NS_FRAME_SELECTED_CONTENT;
if (0 != textLength) {
if (!displaySelection || !mSelected ||
(mSelectionOffset > PRUint32(mContentLength))) {
if (!displaySelection || !isSelected) {
//if selection is > content length then selection has "slid off"
// When there is no selection showing, use the fastest and
// simplest rendering approach
@ -1478,85 +1503,97 @@ nsTextFrame::PaintAsciiText(nsIPresContext* aPresContext,
}
else {
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength)//must set up last one for selection beyond edge if in boundary
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
ip[mContentLength]++;
nscoord textWidth;
if (mSelectionOffset < 0)
mSelectionOffset = 0;
if (mSelectionEnd < 0)
mSelectionEnd = mContentLength;
if (mSelectionEnd > PRUint32(mContentLength))
mSelectionEnd = PRUint32(mContentLength);
if (mSelectionOffset > PRUint32(mContentLength))
mSelectionOffset = PRUint32(mContentLength);
PRInt32 selectionEnd = mSelectionEnd;
PRInt32 selectionOffset = mSelectionOffset;
if (mSelectionEnd < mSelectionOffset)
{
selectionEnd = mSelectionOffset;
selectionOffset = mSelectionEnd;
}
//where are the selection points "really"
selectionOffset = ip[selectionOffset] - mContentOffset;
selectionEnd = ip[selectionEnd] - mContentOffset;
if (selectionOffset == selectionEnd){
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
//shell->RefreshCaret();
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionOffset), textWidth);
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
PRInt32 selectionStartOffset = 0;//frame coordinates
PRInt32 selectionEndOffset = 0;//frame coordinates
PRInt32 textWidth;
nsCOMPtr<nsIPresShell> shell;
nsCOMPtr<nsIDOMSelection> selection;
nsCOMPtr<nsIFrameSelection> frameSelection;
PRBool drawSelected = PR_FALSE;
nsresult rv = aPresContext->GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell){
rv = shell->GetSelection(getter_AddRefs(selection));
if (NS_SUCCEEDED(rv) && selection){
frameSelection = do_QueryInterface(selection);
nsCOMPtr<nsIContent> content;
rv = GetContent(getter_AddRefs(content));
if (NS_SUCCEEDED(rv)){
rv = frameSelection->LookUpSelection(content, mContentOffset,
mContentLength , &selectionStartOffset, &selectionEndOffset,
&drawSelected, 0);// last param notused
}
}
}
else
{
nscoord x = dx;
if (selectionOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionOffset),//si.mStartOffset),
textWidth);
aRenderingContext.DrawString(text, PRUint32(selectionOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
if (frameSelection){
//where are the selection points "really"
if (drawSelected) {
selectionStartOffset = ip[selectionStartOffset] - mContentOffset;
selectionEndOffset = ip[selectionEndOffset] - mContentOffset;
}
PRInt32 secondLen = selectionEnd - selectionOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionOffset,
PRUint32(secondLen), textWidth);
if (!drawSelected || (selectionStartOffset == selectionEndOffset)){
aRenderingContext.DrawString(text, PRUint32(textLength), dx, dy);
PaintTextDecorations(aRenderingContext, aStyleContext,
aTextStyle, dx, dy, width);
//shell->RefreshCaret();
#ifdef SHOW_SELECTION_CURSOR
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
RenderSelectionCursor(aRenderingContext,
dx + textWidth, dy, mRect.height,
CURSOR_COLOR);
#endif
}
if (textLength != selectionEnd) {
PRInt32 thirdLen = textLength - selectionEnd;
else {
nscoord x = dx;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEnd, PRUint32(thirdLen),
if (selectionStartOffset) {
// Render first (unselected) section
aRenderingContext.GetWidth(text, PRUint32(selectionStartOffset),//si.mStartOffset),
textWidth);
aRenderingContext.DrawString(text + selectionEnd,
PRUint32(thirdLen), x, dy);
aRenderingContext.DrawString(text, PRUint32(selectionStartOffset),
x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
x += textWidth;
}
PRInt32 secondLen = selectionEndOffset - selectionStartOffset;
if (0 != secondLen) {
// Get the width of the second (selected) section
aRenderingContext.GetWidth(text + selectionStartOffset,
PRUint32(secondLen), textWidth);
// Render second (selected) section
aRenderingContext.SetColor(aTextStyle.mSelectionBGColor);
aRenderingContext.FillRect(x, dy, textWidth, mRect.height);
aRenderingContext.SetColor(aTextStyle.mSelectionTextColor);
aRenderingContext.DrawString(text + selectionStartOffset,
PRUint32(secondLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
aRenderingContext.SetColor(aTextStyle.mColor->mColor);
x += textWidth;
}
if (textLength != selectionEndOffset) {
PRInt32 thirdLen = textLength - selectionEndOffset;
if (thirdLen > 0) //Text length is not negative or zero
{
// Render third (unselected) section
aRenderingContext.GetWidth(text + selectionEndOffset, PRUint32(thirdLen),
textWidth);
aRenderingContext.DrawString(text + selectionEndOffset,
PRUint32(thirdLen), x, dy);
PaintTextDecorations(aRenderingContext, aStyleContext, aTextStyle,
x, dy, textWidth);
}
}
}
}
@ -1611,7 +1648,7 @@ BinarySearchForPosition(nsIRenderingContext* acx,
}
PRInt32 inx = aStartInx + (range / 2);
PRInt32 textWidth;
PRInt32 textWidth = 0;
acx->GetWidth(aText, inx, textWidth);
PRInt32 fullWidth = aBaseWidth + textWidth;
@ -1648,8 +1685,8 @@ nsTextFrame::GetPosition(nsIPresContext& aPresContext,
{
TextStyle ts(&aPresContext, *aRendContext, mStyleContext);
if (ts.mSmallCaps || ts.mWordSpacing || ts.mLetterSpacing) {
return GetPositionSlowly(&aPresContext, aRendContext, aEvent, aNewFrame,
&aActualContentOffset, &aOffset);
return GetPositionSlowly(aPresContext, aRendContext, aEvent, aNewFrame,
aActualContentOffset, aOffset);
}
PRUnichar wordBufMem[WORD_BUF_SIZE];
@ -1690,7 +1727,7 @@ nsTextFrame::GetPosition(nsIPresContext& aPresContext,
}
PRInt32 index;
PRInt32 textWidth;
PRInt32 textWidth = 0;
PRUnichar* text = paintBuf;
nsPoint origin;
nsIView * view;
@ -1742,129 +1779,83 @@ nsTextFrame::GetPosition(nsIPresContext& aPresContext,
return NS_OK;
}
NS_IMETHODIMP
nsTextFrame::SetSelected(nsSelectionStruct *aSelStruct)
{
if (!aSelStruct)
return NS_ERROR_NULL_POINTER;
if (aSelStruct->mType & nsSelectionStruct::SELON){
aSelStruct->mEndFrame = PR_MIN(aSelStruct->mEndFrame, (PRUint32) mContentLength);
aSelStruct->mStartFrame= PR_MIN(aSelStruct->mStartFrame, (PRUint32) mContentLength);
if (aSelStruct->mType & nsSelectionStruct::SELTOEND)
aSelStruct->mEndFrame = mContentLength;
if (aSelStruct->mType & nsSelectionStruct::SELTOBEGIN)
aSelStruct->mStartFrame = 0;
PRUint32 trueBegin(aSelStruct->mStartFrame);
PRUint32 trueEnd(aSelStruct->mEndFrame);
if (aSelStruct->mDir == eDirPrevious){//change the settings around,
//the frame doesnt track direction it only tracks begin and end.
trueBegin = aSelStruct->mEndFrame;
trueEnd = aSelStruct->mStartFrame;
}
if (mSelectionOffset != trueBegin || mSelectionEnd != trueEnd)
{
//XXX PRBool wasCollapsed = (mSelectionOffset == mSelectionEnd);
mSelectionOffset = trueBegin;
mSelectionEnd = trueEnd;
// XXX when we no longer rely on the blue triangle to show the selection
// position (using the caret instead), then we can uncomment this to reduce
// redrawing. sfraser
aSelStruct->mForceRedraw = PR_TRUE; //!wasCollapsed || (trueBegin != trueEnd);
}
}
return nsFrame::SetSelected(aSelStruct);//this will do the actual
//turning on of the mSelected flag in the nsframe header.
}
// [HACK] Foward Declarations
void ForceDrawFrame(nsFrame * aFrame);
NS_IMETHODIMP
nsTextFrame::SetSelectedContentOffsets(nsSelectionStruct *aSS,
nsIFocusTracker *aTracker,
nsIFrame **aActualSelected)
nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, PRBool aSpread)
{
if (!aActualSelected || !aSS)
if (!aRange)
return NS_ERROR_NULL_POINTER;
nsresult result;
if (aSpread){
nsIFrame *frame = GetPrevInFlow();
while(frame){
frame->SetSelected(aRange,aSelected,PR_FALSE);
result = frame->GetPrevInFlow(&frame);
if (NS_FAILED(result))
break;
}
frame = GetNextInFlow();
while(frame){
frame->SetSelected(aRange,aSelected,PR_FALSE);
result = frame->GetNextInFlow(&frame);
if (NS_FAILED(result))
break;
}
}
//lets see if the range contains us, if so we must redraw!
nsCOMPtr<nsIDOMNode> endNode;
PRInt32 endOffset;
nsCOMPtr<nsIDOMNode> startNode;
PRInt32 startOffset;
aRange->GetEndParent(getter_AddRefs(endNode));
aRange->GetEndOffset(&endOffset);
aRange->GetStartParent(getter_AddRefs(startNode));
aRange->GetStartOffset(&startOffset);
nsCOMPtr<nsIContent> content;
result = GetContent(getter_AddRefs(content));
nsCOMPtr<nsIDOMNode> thisNode;
thisNode = do_QueryInterface(content);
PRInt32 beginOffset(aSS->mStartContent - mContentOffset);
if (beginOffset > mContentLength){
//this is not the droid we are looking for. keep looking
nsSelectionStruct ss = {0};//turn it ALL off
ss.mForceRedraw = aSS->mForceRedraw;
SetSelected(&ss);
nsIFrame *nextInFlow =GetNextInFlow();
if (nextInFlow)
return nextInFlow->SetSelectedContentOffsets(aSS, aTracker, aActualSelected);
else
return NS_ERROR_FAILURE;
}
if (aSS->mType & nsSelectionStruct::CHECKANCHOR && aSS->mAnchorOffset == aSS->mStartContent ){
aTracker->SetFocus(nsnull, this);
aSS->mType = aSS->mType-nsSelectionStruct::CHECKANCHOR;
}
if (aSS->mType & nsSelectionStruct::CHECKFOCUS && aSS->mFocusOffset == aSS->mStartContent ){
aTracker->SetFocus(this, nsnull);
aSS->mType = aSS->mType-nsSelectionStruct::CHECKFOCUS;
}
*aActualSelected = this;
nsIFrame *nextInFlow = GetNextInFlow();
if (nextInFlow){
if (aSS->mType & nsSelectionStruct::SELTOEND || aSS->mEndContent > PRUint32(mContentLength + mContentOffset)){
nextInFlow->SetSelectedContentOffsets(aSS, aTracker ,aActualSelected);
}
else if (aSS->mType & nsSelectionStruct::SELON) { //we must shut off all folowing selected frames if we are selecting frames
if (aSS->mType & nsSelectionStruct::CHECKANCHOR && aSS->mAnchorOffset == aSS->mEndContent ){
aTracker->SetFocus(nsnull, this);
aSS->mType = aSS->mType - nsSelectionStruct::CHECKANCHOR;
PRBool found = PR_FALSE;
if (thisNode == startNode){
if ((mContentOffset + mContentLength) >= startOffset){
found = PR_TRUE;
if (thisNode == endNode){ //special case
/*#ifndef SHOW_SELECTION_CURSOR
if (aSelected && (endOffset == startOffset)) //no need to redraw since drawing takes place with cursor
found = PR_FALSE;
#endif
*/
if (mContentOffset > endOffset)
found = PR_FALSE;
}
if (aSS->mType & nsSelectionStruct::CHECKFOCUS && aSS->mFocusOffset == aSS->mEndContent ){
aTracker->SetFocus(this, nsnull);
aSS->mType = aSS->mType - nsSelectionStruct::CHECKFOCUS;
}
nsSelectionStruct ss={0, 0,0, 0,0, 0,0, eDirNext, aSS->mForceRedraw};
do {
nextInFlow->SetSelected(&ss);
}
while (NS_SUCCEEDED(nextInFlow->GetNextInFlow(&nextInFlow)) && nextInFlow);//this is ok because frames arent reference counted this is not a leak!
}
}
else {
if (aSS->mType & nsSelectionStruct::CHECKANCHOR && aSS->mAnchorOffset == aSS->mEndContent ){
aTracker->SetFocus(nsnull, this);
aSS->mType = aSS->mType - nsSelectionStruct::CHECKANCHOR;
}
if (aSS->mType & nsSelectionStruct::CHECKFOCUS && aSS->mFocusOffset == aSS->mEndContent ){
aTracker->SetFocus(this, nsnull);
aSS->mType = aSS->mType - nsSelectionStruct::CHECKFOCUS;
}
}
if (PRUint32(mContentOffset) > aSS->mStartContent){
aSS->mStartFrame = 0;
}
else
aSS->mStartFrame = aSS->mStartContent - mContentOffset;
aSS->mEndFrame = aSS->mEndContent - mContentOffset;
return SetSelected(aSS);
}
NS_IMETHODIMP
nsTextFrame::GetSelected(PRBool *aSelected,
PRInt32 *aBeginOffset,
PRInt32 *aEndOffset,
PRInt32 *aBeginContentOffset)
{
if (!aSelected || !aBeginOffset || !aEndOffset || !aBeginContentOffset)
return NS_ERROR_NULL_POINTER;
*aBeginOffset = mSelectionOffset;
*aEndOffset = mSelectionEnd;
*aSelected = mSelected;
*aBeginContentOffset = mContentOffset;
//should we check for whitespace here? dont think so.
if (thisNode == endNode){
if (mContentOffset < endOffset)
found = PR_TRUE;
}
if (found){ //if range contains this frame...
/* nsRect frameRect;
GetRect(frameRect);
nsRect rect(0, 0, frameRect.width, frameRect.height);
Invalidate(rect, PR_FALSE);
*/ ForceDrawFrame(this);
}
nsFrameState frameState;
GetFrameState(&frameState);
if ( aSelected )
frameState |= NS_FRAME_SELECTED_CONTENT;
else
frameState &= ~NS_FRAME_SELECTED_CONTENT;
SetFrameState(frameState);
return NS_OK;
}
NS_IMETHODIMP
nsTextFrame::GetPointFromOffset(nsIPresContext* aPresContext,
nsIRenderingContext* inRendContext,
@ -1968,8 +1959,9 @@ nsTextFrame::PeekOffset(nsSelectionAmount aAmount,
nsIFrame **aResultFrame,
PRInt32 *aFrameOffset,
PRInt32 *aContentOffset,
PRBool aEatingWS)
PRBool aEatingWS) const
{
/*
//default, no matter what grab next/ previous sibling.
if (!aResultFrame || !aFrameOffset || !aContentOffset)
return NS_ERROR_NULL_POINTER;
@ -2163,6 +2155,8 @@ nsTextFrame::PeekOffset(nsSelectionAmount aAmount,
result = NS_OK;
}
return result;
*/
return NS_OK;
}
NS_IMETHODIMP