Bug 1251519 Part 5 - Use union rect of child frames for clamping. r=mats

This patch use the union of all child scrollable overflow frame rects to
clamp the caret dragging point.

MozReview-Commit-ID: GEF9BpQkQNd

--HG--
extra : rebase_source : 3722e8a0f32a45439fed753b7d5f9a76add4553f
This commit is contained in:
Ting-Yu Lin 2016-03-10 17:38:33 +08:00
Родитель 14b8c376fa
Коммит edffd8287a
2 изменённых файлов: 45 добавлений и 23 удалений

Просмотреть файл

@ -263,7 +263,6 @@ AccessibleCaretManager::HasNonEmptyTextContent(nsINode* aNode) const
aNode, nsContentUtils::eRecurseIntoChildren);
}
void
AccessibleCaretManager::UpdateCaretsForCursorMode(UpdateCaretsHint aHint)
{
@ -1084,30 +1083,44 @@ AccessibleCaretManager::DragCaretInternal(const nsPoint& aPoint)
}
nsRect
AccessibleCaretManager::GetContentBoundaryForFrame(nsIFrame* aFrame) const
AccessibleCaretManager::GetAllChildFrameRectsUnion(nsIFrame* aFrame) const
{
nsRect resultRect;
nsIFrame* rootFrame = mPresShell->GetRootFrame();
nsRect unionRect;
for (; aFrame; aFrame = aFrame->GetNextContinuation()) {
nsRect rect = aFrame->GetContentRectRelativeToSelf();
nsLayoutUtils::TransformRect(aFrame, rootFrame, rect);
resultRect = resultRect.Union(rect);
// Drill through scroll frames, we don't want to include scrollbar child
// frames below.
for (nsIFrame* frame = aFrame->GetContentInsertionFrame();
frame;
frame = frame->GetNextContinuation()) {
nsRect frameRect;
nsIFrame::ChildListIterator lists(aFrame);
for (; !lists.IsDone(); lists.Next()) {
// Loop over all children to take the overflow rect into consideration.
for (nsIFrame::ChildListIterator lists(frame); !lists.IsDone(); lists.Next()) {
// Loop all children to union their scrollable overflow rect.
for (nsIFrame* child : lists.CurrentList()) {
nsRect overflowRect = child->GetScrollableOverflowRect();
nsLayoutUtils::TransformRect(child, rootFrame, overflowRect);
resultRect = resultRect.Union(overflowRect);
nsRect childRect = child->GetScrollableOverflowRectRelativeToSelf();
nsLayoutUtils::TransformRect(child, frame, childRect);
// A TextFrame containing only '\n' has positive height and width 0, or
// positive width and height 0 if it's vertical. Need to use UnionEdges
// to add its rect. BRFrame rect should be non-empty.
if (childRect.IsEmpty()) {
frameRect = frameRect.UnionEdges(childRect);
} else {
frameRect = frameRect.Union(childRect);
}
}
}
// Shrink rect to make sure we never hit the boundary.
resultRect.Deflate(kBoundaryAppUnits);
return resultRect;
MOZ_ASSERT(!frameRect.IsEmpty(),
"Editable frames should have at least one BRFrame child to make "
"frameRect non-empty!");
if (frame != aFrame) {
nsLayoutUtils::TransformRect(frame, aFrame, frameRect);
}
unionRect = unionRect.Union(frameRect);
}
return unionRect;
}
nsPoint
@ -1121,10 +1134,18 @@ AccessibleCaretManager::AdjustDragBoundary(const nsPoint& aPoint) const
Element* editingHost = GetEditingHostForFrame(focusFrame);
if (editingHost) {
nsRect boundary =
GetContentBoundaryForFrame(editingHost->GetPrimaryFrame());
nsIFrame* editingHostFrame = editingHost->GetPrimaryFrame();
if (editingHostFrame) {
nsRect boundary = GetAllChildFrameRectsUnion(editingHostFrame);
nsLayoutUtils::TransformRect(editingHostFrame, mPresShell->GetRootFrame(),
boundary);
// Shrink the rect to make sure we never hit the boundary.
boundary.Deflate(kBoundaryAppUnits);
adjustedPoint = boundary.ClampPoint(adjustedPoint);
}
}
if (GetCaretMode() == CaretMode::Selection) {
// Bug 1068474: Adjust the Y-coordinate so that the carets won't be in tilt

Просмотреть файл

@ -174,9 +174,10 @@ protected:
dom::Selection* GetSelection() const;
already_AddRefed<nsFrameSelection> GetFrameSelection() const;
// Get the bounding rectangle for aFrame where the caret under cursor mode can
// be positioned. The rectangle is relative to the root frame.
nsRect GetContentBoundaryForFrame(nsIFrame* aFrame) const;
// Get the union of all the child frame scrollable overflow rects for aFrame,
// which is used as a helper function to restrict the area where the caret can
// be dragged. Returns the rect relative to aFrame.
nsRect GetAllChildFrameRectsUnion(nsIFrame* aFrame) const;
// If we're dragging the first caret, we do not want to drag it over the
// previous character of the second caret. Same as the second caret. So we