diff options
Diffstat (limited to 'dom/base')
-rw-r--r-- | dom/base/nsContentUtils.cpp | 50 | ||||
-rw-r--r-- | dom/base/nsContentUtils.h | 9 |
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. */ |