diff --git a/editor/libeditor/WSRunObject.cpp b/editor/libeditor/WSRunObject.cpp index d6250042e739..57f2b57554af 100644 --- a/editor/libeditor/WSRunObject.cpp +++ b/editor/libeditor/WSRunObject.cpp @@ -1046,6 +1046,52 @@ WSRunScanner::TextFragmentData::CreateWSFragmentForVisibleAndMiddleOfLine() return Some(fragment); } + // If all of the range is invisible leading or trailing white-spaces, + // there is no visible content. + const auto leadingWhiteSpaceRange = + GetInvisibleLeadingWhiteSpaceRange(); + const bool maybeHaveLeadingWhiteSpaces = + leadingWhiteSpaceRange.StartRef().IsSet() || + leadingWhiteSpaceRange.EndRef().IsSet(); + if (maybeHaveLeadingWhiteSpaces && + leadingWhiteSpaceRange.StartRef() == mStart.PointRef() && + leadingWhiteSpaceRange.EndRef() == mEnd.PointRef()) { + return Nothing(); + } + const auto trailingWhiteSpaceRange = + GetInvisibleTrailingWhiteSpaceRange(); + const bool maybeHaveTrailingWhiteSpaces = + trailingWhiteSpaceRange.StartRef().IsSet() || + trailingWhiteSpaceRange.EndRef().IsSet(); + if (maybeHaveTrailingWhiteSpaces && + trailingWhiteSpaceRange.StartRef() == mStart.PointRef() && + trailingWhiteSpaceRange.EndRef() == mEnd.PointRef()) { + return Nothing(); + } + + if (!StartsFromHardLineBreak()) { + fragment.MarkAsVisible(); + if (mStart.PointRef().IsSet()) { + fragment.mStartNode = mStart.PointRef().GetContainer(); + fragment.mStartOffset = mStart.PointRef().Offset(); + } + fragment.SetStartFrom(mStart.RawReason()); + if (!maybeHaveTrailingWhiteSpaces) { + fragment.mEndNode = mEnd.PointRef().GetContainer(); + fragment.mEndOffset = mEnd.PointRef().Offset(); + fragment.SetEndBy(mEnd.RawReason()); + // XXX At here, `EndsByBlockBoundary()` may be true. So, the method name, + // "MiddleOfHardLine" is wrong. + return Some(fragment); + } + if (trailingWhiteSpaceRange.StartRef().IsSet()) { + fragment.mEndNode = trailingWhiteSpaceRange.StartRef().GetContainer(); + fragment.mEndOffset = trailingWhiteSpaceRange.StartRef().Offset(); + } + fragment.SetEndByTrailingWhiteSpaces(); + return Some(fragment); + } + // TODO: Implement other cases in the following patches. return Nothing(); } @@ -1129,31 +1175,16 @@ void WSRunScanner::TextFragmentData::InitializeWSFragmentArray( } if (!StartsFromHardLineBreak()) { - WSFragment* startRun = aFragments.AppendElement(); - startRun->MarkAsVisible(); - if (mStart.PointRef().IsSet()) { - startRun->mStartNode = mStart.PointRef().GetContainer(); - startRun->mStartOffset = mStart.PointRef().Offset(); - } - startRun->SetStartFrom(mStart.RawReason()); - if (!maybeHaveTrailingWhiteSpaces) { - startRun->mEndNode = mEnd.PointRef().GetContainer(); - startRun->mEndOffset = mEnd.PointRef().Offset(); - startRun->SetEndBy(mEnd.RawReason()); + aFragments.AppendElement(CreateWSFragmentForVisibleAndMiddleOfLine().ref()); + if (!aFragments[0].EndsByTrailingWhiteSpaces()) { return; } - if (trailingWhiteSpaceRange.StartRef().IsSet()) { - startRun->mEndNode = trailingWhiteSpaceRange.StartRef().GetContainer(); - startRun->mEndOffset = trailingWhiteSpaceRange.StartRef().Offset(); - } - startRun->SetEndByTrailingWhiteSpaces(); - // set up next run WSFragment* lastRun = aFragments.AppendElement(); lastRun->MarkAsEndOfHardLine(); - lastRun->mStartNode = startRun->mEndNode; - lastRun->mStartOffset = startRun->mEndOffset; + lastRun->mStartNode = aFragments[0].mEndNode; + lastRun->mStartOffset = aFragments[0].mEndOffset; lastRun->SetStartFromNormalWhiteSpaces(); // XXX Why don't we set end boundary here?? lastRun->SetEndBy(mEnd.RawReason()); diff --git a/editor/libeditor/WSRunObject.h b/editor/libeditor/WSRunObject.h index 2a60a501acee..3fe49bbed587 100644 --- a/editor/libeditor/WSRunObject.h +++ b/editor/libeditor/WSRunObject.h @@ -510,6 +510,9 @@ class MOZ_STACK_CLASS WSRunScanner { mRightWSType = WSType::TrailingWhiteSpaces; } bool EndsByNormalText() const { return mRightWSType == WSType::NormalText; } + bool EndsByTrailingWhiteSpaces() const { + return mRightWSType == WSType::TrailingWhiteSpaces; + } bool EndsBySpecialContent() const { return mRightWSType == WSType::SpecialContent; }