summaryrefslogtreecommitdiffstats
path: root/dom/base/nsINode.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/nsINode.cpp')
-rw-r--r--dom/base/nsINode.cpp66
1 files changed, 58 insertions, 8 deletions
diff --git a/dom/base/nsINode.cpp b/dom/base/nsINode.cpp
index d5455e5596..6c77574df7 100644
--- a/dom/base/nsINode.cpp
+++ b/dom/base/nsINode.cpp
@@ -287,11 +287,17 @@ static const nsINode* GetClosestCommonInclusiveAncestorForRangeInSelection(
const nsINode* aNode) {
while (aNode &&
!aNode->IsClosestCommonInclusiveAncestorForRangeInSelection()) {
+ const bool isNodeInShadowTree =
+ StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() &&
+ aNode->IsInShadowTree();
if (!aNode
- ->IsDescendantOfClosestCommonInclusiveAncestorForRangeInSelection()) {
+ ->IsDescendantOfClosestCommonInclusiveAncestorForRangeInSelection() &&
+ !isNodeInShadowTree) {
return nullptr;
}
- aNode = aNode->GetParentNode();
+ aNode = StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()
+ ? aNode->GetParentOrShadowHostNode()
+ : aNode->GetParentNode();
}
return aNode;
}
@@ -315,12 +321,12 @@ class IsItemInRangeComparator {
int operator()(const AbstractRange* const aRange) const {
int32_t cmp = nsContentUtils::ComparePoints_Deprecated(
- &mNode, mEndOffset, aRange->GetStartContainer(), aRange->StartOffset(),
- nullptr, mCache);
+ &mNode, mEndOffset, aRange->GetMayCrossShadowBoundaryStartContainer(),
+ aRange->MayCrossShadowBoundaryStartOffset(), nullptr, mCache);
if (cmp == 1) {
cmp = nsContentUtils::ComparePoints_Deprecated(
- &mNode, mStartOffset, aRange->GetEndContainer(), aRange->EndOffset(),
- nullptr, mCache);
+ &mNode, mStartOffset, aRange->GetMayCrossShadowBoundaryEndContainer(),
+ aRange->MayCrossShadowBoundaryEndOffset(), nullptr, mCache);
if (cmp == -1) {
return 0;
}
@@ -386,6 +392,18 @@ bool nsINode::IsSelected(const uint32_t aStartOffset,
return true;
}
+ if (range->MayCrossShadowBoundary()) {
+ MOZ_ASSERT(range->IsDynamicRange(),
+ "range->MayCrossShadowBoundary() can only return true for "
+ "dynamic range");
+ StaticRange* crossBoundaryRange =
+ range->AsDynamicRange()->GetCrossShadowBoundaryRange();
+ MOZ_ASSERT(crossBoundaryRange);
+ if (!crossBoundaryRange->Collapsed()) {
+ return true;
+ }
+ }
+
const AbstractRange* middlePlus1;
const AbstractRange* middleMinus1;
// if node end > start of middle+1, result = 1
@@ -552,7 +570,8 @@ static nsIContent* GetRootForContentSubtree(nsIContent* aContent) {
return nsIContent::FromNode(aContent->SubtreeRoot());
}
-nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
+nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell,
+ bool aAllowCrossShadowBoundary) {
NS_ENSURE_TRUE(aPresShell, nullptr);
if (IsDocument()) return AsDocument()->GetRootElement();
@@ -596,7 +615,7 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
}
RefPtr<nsFrameSelection> fs = aPresShell->FrameSelection();
- nsIContent* content = fs->GetLimiter();
+ nsCOMPtr<nsIContent> content = fs->GetLimiter();
if (!content) {
content = fs->GetAncestorLimiter();
if (!content) {
@@ -616,6 +635,10 @@ nsIContent* nsINode::GetSelectionRootContent(PresShell* aPresShell) {
// Use the host as the root.
if (ShadowRoot* shadowRoot = ShadowRoot::FromNode(content)) {
content = shadowRoot->GetHost();
+ if (content && aAllowCrossShadowBoundary) {
+ content = content->GetSelectionRootContent(aPresShell,
+ aAllowCrossShadowBoundary);
+ }
}
}
@@ -3826,6 +3849,33 @@ void nsINode::FireNodeRemovedForChildren() {
}
}
+ShadowRoot* nsINode::GetShadowRoot() const {
+ return IsContent() ? AsContent()->GetShadowRoot() : nullptr;
+}
+
+ShadowRoot* nsINode::GetShadowRootForSelection() const {
+ if (!StaticPrefs::dom_shadowdom_selection_across_boundary_enabled()) {
+ return nullptr;
+ }
+
+ ShadowRoot* shadowRoot = GetShadowRoot();
+ if (!shadowRoot) {
+ return nullptr;
+ }
+
+ // ie. <details> and <video>
+ if (shadowRoot->IsUAWidget()) {
+ return nullptr;
+ }
+
+ // ie. <use> element
+ if (IsElement() && !AsElement()->CanAttachShadowDOM()) {
+ return nullptr;
+ }
+
+ return shadowRoot;
+}
+
NS_IMPL_ISUPPORTS(nsNodeWeakReference, nsIWeakReference)
nsNodeWeakReference::nsNodeWeakReference(nsINode* aNode)