Commit 8f86fcbd authored by yoichio@chromium.org's avatar yoichio@chromium.org

WebLocalFrameImpl::selectWordAroundPosition should select a word before space.

If you have a "foo| ", WebLocalFrameImpl::selectWordAroundPosition
 selects space after the caret.
This is from the Selection::expandUsingGranularity behavior.
It is used widely including double-click word selection on desktop.
Thus we can not change the behavior.

I changed the implementation to use VisibleUnit functions directly.
New implementation is that we try to find a word on right side and left side.
In addition, move implement from WebLocalFrameImpl to FrameSelection.

BUG=397696

Review URL: https://codereview.chromium.org/675413003

git-svn-id: svn://svn.chromium.org/blink/trunk@185359 bbb929c8-8fbe-4397-9dbb-9b2b20218538
parent 5c96023f
...@@ -72,6 +72,7 @@ ...@@ -72,6 +72,7 @@
#include "platform/SecureTextInput.h" #include "platform/SecureTextInput.h"
#include "platform/geometry/FloatQuad.h" #include "platform/geometry/FloatQuad.h"
#include "platform/graphics/GraphicsContext.h" #include "platform/graphics/GraphicsContext.h"
#include "platform/text/UnicodeUtilities.h"
#include "wtf/text/CString.h" #include "wtf/text/CString.h"
#include <stdio.h> #include <stdio.h>
...@@ -1930,6 +1931,22 @@ void FrameSelection::scheduleVisualUpdate() const ...@@ -1930,6 +1931,22 @@ void FrameSelection::scheduleVisualUpdate() const
page->animator().scheduleVisualUpdate(); page->animator().scheduleVisualUpdate();
} }
bool FrameSelection::selectWordAroundPosition(const VisiblePosition& position)
{
static const EWordSide wordSideList[2] = { RightWordIfOnBoundary, LeftWordIfOnBoundary };
for (EWordSide wordSide : wordSideList) {
VisiblePosition start = startOfWord(position, wordSide);
VisiblePosition end = endOfWord(position, wordSide);
String text = plainText(start.deepEquivalent(), end.deepEquivalent());
if (!text.isEmpty() && !isSeparator(text.characterStartingAt(0))) {
setSelection(VisibleSelection(start, end), WordGranularity);
return true;
}
}
return false;
}
} }
#ifndef NDEBUG #ifndef NDEBUG
......
...@@ -184,6 +184,9 @@ public: ...@@ -184,6 +184,9 @@ public:
void updateSecureKeyboardEntryIfActive(); void updateSecureKeyboardEntryIfActive();
// Returns true if a word is selected.
bool selectWordAroundPosition(const VisiblePosition&);
#ifndef NDEBUG #ifndef NDEBUG
void formatForDebugger(char* buffer, unsigned length) const; void formatForDebugger(char* buffer, unsigned length) const;
void showTreeForThis() const; void showTreeForThis() const;
......
...@@ -138,4 +138,25 @@ TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout) ...@@ -138,4 +138,25 @@ TEST_F(FrameSelectionTest, PaintCaretShouldNotLayout)
EXPECT_EQ(startCount, layoutCount()); EXPECT_EQ(startCount, layoutCount());
} }
#define EXPECT_EQ_SELECTED_TEXT(text) \
EXPECT_EQ(text, WebString(selection().selectedText()).utf8())
TEST_F(FrameSelectionTest, SelectWordAroundPosition)
{
// "Foo Bar Baz,"
RefPtrWillBeRawPtr<Text> text = document().createTextNode("Foo Bar&nbsp;&nbsp;Baz,");
document().body()->appendChild(text);
// "Fo|o Bar Baz,"
EXPECT_TRUE(selection().selectWordAroundPosition(VisiblePosition(Position(text, 2))));
EXPECT_EQ_SELECTED_TEXT("Foo");
// "Foo| Bar Baz,"
EXPECT_TRUE(selection().selectWordAroundPosition(VisiblePosition(Position(text, 3))));
EXPECT_EQ_SELECTED_TEXT("Foo");
// "Foo Bar | Baz,"
EXPECT_FALSE(selection().selectWordAroundPosition(VisiblePosition(Position(text, 13))));
// "Foo Bar Baz|,"
EXPECT_TRUE(selection().selectWordAroundPosition(VisiblePosition(Position(text, 22))));
EXPECT_EQ_SELECTED_TEXT("Baz");
}
} }
...@@ -1156,11 +1156,7 @@ WebString WebLocalFrameImpl::selectionAsMarkup() const ...@@ -1156,11 +1156,7 @@ WebString WebLocalFrameImpl::selectionAsMarkup() const
void WebLocalFrameImpl::selectWordAroundPosition(LocalFrame* frame, VisiblePosition position) void WebLocalFrameImpl::selectWordAroundPosition(LocalFrame* frame, VisiblePosition position)
{ {
VisibleSelection selection(position); frame->selection().selectWordAroundPosition(position);
selection.expandUsingGranularity(WordGranularity);
TextGranularity granularity = selection.isRange() ? WordGranularity : CharacterGranularity;
frame->selection().setSelection(selection, granularity);
} }
bool WebLocalFrameImpl::selectWordAroundCaret() bool WebLocalFrameImpl::selectWordAroundCaret()
...@@ -1168,8 +1164,7 @@ bool WebLocalFrameImpl::selectWordAroundCaret() ...@@ -1168,8 +1164,7 @@ bool WebLocalFrameImpl::selectWordAroundCaret()
FrameSelection& selection = frame()->selection(); FrameSelection& selection = frame()->selection();
if (selection.isNone() || selection.isRange()) if (selection.isNone() || selection.isRange())
return false; return false;
selectWordAroundPosition(frame(), selection.selection().visibleStart()); return frame()->selection().selectWordAroundPosition(selection.selection().visibleStart());
return true;
} }
void WebLocalFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent) void WebLocalFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment