Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(365)

Unified Diff: third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.cpp

Issue 2734013002: Implement cold mode invocation for idle time spell checker (Closed)
Patch Set: rebased Mar 7 Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 6a212b735493137b871943b3c13a82d2c876ee5f..dc8def1b5e6fb6ce551a337b98ed37b4ad57290d 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 kHotModeRequestTimeoutMS = 200;
@@ -32,12 +34,22 @@ const int kInvalidHandle = -1;
const int kDummyHandleForForcedInvocation = -2;
const double kForcedInvocationDeadlineSeconds = 10;
+bool shouldCheckNodeInColdMode(Node& node) {
+ if (!node.isElementNode())
+ return false;
+ const Position& position = Position::firstPositionInNode(&node);
+ if (!isEditablePosition(position))
+ return false;
+ return SpellChecker::isSpellCheckingEnabledAt(position);
+}
+
} // namespace
IdleSpellCheckCallback::~IdleSpellCheckCallback() {}
DEFINE_TRACE(IdleSpellCheckCallback) {
visitor->trace(m_frame);
+ visitor->trace(m_nextNodeInColdMode);
IdleRequestCallback::trace(visitor);
SynchronousMutationObserver::trace(visitor);
}
@@ -52,6 +64,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) {}
@@ -151,8 +164,76 @@ void IdleSpellCheckCallback::hotModeInvocation(IdleDeadline* deadline) {
}
}
+// TODO(xiaochengh): Deduplicate with SpellChecker::chunkAndMarkAllMisspellings.
+void IdleSpellCheckCallback::chunkAndRequestFullCheckingFor(
+ const Element& editable) {
+ const EphemeralRange& fullRange = EphemeralRange::rangeOfContents(editable);
+ const int fullLength = TextIterator::rangeLength(fullRange.startPosition(),
+ 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();
+ const int chunkLimit = fullLength / kColdModeChunkSize + 1;
+ for (int chunkIndex = 0; chunkIndex <= chunkLimit; ++chunkIndex) {
+ const Position& chunkEnd =
+ calculateCharacterSubrange(
+ EphemeralRange(chunkStart, fullRange.endPosition()), 0,
+ kColdModeChunkSize)
+ .endPosition();
+ if (chunkEnd <= chunkStart)
+ break;
+ const EphemeralRange chunkRange(chunkStart, chunkEnd);
+ const EphemeralRange& checkRange =
+ chunkIndex >= 1 ? expandEndToSentenceBoundary(chunkRange)
+ : expandRangeToSentenceBoundary(chunkRange);
+
+ SpellCheckRequest* chunkRequest =
+ SpellCheckRequest::create(checkRange, chunkIndex);
+ spellCheckRequester().requestCheckingFor(chunkRequest);
+
+ chunkStart = checkRange.endPosition();
+ }
+}
+
void IdleSpellCheckCallback::coldModeInvocation(IdleDeadline* deadline) {
- // TODO(xiaochengh): Implementation.
+ TRACE_EVENT0("blink", "IdleSpellCheckCallback::coldModeInvocation");
+
+ Node* body = frame().document()->body();
+ if (!body) {
+ m_nextNodeInColdMode = nullptr;
+ m_lastCheckedDOMTreeVersionInColdMode =
+ frame().document()->domTreeVersion();
+ return;
+ }
+
+ // TODO(xiaochengh): Figure out if this has any performance impact.
+ frame().document()->updateStyleAndLayout();
+
+ if (m_lastCheckedDOMTreeVersionInColdMode !=
+ frame().document()->domTreeVersion())
+ m_nextNodeInColdMode = body;
+
+ while (m_nextNodeInColdMode && deadline->timeRemaining() > 0) {
+ if (!shouldCheckNodeInColdMode(*m_nextNodeInColdMode)) {
+ m_nextNodeInColdMode =
+ FlatTreeTraversal::next(*m_nextNodeInColdMode, body);
+ continue;
+ }
+
+ chunkAndRequestFullCheckingFor(toElement(*m_nextNodeInColdMode));
+ m_nextNodeInColdMode =
+ FlatTreeTraversal::nextSkippingChildren(*m_nextNodeInColdMode, body);
+ }
+
+ m_lastCheckedDOMTreeVersionInColdMode = frame().document()->domTreeVersion();
}
bool IdleSpellCheckCallback::coldModeFinishesFullDocument() const {
@@ -161,8 +242,7 @@ bool IdleSpellCheckCallback::coldModeFinishesFullDocument() const {
return false;
}
- // TODO(xiaochengh): Implementation.
- return true;
+ return !m_nextNodeInColdMode;
}
void IdleSpellCheckCallback::handleEvent(IdleDeadline* deadline) {
« no previous file with comments | « third_party/WebKit/Source/core/editing/spellcheck/IdleSpellCheckCallback.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698