summaryrefslogtreecommitdiff
path: root/dom/base
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base')
-rw-r--r--dom/base/nsContentUtils.cpp50
-rw-r--r--dom/base/nsContentUtils.h9
2 files changed, 59 insertions, 0 deletions
diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp
index 55bcf473e0..c964f0ce29 100644
--- a/dom/base/nsContentUtils.cpp
+++ b/dom/base/nsContentUtils.cpp
@@ -2377,6 +2377,56 @@ nsContentUtils::GetCommonAncestor(nsINode* aNode1,
return parent;
}
+// static
+nsINode*
+nsContentUtils::GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
+ nsINode* aNode2)
+{
+ if (!aNode1 || !aNode2) {
+ return nullptr;
+ }
+
+ if (aNode1 == aNode2) {
+ return aNode1;
+ }
+
+ // Build the chain of parents
+ AutoTArray<nsINode*, 30> parents1;
+ do {
+ parents1.AppendElement(aNode1);
+ if (aNode1->IsElement() &&
+ aNode1->AsElement()->IsInteractiveHTMLContent(true)) {
+ break;
+ }
+ aNode1 = aNode1->GetFlattenedTreeParentNode();
+ } while (aNode1);
+
+ AutoTArray<nsINode*, 30> parents2;
+ do {
+ parents2.AppendElement(aNode2);
+ if (aNode2->IsElement() &&
+ aNode2->AsElement()->IsInteractiveHTMLContent(true)) {
+ break;
+ }
+ aNode2 = aNode2->GetFlattenedTreeParentNode();
+ } while (aNode2);
+
+ // Find where the parent chain differs
+ uint32_t pos1 = parents1.Length();
+ uint32_t pos2 = parents2.Length();
+ nsINode* parent = nullptr;
+ for (uint32_t len = std::min(pos1, pos2); len > 0; --len) {
+ nsINode* child1 = parents1.ElementAt(--pos1);
+ nsINode* child2 = parents2.ElementAt(--pos2);
+ if (child1 != child2) {
+ break;
+ }
+ parent = child1;
+ }
+
+ return parent;
+}
+
/* static */
bool
nsContentUtils::PositionIsBefore(nsINode* aNode1, nsINode* aNode2)
diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h
index 3393a30c5c..eb67ff6a6a 100644
--- a/dom/base/nsContentUtils.h
+++ b/dom/base/nsContentUtils.h
@@ -325,6 +325,15 @@ public:
nsINode* aNode2);
/**
+ * Returns the common ancestor under interactive content, if any.
+ * If neither one has interactive content as ancestor, common ancestor will be
+ * returned. If only one has interactive content as ancestor, null will be
+ * returned. If the nodes are the same, that node is returned.
+ */
+ static nsINode* GetCommonAncestorUnderInteractiveContent(nsINode* aNode1,
+ nsINode* aNode2);
+
+ /**
* Returns true if aNode1 is before aNode2 in the same connected
* tree.
*/