mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Bug 1074736 - Consider multiple range selection in selection caret. r=roc
This commit is contained in:
parent
4f6ac81817
commit
d90f8ec248
@ -9356,21 +9356,30 @@ nsGlobalWindow::UpdateCommands(const nsAString& anAction, nsISelection* aSel, in
|
||||
SelectionChangeEventInit init;
|
||||
init.mBubbles = true;
|
||||
if (aSel) {
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsresult rv = aSel->GetRangeAt(0, getter_AddRefs(range));
|
||||
if (NS_SUCCEEDED(rv) && range) {
|
||||
nsRefPtr<nsRange> nsrange = static_cast<nsRange*>(range.get());
|
||||
init.mBoundingClientRect = nsrange->GetBoundingClientRect(true, false);
|
||||
range->ToString(init.mSelectedText);
|
||||
Selection* selection = static_cast<Selection*>(aSel);
|
||||
int32_t rangeCount = selection->GetRangeCount();
|
||||
nsLayoutUtils::RectAccumulator accumulator;
|
||||
for (int32_t idx = 0; idx < rangeCount; ++idx) {
|
||||
nsRange* range = selection->GetRangeAt(idx);
|
||||
nsRange::CollectClientRects(&accumulator, range,
|
||||
range->GetStartParent(), range->StartOffset(),
|
||||
range->GetEndParent(), range->EndOffset(),
|
||||
true, false);
|
||||
}
|
||||
nsRect rect = accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect :
|
||||
accumulator.mResultRect;
|
||||
nsRefPtr<DOMRect> domRect = new DOMRect(ToSupports(this));
|
||||
domRect->SetLayoutRect(rect);
|
||||
init.mBoundingClientRect = domRect;
|
||||
|
||||
for (uint32_t reasonType = 0;
|
||||
reasonType < static_cast<uint32_t>(SelectionChangeReason::EndGuard_);
|
||||
++reasonType) {
|
||||
SelectionChangeReason strongReasonType =
|
||||
static_cast<SelectionChangeReason>(reasonType);
|
||||
if (CheckReason(aReason, strongReasonType)) {
|
||||
init.mReasons.AppendElement(strongReasonType);
|
||||
}
|
||||
selection->Stringify(init.mSelectedText);
|
||||
for (uint32_t reasonType = 0;
|
||||
reasonType < static_cast<uint32_t>(SelectionChangeReason::EndGuard_);
|
||||
++reasonType) {
|
||||
SelectionChangeReason strongReasonType =
|
||||
static_cast<SelectionChangeReason>(reasonType);
|
||||
if (CheckReason(aReason, strongReasonType)) {
|
||||
init.mReasons.AppendElement(strongReasonType);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -384,21 +384,24 @@ SelectionCarets::UpdateSelectionCarets()
|
||||
return;
|
||||
}
|
||||
|
||||
if (selection->GetRangeCount() <= 0) {
|
||||
if (selection->IsCollapsed()) {
|
||||
SetVisibility(false);
|
||||
return;
|
||||
}
|
||||
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
|
||||
if (range->Collapsed()) {
|
||||
SetVisibility(false);
|
||||
return;
|
||||
}
|
||||
int32_t rangeCount = selection->GetRangeCount();
|
||||
nsRefPtr<nsRange> firstRange = selection->GetRangeAt(0);
|
||||
nsRefPtr<nsRange> lastRange = selection->GetRangeAt(rangeCount - 1);
|
||||
|
||||
nsLayoutUtils::FirstAndLastRectCollector collector;
|
||||
nsRange::CollectClientRects(&collector, range,
|
||||
range->GetStartParent(), range->StartOffset(),
|
||||
range->GetEndParent(), range->EndOffset(), true, true);
|
||||
nsLayoutUtils::FirstAndLastRectCollector collectorStart;
|
||||
nsRange::CollectClientRects(&collectorStart, firstRange,
|
||||
firstRange->GetStartParent(), firstRange->StartOffset(),
|
||||
firstRange->GetEndParent(), firstRange->EndOffset(), true, true);
|
||||
|
||||
nsLayoutUtils::FirstAndLastRectCollector collectorEnd;
|
||||
nsRange::CollectClientRects(&collectorEnd, lastRange,
|
||||
lastRange->GetStartParent(), lastRange->StartOffset(),
|
||||
lastRange->GetEndParent(), lastRange->EndOffset(), true, true);
|
||||
|
||||
nsIFrame* canvasFrame = mPresShell->GetCanvasFrame();
|
||||
nsIFrame* rootFrame = mPresShell->GetRootFrame();
|
||||
@ -412,11 +415,11 @@ SelectionCarets::UpdateSelectionCarets()
|
||||
nsRefPtr<nsFrameSelection> fs = GetFrameSelection();
|
||||
int32_t startOffset;
|
||||
nsIFrame* startFrame = FindFirstNodeWithFrame(mPresShell->GetDocument(),
|
||||
range, fs, false, startOffset);
|
||||
firstRange, fs, false, startOffset);
|
||||
|
||||
int32_t endOffset;
|
||||
nsIFrame* endFrame = FindFirstNodeWithFrame(mPresShell->GetDocument(),
|
||||
range, fs, true, endOffset);
|
||||
lastRange, fs, true, endOffset);
|
||||
|
||||
if (!startFrame || !endFrame) {
|
||||
SetVisibility(false);
|
||||
@ -442,15 +445,15 @@ SelectionCarets::UpdateSelectionCarets()
|
||||
|
||||
// If start frame is LTR, then place start caret in first rect's leftmost
|
||||
// otherwise put it to first rect's rightmost.
|
||||
ReduceRectToVerticalEdge(collector.mFirstRect, startFrameIsRTL);
|
||||
ReduceRectToVerticalEdge(collectorStart.mFirstRect, startFrameIsRTL);
|
||||
|
||||
// Contrary to start frame, if end frame is LTR, put end caret to last
|
||||
// rect's rightmost position, otherwise, put it to last rect's leftmost.
|
||||
ReduceRectToVerticalEdge(collector.mLastRect, !endFrameIsRTL);
|
||||
ReduceRectToVerticalEdge(collectorEnd.mLastRect, !endFrameIsRTL);
|
||||
|
||||
nsAutoTArray<nsIFrame*, 16> hitFramesInFirstRect;
|
||||
nsLayoutUtils::GetFramesForArea(rootFrame,
|
||||
collector.mFirstRect,
|
||||
collectorStart.mFirstRect,
|
||||
hitFramesInFirstRect,
|
||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
|
||||
nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||
@ -458,7 +461,7 @@ SelectionCarets::UpdateSelectionCarets()
|
||||
|
||||
nsAutoTArray<nsIFrame*, 16> hitFramesInLastRect;
|
||||
nsLayoutUtils::GetFramesForArea(rootFrame,
|
||||
collector.mLastRect,
|
||||
collectorEnd.mLastRect,
|
||||
hitFramesInLastRect,
|
||||
nsLayoutUtils::IGNORE_PAINT_SUPPRESSION |
|
||||
nsLayoutUtils::IGNORE_CROSS_DOC |
|
||||
@ -467,11 +470,11 @@ SelectionCarets::UpdateSelectionCarets()
|
||||
SetStartFrameVisibility(hitFramesInFirstRect.Contains(startFrame));
|
||||
SetEndFrameVisibility(hitFramesInLastRect.Contains(endFrame));
|
||||
|
||||
nsLayoutUtils::TransformRect(rootFrame, canvasFrame, collector.mFirstRect);
|
||||
nsLayoutUtils::TransformRect(rootFrame, canvasFrame, collector.mLastRect);
|
||||
nsLayoutUtils::TransformRect(rootFrame, canvasFrame, collectorStart.mFirstRect);
|
||||
nsLayoutUtils::TransformRect(rootFrame, canvasFrame, collectorEnd.mLastRect);
|
||||
|
||||
SetStartFramePos(collector.mFirstRect.BottomLeft());
|
||||
SetEndFramePos(collector.mLastRect.BottomRight());
|
||||
SetStartFramePos(collectorStart.mFirstRect.BottomLeft());
|
||||
SetEndFramePos(collectorEnd.mLastRect.BottomRight());
|
||||
SetVisibility(true);
|
||||
|
||||
// If range select only one character, append tilt class name to it.
|
||||
@ -689,11 +692,13 @@ SelectionCarets::DragSelection(const nsPoint &movePoint)
|
||||
}
|
||||
|
||||
nsRefPtr<dom::Selection> selection = GetSelection();
|
||||
if (selection->GetRangeCount() <= 0) {
|
||||
int32_t rangeCount = selection->GetRangeCount();
|
||||
if (rangeCount <= 0) {
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
|
||||
nsRefPtr<nsRange> range = mDragMode == START_FRAME ?
|
||||
selection->GetRangeAt(0) : selection->GetRangeAt(rangeCount - 1);
|
||||
if (!CompareRangeWithContentOffset(range, fs, offsets, mDragMode)) {
|
||||
return nsEventStatus_eConsumeNoDefault;
|
||||
}
|
||||
@ -737,20 +742,22 @@ SelectionCarets::GetCaretYCenterPosition()
|
||||
}
|
||||
|
||||
nsRefPtr<dom::Selection> selection = GetSelection();
|
||||
if (selection->GetRangeCount() <= 0) {
|
||||
int32_t rangeCount = selection->GetRangeCount();
|
||||
if (rangeCount <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
|
||||
nsRefPtr<nsFrameSelection> fs = GetFrameSelection();
|
||||
|
||||
MOZ_ASSERT(mDragMode != NONE);
|
||||
nsCOMPtr<nsIContent> node;
|
||||
uint32_t nodeOffset;
|
||||
if (mDragMode == START_FRAME) {
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(0);
|
||||
node = do_QueryInterface(range->GetStartParent());
|
||||
nodeOffset = range->StartOffset();
|
||||
} else {
|
||||
nsRefPtr<nsRange> range = selection->GetRangeAt(rangeCount - 1);
|
||||
node = do_QueryInterface(range->GetEndParent());
|
||||
nodeOffset = range->EndOffset();
|
||||
}
|
||||
@ -885,12 +892,6 @@ SelectionCarets::NotifySelectionChanged(nsIDOMDocument* aDoc,
|
||||
nsISelection* aSel,
|
||||
int16_t aReason)
|
||||
{
|
||||
bool isCollapsed;
|
||||
aSel->GetIsCollapsed(&isCollapsed);
|
||||
if (isCollapsed) {
|
||||
SetVisibility(false);
|
||||
return NS_OK;
|
||||
}
|
||||
if (!aReason || (aReason & (nsISelectionListener::DRAG_REASON |
|
||||
nsISelectionListener::KEYPRESS_REASON |
|
||||
nsISelectionListener::MOUSEDOWN_REASON))) {
|
||||
|
Loading…
Reference in New Issue
Block a user