зеркало из https://github.com/mozilla/gecko-dev.git
Bug 371839. Simplify SetSelected signature and semantics, and reimplement it in nsTextFrame much more efficiently. r=bzbarsky
--HG-- extra : rebase_source : 18c390e3ebd09de82b1a23699c56b741f928ca37
This commit is contained in:
Родитель
36956c156b
Коммит
8bab94a96a
|
@ -43,15 +43,7 @@
|
|||
#ifndef nsGenericDOMDataNode_h___
|
||||
#define nsGenericDOMDataNode_h___
|
||||
|
||||
// This bit is set to indicate that if the text node changes to
|
||||
// non-whitespace, we may need to create a frame for it. This bit must
|
||||
// not be set on nodes that already have a frame.
|
||||
#define NS_CREATE_FRAME_IF_NON_WHITESPACE (1 << NODE_TYPE_SPECIFIC_BITS_OFFSET)
|
||||
|
||||
// This bit is set to indicate that if the text node changes to
|
||||
// whitespace, we may need to reframe it (or its ancestors).
|
||||
#define NS_REFRAME_IF_WHITESPACE (1 << (NODE_TYPE_SPECIFIC_BITS_OFFSET + 1))
|
||||
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDOMCharacterData.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIDOM3Text.h"
|
||||
|
@ -66,6 +58,18 @@
|
|||
#include "nsISMILAttr.h"
|
||||
#endif // MOZ_SMIL
|
||||
|
||||
// This bit is set to indicate that if the text node changes to
|
||||
// non-whitespace, we may need to create a frame for it. This bit must
|
||||
// not be set on nodes that already have a frame.
|
||||
#define NS_CREATE_FRAME_IF_NON_WHITESPACE (1 << NODE_TYPE_SPECIFIC_BITS_OFFSET)
|
||||
|
||||
// This bit is set to indicate that if the text node changes to
|
||||
// whitespace, we may need to reframe it (or its ancestors).
|
||||
#define NS_REFRAME_IF_WHITESPACE (1 << (NODE_TYPE_SPECIFIC_BITS_OFFSET + 1))
|
||||
|
||||
// This bit is set to indicate that the text may be part of a selection.
|
||||
#define NS_TEXT_IN_SELECTION (1 << (NODE_TYPE_SPECIFIC_BITS_OFFSET + 2))
|
||||
|
||||
class nsIDOMAttr;
|
||||
class nsIDOMEventListener;
|
||||
class nsIDOMNodeList;
|
||||
|
|
|
@ -110,21 +110,6 @@ nsFirstLetterFrame::SetInitialChildList(nsIAtom* aListName,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFirstLetterFrame::SetSelected(nsPresContext* aPresContext, nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread, SelectionType aType)
|
||||
{
|
||||
if (aSelected && ParentDisablesSelection())
|
||||
return NS_OK;
|
||||
nsIFrame *child = GetFirstChild(nsnull);
|
||||
while (child)
|
||||
{
|
||||
child->SetSelected(aPresContext, aRange, aSelected, aSpread, aType);
|
||||
// don't worry about result. there are more frames to come
|
||||
child = child->GetNextSibling();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFirstLetterFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
|
||||
PRBool inHint,
|
||||
|
|
|
@ -83,8 +83,6 @@ public:
|
|||
|
||||
virtual PRBool CanContinueTextRun() const;
|
||||
|
||||
NS_IMETHOD SetSelected(nsPresContext* aPresContext, nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread, SelectionType aType);
|
||||
|
||||
//override of nsFrame method
|
||||
NS_IMETHOD GetChildFrameContainingOffset(PRInt32 inContentOffset,
|
||||
PRBool inHint,
|
||||
|
|
|
@ -4487,43 +4487,30 @@ nsFrame::DumpBaseRegressionData(nsPresContext* aPresContext, FILE* out, PRInt32
|
|||
}
|
||||
#endif
|
||||
|
||||
/*this method may.. invalidate if the state was changed or if aForceRedraw is PR_TRUE
|
||||
it will not update immediately.*/
|
||||
NS_IMETHODIMP
|
||||
nsFrame::SetSelected(nsPresContext* aPresContext, nsIDOMRange *aRange, PRBool aSelected, nsSpread aSpread, SelectionType aType)
|
||||
void
|
||||
nsIFrame::SetSelected(PRBool aSelected, SelectionType aType)
|
||||
{
|
||||
/*
|
||||
if (aSelected && ParentDisablesSelection())
|
||||
return NS_OK;
|
||||
*/
|
||||
NS_ASSERTION(!GetPrevContinuation(),
|
||||
"Should only be called on first in flow");
|
||||
if (aType != nsISelectionController::SELECTION_NORMAL)
|
||||
return;
|
||||
|
||||
if (aType == nsISelectionController::SELECTION_NORMAL) {
|
||||
// check whether style allows selection
|
||||
PRBool selectable;
|
||||
IsSelectable(&selectable, nsnull);
|
||||
if (!selectable)
|
||||
return NS_OK;
|
||||
}
|
||||
// check whether style allows selection
|
||||
PRBool selectable;
|
||||
IsSelectable(&selectable, nsnull);
|
||||
if (!selectable)
|
||||
return;
|
||||
|
||||
/*
|
||||
if (eSpreadDown == aSpread){
|
||||
nsIFrame* kid = GetFirstChild(nsnull);
|
||||
while (nsnull != kid) {
|
||||
kid->SetSelected(nsnull,aSelected,aSpread);
|
||||
kid = kid->GetNextSibling();
|
||||
for (nsIFrame* f = this; f; f = f->GetNextContinuation()) {
|
||||
if (aSelected) {
|
||||
AddStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
} else {
|
||||
RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
}
|
||||
}
|
||||
*/
|
||||
if ( aSelected ){
|
||||
AddStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
}
|
||||
else
|
||||
RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
|
||||
// Repaint this frame subtree's entire area
|
||||
InvalidateOverflowRect();
|
||||
|
||||
return NS_OK;
|
||||
// Repaint this frame subtree's entire area
|
||||
InvalidateOverflowRect();
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -237,7 +237,6 @@ public:
|
|||
NS_IMETHOD DumpRegressionData(nsPresContext* aPresContext, FILE* out, PRInt32 aIndent);
|
||||
#endif
|
||||
|
||||
NS_IMETHOD SetSelected(nsPresContext* aPresContext, nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread, SelectionType aType);
|
||||
NS_IMETHOD GetSelected(PRBool *aSelected) const;
|
||||
NS_IMETHOD IsSelectable(PRBool* aIsSelectable, PRUint8* aSelectStyle) const;
|
||||
|
||||
|
|
|
@ -1887,19 +1887,20 @@ public:
|
|||
/** Selection related calls
|
||||
*/
|
||||
/**
|
||||
* 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 aRange is the range that will dictate if the frames need to be redrawn null means the whole content needs to be redrawn
|
||||
* Called to set the selection status of the frame.
|
||||
*
|
||||
* This must be called on the primary frame, but all continuations
|
||||
* will be affected the same way.
|
||||
*
|
||||
* This sets or clears NS_FRAME_SELECTED_CONTENT for each frame in the
|
||||
* continuation chain, if the frames are currently selectable.
|
||||
* The frames are unconditionally invalidated, if this selection type
|
||||
* is supported at all.
|
||||
* @param aSelected is it selected?
|
||||
* @param aSpread should it spread the selection to flow elements around it? or go down to its children?
|
||||
* @param aType the selection type of the selection that you are setting on the frame
|
||||
*/
|
||||
NS_IMETHOD SetSelected(nsPresContext* aPresContext,
|
||||
nsIDOMRange* aRange,
|
||||
PRBool aSelected,
|
||||
nsSpread aSpread,
|
||||
SelectionType aType) = 0;
|
||||
virtual void SetSelected(PRBool aSelected,
|
||||
SelectionType aType);
|
||||
|
||||
NS_IMETHOD GetSelected(PRBool *aSelected) const = 0;
|
||||
|
||||
|
|
|
@ -79,6 +79,7 @@
|
|||
#include "nsLayoutCID.h"
|
||||
#include "nsBidiPresUtils.h"
|
||||
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
|
||||
#include "nsTextFrame.h"
|
||||
|
||||
#include "nsIDOMText.h"
|
||||
|
||||
|
@ -301,7 +302,9 @@ private:
|
|||
void setAnchorFocusRange(PRInt32 aIndex); // pass in index into mRanges;
|
||||
// negative value clears
|
||||
// mAnchorFocusRange
|
||||
nsresult selectFrames(nsPresContext* aPresContext, nsIContentIterator *aInnerIter, nsIContent *aContent, nsIPresShell *aPresShell, PRBool aFlags);
|
||||
nsresult SelectAllFramesForContent(nsIContentIterator *aInnerIter,
|
||||
nsIContent *aContent,
|
||||
PRBool aSelected);
|
||||
nsresult selectFrames(nsPresContext* aPresContext, nsIRange *aRange, PRBool aSelect);
|
||||
nsresult getTableCellLocationFromRange(nsIRange *aRange, PRInt32 *aSelectionType, PRInt32 *aRow, PRInt32 *aCol);
|
||||
nsresult addTableCellRange(nsIRange *aRange, PRBool *aDidAddRange, PRInt32 *aOutIndex);
|
||||
|
@ -4177,15 +4180,11 @@ nsTypedSelection::GetPrimaryFrameForFocusNode(nsIFrame **aReturnFrame, PRInt32 *
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//select all content children of aContent
|
||||
nsresult
|
||||
nsTypedSelection::selectFrames(nsPresContext* aPresContext,
|
||||
nsIContentIterator *aInnerIter,
|
||||
nsIContent *aContent,
|
||||
nsIPresShell *aPresShell,
|
||||
PRBool aFlags)
|
||||
nsTypedSelection::SelectAllFramesForContent(nsIContentIterator *aInnerIter,
|
||||
nsIContent *aContent,
|
||||
PRBool aSelected)
|
||||
{
|
||||
if (!mFrameSelection)
|
||||
return NS_OK;//nothing to do
|
||||
|
@ -4200,8 +4199,7 @@ nsTypedSelection::selectFrames(nsPresContext* aPresContext,
|
|||
frame = mFrameSelection->GetShell()->GetPrimaryFrameFor(aContent);
|
||||
if (frame)
|
||||
{
|
||||
//NOTE: eSpreadDown is now IGNORED. Selected state is set only for given frame
|
||||
frame->SetSelected(aPresContext, nsnull, aFlags, eSpreadDown, mType);
|
||||
frame->SetSelected(aSelected, mType);
|
||||
if (mFrameSelection->GetTableCellSelection())
|
||||
{
|
||||
nsITableCellLayout *tcl = do_QueryFrame(frame);
|
||||
|
@ -4220,29 +4218,7 @@ nsTypedSelection::selectFrames(nsPresContext* aPresContext,
|
|||
frame = mFrameSelection->GetShell()->GetPrimaryFrameFor(innercontent);
|
||||
if (frame)
|
||||
{
|
||||
//NOTE: eSpreadDown is now IGNORED. Selected state is set only
|
||||
//for given frame
|
||||
|
||||
//spread from here to hit all frames in flow
|
||||
frame->SetSelected(aPresContext, nsnull, aFlags, eSpreadDown, mType);
|
||||
nsRect frameRect = frame->GetRect();
|
||||
|
||||
//if a rect is 0 height/width then try to notify next
|
||||
//available in flow of selection status.
|
||||
while (!frameRect.width || !frameRect.height)
|
||||
{
|
||||
//try to notify next in flow that its content is selected.
|
||||
frame = frame->GetNextInFlow();
|
||||
if (frame)
|
||||
{
|
||||
frameRect = frame->GetRect();
|
||||
frame->SetSelected(aPresContext, nsnull, aFlags, eSpreadDown, mType);
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
//if the frame is splittable and this frame is 0,0 then set
|
||||
//the next in flow frame to be selected also
|
||||
frame->SetSelected(aSelected, mType);
|
||||
}
|
||||
|
||||
aInnerIter->Next();
|
||||
|
@ -4292,11 +4268,23 @@ nsTypedSelection::selectFrames(nsPresContext* aPresContext, nsIRange *aRange, PR
|
|||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsIFrame *frame;
|
||||
if (!content->IsNodeOfType(nsINode::eELEMENT))
|
||||
if (content->IsNodeOfType(nsINode::eTEXT))
|
||||
{
|
||||
frame = mFrameSelection->GetShell()->GetPrimaryFrameFor(content);
|
||||
if (frame)
|
||||
frame->SetSelected(aPresContext, domRange, aFlags, eSpreadDown, mType);//spread from here to hit all frames in flow
|
||||
// The frame could be an SVG text frame, in which case we'll ignore
|
||||
// it.
|
||||
if (frame && frame->GetType() == nsGkAtoms::textFrame)
|
||||
{
|
||||
nsTextFrame* textFrame = static_cast<nsTextFrame*>(frame);
|
||||
PRUint32 startOffset = aRange->StartOffset();
|
||||
PRUint32 endOffset;
|
||||
if (aRange->GetEndParent() == content) {
|
||||
endOffset = aRange->EndOffset();
|
||||
} else {
|
||||
endOffset = content->GetText()->GetLength();
|
||||
}
|
||||
textFrame->SetSelectedRange(startOffset, endOffset, aFlags, mType);
|
||||
}
|
||||
}
|
||||
|
||||
iter->First();
|
||||
|
@ -4305,7 +4293,7 @@ nsTypedSelection::selectFrames(nsPresContext* aPresContext, nsIRange *aRange, PR
|
|||
{
|
||||
content = do_QueryInterface(iter->GetCurrentNode());
|
||||
|
||||
selectFrames(aPresContext, inneriter, content, presShell,aFlags);
|
||||
SelectAllFramesForContent(inneriter, content, aFlags);
|
||||
|
||||
iter->Next();
|
||||
}
|
||||
|
@ -4317,11 +4305,16 @@ nsTypedSelection::selectFrames(nsPresContext* aPresContext, nsIRange *aRange, PR
|
|||
if (NS_FAILED(result) || !content)
|
||||
return result;
|
||||
|
||||
if (!content->IsNodeOfType(nsINode::eELEMENT))
|
||||
if (content->IsNodeOfType(nsINode::eTEXT))
|
||||
{
|
||||
frame = mFrameSelection->GetShell()->GetPrimaryFrameFor(content);
|
||||
if (frame)
|
||||
frame->SetSelected(aPresContext, domRange, aFlags, eSpreadDown, mType);//spread from here to hit all frames in flow
|
||||
// The frame could be an SVG text frame, in which case we'll
|
||||
// ignore it.
|
||||
if (frame && frame->GetType() == nsGkAtoms::textFrame)
|
||||
{
|
||||
nsTextFrame* textFrame = static_cast<nsTextFrame*>(frame);
|
||||
textFrame->SetSelectedRange(0, aRange->EndOffset(), aFlags, mType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -155,12 +155,22 @@ public:
|
|||
virtual ContentOffsets CalcContentOffsetsFromFramePoint(nsPoint aPoint);
|
||||
ContentOffsets GetCharacterOffsetAtFramePoint(const nsPoint &aPoint);
|
||||
|
||||
NS_IMETHOD SetSelected(nsPresContext* aPresContext,
|
||||
nsIDOMRange *aRange,
|
||||
PRBool aSelected,
|
||||
nsSpread aSpread,
|
||||
SelectionType aType);
|
||||
|
||||
/**
|
||||
* This is called only on the primary text frame. It indicates that
|
||||
* the selection state of the given character range has changed.
|
||||
* Text in the range is unconditionally invalidated
|
||||
* (nsTypedSelection::Repaint depends on this).
|
||||
* @param aSelected true if the selection has been added to the range,
|
||||
* false otherwise
|
||||
* @param aType the type of selection added or removed
|
||||
*/
|
||||
virtual void SetSelected(PRBool aSelected,
|
||||
SelectionType aType);
|
||||
void SetSelectedRange(PRUint32 aStart,
|
||||
PRUint32 aEnd,
|
||||
PRBool aSelected,
|
||||
SelectionType aType);
|
||||
|
||||
virtual PRBool PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset);
|
||||
virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset);
|
||||
virtual PRBool PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
|
||||
|
|
|
@ -4969,120 +4969,98 @@ nsTextFrame::CombineSelectionUnderlineRect(nsPresContext* aPresContext,
|
|||
return !aRect.IsEmpty() && !givenRect.Contains(aRect);
|
||||
}
|
||||
|
||||
//null range means the whole thing
|
||||
NS_IMETHODIMP
|
||||
nsTextFrame::SetSelected(nsPresContext* aPresContext,
|
||||
nsIDOMRange *aRange,
|
||||
PRBool aSelected,
|
||||
nsSpread aSpread,
|
||||
void
|
||||
nsTextFrame::SetSelected(PRBool aSelected,
|
||||
SelectionType aType)
|
||||
{
|
||||
DEBUG_VERIFY_NOT_DIRTY(mState);
|
||||
#if 0 //XXXrbs disable due to bug 310318
|
||||
if (mState & NS_FRAME_IS_DIRTY)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
#endif
|
||||
SetSelectedRange(0, mContent->GetText()->GetLength(), aSelected, aType);
|
||||
}
|
||||
|
||||
void
|
||||
nsTextFrame::SetSelectedRange(PRUint32 aStart,
|
||||
PRUint32 aEnd,
|
||||
PRBool aSelected,
|
||||
SelectionType aType)
|
||||
{
|
||||
NS_ASSERTION(!GetPrevContinuation(), "Should only be called for primary frame");
|
||||
DEBUG_VERIFY_NOT_DIRTY(mState);
|
||||
|
||||
// Selection is collapsed, which can't affect text frame rendering
|
||||
if (aStart == aEnd)
|
||||
return;
|
||||
|
||||
// XXXroc This is stupid, ParentDisablesSelection just returns true. Let's
|
||||
// kill it.
|
||||
if (aSelected && ParentDisablesSelection())
|
||||
return NS_OK;
|
||||
return;
|
||||
|
||||
if (aType == nsISelectionController::SELECTION_NORMAL) {
|
||||
// check whether style allows selection
|
||||
PRBool selectable;
|
||||
IsSelectable(&selectable, nsnull);
|
||||
if (!selectable)
|
||||
return NS_OK;//do not continue no selection for this frame.
|
||||
return;
|
||||
}
|
||||
|
||||
PRBool found = PR_FALSE;
|
||||
if (aRange) {
|
||||
//lets see if the range contains us, if so we must redraw!
|
||||
nsCOMPtr<nsIDOMNode> endNode;
|
||||
PRInt32 endOffset;
|
||||
nsCOMPtr<nsIDOMNode> startNode;
|
||||
PRInt32 startOffset;
|
||||
aRange->GetEndContainer(getter_AddRefs(endNode));
|
||||
aRange->GetEndOffset(&endOffset);
|
||||
aRange->GetStartContainer(getter_AddRefs(startNode));
|
||||
aRange->GetStartOffset(&startOffset);
|
||||
nsCOMPtr<nsIDOMNode> thisNode = do_QueryInterface(GetContent());
|
||||
PRBool anySelected = PR_FALSE;
|
||||
|
||||
if (thisNode == startNode)
|
||||
{
|
||||
if (GetContentEnd() >= startOffset)
|
||||
{
|
||||
found = PR_TRUE;
|
||||
if (thisNode == endNode)
|
||||
{ //special case
|
||||
if (endOffset == startOffset) //no need to redraw since drawing takes place with cursor
|
||||
found = PR_FALSE;
|
||||
nsTextFrame* f = this;
|
||||
while (f && f->GetContentEnd() <= aStart) {
|
||||
if (f->GetStateBits() & NS_FRAME_SELECTED_CONTENT) {
|
||||
anySelected = PR_TRUE;
|
||||
}
|
||||
f = static_cast<nsTextFrame*>(f->GetNextContinuation());
|
||||
}
|
||||
|
||||
if (mContentOffset > endOffset)
|
||||
found = PR_FALSE;
|
||||
}
|
||||
nsPresContext* presContext = PresContext();
|
||||
while (f && f->GetContentOffset() < aEnd) {
|
||||
if (aSelected) {
|
||||
f->AddStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
anySelected = PR_TRUE;
|
||||
} else { // we need to see if any other selection is available.
|
||||
SelectionDetails *details = f->GetSelectionDetails();
|
||||
if (details) {
|
||||
anySelected = PR_TRUE;
|
||||
DestroySelectionDetails(details);
|
||||
} else {
|
||||
f->RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
}
|
||||
}
|
||||
else if (thisNode == endNode)
|
||||
{
|
||||
if (mContentOffset < endOffset)
|
||||
found = PR_TRUE;
|
||||
else
|
||||
{
|
||||
found = PR_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
found = PR_TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// null range means the whole thing
|
||||
found = PR_TRUE;
|
||||
}
|
||||
|
||||
if ( aSelected )
|
||||
AddStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
else
|
||||
{ //we need to see if any other selection is available.
|
||||
SelectionDetails *details = GetSelectionDetails();
|
||||
if (!details) {
|
||||
RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
} else {
|
||||
DestroySelectionDetails(details);
|
||||
}
|
||||
}
|
||||
if (found) {
|
||||
// If the selection state is changed in this content, we need to reflow
|
||||
// to recompute the overflow area for underline of spellchecking or IME if
|
||||
// their underline is thicker than normal decoration line.
|
||||
// We may need to reflow to recompute the overflow area for
|
||||
// spellchecking or IME underline if their underline is thicker than
|
||||
// the normal decoration line.
|
||||
PRBool didHaveOverflowingSelection =
|
||||
(mState & TEXT_SELECTION_UNDERLINE_OVERFLOWED) != 0;
|
||||
(f->GetStateBits() & TEXT_SELECTION_UNDERLINE_OVERFLOWED) != 0;
|
||||
nsRect r(nsPoint(0, 0), GetSize());
|
||||
PRBool willHaveOverflowingSelection =
|
||||
aSelected && CombineSelectionUnderlineRect(PresContext(), r);
|
||||
aSelected && f->CombineSelectionUnderlineRect(presContext, r);
|
||||
if (didHaveOverflowingSelection || willHaveOverflowingSelection) {
|
||||
PresContext()->PresShell()->FrameNeedsReflow(this,
|
||||
nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
presContext->PresShell()->FrameNeedsReflow(f,
|
||||
nsIPresShell::eStyleChange,
|
||||
NS_FRAME_IS_DIRTY);
|
||||
}
|
||||
// Selection might change anything. Invalidate the overflow area.
|
||||
InvalidateOverflowRect();
|
||||
f->InvalidateOverflowRect();
|
||||
|
||||
f = static_cast<nsTextFrame*>(f->GetNextContinuation());
|
||||
}
|
||||
if (aSpread == eSpreadDown)
|
||||
{
|
||||
nsIFrame* frame = GetPrevContinuation();
|
||||
while(frame){
|
||||
frame->SetSelected(aPresContext, aRange,aSelected,eSpreadNone, aType);
|
||||
frame = frame->GetPrevContinuation();
|
||||
}
|
||||
frame = GetNextContinuation();
|
||||
while (frame){
|
||||
frame->SetSelected(aPresContext, aRange,aSelected,eSpreadNone, aType);
|
||||
frame = frame->GetNextContinuation();
|
||||
|
||||
// Scan remaining continuations to see if any are selected
|
||||
while (f && !anySelected) {
|
||||
if (f->GetStateBits() & NS_FRAME_SELECTED_CONTENT) {
|
||||
anySelected = PR_TRUE;
|
||||
}
|
||||
f = static_cast<nsTextFrame*>(f->GetNextContinuation());
|
||||
}
|
||||
|
||||
if (anySelected) {
|
||||
mContent->SetFlags(NS_TEXT_IN_SELECTION);
|
||||
} else {
|
||||
// This is only legal because there is only one presentation for the
|
||||
// content with a selection
|
||||
mContent->UnsetFlags(NS_TEXT_IN_SELECTION);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -6421,7 +6399,18 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
|
||||
SetLength(contentLength);
|
||||
|
||||
Invalidate(nsRect(nsPoint(0, 0), GetSize()));
|
||||
if (mContent->HasFlag(NS_TEXT_IN_SELECTION)) {
|
||||
// XXXroc Watch out, this could be slow!!! Speed up GetSelectionDetails?
|
||||
SelectionDetails* details = GetSelectionDetails();
|
||||
if (details) {
|
||||
AddStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
DestroySelectionDetails(details);
|
||||
} else {
|
||||
RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
}
|
||||
}
|
||||
|
||||
Invalidate(aMetrics.mOverflowArea);
|
||||
|
||||
#ifdef NOISY_REFLOW
|
||||
ListTag(stdout);
|
||||
|
|
|
@ -229,35 +229,30 @@ nsSVGGlyphFrame::DidSetStyleContext(nsStyleContext* aOldStyleContext)
|
|||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSVGGlyphFrame::SetSelected(nsPresContext* aPresContext,
|
||||
nsIDOMRange* aRange,
|
||||
PRBool aSelected,
|
||||
nsSpread aSpread,
|
||||
SelectionType aType)
|
||||
void
|
||||
nsSVGGlyphFrame::SetSelected(PRBool aSelected,
|
||||
SelectionType aType)
|
||||
{
|
||||
#if defined(DEBUG) && defined(SVG_DEBUG_SELECTION)
|
||||
printf("nsSVGGlyphFrame(%p)::SetSelected()\n", this);
|
||||
#endif
|
||||
// return nsSVGGlyphFrameBase::SetSelected(aPresContext, aRange, aSelected, aSpread, aType);
|
||||
|
||||
if (aType == nsISelectionController::SELECTION_NORMAL) {
|
||||
// check whether style allows selection
|
||||
PRBool selectable;
|
||||
IsSelectable(&selectable, nsnull);
|
||||
if (!selectable)
|
||||
return NS_OK;
|
||||
}
|
||||
if (aType != nsISelectionController::SELECTION_NORMAL)
|
||||
return;
|
||||
|
||||
if ( aSelected ){
|
||||
mState |= NS_FRAME_SELECTED_CONTENT;
|
||||
// check whether style allows selection
|
||||
PRBool selectable;
|
||||
IsSelectable(&selectable, nsnull);
|
||||
if (!selectable)
|
||||
return;
|
||||
|
||||
if (aSelected) {
|
||||
AddStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
} else {
|
||||
RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
|
||||
}
|
||||
else
|
||||
mState &= ~NS_FRAME_SELECTED_CONTENT;
|
||||
|
||||
nsSVGUtils::UpdateGraphic(this);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -82,11 +82,8 @@ public:
|
|||
|
||||
virtual void DidSetStyleContext(nsStyleContext* aOldStyleContext);
|
||||
|
||||
NS_IMETHOD SetSelected(nsPresContext* aPresContext,
|
||||
nsIDOMRange* aRange,
|
||||
PRBool aSelected,
|
||||
nsSpread aSpread,
|
||||
SelectionType aType);
|
||||
virtual void SetSelected(PRBool aSelected,
|
||||
SelectionType aType);
|
||||
NS_IMETHOD GetSelected(PRBool *aSelected) const;
|
||||
NS_IMETHOD IsSelectable(PRBool* aIsSelectable, PRUint8* aSelectStyle) const;
|
||||
|
||||
|
|
|
@ -393,16 +393,14 @@ nsTableOuterFrame::BuildDisplayListForInnerTable(nsDisplayListBuilder* aBuilde
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsTableOuterFrame::SetSelected(nsPresContext* aPresContext,
|
||||
nsIDOMRange *aRange,
|
||||
PRBool aSelected,
|
||||
nsSpread aSpread,
|
||||
SelectionType aType)
|
||||
void
|
||||
nsTableOuterFrame::SetSelected(PRBool aSelected,
|
||||
SelectionType aType)
|
||||
{
|
||||
nsresult result = nsFrame::SetSelected(aPresContext, aRange,aSelected, aSpread, aType);
|
||||
if (NS_SUCCEEDED(result) && mInnerTableFrame)
|
||||
return mInnerTableFrame->SetSelected(aPresContext, aRange,aSelected, aSpread, aType);
|
||||
return result;
|
||||
nsFrame::SetSelected(aSelected, aType);
|
||||
if (mInnerTableFrame) {
|
||||
mInnerTableFrame->SetSelected(aSelected, aType);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
|
|
@ -165,11 +165,8 @@ public:
|
|||
|
||||
/** SetSelected needs to be overridden to talk to inner tableframe
|
||||
*/
|
||||
NS_IMETHOD SetSelected(nsPresContext* aPresContext,
|
||||
nsIDOMRange *aRange,
|
||||
PRBool aSelected,
|
||||
nsSpread aSpread,
|
||||
SelectionType aType);
|
||||
void SetSelected(PRBool aSelected,
|
||||
SelectionType aType);
|
||||
|
||||
NS_IMETHOD GetParentStyleContextFrame(nsPresContext* aPresContext,
|
||||
nsIFrame** aProviderFrame,
|
||||
|
|
Загрузка…
Ссылка в новой задаче