Bug 1361301: Extract the core algorithm from nsContentUtils::GetCommonAncestor. r=smaug
authorEmilio Cobos Álvarez <emilio@crisal.io>
Wed, 03 May 2017 12:57:53 +0200
changeset 356793 461422aa386e2eb3a3c8fe8b17fe099d286f9507
parent 356742 43b5aab2e5953925c0ddc17f163ad479d14e2401
child 356794 85415b39c31c812d2245034fc044bbcecf10b370
push id89970
push userkwierso@gmail.com
push dateFri, 05 May 2017 21:20:56 +0000
treeherdermozilla-inbound@c3d254b2070d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1361301
milestone55.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 1361301: Extract the core algorithm from nsContentUtils::GetCommonAncestor. r=smaug MozReview-Commit-ID: 7u6YaYN3dhb
dom/base/nsContentUtils.cpp
dom/base/nsContentUtils.h
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2495,54 +2495,64 @@ nsContentUtils::GetCommonAncestor(nsIDOM
   NS_ENSURE_TRUE(node1 && node2, NS_ERROR_UNEXPECTED);
 
   nsINode* common = GetCommonAncestor(node1, node2);
   NS_ENSURE_TRUE(common, NS_ERROR_NOT_AVAILABLE);
 
   return CallQueryInterface(common, aCommonAncestor);
 }
 
-// static
-nsINode*
-nsContentUtils::GetCommonAncestor(nsINode* aNode1,
-                                  nsINode* aNode2)
+template <typename Node, typename GetParentFunc>
+static Node*
+GetCommonAncestorInternal(Node* aNode1,
+                          Node* aNode2,
+                          GetParentFunc aGetParentFunc)
 {
   if (aNode1 == aNode2) {
     return aNode1;
   }
 
   // Build the chain of parents
-  AutoTArray<nsINode*, 30> parents1, parents2;
+  AutoTArray<Node*, 30> parents1, parents2;
   do {
     parents1.AppendElement(aNode1);
-    aNode1 = aNode1->GetParentNode();
+    aNode1 = aGetParentFunc(aNode1);
   } while (aNode1);
   do {
     parents2.AppendElement(aNode2);
-    aNode2 = aNode2->GetParentNode();
+    aNode2 = aGetParentFunc(aNode2);
   } while (aNode2);
 
   // Find where the parent chain differs
   uint32_t pos1 = parents1.Length();
   uint32_t pos2 = parents2.Length();
-  nsINode* parent = nullptr;
+  Node* parent = nullptr;
   uint32_t len;
   for (len = std::min(pos1, pos2); len > 0; --len) {
-    nsINode* child1 = parents1.ElementAt(--pos1);
-    nsINode* child2 = parents2.ElementAt(--pos2);
+    Node* child1 = parents1.ElementAt(--pos1);
+    Node* child2 = parents2.ElementAt(--pos2);
     if (child1 != child2) {
       break;
     }
     parent = child1;
   }
 
   return parent;
 }
 
 /* static */
+nsINode*
+nsContentUtils::GetCommonAncestor(nsINode* aNode1, nsINode* aNode2)
+{
+  return GetCommonAncestorInternal(aNode1, aNode2, [](nsINode* aNode) {
+    return aNode->GetParentNode();
+  });
+}
+
+/* static */
 bool
 nsContentUtils::PositionIsBefore(nsINode* aNode1, nsINode* aNode2)
 {
   return (aNode2->CompareDocumentPosition(*aNode1) &
     (nsIDOMNode::DOCUMENT_POSITION_PRECEDING |
      nsIDOMNode::DOCUMENT_POSITION_DISCONNECTED)) ==
     nsIDOMNode::DOCUMENT_POSITION_PRECEDING;
 }
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -361,21 +361,22 @@ public:
    * Returns an error if the two nodes are disconnected and don't have
    * a common ancestor.
    */
   static nsresult GetCommonAncestor(nsIDOMNode *aNode,
                                     nsIDOMNode *aOther,
                                     nsIDOMNode** aCommonAncestor);
 
   /**
-   * Returns the common ancestor, if any, for two nodes. Returns null if the
-   * nodes are disconnected.
+   * Returns the common ancestor, if any, for two nodes.
+   *
+   * Returns null if the nodes are disconnected.
    */
-  static nsINode* GetCommonAncestor(nsINode* aNode1,
-                                    nsINode* aNode2);
+  static nsINode* GetCommonAncestor(nsINode* aNode1, nsINode* aNode2);
+
 
   /**
    * Returns true if aNode1 is before aNode2 in the same connected
    * tree.
    */
   static bool PositionIsBefore(nsINode* aNode1, nsINode* aNode2);
 
   /**