Backed out 11 changesets (bug 1587433) for bustages on RangeBoundary.h. CLOSED TREE
authorCsoregi Natalia <ncsoregi@mozilla.com>
Mon, 16 Dec 2019 13:25:51 +0200
changeset 507079 c0c22dbdd5b8d9cd13d58e7a1894655404911801
parent 507078 18f8d61039b0705cb0c40d5640e54c174da3ce84
child 507080 57ee8e8fa11b3df04fd7a42169d0808a4100b23b
push id36922
push userncsoregi@mozilla.com
push dateMon, 16 Dec 2019 17:21:47 +0000
treeherdermozilla-central@27d0d6cc2131 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1587433
milestone73.0a1
backs out18f8d61039b0705cb0c40d5640e54c174da3ce84
69ad70a4f85e79b26e1a86b6f134f4854a326eb1
79ec11ba7fde31452a85d2f854e9f4831ffb5582
f8a7e23843b842bb01c695a0ba16f7d86bd08ec3
f9255884980fc6a89687af026785c672b702aed2
50a798e664a1d32b734b47b68c0213d149abe604
b225586edea68a05b2b3d94888c01aff69bed460
b1d9e55ece86cf22e837849549c0390b2d9b0411
7ebbcb2da48889068c9606106861ebcd95217de5
4032df295a67aca4366d33ebb0ba9a57305d1bcc
0e1577031addefed6aeaa5df8a724b73edb690a0
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out 11 changesets (bug 1587433) for bustages on RangeBoundary.h. CLOSED TREE Backed out changeset 18f8d61039b0 (bug 1587433) Backed out changeset 69ad70a4f85e (bug 1587433) Backed out changeset 79ec11ba7fde (bug 1587433) Backed out changeset f8a7e23843b8 (bug 1587433) Backed out changeset f9255884980f (bug 1587433) Backed out changeset 50a798e664a1 (bug 1587433) Backed out changeset b225586edea6 (bug 1587433) Backed out changeset b1d9e55ece86 (bug 1587433) Backed out changeset 7ebbcb2da488 (bug 1587433) Backed out changeset 4032df295a67 (bug 1587433) Backed out changeset 0e1577031add (bug 1587433)
dom/base/AbstractRange.cpp
dom/base/AbstractRange.h
dom/base/RangeBoundary.h
dom/base/RangeUtils.cpp
dom/base/RangeUtils.h
dom/base/Selection.cpp
dom/base/Selection.h
dom/base/StaticRange.cpp
dom/base/nsContentUtils.cpp
dom/base/nsRange.cpp
dom/base/nsRange.h
dom/events/ContentEventHandler.cpp
dom/events/ContentEventHandler.h
editor/libeditor/DeleteRangeTransaction.cpp
editor/libeditor/HTMLEditSubActionHandler.cpp
--- a/dom/base/AbstractRange.cpp
+++ b/dom/base/AbstractRange.cpp
@@ -102,20 +102,17 @@ nsresult AbstractRange::SetStartAndEndIn
 
   if (aStartBoundary.Container() == aEndBoundary.Container()) {
     if (!aEndBoundary.IsSetAndValid()) {
       return NS_ERROR_DOM_INDEX_SIZE_ERR;
     }
     // XXX: Offsets - handle this more efficiently.
     // If the end offset is less than the start offset, this should be
     // collapsed at the end offset.
-    if (*aStartBoundary.Offset(
-            RangeBoundaryBase<SPT, SRT>::OffsetFilter::kValidOffsets) >
-        *aEndBoundary.Offset(
-            RangeBoundaryBase<EPT, ERT>::OffsetFilter::kValidOffsets)) {
+    if (aStartBoundary.Offset() > aEndBoundary.Offset()) {
       aRange->DoSetRange(aEndBoundary, aEndBoundary, newStartRoot);
     } else {
       aRange->DoSetRange(aStartBoundary, aEndBoundary, newStartRoot);
     }
     return NS_OK;
   }
 
   nsINode* newEndRoot = RangeUtils::ComputeRootNode(aEndBoundary.Container());
--- a/dom/base/AbstractRange.h
+++ b/dom/base/AbstractRange.h
@@ -45,49 +45,45 @@ class AbstractRange : public nsISupports
   // following WebIDL methods are called only when `mIsPositioned` is true.
   // So, it does not make sense to take `ErrorResult` as their parameter
   // since its destruction cost may appear in profile.  If you create range
   // object from C++ and needs to check whether it's positioned, should call
   // `IsPositioned()` directly.
 
   nsINode* GetStartContainer() const { return mStart.Container(); }
   nsINode* GetEndContainer() const { return mEnd.Container(); }
-
-  // FYI: Returns 0 if it's not positioned.
   uint32_t StartOffset() const {
-    return static_cast<uint32_t>(
-        *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets));
+    // FYI: Returns 0 if it's not positioned.
+    return static_cast<uint32_t>(mStart.Offset());
   }
-
-  // FYI: Returns 0 if it's not positioned.
   uint32_t EndOffset() const {
-    return static_cast<uint32_t>(
-        *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets));
+    // FYI: Returns 0 if it's not positioned.
+    return static_cast<uint32_t>(mEnd.Offset());
   }
   bool Collapsed() const {
     return !mIsPositioned || (mStart.Container() == mEnd.Container() &&
-                              StartOffset() == EndOffset());
+                              mStart.Offset() == mEnd.Offset());
   }
 
   nsINode* GetParentObject() const { return mOwner; }
   virtual JSObject* WrapObject(JSContext* aCx,
                                JS::Handle<JSObject*> aGivenProto) override;
 
  protected:
   template <typename SPT, typename SRT, typename EPT, typename ERT,
             typename RangeType>
   static nsresult SetStartAndEndInternal(
       const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
       const RangeBoundaryBase<EPT, ERT>& aEndBoundary, RangeType* aRange);
 
   RefPtr<Document> mOwner;
   RangeBoundary mStart;
   RangeBoundary mEnd;
-  // `true` if `mStart` and `mEnd` are set for StaticRange or set and valid
-  // for nsRange.
+  // `true` if `mStart` has a container and potentially other conditions are
+  // fulfilled.
   bool mIsPositioned;
 
   // Used by nsRange, but this should have this for minimizing the size.
   bool mIsGenerated;
   // Used by nsRange, but this should have this for minimizing the size.
   bool mCalledByJS;
 };
 
--- a/dom/base/RangeBoundary.h
+++ b/dom/base/RangeBoundary.h
@@ -6,18 +6,16 @@
 
 #ifndef mozilla_RangeBoundary_h
 #define mozilla_RangeBoundary_h
 
 #include "nsCOMPtr.h"
 #include "nsIContent.h"
 #include "mozilla/Maybe.h"
 
