| Index: ui/gfx/render_text.cc
|
| diff --git a/ui/gfx/render_text.cc b/ui/gfx/render_text.cc
|
| index 91f9f42bd89ad69dad47646e52c08516e9cad394..a80f0e0e9634d3ebdbf76b835a1ea615f3672202 100644
|
| --- a/ui/gfx/render_text.cc
|
| +++ b/ui/gfx/render_text.cc
|
| @@ -789,6 +789,49 @@ SelectionModel RenderText::GetAdjacentSelectionModel(
|
| return AdjacentWordSelectionModel(current, direction);
|
| }
|
|
|
| +SelectionModel RenderText::AdjacentWordSelectionModel(
|
| + const SelectionModel& selection,
|
| + VisualCursorDirection direction) {
|
| + if (obscured())
|
| + return EdgeSelectionModel(direction);
|
| +
|
| + base::i18n::BreakIterator iter(text(), base::i18n::BreakIterator::BREAK_WORD);
|
| + bool success = iter.Init();
|
| + DCHECK(success);
|
| + if (!success)
|
| + return selection;
|
| +
|
| + size_t pos = 0;
|
| + // TODO(msw): Cache a list of word breaks or add WordIterator functionality to
|
| + // start from supplied indices and to iterate backward for better performance.
|
| + if (direction == CURSOR_RIGHT) {
|
| + pos = std::min(selection.caret_pos() + 1, text().length());
|
| + while (iter.Advance()) {
|
| + pos = iter.pos();
|
| + if (iter.IsWord() && pos > selection.caret_pos())
|
| + break;
|
| + }
|
| + } else {
|
| + pos = std::max<int>(selection.caret_pos() - 1, 0);
|
| + while (iter.Advance()) {
|
| + if (iter.IsWord()) {
|
| + size_t begin = iter.pos() - iter.GetString().length();
|
| + if (begin == selection.caret_pos()) {
|
| + // The cursor is at a word beginning; move it to the previous word.
|
| + break;
|
| + } else if (iter.pos() >= selection.caret_pos()) {
|
| + // The cursor is at a word middle or end; move it to its beginning.
|
| + pos = begin;
|
| + break;
|
| + } else {
|
| + pos = iter.pos() - iter.GetString().length();
|
| + }
|
| + }
|
| + }
|
| + }
|
| + return SelectionModel(pos, CURSOR_FORWARD);
|
| +}
|
| +
|
| SelectionModel RenderText::EdgeSelectionModel(
|
| VisualCursorDirection direction) {
|
| if (direction == GetVisualDirectionOfLogicalEnd())
|
|
|