[BlackBerry] Optimize spellchecking by coalescing messages
authornghanavatian@rim.com <nghanavatian@rim.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jan 2013 19:48:17 +0000 (19:48 +0000)
committernghanavatian@rim.com <nghanavatian@rim.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 23 Jan 2013 19:48:17 +0000 (19:48 +0000)
https://bugs.webkit.org/show_bug.cgi?id=107707

Reviewed by Rob Buis.

PR233604
Instead of taking chunks one line at a time, coalesce them together
to fire off messages as close to our character limit as possible.
This should dramatically reduce the total number of messages in email
giving us a little performance bump.

Internally reviewed by Mike Fenton and Gen Mak.

* WebKitSupport/DOMSupport.cpp:
(BlackBerry::WebKit::DOMSupport::trimWhitespaceFromRange):
(DOMSupport):
* WebKitSupport/DOMSupport.h:
* WebKitSupport/InputHandler.cpp:
* WebKitSupport/InputHandler.h:
(InputHandler):
* WebKitSupport/SpellingHandler.cpp:
(BlackBerry::WebKit::SpellingHandler::spellCheckTextBlock):
(BlackBerry::WebKit::SpellingHandler::createSpellCheckRequest):
(BlackBerry::WebKit::SpellingHandler::parseBlockForSpellChecking):
(BlackBerry::WebKit::SpellingHandler::getRangeForSpellCheckWithFineGranularity):
* WebKitSupport/SpellingHandler.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@140562 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/blackberry/ChangeLog
Source/WebKit/blackberry/WebKitSupport/DOMSupport.cpp
Source/WebKit/blackberry/WebKitSupport/DOMSupport.h
Source/WebKit/blackberry/WebKitSupport/InputHandler.cpp
Source/WebKit/blackberry/WebKitSupport/InputHandler.h
Source/WebKit/blackberry/WebKitSupport/SpellingHandler.cpp
Source/WebKit/blackberry/WebKitSupport/SpellingHandler.h

index 002edd52adb565a2fd7cf9397b1ca12f0e7a9c1c..903c2a57713f6f30dc8f2a152fd0cda7d528c7ab 100644 (file)
@@ -1,3 +1,32 @@
+2013-01-23  Nima Ghanavatian  <nghanavatian@rim.com>
+
+        [BlackBerry] Optimize spellchecking by coalescing messages
+        https://bugs.webkit.org/show_bug.cgi?id=107707
+
+        Reviewed by Rob Buis.
+
+        PR233604
+        Instead of taking chunks one line at a time, coalesce them together
+        to fire off messages as close to our character limit as possible.
+        This should dramatically reduce the total number of messages in email
+        giving us a little performance bump.
+
+        Internally reviewed by Mike Fenton and Gen Mak.
+
+        * WebKitSupport/DOMSupport.cpp:
+        (BlackBerry::WebKit::DOMSupport::trimWhitespaceFromRange):
+        (DOMSupport):
+        * WebKitSupport/DOMSupport.h:
+        * WebKitSupport/InputHandler.cpp:
+        * WebKitSupport/InputHandler.h:
+        (InputHandler):
+        * WebKitSupport/SpellingHandler.cpp:
+        (BlackBerry::WebKit::SpellingHandler::spellCheckTextBlock):
+        (BlackBerry::WebKit::SpellingHandler::createSpellCheckRequest):
+        (BlackBerry::WebKit::SpellingHandler::parseBlockForSpellChecking):
+        (BlackBerry::WebKit::SpellingHandler::getRangeForSpellCheckWithFineGranularity):
+        * WebKitSupport/SpellingHandler.h:
+
 2013-01-23  Shinya Kawanaka  <shinyak@chromium.org>
 
         shadowAncestorNode() should be renamed to deprecatedShadowAncestorNode()
