Commit e28f43b4 authored by Masayuki Nakano's avatar Masayuki Nakano
Browse files

Bug 1825693 - Make `ContentCacheInChild::CacheTextRects` stop emplacing `Selection` r=m_kato

It creates no range `Selection` if `mSelection` has not been emplaced.
However, we don't want `Selection` in the case because `mText` may be nothing
and that violates the dependency.  Therefore, it should stop creating
`Selection` in the case.

Note that first character rect will be cached later even if there is no
`Selection`.  However, this should not occur in usual case because `focus`
notification should've already initialized `mText` and `mSelection`.

Differential Revision: https://phabricator.services.mozilla.com/D178731
parent 5f53d66d
Loading
Loading
Loading
Loading
+45 −53
Original line number Diff line number Diff line
@@ -50,8 +50,7 @@ bool ContentCache::IsValid() const {
    }
  } else {
    // mSelection depends on mText.
    if (mSelection.isSome() && (NS_WARN_IF(mText.isNothing()) ||
                                NS_WARN_IF(!mSelection->IsValidIn(*mText)))) {
    if (mSelection.isSome() && NS_WARN_IF(!mSelection->IsValidIn(*mText))) {
      return false;
    }

@@ -161,6 +160,7 @@ bool ContentCacheInChild::CacheSelection(nsIWidget* aWidget,
       PrintStringDetail(mText, PrintStringDetail::kMaxLengthForEditor).get()));

  mSelection.reset();
  mCaret.reset();

  if (mText.isNothing()) {
    return false;
@@ -203,7 +203,7 @@ bool ContentCacheInChild::CacheCaret(nsIWidget* aWidget,
                                     const IMENotification* aNotification) {
  mCaret.reset();

  if (MOZ_UNLIKELY(mSelection.isNothing())) {
  if (mSelection.isNothing()) {
    return false;
  }

@@ -274,8 +274,7 @@ bool ContentCacheInChild::CacheCaretAndTextRects(
          ("0x%p CacheCaretAndTextRects(aWidget=0x%p, aNotification=%s)", this,
           aWidget, GetNotificationName(aNotification)));

  const bool caretCached =
      mSelection.isSome() && CacheCaret(aWidget, aNotification);
  const bool caretCached = CacheCaret(aWidget, aNotification);
  const bool textRectsCached = CacheTextRects(aWidget, aNotification);
  MOZ_DIAGNOSTIC_ASSERT(IsValid());
  return caretCached || textRectsCached;
@@ -424,9 +423,10 @@ bool ContentCacheInChild::CacheTextRects(nsIWidget* aWidget,
    mTextRectArray.reset();
  }

  if (mSelection.isSome()) {
    // Set mSelection->mAnchorCharRects
    // If we've already have the rect in mTextRectArray, save the query cost.
  if (mSelection.isSome() && mSelection->mHasRange && mTextRectArray.isSome() &&
    if (mSelection->mHasRange && mTextRectArray.isSome() &&
        mTextRectArray->IsOffsetInRange(mSelection->mAnchor) &&
        (!mSelection->mAnchor ||
         mTextRectArray->IsOffsetInRange(mSelection->mAnchor - 1))) {
@@ -440,16 +440,15 @@ bool ContentCacheInChild::CacheTextRects(nsIWidget* aWidget,
    // Otherwise, get it from content even if there is no selection ranges.
    else {
      RectArray rects;
    const uint32_t startOffset =
        mSelection.isSome() && mSelection->mHasRange && mSelection->mAnchor
      const uint32_t startOffset = mSelection->mHasRange && mSelection->mAnchor
                                       ? mSelection->mAnchor - 1u
                                       : 0u;
      const uint32_t length =
        mSelection.isSome() && mSelection->mHasRange && mSelection->mAnchor
            ? 2u
            : 1u;
    if (NS_WARN_IF(!QueryCharRectArray(aWidget, startOffset, length, rects))) {
      MOZ_LOG(sContentCacheLog, LogLevel::Error,
          mSelection->mHasRange && mSelection->mAnchor ? 2u : 1u;
      if (NS_WARN_IF(
              !QueryCharRectArray(aWidget, startOffset, length, rects))) {
        MOZ_LOG(
            sContentCacheLog, LogLevel::Error,
            ("0x%p   CacheTextRects(), FAILED, couldn't retrieve text rect "
             "array around the selection anchor (%s)",
             this,
@@ -459,9 +458,6 @@ bool ContentCacheInChild::CacheTextRects(nsIWidget* aWidget,
        MOZ_ASSERT_IF(mSelection.isSome(),
                      mSelection->mAnchorCharRects[eNextCharRect].IsEmpty());
      } else if (rects.Length()) {
      if (mSelection.isNothing()) {
        mSelection.emplace();  // With no range
      }
        if (rects.Length() > 1) {
          mSelection->mAnchorCharRects[ePrevCharRect] = rects[0];
          mSelection->mAnchorCharRects[eNextCharRect] = rects[1];
@@ -472,10 +468,6 @@ bool ContentCacheInChild::CacheTextRects(nsIWidget* aWidget,
      }
    }

  // Note that if mSelection is Nothing here, we've already failed to get
  // rects in the `else` block above.  In such case, we cannot get character
  // rects around focus point.
  if (mSelection.isSome()) {
    // Set mSelection->mFocusCharRects
    // If selection is collapsed (including no selection case), the focus char
    // rects are same as the anchor char rects so that we can just copy them.