-class nsRange;
-
 namespace mozilla {
 
 template <typename T, typename U>
 class EditorDOMPointBase;
 
 // This class will maintain a reference to the child immediately
 // before the boundary's offset. We try to avoid computing the
 // offset as much as possible and just ensure mRef points to the
@@ -45,25 +43,21 @@ typedef RangeBoundaryBase<nsINode*, nsIC
 // AddRef/Release calls.
 template <typename ParentType, typename RefType>
 class RangeBoundaryBase {
   template <typename T, typename U>
   friend class RangeBoundaryBase;
   template <typename T, typename U>
   friend class EditorDOMPointBase;
 
-  friend nsRange;
-
   friend void ImplCycleCollectionTraverse(nsCycleCollectionTraversalCallback&,
                                           RangeBoundary&, const char*,
                                           uint32_t);
   friend void ImplCycleCollectionUnlink(RangeBoundary&);
 
-  static const uint32_t kFallbackOffset = 0;
-
  public:
   RangeBoundaryBase(nsINode* aContainer, nsIContent* aRef)
       : mParent(aContainer), mRef(aRef) {
     if (mRef) {
       NS_WARNING_ASSERTION(mRef->GetParentNode() == mParent,
                            "Initializing RangeBoundary with invalid value");
     } else {
       mOffset.emplace(0);
@@ -99,22 +93,20 @@ class RangeBoundaryBase {
 
   nsINode* Container() const { return mParent; }
 
   nsIContent* GetChildAtOffset() const {
     if (!mParent || !mParent->IsContainerNode()) {
       return nullptr;
     }
     if (!mRef) {
-      MOZ_ASSERT(*Offset(OffsetFilter::kValidOrInvalidOffsets) == 0,
-                 "invalid RangeBoundary");
+      MOZ_ASSERT(Offset() == 0, "invalid RangeBoundary");
       return mParent->GetFirstChild();
     }
-    MOZ_ASSERT(mParent->GetChildAt_Deprecated(
-                   *Offset(OffsetFilter::kValidOrInvalidOffsets)) ==
+    MOZ_ASSERT(mParent->GetChildAt_Deprecated(Offset()) ==
                mRef->GetNextSibling());
     return mRef->GetNextSibling();
   }
 
   /**
    * GetNextSiblingOfChildOffset() returns next sibling of a child at offset.
    * If this refers after the last child or the container cannot have children,
    * this returns nullptr with warning.
@@ -141,88 +133,59 @@ class RangeBoundaryBase {
     }
     if (NS_WARN_IF(!mRef)) {
       // Already referring the start of the container.
       return nullptr;
     }
     return mRef;
   }
 
-  enum class OffsetFilter { kValidOffsets, kValidOrInvalidOffsets };
+  uint32_t Offset() const {
+    if (mOffset.isSome()) {
+      return mOffset.value();
+    }
 
-  /**
-   * @return maybe an offset, depending on aOffsetFilter. If it is:
-   *         kValidOffsets: if the offset is valid, it, Nothing{} otherwise.
-   *         kValidOrInvalidOffsets: the internally stored offset, even if
-   *                                 invalid, or if not available, a defined
-   *                                 default value. That is, always some value.
-   */
-  Maybe<uint32_t> Offset(const OffsetFilter aOffsetFilter) const {
-    switch (aOffsetFilter) {
-      case OffsetFilter::kValidOffsets: {
-        if (IsSetAndValid()) {
-          if (!mOffset) {
-            DetermineOffsetFromReference();
-          }
-        }
-        return mOffset;
-      }
-      case OffsetFilter::kValidOrInvalidOffsets: {
-        if (mOffset.isSome()) {
-          return mOffset;
-        }
+    if (!mParent) {
+      return 0;
+    }
 
-        if (mParent) {
-          DetermineOffsetFromReference();
-          return mOffset;
-        }
-
-        return Some(kFallbackOffset);
-      }
-    }
-  }
-
- private:
-  void DetermineOffsetFromReference() const {
-    MOZ_ASSERT(mParent);
     MOZ_ASSERT(mRef);
     MOZ_ASSERT(mRef->GetParentNode() == mParent);
 
     const int32_t index = mParent->ComputeIndexOf(mRef);
     MOZ_ASSERT(index >= 0);
     mOffset.emplace(static_cast<uint32_t>(index + 1));
+
+    return mOffset.value();
   }
 
   void InvalidateOffset() {
     MOZ_ASSERT(mParent);
     MOZ_ASSERT(mParent->IsContainerNode(),
                "Range is positioned on a text node!");
 
     if (!mRef) {
       MOZ_ASSERT(mOffset.isSome() && mOffset.value() == 0,
                  "Invalidating offset of invalid RangeBoundary?");
       return;
     }
     mOffset.reset();
   }
 
- public:
   bool IsSet() const { return mParent && (mRef || mOffset.isSome()); }
 
   bool IsSetAndValid() const {
     if (!IsSet()) {
       return false;
     }
 
     if (Ref()) {
       return Ref()->GetParentNode() == Container();
     }
-
-    MOZ_ASSERT(mOffset.isSome());
-    return *mOffset <= Container()->Length();
+    return Offset() <= Container()->Length();
   }
 
   bool IsStartOfContainer() const {
     // We're at the first point in the container if we don't have a reference,
     // and our offset is 0. If we don't have a Ref, we should already have an
     // offset, so we can just directly fetch it.
     return !Ref() && mOffset.value() == 0;
   }
@@ -269,19 +232,16 @@ class RangeBoundaryBase {
 
  private:
   ParentType mParent;
   RefType mRef;
 
   mutable mozilla::Maybe<uint32_t> mOffset;
 };
 
-template <typename ParentType, typename RefType>
-const uint32_t RangeBoundaryBase<ParentType, RefType>::kFallbackOffset;
-
 inline void ImplCycleCollectionUnlink(RangeBoundary& aField) {
   ImplCycleCollectionUnlink(aField.mParent);
   ImplCycleCollectionUnlink(aField.mRef);
 }
 
 inline void ImplCycleCollectionTraverse(
     nsCycleCollectionTraversalCallback& aCallback, RangeBoundary& aField,
     const char* aName, uint32_t aFlags) {
--- a/dom/base/RangeUtils.cpp
+++ b/dom/base/RangeUtils.cpp
@@ -149,31 +149,27 @@ nsresult RangeUtils::CompareNodeToRange(
   // being -1 and it seems to deal with it, or at least we aren't aware of any
   // problems arising because of it. We don't have a better idea how to get
   // rid of the warning without much larger changes so we do this just to
   // silence the warning. (Bug 1438996)
 
   // is RANGE(start) <= NODE(start) ?
   bool disconnected = false;
   *aNodeIsBeforeRange =
-      nsContentUtils::ComparePoints(
-          aAbstractRange->StartRef().Container(),
-          *aAbstractRange->StartRef().Offset(
-              RangeBoundary::OffsetFilter::kValidOrInvalidOffsets),
-          parent, nodeStart, &disconnected) > 0;
+      nsContentUtils::ComparePoints(aAbstractRange->StartRef().Container(),
+                                    aAbstractRange->StartRef().Offset(), parent,
+                                    nodeStart, &disconnected) > 0;
   if (NS_WARN_IF(disconnected)) {
     return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
   }
 
   // is RANGE(end) >= NODE(end) ?
   *aNodeIsAfterRange =
-      nsContentUtils::ComparePoints(
-          aAbstractRange->EndRef().Container(),
-          *aAbstractRange->EndRef().Offset(
-              RangeBoundary::OffsetFilter::kValidOrInvalidOffsets),
-          parent, nodeEnd, &disconnected) < 0;
+      nsContentUtils::ComparePoints(aAbstractRange->EndRef().Container(),
+                                    aAbstractRange->EndRef().Offset(), parent,
+                                    nodeEnd, &disconnected) < 0;
   if (NS_WARN_IF(disconnected)) {
     return NS_ERROR_DOM_WRONG_DOCUMENT_ERR;
   }
   return NS_OK;
 }
 
 }  // namespace mozilla
--- a/dom/base/RangeUtils.h
+++ b/dom/base/RangeUtils.h
@@ -35,18 +35,17 @@ class RangeUtils final {
     nsINode* parentNode = aNode->GetParentNode();
     if (!parentNode) {
       return RawRangeBoundary();
     }
     RawRangeBoundary afterNode(parentNode, aNode->AsContent());
     // If aNode isn't in the child nodes of its parent node, we hit this case.
     // This may occur when we're called by a mutation observer while aNode is
     // removed from the parent node.
-    if (NS_WARN_IF(
-            !afterNode.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets))) {
+    if (NS_WARN_IF(afterNode.Offset() == 0)) {
       return RawRangeBoundary();
     }
     return afterNode;
   }
 
   static const RawRangeBoundary GetRawRangeBoundaryBefore(nsINode* aNode) {
     MOZ_ASSERT(aNode);
 
--- a/dom/base/Selection.cpp
+++ b/dom/base/Selection.cpp
@@ -2118,29 +2118,25 @@ void Selection::Collapse(const RawRangeB
   // Turn off signal for table selection
   frameSelection->ClearTableCellSelection();
 
   // Hack to display the caret on the right line (bug 1237236).
   if (frameSelection->GetHint() != CARET_ASSOCIATE_AFTER &&
       aPoint.Container()->IsContent()) {
     int32_t frameOffset;
     nsTextFrame* f = do_QueryFrame(nsCaret::GetFrameAndOffset(
-        this, aPoint.Container(),
-        *aPoint.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets),
-        &frameOffset));
+        this, aPoint.Container(), aPoint.Offset(), &frameOffset));
     if (f && f->IsAtEndOfLine() && f->HasSignificantTerminalNewline()) {
       // RawRangeBounary::Offset() causes computing offset if it's not been
       // done yet.  However, it's called only when the container is a text
       // node.  In such case, offset has always been set since it cannot have
       // any children.  So, this doesn't cause computing offset with expensive
       // method, nsINode::ComputeIndexOf().
       if ((aPoint.Container()->AsContent() == f->GetContent() &&
-           f->GetContentEnd() ==
-               static_cast<int32_t>(*aPoint.Offset(
-                   RawRangeBoundary::OffsetFilter::kValidOffsets))) ||
+           f->GetContentEnd() == static_cast<int32_t>(aPoint.Offset())) ||
           (aPoint.Container() == f->GetContent()->GetParentNode() &&
            f->GetContent() == aPoint.GetPreviousSiblingOfChildAtOffset())) {
         frameSelection->SetHint(CARET_ASSOCIATE_AFTER);
       }
     }
   }
 
   RefPtr<nsRange> range;
@@ -3292,29 +3288,16 @@ void Selection::Modify(const nsAString& 
 void Selection::SetBaseAndExtentJS(nsINode& aAnchorNode, uint32_t aAnchorOffset,
                                    nsINode& aFocusNode, uint32_t aFocusOffset,
                                    ErrorResult& aRv) {
   AutoRestore<bool> calledFromJSRestorer(mCalledByJS);
   mCalledByJS = true;
   SetBaseAndExtent(aAnchorNode, aAnchorOffset, aFocusNode, aFocusOffset, aRv);
 }
 
-void Selection::SetBaseAndExtent(nsINode& aAnchorNode, uint32_t aAnchorOffset,
-                                 nsINode& aFocusNode, uint32_t aFocusOffset,
-                                 ErrorResult& aRv) {
-  if ((aAnchorOffset > aAnchorNode.Length()) ||
-      (aFocusOffset > aFocusNode.Length())) {
-    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return;
-  }
-
-  SetBaseAndExtent(RawRangeBoundary{&aAnchorNode, aAnchorOffset},
-                   RawRangeBoundary{&aFocusNode, aFocusOffset}, aRv);
-}
-
 void Selection::SetBaseAndExtentInternal(InLimiter aInLimiter,
                                          const RawRangeBoundary& aAnchorRef,
                                          const RawRangeBoundary& aFocusRef,
                                          ErrorResult& aRv) {
   if (!mFrameSelection) {
     return;
   }
 
--- a/dom/base/Selection.h
+++ b/dom/base/Selection.h
@@ -226,29 +226,25 @@ class Selection final : public nsSupport
 
   // WebIDL methods
   nsINode* GetAnchorNode() const {
     const RangeBoundary& anchor = AnchorRef();
     return anchor.IsSet() ? anchor.Container() : nullptr;
   }
   uint32_t AnchorOffset() const {
     const RangeBoundary& anchor = AnchorRef();
-    const Maybe<uint32_t> offset =
-        anchor.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
-    return offset ? *offset : 0;
+    return anchor.IsSet() ? anchor.Offset() : 0;
   }
   nsINode* GetFocusNode() const {
     const RangeBoundary& focus = FocusRef();
     return focus.IsSet() ? focus.Container() : nullptr;
   }
   uint32_t FocusOffset() const {
     const RangeBoundary& focus = FocusRef();
-    const Maybe<uint32_t> offset =
-        focus.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
-    return offset ? *offset : 0;
+    return focus.IsSet() ? focus.Offset() : 0;
   }
 
   nsIContent* GetChildAtAnchorOffset() {
     const RangeBoundary& anchor = AnchorRef();
     return anchor.IsSet() ? anchor.GetChildAtOffset() : nullptr;
   }
   nsIContent* GetChildAtFocusOffset() {
     const RangeBoundary& focus = FocusRef();
@@ -503,17 +499,20 @@ class Selection final : public nsSupport
    * specified, then if anchor point is after focus node, this sets the
    * direction to eDirPrevious.
    * Note that this may reset the limiter and move focus.  If you don't want
    * that, use SetBaseAndExtentInLimier() instead.
    */
   MOZ_CAN_RUN_SCRIPT
   void SetBaseAndExtent(nsINode& aAnchorNode, uint32_t aAnchorOffset,
                         nsINode& aFocusNode, uint32_t aFocusOffset,
-                        ErrorResult& aRv);
+                        ErrorResult& aRv) {
+    SetBaseAndExtent(RawRangeBoundary(&aAnchorNode, aAnchorOffset),
+                     RawRangeBoundary(&aFocusNode, aFocusOffset), aRv);
+  }
   MOZ_CAN_RUN_SCRIPT
   void SetBaseAndExtent(const RawRangeBoundary& aAnchorRef,
                         const RawRangeBoundary& aFocusRef, ErrorResult& aRv) {
     SetBaseAndExtentInternal(InLimiter::eNo, aAnchorRef, aFocusRef, aRv);
   }
 
   /**
    * SetBaseAndExtentInLimier() is similar to SetBaseAndExtent(), but this
--- a/dom/base/StaticRange.cpp
+++ b/dom/base/StaticRange.cpp
@@ -77,18 +77,17 @@ already_AddRefed<StaticRange> StaticRang
 }
 
 template <typename SPT, typename SRT, typename EPT, typename ERT>
 void StaticRange::DoSetRange(const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
                              const RangeBoundaryBase<EPT, ERT>& aEndBoundary,
                              nsINode* aRootNode) {
   mStart = aStartBoundary;
   mEnd = aEndBoundary;
-  MOZ_ASSERT(mStart.IsSet() == mEnd.IsSet());
-  mIsPositioned = mStart.IsSet() && mEnd.IsSet();
+  mIsPositioned = mStart.IsSet();
 }
 
 /* static */
 already_AddRefed<StaticRange> StaticRange::Constructor(
     const GlobalObject& global, const StaticRangeInit& init, ErrorResult& aRv) {
   if (init.mStartContainer->NodeType() == nsINode::DOCUMENT_TYPE_NODE ||
       init.mStartContainer->NodeType() == nsINode::ATTRIBUTE_NODE ||
       init.mEndContainer->NodeType() == nsINode::DOCUMENT_TYPE_NODE ||
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2491,24 +2491,19 @@ int32_t nsContentUtils::ComparePoints(
     const RangeBoundaryBase<FPT, FRT>& aFirstBoundary,
     const RangeBoundaryBase<SPT, SRT>& aSecondBoundary, bool* aDisconnected) {
   if (NS_WARN_IF(!aFirstBoundary.IsSet()) ||
       NS_WARN_IF(!aSecondBoundary.IsSet())) {
     return -1;
   }
   // XXX Re-implement this without calling `Offset()` as far as possible,
   //     and the other overload should be an alias of this.
-  return ComparePoints(
-      aFirstBoundary.Container(),
-      *aFirstBoundary.Offset(
-          RangeBoundaryBase<FPT, FRT>::OffsetFilter::kValidOrInvalidOffsets),
-      aSecondBoundary.Container(),
-      *aSecondBoundary.Offset(
-          RangeBoundaryBase<SPT, SRT>::OffsetFilter::kValidOrInvalidOffsets),
-      aDisconnected);
+  return ComparePoints(aFirstBoundary.Container(), aFirstBoundary.Offset(),
+                       aSecondBoundary.Container(), aSecondBoundary.Offset(),
+                       aDisconnected);
 }
 
 inline bool IsCharInSet(const char* aSet, const char16_t aChar) {
   char16_t ch;
   while ((ch = *aSet)) {
     if (aChar == char16_t(ch)) {
       return true;
     }
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -436,57 +436,51 @@ nsRange::DetermineNewRangeBoundariesAndR
   RawRangeBoundary newStart;
   RawRangeBoundary newEnd;
   nsINode* newRoot = nullptr;
 
   // normalize(), aInfo.mDetails->mNextSibling is the merged text node
   // that will be removed
   nsIContent* removed = aInfo.mDetails->mNextSibling;
   if (removed == mStart.Container()) {
-    CheckedUint32 newStartOffset{
-        *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets)};
+    CheckedUint32 newStartOffset{mStart.Offset()};
     newStartOffset += aInfo.mChangeStart;
 
     // newStartOffset.isValid() isn't checked explicitly here, because
     // newStartOffset.value() contains an assertion.
     newStart = {aContent, newStartOffset.value()};
     if (MOZ_UNLIKELY(removed == mRoot)) {
       newRoot = RangeUtils::ComputeRootNode(newStart.Container());
     }
   }
   if (removed == mEnd.Container()) {
-    CheckedUint32 newEndOffset{
-        *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets)};
+    CheckedUint32 newEndOffset{mEnd.Offset()};
     newEndOffset += aInfo.mChangeStart;
 
     // newEndOffset.isValid() isn't checked explicitly here, because
     // newEndOffset.value() contains an assertion.
     newEnd = {aContent, newEndOffset.value()};
     if (MOZ_UNLIKELY(removed == mRoot)) {
       newRoot = {RangeUtils::ComputeRootNode(newEnd.Container())};
     }
   }
   // When the removed text node's parent is one of our boundary nodes we may
   // need to adjust the offset to account for the removed node. However,
   // there will also be a ContentRemoved notification later so the only cases
   // we need to handle here is when the removed node is the text node after
   // the boundary.  (The m*Offset > 0 check is an optimization - a boundary
   // point before the first child is never affected by normalize().)
   nsINode* parentNode = aContent->GetParentNode();
-  if (parentNode == mStart.Container() &&
-      *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) > 0 &&
-      *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) <
-          parentNode->GetChildCount() &&
+  if (parentNode == mStart.Container() && mStart.Offset() > 0 &&
+      mStart.Offset() < parentNode->GetChildCount() &&
       removed == mStart.GetChildAtOffset()) {
     newStart = {aContent, aInfo.mChangeStart};
   }
-  if (parentNode == mEnd.Container() &&
-      *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) > 0 &&
-      *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) <
-          parentNode->GetChildCount() &&
+  if (parentNode == mEnd.Container() && mEnd.Offset() > 0 &&
+      mEnd.Offset() < parentNode->GetChildCount() &&
       removed == mEnd.GetChildAtOffset()) {
     newEnd = {aContent, aInfo.mChangeEnd};
   }
 
   return {newStart, newEnd, newRoot};
 }
 
 /******************************************************
@@ -512,31 +506,25 @@ void nsRange::CharacterDataChanged(nsICo
 
   if (aInfo.mDetails &&
       aInfo.mDetails->mType == CharacterDataChangeInfo::Details::eSplit) {
     AdjustNextRefsOnCharacterDataSplit(*aContent, aInfo);
   }
 
   // If the changed node contains our start boundary and the change starts
   // before the boundary we'll need to adjust the offset.
-  if (aContent == mStart.Container() &&
-      aInfo.mChangeStart <
-          *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets)) {
+  if (aContent == mStart.Container() && aInfo.mChangeStart < mStart.Offset()) {
     if (aInfo.mDetails) {
       // splitText(), aInfo->mDetails->mNextSibling is the new text node
       NS_ASSERTION(
           aInfo.mDetails->mType == CharacterDataChangeInfo::Details::eSplit,
           "only a split can start before the end");
-      NS_ASSERTION(
-          *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) <=
-              aInfo.mChangeEnd + 1,
-          "mStart.Offset() is beyond the end of this node");
-      const uint32_t newStartOffset =
-          *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) -
-          aInfo.mChangeStart;
+      NS_ASSERTION(mStart.Offset() <= aInfo.mChangeEnd + 1,
+                   "mStart.Offset() is beyond the end of this node");
+      const uint32_t newStartOffset = mStart.Offset() - aInfo.mChangeStart;
       newStart = {aInfo.mDetails->mNextSibling, newStartOffset};
       if (MOZ_UNLIKELY(aContent == mRoot)) {
         newRoot = RangeUtils::ComputeRootNode(newStart.Container());
       }
 
       bool isCommonAncestor =
           IsInSelection() && mStart.Container() == mEnd.Container();
       if (isCommonAncestor) {
@@ -547,72 +535,62 @@ void nsRange::CharacterDataChanged(nsICo
               ->IsDescendantOfCommonAncestorForRangeInSelection()) {
         newStart.Container()
             ->SetDescendantOfCommonAncestorForRangeInSelection();
       }
     } else {
       // If boundary is inside changed text, position it before change
       // else adjust start offset for the change in length.
       CheckedUint32 newStartOffset{0};
-      if (*mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) <=
-          aInfo.mChangeEnd) {
+      if (mStart.Offset() <= aInfo.mChangeEnd) {
         newStartOffset = aInfo.mChangeStart;
       } else {
-        newStartOffset =
-            *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
+        newStartOffset = mStart.Offset();
         newStartOffset -= aInfo.LengthOfRemovedText();
         newStartOffset += aInfo.mReplaceLength;
       }
 
       // newStartOffset.isValid() isn't checked explicitly here, because
       // newStartOffset.value() contains an assertion.
       newStart = {mStart.Container(), newStartOffset.value()};
     }
   }
 
   // Do the same thing for the end boundary, except for splitText of a node
   // with no parent then only switch to the new node if the start boundary
   // did so too (otherwise the range would end up with disconnected nodes).
-  if (aContent == mEnd.Container() &&
-      aInfo.mChangeStart <
-          *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets)) {
+  if (aContent == mEnd.Container() && aInfo.mChangeStart < mEnd.Offset()) {
     if (aInfo.mDetails && (aContent->GetParentNode() || newStart.Container())) {
       // splitText(), aInfo.mDetails->mNextSibling is the new text node
       NS_ASSERTION(
           aInfo.mDetails->mType == CharacterDataChangeInfo::Details::eSplit,
           "only a split can start before the end");
-      MOZ_ASSERT(
-          *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) <=
-              aInfo.mChangeEnd + 1,
-          "mEnd.Offset() is beyond the end of this node");
-
-      const uint32_t newEndOffset{
-          *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) -
-          aInfo.mChangeStart};
+      MOZ_ASSERT(mEnd.Offset() <= aInfo.mChangeEnd + 1,
+                 "mEnd.Offset() is beyond the end of this node");
+
+      const uint32_t newEndOffset{mEnd.Offset() - aInfo.mChangeStart};
       newEnd = {aInfo.mDetails->mNextSibling, newEndOffset};
 
       bool isCommonAncestor =
           IsInSelection() && mStart.Container() == mEnd.Container();
       if (isCommonAncestor && !newStart.Container()) {
         // The split occurs inside the range.
         UnregisterCommonAncestor(mStart.Container(), false);
         RegisterCommonAncestor(mStart.Container()->GetParentNode());
         newEnd.Container()->SetDescendantOfCommonAncestorForRangeInSelection();
       } else if (mEnd.Container()
                      ->IsDescendantOfCommonAncestorForRangeInSelection()) {
         newEnd.Container()->SetDescendantOfCommonAncestorForRangeInSelection();
       }
     } else {
       CheckedUint32 newEndOffset{0};
-      if (*mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets) <=
-          aInfo.mChangeEnd) {
+      if (mEnd.Offset() <= aInfo.mChangeEnd) {
         newEndOffset = aInfo.mChangeStart;
       } else {
-        newEndOffset =
-            *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
+        newEndOffset = mEnd.Offset();
         newEndOffset -= aInfo.LengthOfRemovedText();
         newEndOffset += aInfo.mReplaceLength;
       }
 
       // newEndOffset.isValid() isn't checked explicitly here, because
       // newEndOffset.value() contains an assertion.
       newEnd = {mEnd.Container(), newEndOffset.value()};
     }
@@ -819,70 +797,62 @@ void nsRange::ParentChainChanged(nsICont
     Reset();
     return;
   }
   // This is safe without holding a strong ref to self as long as the change
   // of mRoot is the last thing in DoSetRange.
   DoSetRange(mStart, mEnd, newRoot);
 }
 
-bool nsRange::IsPointComparableToRange(const nsINode& aContainer,
-                                       uint32_t aOffset,
-                                       ErrorResult& aErrorResult) const {
-  // our range is in a good state?
-  if (!mIsPositioned) {
-    aErrorResult.Throw(NS_ERROR_NOT_INITIALIZED);
-    return false;
-  }
-
-  if (!aContainer.IsInclusiveDescendantOf(mRoot)) {
-    aErrorResult.Throw(NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
-    return false;
-  }
-
-  if (aContainer.NodeType() == nsINode::DOCUMENT_TYPE_NODE) {
-    aErrorResult.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
-    return false;
-  }
-
-  if (aOffset > aContainer.Length()) {
-    aErrorResult.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
-    return false;
-  }
-
-  return true;
-}
-
-bool nsRange::IsPointInRange(nsINode& aContainer, uint32_t aOffset,
-                             ErrorResult& aRv) const {
-  uint16_t compareResult = ComparePoint(aContainer, aOffset, aRv);
+bool nsRange::IsPointInRange(const RawRangeBoundary& aPoint, ErrorResult& aRv) {
+  uint16_t compareResult = ComparePoint(aPoint, aRv);
   // If the node isn't in the range's document, it clearly isn't in the range.
   if (aRv.ErrorCodeIs(NS_ERROR_DOM_WRONG_DOCUMENT_ERR)) {
     aRv.SuppressException();
     return false;
   }
 
   return compareResult == 0;
 }
 
-int16_t nsRange::ComparePoint(nsINode& aContainer, uint32_t aOffset,
-                              ErrorResult& aRv) const {
-  if (!IsPointComparableToRange(aContainer, aOffset, aRv)) {
+int16_t nsRange::ComparePoint(const RawRangeBoundary& aPoint,
+                              ErrorResult& aRv) {
+  if (NS_WARN_IF(!aPoint.IsSet())) {
+    // FYI: Shouldn't reach this case if it's called by JS.  Therefore, it's
+    //      okay to warn.
+    aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
+    return 0;
+  }
+
+  // our range is in a good state?
+  if (!mIsPositioned) {
+    aRv.Throw(NS_ERROR_NOT_INITIALIZED);
     return 0;
   }
 
-  const RawRangeBoundary point{&aContainer, aOffset};
-
-  MOZ_ASSERT(point.IsSetAndValid());
-
-  const int32_t cmp = nsContentUtils::ComparePoints(point, mStart);
+  if (!aPoint.Container()->IsInclusiveDescendantOf(mRoot)) {
+    aRv.Throw(NS_ERROR_DOM_WRONG_DOCUMENT_ERR);
+    return 0;
+  }
+
+  if (aPoint.Container()->NodeType() == nsINode::DOCUMENT_TYPE_NODE) {
+    aRv.Throw(NS_ERROR_DOM_INVALID_NODE_TYPE_ERR);
+    return 0;
+  }
+
+  if (aPoint.Offset() > aPoint.Container()->Length()) {
+    aRv.Throw(NS_ERROR_DOM_INDEX_SIZE_ERR);
+    return 0;
+  }
+
+  int32_t cmp = nsContentUtils::ComparePoints(aPoint, mStart);
   if (cmp <= 0) {
     return cmp;
   }
-  if (nsContentUtils::ComparePoints(mEnd, point) == -1) {
+  if (nsContentUtils::ComparePoints(mEnd, aPoint) == -1) {
     return 1;
   }
 
   return 0;
 }
 
 bool nsRange::IntersectsNode(nsINode& aNode, ErrorResult& aRv) {
   if (!mIsPositioned) {
@@ -899,24 +869,21 @@ bool nsRange::IntersectsNode(nsINode& aN
   }
 
   // Step 5.
   int32_t nodeIndex = parent->ComputeIndexOf(&aNode);
 
   // Steps 6-7.
   // Note: if disconnected is true, ComparePoints returns 1.
   bool disconnected = false;
-  bool result = nsContentUtils::ComparePoints(
-                    mStart.Container(),
-                    *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-                    parent, nodeIndex + 1, &disconnected) < 0 &&
-                nsContentUtils::ComparePoints(
-                    parent, nodeIndex, mEnd.Container(),
-                    *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-                    &disconnected) < 0;
+  bool result =
+      nsContentUtils::ComparePoints(mStart.Container(), mStart.Offset(), parent,
+                                    nodeIndex + 1, &disconnected) < 0 &&
+      nsContentUtils::ComparePoints(parent, nodeIndex, mEnd.Container(),
+                                    mEnd.Offset(), &disconnected) < 0;
 
   // Step 2.
   if (disconnected) {
     result = false;
   }
   return result;
 }
 
@@ -944,21 +911,19 @@ void nsRange::NotifySelectionListenersAf
 // for content notification of range ownership.
 // Calling DoSetRange with either parent argument null will collapse
 // the range to have both endpoints point to the other node
 template <typename SPT, typename SRT, typename EPT, typename ERT>
 void nsRange::DoSetRange(const RangeBoundaryBase<SPT, SRT>& aStartBoundary,
                          const RangeBoundaryBase<EPT, ERT>& aEndBoundary,
                          nsINode* aRootNode,
                          bool aNotInsertedYet /* = false */) {
-  mIsPositioned = aStartBoundary.IsSetAndValid() &&
-                  aEndBoundary.IsSetAndValid() && aRootNode;
-  MOZ_ASSERT(
-      mIsPositioned || (!aStartBoundary.IsSet() && !aEndBoundary.IsSet()),
-      "Set all or none");
+  MOZ_ASSERT((aStartBoundary.IsSet() && aEndBoundary.IsSet() && aRootNode) ||
+                 (!aStartBoundary.IsSet() && !aEndBoundary.IsSet()),
+             "Set all or none");
 
   MOZ_ASSERT(
       !aRootNode || (!aStartBoundary.IsSet() && !aEndBoundary.IsSet()) ||
           aNotInsertedYet ||
           (aStartBoundary.Container()->IsInclusiveDescendantOf(aRootNode) &&
            aEndBoundary.Container()->IsInclusiveDescendantOf(aRootNode) &&
            aRootNode ==
                RangeUtils::ComputeRootNode(aStartBoundary.Container()) &&
@@ -993,16 +958,17 @@ void nsRange::DoSetRange(const RangeBoun
       IsInSelection() && !aNotInsertedYet;
 
   // GetCommonAncestor is unreliable while we're unlinking (could
   // return null if our start/end have already been unlinked), so make
   // sure to not use it here to determine our "old" current ancestor.
   mStart = aStartBoundary;
   mEnd = aEndBoundary;
 
+  mIsPositioned = !!mStart.Container();
   if (checkCommonAncestor) {
     nsINode* oldCommonAncestor = mRegisteredCommonAncestor;
     nsINode* newCommonAncestor = GetCommonAncestor();
     if (newCommonAncestor != oldCommonAncestor) {
       if (oldCommonAncestor) {
         UnregisterCommonAncestor(oldCommonAncestor, false);
       }
       if (newCommonAncestor) {
@@ -1679,21 +1645,19 @@ nsresult nsRange::CutContents(DocumentFr
 
   // Batch possible DOMSubtreeModified events.
   mozAutoSubtreeModified subtree(mRoot ? mRoot->OwnerDoc() : nullptr, nullptr);
 
   // Save the range end points locally to avoid interference
   // of Range gravity during our edits!
 
   nsCOMPtr<nsINode> startContainer = mStart.Container();
-  uint32_t startOffset =
-      *mStart.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
+  uint32_t startOffset = mStart.Offset();
   nsCOMPtr<nsINode> endContainer = mEnd.Container();
-  uint32_t endOffset =
-      *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
+  uint32_t endOffset = mEnd.Offset();
 
   if (retval) {
     // For extractContents(), abort early if there's a doctype (bug 719533).
     // This can happen only if the common ancestor is a document, in which case
     // we just need to find its doctype child and check if that's in the range.
     nsCOMPtr<Document> commonAncestorDocument =
         do_QueryInterface(commonAncestor);
     if (commonAncestorDocument) {
@@ -1982,35 +1946,35 @@ int16_t nsRange::CompareBoundaryPoints(u
   }
 
   nsINode *ourNode, *otherNode;
   uint32_t ourOffset, otherOffset;
 
   switch (aHow) {
     case Range_Binding::START_TO_START:
       ourNode = mStart.Container();
-      ourOffset = *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
+      ourOffset = mStart.Offset();
       otherNode = aOtherRange.GetStartContainer();
       otherOffset = aOtherRange.StartOffset();
       break;
     case Range_Binding::START_TO_END:
       ourNode = mEnd.Container();
-      ourOffset = *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
+      ourOffset = mEnd.Offset();
       otherNode = aOtherRange.GetStartContainer();
       otherOffset = aOtherRange.StartOffset();
       break;
     case Range_Binding::END_TO_START:
       ourNode = mStart.Container();
-      ourOffset = *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
+      ourOffset = mStart.Offset();
       otherNode = aOtherRange.GetEndContainer();
       otherOffset = aOtherRange.EndOffset();
       break;
     case Range_Binding::END_TO_END:
       ourNode = mEnd.Container();
-      ourOffset = *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
+      ourOffset = mEnd.Offset();
       otherNode = aOtherRange.GetEndContainer();
       otherOffset = aOtherRange.EndOffset();
       break;
     default:
       // We were passed an illegal value
       rv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
       return 0;
   }
@@ -2088,20 +2052,16 @@ already_AddRefed<DocumentFragment> nsRan
   }
 
   // Create a new document fragment in the context of this document,
   // which might be null
 
   RefPtr<DocumentFragment> clonedFrag =
       new DocumentFragment(doc->NodeInfoManager());
 
-  if (Collapsed()) {
-    return clonedFrag.forget();
-  }
-
   nsCOMPtr<nsINode> commonCloneAncestor = clonedFrag.get();
 
   // Create and initialize a subtree iterator that will give
   // us all the subtrees within the range.
 
   RangeSubtreeIterator iter;
 
   aRv = iter.Init(this);
@@ -2123,23 +2083,20 @@ already_AddRefed<DocumentFragment> nsRan
   //
   // Unfortunately these subtrees don't contain the parent hierarchy/context
   // that the Range spec requires us to return. This loop clones the
   // parent hierarchy, adds a cloned version of the subtree, to it, then
   // correctly places this new subtree into the doc fragment.
 
   while (!iter.IsDone()) {
     nsCOMPtr<nsINode> node = iter.GetCurrentNode();
-    bool deepClone =
-        !node->IsElement() ||
-        (!(node == mEnd.Container() &&
-           *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets) == 0) &&
-         !(node == mStart.Container() &&
-           *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets) ==
-               node->AsElement()->GetChildCount()));
+    bool deepClone = !node->IsElement() ||
+                     (!(node == mEnd.Container() && mEnd.Offset() == 0) &&
+                      !(node == mStart.Container() &&
+                        mStart.Offset() == node->AsElement()->GetChildCount()));
 
     // Clone the current subtree!
 
     nsCOMPtr<nsINode> clone = node->CloneNode(deepClone, aRv);
     if (aRv.Failed()) {
       return nullptr;
     }
 
@@ -2150,37 +2107,30 @@ already_AddRefed<DocumentFragment> nsRan
     // XXX_kin: according to the spec.
 
     if (auto charData = CharacterData::FromNode(clone)) {
       if (node == mEnd.Container()) {
         // We only need the data before mEndOffset, so get rid of any
         // data after it.
 
         uint32_t dataLength = charData->Length();
-        if (dataLength >
-            *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets)) {
-          charData->DeleteData(
-              *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-              dataLength -
-                  *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-              aRv);
+        if (dataLength > (uint32_t)mEnd.Offset()) {
+          charData->DeleteData(mEnd.Offset(), dataLength - mEnd.Offset(), aRv);
           if (aRv.Failed()) {
             return nullptr;
           }
         }
       }
 
       if (node == mStart.Container()) {
         // We don't need any data before mStartOffset, so just
         // delete it!
 
-        if (*mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets) > 0) {
-          charData->DeleteData(
-              0, *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-              aRv);
+        if (mStart.Offset() > 0) {
+          charData->DeleteData(0, mStart.Offset(), aRv);
           if (aRv.Failed()) {
             return nullptr;
           }
         }
       }
     }
 
     // Clone the parent hierarchy between commonAncestor and node.
@@ -2488,21 +2438,18 @@ void nsRange::ToString(nsAString& aRetur
     if (textNode) {
 #ifdef DEBUG_range
       // If debug, dump it:
       textNode->List(stdout);
       printf("End Range dump: -----------------------\n");
 #endif /* DEBUG */
 
       // grab the text
-      textNode->SubstringData(
-          *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-          *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets) -
-              *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-          aReturn, aErr);
+      textNode->SubstringData(mStart.Offset(), mEnd.Offset() - mStart.Offset(),
+                              aReturn, aErr);
       return;
     }
   }
 
   /* complex case: mStart.Container() != mEnd.Container(), or mStartParent not a
      text node revisit - there are potential optimizations here and also
      tradeoffs.
   */
@@ -2525,27 +2472,22 @@ void nsRange::ToString(nsAString& aRetur
     // If debug, dump it:
     n->List(stdout);
 #endif /* DEBUG */
     Text* textNode = n->GetAsText();
     if (textNode)  // if it's a text node, get the text
     {
       if (n == mStart.Container()) {  // only include text past start offset
         uint32_t strLength = textNode->Length();
-        textNode->SubstringData(
-            *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-            strLength -
-                *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-            tempString, IgnoreErrors());
+        textNode->SubstringData(mStart.Offset(), strLength - mStart.Offset(),
+                                tempString, IgnoreErrors());
         aReturn += tempString;
       } else if (n ==
                  mEnd.Container()) {  // only include text before end offset
-        textNode->SubstringData(
-            0, *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-            tempString, IgnoreErrors());
+        textNode->SubstringData(0, mEnd.Offset(), tempString, IgnoreErrors());
         aReturn += tempString;
       } else {  // grab the whole kit-n-kaboodle
         textNode->GetData(tempString);
         aReturn += tempString;
       }
     }
   }
 
@@ -2790,75 +2732,67 @@ void nsRange::CollectClientRectsAndText(
           aCollector, aTextList, nsLayoutUtils::RECTS_ACCOUNT_FOR_TRANSFORMS);
     }
   } while (!iter.IsDone());
 }
 
 already_AddRefed<DOMRect> nsRange::GetBoundingClientRect(bool aClampToEdge,
                                                          bool aFlushLayout) {
   RefPtr<DOMRect> rect = new DOMRect(ToSupports(this));
-  if (!mIsPositioned) {
+  if (!mStart.Container()) {
     return rect.forget();
   }
 
   nsLayoutUtils::RectAccumulator accumulator;
-  CollectClientRectsAndText(
-      &accumulator, nullptr, this, mStart.Container(),
-      *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-      mEnd.Container(),
-      *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets), aClampToEdge,
-      aFlushLayout);
+  CollectClientRectsAndText(&accumulator, nullptr, this, mStart.Container(),
+                            mStart.Offset(), mEnd.Container(), mEnd.Offset(),
+                            aClampToEdge, aFlushLayout);
 
   nsRect r = accumulator.mResultRect.IsEmpty() ? accumulator.mFirstRect
                                                : accumulator.mResultRect;
   rect->SetLayoutRect(r);
   return rect.forget();
 }
 
 already_AddRefed<DOMRectList> nsRange::GetClientRects(bool aClampToEdge,
                                                       bool aFlushLayout) {
-  if (!mIsPositioned) {
+  if (!mStart.Container()) {
     return nullptr;
   }
 
   RefPtr<DOMRectList> rectList =
       new DOMRectList(static_cast<AbstractRange*>(this));
 
   nsLayoutUtils::RectListBuilder builder(rectList);
 
-  CollectClientRectsAndText(
-      &builder, nullptr, this, mStart.Container(),
-      *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-      mEnd.Container(),
-      *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets), aClampToEdge,
-      aFlushLayout);
+  CollectClientRectsAndText(&builder, nullptr, this, mStart.Container(),
+                            mStart.Offset(), mEnd.Container(), mEnd.Offset(),
+                            aClampToEdge, aFlushLayout);
   return rectList.forget();
 }
 
 void nsRange::GetClientRectsAndTexts(mozilla::dom::ClientRectsAndTexts& aResult,
                                      ErrorResult& aErr) {
-  if (!mIsPositioned) {
+  if (!mStart.Container()) {
     return;
   }
 
   aResult.mRectList = new DOMRectList(static_cast<AbstractRange*>(this));
 
   nsLayoutUtils::RectListBuilder builder(aResult.mRectList);
 
-  CollectClientRectsAndText(
-      &builder, &aResult.mTextList, this, mStart.Container(),
-      *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-      mEnd.Container(),
-      *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets), true, true);
+  CollectClientRectsAndText(&builder, &aResult.mTextList, this,
+                            mStart.Container(), mStart.Offset(),
+                            mEnd.Container(), mEnd.Offset(), true, true);
 }
 
 nsresult nsRange::GetUsedFontFaces(nsLayoutUtils::UsedFontFaceList& aResult,
                                    uint32_t aMaxRanges,
                                    bool aSkipCollapsedWhitespace) {
-  NS_ENSURE_TRUE(mIsPositioned, NS_ERROR_UNEXPECTED);
+  NS_ENSURE_TRUE(mStart.Container(), NS_ERROR_UNEXPECTED);
 
   nsCOMPtr<nsINode> startContainer = mStart.Container();
   nsCOMPtr<nsINode> endContainer = mEnd.Container();
 
   // Flush out layout so our frames are up to date.
   Document* doc = mStart.Container()->OwnerDoc();
   NS_ENSURE_TRUE(doc, NS_ERROR_UNEXPECTED);
   doc->FlushPendingNotifications(FlushType::Frames);
@@ -2886,30 +2820,28 @@ nsresult nsRange::GetUsedFontFaces(nsLay
     }
     nsIFrame* frame = content->GetPrimaryFrame();
     if (!frame) {
       continue;
     }
 
     if (content->IsText()) {
       if (node == startContainer) {
-        int32_t offset =
-            startContainer == endContainer
-                ? *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets)
-                : content->AsText()->TextDataLength();
-        nsLayoutUtils::GetFontFacesForText(
-            frame, *mStart.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-            offset, true, aResult, fontFaces, aMaxRanges,
-            aSkipCollapsedWhitespace);
+        int32_t offset = startContainer == endContainer
+                             ? mEnd.Offset()
+                             : content->AsText()->TextDataLength();
+        nsLayoutUtils::GetFontFacesForText(frame, mStart.Offset(), offset, true,
+                                           aResult, fontFaces, aMaxRanges,
+                                           aSkipCollapsedWhitespace);
         continue;
       }
       if (node == endContainer) {
-        nsLayoutUtils::GetFontFacesForText(
-            frame, 0, *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets),
-            true, aResult, fontFaces, aMaxRanges, aSkipCollapsedWhitespace);
+        nsLayoutUtils::GetFontFacesForText(frame, 0, mEnd.Offset(), true,
+                                           aResult, fontFaces, aMaxRanges,
+                                           aSkipCollapsedWhitespace);
         continue;
       }
     }
 
     nsLayoutUtils::GetFontFacesForFrames(frame, aResult, fontFaces, aMaxRanges,
                                          aSkipCollapsedWhitespace);
   }
 
@@ -2963,20 +2895,17 @@ already_AddRefed<nsRange> nsRange::Const
 }
 
 static bool ExcludeIfNextToNonSelectable(nsIContent* aContent) {
   return aContent->IsText() &&
          aContent->HasFlag(NS_CREATE_FRAME_IF_NON_WHITESPACE);
 }
 
 void nsRange::ExcludeNonSelectableNodes(nsTArray<RefPtr<nsRange>>* aOutRanges) {
-  if (!mIsPositioned) {
-    MOZ_ASSERT(false);
-    return;
-  }
+  MOZ_ASSERT(mIsPositioned);
   MOZ_ASSERT(mEnd.Container());
   MOZ_ASSERT(mStart.Container());
 
   nsRange* range = this;
   RefPtr<nsRange> newRange;
   while (range) {
     PreContentIterator preOrderIter;
     nsresult rv = preOrderIter.Init(range);
@@ -3032,18 +2961,17 @@ void nsRange::ExcludeNonSelectableNodes(
           range->SetStartBefore(*node, err);
           if (err.Failed()) {
             return;
           }
           break;  // restart the same range with a new iterator
         } else {
           // Save the end point before truncating the range.
           nsINode* endContainer = range->mEnd.Container();
-          const int32_t endOffset =
-              *range->mEnd.Offset(RangeBoundary::OffsetFilter::kValidOffsets);
+          int32_t endOffset = range->mEnd.Offset();
 
           // Truncate the current range before the first non-selectable node.
           range->SetEndBefore(*firstNonSelectableContent, err);
 
           // Store it in the result (strong ref) - do this before creating
           // a new range in |newRange| below so we don't drop the last ref
           // to the range created in the previous iteration.
           if (!added && !err.Failed()) {
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -212,31 +212,37 @@ class nsRange final : public mozilla::do
 
   already_AddRefed<mozilla::dom::DocumentFragment> CreateContextualFragment(
       const nsAString& aString, ErrorResult& aError);
   already_AddRefed<mozilla::dom::DocumentFragment> CloneContents(
       ErrorResult& aErr);
   int16_t CompareBoundaryPoints(uint16_t aHow, nsRange& aOther,
                                 ErrorResult& aErr);
   int16_t ComparePoint(nsINode& aContainer, uint32_t aOffset,
-                       ErrorResult& aErr) const;
+                       ErrorResult& aErr) {
+    return ComparePoint(RawRangeBoundary(&aContainer, aOffset), aErr);
+  }
+  int16_t ComparePoint(const RawRangeBoundary& aPoint, ErrorResult& aErr);
   void DeleteContents(ErrorResult& aRv);
   already_AddRefed<mozilla::dom::DocumentFragment> ExtractContents(
       ErrorResult& aErr);
   nsINode* GetCommonAncestorContainer(ErrorResult& aRv) const {
     if (!mIsPositioned) {
       aRv.Throw(NS_ERROR_NOT_INITIALIZED);
       return nullptr;
     }
     return GetCommonAncestor();
   }
   void InsertNode(nsINode& aNode, ErrorResult& aErr);
   bool IntersectsNode(nsINode& aNode, ErrorResult& aRv);
   bool IsPointInRange(nsINode& aContainer, uint32_t aOffset,
-                      ErrorResult& aErr) const;
+                      ErrorResult& aErr) {
+    return IsPointInRange(RawRangeBoundary(&aContainer, aOffset), aErr);
+  }
+  bool IsPointInRange(const RawRangeBoundary& aPoint, ErrorResult& aErr);
   void ToString(nsAString& aReturn, ErrorResult& aErr);
   void Detach();
 
   // *JS() methods are mapped to Range.*() of DOM.
   // They may move focus only when the range represents normal selection.
   // These methods shouldn't be used from internal.
   void CollapseJS(bool aToStart);
   void SelectNodeJS(nsINode& aNode, ErrorResult& aErr);
@@ -310,22 +316,16 @@ class nsRange final : public mozilla::do
   };
 
   /**
    * @param aContent Must be non-nullptr.
    */
   RangeBoundariesAndRoot DetermineNewRangeBoundariesAndRootOnCharacterDataMerge(
       nsIContent* aContent, const CharacterDataChangeInfo& aInfo) const;
 
-  // @return true iff the range is positioned, aContainer belongs to the same
-  //         document as the range, aContainer is a DOCUMENT_TYPE_NODE and
-  //         aOffset doesn't exceed aContainer's length.
-  bool IsPointComparableToRange(const nsINode& aContainer, uint32_t aOffset,
-                                ErrorResult& aErrorResult) const;
-
  public:
   /**
    * Return true if any part of (aNode, aStartOffset) .. (aNode, aEndOffset)
    * overlaps any nsRange in aNode's GetNextRangeCommonAncestor ranges (i.e.
    * where aNode is a descendant of a range's common ancestor node).
    * If a nsRange starts in (aNode, aEndOffset) or if it ends in
    * (aNode, aStartOffset) then it is non-overlapping and the result is false
    * for that nsRange.  Collapsed ranges always counts as non-overlapping.
--- a/dom/events/ContentEventHandler.cpp
+++ b/dom/events/ContentEventHandler.cpp
@@ -46,23 +46,18 @@ using namespace dom;
 using namespace widget;
 
 /******************************************************************/
 /* ContentEventHandler::RawRange                                  */
 /******************************************************************/
 
 void ContentEventHandler::RawRange::AssertStartIsBeforeOrEqualToEnd() {
   MOZ_ASSERT(nsContentUtils::ComparePoints(
-                 mStart.Container(),
-                 static_cast<int32_t>(*mStart.Offset(
-                     NodePosition::OffsetFilter::kValidOrInvalidOffsets)),
-                 mEnd.Container(),
-                 static_cast<int32_t>(*mEnd.Offset(
-                     NodePosition::OffsetFilter::kValidOrInvalidOffsets))) <=
-             0);
+                 mStart.Container(), static_cast<int32_t>(mStart.Offset()),
+                 mEnd.Container(), static_cast<int32_t>(mEnd.Offset())) <= 0);
 }
 
 nsresult ContentEventHandler::RawRange::SetStart(
     const RawRangeBoundary& aStart) {
   nsINode* newRoot = RangeUtils::ComputeRootNode(aStart.Container());
   if (!newRoot) {
     return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
   }
@@ -124,18 +119,17 @@ nsresult ContentEventHandler::RawRange::
   if (!aStart.IsSetAndValid()) {
     return NS_ERROR_DOM_INDEX_SIZE_ERR;
   }
 
   if (aStart.Container() == aEnd.Container()) {
     if (!aEnd.IsSetAndValid()) {
       return NS_ERROR_DOM_INDEX_SIZE_ERR;
     }
-    MOZ_ASSERT(*aStart.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets) <=
-               *aEnd.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets));
+    MOZ_ASSERT(aStart.Offset() <= aEnd.Offset());
     mRoot = newStartRoot;
     mStart = aStart;
     mEnd = aEnd;
     return NS_OK;
   }
 
   nsINode* newEndRoot = RangeUtils::ComputeRootNode(aEnd.Container());
   if (!newEndRoot) {
@@ -1489,42 +1483,38 @@ ContentEventHandler::GetFirstFrameInRang
     // If the element node causes a line break before it, it's the first
     // node causing text.
     if (ShouldBreakLineBefore(node->AsContent(), mRootContent) ||
         IsPaddingBR(node->AsContent())) {
       nodePosition = {node, 0};
     }
   }
 
-  if (!nodePosition.IsSetAndValid()) {
+  if (!nodePosition.IsSet()) {
     return FrameAndNodeOffset();
   }
 
   nsIFrame* firstFrame = nullptr;
-  GetFrameForTextRect(
-      nodePosition.Container(),
-      *nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets), true,
-      &firstFrame);
-  return FrameAndNodeOffset(
-      firstFrame,
-      *nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets));
+  GetFrameForTextRect(nodePosition.Container(), nodePosition.Offset(), true,
+                      &firstFrame);
+  return FrameAndNodeOffset(firstFrame, nodePosition.Offset());
 }
 
 ContentEventHandler::FrameAndNodeOffset
 ContentEventHandler::GetLastFrameInRangeForTextRect(const RawRange& aRawRange) {
   NodePosition nodePosition;
   PreContentIterator preOrderIter;
   nsresult rv =
       preOrderIter.Init(aRawRange.Start().AsRaw(), aRawRange.End().AsRaw());
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return FrameAndNodeOffset();
   }
 
   const RangeBoundary& endPoint = aRawRange.End();
-  MOZ_ASSERT(endPoint.IsSetAndValid());
+  MOZ_ASSERT(endPoint.IsSet());
   // If the end point is start of a text node or specified by its parent and
   // index, the node shouldn't be included into the range.  For example,
   // with this case, |<p>abc[<br>]def</p>|, the range ends at 3rd children of
   // <p> (see the range creation rules, "2.4. Cases: <element/>]"). This causes
   // following frames:
   // +----+-----+
   // | abc|[<br>|
   // +----+-----+
@@ -1569,18 +1559,17 @@ ContentEventHandler::GetLastFrameInRange
       }
 
       nodePosition = {node, offset.value()};
 
       // If the text node is empty or the last node of the range but the index
       // is 0, we should store current position but continue looking for
       // previous node (If there are no nodes before it, we should use current
       // node position for returning its frame).
