2008-11-24 Glenn Wilson <gwilson@chromium.org>
authordarin@chromium.org <darin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 Nov 2008 00:18:48 +0000 (00:18 +0000)
committerdarin@chromium.org <darin@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 25 Nov 2008 00:18:48 +0000 (00:18 +0000)
        Reviewed by Alexey Proskuryakov.

        http://bugs.webkit.org/show_bug.cgi?id=15643

        Added support for clients that wish to disable smart insert/delete
        and enable the "trailing whitespace selection" work-around.

        Tests: editing/selection/doubleclick-whitespace.html

        * editing/Editor.cpp:
        (WebCore::Editor::selectTrailingWhitespaceEnabled):
        * editing/Editor.h:
        * editing/Selection.cpp:
        (WebCore::Selection::includeTrailingWhitespace):
        * editing/Selection.h:
        * loader/EmptyClients.h:
        (WebCore::EmptyEditorClient::selectTrailingWhitespaceEnabled):
        * page/EditorClient.h:
        * page/EventHandler.cpp:
        (WebCore::EventHandler::selectClosestWordFromMouseEvent):

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

27 files changed:
LayoutTests/ChangeLog
LayoutTests/editing/selection/doubleclick-whitespace-expected.txt [new file with mode: 0644]
LayoutTests/editing/selection/doubleclick-whitespace.html [new file with mode: 0644]
WebCore/ChangeLog
WebCore/editing/Editor.cpp
WebCore/editing/Editor.h
WebCore/editing/Selection.cpp
WebCore/editing/Selection.h
WebCore/loader/EmptyClients.h
WebCore/page/EditorClient.h
WebCore/page/EventHandler.cpp
WebKit/mac/ChangeLog
WebKit/mac/WebCoreSupport/WebEditorClient.h
WebKit/mac/WebCoreSupport/WebEditorClient.mm
WebKit/mac/WebView/WebView.mm
WebKit/mac/WebView/WebViewPrivate.h
WebKit/win/ChangeLog
WebKit/win/Interfaces/IWebView.idl
WebKit/win/WebCoreSupport/WebEditorClient.cpp
WebKit/win/WebCoreSupport/WebEditorClient.h
WebKit/win/WebView.cpp
WebKit/win/WebView.h
WebKitTools/ChangeLog
WebKitTools/DumpRenderTree/LayoutTestController.cpp
WebKitTools/DumpRenderTree/LayoutTestController.h
WebKitTools/DumpRenderTree/mac/LayoutTestControllerMac.mm
WebKitTools/DumpRenderTree/win/LayoutTestControllerWin.cpp

index 851b6e4..4755d4e 100644 (file)
@@ -1,5 +1,18 @@
 2008-11-24  Glenn Wilson  <gwilson@chromium.org>
 
+        Reviewed by Alexey Proskuryakov.
+
+        http://bugs.webkit.org/show_bug.cgi?id=15643
+
+        New test added to verify that LayoutTestController and other clients
+        can disable smart insert/delete and enable selection of trailing whitespace
+        as a workaround for smart insert/delete.
+
+        * editing/selection/doubleclick-whitespace-expected.txt: Added.
+        * editing/selection/doubleclick-whitespace.html: Added.
+
+2008-11-24  Glenn Wilson  <gwilson@chromium.org>
+
         Reviewed by Darin Adler.
 
         http://bugs.webkit.org/show_bug.cgi?id=18703
