Bug 1241631 - Don't trim leading whitespace from soft-wrapped lines when getting rendered text for a11y or .innerText. r=mats

Differential Revision: https://phabricator.services.mozilla.com/D45157

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jonathan Kew 2019-09-17 17:36:13 +00:00
Родитель d03f6422fd
Коммит a8d927de19
2 изменённых файлов: 41 добавлений и 16 удалений

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

@ -19,7 +19,7 @@
// __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__ // __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
var IDs = [ "i1", "d1", "e1", "t1" ]; var IDs = [ "i1", "d1", "d1wrap", "e1", "t1" ];
testCharacterCount(IDs, 15); testCharacterCount(IDs, 15);
@ -96,6 +96,7 @@
<input id="i1" value="hello my friend"/> <input id="i1" value="hello my friend"/>
<div id="d1">hello my friend</div> <div id="d1">hello my friend</div>
<div id="d1wrap" style="word-wrap:break-word; width:1px">hello my friend</div>
<div id="e1" contenteditable="true">hello my friend</div> <div id="e1" contenteditable="true">hello my friend</div>
<textarea id="t1">hello my friend</textarea> <textarea id="t1">hello my friend</textarea>

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

@ -9740,15 +9740,25 @@ static void TransformChars(nsTextFrame* aFrame, const nsStyleText* aStyle,
} }
} }
static bool LineEndsInHardLineBreak(nsTextFrame* aFrame, static void LineStartsOrEndsAtHardLineBreak(nsTextFrame* aFrame,
nsBlockFrame* aLineContainer) { nsBlockFrame* aLineContainer,
bool* aStartsAtHardBreak,
bool* aEndsAtHardBreak) {
bool foundValidLine; bool foundValidLine;
nsBlockInFlowLineIterator iter(aLineContainer, aFrame, &foundValidLine); nsBlockInFlowLineIterator iter(aLineContainer, aFrame, &foundValidLine);
if (!foundValidLine) { if (!foundValidLine) {
NS_ERROR("Invalid line!"); NS_ERROR("Invalid line!");
return true; *aStartsAtHardBreak = *aEndsAtHardBreak = true;
return;
}
*aEndsAtHardBreak = !iter.GetLine()->IsLineWrapped();
if (iter.Prev()) {
*aStartsAtHardBreak = !iter.GetLine()->IsLineWrapped();
} else {
// Hit block boundary
*aStartsAtHardBreak = true;
} }
return !iter.GetLine()->IsLineWrapped();
} }
nsIFrame::RenderedText nsTextFrame::GetRenderedText( nsIFrame::RenderedText nsTextFrame::GetRenderedText(
@ -9786,11 +9796,11 @@ nsIFrame::RenderedText nsTextFrame::GetRenderedText(
} }
gfxSkipCharsIterator tmpIter = iter; gfxSkipCharsIterator tmpIter = iter;
// Whether we need to trim whitespaces after the text frame. // Check if the frame starts/ends at a hard line break, to determine
bool trimAfter; // whether whitespace should be trimmed.
if (!textFrame->IsAtEndOfLine() || bool startsAtHardBreak, endsAtHardBreak;
aTrimTrailingWhitespace != TrailingWhitespace::Trim) { if (!(GetStateBits() & (TEXT_START_OF_LINE | TEXT_END_OF_LINE))) {
trimAfter = false; startsAtHardBreak = endsAtHardBreak = false;
} else if (nsBlockFrame* thisLc = } else if (nsBlockFrame* thisLc =
do_QueryFrame(FindLineContainer(textFrame))) { do_QueryFrame(FindLineContainer(textFrame))) {
if (thisLc != lineContainer) { if (thisLc != lineContainer) {
@ -9799,17 +9809,31 @@ nsIFrame::RenderedText nsTextFrame::GetRenderedText(
autoLineCursor.reset(); autoLineCursor.reset();
autoLineCursor.emplace(lineContainer); autoLineCursor.emplace(lineContainer);
} }
trimAfter = LineEndsInHardLineBreak(textFrame, lineContainer); LineStartsOrEndsAtHardLineBreak(textFrame, lineContainer,
&startsAtHardBreak, &endsAtHardBreak);
} else { } else {
// Weird situation where we have a line layout without a block. // Weird situation where we have a line layout without a block.
// No soft breaks occur in this situation. // No soft breaks occur in this situation.
trimAfter = true; startsAtHardBreak = endsAtHardBreak = true;
} }
// Skip to the start of the text run, past ignored chars at start of line // Whether we need to trim whitespaces after the text frame.
TrimmedOffsets trimmedOffsets = textFrame->GetTrimmedOffsets( // TrimmedOffsetFlags::Default will allow trimming; we set NoTrim* flags
textFrag, (trimAfter ? TrimmedOffsetFlags::Default // in the cases where this should not occur.
: TrimmedOffsetFlags::NoTrimAfter)); TrimmedOffsetFlags trimFlags = TrimmedOffsetFlags::Default;
if (!textFrame->IsAtEndOfLine() ||
aTrimTrailingWhitespace != TrailingWhitespace::Trim ||
!endsAtHardBreak) {
trimFlags |= TrimmedOffsetFlags::NoTrimAfter;
}
// Whether to trim whitespaces before the text frame.
if (!startsAtHardBreak) {
trimFlags |= TrimmedOffsetFlags::NoTrimBefore;
}
TrimmedOffsets trimmedOffsets =
textFrame->GetTrimmedOffsets(textFrag, trimFlags);
bool trimmedSignificantNewline = bool trimmedSignificantNewline =
trimmedOffsets.GetEnd() < GetContentEnd() && trimmedOffsets.GetEnd() < GetContentEnd() &&
HasSignificantTerminalNewline(); HasSignificantTerminalNewline();