зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1740847 - part 3: Make `WhiteSpaceVisibilityKeeper::ReplaceText()` track insert position in smaller block r=m_kato
Similar to the previous patch, this patch also make it track invisible white-space ranges and clear outdated things. And this makes it cache some information instead of tracking some changes because of performance reason. Depends on D131037 Differential Revision: https://phabricator.services.mozilla.com/D131038
This commit is contained in:
Родитель
d5a15f449b
Коммит
0dcfd11fa8
|
@ -886,15 +886,19 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
textFragmentDataAtEnd.EndRef().EqualsOrIsBefore(
|
||||
aRangeToBeReplaced.EndRef());
|
||||
|
||||
const EditorDOMRange invisibleLeadingWhiteSpaceRangeAtStart =
|
||||
EditorDOMRange invisibleLeadingWhiteSpaceRangeAtStart =
|
||||
textFragmentDataAtStart
|
||||
.GetNewInvisibleLeadingWhiteSpaceRangeIfSplittingAt(
|
||||
aRangeToBeReplaced.StartRef());
|
||||
const EditorDOMRange invisibleTrailingWhiteSpaceRangeAtEnd =
|
||||
const bool isInvisibleLeadingWhiteSpaceRangeAtStartPositioned =
|
||||
invisibleLeadingWhiteSpaceRangeAtStart.IsPositioned();
|
||||
EditorDOMRange invisibleTrailingWhiteSpaceRangeAtEnd =
|
||||
textFragmentDataAtEnd.GetNewInvisibleTrailingWhiteSpaceRangeIfSplittingAt(
|
||||
aRangeToBeReplaced.EndRef());
|
||||
const bool isInvisibleTrailingWhiteSpaceRangeAtEndPositioned =
|
||||
invisibleTrailingWhiteSpaceRangeAtEnd.IsPositioned();
|
||||
const Maybe<const VisibleWhiteSpacesData> visibleWhiteSpacesAtStart =
|
||||
!invisibleLeadingWhiteSpaceRangeAtStart.IsPositioned()
|
||||
!isInvisibleLeadingWhiteSpaceRangeAtStartPositioned
|
||||
? Some(textFragmentDataAtStart.VisibleWhiteSpacesDataRef())
|
||||
: Nothing();
|
||||
const PointPosition pointPositionWithVisibleWhiteSpacesAtStart =
|
||||
|
@ -904,7 +908,7 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
aRangeToBeReplaced.StartRef())
|
||||
: PointPosition::NotInSameDOMTree;
|
||||
const Maybe<const VisibleWhiteSpacesData> visibleWhiteSpacesAtEnd =
|
||||
!invisibleTrailingWhiteSpaceRangeAtEnd.IsPositioned()
|
||||
!isInvisibleTrailingWhiteSpaceRangeAtEndPositioned
|
||||
? Some(textFragmentDataAtEnd.VisibleWhiteSpacesDataRef())
|
||||
: Nothing();
|
||||
const PointPosition pointPositionWithVisibleWhiteSpacesAtEnd =
|
||||
|
@ -915,14 +919,31 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
: PointPosition::NotInSameDOMTree;
|
||||
|
||||
EditorDOMPoint pointToInsert(aRangeToBeReplaced.StartRef());
|
||||
EditorDOMPoint atNBSPReplaceableWithSP;
|
||||
if (!invisibleTrailingWhiteSpaceRangeAtEnd.IsPositioned() &&
|
||||
(pointPositionWithVisibleWhiteSpacesAtStart ==
|
||||
PointPosition::MiddleOfFragment ||
|
||||
pointPositionWithVisibleWhiteSpacesAtStart ==
|
||||
PointPosition::EndOfFragment)) {
|
||||
atNBSPReplaceableWithSP =
|
||||
textFragmentDataAtStart
|
||||
.GetPreviousNBSPPointIfNeedToReplaceWithASCIIWhiteSpace(
|
||||
pointToInsert);
|
||||
}
|
||||
nsAutoString theString(aStringToInsert);
|
||||
{
|
||||
// Some scoping for AutoTrackDOMPoint. This will track our insertion
|
||||
// point while we tweak any surrounding white-space
|
||||
AutoTrackDOMPoint tracker(aHTMLEditor.RangeUpdaterRef(), &pointToInsert);
|
||||
|
||||
if (invisibleTrailingWhiteSpaceRangeAtEnd.IsPositioned()) {
|
||||
if (!invisibleTrailingWhiteSpaceRangeAtEnd.Collapsed()) {
|
||||
AutoTrackDOMPoint trackPointToInsert(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToInsert);
|
||||
AutoTrackDOMPoint trackPrecedingNBSP(aHTMLEditor.RangeUpdaterRef(),
|
||||
&atNBSPReplaceableWithSP);
|
||||
AutoTrackDOMRange trackInvisibleLeadingWhiteSpaceRange(
|
||||
aHTMLEditor.RangeUpdaterRef(),
|
||||
&invisibleLeadingWhiteSpaceRangeAtStart);
|
||||
AutoTrackDOMRange trackInvisibleTrailingWhiteSpaceRange(
|
||||
aHTMLEditor.RangeUpdaterRef(),
|
||||
&invisibleTrailingWhiteSpaceRangeAtEnd);
|
||||
// XXX Why don't we remove all of the invisible white-spaces?
|
||||
MOZ_ASSERT(invisibleTrailingWhiteSpaceRangeAtEnd.StartRef() ==
|
||||
pointToInsert);
|
||||
|
@ -952,6 +973,16 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
.GetInclusiveNextNBSPPointIfNeedToReplaceWithASCIIWhiteSpace(
|
||||
aRangeToBeReplaced.EndRef());
|
||||
if (atNBSPReplacedWithASCIIWhiteSpace.IsSet()) {
|
||||
AutoTrackDOMPoint trackPointToInsert(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToInsert);
|
||||
AutoTrackDOMPoint trackPrecedingNBSP(aHTMLEditor.RangeUpdaterRef(),
|
||||
&atNBSPReplaceableWithSP);
|
||||
AutoTrackDOMRange trackInvisibleLeadingWhiteSpaceRange(
|
||||
aHTMLEditor.RangeUpdaterRef(),
|
||||
&invisibleLeadingWhiteSpaceRangeAtStart);
|
||||
AutoTrackDOMRange trackInvisibleTrailingWhiteSpaceRange(
|
||||
aHTMLEditor.RangeUpdaterRef(),
|
||||
&invisibleTrailingWhiteSpaceRangeAtEnd);
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(aHTMLEditor);
|
||||
nsresult rv = aHTMLEditor.ReplaceTextWithTransaction(
|
||||
MOZ_KnownLive(*atNBSPReplacedWithASCIIWhiteSpace.ContainerAsText()),
|
||||
|
@ -965,12 +996,14 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
|
||||
if (invisibleLeadingWhiteSpaceRangeAtStart.IsPositioned()) {
|
||||
if (!invisibleLeadingWhiteSpaceRangeAtStart.Collapsed()) {
|
||||
AutoTrackDOMPoint trackPointToInsert(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToInsert);
|
||||
AutoTrackDOMRange trackInvisibleTrailingWhiteSpaceRange(
|
||||
aHTMLEditor.RangeUpdaterRef(),
|
||||
&invisibleTrailingWhiteSpaceRangeAtEnd);
|
||||
// XXX Why don't we remove all of the invisible white-spaces?
|
||||
MOZ_ASSERT(invisibleLeadingWhiteSpaceRangeAtStart.EndRef() ==
|
||||
pointToInsert);
|
||||
// XXX If the DOM tree has been changed above,
|
||||
// invisibleLeadingWhiteSpaceRangeAtStart may be invalid now.
|
||||
// So, we may do something wrong here.
|
||||
nsresult rv = aHTMLEditor.DeleteTextAndTextNodesWithTransaction(
|
||||
invisibleLeadingWhiteSpaceRangeAtStart.StartRef(),
|
||||
invisibleLeadingWhiteSpaceRangeAtStart.EndRef(),
|
||||
|
@ -980,6 +1013,10 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
"HTMLEditor::DeleteTextAndTextNodesWithTransaction() failed");
|
||||
return rv;
|
||||
}
|
||||
// Don't refer the following variables anymore unless tracking the
|
||||
// change.
|
||||
atNBSPReplaceableWithSP.Clear();
|
||||
invisibleLeadingWhiteSpaceRangeAtStart.Clear();
|
||||
}
|
||||
}
|
||||
// Replace an NBSP at previous character of insertion point to an ASCII
|
||||
|
@ -988,18 +1025,16 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
// opportunity before the inserting string, but this causes
|
||||
// inconsistent result with inserting order. E.g., type white-space
|
||||
// n times with various order.
|
||||
else if (pointPositionWithVisibleWhiteSpacesAtStart ==
|
||||
PointPosition::MiddleOfFragment ||
|
||||
pointPositionWithVisibleWhiteSpacesAtStart ==
|
||||
PointPosition::EndOfFragment) {
|
||||
// XXX If the DOM tree has been changed above, pointToInsert` and/or
|
||||
// `visibleWhiteSpaces` may be invalid. So, we may do
|
||||
// something wrong here.
|
||||
else if (atNBSPReplaceableWithSP.IsInTextNode()) {
|
||||
EditorDOMPointInText atNBSPReplacedWithASCIIWhiteSpace =
|
||||
textFragmentDataAtStart
|
||||
.GetPreviousNBSPPointIfNeedToReplaceWithASCIIWhiteSpace(
|
||||
pointToInsert);
|
||||
if (atNBSPReplacedWithASCIIWhiteSpace.IsSet()) {
|
||||
atNBSPReplaceableWithSP.AsInText();
|
||||
if (!atNBSPReplacedWithASCIIWhiteSpace.IsEndOfContainer() &&
|
||||
atNBSPReplacedWithASCIIWhiteSpace.IsCharNBSP()) {
|
||||
AutoTrackDOMPoint trackPointToInsert(aHTMLEditor.RangeUpdaterRef(),
|
||||
&pointToInsert);
|
||||
AutoTrackDOMRange trackInvisibleTrailingWhiteSpaceRange(
|
||||
aHTMLEditor.RangeUpdaterRef(),
|
||||
&invisibleTrailingWhiteSpaceRangeAtEnd);
|
||||
AutoTransactionsConserveSelection dontChangeMySelection(aHTMLEditor);
|
||||
nsresult rv = aHTMLEditor.ReplaceTextWithTransaction(
|
||||
MOZ_KnownLive(*atNBSPReplacedWithASCIIWhiteSpace.ContainerAsText()),
|
||||
|
@ -1008,10 +1043,12 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
NS_WARNING("HTMLEditor::ReplaceTextWithTransaction() failed failed");
|
||||
return rv;
|
||||
}
|
||||
// Don't refer the following variables anymore unless tracking the
|
||||
// change.
|
||||
atNBSPReplaceableWithSP.Clear();
|
||||
invisibleLeadingWhiteSpaceRangeAtStart.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// After this block, pointToInsert is modified by AutoTrackDOMPoint.
|
||||
}
|
||||
|
||||
// If white-space and/or linefeed characters are collapsible, and inserting
|
||||
|
@ -1033,7 +1070,7 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
if (isCollapsibleChar(theString[0])) {
|
||||
// If inserting string will follow some invisible leading white-spaces,
|
||||
// the string needs to start with an NBSP.
|
||||
if (invisibleLeadingWhiteSpaceRangeAtStart.IsPositioned()) {
|
||||
if (isInvisibleLeadingWhiteSpaceRangeAtStartPositioned) {
|
||||
theString.SetCharAt(HTMLEditUtils::kNBSP, 0);
|
||||
}
|
||||
// If inserting around visible white-spaces, check whether the previous
|
||||
|
@ -1063,7 +1100,7 @@ nsresult WhiteSpaceVisibilityKeeper::ReplaceText(
|
|||
if (isCollapsibleChar(theString[lastCharIndex])) {
|
||||
// If inserting string will be followed by some invisible trailing
|
||||
// white-spaces, the string needs to end with an NBSP.
|
||||
if (invisibleTrailingWhiteSpaceRangeAtEnd.IsPositioned()) {
|
||||
if (isInvisibleTrailingWhiteSpaceRangeAtEndPositioned) {
|
||||
theString.SetCharAt(HTMLEditUtils::kNBSP, lastCharIndex);
|
||||
}
|
||||
// If inserting around visible white-spaces, check whether the inclusive
|
||||
|
|
Загрузка…
Ссылка в новой задаче