Bug 1286464 part.16 Rename ContentEventHandler::Get*FrameHavingFlatTextInRange() to ContentEventHandler::Get*FrameInRangeForTextRect() and make them treat a moz-<br> element as a normal <br> element because it doesn't cause text but needs to compute text rect in the last empty line r=smaug

In plain text editor, moz-<br> element is appended for a placeholder of empty line when the text ends with a line breaker. Therefore, when we compute text rects, we need to handle it same as a normal <br> element even though it doesn't cause any text.

MozReview-Commit-ID: 4IXLafU6o0W

--HG--
extra : rebase_source : 5db9c70e3acd40e4f47f35fcf293702ce0fb0295
This commit is contained in:
Masayuki Nakano 2016-08-02 14:00:32 +09:00
Родитель b933e7c9bb
Коммит 7b45431d6c
2 изменённых файлов: 30 добавлений и 17 удалений

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

@ -420,6 +420,11 @@ static bool IsContentBR(nsIContent* aContent)
eIgnoreCase);
}
static bool IsMozBR(nsIContent* aContent)
{
return aContent->IsHTMLElement(nsGkAtoms::br) && !IsContentBR(aContent);
}
static void ConvertToNativeNewlines(nsAFlatString& aString)
{
#if defined(XP_WIN)
@ -1450,7 +1455,7 @@ ContentEventHandler::GetNodePositionHavingFlatText(nsINode* aNode,
}
ContentEventHandler::FrameAndNodeOffset
ContentEventHandler::GetFirstFrameHavingFlatTextInRange(nsRange* aRange)
ContentEventHandler::GetFirstFrameInRangeForTextRect(nsRange* aRange)
{
NodePosition nodePosition;
nsCOMPtr<nsIContentIterator> iter = NS_NewPreContentIterator();
@ -1479,7 +1484,8 @@ ContentEventHandler::GetFirstFrameHavingFlatTextInRange(nsRange* aRange)
// If the element node causes a line break before it, it's the first
// node causing text.
if (ShouldBreakLineBefore(node->AsContent(), mRootContent)) {
if (ShouldBreakLineBefore(node->AsContent(), mRootContent) ||
IsMozBR(node->AsContent())) {
nodePosition.mNode = node;
nodePosition.mOffset = 0;
}
@ -1496,7 +1502,7 @@ ContentEventHandler::GetFirstFrameHavingFlatTextInRange(nsRange* aRange)
}
ContentEventHandler::FrameAndNodeOffset
ContentEventHandler::GetLastFrameHavingFlatTextInRange(nsRange* aRange)
ContentEventHandler::GetLastFrameInRangeForTextRect(nsRange* aRange)
{
NodePosition nodePosition;
nsCOMPtr<nsIContentIterator> iter = NS_NewPreContentIterator();
@ -1549,7 +1555,8 @@ ContentEventHandler::GetLastFrameHavingFlatTextInRange(nsRange* aRange)
break;
}
if (ShouldBreakLineBefore(node->AsContent(), mRootContent)) {
if (ShouldBreakLineBefore(node->AsContent(), mRootContent) ||
IsMozBR(node->AsContent())) {
nodePosition.mNode = node;
nodePosition.mOffset = 0;
break;
@ -1598,8 +1605,10 @@ ContentEventHandler::FrameRelativeRect
ContentEventHandler::GetLineBreakerRectBefore(nsIFrame* aFrame)
{
// Note that this method should be called only with an element's frame whose
// open tag causes a line break.
MOZ_ASSERT(ShouldBreakLineBefore(aFrame->GetContent(), mRootContent));
// open tag causes a line break or moz-<br> for computing empty last line's
// rect.
MOZ_ASSERT(ShouldBreakLineBefore(aFrame->GetContent(), mRootContent) ||
IsMozBR(aFrame->GetContent()));
nsIFrame* frameForFontMetrics = aFrame;
@ -1703,9 +1712,9 @@ ContentEventHandler::OnQueryTextRectArray(WidgetQueryContentEvent* aEvent)
}
// Get the first frame which causes some text after the offset.
FrameAndNodeOffset firstFrame = GetFirstFrameHavingFlatTextInRange(range);
FrameAndNodeOffset firstFrame = GetFirstFrameInRangeForTextRect(range);
// If GetFirstFrameHavingFlatTextInRange() does not return valid frame,
// If GetFirstFrameInRangeForTextRect() does not return valid frame,
// that means that there is no remaining content which causes text.
// So, in such case, we must have reached the end of the contents.
if (!firstFrame.IsValid()) {
@ -1731,7 +1740,8 @@ ContentEventHandler::OnQueryTextRectArray(WidgetQueryContentEvent* aEvent)
AutoTArray<nsRect, 16> charRects;
if (ShouldBreakLineBefore(firstContent, mRootContent)) {
if (ShouldBreakLineBefore(firstContent, mRootContent) ||
IsMozBR(firstContent)) {
nsRect brRect;
// If the frame is <br> frame, we can always trust
// GetLineBreakerRectBefore(). Otherwise, "after" the last character
@ -1772,7 +1782,7 @@ ContentEventHandler::OnQueryTextRectArray(WidgetQueryContentEvent* aEvent)
return NS_ERROR_UNEXPECTED;
}
FrameAndNodeOffset frameForPrevious =
GetFirstFrameHavingFlatTextInRange(range);
GetFirstFrameInRangeForTextRect(range);
startsBetweenLineBreaker = frameForPrevious.mFrame == firstFrame.mFrame;
}
} else {
@ -1932,9 +1942,9 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
iter->Init(range);
// Get the first frame which causes some text after the offset.
FrameAndNodeOffset firstFrame = GetFirstFrameHavingFlatTextInRange(range);
FrameAndNodeOffset firstFrame = GetFirstFrameInRangeForTextRect(range);
// If GetFirstFrameHavingFlatTextInRange() does not return valid frame,
// If GetFirstFrameInRangeForTextRect() does not return valid frame,
// that means that there is no remaining content which causes text.
// So, in such case, we must have reached the end of the contents.
if (!firstFrame.IsValid()) {
@ -1985,7 +1995,7 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
EnsureNonEmptyRect(rect);
// Get the last frame which causes some text in the range.
FrameAndNodeOffset lastFrame = GetLastFrameHavingFlatTextInRange(range);
FrameAndNodeOffset lastFrame = GetLastFrameInRangeForTextRect(range);
if (NS_WARN_IF(!lastFrame.IsValid())) {
return NS_ERROR_FAILURE;
}
@ -2080,6 +2090,7 @@ ContentEventHandler::OnQueryTextRect(WidgetQueryContentEvent* aEvent)
rect.UnionRect(rect, frameRect);
}
}
aEvent->mReply.mRect = LayoutDeviceIntRect::FromUnknownRect(
rect.ToOutsidePixels(mPresContext->AppUnitsPerDevPixel()));
// Returning empty rect may cause native IME confused, let's make sure to

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

@ -341,13 +341,15 @@ protected:
};
// Get first frame after the start of the given range for computing text rect.
// This returns invalid FrameAndNodeOffset if there is no content which
// causes text in the range. mOffsetInNode is start offset in the frame.
FrameAndNodeOffset GetFirstFrameHavingFlatTextInRange(nsRange* aRange);
// should affect to computing text rect in the range. mOffsetInNode is start
// offset in the frame.
FrameAndNodeOffset GetFirstFrameInRangeForTextRect(nsRange* aRange);
// Get last frame before the end of the given range for computing text rect.
// This returns invalid FrameAndNodeOffset if there is no content which
// causes text in the range. mOffsetInNode is end offset in the frame.
FrameAndNodeOffset GetLastFrameHavingFlatTextInRange(nsRange* aRange);
// should affect to computing text rect in the range. mOffsetInNode is end
// offset in the frame.
FrameAndNodeOffset GetLastFrameInRangeForTextRect(nsRange* aRange);
struct MOZ_STACK_CLASS FrameRelativeRect final
{