diff --git a/LayoutTests/editing/selection/doubleclick-whitespace-expected.txt b/LayoutTests/editing/selection/doubleclick-whitespace-expected.txt
new file mode 100644 (file)
index 0000000..96ff98b
--- /dev/null
@@ -0,0 +1,6 @@
+This tests that double-clicking a word on the Windows platform selects the whitespace after the word.  You should see the word "PASS" below.
+
+PASS
+
+
+
diff --git a/LayoutTests/editing/selection/doubleclick-whitespace.html b/LayoutTests/editing/selection/doubleclick-whitespace.html
new file mode 100644 (file)
index 0000000..0d4dcdc
--- /dev/null
@@ -0,0 +1,38 @@
+<html>
+<head>
+<script>
+if (window.layoutTestController) {
+     layoutTestController.dumpAsText();
+     layoutTestController.setSmartInsertDeleteEnabled(false);
+     layoutTestController.setSelectTrailingWhitespaceEnabled(true);
+}
+</script>
+<style>
+body { margin: 0; padding: 0 }
+</style>
+</head>
+<body>
+<pre>
+This tests that double-clicking a word on the Windows platform selects the whitespace after the word.  You should see the word "PASS" below.
+<p>
+<script type="text/javascript">
+    if (window.layoutTestController) {
+        eventSender.mouseMoveTo(20, 10);
+        eventSender.mouseDown();
+        eventSender.leapForward(1);
+        eventSender.mouseUp();
+        eventSender.leapForward(100);
+        eventSender.mouseDown();
+        eventSender.leapForward(1);
+        eventSender.mouseUp();
+        var sel = window.getSelection();
+        var range = sel.getRangeAt(0);
+        if (range.toString() != "This ")
+            document.write("FAIL");
+        else
+            document.write("PASS");
+    } else
+        document.write("This test is only expected to pass when run in automated mode, with access to LayoutTestController.");
+</script>
+</body>
+</html>
index e165e78..f52b3d2 100644 (file)
@@ -1,3 +1,26 @@
+2008-11-24  Glenn Wilson  <gwilson@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        http://bugs.webkit.org/show_bug.cgi?id=15643
+
+        Added support for clients that wish to disable smart insert/delete
+        and enable the "trailing whitespace selection" work-around.
+
+        Tests: editing/selection/doubleclick-whitespace.html
+
+        * editing/Editor.cpp:
+        (WebCore::Editor::selectTrailingWhitespaceEnabled):
+        * editing/Editor.h:
+        * editing/Selection.cpp:
+        (WebCore::Selection::includeTrailingWhitespace):
+        * editing/Selection.h:
+        * loader/EmptyClients.h:
+        (WebCore::EmptyEditorClient::selectTrailingWhitespaceEnabled):
+        * page/EditorClient.h:
+        * page/EventHandler.cpp:
+        (WebCore::EventHandler::selectClosestWordFromMouseEvent):
+
 2008-11-24  Nikolas Zimmermann  <nikolas.zimmermann@torchmobile.com>
 
         Not reviewed. Forgot to include WMLPageState.h in last commit.
index 77ba472..f43868b 100644 (file)
@@ -214,6 +214,11 @@ bool Editor::canSmartCopyOrDelete()
     return client() && client()->smartInsertDeleteEnabled() && m_frame->selectionGranularity() == WordGranularity;
 }
 
+bool Editor::isSelectTrailingWhitespaceEnabled()
+{
+    return client() && client()->isSelectTrailingWhitespaceEnabled();
+}
+
 bool Editor::deleteWithDirection(SelectionController::EDirection direction, TextGranularity granularity, bool killRing, bool isTypingAction)
 {
     if (!canEdit() || !m_frame->document())
index 5fccffd..d97f670 100644 (file)
@@ -219,7 +219,10 @@ public:
     void toggleUnderline();
     void setBaseWritingDirection(WritingDirection);
 
+    // smartInsertDeleteEnabled and selectTrailingWhitespaceEnabled are 
+    // mutually exclusive, meaning that enabling one will disable the other.
     bool smartInsertDeleteEnabled();
+    bool isSelectTrailingWhitespaceEnabled();
     
     bool hasBidiSelection() const;
 
index 9b17567..ea30f19 100644 (file)
@@ -193,6 +193,14 @@ bool Selection::expandUsingGranularity(TextGranularity granularity)
     return true;
 }
 
