Bug 1685303: part 28) Add virtual AccessibleCaretManager::MaybeFlushLayout. r=TYLin,smaug

In the unit-tests, flushing is not done. This was prevented implicitly
by nulling `mPresShell`. This change makes that explicit by stubbing
`MaybeFlushLayout`.

Note that `IsTerminated`, which is called in the same context is already
virtual, so I expect this to not have a noticeable performance-impact.

Depends on D102607

Differential Revision: https://phabricator.services.mozilla.com/D102608
This commit is contained in:
Mirko Brodesser 2021-01-22 12:18:05 +00:00
parent 17413678c3
commit e18a0436b9
3 changed files with 31 additions and 19 deletions

View File

@ -182,8 +182,18 @@ void AccessibleCaretManager::HideCaretsAndDispatchCaretStateChangedEvent() {
}
}
auto AccessibleCaretManager::MaybeFlushLayout() -> Terminated {
if (mPresShell) {
// `MaybeFlush` doesn't access the PresShell after flushing, so it's OK to
// mark it as live.
mLayoutFlusher.MaybeFlush(MOZ_KnownLive(*mPresShell));
}
return IsTerminated();
}
void AccessibleCaretManager::UpdateCarets(const UpdateCaretsHintSet& aHint) {
if (mLayoutFlusher.MaybeFlush(*this) == Terminated::Yes) {
if (MaybeFlushLayout() == Terminated::Yes) {
return;
}
@ -346,7 +356,7 @@ void AccessibleCaretManager::UpdateCaretsForSelectionMode(
if (mIsCaretPositionChanged) {
// Flush layout to make the carets intersection correct.
if (mLayoutFlusher.MaybeFlush(*this) == Terminated::Yes) {
if (MaybeFlushLayout() == Terminated::Yes) {
return;
}
}
@ -1025,18 +1035,17 @@ void AccessibleCaretManager::ClearMaintainedSelection() const {
}
}
auto AccessibleCaretManager::LayoutFlusher::MaybeFlush(
const AccessibleCaretManager& aAccessibleCaretManager) -> Terminated {
if (aAccessibleCaretManager.mPresShell && mAllowFlushing) {
void AccessibleCaretManager::LayoutFlusher::MaybeFlush(
const PresShell& aPresShell) {
if (mAllowFlushing) {
AutoRestore<bool> flushing(mFlushing);
mFlushing = true;
if (Document* doc = aAccessibleCaretManager.mPresShell->GetDocument()) {
if (Document* doc = aPresShell.GetDocument()) {
doc->FlushPendingNotifications(FlushType::Layout);
// Don't access the PresShell after flushing, it could've become invalid.
}
}
return aAccessibleCaretManager.IsTerminated();
}
nsIFrame* AccessibleCaretManager::GetFrameForFirstRangeStartOrLastRangeEnd(
@ -1405,7 +1414,7 @@ void AccessibleCaretManager::StopSelectionAutoScrollTimer() const {
void AccessibleCaretManager::DispatchCaretStateChangedEvent(
CaretChangedReason aReason) {
if (mLayoutFlusher.MaybeFlush(*this) == Terminated::Yes) {
if (MaybeFlushLayout() == Terminated::Yes) {
return;
}

View File

@ -50,6 +50,7 @@ class Selection;
//
class AccessibleCaretManager {
public:
// @param aPresShell may be nullptr for testing.
explicit AccessibleCaretManager(PresShell* aPresShell);
virtual ~AccessibleCaretManager() = default;
@ -160,6 +161,15 @@ class AccessibleCaretManager {
friend std::ostream& operator<<(std::ostream& aStream,
const UpdateCaretsHint& aResult);
enum class Terminated : bool { No, Yes };
// This method could kill the shell, so callers to methods that call
// MaybeFlushLayout should ensure the event hub that owns us is still alive.
//
// See the mRefCnt assertions in AccessibleCaretEventHub.
//
[[nodiscard]] MOZ_CAN_RUN_SCRIPT virtual Terminated MaybeFlushLayout();
// Update carets based on current selection status. This function will flush
// layout, so caller must ensure the PresShell is still valid after calling
// this method.
@ -231,8 +241,6 @@ class AccessibleCaretManager {
void ClearMaintainedSelection() const;
enum class Terminated : bool { No, Yes };
static dom::Element* GetEditingHostForFrame(const nsIFrame* aFrame);
dom::Selection* GetSelection() const;
already_AddRefed<nsFrameSelection> GetFrameSelection() const;
@ -333,14 +341,7 @@ class AccessibleCaretManager {
public:
~LayoutFlusher();
// This method could kill the shell, so callers to methods that call
// MaybeFlush should ensure the event hub that owns us is still alive.
//
// See the mRefCnt assertions in AccessibleCaretEventHub.
//
// @return aAccessibleCaretManager.IsTerminated().
[[nodiscard]] MOZ_CAN_RUN_SCRIPT Terminated
MaybeFlush(const AccessibleCaretManager& aAccessibleCaretManager);
MOZ_CAN_RUN_SCRIPT void MaybeFlush(const PresShell& aPresShell);
// Set to false to disallow flushing layout in some callbacks such as
// OnReflow(), OnScrollStart(), OnScrollStart(), or

View File

@ -102,6 +102,8 @@ class AccessibleCaretManagerTester : public ::testing::Test {
Terminated IsTerminated() const override { return Terminated::No; }
bool IsScrollStarted() const { return mIsScrollStarted; }
Terminated MaybeFlushLayout() override { return Terminated::No; }
MOCK_CONST_METHOD0(GetCaretMode, CaretMode());
MOCK_METHOD1(DispatchCaretStateChangedEvent,
void(CaretChangedReason aReason));