Commit 6fb51e8c authored by Marco Zehe's avatar Marco Zehe
Browse files

Bug 1520779 Part 6: Return consistent results for paragraphs that contain...

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 a single line break at the beginning of the enclosing paragraph, or 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
parent 2209e8f5
Loading
Loading
Loading
Loading
+30 −4
Original line number Diff line number Diff line
@@ -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,30 @@ 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 (adjustedOffset == 0 || IsLineEndCharAt(adjustedOffset - 1)) {
          // However, if the line break is at the start of the enclosing
          // paragraph, or 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);
+13 −0
Original line number Diff line number Diff line
@@ -28,6 +28,17 @@
      testTextAtOffset("forced_wrap", BOUNDARY_PARAGRAPH,
      [[0, 2, "ab", 0, 2]]);

      // Test paragraphs 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
      testTextAtOffset("br_at_beginning", BOUNDARY_PARAGRAPH,
      [[0, 0, "\n", 0, 1],  // br treated as a separate paragraph
       [1, 2, "a\n", 1, 3],  // a and br treated as a paragraph
       [3, 4, "b", 3, 4]]);  // b treated as last paragraph

      // Test a paragraph with an embedded link.
      testTextAtOffset("pWithLink", BOUNDARY_PARAGRAPH,
      [[0, 3, "a" + kEmbedChar + "d", 0, 3]]);
@@ -66,6 +77,8 @@
    <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="br_at_beginning"><br>a<br>b</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>