`Selection::Extend` may cross anonymous subtree root boundary
Categories
(Core :: DOM: Selection, defect)
Tracking
()
Tracking | Status | |
---|---|---|
firefox138 | --- | fixed |
People
(Reporter: masayuki, Assigned: masayuki)
References
(Regressed 1 open bug)
Details
Attachments
(2 files)
With the patch for bug 1945711 and adding assertion, I got this assertion failure.
[Child 5458, Main Thread] WARNING: The caller cannot compare the position of the child of the common ancestor due to not in the child list of the common ancestor:
textarea.div['content'].body.html.#document
+ div.textarea.div['content'].body.html.#document
: file /builds/worker/checkouts/gecko/dom/base/nsContentUtils.cpp:880
#01: nsContentUtils::ComparePointsWithIndices(nsINode const*, unsigned int, nsINode const*, unsigned int, nsContentUtils::ResizableNodeIndexCache<(unsigned long)100>*) [dom/base/nsContentUtils.cpp:3408]
#02: mozilla::RangeUtils::CompareNodeToRangeBoundaries<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent>, nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> >(nsINode*, mozilla::RangeBoundaryBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&, mozilla::RangeBoundaryBase<nsCOMPtr<nsINode>, nsCOMPtr<nsIContent> > const&, bool*, bool*) [dom/base/RangeUtils.cpp:220]
#03: mozilla::RangeUtils::IsNodeContainedInRange(nsINode&, mozilla::dom::AbstractRange*) [dom/base/RangeUtils.cpp:127]
#04: mozilla::ContentSubtreeIterator::GetTopAncestorInRange(nsINode*) const [dom/base/ContentIterator.cpp:1255]
#05: mozilla::ContentSubtreeIterator::DetermineFirstContent() const [dom/base/ContentIterator.cpp:0]
#06: mozilla::ContentSubtreeIterator::InitWithRange() [dom/base/ContentIterator.cpp:1093]
#07: mozilla::ContentSubtreeIterator::InitWithAllowCrossShadowBoundary(mozilla::dom::AbstractRange*) [dom/base/ContentIterator.cpp:0]
#08: mozilla::dom::Selection::SelectFrames(nsPresContext*, mozilla::dom::AbstractRange&, bool) const [dom/base/Selection.cpp:1942]
#09: mozilla::dom::Selection::Extend(nsINode&, unsigned int, mozilla::ErrorResult&) [dom/base/Selection.cpp:0]
#10: mozilla::dom::Selection::Extend(nsINode*, unsigned int) [dom/base/Selection.cpp:3005]
#11: nsFrameSelection::TakeFocus(nsIContent&, unsigned int, unsigned int, mozilla::CaretAssociationHint, nsFrameSelection::FocusMode) [layout/generic/nsFrameSelection.cpp:1524]
#12: nsFrameSelection::HandleClick(nsIContent*, unsigned int, unsigned int, nsFrameSelection::FocusMode, mozilla::CaretAssociationHint) [layout/generic/nsFrameSelection.cpp:1267]
#13: nsIFrame::PeekBackwardAndForward(nsSelectionAmount, nsSelectionAmount, int, bool, unsigned int) [layout/generic/nsIFrame.cpp:5168]
#14: nsIFrame::SelectByTypeAtPoint(nsPresContext*, nsPoint const&, nsSelectionAmount, nsSelectionAmount, unsigned int) [layout/generic/nsIFrame.cpp:0]
#15: nsIFrame::HandleMultiplePress(nsPresContext*, mozilla::WidgetGUIEvent*, nsEventStatus*, bool) [layout/generic/nsIFrame.cpp:5094]
#16: nsIFrame::MoveCaretToEventPoint(nsPresContext*, mozilla::WidgetMouseEvent*, nsEventStatus*) [layout/generic/nsIFrame.cpp:4784]
#17: nsIFrame::HandleEvent(nsPresContext*, mozilla::WidgetGUIEvent*, nsEventStatus*) [layout/generic/nsIFrame.cpp:4434]
This may be related to bug 1943225. The root cause must be that nsIFrame::PeekBackwardAndForward
crosses the anonymous subtree root element boundary, but Selection::Extend
may allow to extend the range as crossing the boundary.
Assignee | ||
Comment 1•2 months ago
|
||
I saw this failure with running layout/generic/test/test_bug1655135.html
.
Assignee | ||
Updated•14 days ago
|
Assignee | ||
Comment 2•10 days ago
|
||
This patch fixes multiple points which may cross independent selection
boundaries which is element boundary of the native anonymous <div>
for
editable content in text controls. The reason why I don't split this patch is,
fixing one of them leads another assertion failure. So, I couldn't pass all
tests with separated patches.
nsFrameTraversal
should takeElement
instead ofnsIFrame
for the
limiter because e.g., inline editing host like<span contenteditable>
may
have multiple frames if it's wrapped. Therefore, we should make it take
an element as the ancestor limiter, and check it when getting parent frame
or after getting previous or next frame.nsIFrame::PeekBackwardAndForward
may cross the boundary because it does not
take the anonymous<div>
element as ancestor limiter of the selection. It's
currently used only for extending selection. Therefore, I rename it to make
it clearer.SelectionMovementUtils::GetPrevNextBidiLevel
to take the ancestor limiter
for callingnsIFrame::GetFrameFromDirection()
.nsINode
should have a method to return thensFrameSelection
instance
which manages the selection in the node. This makes the check simpler, and
this is not expensive. Then, for making it clearer, I rename
TextControlElement::GetConstFrameSelection()
to
GetIndependentFrameSelection()
.nsINode::GetSelectionRootContent()
should have an option to return
independent selection root when the node is its host for
nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree()
nsFrameSelection::ConstrainFrameAndPointToAnchorSubtree()
should not
retrieve independent selection root when the given frame is a text control
frame.RangeUtils
should get parent with checking the independent selection
boundaries.Selection::Extend
should assert if the destination is managed by its
frame selection to detect a bug.
Assignee | ||
Comment 3•7 days ago
|
||
The methods are now, GetConstFrameSelection()
etc, but does not return
const nsFrameSelection*
. I believe that GetIndependentFrameSelection()
is
clearer than the old names.
And also this patch adds IsIndependentSelection()
and
GetIndependentSelectionRootParentElement()
to make some callers of
GetLimiter()
easier to read.
For the consistency, GetLimiter()
should be renamed too, but I already have
a patch doing it in bug 1954020 and it's bigger. Therefore, I leave it as-is
for now.
Comment 5•7 days ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/30cfc2e67ec3
https://hg.mozilla.org/mozilla-central/rev/56e690d6db67
Description
•