new table selection code drag inside and outside of tables with ease. added some overriding methods to nsTableCellFrame and nsTableFrame to make selection "draw" correctly for those containers.

This commit is contained in:
mjudge%netscape.com 1999-06-01 23:04:13 +00:00
parent 5b77f19cc1
commit 864e061209
15 changed files with 812 additions and 193 deletions

View File

@ -50,12 +50,16 @@
static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID); static NS_DEFINE_IID(kRangeCID, NS_RANGE_CID);
static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID); static NS_DEFINE_IID(kCContentIteratorCID, NS_CONTENTITERATOR_CID);
static NS_DEFINE_IID(kCSubtreeIteratorCID, NS_SUBTREEITERATOR_CID);
//PROTOTYPES //PROTOTYPES
static void printRange(nsIDOMRange *aDomRange); static void printRange(nsIDOMRange *aDomRange);
static nsCOMPtr<nsIAtom> GetTag(nsIDOMNode *aNode);
static nsresult ParentOffset(nsIDOMNode *aNode, nsIDOMNode **aParent, PRInt32 *aChildOffset);
#if 0
#if 1
#define DEBUG_OUT_RANGE(x) printRange(x) #define DEBUG_OUT_RANGE(x) printRange(x)
#else #else
#define DEBUG_OUT_RANGE(x) #define DEBUG_OUT_RANGE(x)
@ -137,9 +141,18 @@ private:
nsIDOMNode* FetchAnchorNode(); //where did the selection begin nsIDOMNode* FetchAnchorNode(); //where did the selection begin
PRInt32 FetchAnchorOffset(); PRInt32 FetchAnchorOffset();
nsIDOMNode* FetchOriginalAnchorNode(); //where did the ORIGINAL selection begin
PRInt32 FetchOriginalAnchorOffset();
nsIDOMNode* FetchFocusNode(); //where is the carret nsIDOMNode* FetchFocusNode(); //where is the carret
PRInt32 FetchFocusOffset(); PRInt32 FetchFocusOffset();
nsIDOMNode* FetchStartParent(nsIDOMRange *aRange); //skip all the com stuff and give me the start/end
PRInt32 FetchStartOffset(nsIDOMRange *aRange);
nsIDOMNode* FetchEndParent(nsIDOMRange *aRange); //skip all the com stuff and give me the start/end
PRInt32 FetchEndOffset(nsIDOMRange *aRange);
void setAnchorFocusRange(PRInt32); //pass in index into rangelist void setAnchorFocusRange(PRInt32); //pass in index into rangelist
PRUint32 GetBatching(){return mBatching;} PRUint32 GetBatching(){return mBatching;}
@ -152,9 +165,15 @@ private:
NS_IMETHOD selectFrames(nsIDOMRange *aRange, PRBool aSelect); NS_IMETHOD selectFrames(nsIDOMRange *aRange, PRBool aSelect);
NS_IMETHOD FixupSelectionPoints(nsIDOMRange *aRange, nsDirection *aDir, PRBool *aFixupState);
NS_IMETHOD SetOriginalAnchorPoint(nsIDOMNode *aNode, PRInt32 aOffset);
NS_IMETHOD GetOriginalAnchorPoint(nsIDOMNode **aNode, PRInt32 *aOffset);
nsCOMPtr<nsISupportsArray> mRangeArray; nsCOMPtr<nsISupportsArray> mRangeArray;
nsCOMPtr<nsIDOMRange> mAnchorFocusRange; nsCOMPtr<nsIDOMRange> mAnchorFocusRange;
nsCOMPtr<nsIDOMRange> mOriginalAnchorRange; //used as a point with range gravity for security
PRBool mFixupState; //was there a fixup?
nsDirection mDirection; //FALSE = focus, anchor; TRUE = anchor,focus nsDirection mDirection; //FALSE = focus, anchor; TRUE = anchor,focus
//batching //batching
@ -168,6 +187,10 @@ private:
void* mScriptObject; void* mScriptObject;
nsIFocusTracker *mTracker; nsIFocusTracker *mTracker;
PRBool mMouseDownState; //for drag purposes PRBool mMouseDownState; //for drag purposes
static nsIAtom *sTableAtom;
static nsIAtom *sCellAtom;
static nsIAtom *sTbodyAtom;
static PRInt32 sInstanceCount;
}; };
class nsRangeListIterator : public nsIBidirectionalEnumerator class nsRangeListIterator : public nsIBidirectionalEnumerator
@ -221,7 +244,11 @@ nsresult NS_NewRangeList(nsIDOMSelection **aRangeList)
//Horrible statics but no choice
nsIAtom *nsRangeList::sTableAtom = 0;
nsIAtom *nsRangeList::sCellAtom = 0;
nsIAtom *nsRangeList::sTbodyAtom = 0;
PRInt32 nsRangeList::sInstanceCount = 0;
///////////BEGIN nsRangeListIterator methods ///////////BEGIN nsRangeListIterator methods
nsRangeListIterator::nsRangeListIterator(nsRangeList *aList) nsRangeListIterator::nsRangeListIterator(nsRangeList *aList)
@ -404,9 +431,17 @@ nsRangeList::nsRangeList()
NS_NewISupportsArray(getter_AddRefs(mSelectionListeners)); NS_NewISupportsArray(getter_AddRefs(mSelectionListeners));
mBatching = 0; mBatching = 0;
mChangesDuringBatching = PR_FALSE; mChangesDuringBatching = PR_FALSE;
mFixupState = PR_FALSE;
mNotifyFrames = PR_TRUE; mNotifyFrames = PR_TRUE;
mScriptObject = nsnull; mScriptObject = nsnull;
mDirection = eDirNext; mDirection = eDirNext;
if (sInstanceCount <= 0)
{
sTableAtom = NS_NewAtom("table");
sCellAtom = NS_NewAtom("td");
sTbodyAtom = NS_NewAtom("tbody");
}
sInstanceCount ++;
} }
@ -435,7 +470,13 @@ nsRangeList::~nsRangeList()
} }
} }
setAnchorFocusRange(-1); setAnchorFocusRange(-1);
if (sInstanceCount <= 1)
{
NS_IF_RELEASE(sTableAtom);
NS_IF_RELEASE(sCellAtom);
NS_IF_RELEASE(sTbodyAtom);
}
sInstanceCount--;
} }
@ -590,6 +631,30 @@ nsRangeList::FetchAnchorOffset()
nsIDOMNode*
nsRangeList::FetchOriginalAnchorNode() //where did the ORIGINAL selection begin
{
nsCOMPtr<nsIDOMNode>retval;
PRInt32 unused;
if (NS_SUCCEEDED(GetOriginalAnchorPoint(getter_AddRefs(retval), &unused)))//this queries
return retval;
return nsnull;
}
PRInt32
nsRangeList::FetchOriginalAnchorOffset()
{
nsCOMPtr<nsIDOMNode>unused;
PRInt32 retval;
if (NS_SUCCEEDED(GetOriginalAnchorPoint(getter_AddRefs(unused), &retval)))//this queries
return retval;
return 0;
}
nsIDOMNode* nsIDOMNode*
nsRangeList::FetchFocusNode() nsRangeList::FetchFocusNode()
{ //where is the carret { //where is the carret
@ -611,6 +676,54 @@ nsRangeList::FetchFocusOffset()
} }
nsIDOMNode*
nsRangeList::FetchStartParent(nsIDOMRange *aRange) //skip all the com stuff and give me the start/end
{
if (!aRange)
return nsnull;
nsIDOMNode *returnval;
aRange->GetStartParent(&returnval);
return returnval;
}
PRInt32
nsRangeList::FetchStartOffset(nsIDOMRange *aRange)
{
if (!aRange)
return nsnull;
PRInt32 returnval;
aRange->GetStartOffset(&returnval);
return returnval;
}
nsIDOMNode*
nsRangeList::FetchEndParent(nsIDOMRange *aRange) //skip all the com stuff and give me the start/end
{
if (!aRange)
return nsnull;
nsIDOMNode *returnval;
aRange->GetEndParent(&returnval);
return returnval;
}
PRInt32
nsRangeList::FetchEndOffset(nsIDOMRange *aRange)
{
if (!aRange)
return nsnull;
PRInt32 returnval;
aRange->GetEndOffset(&returnval);
return returnval;
}
nsresult nsresult
nsRangeList::AddItem(nsISupports *aItem) nsRangeList::AddItem(nsISupports *aItem)
@ -699,7 +812,7 @@ void printRange(nsIDOMRange *aDomRange)
aDomRange->GetEndParent(getter_AddRefs(endNode)); aDomRange->GetEndParent(getter_AddRefs(endNode));
aDomRange->GetEndOffset(&endOffset); aDomRange->GetEndOffset(&endOffset);
printf("print DOMRANGE 0x%lx\t start: 0x%lx %ld, \t end: 0x%lx,%ld \n", printf("range: 0x%lx\t start: 0x%lx %ld, \t end: 0x%lx,%ld\n",
(unsigned long)aDomRange, (unsigned long)aDomRange,
(unsigned long)(nsIDOMNode*)startNode, (long)startOffset, (unsigned long)(nsIDOMNode*)startNode, (long)startOffset,
(unsigned long)(nsIDOMNode*)endNode, (long)endOffset); (unsigned long)(nsIDOMNode*)endNode, (long)endOffset);
@ -707,6 +820,48 @@ void printRange(nsIDOMRange *aDomRange)
} }
nsCOMPtr<nsIAtom> GetTag(nsIDOMNode *aNode)
{
nsCOMPtr<nsIAtom> atom;
if (!aNode)
{
NS_NOTREACHED("null node passed to nsHTMLEditRules::GetTag()");
return atom;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
if (content)
content->GetTag(*getter_AddRefs(atom));
return atom;
}
nsresult
ParentOffset(nsIDOMNode *aNode, nsIDOMNode **aParent, PRInt32 *aChildOffset)
{
if (!aNode || !aParent || !aChildOffset)
return NS_ERROR_NULL_POINTER;
nsresult result = NS_OK;
nsCOMPtr<nsIContent> content;
result = aNode->QueryInterface(nsIContent::GetIID(),getter_AddRefs(content));
if (NS_SUCCEEDED(result) && content)
{
nsCOMPtr<nsIContent> parent;
result = content->GetParent(*getter_AddRefs(parent));
if (NS_SUCCEEDED(result))
{
result = parent->IndexOf(content, *aChildOffset);
if (NS_SUCCEEDED(result))
result = parent->QueryInterface(nsIDOMNode::GetIID(),(void **)aParent);
}
}
return result;
}
NS_IMETHODIMP NS_IMETHODIMP
nsRangeList::Init(nsIFocusTracker *aTracker) nsRangeList::Init(nsIFocusTracker *aTracker)
@ -876,7 +1031,7 @@ nsRangeList::selectFrames(nsIDOMRange *aRange, PRBool aFlags)
if (!aRange) if (!aRange)
return NS_ERROR_NULL_POINTER; return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIContentIterator> iter; nsCOMPtr<nsIContentIterator> iter;
nsresult result = nsComponentManager::CreateInstance(kCContentIteratorCID, nsnull, nsresult result = nsComponentManager::CreateInstance(kCSubtreeIteratorCID, nsnull,
nsIContentIterator::GetIID(), nsIContentIterator::GetIID(),
getter_AddRefs(iter)); getter_AddRefs(iter));
if ((NS_SUCCEEDED(result)) && iter) if ((NS_SUCCEEDED(result)) && iter)
@ -888,22 +1043,42 @@ nsRangeList::selectFrames(nsIDOMRange *aRange, PRBool aFlags)
// ask the style context about the property // ask the style context about the property
nsCOMPtr<nsIContent> content; nsCOMPtr<nsIContent> content;
PRBool drawWholeContent = PR_FALSE; PRBool drawWholeContent = PR_FALSE;
result = iter->First(); nsIFrame *frame;
//we must call first one explicitly
content = do_QueryInterface(FetchStartParent(aRange), &result);
if (NS_FAILED(result)) if (NS_FAILED(result))
return result; return result;
nsIFrame *frame; result = mTracker->GetPrimaryFrameFor(content, &frame);
while (NS_COMFALSE == iter->IsDone()) if (NS_SUCCEEDED(result) && frame)
frame->SetSelected(aRange,aFlags,eSpreadDown);//spread from here to hit all frames in flow
//end start content
result = iter->First();
if (NS_SUCCEEDED(result))
{ {
result = iter->CurrentNode(getter_AddRefs(content)); while (NS_COMFALSE == iter->IsDone())
{
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,eSpreadDown);//spread from here to hit all frames in flow
result = iter->Next();
if (NS_FAILED(result))
return result;
}
}
//we must now do the last one if it is not the same as the first
if (FetchEndParent(aRange) != FetchStartParent(aRange))
{
content = do_QueryInterface(FetchEndParent(aRange), &result);
if (NS_FAILED(result)) if (NS_FAILED(result))
return result; return result;
result = mTracker->GetPrimaryFrameFor(content, &frame); result = mTracker->GetPrimaryFrameFor(content, &frame);
if (NS_SUCCEEDED(result) && frame) if (NS_SUCCEEDED(result) && frame)
frame->SetSelected(aRange,aFlags,eSpreadAcross);//spread from here to hit all frames in flow frame->SetSelected(aRange,aFlags,eSpreadDown);//spread from here to hit all frames in flow
result = iter->Next();
if (NS_FAILED(result))
return result;
} }
//end end parent
} }
return result; return result;
} }
@ -1194,6 +1369,8 @@ nsRangeList::Collapse(nsIDOMNode* aParentNode, PRInt32 aOffset)
// Delete all of the current ranges // Delete all of the current ranges
if (!mRangeArray) if (!mRangeArray)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
if (NS_FAILED(SetOriginalAnchorPoint(aParentNode,aOffset)))
return NS_ERROR_FAILURE; //???
Clear(); Clear();
nsCOMPtr<nsIDOMRange> range; nsCOMPtr<nsIDOMRange> range;
@ -1334,6 +1511,226 @@ nsRangeList::GetRangeAt(PRInt32 aIndex, nsIDOMRange** aReturn)
return NS_OK; return NS_OK;
} }
//may change parameters may not.
//return NS_ERROR_FAILED if invalid new selection between anchor and passed in parameters
NS_IMETHODIMP
nsRangeList::FixupSelectionPoints(nsIDOMRange *aRange , nsDirection *aDir, PRBool *aFixupState)
{
if (!aRange || !aFixupState)
return NS_ERROR_NULL_POINTER;
*aFixupState = PR_FALSE;
nsresult res;
//startNode is the beginning or "anchor" of the range
//end Node is the end or "focus of the range
nsCOMPtr<nsIDOMNode> startNode;
nsCOMPtr<nsIDOMNode> endNode;
PRInt32 startOffset;
PRInt32 endOffset;
nsresult result;
if (*aDir == eDirNext)
{
if (NS_FAILED(GetOriginalAnchorPoint(getter_AddRefs(startNode), &startOffset)))
{
aRange->GetStartParent(getter_AddRefs(startNode));
aRange->GetStartOffset(&startOffset);
}
aRange->GetEndParent(getter_AddRefs(endNode));
aRange->GetEndOffset(&endOffset);
}
else
{
if (NS_FAILED(GetOriginalAnchorPoint(getter_AddRefs(startNode), &startOffset)))
{
aRange->GetEndParent(getter_AddRefs(startNode));
aRange->GetEndOffset(&startOffset);
}
aRange->GetStartParent(getter_AddRefs(endNode));
aRange->GetStartOffset(&endOffset);
}
if (!startNode || !endNode)
return NS_ERROR_FAILURE;
// if end node is a tbody then all bets are off we cannot select "rows"
nsCOMPtr<nsIAtom> atom;
atom = GetTag(endNode);
if (atom.get() == sTbodyAtom)
return NS_ERROR_FAILURE; //cannot select INTO row node ony cells
//get common parent
nsCOMPtr<nsIDOMNode> parent;
res = aRange->GetCommonParent(getter_AddRefs(parent));
if (NS_FAILED(res) || !parent)
return res;
//look for dest. if you see a cell you are in "cell mode"
//if you see a table you select "whole" table
//src first
//if src EVER hits a table, all bets are off!
nsCOMPtr<nsIDOMNode> tempNode;
nsCOMPtr<nsIDOMNode> tempNode2;
PRBool cellMode = PR_FALSE;
PRBool dirty = PR_FALSE;
PRBool fixupState = PR_FALSE;
if (startNode != endNode)
{
if (parent != startNode)
{
result = startNode->GetParentNode(getter_AddRefs(tempNode));
if (NS_FAILED(result))
return result;
while (tempNode != parent)
{
atom = GetTag(tempNode);
if (atom.get() == sTableAtom)
{
return NS_ERROR_FAILURE; //cannot do this
}
else if (atom.get() == sCellAtom) //you are in "cell" mode put selection to end of cell
{
cellMode = PR_TRUE;
result = ParentOffset(tempNode, getter_AddRefs(startNode), &startOffset);
if (NS_FAILED(result))
return result;
if (*aDir == eDirPrevious) //select after
startOffset++;
dirty = PR_TRUE;
}
result = tempNode->GetParentNode(getter_AddRefs(tempNode2));
if (NS_FAILED(result))
return result;
tempNode = tempNode2;
}
}
//now for dest node
if (parent != endNode)
{
result = endNode->GetParentNode(getter_AddRefs(tempNode));
PRBool found = !cellMode;
if (NS_FAILED(result))
return result;
while (tempNode != parent)
{
nsCOMPtr<nsIAtom> atom = GetTag(tempNode);
if (atom.get() == sTableAtom) //select whole table if in cell mode, wait for cell
{
if (!cellMode)
{
result = ParentOffset(tempNode, getter_AddRefs(endNode), &endOffset);
if (NS_FAILED(result))
return result;
if (*aDir == eDirNext) //select after
endOffset++;
dirty = PR_TRUE;
}
else
found = PR_FALSE; //didnt find the right cell yet
}
else if (atom.get() == sCellAtom) //you are in "cell" mode put selection to end of cell
{
result = ParentOffset(tempNode, getter_AddRefs(endNode), &endOffset);
if (NS_FAILED(result))
return result;
if (*aDir == eDirNext) //select after
endOffset++;
found = PR_TRUE;
dirty = PR_TRUE;
}
result = tempNode->GetParentNode(getter_AddRefs(tempNode2));
if (NS_FAILED(result))
return result;
tempNode = tempNode2;
}
if (!found)
return NS_ERROR_FAILURE;
}
}
if (startNode != FetchAnchorNode() || startOffset != FetchAnchorOffset())
dirty = PR_TRUE; //something has changed we are dirty no matter what
if (dirty && *aDir != mDirection) //fixup took place but new direction all bets are off
{
*aFixupState = PR_TRUE;
mFixupState = PR_FALSE;
}
else
if (FetchOriginalAnchorNode() == startNode && PR_TRUE == mFixupState) //no longer a fixup
{
*aFixupState = PR_TRUE;
mFixupState = PR_FALSE;
}
else
{
mFixupState = dirty;
*aFixupState = dirty;
}
if (dirty){
if (*aDir == eDirNext)
{
if (NS_FAILED(aRange->SetStart(startNode,startOffset)) || NS_FAILED(aRange->SetEnd(endNode, endOffset)))
{
*aDir = eDirPrevious;
aRange->SetStart(endNode, endOffset);
aRange->SetEnd(startNode, startOffset);
}
}
else
{
if (NS_FAILED(aRange->SetStart(endNode,endOffset)) || NS_FAILED(aRange->SetEnd(startNode, startOffset)))
{
*aDir = eDirNext;
aRange->SetStart(startNode, startOffset);
aRange->SetEnd(endNode, endOffset);
}
}
}
return NS_OK;
}
NS_IMETHODIMP
nsRangeList::SetOriginalAnchorPoint(nsIDOMNode *aNode, PRInt32 aOffset)
{
if (!aNode){
mOriginalAnchorRange = 0;
return NS_OK;
}
nsCOMPtr<nsIDOMRange> newRange;
nsresult result;
result = nsComponentManager::CreateInstance(kRangeCID, nsnull,
nsIDOMRange::GetIID(),
getter_AddRefs(newRange));
result = newRange->SetStart(aNode,aOffset);
if (NS_FAILED(result))
return result;
result = newRange->SetEnd(aNode,aOffset);
if (NS_FAILED(result))
return result;
mOriginalAnchorRange = newRange;
return result;
}
NS_IMETHODIMP
nsRangeList::GetOriginalAnchorPoint(nsIDOMNode **aNode, PRInt32 *aOffset)
{
if (!aNode || !aOffset || !mOriginalAnchorRange)
return NS_ERROR_NULL_POINTER;
nsresult result;
result = mOriginalAnchorRange->GetStartParent(aNode);
if (NS_FAILED(result))
return result;
result = mOriginalAnchorRange->GetStartOffset(aOffset);
return result;
}
/* /*
Notes which might come in handy for extend: Notes which might come in handy for extend:
@ -1358,6 +1755,7 @@ a 2 1 deselect from 2 to 1
2 1 a = continue selection from 2 to 1 2 1 a = continue selection from 2 to 1
*/ */
/* /*
* Extend extends the selection away from the anchor. * Extend extends the selection away from the anchor.
* We don't need to know the direction, because we always change the focus. * We don't need to know the direction, because we always change the focus.
@ -1376,171 +1774,242 @@ nsRangeList::Extend(nsIDOMNode* aParentNode, PRInt32 aOffset)
getter_AddRefs(difRange)); getter_AddRefs(difRange));
PRUint32 i; if (NS_FAILED(res))
PRBool found = PR_FALSE; return res;
PRUint32 cnt; nsCOMPtr<nsIDOMRange> range;
nsresult rv = mRangeArray->Count(&cnt); res = mAnchorFocusRange->Clone(getter_AddRefs(range));
if (NS_FAILED(rv)) return rv;
for (i = 0; i < cnt; i++)
{
nsCOMPtr<nsISupports> isupportsindex = dont_AddRef(mRangeArray->ElementAt(i));
nsCOMPtr<nsIDOMRange> range (do_QueryInterface(isupportsindex));
nsCOMPtr<nsIDOMNode> endNode; nsCOMPtr<nsIDOMNode> startNode;
PRInt32 endOffset; nsCOMPtr<nsIDOMNode> endNode;
nsCOMPtr<nsIDOMNode> startNode; PRInt32 startOffset;
PRInt32 startOffset; PRInt32 endOffset;
range->GetEndParent(getter_AddRefs(endNode));
range->GetEndOffset(&endOffset);
range->GetStartParent(getter_AddRefs(startNode));
range->GetStartOffset(&startOffset);
if ((FetchFocusNode() == endNode.get()) && (FetchFocusOffset() == endOffset))
{
found = PR_TRUE;
}
else if ((FetchFocusNode() == startNode.get()) && (FetchFocusOffset() == startOffset))
{
found = PR_TRUE;
}
if (found && !(FetchFocusNode() == aParentNode && FetchFocusOffset() == aOffset )){
res = nsComponentManager::CreateInstance(kRangeCID, nsnull,
nsIDOMRange::GetIID(),
getter_AddRefs(difRange));
range->GetStartParent(getter_AddRefs(startNode));
range->GetEndParent(getter_AddRefs(endNode));
range->GetStartOffset(&startOffset);
range->GetEndOffset(&endOffset);
nsDirection dir = GetDirection();
PRBool fixupState; //if there was a previous fixup the optimal drawing erasing will NOT work
if (NS_FAILED(res))
return res;
res = nsComponentManager::CreateInstance(kRangeCID, nsnull,
nsIDOMRange::GetIID(),
getter_AddRefs(difRange));
if (NS_FAILED(res))
return res;
//compare anchor to old cursor.
if (NS_FAILED(res))
return res;
PRInt32 result1 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset()
,FetchFocusNode(), FetchFocusOffset());
//compare old cursor to new cursor
PRInt32 result2 = ComparePoints(FetchFocusNode(), FetchFocusOffset(),
aParentNode, aOffset );
//compare anchor to new cursor
PRInt32 result3 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset(),
aParentNode , aOffset );
if ((result1 == 0 && result3 < 0) || (result1 <= 0 && result2 <= 0)){//a1,2 a,1,2
//select from 1 to 2
res = range->SetEnd(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
dir = eDirNext;
res = FixupSelectionPoints(range, &dir, &fixupState);
if (NS_FAILED(res))
return res;
if (fixupState) //unselect previous and select new state has changed to not fixed up
{
selectFrames(mAnchorFocusRange, PR_FALSE);
selectFrames(range, PR_TRUE);
}
else{
res = difRange->SetEnd(FetchEndParent(range), FetchEndOffset(range));
res |= difRange->SetStart(FetchFocusNode(), FetchFocusOffset());
if (NS_FAILED(res)) if (NS_FAILED(res))
return res; return res;
//compare anchor to old cursor. selectFrames(difRange , PR_TRUE);
if (NS_FAILED(res))
return res;
PRInt32 result1 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset()
,FetchFocusNode(), FetchFocusOffset());
//compare old cursor to new cursor
PRInt32 result2 = ComparePoints(FetchFocusNode(), FetchFocusOffset(),
aParentNode, aOffset );
//compare anchor to new cursor
PRInt32 result3 = ComparePoints(FetchAnchorNode(), FetchAnchorOffset(),
aParentNode , aOffset );
if ((result1 == 0 && result3 < 0) || (result1 <= 0 && result2 <= 0)){//a1,2 a,1,2
//select from 1 to 2
res = difRange->SetEnd(aParentNode, aOffset);
res |= difRange->SetStart(FetchFocusNode(), FetchFocusOffset());
if (NS_FAILED(res))
return res;
SetDirection(eDirNext);
res = range->SetEnd(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
selectFrames(difRange , PR_TRUE);
}
else if (result1 == 0 && result3 > 0){//2, a1
//select from 2 to 1
res = difRange->SetEnd(FetchFocusNode(), FetchFocusOffset());
res |= difRange->SetStart(aParentNode, aOffset);
if (NS_FAILED(res))
return res;
SetDirection(eDirPrevious);
res = range->SetStart(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
selectFrames(difRange , PR_TRUE);
}
else if (result3 <= 0 && result2 >= 0) {//a,2,1 or a2,1 or a,21 or a21
//deselect from 2 to 1
res = difRange->SetEnd(FetchFocusNode(), FetchFocusOffset());
res |= difRange->SetStart(aParentNode, aOffset);
if (NS_FAILED(res))
return res;
SetDirection(eDirNext);
res = range->SetEnd(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
selectFrames(difRange, 0);
difRange->SetEnd(aParentNode,aOffset);
selectFrames(difRange, PR_TRUE);//must reselect last node
}
else if (result1 >= 0 && result3 <= 0) {//1,a,2 or 1a,2 or 1,a2 or 1a2
if (FetchFocusNode() != FetchAnchorNode() || FetchFocusOffset() != FetchAnchorOffset() ){//if collapsed diff dont do anything
res = difRange->SetStart(FetchFocusNode(), FetchFocusOffset());
res |= difRange->SetEnd(FetchAnchorNode(), FetchAnchorOffset());
if (NS_FAILED(res))
return res;
//deselect from 1 to a
selectFrames(difRange , PR_FALSE);
}
//select from a to 2
res = difRange->SetEnd(aParentNode, aOffset);
res |= difRange->SetStart(FetchAnchorNode(), FetchAnchorOffset());
if (NS_FAILED(res))
return res;
if (GetDirection() == eDirPrevious){
res = range->SetStart(endNode,endOffset);
if (NS_FAILED(res))
return res;
}
SetDirection(eDirNext);
res = range->SetEnd(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
selectFrames(difRange , PR_TRUE);
}
else if (result2 <= 0 && result3 >= 0) {//1,2,a or 12,a or 1,2a or 12a
//deselect from 1 to 2
res = difRange->SetEnd(aParentNode, aOffset);
res |= difRange->SetStart(FetchFocusNode(), FetchFocusOffset());
if (NS_FAILED(res))
return res;
SetDirection(eDirPrevious);
res = range->SetStart(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
selectFrames(difRange , PR_FALSE);
difRange->SetStart(aParentNode,aOffset);
selectFrames(difRange, PR_TRUE);//must reselect last node
}
else if (result3 >= 0 && result1 <= 0) {//2,a,1 or 2a,1 or 2,a1 or 2a1
//deselect from a to 1
if (FetchFocusNode() != FetchAnchorNode() || FetchFocusOffset() != FetchAnchorOffset() ){//if collapsed diff dont do anything
res = difRange->SetStart(FetchAnchorNode(), FetchAnchorOffset());
res |= difRange->SetEnd(FetchFocusNode(), FetchFocusOffset());
selectFrames(difRange, 0);
}
//select from 2 to a
res = difRange->SetEnd(FetchAnchorNode(), FetchAnchorOffset());
res |= difRange->SetStart(aParentNode, aOffset);
if (NS_FAILED(res))
return res;
if (GetDirection() == eDirNext){
range->SetEnd(startNode,startOffset);
}
SetDirection(eDirPrevious);
res = range->SetStart(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
selectFrames(difRange , PR_TRUE);
}
else if (result2 >= 0 && result1 >= 0) {//2,1,a or 21,a or 2,1a or 21a
//select from 2 to 1
res = difRange->SetEnd(FetchFocusNode(), FetchFocusOffset());
res |= difRange->SetStart(aParentNode, aOffset);
SetDirection(eDirPrevious);
res = range->SetStart(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
selectFrames(difRange, PR_TRUE);
}
setAnchorFocusRange(i);
DEBUG_OUT_RANGE(range);
ScrollIntoView();
return NotifySelectionListeners();
} }
} }
else if (result1 == 0 && result3 > 0){//2, a1
return NS_OK; //select from 2 to 1a
dir = eDirPrevious;
res = range->SetStart(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
res = FixupSelectionPoints(range, &dir, &fixupState);
if (NS_FAILED(res))
return res;
if (fixupState) //unselect previous and select new state has changed to not fixed up
{
selectFrames(mAnchorFocusRange, PR_FALSE);
selectFrames(range, PR_TRUE);
}
else
selectFrames(range, PR_TRUE);
}
else if (result3 <= 0 && result2 >= 0) {//a,2,1 or a2,1 or a,21 or a21
//deselect from 2 to 1
res = difRange->SetEnd(FetchFocusNode(), FetchFocusOffset());
res |= difRange->SetStart(aParentNode, aOffset);
if (NS_FAILED(res))
return res;
dir = eDirNext;
res = range->SetEnd(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
res = FixupSelectionPoints(range, &dir, &fixupState);
if (NS_FAILED(res))
return res;
if (fixupState) //unselect previous and select new state has changed to not fixed up
{
selectFrames(mAnchorFocusRange, PR_FALSE);
selectFrames(range, PR_TRUE);
}
else {
selectFrames(difRange, 0);//deselect now if fixup succeeded
difRange->SetEnd(FetchEndParent(range),FetchEndOffset(range));
selectFrames(difRange, PR_TRUE);//must reselect last node maybe more if fixup did something
}
}
else if (result1 >= 0 && result3 <= 0) {//1,a,2 or 1a,2 or 1,a2 or 1a2
if (GetDirection() == eDirPrevious){
res = range->SetStart(endNode,endOffset);
if (NS_FAILED(res))
return res;
}
dir = eDirNext;
res = range->SetEnd(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
res = FixupSelectionPoints(range, &dir, &fixupState);
if (NS_FAILED(res))
return res;
if (fixupState) //unselect previous and select new state has changed to not fixed up
{
selectFrames(mAnchorFocusRange, PR_FALSE);
selectFrames(range, PR_TRUE);
}
else {
if (FetchFocusNode() != FetchAnchorNode() || FetchFocusOffset() != FetchAnchorOffset() ){//if collapsed diff dont do anything
res = difRange->SetStart(FetchFocusNode(), FetchFocusOffset());
res |= difRange->SetEnd(FetchAnchorNode(), FetchAnchorOffset());
if (NS_FAILED(res))
return res;
//deselect from 1 to a
selectFrames(difRange , PR_FALSE);
}
//select from a to 2
selectFrames(range , PR_TRUE);
}
}
else if (result2 <= 0 && result3 >= 0) {//1,2,a or 12,a or 1,2a or 12a
//deselect from 1 to 2
res = difRange->SetEnd(aParentNode, aOffset);
res |= difRange->SetStart(FetchFocusNode(), FetchFocusOffset());
if (NS_FAILED(res))
return res;
dir = eDirPrevious;
res = range->SetStart(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
res = FixupSelectionPoints(range, &dir, &fixupState);
if (NS_FAILED(res))
return res;
if (fixupState) //unselect previous and select new state has changed to not fixed up
{
selectFrames(mAnchorFocusRange, PR_FALSE);
selectFrames(range, PR_TRUE);
}
else {
selectFrames(difRange , PR_FALSE);
difRange->SetStart(FetchStartParent(range),FetchStartOffset(range));
selectFrames(difRange, PR_TRUE);//must reselect last node
}
}
else if (result3 >= 0 && result1 <= 0) {//2,a,1 or 2a,1 or 2,a1 or 2a1
if (GetDirection() == eDirNext){
range->SetEnd(startNode,startOffset);
}
dir = eDirPrevious;
res = range->SetStart(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
res = FixupSelectionPoints(range, &dir, &fixupState);
if (NS_FAILED(res))
return res;
if (fixupState) //unselect previous and select new state has changed to not fixed up
{
selectFrames(mAnchorFocusRange, PR_FALSE);
selectFrames(range, PR_TRUE);
}
else
{
//deselect from a to 1
if (FetchFocusNode() != FetchAnchorNode() || FetchFocusOffset() != FetchAnchorOffset() ){//if collapsed diff dont do anything
res = difRange->SetStart(FetchAnchorNode(), FetchAnchorOffset());
res |= difRange->SetEnd(FetchFocusNode(), FetchFocusOffset());
selectFrames(difRange, 0);
}
//select from 2 to a
selectFrames(range , PR_TRUE);
}
}
else if (result2 >= 0 && result1 >= 0) {//2,1,a or 21,a or 2,1a or 21a
//select from 2 to 1
res = range->SetStart(aParentNode,aOffset);
if (NS_FAILED(res))
return res;
dir = eDirPrevious;
res = FixupSelectionPoints(range, &dir, &fixupState);
if (NS_FAILED(res))
return res;
if (fixupState) //unselect previous and select new state has changed to not fixed up
{
selectFrames(mAnchorFocusRange, PR_FALSE);
selectFrames(range, PR_TRUE);
}
else {
res = difRange->SetEnd(FetchFocusNode(), FetchFocusOffset());
res |= difRange->SetStart(FetchStartParent(range), FetchStartOffset(range));
if (NS_FAILED(res))
return res;
selectFrames(difRange, PR_TRUE);
}
}
DEBUG_OUT_RANGE(range);
//DEBUG
if (eDirNext == mDirection)
printf(" direction = 1 LEFT TO RIGHT\n");
else
printf(" direction = 0 RIGHT TO LEFT\n");
//ENDDEBUG
SetDirection(dir);
/*hack*/
range->GetStartParent(getter_AddRefs(startNode));
range->GetEndParent(getter_AddRefs(endNode));
range->GetStartOffset(&startOffset);
range->GetEndOffset(&endOffset);
if (NS_FAILED(mAnchorFocusRange->SetStart(startNode,startOffset)))
{
if (NS_FAILED(mAnchorFocusRange->SetEnd(endNode,endOffset)))
return NS_ERROR_FAILURE;//???
if (NS_FAILED(mAnchorFocusRange->SetStart(startNode,startOffset)))
return NS_ERROR_FAILURE;//???
}
else if (NS_FAILED(mAnchorFocusRange->SetEnd(endNode,endOffset)))
return NS_ERROR_FAILURE;//???
/*end hack*/
ScrollIntoView();
return NotifySelectionListeners();
} }

