[Chromium] Replace correct misspelled range in WebKit::WebFrameImpl::replaceMisspelle...
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Feb 2013 20:23:48 +0000 (20:23 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 11 Feb 2013 20:23:48 +0000 (20:23 +0000)
https://bugs.webkit.org/show_bug.cgi?id=108513

Patch by Rouslan Solomakhin <rouslan@chromium.org> on 2013-02-11
Reviewed by Tony Chang.

WebKit::WebFrameImpl::replaceMisspelledRange is going to be used by Chromium instead of
WebKit::WebFrameImpl::replaceSelection for correcting misspellings. The current implementation
of WebKit::WebFrameImpl::replaceMisspelledRange sometimes replaces the wrong range. This change
uses Range::create instead of TextIterator::rangeFromLocationAndLength to select the correct
range. This change also disables smart replace in WebKit::WebFrameImpl::replaceMisspelledRange
to avoid introducing spaces around misspellings.

* src/WebFrameImpl.cpp:
(WebKit::WebFrameImpl::replaceMisspelledRange): Replace correct misspelled range.
* tests/WebFrameTest.cpp: Add unit test for WebKit::WebFrameImpl::replaceMisspelledRange method.

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

Source/WebKit/chromium/ChangeLog
Source/WebKit/chromium/src/WebFrameImpl.cpp
Source/WebKit/chromium/tests/WebFrameTest.cpp

index 2743e7a5b3e526e2ce581a62a9ef769177f9a8c1..ffa76e2e8f062087eafd10bce5fe433121669532 100644 (file)
@@ -1,3 +1,21 @@
+2013-02-11  Rouslan Solomakhin  <rouslan@chromium.org>
+
+        [Chromium] Replace correct misspelled range in WebKit::WebFrameImpl::replaceMisspelledRange
+        https://bugs.webkit.org/show_bug.cgi?id=108513
+
+        Reviewed by Tony Chang.
+
+        WebKit::WebFrameImpl::replaceMisspelledRange is going to be used by Chromium instead of
+        WebKit::WebFrameImpl::replaceSelection for correcting misspellings. The current implementation
+        of WebKit::WebFrameImpl::replaceMisspelledRange sometimes replaces the wrong range. This change
+        uses Range::create instead of TextIterator::rangeFromLocationAndLength to select the correct
+        range. This change also disables smart replace in WebKit::WebFrameImpl::replaceMisspelledRange
+        to avoid introducing spaces around misspellings.
+
+        * src/WebFrameImpl.cpp:
+        (WebKit::WebFrameImpl::replaceMisspelledRange): Replace correct misspelled range.
+        * tests/WebFrameTest.cpp: Add unit test for WebKit::WebFrameImpl::replaceMisspelledRange method.
+
 2013-02-11  Alexei Filippov  <alph@chromium.org>
 
         Web Inspector: Split Profiler domain in protocol into Profiler and HeapProfiler
 2013-02-11  Alexei Filippov  <alph@chromium.org>
 
         Web Inspector: Split Profiler domain in protocol into Profiler and HeapProfiler
index 9ef5002174676402ad70931451d23b77caa8ea26..9ac696f966662d8367969df2cfbb05a8a9d22d88 100644 (file)
@@ -1310,11 +1310,13 @@ void WebFrameImpl::replaceMisspelledRange(const WebString& text)
     Vector<DocumentMarker*> markers = frame()->document()->markers()->markersInRange(caretRange.get(), DocumentMarker::Spelling | DocumentMarker::Grammar);
     if (markers.size() < 1 || markers[0]->startOffset() >= markers[0]->endOffset())
         return;
     Vector<DocumentMarker*> markers = frame()->document()->markers()->markersInRange(caretRange.get(), DocumentMarker::Spelling | DocumentMarker::Grammar);
     if (markers.size() < 1 || markers[0]->startOffset() >= markers[0]->endOffset())
         return;
-    RefPtr<Range> markerRange = TextIterator::rangeFromLocationAndLength(frame()->selection()->rootEditableElementOrDocumentElement(), markers[0]->startOffset(), markers[0]->endOffset() - markers[0]->startOffset());
-    if (!markerRange.get() || !frame()->selection()->shouldChangeSelection(markerRange.get()))
+    RefPtr<Range> markerRange = Range::create(caretRange->ownerDocument(), caretRange->startContainer(), markers[0]->startOffset(), caretRange->endContainer(), markers[0]->endOffset());
+    if (!markerRange)
+        return;
+    if (!frame()->selection()->shouldChangeSelection(markerRange.get()))
         return;
     frame()->selection()->setSelection(markerRange.get(), CharacterGranularity);
         return;
     frame()->selection()->setSelection(markerRange.get(), CharacterGranularity);
-    frame()->editor()->replaceSelectionWithText(text, false, true);
+    frame()->editor()->replaceSelectionWithText(text, false, false);
 }
 
 bool WebFrameImpl::hasSelection() const
 }
 
 bool WebFrameImpl::hasSelection() const
