Chromium Code Reviews| Index: third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp |
| diff --git a/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp b/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp |
| index cfdac39e20df07ff345af77fa7bca31e3b0871a5..a182bc3b786a178c1f10d6f817c4bb410cccd13e 100644 |
| --- a/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp |
| +++ b/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp |
| @@ -31,6 +31,9 @@ namespace { |
| const int kColdModeTimerIntervalMS = 1000; |
| const int kConsecutiveColdModeTimerIntervalMS = 200; |
| const int kRequestTimeoutMS = 200; |
| +const int kInvalidHandle = -1; |
| +const int kDummyHandleForForcedInvocation = -2; |
| +const double kForcedInvocationDeadlineSeconds = 10; |
| } // namespace |
| @@ -39,6 +42,7 @@ IdleSpellCheckCallback::~IdleSpellCheckCallback() {} |
| DEFINE_TRACE(IdleSpellCheckCallback) { |
| visitor->trace(m_frame); |
| IdleRequestCallback::trace(visitor); |
| + SynchronousMutationObserver::trace(visitor); |
| } |
| IdleSpellCheckCallback* IdleSpellCheckCallback::create(LocalFrame& frame) { |
| @@ -47,6 +51,8 @@ IdleSpellCheckCallback* IdleSpellCheckCallback::create(LocalFrame& frame) { |
| IdleSpellCheckCallback::IdleSpellCheckCallback(LocalFrame& frame) |
| : m_state(State::kInactive), |
| + m_idleCallbackHandle(kInvalidHandle), |
| + m_needsMoreColdModeInvocationForTesting(false), |
| m_frame(frame), |
| m_coldModeTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame), |
| this, |
| @@ -61,26 +67,31 @@ bool IdleSpellCheckCallback::isSpellCheckingEnabled() const { |
| } |
| void IdleSpellCheckCallback::requestInvocation() { |
| + DCHECK_EQ(m_idleCallbackHandle, kInvalidHandle); |
| + |
| IdleRequestOptions options; |
| options.setTimeout(kRequestTimeoutMS); |
| - frame().document()->requestIdleCallback(this, options); |
| + m_idleCallbackHandle = frame().document()->requestIdleCallback(this, options); |
| } |
| void IdleSpellCheckCallback::deactivate() { |
| m_state = State::kInactive; |
| if (m_coldModeTimer.isActive()) |
| m_coldModeTimer.stop(); |
| + if (m_idleCallbackHandle != kInvalidHandle) |
| + frame().document()->cancelIdleCallback(m_idleCallbackHandle); |
| + m_idleCallbackHandle = kInvalidHandle; |
| } |
| -void IdleSpellCheckCallback::setNeedsHotModeInvocation() { |
| - if (!RuntimeEnabledFeatures::idleTimeSpellCheckingEnabled()) |
| - return; |
| - |
| +void IdleSpellCheckCallback::setNeedsInvocation() { |
| if (!isSpellCheckingEnabled()) { |
| deactivate(); |
| return; |
| } |
| + if (m_state == State::kHotModeRequested) |
| + return; |
| + |
| if (m_state == State::kColdModeTimerStarted) { |
| DCHECK(m_coldModeTimer.isActive()); |
| m_coldModeTimer.stop(); |
| @@ -92,9 +103,6 @@ void IdleSpellCheckCallback::setNeedsHotModeInvocation() { |
| } |
| void IdleSpellCheckCallback::setNeedsColdModeInvocation() { |
| - if (!RuntimeEnabledFeatures::idleTimeSpellCheckingEnabled()) |
| - return; |
| - |
| if (!isSpellCheckingEnabled()) { |
| deactivate(); |
| return; |
| @@ -133,6 +141,11 @@ void IdleSpellCheckCallback::coldModeInvocation(IdleDeadline* deadline) { |
| } |
| bool IdleSpellCheckCallback::coldModeFinishesFullDocument() const { |
| + if (m_needsMoreColdModeInvocationForTesting) { |
| + m_needsMoreColdModeInvocationForTesting = false; |
| + return false; |
| + } |
| + |
| // TODO(xiaochengh): Implementation. |
| return true; |
| } |
| @@ -140,6 +153,8 @@ bool IdleSpellCheckCallback::coldModeFinishesFullDocument() const { |
| void IdleSpellCheckCallback::handleEvent(IdleDeadline* deadline) { |
| DCHECK(frame().document()); |
| DCHECK(frame().document()->isActive()); |
| + DCHECK_NE(m_idleCallbackHandle, kInvalidHandle); |
| + m_idleCallbackHandle = kInvalidHandle; |
| if (!isSpellCheckingEnabled()) { |
| deactivate(); |
| @@ -162,4 +177,44 @@ void IdleSpellCheckCallback::handleEvent(IdleDeadline* deadline) { |
| } |
| } |
| +void IdleSpellCheckCallback::documentAttached(Document* document) { |
| + setNeedsColdModeInvocation(); |
| + setContext(document); |
| +} |
| + |
| +void IdleSpellCheckCallback::contextDestroyed(Document*) { |
| + deactivate(); |
| +} |
| + |
| +void IdleSpellCheckCallback::forceInvocationForTesting() { |
| + if (!isSpellCheckingEnabled()) |
| + return; |
| + |
| + IdleDeadline* deadline = |
| + IdleDeadline::create(kForcedInvocationDeadlineSeconds, |
| + IdleDeadline::CallbackType::CalledWhenIdle); |
| + |
| + switch (m_state) { |
| + case State::kColdModeTimerStarted: |
| + m_coldModeTimer.stop(); |
| + m_state = State::kColdModeRequested; |
| + m_idleCallbackHandle = kDummyHandleForForcedInvocation; |
| + handleEvent(deadline); |
| + break; |
| + case State::kHotModeRequested: |
| + case State::kColdModeRequested: |
| + frame().document()->cancelIdleCallback(m_idleCallbackHandle); |
| + handleEvent(deadline); |
| + break; |
| + default: |
|
tkent
2017/02/26 20:35:58
Do not use |default:| in |switch| for an enum. Pl
Xiaocheng
2017/02/27 04:07:18
Done
|
| + NOTREACHED(); |
| + } |
| +} |
| + |
| +void IdleSpellCheckCallback::skipColdModeTimerForTesting() { |
| + DCHECK(m_coldModeTimer.isActive()); |
| + m_coldModeTimer.stop(); |
| + coldModeTimerFired(&m_coldModeTimer); |
| +} |
| + |
| } // namespace blink |