Bug 1659717 - Make AutoSetTemporaryAncestorLimiter update cached ranges if selection limiter is updated r=m_kato

If `AutoSetTemporaryAncestorLimiter` sets ancestor limiter of the `Selection`,
existing range which is already cached by `AutoRangeArray` may be changed
into the new limiter.

Therefore, this patch makes `AutoSetTemporaryAncestorLimiter` take
`AutoRangeArray` optionally and reset it only when it sets new limiter for
the performance.

Differential Revision: https://phabricator.services.mozilla.com/D87820
This commit is contained in:
Masayuki Nakano 2020-08-24 08:54:56 +00:00
parent 2789c3c5d4
commit 4405418105
4 changed files with 34 additions and 7 deletions

View File

@ -741,8 +741,13 @@ class MOZ_STACK_CLASS AutoSelectionRangeArray final {
*****************************************************************************/
class MOZ_STACK_CLASS AutoRangeArray final {
public:
explicit AutoRangeArray(const dom::Selection& aSelection)
: mDirection(aSelection.GetDirection()) {
explicit AutoRangeArray(const dom::Selection& aSelection) {
Initialize(aSelection);
}
void Initialize(const dom::Selection& aSelection) {
mDirection = aSelection.GetDirection();
mRanges.Clear();
for (uint32_t i = 0; i < aSelection.RangeCount(); i++) {
mRanges.AppendElement(aSelection.GetRangeAt(i)->CloneRange());
if (aSelection.GetRangeAt(i) == aSelection.GetAnchorFocusRange()) {
@ -846,7 +851,7 @@ class MOZ_STACK_CLASS AutoRangeArray final {
private:
AutoTArray<mozilla::OwningNonNull<nsRange>, 8> mRanges;
RefPtr<nsRange> mAnchorFocusRange;
nsDirection mDirection;
nsDirection mDirection = nsDirection::eDirNext;
};
/******************************************************************************

View File

@ -103,9 +103,10 @@ static bool IsStyleCachePreservingSubAction(EditSubAction aEditSubAction) {
class MOZ_RAII AutoSetTemporaryAncestorLimiter final {
public:
explicit AutoSetTemporaryAncestorLimiter(HTMLEditor& aHTMLEditor,
Selection& aSelection,
nsINode& aStartPointNode) {
AutoSetTemporaryAncestorLimiter(HTMLEditor& aHTMLEditor,
Selection& aSelection,
nsINode& aStartPointNode,
AutoRangeArray* aRanges = nullptr) {
MOZ_ASSERT(aSelection.GetType() == SelectionType::eNormal);
if (aSelection.GetAncestorLimiter()) {
@ -116,6 +117,11 @@ class MOZ_RAII AutoSetTemporaryAncestorLimiter final {
if (root) {
aHTMLEditor.InitializeSelectionAncestorLimit(*root);
mSelection = &aSelection;
// Setting ancestor limiter may change ranges which were outer of
// the new limiter. Therefore, we need to reinitialize aRanges.
if (aRanges) {
aRanges->Initialize(aSelection);
}
}
}
@ -2508,7 +2514,8 @@ EditActionResult HTMLEditor::HandleDeleteSelectionInternal(
// yet, ancestor isn't set. So we must set root element of editor to
// ancestor temporarily.
AutoSetTemporaryAncestorLimiter autoSetter(*this, *SelectionRefPtr(),
*startPoint.GetContainer());
*startPoint.GetContainer(),
&aRangesToDelete);
Result<nsIEditor::EDirection, nsresult> extendResult =
aRangesToDelete.ExtendAnchorFocusRangeFor(*this, aDirectionAndAmount);

View File

@ -0,0 +1,14 @@
<html><script type="text/javascript" id="__gaOptOutExtension">window["_gaUserPrefs"] = { ioo : function() { return true; } }</script><head>
<meta http-equiv="content-type" content="text/html; charset=windows-1252">
<script>
document.addEventListener('DOMContentLoaded', async () => {
const selection = document.getSelection()
document.designMode = 'on'
selection.collapse(document, 0)
document.execCommand('forwardDelete', false, null)
})
</script>
</head>
<body>
<aside style="position:fixed;top:0px;right:0px;font-family:&quot;Lucida Console&quot;,monospace;background-color:#f2e6d9;padding:3px;z-index:10000;text-align:center;max-width:120px;opacity:0;transition:opacity linear;"></aside></body></html>
<!-- COMMENT -->

View File

@ -127,3 +127,4 @@ load 1644903.html
load 1645983-1.html
load 1645983-2.html
load 1648564.html
load 1659717.html