+void Selection::appendTrailingWhitespace()
+{
+    VisiblePosition end = VisiblePosition(m_end, m_affinity);
+    while (end.isNotNull() && isSpaceOrNewline(end.characterAfter()))
+        end = end.next();
+    m_end = end.deepEquivalent();
+}
+
 void Selection::validate()
 {
     // Move the selection to rendered positions, if possible.
index ae50073..5e21701 100644 (file)
@@ -77,6 +77,8 @@ public:
 
     bool isBaseFirst() const { return m_baseIsFirst; }
 
+    void appendTrailingWhitespace();
+
     bool expandUsingGranularity(TextGranularity granularity);
     TextGranularity granularity() const { return m_granularity; }
 
index 10d520c..1f69cf0 100644 (file)
@@ -281,6 +281,7 @@ public:
     virtual bool shouldDeleteRange(Range*) { return false; }
     virtual bool shouldShowDeleteInterface(HTMLElement*) { return false; }
     virtual bool smartInsertDeleteEnabled() { return false; }
+    virtual bool isSelectTrailingWhitespaceEnabled() { return false; }
     virtual bool isContinuousSpellCheckingEnabled() { return false; }
     virtual void toggleContinuousSpellChecking() { }
     virtual bool isGrammarCheckingEnabled() { return false; }
index b36709f..56d0435 100644 (file)
@@ -69,6 +69,7 @@ public:
     virtual bool shouldDeleteRange(Range*) = 0;
     virtual bool shouldShowDeleteInterface(HTMLElement*) = 0;
     virtual bool smartInsertDeleteEnabled() = 0; 
+    virtual bool isSelectTrailingWhitespaceEnabled() = 0;
     virtual bool isContinuousSpellCheckingEnabled() = 0;
     virtual void toggleContinuousSpellChecking() = 0;
     virtual bool isGrammarCheckingEnabled() = 0;
index 7b45357..4dc37d8 100644 (file)
@@ -192,6 +192,8 @@ void EventHandler::selectClosestWordFromMouseEvent(const MouseEventWithHitTestRe
         if (newSelection.isRange()) {
             m_frame->setSelectionGranularity(WordGranularity);
             m_beganSelectingText = true;
+            if (result.event().clickCount() == 2 && m_frame->editor()->isSelectTrailingWhitespaceEnabled()) 
+                newSelection.appendTrailingWhitespace();            
         }
         
         if (m_frame->shouldChangeSelection(newSelection))
index 6a27176..7bfa3ba 100644 (file)
@@ -1,3 +1,21 @@
+2008-11-24  Glenn Wilson  <gwilson@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        http://bugs.webkit.org/show_bug.cgi?id=15643
+
+        Added API support for the "trailing whitespace" work-around.  This includes an APIs
+        to get and set the state of this configuration variable.
+
+        * WebCoreSupport/WebEditorClient.h:
+        * WebCoreSupport/WebEditorClient.mm:
+        (WebEditorClient::selectTrailingWhitespaceEnabled):
+        * WebView/WebView.mm:
+        (-[WebView setSelectTrailingWhitespaceEnabled:]):
+        (-[WebView isSelectTrailingWhitespaceEnabled]):
+        (-[WebView setSmartInsertDeleteEnabled:]):
+        * WebView/WebViewPrivate.h:
+
 2008-11-24  Darin Adler  <darin@apple.com>
 
         Reviewed by Dan Bernstein.
index 245e575..2845b97 100644 (file)
@@ -48,6 +48,7 @@ public:
     virtual int spellCheckerDocumentTag();
 
     virtual bool smartInsertDeleteEnabled();
+    virtual bool isSelectTrailingWhitespaceEnabled();
     virtual bool isEditable();
 
     virtual bool shouldDeleteRange(WebCore::Range*);    
index f2ed480..f6fecae 100644 (file)
@@ -222,6 +222,11 @@ bool WebEditorClient::smartInsertDeleteEnabled()
     return [m_webView smartInsertDeleteEnabled];
 }
 
+bool WebEditorClient::isSelectTrailingWhitespaceEnabled()
+{
+    return [m_webView isSelectTrailingWhitespaceEnabled];
+}
+
 bool WebEditorClient::shouldApplyStyle(CSSStyleDeclaration* style, Range* range)
 {
     return [[m_webView _editingDelegateForwarder] webView:m_webView
index 2de8f8e..49997c4 100644 (file)
@@ -378,6 +378,7 @@ static const char webViewIsOpen[] = "At least one WebView is still open.";
     NSInteger spellCheckerDocumentTag;
 
     BOOL smartInsertDeleteEnabled;
+    BOOL selectTrailingWhitespaceEnabled;
         
 #if ENABLE(DASHBOARD_SUPPORT)
     BOOL dashboardBehaviorAlwaysSendMouseEventsToAllWindows;
@@ -2017,6 +2018,18 @@ WebFrameLoadDelegateImplementationCache* WebViewGetFrameLoadDelegateImplementati
     _private->page->mainFrame()->tree()->clearName();
 }
 
+- (void)setSelectTrailingWhitespaceEnabled:(BOOL)flag
+{
+    _private->selectTrailingWhitespaceEnabled = flag;
+    if (flag)
+        [self setSmartInsertDeleteEnabled:false];
+}
+
+- (BOOL)isSelectTrailingWhitespaceEnabled
+{
+    return _private->selectTrailingWhitespaceEnabled;
+}
+
 @end
 
 @implementation _WebSafeForwarder
@@ -4053,6 +4066,8 @@ static NSAppleEventDescriptor* aeDescFromJSValue(ExecState* exec, JSValue* jsVal
 - (void)setSmartInsertDeleteEnabled:(BOOL)flag
 {
     _private->smartInsertDeleteEnabled = flag;
+    if (flag)
+        [self setSelectTrailingWhitespaceEnabled:false];
 }
 
 - (BOOL)smartInsertDeleteEnabled
index 0dd189f..ccb057c 100644 (file)
@@ -398,6 +398,9 @@ Could be worth adding to the API.
 - (id)_initWithFrame:(NSRect)f frameName:(NSString *)frameName groupName:(NSString *)groupName usesDocumentViews:(BOOL)usesDocumentViews;
 - (BOOL)_usesDocumentViews;
 
+- (void)setSelectTrailingWhitespaceEnabled:(BOOL)flag;
+- (BOOL)isSelectTrailingWhitespaceEnabled;
+
 @end
 
 @interface WebView (WebViewPrintingPrivate)
index 05b1ed3..c04e6f4 100644 (file)
@@ -1,3 +1,22 @@
+2008-11-24  Glenn Wilson  <gwilson@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        http://bugs.webkit.org/show_bug.cgi?id=15643
+
+        Added API support for the "trailing whitespace" work-around.  This includes an APIs
+        to get and set the state of this configuration variable.
+
+        * Interfaces/IWebView.idl:
+        * WebCoreSupport/WebEditorClient.cpp:
+        (WebEditorClient::selectTrailingWhitespaceEnabled):
+        * WebCoreSupport/WebEditorClient.h:
+        * WebView.cpp:
+        (WebView::WebView):
+        (WebView::setSelectTrailingWhitespaceEnabled):
+        (WebView::selectTrailingWhitespaceEnabled):
+        * WebView.h:
+
 2008-11-24  Darin Adler  <darin@apple.com>
 
         Reviewed by Dan Bernstein.
index 92fa2b5..e38406b 100644 (file)
@@ -1014,6 +1014,16 @@ interface IWebViewEditing : IUnknown
         - (void)setGrammarCheckingEnabled:(BOOL)flag
     */
     HRESULT setGrammarCheckingEnabled(BOOL enabled);
+
+    /*
+        - (void)setSelectTrailingWhitespaceEnabled:(BOOL)flag;
+    */
+    HRESULT setSelectTrailingWhitespaceEnabled([in] BOOL flag);
+
+    /*
+        - (BOOL)selectTrailingWhitespaceEnabled;
+    */
+    HRESULT isSelectTrailingWhitespaceEnabled([out, retval] BOOL* enabled);
 }
 
 /*
index e38cd0d..985742f 100644 (file)
@@ -295,6 +295,13 @@ bool WebEditorClient::smartInsertDeleteEnabled(void)
     return !!enabled;
 }
 
+bool WebEditorClient::isSelectTrailingWhitespaceEnabled(void)
+{
+    BOOL enabled = FALSE;
+    m_webView->isSelectTrailingWhitespaceEnabled(&enabled);
+    return !!enabled;
+}
+
 bool WebEditorClient::shouldChangeSelectedRange(WebCore::Range*, WebCore::Range*, WebCore::EAffinity, bool)
 { notImplemented(); return true; }
 
index 8c603f2..52cb66d 100644 (file)
@@ -75,6 +75,7 @@ public:
     void webViewDidChangeSelection(WebNotification*);
 
     bool smartInsertDeleteEnabled();
+    bool isSelectTrailingWhitespaceEnabled();
 
     void registerCommandForUndo(PassRefPtr<WebCore::EditCommand>);
     void registerCommandForRedo(PassRefPtr<WebCore::EditCommand>);
index 71c79d3..6468fa1 100644 (file)
@@ -283,6 +283,7 @@ WebView::WebView()
 , m_topLevelParent(0)
 , m_deleteBackingStoreTimerActive(false)
 , m_transparent(false)
+, m_selectTrailingWhitespaceEnabled(false)
 {
     JSC::initializeThreading();
 
@@ -3492,6 +3493,8 @@ HRESULT STDMETHODCALLTYPE WebView::setSmartInsertDeleteEnabled(
         /* [in] */ BOOL flag)
 {
     m_smartInsertDeleteEnabled = !!flag;
+    if (m_smartInsertDeleteEnabled)
+        setSelectTrailingWhitespaceEnabled(false);
     return S_OK;
 }
     
@@ -3501,7 +3504,23 @@ HRESULT STDMETHODCALLTYPE WebView::smartInsertDeleteEnabled(
     *enabled = m_smartInsertDeleteEnabled ? TRUE : FALSE;
     return S_OK;
 }
+HRESULT STDMETHODCALLTYPE WebView::setSelectTrailingWhitespaceEnabled( 
+        /* [in] */ BOOL flag)
+{
+    m_selectTrailingWhitespaceEnabled = !!flag;
+    if (m_selectTrailingWhitespaceEnabled)
+        setSmartInsertDeleteEnabled(false);
+    return S_OK;
+}
     
+HRESULT STDMETHODCALLTYPE WebView::isSelectTrailingWhitespaceEnabled( 
+        /* [retval][out] */ BOOL* enabled)
+{
+    *enabled = m_selectTrailingWhitespaceEnabled ? TRUE : FALSE;
+    return S_OK;
+}
+
 HRESULT STDMETHODCALLTYPE WebView::setContinuousSpellCheckingEnabled( 
         /* [in] */ BOOL flag)
 {
index e8c47d8..99e3267 100644 (file)
@@ -390,7 +390,13 @@ public:
     
     virtual HRESULT STDMETHODCALLTYPE smartInsertDeleteEnabled( 
         /* [in] */ BOOL *enabled);
+
+    virtual HRESULT STDMETHODCALLTYPE setSelectTrailingWhitespaceEnabled( 
+        /* [in] */ BOOL flag);
     
+    virtual HRESULT STDMETHODCALLTYPE isSelectTrailingWhitespaceEnabled( 
+        /* [in] */ BOOL *enabled);
+
     virtual HRESULT STDMETHODCALLTYPE setContinuousSpellCheckingEnabled( 
         /* [in] */ BOOL flag);
     
@@ -867,6 +873,7 @@ protected:
     unsigned m_paintCount;
     bool m_hasSpellCheckerDocumentTag;
     bool m_smartInsertDeleteEnabled;
+    bool m_selectTrailingWhitespaceEnabled;
     bool m_didClose;
     bool m_hasCustomDropTarget;
     unsigned m_inIMEComposition;
index f1d956c..8b38d4a 100644 (file)
@@ -1,3 +1,21 @@
+2008-11-24  Glenn Wilson  <gwilson@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        http://bugs.webkit.org/show_bug.cgi?id=15643
+
+        Added support for changing the "trailing whitespace" work-around
+        in LayoutTestController (so layout tests can verify this functionality)
+
+        * DumpRenderTree/LayoutTestController.cpp:
+        (setSelectTrailingWhitespaceEnabledCallback):
+        (LayoutTestController::staticFunctions):
+        * DumpRenderTree/LayoutTestController.h:
+        * DumpRenderTree/mac/LayoutTestControllerMac.mm:
+        (LayoutTestController::setSelectTrailingWhitespaceEnabled):
+        * DumpRenderTree/win/LayoutTestControllerWin.cpp:
+        (LayoutTestController::setSelectTrailingWhitespaceEnabled):
+
 2008-11-24  Simon Fraser  <simon.fraser@apple.com>
 
         Reviewed by Darin Adler
index a82f138..808097a 100644 (file)
@@ -636,6 +636,16 @@ static JSValueRef setSmartInsertDeleteEnabledCallback(JSContextRef context, JSOb
     return JSValueMakeUndefined(context);
 }
 
+static JSValueRef setSelectTrailingWhitespaceEnabledCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
+{
+    if (argumentCount < 1)
+        return JSValueMakeUndefined(context);
+
+    LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
+    controller->setSelectTrailingWhitespaceEnabled(JSValueToBoolean(context, arguments[0]));
+    return JSValueMakeUndefined(context);
+}
+
 static JSValueRef setStopProvisionalFrameLoadsCallback(JSContextRef context, JSObjectRef function, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
 {
     LayoutTestController* controller = reinterpret_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
@@ -792,6 +802,7 @@ JSStaticFunction* LayoutTestController::staticFunctions()
         { "setPrivateBrowsingEnabled", setPrivateBrowsingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setPopupBlockingEnabled", setPopupBlockingEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setSmartInsertDeleteEnabled", setSmartInsertDeleteEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
+        { "setSelectTrailingWhitespaceEnabled", setSelectTrailingWhitespaceEnabledCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setStopProvisionalFrameLoads", setStopProvisionalFrameLoadsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setTabKeyCyclesThroughElements", setTabKeyCyclesThroughElementsCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
         { "setUseDashboardCompatibilityMode", setUseDashboardCompatibilityModeCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
index 9603c51..a7acdb8 100644 (file)
@@ -65,6 +65,7 @@ public:
     void setPopupBlockingEnabled(bool flag);
     void setTabKeyCyclesThroughElements(bool cycles);
     void setSmartInsertDeleteEnabled(bool flag);
+    void setSelectTrailingWhitespaceEnabled(bool flag);
     void setJavaScriptProfilingEnabled(bool profilingEnabled);
     void setUseDashboardCompatibilityMode(bool flag);
     void setUserStyleSheetEnabled(bool flag);
index 8a1c624..ad2a853 100644 (file)
@@ -263,6 +263,11 @@ void LayoutTestController::setJavaScriptProfilingEnabled(bool profilingEnabled)
     [[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:profilingEnabled];
 }
 
+void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag)
+{
+    [[mainFrame webView] setSelectTrailingWhitespaceEnabled:flag];
+}
+
 static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
 
 static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)
index 6d5d8b8..5bd610f 100644 (file)
@@ -547,6 +547,19 @@ void LayoutTestController::setJavaScriptProfilingEnabled(bool flag)
     inspector->setJavaScriptProfilingEnabled(flag);
 }
 
+void LayoutTestController::setSelectTrailingWhitespaceEnabled(bool flag)
+{
+    COMPtr<IWebView> webView;
+    if (FAILED(frame->webView(&webView)))
+        return;
+
+    COMPtr<IWebViewEditing> viewEditing;
+    if (FAILED(webView->QueryInterface(&viewEditing)))
+        return;
+
+    viewEditing->setSelectTrailingWhitespaceEnabled(flag ? TRUE : FALSE);
+}
+
 static const CFTimeInterval waitToDumpWatchdogInterval = 10.0;
 
 static void waitUntilDoneWatchdogFired(CFRunLoopTimerRef timer, void* info)