-      if (*nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets) ==
-          0) {
+      if (!nodePosition.Offset()) {
         continue;
       }
       break;
     }
 
     if (ShouldBreakLineBefore(node->AsContent(), mRootContent) ||
         IsPaddingBR(node->AsContent())) {
       nodePosition = {node, 0};
@@ -1588,61 +1577,51 @@ ContentEventHandler::GetLastFrameInRange
     }
   }
 
   if (!nodePosition.IsSet()) {
     return FrameAndNodeOffset();
   }
 
   nsIFrame* lastFrame = nullptr;
-  GetFrameForTextRect(
-      nodePosition.Container(),
-      *nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets), true,
-      &lastFrame);
+  GetFrameForTextRect(nodePosition.Container(), nodePosition.Offset(), true,
+                      &lastFrame);
   if (!lastFrame) {
     return FrameAndNodeOffset();
   }
 
   // If the last frame is a text frame, we need to check if the range actually
   // includes at least one character in the range.  Therefore, if it's not a
   // text frame, we need to do nothing anymore.
   if (!lastFrame->IsTextFrame()) {
-    return FrameAndNodeOffset(
-        lastFrame,
-        *nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets));
+    return FrameAndNodeOffset(lastFrame, nodePosition.Offset());
   }
 
   int32_t start, end;
   if (NS_WARN_IF(NS_FAILED(lastFrame->GetOffsets(start, end)))) {
     return FrameAndNodeOffset();
   }
 
   // If the start offset in the node is same as the computed offset in the
   // node and it's not 0, the frame shouldn't be added to the text rect.  So,
   // this should return previous text frame and its last offset if there is
   // at least one text frame.