View File

@ -1481,6 +1481,22 @@ nsFrame::XMLQuote(nsString& aString)
} }
} }
PRBool
nsFrame::ParentDisablesSelection() const
{
PRBool selected;
if (NS_FAILED(GetSelected(&selected)))
return PR_FALSE;
if (selected)
return PR_FALSE; //if this frame is selected and no one has overridden the selection from "higher up"
//then no one below us will be disabled by this frame.
nsIFrame* target;
GetParent(&target);
if (target)
return ((nsFrame *)target)->ParentDisablesSelection();
return PR_FALSE; //default this does not happen
}
NS_IMETHODIMP NS_IMETHODIMP
nsFrame::DumpRegressionData(FILE* out, PRInt32 aIndent) nsFrame::DumpRegressionData(FILE* out, PRInt32 aIndent)
{ {
@ -1570,17 +1586,22 @@ nsFrame::VerifyTree() const
NS_IMETHODIMP NS_IMETHODIMP
nsFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread) nsFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
{ {
if (aSelected && ParentDisablesSelection())
return NS_OK;
if (eSpreadDown == aSpread){ if (eSpreadDown == aSpread){
nsIFrame* kid; nsIFrame* kid;
nsresult rv = FirstChild(nsnull, &kid); nsresult rv = FirstChild(nsnull, &kid);
while (nsnull != kid) { while (nsnull != kid) {
kid->SetSelected(nsnull,PR_FALSE,aSpread); kid->SetSelected(nsnull,aSelected,aSpread);
kid->GetNextSibling(&kid); kid->GetNextSibling(&kid);
} }
} }
nsFrameState frameState; nsFrameState frameState;
GetFrameState(&frameState); GetFrameState(&frameState);
if (aSelected == frameState & NS_FRAME_SELECTED_CONTENT) //allready set thanks
{
return NS_OK;
}
if ( aSelected ){ if ( aSelected ){
frameState |= NS_FRAME_SELECTED_CONTENT; frameState |= NS_FRAME_SELECTED_CONTENT;
} }

View File

@ -338,6 +338,8 @@ protected:
static void XMLQuote(nsString& aString); static void XMLQuote(nsString& aString);
virtual PRBool ParentDisablesSelection() const;
// Set the clip rect into the rendering-context after applying CSS's // Set the clip rect into the rendering-context after applying CSS's
// clip property. This method assumes that the caller has checked // clip property. This method assumes that the caller has checked
// that the clip property applies to its situation. // that the clip property applies to its situation.

View File

@ -1813,7 +1813,10 @@ NS_IMETHODIMP
nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread) nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
{ {
nsresult result; nsresult result;
if (eSpreadAcross == aSpread){ if (aSelected && ParentDisablesSelection())
return NS_OK;
if (aSpread == eSpreadDown)
{
nsIFrame *frame = GetPrevInFlow(); nsIFrame *frame = GetPrevInFlow();
while(frame){ while(frame){
frame->SetSelected(aRange,aSelected,eSpreadNone); frame->SetSelected(aRange,aSelected,eSpreadNone);
@ -1831,10 +1834,10 @@ nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
} }
nsFrameState frameState; nsFrameState frameState;
GetFrameState(&frameState); GetFrameState(&frameState);
if ( aSelected ) if (aSelected == frameState & NS_FRAME_SELECTED_CONTENT) //allready set thanks
frameState |= NS_FRAME_SELECTED_CONTENT; {
else return NS_OK;
frameState &= ~NS_FRAME_SELECTED_CONTENT; }
PRBool found = PR_FALSE; PRBool found = PR_FALSE;
if (aRange) { if (aRange) {
@ -1881,6 +1884,10 @@ nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
} }
} }
if ( aSelected )
frameState |= NS_FRAME_SELECTED_CONTENT;
else
frameState &= ~NS_FRAME_SELECTED_CONTENT;
SetFrameState(frameState); SetFrameState(frameState);
if (found){ //if range contains this frame... if (found){ //if range contains this frame...
nsRect frameRect; nsRect frameRect;

View File

@ -1481,6 +1481,22 @@ nsFrame::XMLQuote(nsString& aString)
} }
} }
PRBool
nsFrame::ParentDisablesSelection() const
{
PRBool selected;
if (NS_FAILED(GetSelected(&selected)))
return PR_FALSE;
if (selected)
return PR_FALSE; //if this frame is selected and no one has overridden the selection from "higher up"
//then no one below us will be disabled by this frame.
nsIFrame* target;
GetParent(&target);
if (target)
return ((nsFrame *)target)->ParentDisablesSelection();
return PR_FALSE; //default this does not happen
}
NS_IMETHODIMP NS_IMETHODIMP
nsFrame::DumpRegressionData(FILE* out, PRInt32 aIndent) nsFrame::DumpRegressionData(FILE* out, PRInt32 aIndent)
{ {
@ -1570,17 +1586,22 @@ nsFrame::VerifyTree() const
NS_IMETHODIMP NS_IMETHODIMP
nsFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread) nsFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
{ {
if (aSelected && ParentDisablesSelection())
return NS_OK;
if (eSpreadDown == aSpread){ if (eSpreadDown == aSpread){
nsIFrame* kid; nsIFrame* kid;
nsresult rv = FirstChild(nsnull, &kid); nsresult rv = FirstChild(nsnull, &kid);
while (nsnull != kid) { while (nsnull != kid) {
kid->SetSelected(nsnull,PR_FALSE,aSpread); kid->SetSelected(nsnull,aSelected,aSpread);
kid->GetNextSibling(&kid); kid->GetNextSibling(&kid);
} }
} }
nsFrameState frameState; nsFrameState frameState;
GetFrameState(&frameState); GetFrameState(&frameState);
if (aSelected == frameState & NS_FRAME_SELECTED_CONTENT) //allready set thanks
{
return NS_OK;
}
if ( aSelected ){ if ( aSelected ){
frameState |= NS_FRAME_SELECTED_CONTENT; frameState |= NS_FRAME_SELECTED_CONTENT;
} }

View File

@ -338,6 +338,8 @@ protected:
static void XMLQuote(nsString& aString); static void XMLQuote(nsString& aString);
virtual PRBool ParentDisablesSelection() const;
// Set the clip rect into the rendering-context after applying CSS's // Set the clip rect into the rendering-context after applying CSS's
// clip property. This method assumes that the caller has checked // clip property. This method assumes that the caller has checked
// that the clip property applies to its situation. // that the clip property applies to its situation.

View File

@ -1813,7 +1813,10 @@ NS_IMETHODIMP
nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread) nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
{ {
nsresult result; nsresult result;
if (eSpreadAcross == aSpread){ if (aSelected && ParentDisablesSelection())
return NS_OK;
if (aSpread == eSpreadDown)
{
nsIFrame *frame = GetPrevInFlow(); nsIFrame *frame = GetPrevInFlow();
while(frame){ while(frame){
frame->SetSelected(aRange,aSelected,eSpreadNone); frame->SetSelected(aRange,aSelected,eSpreadNone);
@ -1831,10 +1834,10 @@ nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
} }
nsFrameState frameState; nsFrameState frameState;
GetFrameState(&frameState); GetFrameState(&frameState);
if ( aSelected ) if (aSelected == frameState & NS_FRAME_SELECTED_CONTENT) //allready set thanks
frameState |= NS_FRAME_SELECTED_CONTENT; {
else return NS_OK;
frameState &= ~NS_FRAME_SELECTED_CONTENT; }
PRBool found = PR_FALSE; PRBool found = PR_FALSE;
if (aRange) { if (aRange) {
@ -1881,6 +1884,10 @@ nsTextFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
} }
} }
if ( aSelected )
frameState |= NS_FRAME_SELECTED_CONTENT;
else
frameState &= ~NS_FRAME_SELECTED_CONTENT;
SetFrameState(frameState); SetFrameState(frameState);
if (found){ //if range contains this frame... if (found){ //if range contains this frame...
nsRect frameRect; nsRect frameRect;

View File

@ -204,7 +204,27 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext,
PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
aRenderingContext.PopState(clipState); aRenderingContext.PopState(clipState);
return NS_OK; return nsFrame::Paint(aPresContext,
aRenderingContext,
aDirtyRect,
aWhichLayer);
}
//null range means the whole thing
NS_IMETHODIMP
nsTableCellFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
{
//traverse through children unselect tables
if ((aSpread == eSpreadDown) && aSelected){
nsIFrame* kid;
nsresult rv = FirstChild(nsnull, &kid);
while (nsnull != kid) {
kid->SetSelected(nsnull,PR_FALSE,eSpreadDown);
kid->GetNextSibling(&kid);
}
}
return nsFrame::SetSelected(aRange,aSelected,eSpreadNone);
} }
PRIntn PRIntn
@ -220,6 +240,16 @@ nsTableCellFrame::GetSkipSides() const
return skip; return skip;
} }
PRBool nsTableCellFrame::ParentDisablesSelection() const //override default behavior
{
PRBool returnval;
if (NS_FAILED(GetSelected(&returnval)))
return PR_FALSE;
if (returnval)
return PR_TRUE;
return nsFrame::ParentDisablesSelection();
}
void nsTableCellFrame::SetBorderEdge(PRUint8 aSide, void nsTableCellFrame::SetBorderEdge(PRUint8 aSide,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex, PRInt32 aColIndex,

View File

@ -80,6 +80,8 @@ public:
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer); nsFramePaintLayer aWhichLayer);
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread);
NS_IMETHOD Reflow(nsIPresContext& aPresContext, NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
@ -170,6 +172,8 @@ protected:
/** implement abstract method on nsHTMLContainerFrame */ /** implement abstract method on nsHTMLContainerFrame */
virtual PRIntn GetSkipSides() const; virtual PRIntn GetSkipSides() const;
virtual PRBool ParentDisablesSelection() const; //override default behavior
private: private:
// All these methods are support methods for RecalcLayoutData // All these methods are support methods for RecalcLayoutData

View File

@ -2320,7 +2320,7 @@ NS_IMETHODIMP
nsTableFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread) nsTableFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
{ {
//traverse through children unselect tables //traverse through children unselect tables
if ((aSpread == eSpreadAcross) && aSelected){ if ((aSpread == eSpreadDown) && aSelected){
nsIFrame* kid; nsIFrame* kid;
nsresult rv = FirstChild(nsnull, &kid); nsresult rv = FirstChild(nsnull, &kid);
while (nsnull != kid) { while (nsnull != kid) {
@ -2329,9 +2329,18 @@ nsTableFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread
kid->GetNextSibling(&kid); kid->GetNextSibling(&kid);
} }
} }
return nsFrame::SetSelected(aRange,aSelected,aSpread); return nsFrame::SetSelected(aRange,aSelected,eSpreadNone);
} }
PRBool nsTableFrame::ParentDisablesSelection() const //override default behavior
{
PRBool returnval;
if (NS_FAILED(GetSelected(&returnval)))
return PR_FALSE;
if (returnval)
return PR_TRUE;
return nsFrame::ParentDisablesSelection();
}
PRIntn PRIntn
nsTableFrame::GetSkipSides() const nsTableFrame::GetSkipSides() const

View File

@ -429,6 +429,8 @@ protected:
/** implement abstract method on nsHTMLContainerFrame */ /** implement abstract method on nsHTMLContainerFrame */
virtual PRIntn GetSkipSides() const; virtual PRIntn GetSkipSides() const;
virtual PRBool ParentDisablesSelection() const; //override default behavior
/** first pass of ResizeReflow. /** first pass of ResizeReflow.
* lays out all table content with aMaxSize(NS_UNCONSTRAINEDSIZE,NS_UNCONSTRAINEDSIZE) and * lays out all table content with aMaxSize(NS_UNCONSTRAINEDSIZE,NS_UNCONSTRAINEDSIZE) and
* a non-null aMaxElementSize so we get all the metrics we need to do column balancing. * a non-null aMaxElementSize so we get all the metrics we need to do column balancing.

View File

@ -204,7 +204,27 @@ NS_METHOD nsTableCellFrame::Paint(nsIPresContext& aPresContext,
PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer); PaintChildren(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
aRenderingContext.PopState(clipState); aRenderingContext.PopState(clipState);
return NS_OK; return nsFrame::Paint(aPresContext,
aRenderingContext,
aDirtyRect,
aWhichLayer);
}
//null range means the whole thing
NS_IMETHODIMP
nsTableCellFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
{
//traverse through children unselect tables
if ((aSpread == eSpreadDown) && aSelected){
nsIFrame* kid;
nsresult rv = FirstChild(nsnull, &kid);
while (nsnull != kid) {
kid->SetSelected(nsnull,PR_FALSE,eSpreadDown);
kid->GetNextSibling(&kid);
}
}
return nsFrame::SetSelected(aRange,aSelected,eSpreadNone);
} }
PRIntn PRIntn
@ -220,6 +240,16 @@ nsTableCellFrame::GetSkipSides() const
return skip; return skip;
} }
PRBool nsTableCellFrame::ParentDisablesSelection() const //override default behavior
{
PRBool returnval;
if (NS_FAILED(GetSelected(&returnval)))
return PR_FALSE;
if (returnval)
return PR_TRUE;
return nsFrame::ParentDisablesSelection();
}
void nsTableCellFrame::SetBorderEdge(PRUint8 aSide, void nsTableCellFrame::SetBorderEdge(PRUint8 aSide,
PRInt32 aRowIndex, PRInt32 aRowIndex,
PRInt32 aColIndex, PRInt32 aColIndex,

View File

@ -80,6 +80,8 @@ public:
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer); nsFramePaintLayer aWhichLayer);
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread);
NS_IMETHOD Reflow(nsIPresContext& aPresContext, NS_IMETHOD Reflow(nsIPresContext& aPresContext,
nsHTMLReflowMetrics& aDesiredSize, nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState, const nsHTMLReflowState& aReflowState,
@ -170,6 +172,8 @@ protected:
/** implement abstract method on nsHTMLContainerFrame */ /** implement abstract method on nsHTMLContainerFrame */
virtual PRIntn GetSkipSides() const; virtual PRIntn GetSkipSides() const;
virtual PRBool ParentDisablesSelection() const; //override default behavior
private: private:
// All these methods are support methods for RecalcLayoutData // All these methods are support methods for RecalcLayoutData

View File

@ -2320,7 +2320,7 @@ NS_IMETHODIMP
nsTableFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread) nsTableFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread)
{ {
//traverse through children unselect tables //traverse through children unselect tables
if ((aSpread == eSpreadAcross) && aSelected){ if ((aSpread == eSpreadDown) && aSelected){
nsIFrame* kid; nsIFrame* kid;
nsresult rv = FirstChild(nsnull, &kid); nsresult rv = FirstChild(nsnull, &kid);
while (nsnull != kid) { while (nsnull != kid) {
@ -2329,9 +2329,18 @@ nsTableFrame::SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread
kid->GetNextSibling(&kid); kid->GetNextSibling(&kid);
} }
} }
return nsFrame::SetSelected(aRange,aSelected,aSpread); return nsFrame::SetSelected(aRange,aSelected,eSpreadNone);
} }
PRBool nsTableFrame::ParentDisablesSelection() const //override default behavior
{
PRBool returnval;
if (NS_FAILED(GetSelected(&returnval)))
return PR_FALSE;
if (returnval)
return PR_TRUE;
return nsFrame::ParentDisablesSelection();
}
PRIntn PRIntn
nsTableFrame::GetSkipSides() const nsTableFrame::GetSkipSides() const

View File

@ -429,6 +429,8 @@ protected:
/** implement abstract method on nsHTMLContainerFrame */ /** implement abstract method on nsHTMLContainerFrame */
virtual PRIntn GetSkipSides() const; virtual PRIntn GetSkipSides() const;
virtual PRBool ParentDisablesSelection() const; //override default behavior
/** first pass of ResizeReflow. /** first pass of ResizeReflow.
* lays out all table content with aMaxSize(NS_UNCONSTRAINEDSIZE,NS_UNCONSTRAINEDSIZE) and * lays out all table content with aMaxSize(NS_UNCONSTRAINEDSIZE,NS_UNCONSTRAINEDSIZE) and
* a non-null aMaxElementSize so we get all the metrics we need to do column balancing. * a non-null aMaxElementSize so we get all the metrics we need to do column balancing.