1 // Copyright 2017 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "third_party/blink/renderer/core/editing/frame_caret.h" 6 7 #include "third_party/blink/renderer/core/editing/commands/typing_command.h" 8 #include "third_party/blink/renderer/core/editing/frame_selection.h" 9 #include "third_party/blink/renderer/core/editing/selection_template.h" 10 #include "third_party/blink/renderer/core/editing/testing/editing_test_base.h" 11 #include "third_party/blink/renderer/core/frame/local_frame_view.h" 12 #include "third_party/blink/renderer/core/frame/settings.h" 13 #include "third_party/blink/renderer/core/layout/layout_theme.h" 14 #include "third_party/blink/renderer/core/page/focus_controller.h" 15 #include "third_party/blink/renderer/platform/scheduler/test/fake_task_runner.h" 16 #include "third_party/blink/renderer/platform/web_test_support.h" 17 18 namespace blink { 19 20 class FrameCaretTest : public EditingTestBase { 21 public: FrameCaretTest()22 FrameCaretTest() : was_running_web_test_(WebTestSupport::IsRunningWebTest()) { 23 // The caret blink timer doesn't work if IsRunningWebTest() because 24 // LayoutTheme::CaretBlinkInterval() returns 0. 25 WebTestSupport::SetIsRunningWebTest(false); 26 } ~FrameCaretTest()27 ~FrameCaretTest() override { 28 WebTestSupport::SetIsRunningWebTest(was_running_web_test_); 29 } 30 ShouldBlinkCaret(const FrameCaret & caret)31 static bool ShouldBlinkCaret(const FrameCaret& caret) { 32 return caret.ShouldBlinkCaret(); 33 } 34 35 private: 36 const bool was_running_web_test_; 37 }; 38 TEST_F(FrameCaretTest,BlinkAfterTyping)39TEST_F(FrameCaretTest, BlinkAfterTyping) { 40 FrameCaret& caret = Selection().FrameCaretForTesting(); 41 scoped_refptr<scheduler::FakeTaskRunner> task_runner = 42 base::MakeRefCounted<scheduler::FakeTaskRunner>(); 43 task_runner->SetTime(0); 44 caret.RecreateCaretBlinkTimerForTesting(task_runner.get()); 45 const double kInterval = 10; 46 LayoutTheme::GetTheme().SetCaretBlinkInterval( 47 base::TimeDelta::FromSecondsD(kInterval)); 48 GetDocument().GetPage()->GetFocusController().SetActive(true); 49 GetDocument().GetPage()->GetFocusController().SetFocused(true); 50 GetDocument().body()->setInnerHTML("<textarea>"); 51 auto* editor = To<Element>(GetDocument().body()->firstChild()); 52 editor->focus(); 53 UpdateAllLifecyclePhasesForTest(); 54 55 EXPECT_TRUE(caret.IsActive()); 56 EXPECT_FALSE(caret.ShouldShowBlockCursor()); 57 EXPECT_TRUE(caret.ShouldPaintCaretForTesting()) 58 << "Initially a caret should be in visible cycle."; 59 60 task_runner->AdvanceTimeAndRun(kInterval); 61 EXPECT_FALSE(caret.ShouldPaintCaretForTesting()) 62 << "The caret blinks normally."; 63 64 TypingCommand::InsertLineBreak(GetDocument()); 65 UpdateAllLifecyclePhasesForTest(); 66 EXPECT_TRUE(caret.ShouldPaintCaretForTesting()) 67 << "The caret should be in visible cycle just after a typing command."; 68 69 task_runner->AdvanceTimeAndRun(kInterval - 1); 70 UpdateAllLifecyclePhasesForTest(); 71 EXPECT_TRUE(caret.ShouldPaintCaretForTesting()) 72 << "The typing command reset the timer. The caret is still visible."; 73 74 task_runner->AdvanceTimeAndRun(1); 75 UpdateAllLifecyclePhasesForTest(); 76 EXPECT_FALSE(caret.ShouldPaintCaretForTesting()) 77 << "The caret should blink after the typing command."; 78 } 79 TEST_F(FrameCaretTest,ShouldNotBlinkWhenSelectionLooseFocus)80TEST_F(FrameCaretTest, ShouldNotBlinkWhenSelectionLooseFocus) { 81 FrameCaret& caret = Selection().FrameCaretForTesting(); 82 GetDocument().GetPage()->GetFocusController().SetActive(true); 83 GetDocument().GetPage()->GetFocusController().SetFocused(true); 84 GetDocument().body()->setInnerHTML( 85 "<div id='outer' tabindex='-1'>" 86 "<div id='input' contenteditable>foo</div>" 87 "</div>"); 88 Element* input = GetDocument().QuerySelector("#input"); 89 input->focus(); 90 Element* outer = GetDocument().QuerySelector("#outer"); 91 outer->focus(); 92 UpdateAllLifecyclePhasesForTest(); 93 const SelectionInDOMTree& selection = Selection().GetSelectionInDOMTree(); 94 EXPECT_EQ(selection.Base(), 95 Position(input, PositionAnchorType::kBeforeChildren)); 96 EXPECT_FALSE(ShouldBlinkCaret(caret)); 97 } 98 TEST_F(FrameCaretTest,ShouldBlinkCaretWhileCaretBrowsing)99TEST_F(FrameCaretTest, ShouldBlinkCaretWhileCaretBrowsing) { 100 FrameCaret& caret = Selection().FrameCaretForTesting(); 101 Selection().SetSelection(SetSelectionTextToBody("<div>a|b</div>"), 102 SetSelectionOptions()); 103 Selection().SetCaretVisible(true); 104 EXPECT_FALSE(ShouldBlinkCaret(caret)); 105 GetDocument().GetFrame()->GetSettings()->SetCaretBrowsingEnabled(true); 106 EXPECT_TRUE(ShouldBlinkCaret(caret)); 107 } 108 109 } // namespace blink 110