Bug 1399626 - Part 2: Add overloads of nsRange::{CreateRange, SetStartAndEnd} which take RangeBoundaries, r=masayuki
authorNika Layzell <nika@thelayzells.com>
Mon, 02 Oct 2017 10:58:26 -0400
changeset 437259 40e91907879c49cd997d78695120714c69b71903
parent 437258 97289c8c2b279664a64557758402e3daed9f50e9
child 437260 c931f9aa36ec012a1e3d587a6de7613d66fc480d
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmasayuki
bugs1399626
milestone58.0a1
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
Bug 1399626 - Part 2: Add overloads of nsRange::{CreateRange, SetStartAndEnd} which take RangeBoundaries, r=masayuki MozReview-Commit-ID: 3u6jcMh5mni
dom/base/nsRange.cpp
dom/base/nsRange.h
--- a/dom/base/nsRange.cpp
+++ b/dom/base/nsRange.cpp
@@ -312,16 +312,31 @@ nsRange::CreateRange(nsIDOMNode* aStartC
 {
   RefPtr<nsRange> range;
   nsresult rv = nsRange::CreateRange(aStartContainer, aStartOffset, aEndParent,
                                      aEndOffset, getter_AddRefs(range));
   range.forget(aRange);
   return rv;
 }
 
+/* static */
+nsresult
+nsRange::CreateRange(const RawRangeBoundary& aStart,
+                     const RawRangeBoundary& aEnd,
+                     nsRange** aRange)
+{
+  RefPtr<nsRange> range = new nsRange(aStart.Container());
+  nsresult rv = range->SetStartAndEnd(aStart, aEnd);
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+  range.forget(aRange);
+  return NS_OK;
+}
+
 /******************************************************
  * nsISupports
  ******************************************************/
 
 NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_ADDREF(nsRange)
 NS_IMPL_MAIN_THREAD_ONLY_CYCLE_COLLECTING_RELEASE_WITH_LAST_RELEASE(
   nsRange, DoSetRange(RawRangeBoundary(), RawRangeBoundary(), nullptr))
 
@@ -1525,77 +1540,82 @@ nsRange::SelectNodesInContainer(nsINode*
   }
 
   RawRangeBoundary start(aContainer, aStartContent->GetPreviousSibling());
   RawRangeBoundary end(aContainer, aEndContent);
   DoSetRange(start, end, newRoot);
 }
 
 nsresult
