| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 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 "core/editing/spellcheck/IdleSpellCheckCallback.h" |
| 6 |
| 7 #include "core/dom/IdleRequestOptions.h" |
| 8 #include "core/editing/EditingUtilities.h" |
| 9 #include "core/editing/FrameSelection.h" |
| 10 #include "core/editing/VisibleSelection.h" |
| 11 #include "core/editing/VisibleUnits.h" |
| 12 #include "core/editing/commands/CompositeEditCommand.h" |
| 13 #include "core/editing/commands/UndoStep.h" |
| 14 #include "core/editing/iterators/BackwardsCharacterIterator.h" |
| 15 #include "core/editing/iterators/CharacterIterator.h" |
| 16 #include "core/editing/spellcheck/SpellCheckRequester.h" |
| 17 #include "core/editing/spellcheck/SpellChecker.h" |
| 18 #include "core/frame/FrameView.h" |
| 19 #include "core/frame/LocalFrame.h" |
| 20 #include "core/html/TextControlElement.h" |
| 21 #include "core/layout/LayoutObject.h" |
| 22 #include "platform/RuntimeEnabledFeatures.h" |
| 23 #include "platform/tracing/TraceEvent.h" |
| 24 #include "wtf/CurrentTime.h" |
| 25 |
| 26 namespace blink { |
| 27 |
| 28 namespace { |
| 29 |
| 30 const int kColdModeTimerIntervalMS = 1000; |
| 31 const int kConsecutiveColdModeTimerIntervalMS = 200; |
| 32 const int kRequestTimeoutMS = 200; |
| 33 |
| 34 } // namespace |
| 35 |
| 36 IdleSpellCheckCallback::~IdleSpellCheckCallback() {} |
| 37 |
| 38 DEFINE_TRACE(IdleSpellCheckCallback) { |
| 39 visitor->trace(m_frame); |
| 40 IdleRequestCallback::trace(visitor); |
| 41 } |
| 42 |
| 43 IdleSpellCheckCallback* IdleSpellCheckCallback::create(LocalFrame& frame) { |
| 44 return new IdleSpellCheckCallback(frame); |
| 45 } |
| 46 |
| 47 IdleSpellCheckCallback::IdleSpellCheckCallback(LocalFrame& frame) |
| 48 : m_state(State::Inactive), |
| 49 m_frame(frame), |
| 50 m_coldModeTimer(this, &IdleSpellCheckCallback::coldModeTimerFired) {} |
| 51 |
| 52 bool IdleSpellCheckCallback::isSpellCheckingEnabled() const { |
| 53 // TODO(xiaochengh): decouple with SpellChecker. |
| 54 return frame().spellChecker().isSpellCheckingEnabled(); |
| 55 } |
| 56 |
| 57 void IdleSpellCheckCallback::requestInvocation() { |
| 58 IdleRequestOptions options; |
| 59 options.setTimeout(kRequestTimeoutMS); |
| 60 frame().document()->requestIdleCallback(this, options); |
| 61 } |
| 62 |
| 63 void IdleSpellCheckCallback::deactivate() { |
| 64 m_state = State::Inactive; |
| 65 if (m_coldModeTimer.isActive()) |
| 66 m_coldModeTimer.stop(); |
| 67 } |
| 68 |
| 69 void IdleSpellCheckCallback::setNeedsHotModeInvocation() { |
| 70 if (!RuntimeEnabledFeatures::idleTimeSpellCheckingEnabled()) |
| 71 return; |
| 72 |
| 73 if (!isSpellCheckingEnabled()) { |
| 74 deactivate(); |
| 75 return; |
| 76 } |
| 77 |
| 78 if (m_state == State::ColdModeTimerStarted) { |
| 79 DCHECK(m_coldModeTimer.isActive()); |
| 80 m_coldModeTimer.stop(); |
| 81 } |
| 82 |
| 83 if (m_state != State::ColdModeRequested) |
| 84 requestInvocation(); |
| 85 m_state = State::HotModeRequested; |
| 86 } |
| 87 |
| 88 void IdleSpellCheckCallback::setNeedsColdModeInvocation() { |
| 89 if (!RuntimeEnabledFeatures::idleTimeSpellCheckingEnabled()) |
| 90 return; |
| 91 |
| 92 if (!isSpellCheckingEnabled()) { |
| 93 deactivate(); |
| 94 return; |
| 95 } |
| 96 |
| 97 if (m_state != State::Inactive && m_state != State::InHotModeInvocation && |
| 98 m_state != State::InColdModeInvocation) |
| 99 return; |
| 100 |
| 101 DCHECK(!m_coldModeTimer.isActive()); |
| 102 int intervalMS = m_state == State::InColdModeInvocation |
| 103 ? kConsecutiveColdModeTimerIntervalMS |
| 104 : kColdModeTimerIntervalMS; |
| 105 m_coldModeTimer.startOneShot(intervalMS / 1000.0, BLINK_FROM_HERE); |
| 106 m_state = State::ColdModeTimerStarted; |
| 107 } |
| 108 |
| 109 void IdleSpellCheckCallback::coldModeTimerFired(TimerBase*) { |
| 110 DCHECK_EQ(State::ColdModeTimerStarted, m_state); |
| 111 |
| 112 if (!isSpellCheckingEnabled()) { |
| 113 deactivate(); |
| 114 return; |
| 115 } |
| 116 |
| 117 requestInvocation(); |
| 118 m_state = State::ColdModeRequested; |
| 119 } |
| 120 |
| 121 void IdleSpellCheckCallback::hotModeInvocation(IdleDeadline* deadline) { |
| 122 // TODO(xiaochengh): Implementation. |
| 123 } |
| 124 |
| 125 void IdleSpellCheckCallback::coldModeInvocation(IdleDeadline* deadline) { |
| 126 // TODO(xiaochengh): Implementation. |
| 127 } |
| 128 |
| 129 bool IdleSpellCheckCallback::coldModeFinishesFullDocument() const { |
| 130 // TODO(xiaochengh): Implementation. |
| 131 return true; |
| 132 } |
| 133 |
| 134 void IdleSpellCheckCallback::handleEvent(IdleDeadline* deadline) { |
| 135 DCHECK(frame().document()); |
| 136 DCHECK(frame().document()->isActive()); |
| 137 |
| 138 if (!isSpellCheckingEnabled()) { |
| 139 deactivate(); |
| 140 return; |
| 141 } |
| 142 |
| 143 if (m_state == State::HotModeRequested) { |
| 144 m_state = State::InHotModeInvocation; |
| 145 hotModeInvocation(deadline); |
| 146 setNeedsColdModeInvocation(); |
| 147 } else if (m_state == State::ColdModeRequested) { |
| 148 m_state = State::InColdModeInvocation; |
| 149 coldModeInvocation(deadline); |
| 150 if (coldModeFinishesFullDocument()) |
| 151 m_state = State::Inactive; |
| 152 else |
| 153 setNeedsColdModeInvocation(); |
| 154 } else { |
| 155 NOTREACHED(); |
| 156 } |
| 157 } |
| 158 |
| 159 } // namespace blink |
| OLD | NEW |