index d519703830f1903e2185e63e1fa7cb90ab0c14ae..eaa97526b755acc9ae69f20c590ed168b00ba76d 100644 (file)
@@ -32,6 +32,7 @@
 
 #include "WebFrame.h"
 
 
 #include "WebFrame.h"
 
+#include "DocumentMarkerController.h"
 #include "FloatRect.h"
 #include "Frame.h"
 #include "FrameTestHelpers.h"
 #include "FloatRect.h"
 #include "Frame.h"
 #include "FrameTestHelpers.h"
@@ -57,6 +58,9 @@
 #include "WebSecurityOrigin.h"
 #include "WebSecurityPolicy.h"
 #include "WebSettings.h"
 #include "WebSecurityOrigin.h"
 #include "WebSecurityPolicy.h"
 #include "WebSettings.h"
+#include "WebSpellCheckClient.h"
+#include "WebTextCheckingCompletion.h"
+#include "WebTextCheckingResult.h"
 #include "WebViewClient.h"
 #include "WebViewImpl.h"
 #include "v8.h"
 #include "WebViewClient.h"
 #include "WebViewImpl.h"
 #include "v8.h"
@@ -69,6 +73,9 @@
 #include <wtf/Forward.h>
 
 using namespace WebKit;
 #include <wtf/Forward.h>
 
 using namespace WebKit;
+using WebCore::Document;
+using WebCore::DocumentMarker;
+using WebCore::Element;
 using WebCore::FloatRect;
 using WebCore::Range;
 using WebKit::URLTestHelpers::toKURL;
 using WebCore::FloatRect;
 using WebCore::Range;
 using WebKit::URLTestHelpers::toKURL;
@@ -2233,4 +2240,54 @@ TEST_F(WebFrameTest, MoveCaretSelectionTowardsWindowPointWithNoSelection)
     frame->moveCaretSelectionTowardsWindowPoint(WebPoint(0, 0));
 }
 
     frame->moveCaretSelectionTowardsWindowPoint(WebPoint(0, 0));
 }
 
+class SpellCheckClient : public WebSpellCheckClient {
+public:
+    SpellCheckClient() : m_numberOfTimesChecked(0) { }
+    virtual ~SpellCheckClient() { }
+    virtual void requestCheckingOfText(const WebKit::WebString&, WebKit::WebTextCheckingCompletion* completion) OVERRIDE
+    {
+        ++m_numberOfTimesChecked;
+        Vector<WebTextCheckingResult> results;
+        const int misspellingStartOffset = 1;
+        const int misspellingLength = 8;
+        results.append(WebTextCheckingResult(WebTextCheckingTypeSpelling, misspellingStartOffset, misspellingLength, WebString()));
+        completion->didFinishCheckingText(results);
+    }
+    int numberOfTimesChecked() const { return m_numberOfTimesChecked; }
+private:
+    int m_numberOfTimesChecked;
+};
+
+TEST_F(WebFrameTest, ReplaceMisspelledRange)
+{
+    m_webView = FrameTestHelpers::createWebViewAndLoad("data:text/html,<div id=\"data\" contentEditable></div>");
+    SpellCheckClient spellcheck;
+    m_webView->setSpellCheckClient(&spellcheck);
+
+    WebFrameImpl* frame = static_cast<WebFrameImpl*>(m_webView->mainFrame());
+    Document* document = frame->frame()->document();
+    Element* element = document->getElementById("data");
+
+    frame->frame()->settings()->setAsynchronousSpellCheckingEnabled(true);
+    frame->frame()->settings()->setUnifiedTextCheckerEnabled(true);
+    frame->frame()->settings()->setEditingBehaviorType(WebCore::EditingWindowsBehavior);
+
+    element->focus();
+    document->execCommand("InsertText", false, "_wellcome_.");
+
+    const int allTextBeginOffset = 0;
+    const int allTextLength = 11;
+    frame->selectRange(WebRange::fromDocumentRange(frame, allTextBeginOffset, allTextLength));
+    RefPtr<Range> selectionRange = frame->frame()->selection()->toNormalizedRange();
+
+    EXPECT_EQ(1, spellcheck.numberOfTimesChecked());
+    EXPECT_EQ(1U, document->markers()->markersInRange(selectionRange.get(), DocumentMarker::Spelling).size());
+
+    frame->replaceMisspelledRange("welcome");
+    EXPECT_EQ("_welcome_.", std::string(frame->contentAsText(std::numeric_limits<size_t>::max()).utf8().data()));
+
+    m_webView->close();
+    m_webView = 0;
+}
+
 } // namespace
 } // namespace