Bug 1533293 - part 4: Make Selection::SetStartAndEndInternal() select frames by itself r=smaug

When adding an range via `Selection::AddItem()` and only when it's caused by
user's operation, the range may be split at non-selectable content.  This is
done in `nsRange::ExcludeNonSelectableNodes()` but it modifies the given range
as the first range.  Then, [`Selection::AddRangeInternal()` calls
`Selection::SelectFrames()` with the range which may have been modified by
`nsRange::ExcludeNonSelectableNodes()`](https://searchfox.org/mozilla-central/rev/358f816f63da072145c593e9e2ac36b7250ecd25/dom/base/Selection.cpp#2030,2049).

Therefore, only the frames between first child of `<body>` element and
previous element of first non-selectable content are painted as selection
after user does "Select All".

[`Selection::Extend()` calls `Selection::SelectFrames()` by itself for all
existing ranges](https://searchfox.org/mozilla-central/rev/358f816f63da072145c593e9e2ac36b7250ecd25/dom/base/Selection.cpp#2718-2724).  Therefore, this patch creates new method and makes both
`Selection::Extend()` and `Selection::SetStartAndEndInternal()` call it only
when the result is not only one range.

Differential Revision: https://phabricator.services.mozilla.com/D24871

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Masayuki Nakano 2019-03-26 10:16:20 +00:00
Родитель 0a753c3aac
Коммит 05ac721436
2 изменённых файлов: 25 добавлений и 5 удалений

Просмотреть файл

@ -1509,6 +1509,14 @@ nsresult Selection::SelectAllFramesForContent(
return NS_OK;
}
void Selection::SelectFramesInAllRanges(nsPresContext* aPresContext) {
for (size_t i = 0; i < mRanges.Length(); ++i) {
nsRange* range = mRanges[i].mRange;
MOZ_ASSERT(range->IsInSelection());
SelectFrames(aPresContext, range, range->IsInSelection());
}
}
/**
* The idea of this helper method is to select or deselect "top to bottom",
* traversing through the frames
@ -2716,11 +2724,7 @@ void Selection::Extend(nsINode& aContainer, uint32_t aOffset,
}
if (mRanges.Length() > 1) {
for (size_t i = 0; i < mRanges.Length(); ++i) {
nsRange* range = mRanges[i].mRange;
MOZ_ASSERT(range->IsInSelection());
SelectFrames(presContext, range, range->IsInSelection());
}
SelectFramesInAllRanges(presContext);
}
DEBUG_OUT_RANGE(range);
@ -3487,6 +3491,16 @@ void Selection::SetStartAndEndInternal(InLimiter aInLimiter,
return;
}
// Adding a range may set 2 or more ranges if there are non-selectable
// contents only when this change is caused by a user operation. Therefore,
// we need to select frames with the result in such case.
if (mUserInitiated) {
RefPtr<nsPresContext> presContext = GetPresContext();
if (mRanges.Length() > 1 && presContext) {
SelectFramesInAllRanges(presContext);
}
}
SetDirection(aDirection);
}

Просмотреть файл

@ -697,6 +697,12 @@ class Selection final : public nsSupportsWeakReference,
nsresult SelectFrames(nsPresContext* aPresContext, nsRange* aRange,
bool aSelect);
/**
* SelectFramesInAllRanges() calls SelectFrames() for all current
* ranges.
*/
void SelectFramesInAllRanges(nsPresContext* aPresContext);
/**
* Test whether the supplied range points to a single table element.
* Result is one of the TableSelection constants. "None" means