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 2c400a479fa4ad213609139d7e6f4af24c4694fb..a4ed8e2ffe51dd20e3f27f9053ccb00171bd6dc5 100644 |
| --- a/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp |
| +++ b/third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp |
| @@ -13,6 +13,7 @@ |
| #include "core/editing/VisibleUnits.h" |
| #include "core/editing/commands/UndoStack.h" |
| #include "core/editing/commands/UndoStep.h" |
| +#include "core/editing/iterators/CharacterIterator.h" |
| #include "core/editing/spellcheck/HotModeSpellCheckRequester.h" |
| #include "core/editing/spellcheck/SpellCheckRequester.h" |
| #include "core/editing/spellcheck/SpellChecker.h" |
| @@ -25,6 +26,7 @@ namespace blink { |
| namespace { |
| +const int kColdModeChunkSize = 16384; |
| const int kColdModeTimerIntervalMS = 1000; |
| const int kConsecutiveColdModeTimerIntervalMS = 200; |
| const int kRequestTimeoutMS = 200; |
| @@ -38,6 +40,7 @@ IdleSpellCheckCallback::~IdleSpellCheckCallback() {} |
| DEFINE_TRACE(IdleSpellCheckCallback) { |
| visitor->trace(m_frame); |
| + visitor->trace(m_nextNodeInColdMode); |
| IdleRequestCallback::trace(visitor); |
| SynchronousMutationObserver::trace(visitor); |
| } |
| @@ -52,6 +55,7 @@ IdleSpellCheckCallback::IdleSpellCheckCallback(LocalFrame& frame) |
| m_needsMoreColdModeInvocationForTesting(false), |
| m_frame(frame), |
| m_lastProcessedUndoStepSequence(0), |
| + m_lastCheckedDOMTreeVersionInColdMode(0), |
| m_coldModeTimer(TaskRunnerHelper::get(TaskType::UnspecedTimer, &frame), |
| this, |
| &IdleSpellCheckCallback::coldModeTimerFired) {} |
| @@ -152,8 +156,71 @@ void IdleSpellCheckCallback::hotModeInvocation(IdleDeadline* deadline) { |
| } |
| } |
| +// TODO(xiaochengh): Deduplicate with SpellChecker::chunkAndMarkAllMisspellings. |
| +void IdleSpellCheckCallback::chunkAndRequestFullCheckingFor( |
| + const Element& editable) { |
| + const EphemeralRange& fullRange = EphemeralRange::rangeOfContents(editable); |
| + int fullLength = TextIterator::rangeLength(fullRange.startPosition(), |
|
yosin_UTC9
2017/03/07 01:47:03
nit: s/int/const int/
Xiaocheng
2017/03/07 04:20:30
Done.
|
| + fullRange.endPosition()); |
| + |
| + // Check the full content if it is short. |
| + if (fullLength <= kColdModeChunkSize) { |
| + SpellCheckRequest* fullRequest = SpellCheckRequest::create(fullRange); |
| + spellCheckRequester().requestCheckingFor(fullRequest); |
| + return; |
| + } |
| + |
| + // TODO(xiaochengh): Figure out if this is going to cause performance issues. |
| + // In that case, we need finer-grained control over request generation. |
| + Position chunkStart = fullRange.startPosition(); |
| + int chunkLimit = fullLength / kColdModeChunkSize + 1; |
|
yosin_UTC9
2017/03/07 01:47:03
nit: s/int/const int/
Xiaocheng
2017/03/07 04:20:30
Done.
|
| + for (int requestNum = 0; requestNum <= chunkLimit; ++requestNum) { |
|
yosin_UTC9
2017/03/07 01:47:03
nit: s/requestNum/chunkNumber/
or
nit: s/requestNu
Xiaocheng
2017/03/07 04:20:30
Done.
|
| + Position chunkEnd = calculateCharacterSubrange( |
|
yosin_UTC9
2017/03/07 01:47:03
nit: s/Position/const Position/
Xiaocheng
2017/03/07 04:20:29
Done.
|
| + EphemeralRange(chunkStart, fullRange.endPosition()), |
| + 0, kColdModeChunkSize) |
| + .endPosition(); |
| + if (chunkEnd <= chunkStart) |
| + break; |
| + EphemeralRange chunkRange(chunkStart, chunkEnd); |
|
yosin_UTC9
2017/03/07 01:47:03
nit: s/EphemeralRange/const EphmeralRange/
Xiaocheng
2017/03/07 04:20:30
Done.
|
| + EphemeralRange checkRange = requestNum |
|
yosin_UTC9
2017/03/07 01:47:03
nit: s/EphmeralRange/const EphemeralRange&/ to avo
Xiaocheng
2017/03/07 04:20:30
Done.
|
| + ? expandEndToSentenceBoundary(chunkRange) |
| + : expandRangeToSentenceBoundary(chunkRange); |
| + |
| + SpellCheckRequest* chunkRequest = |
| + SpellCheckRequest::create(checkRange, requestNum); |
| + spellCheckRequester().requestCheckingFor(chunkRequest); |
| + |
| + chunkStart = checkRange.endPosition(); |
| + } |
| +} |
| + |
| void IdleSpellCheckCallback::coldModeInvocation(IdleDeadline* deadline) { |
| - // TODO(xiaochengh): Implementation. |
| + TRACE_EVENT0("blink", "IdleSpellCheckCallback::coldModeInvocation"); |
| + |
| + // TODO(xiaochengh): Figure out if this has any performance impact. |
| + frame().document()->updateStyleAndLayout(); |
| + |
| + Node* body = frame().document()->body(); |
|
yosin_UTC9
2017/03/07 01:47:03
|body| can be null, e.g. no BODY element.
We may w
Xiaocheng
2017/03/07 04:20:30
Done.
|
| + if (m_lastCheckedDOMTreeVersionInColdMode != |
| + frame().document()->domTreeVersion()) |
| + m_nextNodeInColdMode = body; |
| + |
| + while (m_nextNodeInColdMode && deadline->timeRemaining() > 0) { |
| + const Position& refPosition = |
| + Position::firstPositionInNode(m_nextNodeInColdMode); |
| + if (m_nextNodeInColdMode->isElementNode() && |
| + isEditablePosition(refPosition) && |
| + SpellChecker::isSpellCheckingEnabledAt(refPosition)) { |
| + chunkAndRequestFullCheckingFor(toElement(*m_nextNodeInColdMode)); |
| + m_nextNodeInColdMode = |
| + FlatTreeTraversal::nextSkippingChildren(*m_nextNodeInColdMode, body); |
| + } else { |
|
yosin_UTC9
2017/03/07 01:47:03
Prefer early-continue style to shallow indentation
Xiaocheng
2017/03/07 04:20:29
Done by introducing |shouldCheckNodeInColdMode()|
|
| + m_nextNodeInColdMode = |
| + FlatTreeTraversal::next(*m_nextNodeInColdMode, body); |
| + } |
| + } |
| + |
| + m_lastCheckedDOMTreeVersionInColdMode = frame().document()->domTreeVersion(); |
| } |
| bool IdleSpellCheckCallback::coldModeFinishesFullDocument() const { |
| @@ -162,8 +229,7 @@ bool IdleSpellCheckCallback::coldModeFinishesFullDocument() const { |
| return false; |
| } |
| - // TODO(xiaochengh): Implementation. |
| - return true; |
| + return !m_nextNodeInColdMode; |
| } |
| void IdleSpellCheckCallback::handleEvent(IdleDeadline* deadline) { |