index 2e3224534a36d59020152a6f3e3aa01e0a4b6dc0..da1c4ac59005db165c7f096df0939f76da339d61 100644 (file)
@@ -516,6 +516,11 @@ Frame* incrementFrame(Frame* curr, bool forward, bool wrapFlag)
         : curr->tree()->traversePreviousWithWrap(wrapFlag);
 }
 
+PassRefPtr<Range> trimWhitespaceFromRange(PassRefPtr<Range> range)
+{
+    return trimWhitespaceFromRange(VisiblePosition(range->startPosition()), VisiblePosition(range->endPosition()));
+}
+
 PassRefPtr<Range> trimWhitespaceFromRange(VisiblePosition startPosition, VisiblePosition endPosition)
 {
     if (isEmptyRangeOrAllSpaces(startPosition, endPosition))
index 340fa965cf4dafccf4f182b4ef70af8c1bb9ca05..1e88ab50b8c813486f2ea6095f8c3b91a7d0f264 100644 (file)
@@ -93,6 +93,7 @@ WebCore::VisibleSelection visibleSelectionForClosestActualWordStart(const WebCor
 
 WebCore::Frame* incrementFrame(WebCore::Frame* curr, bool forward, bool wrapFlag);
 
+PassRefPtr<WebCore::Range> trimWhitespaceFromRange(PassRefPtr<WebCore::Range>);
 PassRefPtr<WebCore::Range> trimWhitespaceFromRange(WebCore::VisiblePosition startPosition, WebCore::VisiblePosition endPosition);
 bool isEmptyRangeOrAllSpaces(WebCore::VisiblePosition, WebCore::VisiblePosition);
 
index 0d94ebc0bc155841a0311f7f6a04c6fd5820eb90..ec46636e157240ff85bc94d6ccfadb3d2cdeab91 100644 (file)
@@ -70,7 +70,6 @@
 #include <BlackBerryPlatformIMF.h>
 #include <BlackBerryPlatformKeyboardEvent.h>
 #include <BlackBerryPlatformLog.h>
-#include <BlackBerryPlatformMisc.h>
 #include <BlackBerryPlatformScreen.h>
 #include <BlackBerryPlatformSettings.h>
 #include <sys/keycodes.h>
index eb123cf2aa3bd4754dca0050bb7ab3dbf4b57d94..959d160f9fe2af2bed6d38c825c6146c1c1db5c9 100644 (file)
@@ -23,6 +23,7 @@
 #include "TextChecking.h"
 
 #include <BlackBerryPlatformInputEvents.h>
+#include <BlackBerryPlatformMisc.h>
 #include <BlackBerryPlatformSettings.h>
 
 #include <imf/events.h>
@@ -240,6 +241,7 @@ private:
     bool m_didSpellCheckWord;
     SpellingHandler* m_spellingHandler;
 
+    DISABLE_COPY(InputHandler);
 };
 
 }
index 4dd9949b8fbc469bf03a8a2cd84350222b090390..178317cdeada3009d94d5fcb9a85fcb9de71490e 100644 (file)
@@ -9,7 +9,6 @@
 #include "InputHandler.h"
 #include "Range.h"
 #include "SpellChecker.h"
-#include "TextIterator.h"
 #include "visible_units.h"
 
 #include <BlackBerryPlatformIMF.h>
