--- a/content/base/src/nsGenericDOMDataNode.h
+++ b/content/base/src/nsGenericDOMDataNode.h
@@ -38,39 +38,43 @@
/*
* Base class for DOM Core's nsIDOMComment, nsIDOMDocumentType, nsIDOMText,
* nsIDOMCDATASection, and nsIDOMProcessingInstruction nodes.
*/
#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"
#include "nsTextFragment.h"
#include "nsDOMError.h"
#include "nsIEventListenerManager.h"
#include "nsGenericElement.h"
#include "nsCycleCollectionParticipant.h"
#include "nsContentUtils.h"
#ifdef MOZ_SMIL
#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;
class nsIFrame;
class nsIDOMText;
class nsINodeInfo;
class nsURI;
--- a/layout/generic/nsFirstLetterFrame.cpp
+++ b/layout/generic/nsFirstLetterFrame.cpp
@@ -106,31 +106,16 @@ nsFirstLetterFrame::SetInitialChildList(
for (nsIFrame* frame = aChildList; frame; frame = frame->GetNextSibling()) {
NS_ASSERTION(frame->GetParent() == this, "Unexpected parent");
frameManager->ReParentStyleContext(frame);
}
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,
PRInt32* outFrameContentOffset,
nsIFrame **outChildFrame)
{
nsIFrame *kid = mFrames.FirstChild();
if (kid)
{
--- a/layout/generic/nsFirstLetterFrame.h
+++ b/layout/generic/nsFirstLetterFrame.h
@@ -78,18 +78,16 @@ public:
PRBool aShrinkWrap);
NS_IMETHOD Reflow(nsPresContext* aPresContext,
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
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,
PRInt32* outFrameContentOffset,
nsIFrame **outChildFrame);
nscoord GetFirstLetterBaseline() const { return mBaseline; }
--- a/layout/generic/nsFrame.cpp
+++ b/layout/generic/nsFrame.cpp
@@ -4482,53 +4482,40 @@ nsFrame::DumpBaseRegressionData(nsPresCo
IndentBy(out, aIndent);
fprintf(out, "</child-list>\n");
}
list = GetAdditionalChildListName(listIndex++);
} while (nsnull != list);
}
#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)
-{
-/*
- if (aSelected && ParentDisablesSelection())
- return NS_OK;
-*/
-
- if (aType == nsISelectionController::SELECTION_NORMAL) {
- // check whether style allows selection
- PRBool selectable;
- IsSelectable(&selectable, nsnull);
- if (!selectable)
- return NS_OK;
- }
-
-/*
- if (eSpreadDown == aSpread){
- nsIFrame* kid = GetFirstChild(nsnull);
- while (nsnull != kid) {
- kid->SetSelected(nsnull,aSelected,aSpread);
- kid = kid->GetNextSibling();
- }
- }
-*/
- if ( aSelected ){
- AddStateBits(NS_FRAME_SELECTED_CONTENT);
- }
- else
- RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
-
- // Repaint this frame subtree's entire area
- InvalidateOverflowRect();
-
- return NS_OK;
+void
+nsIFrame::SetSelected(PRBool aSelected, SelectionType aType)
+{
+ NS_ASSERTION(!GetPrevContinuation(),
+ "Should only be called on first in flow");
+ if (aType != nsISelectionController::SELECTION_NORMAL)
+ return;
+
+ // check whether style allows selection
+ PRBool selectable;
+ IsSelectable(&selectable, nsnull);
+ if (!selectable)
+ return;
+
+ for (nsIFrame* f = this; f; f = f->GetNextContinuation()) {
+ if (aSelected) {
+ AddStateBits(NS_FRAME_SELECTED_CONTENT);
+ } else {
+ RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
+ }
+
+ // Repaint this frame subtree's entire area
+ InvalidateOverflowRect();
+ }
}
NS_IMETHODIMP
nsFrame::GetSelected(PRBool *aSelected) const
{
if (!aSelected )
return NS_ERROR_NULL_POINTER;
*aSelected = !!(mState & NS_FRAME_SELECTED_CONTENT);
--- a/layout/generic/nsFrame.h
+++ b/layout/generic/nsFrame.h
@@ -232,17 +232,16 @@ public:
virtual PRBool IsContainingBlock() const;
#ifdef NS_DEBUG
NS_IMETHOD List(FILE* out, PRInt32 aIndent) const;
NS_IMETHOD GetFrameName(nsAString& aResult) const;
NS_IMETHOD_(nsFrameState) GetDebugStateBits() const;
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;
NS_IMETHOD GetSelectionController(nsPresContext *aPresContext, nsISelectionController **aSelCon);
virtual PRBool PeekOffsetNoAmount(PRBool aForward, PRInt32* aOffset);
virtual PRBool PeekOffsetCharacter(PRBool aForward, PRInt32* aOffset);
virtual PRBool PeekOffsetWord(PRBool aForward, PRBool aWordSelectEatSpace, PRBool aIsKeyboardSelect,
--- a/layout/generic/nsIFrame.h
+++ b/layout/generic/nsIFrame.h
@@ -1882,29 +1882,30 @@ public:
* Determine whether borders should not be painted on certain sides of the
* frame.
*/
virtual PRIntn GetSkipSides() const { return 0; }
/** 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;
/**
* called to discover where this frame, or a parent frame has user-select style
* applied, which affects that way that it is selected.
*
* @param aIsSelectable out param. Set to true if the frame can be selected
--- a/layout/generic/nsSelection.cpp
+++ b/layout/generic/nsSelection.cpp
@@ -74,16 +74,17 @@
#include "nsFrameTraversal.h"
#include "nsILineIterator.h"
#include "nsGkAtoms.h"
#include "nsIFrameTraversal.h"
#include "nsLayoutUtils.h"
#include "nsLayoutCID.h"
#include "nsBidiPresUtils.h"
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
+#include "nsTextFrame.h"
#include "nsIDOMText.h"
#include "nsContentUtils.h"
#include "nsThreadUtils.h"
//included for desired x position;
#include "nsPresContext.h"
@@ -296,17 +297,19 @@ private:
private:
nsTypedSelection *mTypedSelection;
SelectionRegion mRegion;
};
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);
PRInt32 FindInsertionPoint(
nsTArray<RangeData>* aElementArray,
nsINode* aPointNode, PRInt32 aPointOffset,
PRInt32 (*aComparator)(nsINode*,PRInt32,nsIRange*));
@@ -4172,41 +4175,36 @@ nsTypedSelection::GetPrimaryFrameForFocu
GetFrameForNodeOffset(content, GetFocusOffset(),
hint, aOffsetUsed);
if (!*aReturnFrame)
return NS_ERROR_FAILURE;
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
nsresult result;
if (!aInnerIter)
return NS_ERROR_NULL_POINTER;
result = aInnerIter->Init(aContent);
nsIFrame *frame;
if (NS_SUCCEEDED(result))
{
// First select frame of content passed in
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);
if (tcl)
{
return NS_OK;
}
}
@@ -4215,39 +4213,17 @@ nsTypedSelection::selectFrames(nsPresCon
while (!aInnerIter->IsDone())
{
nsCOMPtr<nsIContent> innercontent =
do_QueryInterface(aInnerIter->GetCurrentNode());
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();
}
return NS_OK;
}
@@ -4287,46 +4263,63 @@ nsTypedSelection::selectFrames(nsPresCon
// for each text node, call SetSelected on it:
nsCOMPtr<nsIContent> content = do_QueryInterface(aRange->GetStartParent());
// we must call first one explicitly
if (!content)
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();
while (!iter->IsDone())
{
content = do_QueryInterface(iter->GetCurrentNode());
- selectFrames(aPresContext, inneriter, content, presShell,aFlags);
+ SelectAllFramesForContent(inneriter, content, aFlags);
iter->Next();
}
//we must now do the last one if it is not the same as the first
if (aRange->GetEndParent() != aRange->GetStartParent())
{
content = do_QueryInterface(aRange->GetEndParent(), &result);
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);
+ }
}
}
}
return result;
}
// nsTypedSelection::LookUpSelection
//
--- a/layout/generic/nsTextFrame.h
+++ b/layout/generic/nsTextFrame.h
@@ -150,22 +150,32 @@ public:
NS_IMETHOD List(FILE* out, PRInt32 aIndent) const;
NS_IMETHOD GetFrameName(nsAString& aResult) const;
NS_IMETHOD_(nsFrameState) GetDebugStateBits() const ;
#endif
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,
PRInt32* aOffset, PeekWordState* aState);
NS_IMETHOD CheckVisibility(nsPresContext* aContext, PRInt32 aStartIndex, PRInt32 aEndIndex, PRBool aRecurse, PRBool *aFinished, PRBool *_retval);
// Update offsets to account for new length. This may clear mTextRun.
--- a/layout/generic/nsTextFrameThebes.cpp
+++ b/layout/generic/nsTextFrameThebes.cpp
@@ -4964,130 +4964,108 @@ nsTextFrame::CombineSelectionUnderlineRe
style, descentLimit);
aRect.UnionRect(aRect, decorationArea);
}
DestroySelectionDetails(details);
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)
{
+ 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);
-#if 0 //XXXrbs disable due to bug 310318
- if (mState & NS_FRAME_IS_DIRTY)
- return NS_ERROR_UNEXPECTED;
-#endif
-
+
+ // 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.
- }
-
- 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());
-
- 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;
-
- if (mContentOffset > endOffset)
- found = PR_FALSE;
- }
- }
+ return;
+ }
+
+ PRBool anySelected = PR_FALSE;
+
+ nsTextFrame* f = this;
+ while (f && f->GetContentEnd() <= aStart) {
+ if (f->GetStateBits() & NS_FRAME_SELECTED_CONTENT) {
+ anySelected = PR_TRUE;
}
- else if (thisNode == endNode)
- {
- if (mContentOffset < endOffset)
- found = PR_TRUE;
- else
- {
- found = PR_FALSE;
+ f = static_cast<nsTextFrame*>(f->GetNextContinuation());
+ }
+
+ 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
- {
- 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();
- }
- if (aSpread == eSpreadDown)
- {
- nsIFrame* frame = GetPrevContinuation();
- while(frame){
- frame->SetSelected(aPresContext, aRange,aSelected,eSpreadNone, aType);
- frame = frame->GetPrevContinuation();
+ f->InvalidateOverflowRect();
+
+ f = static_cast<nsTextFrame*>(f->GetNextContinuation());
+ }
+
+ // Scan remaining continuations to see if any are selected
+ while (f && !anySelected) {
+ if (f->GetStateBits() & NS_FRAME_SELECTED_CONTENT) {
+ anySelected = PR_TRUE;
}
- frame = GetNextContinuation();
- while (frame){
- frame->SetSelected(aPresContext, aRange,aSelected,eSpreadNone, aType);
- frame = frame->GetNextContinuation();
- }
- }
- return NS_OK;
+ 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);
+ }
}
NS_IMETHODIMP
nsTextFrame::GetPointFromOffset(PRInt32 inOffset,
nsPoint* outPoint)
{
if (!outPoint)
return NS_ERROR_NULL_POINTER;
@@ -6416,17 +6394,28 @@ nsTextFrame::Reflow(nsPresContext*
NS_ASSERTION(numJustifiableCharacters <= charsFit,
"Bad justifiable character count");
lineLayout.SetTextJustificationWeights(numJustifiableCharacters,
charsFit - numJustifiableCharacters);
}
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);
printf(": desiredSize=%d,%d(b=%d) status=%x\n",
aMetrics.width, aMetrics.height, aMetrics.ascent,
aStatus);
#endif
NS_FRAME_SET_TRUNCATION(aStatus, aReflowState, aMetrics);
--- a/layout/svg/base/src/nsSVGGlyphFrame.cpp
+++ b/layout/svg/base/src/nsSVGGlyphFrame.cpp
@@ -224,45 +224,40 @@ nsSVGGlyphFrame::DidSetStyleContext(nsSt
nsSVGGlyphFrameBase::DidSetStyleContext(aOldStyleContext);
if (!(GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
ClearTextRun();
NotifyGlyphMetricsChange();
}
}
-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)
+ 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 (aSelected) {
+ AddStateBits(NS_FRAME_SELECTED_CONTENT);
+ } else {
+ RemoveStateBits(NS_FRAME_SELECTED_CONTENT);
}
- if ( aSelected ){
- mState |= NS_FRAME_SELECTED_CONTENT;
- }
- else
- mState &= ~NS_FRAME_SELECTED_CONTENT;
-
nsSVGUtils::UpdateGraphic(this);
-
- return NS_OK;
}
NS_IMETHODIMP
nsSVGGlyphFrame::GetSelected(PRBool *aSelected) const
{
nsresult rv = nsSVGGlyphFrameBase::GetSelected(aSelected);
#if defined(DEBUG) && defined(SVG_DEBUG_SELECTION)
printf("nsSVGGlyphFrame(%p)::GetSelected()=%d\n", this, *aSelected);
--- a/layout/svg/base/src/nsSVGGlyphFrame.h
+++ b/layout/svg/base/src/nsSVGGlyphFrame.h
@@ -77,21 +77,18 @@ public:
// nsIFrame interface:
NS_IMETHOD CharacterDataChanged(nsPresContext* aPresContext,
nsIContent* aChild,
PRBool aAppend);
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;
NS_IMETHOD Init(nsIContent* aContent,
nsIFrame* aParent,
nsIFrame* aPrevInFlow);
/**
--- a/layout/tables/nsTableOuterFrame.cpp
+++ b/layout/tables/nsTableOuterFrame.cpp
@@ -388,26 +388,24 @@ nsTableOuterFrame::BuildDisplayListForIn
while (kid) {
nsresult rv = BuildDisplayListForChild(aBuilder, kid, aDirtyRect, aLists);
NS_ENSURE_SUCCESS(rv, rv);
kid = kid->GetNextSibling();
}
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
nsTableOuterFrame::GetParentStyleContextFrame(nsPresContext* aPresContext,
nsIFrame** aProviderFrame,
PRBool* aIsChild)
{
// The table outer frame and the (inner) table frame split the style
--- a/layout/tables/nsTableOuterFrame.h
+++ b/layout/tables/nsTableOuterFrame.h
@@ -160,21 +160,18 @@ public:
virtual nsIAtom* GetType() const;
#ifdef DEBUG
NS_IMETHOD GetFrameName(nsAString& aResult) const;
#endif
/** 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,
PRBool* aIsChild);
/*---------------- nsITableLayout methods ------------------------*/
/** @see nsITableFrame::GetCellDataAt */