+nsRange::SetStartAndEnd(const RawRangeBoundary& aStart,
+                        const RawRangeBoundary& aEnd)
+{
+  if (NS_WARN_IF(!aStart.IsSet()) || NS_WARN_IF(!aEnd.IsSet())) {
+    return NS_ERROR_INVALID_ARG;
+  }
+
+  nsINode* newStartRoot = IsValidBoundary(aStart.Container());
+  if (!newStartRoot) {
+    return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
+  }
+  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;
+    }
+    // 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 (aStart.Offset() > aEnd.Offset()) {
+      DoSetRange(aEnd, aEnd, newStartRoot);
+    } else {
+      DoSetRange(aStart, aEnd, newStartRoot);
+    }
+    return NS_OK;
+  }
+
+  nsINode* newEndRoot = IsValidBoundary(aEnd.Container());
+  if (!newEndRoot) {
+    return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
+  }
+  if (!aEnd.IsSetAndValid()) {
+    return NS_ERROR_DOM_INDEX_SIZE_ERR;
+  }
+
+  // If they have different root, this should be collapsed at the end point.
+  if (newStartRoot != newEndRoot) {
+    DoSetRange(aEnd, aEnd, newEndRoot);
+    return NS_OK;
+  }
+
+  // If the end point is before the start point, this should be collapsed at
+  // the end point.
+  if (nsContentUtils::ComparePoints(aStart, aEnd) == 1) {
+    DoSetRange(aEnd, aEnd, newEndRoot);
+    return NS_OK;
+  }
+
+  // Otherwise, set the range as specified.
+  DoSetRange(aStart, aEnd, newStartRoot);
+  return NS_OK;
+}
+
+nsresult
 nsRange::SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset,
                         nsINode* aEndContainer, uint32_t aEndOffset)
 {
   if (NS_WARN_IF(!aStartContainer) || NS_WARN_IF(!aEndContainer)) {
     return NS_ERROR_INVALID_ARG;
   }
 
-  nsINode* newStartRoot = IsValidBoundary(aStartContainer);
-  if (!newStartRoot) {
-    return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
-  }
-  if (!IsValidOffset(aStartContainer, aStartOffset)) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-
-  if (aStartContainer == aEndContainer) {
-    if (!IsValidOffset(aEndContainer, aEndOffset)) {
-      return NS_ERROR_DOM_INDEX_SIZE_ERR;
-    }
-    // If the end offset is less than the start offset, this should be
-    // collapsed at the end offset.
-    if (aStartOffset > aEndOffset) {
-      DoSetRange(aEndContainer, aEndOffset,
-                 aEndContainer, aEndOffset, newStartRoot);
-    } else {
-      DoSetRange(aStartContainer, aStartOffset,
-                 aEndContainer, aEndOffset, newStartRoot);
-    }
-    return NS_OK;
-  }
-
-  nsINode* newEndRoot = IsValidBoundary(aEndContainer);
-  if (!newEndRoot) {
-    return NS_ERROR_DOM_INVALID_NODE_TYPE_ERR;
-  }
-  if (!IsValidOffset(aEndContainer, aEndOffset)) {
-    return NS_ERROR_DOM_INDEX_SIZE_ERR;
-  }
-
-  // If they have different root, this should be collapsed at the end point.
-  if (newStartRoot != newEndRoot) {
-    DoSetRange(aEndContainer, aEndOffset,
-               aEndContainer, aEndOffset, newEndRoot);
-    return NS_OK;
-  }
-
-  // If the end point is before the start point, this should be collapsed at
-  // the end point.
-  if (nsContentUtils::ComparePoints(aStartContainer,
-                                    static_cast<int32_t>(aStartOffset),
-                                    aEndContainer,
-                                    static_cast<int32_t>(aEndOffset)) == 1) {
-    DoSetRange(aEndContainer, aEndOffset,
-               aEndContainer, aEndOffset, newEndRoot);
-    return NS_OK;
-  }
-
-  // Otherwise, set the range as specified.
-  DoSetRange(aStartContainer, aStartOffset,
-             aEndContainer, aEndOffset, newStartRoot);
-  return NS_OK;
+  return SetStartAndEnd(RawRangeBoundary(aStartContainer, aStartOffset),
+                        RawRangeBoundary(aEndContainer, aEndOffset));
 }
 
 void
 nsRange::SetEndBeforeJS(nsINode& aNode, ErrorResult& aErr)
 {
   AutoCalledByJSRestore calledByJSRestorer(*this);
   mCalledByJS = true;
   SetEndBefore(aNode, aErr);
--- a/dom/base/nsRange.h
+++ b/dom/base/nsRange.h
@@ -63,16 +63,19 @@ public:
                               nsIDOMNode* aEndContainer,
                               uint32_t aEndOffset,
                               nsIDOMRange** aRange);
   static nsresult CreateRange(nsINode* aStartContainer,
                               uint32_t aStartOffset,
                               nsINode* aEndContainer,
                               uint32_t aEndOffset,
                               nsRange** aRange);
+  static nsresult CreateRange(const RawRangeBoundary& aStart,
+                              const RawRangeBoundary& aEnd,
+                              nsRange** aRange);
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsRange, nsIDOMRange)
 
   nsrefcnt GetRefCount() const
   {
     return mRefCnt;
   }
@@ -189,16 +192,18 @@ public:
    * Different from calls them separately, this does nothing if either
    * the start point or the end point is invalid point.
    * If the specified start point is after the end point, the range will be
    * collapsed at the end point.  Similarly, if they are in different root,
    * the range will be collapsed at the end point.
    */
   nsresult SetStartAndEnd(nsINode* aStartContainer, uint32_t aStartOffset,
                           nsINode* aEndContainer, uint32_t aEndOffset);
+  nsresult SetStartAndEnd(const RawRangeBoundary& aStart,
+                          const RawRangeBoundary& aEnd);
 
   /**
    * Adds all nodes between |aStartContent| and |aEndContent| to the range.
    * The start offset will be set before |aStartContent|,
    * while the end offset will be set immediately after |aEndContent|.
    *
    * Caller must guarantee both nodes are non null and
    * children of |aContainer| and that |aEndContent| is after |aStartContent|.