1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "gtest/gtest.h"
8 #include "gmock/gmock.h"
12 #include "AccessibleCaret.h"
13 #include "AccessibleCaretManager.h"
14 #include "mozilla/Preferences.h"
17 using ::testing::DefaultValue
;
19 using ::testing::InSequence
;
20 using ::testing::MockFunction
;
21 using ::testing::Return
;
23 // -----------------------------------------------------------------------------
24 // This file tests CaretStateChanged events and the appearance of the two
25 // AccessibleCarets manipulated by AccessibleCaretManager.
28 using dom::CaretChangedReason
;
30 class MOZ_RAII AutoRestoreBoolPref final
{
32 AutoRestoreBoolPref(const char* aPref
, bool aValue
) : mPref(aPref
) {
33 Preferences::GetBool(mPref
, &mOldValue
);
34 Preferences::SetBool(mPref
, aValue
);
37 ~AutoRestoreBoolPref() { Preferences::SetBool(mPref
, mOldValue
); }
40 const char* mPref
= nullptr;
41 bool mOldValue
= false;
44 class AccessibleCaretManagerTester
: public ::testing::Test
{
46 class MockAccessibleCaret
: public AccessibleCaret
{
48 MockAccessibleCaret() : AccessibleCaret(nullptr) {}
50 void SetAppearance(Appearance aAppearance
) override
{
51 // A simplified version without touching CaretElement().
52 mAppearance
= aAppearance
;
55 MOCK_METHOD2(SetPosition
,
56 PositionChangedResult(nsIFrame
* aFrame
, int32_t aOffset
));
58 }; // class MockAccessibleCaret
60 class MockAccessibleCaretManager
: public AccessibleCaretManager
{
62 using CaretMode
= AccessibleCaretManager::CaretMode
;
63 using AccessibleCaretManager::HideCaretsAndDispatchCaretStateChangedEvent
;
64 using AccessibleCaretManager::UpdateCarets
;
66 MockAccessibleCaretManager()
67 : AccessibleCaretManager(nullptr,
68 Carets
{MakeUnique
<MockAccessibleCaret
>(),
69 MakeUnique
<MockAccessibleCaret
>()}) {}
71 MockAccessibleCaret
& FirstCaret() {
72 return static_cast<MockAccessibleCaret
&>(*mCarets
.GetFirst());
75 MockAccessibleCaret
& SecondCaret() {
76 return static_cast<MockAccessibleCaret
&>(*mCarets
.GetSecond());
79 bool CompareTreePosition(nsIFrame
* aStartFrame
,
80 nsIFrame
* aEndFrame
) const override
{
84 bool IsCaretDisplayableInCursorMode(
85 nsIFrame
** aOutFrame
= nullptr,
86 int32_t* aOutOffset
= nullptr) const override
{
90 bool UpdateCaretsForOverlappingTilt() override
{ return true; }
92 void UpdateCaretsForAlwaysTilt(const nsIFrame
* aStartFrame
,
93 const nsIFrame
* aEndFrame
) override
{
94 if (mCarets
.GetFirst()->IsVisuallyVisible()) {
95 mCarets
.GetFirst()->SetAppearance(Appearance::Left
);
97 if (mCarets
.GetSecond()->IsVisuallyVisible()) {
98 mCarets
.GetSecond()->SetAppearance(Appearance::Right
);
102 Terminated
IsTerminated() const override
{ return Terminated::No
; }
103 bool IsScrollStarted() const { return mIsScrollStarted
; }
105 Terminated
MaybeFlushLayout() override
{ return Terminated::No
; }
107 MOCK_CONST_METHOD0(GetCaretMode
, CaretMode());
108 MOCK_METHOD1(DispatchCaretStateChangedEvent
,
109 void(CaretChangedReason aReason
));
110 MOCK_CONST_METHOD1(HasNonEmptyTextContent
, bool(nsINode
* aNode
));
112 }; // class MockAccessibleCaretManager
114 using Appearance
= AccessibleCaret::Appearance
;
115 using PositionChangedResult
= AccessibleCaret::PositionChangedResult
;
116 using CaretMode
= MockAccessibleCaretManager::CaretMode
;
118 AccessibleCaretManagerTester() {
119 DefaultValue
<CaretMode
>::Set(CaretMode::None
);
120 DefaultValue
<PositionChangedResult
>::Set(PositionChangedResult::NotChanged
);
122 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
123 .WillRepeatedly(Return(PositionChangedResult::Position
));
125 EXPECT_CALL(mManager
.SecondCaret(), SetPosition(_
, _
))
126 .WillRepeatedly(Return(PositionChangedResult::Position
));
129 AccessibleCaret::Appearance
FirstCaretAppearance() {
130 return mManager
.FirstCaret().GetAppearance();
133 AccessibleCaret::Appearance
SecondCaretAppearance() {
134 return mManager
.SecondCaret().GetAppearance();
138 MockAccessibleCaretManager mManager
;
140 }; // class AccessibleCaretManagerTester
142 TEST_F(AccessibleCaretManagerTester
, TestUpdatesInSelectionMode
)
143 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
144 // Set default preference.
145 AutoRestoreBoolPref
savedPref("layout.accessiblecaret.always_tilt", false);
147 EXPECT_CALL(mManager
, GetCaretMode())
148 .WillRepeatedly(Return(CaretMode::Selection
));
150 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
151 CaretChangedReason::Updateposition
))
154 mManager
.UpdateCarets();
155 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
156 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal
);
159 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
160 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal
);
162 mManager
.OnScrollPositionChanged();
163 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
164 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal
);
167 TEST_F(AccessibleCaretManagerTester
, TestSingleTapOnNonEmptyInput
)
168 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
169 EXPECT_CALL(mManager
, GetCaretMode())
170 .WillRepeatedly(Return(CaretMode::Cursor
));
172 EXPECT_CALL(mManager
, HasNonEmptyTextContent(_
)).WillRepeatedly(Return(true));
174 MockFunction
<void(std::string aCheckPointName
)> check
;
178 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
179 CaretChangedReason::Updateposition
))
181 EXPECT_CALL(check
, Call("update"));
183 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
184 CaretChangedReason::Visibilitychange
))
186 EXPECT_CALL(check
, Call("mouse down"));
188 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(_
)).Times(0);
189 EXPECT_CALL(check
, Call("reflow"));
191 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(_
)).Times(0);
192 EXPECT_CALL(check
, Call("blur"));
194 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
195 CaretChangedReason::Updateposition
))
197 EXPECT_CALL(check
, Call("mouse up"));
199 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
200 CaretChangedReason::Updateposition
))
202 EXPECT_CALL(check
, Call("reflow2"));
204 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
205 CaretChangedReason::Updateposition
))
209 // Simulate a single tap on a non-empty input.
210 mManager
.UpdateCarets();
211 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
212 check
.Call("update");
214 mManager
.OnSelectionChanged(nullptr, nullptr,
215 nsISelectionListener::DRAG_REASON
|
216 nsISelectionListener::MOUSEDOWN_REASON
);
217 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
218 check
.Call("mouse down");
221 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
222 check
.Call("reflow");
225 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
228 mManager
.OnSelectionChanged(nullptr, nullptr,
229 nsISelectionListener::MOUSEUP_REASON
);
230 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
231 check
.Call("mouse up");
234 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
235 check
.Call("reflow2");
237 mManager
.OnScrollPositionChanged();
238 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
241 TEST_F(AccessibleCaretManagerTester
, TestSingleTapOnEmptyInput
)
242 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
243 // Set default preference.
244 AutoRestoreBoolPref
savedPref(
245 "layout.accessiblecaret.caret_shown_when_long_tapping_on_empty_content",
248 EXPECT_CALL(mManager
, GetCaretMode())
249 .WillRepeatedly(Return(CaretMode::Cursor
));
251 EXPECT_CALL(mManager
, HasNonEmptyTextContent(_
))
252 .WillRepeatedly(Return(false));
254 MockFunction
<void(std::string aCheckPointName
)> check
;
258 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
259 CaretChangedReason::Updateposition
))
261 EXPECT_CALL(check
, Call("update"));
263 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
264 CaretChangedReason::Visibilitychange
))
266 EXPECT_CALL(check
, Call("mouse down"));
268 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(_
)).Times(0);
269 EXPECT_CALL(check
, Call("reflow"));
271 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(_
)).Times(0);
272 EXPECT_CALL(check
, Call("blur"));
274 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
275 CaretChangedReason::Updateposition
))
277 EXPECT_CALL(check
, Call("mouse up"));
279 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
280 CaretChangedReason::Updateposition
))
282 EXPECT_CALL(check
, Call("reflow2"));
284 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
285 CaretChangedReason::Updateposition
))
289 // Simulate a single tap on an empty input.
290 mManager
.UpdateCarets();
291 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
292 check
.Call("update");
294 mManager
.OnSelectionChanged(nullptr, nullptr,
295 nsISelectionListener::DRAG_REASON
|
296 nsISelectionListener::MOUSEDOWN_REASON
);
297 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
298 check
.Call("mouse down");
301 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
302 check
.Call("reflow");
305 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
308 mManager
.OnSelectionChanged(nullptr, nullptr,
309 nsISelectionListener::MOUSEUP_REASON
);
310 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
311 check
.Call("mouse up");
314 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
315 check
.Call("reflow2");
317 mManager
.OnScrollPositionChanged();
318 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
321 TEST_F(AccessibleCaretManagerTester
, TestTypingAtEndOfInput
)
322 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
323 EXPECT_CALL(mManager
, GetCaretMode())
324 .WillRepeatedly(Return(CaretMode::Cursor
));
326 EXPECT_CALL(mManager
, HasNonEmptyTextContent(_
)).WillRepeatedly(Return(true));
328 MockFunction
<void(std::string aCheckPointName
)> check
;
332 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
333 CaretChangedReason::Updateposition
))
335 EXPECT_CALL(check
, Call("update"));
337 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
338 CaretChangedReason::Visibilitychange
))
340 EXPECT_CALL(check
, Call("keyboard"));
342 // No CaretStateChanged events should be dispatched since the caret has
343 // being hidden in cursor mode.
344 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(_
)).Times(0);
347 // Simulate typing the end of the input.
348 mManager
.UpdateCarets();
349 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
350 check
.Call("update");
352 mManager
.OnKeyboardEvent();
353 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
354 check
.Call("keyboard");
356 mManager
.OnSelectionChanged(nullptr, nullptr,
357 nsISelectionListener::NO_REASON
);
358 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
360 mManager
.OnScrollPositionChanged();
361 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
364 TEST_F(AccessibleCaretManagerTester
, TestScrollInSelectionMode
)
365 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
366 // Set default preference.
367 AutoRestoreBoolPref
savedPref("layout.accessiblecaret.always_tilt", false);
369 EXPECT_CALL(mManager
, GetCaretMode())
370 .WillRepeatedly(Return(CaretMode::Selection
));
372 MockFunction
<void(std::string aCheckPointName
)> check
;
376 // Initially, first caret is out of scrollport, and second caret is visible.
377 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
378 .WillOnce(Return(PositionChangedResult::Invisible
));
380 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
381 CaretChangedReason::Updateposition
));
382 EXPECT_CALL(check
, Call("updatecarets"));
384 EXPECT_CALL(mManager
,
385 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
386 EXPECT_CALL(check
, Call("scrollstart1"));
388 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
389 CaretChangedReason::Updateposition
));
390 EXPECT_CALL(check
, Call("reflow1"));
392 // After scroll ended, first caret is visible and second caret is out of
394 EXPECT_CALL(mManager
.SecondCaret(), SetPosition(_
, _
))
395 .WillOnce(Return(PositionChangedResult::Invisible
));
397 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
398 CaretChangedReason::Updateposition
));
399 EXPECT_CALL(check
, Call("scrollend1"));
401 EXPECT_CALL(mManager
,
402 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
403 EXPECT_CALL(check
, Call("scrollstart2"));
405 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
406 CaretChangedReason::Updateposition
));
407 EXPECT_CALL(check
, Call("reflow2"));
409 // After the scroll ended, both carets are visible.
410 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
411 CaretChangedReason::Updateposition
));
412 EXPECT_CALL(check
, Call("scrollend2"));
415 mManager
.UpdateCarets();
416 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
417 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal
);
418 check
.Call("updatecarets");
420 mManager
.OnScrollStart();
421 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
422 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal
);
423 check
.Call("scrollstart1");
426 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
427 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal
);
428 check
.Call("reflow1");
430 mManager
.OnScrollEnd();
431 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
432 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown
);
433 check
.Call("scrollend1");
435 mManager
.OnScrollStart();
436 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
437 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown
);
438 check
.Call("scrollstart2");
441 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
442 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown
);
443 check
.Call("reflow2");
445 mManager
.OnScrollEnd();
446 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
447 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal
);
448 check
.Call("scrollend2");
451 TEST_F(AccessibleCaretManagerTester
,
452 TestScrollInSelectionModeWithAlwaysTiltPref
)
453 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
454 // Simulate Firefox Android preference.
455 AutoRestoreBoolPref
savedPref("layout.accessiblecaret.always_tilt", true);
457 EXPECT_CALL(mManager
, GetCaretMode())
458 .WillRepeatedly(Return(CaretMode::Selection
));
460 MockFunction
<void(std::string aCheckPointName
)> check
;
464 // Initially, first caret is out of scrollport, and second caret is visible.
465 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
466 .WillOnce(Return(PositionChangedResult::Invisible
));
468 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
469 CaretChangedReason::Updateposition
));
470 EXPECT_CALL(check
, Call("updatecarets"));
472 EXPECT_CALL(mManager
,
473 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
474 EXPECT_CALL(check
, Call("scrollstart1"));
476 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(_
)).Times(0);
477 EXPECT_CALL(check
, Call("scrollPositionChanged1"));
479 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
480 CaretChangedReason::Updateposition
));
481 EXPECT_CALL(check
, Call("reflow1"));
483 // After scroll ended, first caret is visible and second caret is out of
485 EXPECT_CALL(mManager
.SecondCaret(), SetPosition(_
, _
))
486 .WillOnce(Return(PositionChangedResult::Invisible
));
488 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
489 CaretChangedReason::Updateposition
));
490 EXPECT_CALL(check
, Call("scrollend1"));
492 EXPECT_CALL(mManager
,
493 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
494 EXPECT_CALL(check
, Call("scrollstart2"));
496 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(_
)).Times(0);
497 EXPECT_CALL(check
, Call("scrollPositionChanged2"));
499 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
500 CaretChangedReason::Updateposition
));
501 EXPECT_CALL(check
, Call("reflow2"));
503 // After the scroll ended, both carets are visible.
504 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
505 CaretChangedReason::Updateposition
));
506 EXPECT_CALL(check
, Call("scrollend2"));
509 mManager
.UpdateCarets();
510 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
511 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right
);
512 check
.Call("updatecarets");
514 mManager
.OnScrollStart();
515 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
516 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right
);
517 check
.Call("scrollstart1");
519 mManager
.OnScrollPositionChanged();
520 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
521 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right
);
522 check
.Call("scrollPositionChanged1");
525 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
526 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right
);
527 check
.Call("reflow1");
529 mManager
.OnScrollEnd();
530 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left
);
531 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown
);
532 check
.Call("scrollend1");
534 mManager
.OnScrollStart();
535 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left
);
536 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown
);
537 check
.Call("scrollstart2");
539 mManager
.OnScrollPositionChanged();
540 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left
);
541 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown
);
542 check
.Call("scrollPositionChanged2");
545 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left
);
546 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown
);
547 check
.Call("reflow2");
549 mManager
.OnScrollEnd();
550 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left
);
551 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right
);
552 check
.Call("scrollend2");
555 TEST_F(AccessibleCaretManagerTester
, TestScrollInCursorModeWhenLogicallyVisible
)
556 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
557 EXPECT_CALL(mManager
, GetCaretMode())
558 .WillRepeatedly(Return(CaretMode::Cursor
));
560 EXPECT_CALL(mManager
, HasNonEmptyTextContent(_
)).WillRepeatedly(Return(true));
562 MockFunction
<void(std::string aCheckPointName
)> check
;
566 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
567 CaretChangedReason::Updateposition
))
569 EXPECT_CALL(check
, Call("updatecarets"));
571 EXPECT_CALL(mManager
,
572 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
))
574 EXPECT_CALL(check
, Call("scrollstart1"));
576 // After scroll ended, the caret is out of scroll port.
577 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
578 .WillRepeatedly(Return(PositionChangedResult::Invisible
));
579 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
580 CaretChangedReason::Updateposition
))
582 EXPECT_CALL(check
, Call("scrollend1"));
584 EXPECT_CALL(mManager
,
585 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
))
587 EXPECT_CALL(check
, Call("scrollstart2"));
589 // After scroll ended, the caret is visible again.
590 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
591 .WillRepeatedly(Return(PositionChangedResult::Position
));
592 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
593 CaretChangedReason::Updateposition
))
595 EXPECT_CALL(check
, Call("scrollend2"));
598 mManager
.UpdateCarets();
599 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
600 check
.Call("updatecarets");
602 mManager
.OnScrollStart();
603 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
604 check
.Call("scrollstart1");
606 mManager
.OnScrollEnd();
607 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
608 check
.Call("scrollend1");
610 mManager
.OnScrollStart();
611 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
612 check
.Call("scrollstart2");
614 mManager
.OnScrollEnd();
615 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
616 check
.Call("scrollend2");
619 TEST_F(AccessibleCaretManagerTester
, TestScrollInCursorModeWhenHidden
)
620 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
621 EXPECT_CALL(mManager
, GetCaretMode())
622 .WillRepeatedly(Return(CaretMode::Cursor
));
624 EXPECT_CALL(mManager
, HasNonEmptyTextContent(_
)).WillRepeatedly(Return(true));
626 MockFunction
<void(std::string aCheckPointName
)> check
;
630 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
631 CaretChangedReason::Updateposition
))
633 EXPECT_CALL(check
, Call("updatecarets"));
635 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
636 CaretChangedReason::Visibilitychange
))
638 EXPECT_CALL(check
, Call("hidecarets"));
640 // After scroll ended, the caret is out of scroll port.
641 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
642 .WillRepeatedly(Return(PositionChangedResult::Invisible
));
643 EXPECT_CALL(check
, Call("scrollend1"));
645 // After scroll ended, the caret is visible again.
646 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
647 .WillRepeatedly(Return(PositionChangedResult::Position
));
648 EXPECT_CALL(check
, Call("scrollend2"));
651 mManager
.UpdateCarets();
652 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
653 check
.Call("updatecarets");
655 mManager
.HideCaretsAndDispatchCaretStateChangedEvent();
656 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
657 check
.Call("hidecarets");
659 mManager
.OnScrollStart();
660 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
662 mManager
.OnScrollEnd();
663 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
664 check
.Call("scrollend1");
666 mManager
.OnScrollStart();
667 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
669 mManager
.OnScrollEnd();
670 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
671 check
.Call("scrollend2");
674 TEST_F(AccessibleCaretManagerTester
, TestScrollInCursorModeOnEmptyContent
)
675 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
676 // Set default preference.
677 AutoRestoreBoolPref
savedPref(
678 "layout.accessiblecaret.caret_shown_when_long_tapping_on_empty_content",
681 EXPECT_CALL(mManager
, GetCaretMode())
682 .WillRepeatedly(Return(CaretMode::Cursor
));
684 EXPECT_CALL(mManager
, HasNonEmptyTextContent(_
))
685 .WillRepeatedly(Return(false));
687 MockFunction
<void(std::string aCheckPointName
)> check
;
691 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
692 CaretChangedReason::Updateposition
));
693 EXPECT_CALL(check
, Call("updatecarets"));
695 EXPECT_CALL(mManager
,
696 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
697 EXPECT_CALL(check
, Call("scrollstart1"));
699 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
700 .WillOnce(Return(PositionChangedResult::Invisible
));
701 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
702 CaretChangedReason::Updateposition
));
703 EXPECT_CALL(check
, Call("scrollend1"));
705 EXPECT_CALL(mManager
,
706 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
707 EXPECT_CALL(check
, Call("scrollstart2"));
709 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
710 CaretChangedReason::Updateposition
));
711 EXPECT_CALL(check
, Call("scrollend2"));
713 EXPECT_CALL(mManager
,
714 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
715 EXPECT_CALL(check
, Call("scrollstart3"));
717 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
718 CaretChangedReason::Updateposition
));
719 EXPECT_CALL(check
, Call("scrollend3"));
722 // Simulate a pinch-zoom operation before tapping on an empty content.
723 mManager
.OnScrollStart();
724 mManager
.OnScrollEnd();
725 EXPECT_EQ(mManager
.IsScrollStarted(), false);
727 // Simulate a single tap on an empty content.
728 mManager
.UpdateCarets();
729 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
730 check
.Call("updatecarets");
732 // Scroll the caret to be out of the viewport.
733 mManager
.OnScrollStart();
734 check
.Call("scrollstart1");
735 mManager
.OnScrollEnd();
736 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
737 check
.Call("scrollend1");
739 // Scroll the caret into the viewport.
740 mManager
.OnScrollStart();
741 check
.Call("scrollstart2");
742 mManager
.OnScrollEnd();
743 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
744 check
.Call("scrollend2");
746 // Scroll the caret within the viewport.
747 mManager
.OnScrollStart();
748 check
.Call("scrollstart3");
749 mManager
.OnScrollEnd();
750 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
751 check
.Call("scrollend3");
754 TEST_F(AccessibleCaretManagerTester
,
755 TestScrollInCursorModeWithCaretShownWhenLongTappingOnEmptyContentPref
)
756 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION
{
757 // Simulate Firefox Android preference.
758 AutoRestoreBoolPref
savedPref(
759 "layout.accessiblecaret.caret_shown_when_long_tapping_on_empty_content",
762 EXPECT_CALL(mManager
, GetCaretMode())
763 .WillRepeatedly(Return(CaretMode::Cursor
));
765 EXPECT_CALL(mManager
, HasNonEmptyTextContent(_
))
766 .WillRepeatedly(Return(false));
768 MockFunction
<void(std::string aCheckPointName
)> check
;
772 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
773 CaretChangedReason::Updateposition
));
774 EXPECT_CALL(check
, Call("singletap updatecarets"));
776 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
777 CaretChangedReason::Updateposition
));
778 EXPECT_CALL(check
, Call("longtap updatecarets"));
780 EXPECT_CALL(mManager
,
781 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
782 EXPECT_CALL(check
, Call("longtap scrollstart1"));
784 EXPECT_CALL(mManager
.FirstCaret(), SetPosition(_
, _
))
785 .WillOnce(Return(PositionChangedResult::Invisible
));
786 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
787 CaretChangedReason::Updateposition
));
788 EXPECT_CALL(check
, Call("longtap scrollend1"));
790 EXPECT_CALL(mManager
,
791 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
792 EXPECT_CALL(check
, Call("longtap scrollstart2"));
794 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
795 CaretChangedReason::Updateposition
));
796 EXPECT_CALL(check
, Call("longtap scrollend2"));
798 EXPECT_CALL(mManager
,
799 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll
));
800 EXPECT_CALL(check
, Call("longtap scrollstart3"));
802 EXPECT_CALL(mManager
, DispatchCaretStateChangedEvent(
803 CaretChangedReason::Updateposition
));
804 EXPECT_CALL(check
, Call("longtap scrollend3"));
807 // Simulate a single tap on an empty input.
808 mManager
.FirstCaret().SetAppearance(Appearance::None
);
809 mManager
.UpdateCarets();
810 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
811 check
.Call("singletap updatecarets");
813 // Scroll the caret within the viewport.
814 mManager
.OnScrollStart();
815 mManager
.OnScrollEnd();
816 EXPECT_EQ(FirstCaretAppearance(), Appearance::None
);
818 // Simulate a long tap on an empty input.
819 mManager
.FirstCaret().SetAppearance(Appearance::Normal
);
820 mManager
.UpdateCarets();
821 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
822 check
.Call("longtap updatecarets");
824 // Scroll the caret to be out of the viewport.
825 mManager
.OnScrollStart();
826 check
.Call("longtap scrollstart1");
827 mManager
.OnScrollEnd();
828 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown
);
829 check
.Call("longtap scrollend1");
831 // Scroll the caret into the viewport.
832 mManager
.OnScrollStart();
833 check
.Call("longtap scrollstart2");
834 mManager
.OnScrollPositionChanged();
835 mManager
.OnScrollEnd();
836 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
837 check
.Call("longtap scrollend2");
839 // Scroll the caret within the viewport.
840 mManager
.OnScrollStart();
841 check
.Call("longtap scrollstart3");
842 mManager
.OnScrollPositionChanged();
843 mManager
.OnScrollEnd();
844 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal
);
845 check
.Call("longtap scrollend3");
848 } // namespace mozilla