Bug 1647556 - part 8: Make `WSRunObject::PrepareToSplitAcrossBlocksPriv()` stop using `FindNearestFragment()` r=m_kato

It looks for same `WSFragment` twice with comparing text and what it looks for
is the instance whose `IsVisibleAndMiddleOfLine()` returns `true`.
Additionally, doing twice is for checking only whether the split point is
start or end of the range.  Therefore, we can make it simpler with using
`TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine()`.

Differential Revision: https://phabricator.services.mozilla.com/D82281
This commit is contained in:
Masayuki Nakano 2020-07-09 05:04:56 +00:00
Родитель e660db877a
Коммит e63d0f9e18
2 изменённых файлов: 63 добавлений и 14 удалений

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

@ -1376,18 +1376,28 @@ nsresult WSRunObject::PrepareToDeleteRangePriv(WSRunObject* aEndObject) {
}
nsresult WSRunObject::PrepareToSplitAcrossBlocksPriv() {
// used to prepare ws to be split across two blocks. The main issue
// here is make sure normalWS doesn't end up becoming non-significant
// leading or trailing ws after the split.
// used to prepare white-space sequence to be split across two blocks.
// The main issue here is make sure white-spaces around the split point
// doesn't end up becoming non-significant leading or trailing ws after
// the split.
Maybe<WSFragment> visibleWSFragmentInMiddleOfLine =
TextFragmentData(mStart, mEnd, mNBSPData, mPRE)
.CreateWSFragmentForVisibleAndMiddleOfLine();
if (visibleWSFragmentInMiddleOfLine.isNothing()) {
return NS_OK; // No visible white-space sequence.
}
// get the runs before and after selection
const WSFragment* beforeRun = FindNearestFragment(mScanStartPoint, false);
const WSFragment* afterRun = FindNearestFragment(mScanStartPoint, true);
PointPosition pointPositionWithVisibleWhiteSpaces =
visibleWSFragmentInMiddleOfLine.ref().ComparePoint(mScanStartPoint);
// adjust normal ws in afterRun if needed
if (afterRun && afterRun->IsVisibleAndMiddleOfHardLine()) {
// make sure leading char of following ws is an nbsp, so that it will show
// up
// XXX If we split white-space sequence, the following code modify the DOM
// tree twice. This is not reasonable and the latter change may touch
// wrong position. We should do this once.
// If we insert block boundary to start or middle of the white-space sequence,
// the character at the insertion point needs to be an NBSP.
if (pointPositionWithVisibleWhiteSpaces == PointPosition::StartOfFragment ||
pointPositionWithVisibleWhiteSpaces == PointPosition::MiddleOfFragment) {
EditorDOMPointInText atNextCharOfStart =
GetInclusiveNextEditableCharPoint(mScanStartPoint);
if (atNextCharOfStart.IsSet() && !atNextCharOfStart.IsEndOfContainer() &&
@ -1411,10 +1421,11 @@ nsresult WSRunObject::PrepareToSplitAcrossBlocksPriv() {
}
}
// adjust normal ws in beforeRun if needed
if (beforeRun && beforeRun->IsVisibleAndMiddleOfHardLine()) {
// make sure trailing char of starting ws is an nbsp, so that it will show
// up
// If we insert block boundary to middle of or end of the white-space
// sequence, the previous character at the insertion point needs to be an
// NBSP.
if (pointPositionWithVisibleWhiteSpaces == PointPosition::MiddleOfFragment ||
pointPositionWithVisibleWhiteSpaces == PointPosition::EndOfFragment) {
EditorDOMPointInText atPreviousCharOfStart =
GetPreviousEditableCharPoint(mScanStartPoint);
if (atPreviousCharOfStart.IsSet() &&

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

@ -522,6 +522,42 @@ class MOZ_STACK_CLASS WSRunScanner {
mRightWSType == WSType::OtherBlockBoundary;
}
/**
* ComparePointWitWSFragment() compares aPoint with this fragment.
*/
enum class PointPosition {
BeforeStartOfFragment,
StartOfFragment,
MiddleOfFragment,
EndOfFragment,
AfterEndOfFragment,
NotInSameDOMTree,
};
template <typename EditorDOMPointType>
PointPosition ComparePoint(const EditorDOMPointType& aPoint) const {
MOZ_ASSERT(aPoint.IsSetAndValid());
const EditorRawDOMPoint start = RawStartPoint();
if (start == aPoint) {
return PointPosition::StartOfFragment;
}
const EditorRawDOMPoint end = RawEndPoint();
if (end == aPoint) {
return PointPosition::EndOfFragment;
}
const bool startIsBeforePoint = start.IsBefore(aPoint);
const bool pointIsBeforeEnd = aPoint.IsBefore(end);
if (startIsBeforePoint && pointIsBeforeEnd) {
return PointPosition::MiddleOfFragment;
}
if (startIsBeforePoint) {
return PointPosition::AfterEndOfFragment;
}
if (pointIsBeforeEnd) {
return PointPosition::BeforeStartOfFragment;
}
return PointPosition::NotInSameDOMTree;
}
private:
WSType mLeftWSType, mRightWSType;
Visible mIsVisible;
@ -529,6 +565,8 @@ class MOZ_STACK_CLASS WSRunScanner {
EndOfHardLine mIsEndOfHardLine;
};
using PointPosition = WSFragment::PointPosition;
using WSFragmentArray = AutoTArray<WSFragment, 3>;
const WSFragmentArray& WSFragmentArrayRef() const {
const_cast<WSRunScanner*>(this)->EnsureWSFragments();