зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
d03f6422fd
Коммит
a8d927de19
|
@ -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();
|
||||||
|
|
Загрузка…
Ссылка в новой задаче