Bug 1413181 - part 11: Create AutoEditorDOMPointOffsetInvalidator stack class for automatically invalidate offset of EditorDOMPoint r?m_kato draft
authorMasayuki Nakano <masayuki@d-toybox.com>
Fri, 17 Nov 2017 17:00:56 +0900
changeset 701131 08afd7e2d25ad9c8374d7f0d3b701ee0e4a856df
parent 701130 7370f20e5f8cb0070a45baebd4f78510ac361f59
child 701132 7b075bf9426bb22c1a9b23582403d3d6ef22cc3e
push id90079
push usermasayuki@d-toybox.com
push dateTue, 21 Nov 2017 08:41:26 +0000
reviewersm_kato
bugs1413181
milestone59.0a1
Bug 1413181 - part 11: Create AutoEditorDOMPointOffsetInvalidator stack class for automatically invalidate offset of EditorDOMPoint r?m_kato In the following patch, we need to invalidate offset a lot of places after splitting nodes. Therefore, there should be a helper stack class before that. MozReview-Commit-ID: BgijAU7OizU
editor/libeditor/EditorDOMPoint.h
--- a/editor/libeditor/EditorDOMPoint.h
+++ b/editor/libeditor/EditorDOMPoint.h
@@ -115,11 +115,107 @@ private:
     // If referring after the last child, the 'ref' should be the last child.
     if (aContainerNode && aContainerNode->IsContainerNode()) {
       return aContainerNode->GetLastChild();
     }
     return nullptr;
   }
 };
 
+/**
+ * AutoEditorDOMPointOffsetInvalidator is useful if DOM tree will be changed
+ * when EditorDOMPoint instance is available and keeps referring same child
+ * node.
+ *
+ * This class automatically guarantees that given EditorDOMPoint instance
+ * stores the child node and invalidates its offset when the instance is
+ * destroyed.  Additionally, users of this class can invalidate the offset
+ * manually when they need.
+ */
+class MOZ_STACK_CLASS AutoEditorDOMPointOffsetInvalidator final
+{
+public:
+  explicit AutoEditorDOMPointOffsetInvalidator(EditorDOMPoint& aPoint)
+    : mPoint(aPoint)
+  {
+    MOZ_ASSERT(aPoint.IsSetAndValid());
+    mChild = mPoint.GetChildAtOffset();
+  }
+
+  ~AutoEditorDOMPointOffsetInvalidator()
+  {
+    InvalidateOffset();
+  }
+
+  /**
+   * Manually, invalidate offset of the given point.
+   */
+  void InvalidateOffset()
+  {
+    if (mChild) {
+      mPoint.Set(mChild);
+    } else {
+      // If the point referred after the last child, let's keep referring
+      // after current last node of the old container.
+      mPoint.Set(mPoint.Container(), mPoint.Container()->Length());
+    }
+  }
+
+private:
+  EditorDOMPoint& mPoint;
+  // Needs to store child node by ourselves because EditorDOMPoint stores
+  // child node with mRef which is previous sibling of current child node.
+  // Therefore, we cannot keep referring it if it's first child.
+  nsCOMPtr<nsIContent> mChild;
+
+  AutoEditorDOMPointOffsetInvalidator() = delete;
+  AutoEditorDOMPointOffsetInvalidator(
+    const AutoEditorDOMPointOffsetInvalidator& aOther) = delete;
+  const AutoEditorDOMPointOffsetInvalidator& operator=(
+    const AutoEditorDOMPointOffsetInvalidator& aOther) = delete;
+};
+
+/**
+ * AutoEditorDOMPointChildInvalidator is useful if DOM tree will be changed
+ * when EditorDOMPoint instance is available and keeps referring same container
+ * and offset in it.
+ *
+ * This class automatically guarantees that given EditorDOMPoint instance
+ * stores offset and invalidates its child node when the instance is destroyed.
+ * Additionally, users of this class can invalidate the child manually when
+ * they need.
+ */
+class MOZ_STACK_CLASS AutoEditorDOMPointChildInvalidator final
+{
+public:
+  explicit AutoEditorDOMPointChildInvalidator(EditorDOMPoint& aPoint)
+    : mPoint(aPoint)
+  {
+    MOZ_ASSERT(aPoint.IsSetAndValid());
+    Unused << mPoint.Offset();
+  }
+
+  ~AutoEditorDOMPointChildInvalidator()
+  {
+    InvalidateChild();
+  }
+
+  /**
+   * Manually, invalidate child of the given point.
+   */
+  void InvalidateChild()
+  {
+    mPoint.Set(mPoint.Container(), mPoint.Offset());
+  }
+
+private:
+  EditorDOMPoint& mPoint;
+
+  AutoEditorDOMPointChildInvalidator() = delete;
+  AutoEditorDOMPointChildInvalidator(
+    const AutoEditorDOMPointChildInvalidator& aOther) = delete;
+  const AutoEditorDOMPointChildInvalidator& operator=(
+    const AutoEditorDOMPointChildInvalidator& aOther) = delete;
+};
+
 } // namespace mozilla
 
 #endif // #ifndef mozilla_EditorDOMPoint_h