Bug 1520779 Part 6: Return consistent results for paragraphs that contain forced line breaks, r=Jamie

1. Make sure the paragraph text and start and end ofsets returned for offsets on either the text or its adjacent br always match.
2. For two consecutive line breaks, treat the second one as its own paragraph without text, and its start offset corresponding to its offset, and end offset being 1 greater.
3. Add a test case exercising all cases.

Differential Revision: https://phabricator.services.mozilla.com/D90355
This commit is contained in:
Marco Zehe 2020-09-16 20:59:21 +00:00
Родитель 58bbff873c
Коммит e828bc6794
2 изменённых файлов: 37 добавлений и 4 удалений

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

@ -552,11 +552,13 @@ uint32_t HyperTextAccessible::FindOffset(uint32_t aOffset,
uint32_t hyperTextOffset = DOMPointToOffset(
pos.mResultContent, pos.mContentOffset, aDirection == eDirNext);
if (fallBackToSelectEndLine && IsLineEndCharAt(hyperTextOffset)) {
if ((fallBackToSelectEndLine || aAmount == eSelectParagraph) &&
IsLineEndCharAt(hyperTextOffset)) {
// We used eSelectEndLine, but the caller requested eSelectLine.
// If there's a '\n' at the end of the line, eSelectEndLine will stop
// on it rather than after it. This is not what we want, since the caller
// wants the next line, not the same line.
// Or, we were asked for the paragraph.
// If there's a '\n' at the end of the line, eSelectEndLine and
// eSelectParagraph will stop on it rather than after it. This is not what
// we want, since the caller wants the next line, not the same line.
++hyperTextOffset;
}
@ -787,6 +789,29 @@ void HyperTextAccessible::TextAtOffset(int32_t aOffset,
adjustedOffset = AdjustCaretOffset(adjustedOffset);
}
if (IsLineEndCharAt(adjustedOffset)) {
// Layout gives us different results for a paragraph with line breaks.
// For the text, we get the text, for the line break, we get the text
// with the line break included. We adjust for the former case in
// FindOffset. However, querying on the whitespace also gives us text
// from the next chunk, which is never what we want. So, adjust the
// offset to make sure we always get the text with the '\n' included.
if (IsLineEndCharAt(adjustedOffset - 1)) {
// However, if the character before this is also a line break, we
// want this to be only '\n'. In addition, layout would still
// give us the text of the next chunk here, too, which is still
// not what we want, either.
*aStartOffset = adjustedOffset;
*aEndOffset = adjustedOffset + 1;
TextSubstring(*aStartOffset, *aEndOffset, aText);
break;
}
// We're on a non-line-end character, adjust the offset and
// calculate the paragraph text and offsets as usual.
adjustedOffset--;
}
*aStartOffset =
FindOffset(adjustedOffset, eDirPrevious, eSelectParagraph);
*aEndOffset = FindOffset(adjustedOffset, eDirNext, eSelectParagraph);

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

@ -28,6 +28,13 @@
testTextAtOffset("forced_wrap", BOUNDARY_PARAGRAPH,
[[0, 2, "ab", 0, 2]]);
// Test a paragraph with a few line breaks.
testTextAtOffset("forced_br", BOUNDARY_PARAGRAPH,
[[0, 1, "a\n", 0, 2], // a and br treated as a paragraph
[2, 3, "b\n", 2, 4], // b treated as a paragraph, excl 2nd line break
[4, 4, "\n", 4, 5], // second br treated as a separate paragraph
[5, 6, "c", 5, 6]]); // Last paragraph treated as usual
// Test a paragraph with an embedded link.
testTextAtOffset("pWithLink", BOUNDARY_PARAGRAPH,
[[0, 3, "a" + kEmbedChar + "d", 0, 3]]);
@ -66,6 +73,7 @@
<p>hello again</p>
</div>
<p id="forced_wrap" style="width: 1px; word-break: break-all;">ab</p>
<p id="forced_br">a<br>b<br><br>c</p>
<p id="pWithLink">a<a id="link" href="https://example.com/">bc</a>d</p>
<ul id="ul"><li id="li1">a</li><li>b</li></ul>
</body>