Bug 1965664 - Fix some crashes in ContentSubtreeIterator r=jjaschke,dom-core
by skipping the shadow hosts that ShadowDOM selection doesn't support at the moment. Differential Revision: https://phabricator.services.mozilla.com/D248917
This commit is contained in:
committed by
sefeng@mozilla.com
parent
3c343a8e2b
commit
e6a6045ffb
@@ -664,6 +664,13 @@ nsIContent* ContentIteratorBase<NodeType>::GetNextSibling(
|
|||||||
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {
|
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {
|
||||||
// Could have nested slots
|
// Could have nested slots
|
||||||
while (HTMLSlotElement* slot = aNode->AsContent()->GetAssignedSlot()) {
|
while (HTMLSlotElement* slot = aNode->AsContent()->GetAssignedSlot()) {
|
||||||
|
if (!ShadowDOMSelectionHelpers::GetShadowRoot(
|
||||||
|
slot->GetContainingShadowHost(), aAllowCrossShadowBoundary)) {
|
||||||
|
// The corresponding shadow host isn't supported
|
||||||
|
// by ContentSubtreeIterator, so let's skip this slot.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Next sibling of a slotted node should be the next slotted node
|
// Next sibling of a slotted node should be the next slotted node
|
||||||
auto currentIndex = slot->AssignedNodes().IndexOf(aNode);
|
auto currentIndex = slot->AssignedNodes().IndexOf(aNode);
|
||||||
if (currentIndex < slot->AssignedNodes().Length() - 1) {
|
if (currentIndex < slot->AssignedNodes().Length() - 1) {
|
||||||
@@ -726,6 +733,12 @@ nsIContent* ContentIteratorBase<NodeType>::GetPrevSibling(
|
|||||||
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {
|
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {
|
||||||
// Could have nested slots.
|
// Could have nested slots.
|
||||||
while (HTMLSlotElement* slot = aNode->AsContent()->GetAssignedSlot()) {
|
while (HTMLSlotElement* slot = aNode->AsContent()->GetAssignedSlot()) {
|
||||||
|
if (!ShadowDOMSelectionHelpers::GetShadowRoot(
|
||||||
|
slot->GetContainingShadowHost(), aAllowCrossShadowBoundary)) {
|
||||||
|
// The corresponding shadow host isn't supported
|
||||||
|
// by ContentSubtreeIterator, so let's skip this slot.
|
||||||
|
break;
|
||||||
|
}
|
||||||
// prev sibling of a slotted node should be the prev slotted node
|
// prev sibling of a slotted node should be the prev slotted node
|
||||||
auto currentIndex = slot->AssignedNodes().IndexOf(aNode);
|
auto currentIndex = slot->AssignedNodes().IndexOf(aNode);
|
||||||
if (currentIndex > 0) {
|
if (currentIndex > 0) {
|
||||||
@@ -1026,15 +1039,19 @@ void ContentSubtreeIterator::CacheInclusiveAncestorsOfEndContainer() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const bool isDescendantInShadowTree =
|
// `ShadowDOMSelectionHelpers::GetShadowRoot` would return non-null shadow
|
||||||
IterAllowCrossShadowBoundary() && child->IsShadowRoot();
|
// root if parent is a shadow host that we support cross boundary selection.
|
||||||
|
const bool isChildAShadowRootForSelection =
|
||||||
|
ShadowDOMSelectionHelpers::GetShadowRoot(
|
||||||
|
parent, mAllowCrossShadowBoundary) == child;
|
||||||
|
|
||||||
info.mAncestor = parent->AsContent();
|
info.mAncestor = parent->AsContent();
|
||||||
// mIsDescendantInShadowTree indicates that whether child is in the
|
// mIsDescendantInShadowTree indicates that whether child is in the
|
||||||
// shadow tree of parent or in the regular light DOM tree of parent.
|
// shadow tree of parent or in the regular light DOM tree of parent.
|
||||||
// So that later, when info.mAncestor is reached, we can decide whether
|
// So that later, when info.mAncestor is reached, we can decide whether
|
||||||
// we should dive into the shadow tree.
|
// we should dive into the shadow tree.
|
||||||
info.mIsDescendantInShadowTree = isDescendantInShadowTree;
|
info.mIsDescendantInShadowTree =
|
||||||
|
IterAllowCrossShadowBoundary() && isChildAShadowRootForSelection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1255,6 +1272,7 @@ void ContentSubtreeIterator::Next() {
|
|||||||
ShadowRoot* root = ShadowDOMSelectionHelpers::GetShadowRoot(
|
ShadowRoot* root = ShadowDOMSelectionHelpers::GetShadowRoot(
|
||||||
nextNode, mAllowCrossShadowBoundary);
|
nextNode, mAllowCrossShadowBoundary);
|
||||||
if (mInclusiveAncestorsOfEndContainer[i].mIsDescendantInShadowTree) {
|
if (mInclusiveAncestorsOfEndContainer[i].mIsDescendantInShadowTree) {
|
||||||
|
MOZ_ASSERT(root);
|
||||||
nextNode = root->GetFirstChild();
|
nextNode = root->GetFirstChild();
|
||||||
} else if (auto* slot = HTMLSlotElement::FromNode(nextNode);
|
} else if (auto* slot = HTMLSlotElement::FromNode(nextNode);
|
||||||
slot && IterAllowCrossShadowBoundary()) {
|
slot && IterAllowCrossShadowBoundary()) {
|
||||||
|
|||||||
@@ -365,7 +365,9 @@ nsINode* ShadowDOMSelectionHelpers::GetParentNodeInSameSelection(
|
|||||||
if (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() &&
|
if (StaticPrefs::dom_shadowdom_selection_across_boundary_enabled() &&
|
||||||
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {
|
aAllowCrossShadowBoundary == AllowRangeCrossShadowBoundary::Yes) {
|
||||||
if (aNode.IsContent()) {
|
if (aNode.IsContent()) {
|
||||||
if (HTMLSlotElement* slot = aNode.AsContent()->GetAssignedSlot()) {
|
if (HTMLSlotElement* slot = aNode.AsContent()->GetAssignedSlot();
|
||||||
|
slot && GetShadowRoot(slot->GetContainingShadowHost(),
|
||||||
|
aAllowCrossShadowBoundary)) {
|
||||||
return slot;
|
return slot;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
10
dom/base/crashtests/1965664.html
Normal file
10
dom/base/crashtests/1965664.html
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<script>
|
||||||
|
addEventListener("DOMContentLoaded", () => {
|
||||||
|
a.ownerDocument.designMode = "on"
|
||||||
|
document.execCommand("selectAll", false, null)
|
||||||
|
document.execCommand("superscript", false, null)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
<s>
|
||||||
|
<h2>
|
||||||
|
<marquee id="a">
|
||||||
@@ -283,3 +283,4 @@ load 1897248.html
|
|||||||
load 1907464.html
|
load 1907464.html
|
||||||
asserts(0-1) load 1907228.html # see bug 1908485 for assert
|
asserts(0-1) load 1907228.html # see bug 1908485 for assert
|
||||||
load 1922153.html
|
load 1922153.html
|
||||||
|
load 1965664.html
|
||||||
|
|||||||
Reference in New Issue
Block a user