-  if (*nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets) &&
-      *nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets) ==
-          static_cast<uint32_t>(start)) {
-    const CheckedInt<int32_t> newNodePositionOffset{
-        *nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets) - 1};
+  if (nodePosition.Offset() &&
+      nodePosition.Offset() == static_cast<uint32_t>(start)) {
+    const CheckedInt<int32_t> newNodePositionOffset{nodePosition.Offset() - 1};
 
     nodePosition = {nodePosition.Container(), newNodePositionOffset.value()};
-    GetFrameForTextRect(
-        nodePosition.Container(),
-        *nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets), true,
-        &lastFrame);
+    GetFrameForTextRect(nodePosition.Container(), nodePosition.Offset(), true,
+                        &lastFrame);
     if (NS_WARN_IF(!lastFrame)) {
       return FrameAndNodeOffset();
     }
   }
 
-  return FrameAndNodeOffset(
-      lastFrame,
-      *nodePosition.Offset(NodePosition::OffsetFilter::kValidOffsets));
+  return FrameAndNodeOffset(lastFrame, nodePosition.Offset());
 }
 
 ContentEventHandler::FrameRelativeRect
 ContentEventHandler::GetLineBreakerRectBefore(nsIFrame* aFrame) {
   // Note that this method should be called only with an element's frame whose
   // open tag causes a line break or moz-<br> for computing empty last line's
   // rect.
   MOZ_ASSERT(ShouldBreakLineBefore(aFrame->GetContent(), mRootContent) ||
@@ -2696,22 +2675,20 @@ nsresult ContentEventHandler::GetFlatTex
   if (aIsRemovingNode) {
     DebugOnly<nsIContent*> parent = aStartPosition.Container()->GetParent();
     MOZ_ASSERT(
         parent && parent->ComputeIndexOf(aStartPosition.Container()) == -1,
         "At removing the node, the node shouldn't be in the array of children "
         "of its parent");
     MOZ_ASSERT(aStartPosition.Container() == endPosition.Container(),
                "At removing the node, start and end node should be same");
-    MOZ_ASSERT(*aStartPosition.Offset(
-                   NodePosition::OffsetFilter::kValidOrInvalidOffsets) == 0,
+    MOZ_ASSERT(aStartPosition.Offset() == 0,
                "When the node is being removed, the start offset should be 0");
     MOZ_ASSERT(
-        static_cast<uint32_t>(*endPosition.Offset(
-            NodePosition::OffsetFilter::kValidOrInvalidOffsets)) ==
+        static_cast<uint32_t>(endPosition.Offset()) ==
             endPosition.Container()->GetChildCount(),
         "When the node is being removed, the end offset should be child count");
     nsresult rv = preOrderIter.Init(aStartPosition.Container());
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
   } else {
     RawRange prevRawRange;
@@ -2789,20 +2766,18 @@ nsresult ContentEventHandler::GetFlatTex
     }
     nsIContent* content = node->AsContent();
 
     if (node->IsText()) {
       // Note: our range always starts from offset 0
       if (node == endPosition.Container()) {
         // NOTE: We should have an offset here, as endPosition.Container() is a
         // nsINode::eTEXT, which always has an offset.
-        *aLength += GetTextLength(
-            content, aLineBreakType,
-            *endPosition.Offset(
-                NodePosition::OffsetFilter::kValidOrInvalidOffsets));
+        *aLength +=
+            GetTextLength(content, aLineBreakType, endPosition.Offset());
       } else {
         *aLength += GetTextLength(content, aLineBreakType);
       }
     } else if (ShouldBreakLineBefore(content, aRootContent)) {
       // If the start position is start of this node but doesn't include the
       // open tag, don't append the line break length.
       if (node == aStartPosition.Container() &&
           !aStartPosition.IsBeforeOpenTag()) {
--- a/dom/events/ContentEventHandler.h
+++ b/dom/events/ContentEventHandler.h
@@ -46,23 +46,18 @@ class MOZ_STACK_CLASS ContentEventHandle
       mStart = RangeBoundary();
       mEnd = RangeBoundary();
     }
 
     bool IsPositioned() const { return mStart.IsSet() && mEnd.IsSet(); }
     bool Collapsed() const { return mStart == mEnd && IsPositioned(); }
     nsINode* GetStartContainer() const { return mStart.Container(); }
     nsINode* GetEndContainer() const { return mEnd.Container(); }
-    uint32_t StartOffset() const {
-      return *mStart.Offset(
-          RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
-    }
-    uint32_t EndOffset() const {
-      return *mEnd.Offset(RangeBoundary::OffsetFilter::kValidOrInvalidOffsets);
-    }
+    uint32_t StartOffset() const { return mStart.Offset(); }
+    uint32_t EndOffset() const { return mEnd.Offset(); }
     nsIContent* StartRef() const { return mStart.Ref(); }
     nsIContent* EndRef() const { return mEnd.Ref(); }
 
     const RangeBoundary& Start() const { return mStart; }
     const RangeBoundary& End() const { return mEnd; }
 
     // XXX: Make these use RangeBoundaries...
     nsresult CollapseTo(const RawRangeBoundary& aBoundary) {
--- a/editor/libeditor/DeleteRangeTransaction.cpp
+++ b/editor/libeditor/DeleteRangeTransaction.cpp
@@ -125,26 +125,23 @@ nsresult DeleteRangeTransaction::CreateT
 
   // see what kind of node we have
   if (RefPtr<Text> textNode = Text::FromNode(aStart.Container())) {
     // if the node is a chardata node, then delete chardata content
     int32_t numToDel;
     if (aStart == aEnd) {
       numToDel = 1;
     } else {
-      numToDel = *aEnd.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets) -
-                 *aStart.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets);
+      numToDel = aEnd.Offset() - aStart.Offset();
       MOZ_DIAGNOSTIC_ASSERT(numToDel > 0);
     }
 
     RefPtr<DeleteTextTransaction> deleteTextTransaction =
-        DeleteTextTransaction::MaybeCreate(
-            *mEditorBase, *textNode,
-            *aStart.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets),
-            numToDel);
+        DeleteTextTransaction::MaybeCreate(*mEditorBase, *textNode,
+                                           aStart.Offset(), numToDel);
     // If the text node isn't editable, it should be never undone/redone.
     // So, the transaction shouldn't be recorded.
     if (NS_WARN_IF(!deleteTextTransaction)) {
       return NS_ERROR_FAILURE;
     }
     AppendChild(deleteTextTransaction);
     return NS_OK;
   }
@@ -181,21 +178,21 @@ nsresult DeleteRangeTransaction::CreateT
   RefPtr<Text> textNode = Text::FromNode(aPoint.Container());
   if (!textNode) {
     return NS_OK;
   }
 
   // If the node is a chardata node, then delete chardata content
   uint32_t startOffset, numToDelete;
   if (nsIEditor::eNext == aAction) {
-    startOffset = *aPoint.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets);
-    numToDelete = aPoint.Container()->Length() - startOffset;
+    startOffset = aPoint.Offset();
+    numToDelete = aPoint.Container()->Length() - aPoint.Offset();
   } else {
     startOffset = 0;
-    numToDelete = *aPoint.Offset(RawRangeBoundary::OffsetFilter::kValidOffsets);
+    numToDelete = aPoint.Offset();
   }
 
   if (!numToDelete) {
     return NS_OK;
   }
 
   RefPtr<DeleteTextTransaction> deleteTextTransaction =
       DeleteTextTransaction::MaybeCreate(*mEditorBase, *textNode, startOffset,
--- a/editor/libeditor/HTMLEditSubActionHandler.cpp
+++ b/editor/libeditor/HTMLEditSubActionHandler.cpp
@@ -7189,18 +7189,17 @@ EditorDOMPoint HTMLEditor::GetWhiteSpace
     const RangeBoundaryBase<PT, RT>& aPoint, ScanDirection aScanDirection) {
   if (NS_WARN_IF(!aPoint.IsSet()) ||
       NS_WARN_IF(!aPoint.Container()->IsContent())) {
     return EditorDOMPoint();
   }
 
   bool isSpace = false, isNBSP = false;
   nsIContent* newContent = aPoint.Container()->AsContent();
-  int32_t newOffset = *aPoint.Offset(
-      RangeBoundaryBase<PT, RT>::OffsetFilter::kValidOrInvalidOffsets);
+  int32_t newOffset = aPoint.Offset();
   while (newContent) {
     int32_t offset = -1;
     nsCOMPtr<nsIContent> content;
     if (aScanDirection == ScanDirection::Backward) {
       HTMLEditor::IsPrevCharInNodeWhitespace(newContent, newOffset, &isSpace,
                                              &isNBSP, getter_AddRefs(content),
                                              &offset);
     } else {