@@ -44,6 +43,8 @@ SpellingHandler::~SpellingHandler()
 
 void SpellingHandler::spellCheckTextBlock(WebCore::VisibleSelection& visibleSelection, WebCore::TextCheckingProcessType textCheckingProcessType)
 {
+    SpellingLog(Platform::LogLevelInfo, "SpellingHandler::spellCheckTextBlock");
+
     // Check if this request can be sent off in one message, or if it needs to be broken down.
     RefPtr<Range> rangeForSpellChecking = visibleSelection.toNormalizedRange();
     if (!rangeForSpellChecking || !rangeForSpellChecking->text() || !rangeForSpellChecking->text().length())
@@ -79,43 +80,41 @@ void SpellingHandler::spellCheckTextBlock(WebCore::VisibleSelection& visibleSele
 void SpellingHandler::createSpellCheckRequest(PassRefPtr<WebCore::Range> rangeForSpellCheckingPtr, WebCore::TextCheckingProcessType textCheckingProcessType)
 {
     RefPtr<WebCore::Range> rangeForSpellChecking = rangeForSpellCheckingPtr;
-    if (isSpellCheckActive() && rangeForSpellChecking->text().length() >= MinSpellCheckingStringLength)
+    rangeForSpellChecking = DOMSupport::trimWhitespaceFromRange(rangeForSpellChecking);
+
+    SpellingLog(Platform::LogLevelInfo, "SpellingHandler::createSpellCheckRequest Substring text is '%s', of size %d"
+        , rangeForSpellChecking->text().latin1().data()
+        , rangeForSpellChecking->text().length());
+
+    if (rangeForSpellChecking->text().length() >= MinSpellCheckingStringLength)
         m_inputHandler->callRequestCheckingFor(SpellCheckRequest::create(TextCheckingTypeSpelling, textCheckingProcessType, rangeForSpellChecking, rangeForSpellChecking));
 }
 
 void SpellingHandler::parseBlockForSpellChecking(WebCore::Timer<SpellingHandler>*)
 {
-    if (isEndOfDocument(m_startOfCurrentLine)) {
-        m_isSpellCheckActive = false;
-        return;
-    }
-
     // Create a selection with the start and end points of the line, and convert to Range to create a SpellCheckRequest.
-    RefPtr<Range> rangeForSpellChecking = VisibleSelection(m_startOfCurrentLine, m_endOfCurrentLine).toNormalizedRange();
+    RefPtr<Range> rangeForSpellChecking = makeRange(m_startOfCurrentLine, m_endOfCurrentLine);
     if (!rangeForSpellChecking) {
-        SpellingLog(Platform::LogLevelInfo, "SpellingHandler::spellCheckBlock Failed to set text range for spellchecking.");
+        SpellingLog(Platform::LogLevelInfo, "SpellingHandler::parseBlockForSpellChecking Failed to set text range for spellchecking.");
         return;
     }
 
     if (rangeForSpellChecking->text().length() < MaxSpellCheckingStringLength) {
-        m_startOfCurrentLine = nextLinePosition(m_startOfCurrentLine, m_startOfCurrentLine.lineDirectionPointForBlockDirectionNavigation());
-        m_endOfCurrentLine = endOfLine(m_startOfCurrentLine);
-    } else {
-        // Iterate through words from the start of the line to the end.
-        rangeForSpellChecking = getRangeForSpellCheckWithFineGranularity(m_startOfCurrentLine, m_endOfCurrentLine);
-        if (!rangeForSpellChecking) {
-            SpellingLog(Platform::LogLevelWarn, "SpellingHandler::spellCheckBlock Failed to set text range with fine granularity.");
+        if (isEndOfDocument(m_endOfCurrentLine)) {
+            createSpellCheckRequest(rangeForSpellChecking, m_textCheckingProcessType);
+            m_isSpellCheckActive = false;
             return;
         }
-        m_startOfCurrentLine = VisiblePosition(rangeForSpellChecking->endPosition());
-        m_endOfCurrentLine = endOfLine(m_startOfCurrentLine);
-        rangeForSpellChecking = DOMSupport::trimWhitespaceFromRange(VisiblePosition(rangeForSpellChecking->startPosition()), VisiblePosition(rangeForSpellChecking->endPosition()));
+        m_endOfCurrentLine = endOfLine(nextLinePosition(m_endOfCurrentLine, m_endOfCurrentLine.lineDirectionPointForBlockDirectionNavigation()));
+        m_timer.startOneShot(s_timeout);
+        return;
     }
 
-    SpellingLog(Platform::LogLevelInfo,
-        "SpellingHandler::spellCheckBlock Substring text is '%s', of size %d",
-        rangeForSpellChecking->text().latin1().data(),
-        rangeForSpellChecking->text().length());
+    // Iterate through words from the start of the line to the end.
+    rangeForSpellChecking = getRangeForSpellCheckWithFineGranularity(m_startOfCurrentLine, m_endOfCurrentLine);
+
+    m_startOfCurrentLine = VisiblePosition(rangeForSpellChecking->endPosition());
+    m_endOfCurrentLine = endOfLine(m_startOfCurrentLine);
 
     // Call spellcheck with substring.
     createSpellCheckRequest(rangeForSpellChecking, m_textCheckingProcessType);
@@ -125,25 +124,33 @@ void SpellingHandler::parseBlockForSpellChecking(WebCore::Timer<SpellingHandler>
 
 PassRefPtr<Range> SpellingHandler::getRangeForSpellCheckWithFineGranularity(WebCore::VisiblePosition startPosition, WebCore::VisiblePosition endPosition)
 {
+    SpellingLog(Platform::LogLevelWarn, "SpellingHandler::getRangeForSpellCheckWithFineGranularity");
+    ASSERT(makeRange(startPosition, endOfCurrentWord));
     VisiblePosition endOfCurrentWord = endOfWord(startPosition);
 
     // Keep iterating until one of our cases is hit, or we've incremented the starting position right to the end.
     while (startPosition != endPosition) {
         // Check the text length within this range.
-        if (VisibleSelection(startPosition, endOfCurrentWord).toNormalizedRange()->text().length() >= MaxSpellCheckingStringLength) {
+        if (makeRange(startPosition, endOfCurrentWord)->text().length() >= MaxSpellCheckingStringLength) {
             // If this is not the first word, return a Range with end boundary set to the previous word.
-            if (startOfWord(endOfCurrentWord, LeftWordIfOnBoundary) != startPosition && !DOMSupport::isEmptyRangeOrAllSpaces(startPosition, endOfCurrentWord))
-                return VisibleSelection(startPosition, endOfWord(previousWordPosition(endOfCurrentWord), LeftWordIfOnBoundary)).toNormalizedRange();
-
+            if (startOfWord(endOfCurrentWord, LeftWordIfOnBoundary) != startPosition && !DOMSupport::isEmptyRangeOrAllSpaces(startPosition, endOfCurrentWord)) {
+                // When a series of whitespace follows a word, previousWordPosition will jump passed all of them, and using LeftWordIfOnBoundary brings us to
+                // our starting position. Check for this case and use RightWordIfOnBoundary to jump back over the word.
+                VisiblePosition endOfPreviousWord = endOfWord(previousWordPosition(endOfCurrentWord), LeftWordIfOnBoundary);
+                if (startPosition == endOfPreviousWord)
+                    return makeRange(startPosition, endOfWord(previousWordPosition(endOfCurrentWord), RightWordIfOnBoundary));
+                return makeRange(startPosition, endOfPreviousWord);
+            }
             // Our first word has gone over the character limit. Increment the starting position past an uncheckable word.
             startPosition = endOfCurrentWord;
             endOfCurrentWord = endOfWord(nextWordPosition(endOfCurrentWord));
         } else if (endOfCurrentWord == endPosition)
-            return VisibleSelection(startPosition, endPosition).toNormalizedRange(); // Return the last segment if the end of our word lies at the end of the range.
+            return makeRange(startPosition, endPosition); // Return the last segment if the end of our word lies at the end of the range.
         else
             endOfCurrentWord = endOfWord(nextWordPosition(endOfCurrentWord)); // Increment the current word.
     }
-    return 0;
+    // This will return an range with no string, but allows processing to continue
+    return makeRange(startPosition, endPosition);
 }
 
 } // WebKit
index 0b83fec366a7c471b9eca8bdc46b78148659a602..3221b388b9265e935101f9be83801f3f571ae3de 100644 (file)
@@ -18,9 +18,6 @@
 
 namespace WebCore {
 class Range;
-class SpellChecker;
-class VisibleSelection;
-class VisiblePosition;
 }
 
 namespace BlackBerry {