1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// found in the LICENSE file.
4c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/web_contents/touch_editable_impl_aura.h"
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_impl.h"
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/renderer_host/render_widget_host_view_aura.h"
9c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "content/browser/web_contents/web_contents_impl.h"
10c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/common/view_messages.h"
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
12c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/render_widget_host.h"
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/client/screen_position_client.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/aura/window.h"
1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "ui/aura/window_tree_host.h"
16c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/clipboard/clipboard.h"
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/base/ui_base_switches_util.h"
1858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "ui/gfx/range/range.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "ui/strings/grit/ui_strings.h"
20effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "ui/wm/public/activation_client.h"
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content {
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TouchEditableImplAura, public:
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TouchEditableImplAura::~TouchEditableImplAura() {
28c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Cleanup();
29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
30c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
32c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TouchEditableImplAura* TouchEditableImplAura::Create() {
33c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (switches::IsTouchEditingEnabled())
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return new TouchEditableImplAura();
35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return NULL;
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::AttachToView(RenderWidgetHostViewAura* view) {
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (rwhva_ == view)
40c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Cleanup();
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!view)
44c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rwhva_ = view;
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rwhva_->set_touch_editing_client(this);
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::UpdateEditingController() {
517dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!rwhva_ || !rwhva_->HasFocus())
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
54c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (text_input_type_ != ui::TEXT_INPUT_TYPE_NONE ||
55c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      selection_anchor_rect_ != selection_focus_rect_) {
56c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if (touch_selection_controller_)
57c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      touch_selection_controller_->SelectionChanged();
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  } else {
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    EndTouchEditing(false);
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
6358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TouchEditableImplAura::OverscrollStarted() {
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scrolls_in_progress_++;
6558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
6658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
6758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)void TouchEditableImplAura::OverscrollCompleted() {
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ScrollEnded();
6958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)}
7058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
71c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TouchEditableImplAura, RenderWidgetHostViewAura::TouchEditingClient
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// implementation:
74c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
75c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::StartTouchEditing() {
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (!rwhva_ || !rwhva_->HasFocus())
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    return;
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
79c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!touch_selection_controller_) {
80c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    touch_selection_controller_.reset(
81c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ui::TouchSelectionController::create(this));
82c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
83c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (touch_selection_controller_)
84c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    touch_selection_controller_->SelectionChanged();
85c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
86c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void TouchEditableImplAura::EndTouchEditing(bool quick) {
88c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (touch_selection_controller_) {
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (touch_selection_controller_->IsHandleDragInProgress()) {
90c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      touch_selection_controller_->SelectionChanged();
915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    } else {
92cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      selection_gesture_in_process_ = false;
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      touch_selection_controller_->HideHandles(quick);
94c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      touch_selection_controller_.reset();
955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
96c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
97c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
98c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
99c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::OnSelectionOrCursorChanged(const gfx::Rect& anchor,
100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                       const gfx::Rect& focus) {
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  selection_anchor_rect_ = anchor;
102c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  selection_focus_rect_ = focus;
1030529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If touch editing handles were not visible, we bring them up only if the
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // current event is a gesture event, no scroll/fling/overscoll is in progress,
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // and there is non-zero selection on the page
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (selection_gesture_in_process_ && !scrolls_in_progress_ &&
1080529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      selection_anchor_rect_ != selection_focus_rect_) {
1090529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    StartTouchEditing();
1100529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    selection_gesture_in_process_ = false;
1110529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  }
1120529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  UpdateEditingController();
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::OnTextInputTypeChanged(ui::TextInputType type) {
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  text_input_type_ = type;
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool TouchEditableImplAura::HandleInputEvent(const ui::Event* event) {
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(rwhva_);
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!event->IsGestureEvent()) {
123cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // Ignore all non-gesture events. Non-gesture events that can deactivate
124cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    // touch editing are handled in TouchSelectionControllerImpl.
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ui::GestureEvent* gesture_event =
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      static_cast<const ui::GestureEvent*>(event);
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (event->type()) {
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case ui::ET_GESTURE_TAP:
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // When the user taps, we want to show touch editing handles if user
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      // tapped on selected text.
134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      if (gesture_event->details().tap_count() == 1 &&
135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          selection_anchor_rect_ != selection_focus_rect_) {
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        // UnionRects only works for rects with non-zero width.
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        gfx::Rect anchor(selection_anchor_rect_.origin(),
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                         gfx::Size(1, selection_anchor_rect_.height()));
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        gfx::Rect focus(selection_focus_rect_.origin(),
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                        gfx::Size(1, selection_focus_rect_.height()));
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        gfx::Rect selection_rect = gfx::UnionRects(anchor, focus);
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if (selection_rect.Contains(gesture_event->location())) {
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          StartTouchEditing();
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          return true;
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        }
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // For single taps, not inside selected region, we want to show handles
1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      // only when the tap is on an already focused textfield.
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      textfield_was_focused_on_tap_ =
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          gesture_event->details().tap_count() == 1 &&
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          text_input_type_ != ui::TEXT_INPUT_TYPE_NONE;
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case ui::ET_GESTURE_LONG_PRESS:
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      selection_gesture_in_process_ = true;
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
1567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case ui::ET_GESTURE_SCROLL_BEGIN:
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scrolls_in_progress_++;
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // We need to hide selection handles during scroll (including fling and
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // overscroll), but they should be re-activated after scrolling if:
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      //  - an existing scroll decided that handles should be shown after
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      //    scrolling; or
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      //  - the gesture in progress is going to end in selection; or
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      //  - selection handles are currently active.
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      handles_hidden_due_to_scroll_ = handles_hidden_due_to_scroll_ ||
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      selection_gesture_in_process_ ||
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                      touch_selection_controller_ != NULL;
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      selection_gesture_in_process_ = false;
1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      EndTouchEditing(true);
1697d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
1707d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    case ui::ET_GESTURE_SCROLL_END:
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ScrollEnded();
1727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      break;
173c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
174c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
175c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
176c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
177c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
178c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
179c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::GestureEventAck(int gesture_event_type) {
180c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  DCHECK(rwhva_);
181f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (gesture_event_type == blink::WebInputEvent::GestureTap &&
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      text_input_type_ != ui::TEXT_INPUT_TYPE_NONE &&
1830529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      textfield_was_focused_on_tap_) {
184c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    StartTouchEditing();
1850529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch    UpdateEditingController();
186a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch  }
187c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
188c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid TouchEditableImplAura::DidStopFlinging() {
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ScrollEnded();
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
193c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::OnViewDestroyed() {
194c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Cleanup();
195c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TouchEditableImplAura, ui::TouchEditable implementation:
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::SelectRect(const gfx::Point& start,
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                       const gfx::Point& end) {
202c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RenderWidgetHost* host = rwhva_->GetRenderWidgetHost();
203c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RenderViewHost* rvh = RenderViewHost::From(host);
204c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  WebContentsImpl* wc =
205c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      static_cast<WebContentsImpl*>(WebContents::FromRenderViewHost(rvh));
206c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  wc->SelectRange(start, end);
207c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
208c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
209c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::MoveCaretTo(const gfx::Point& point) {
210c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!rwhva_)
211c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
212c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
213c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RenderWidgetHostImpl* host = RenderWidgetHostImpl::From(
214c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      rwhva_->GetRenderWidgetHost());
215c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  host->MoveCaret(point);
216c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
217c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
218c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::GetSelectionEndPoints(gfx::Rect* p1,
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                                  gfx::Rect* p2) {
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *p1 = selection_anchor_rect_;
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  *p2 = selection_focus_rect_;
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
223c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
224c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)gfx::Rect TouchEditableImplAura::GetBounds() {
2255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return rwhva_ ? gfx::Rect(rwhva_->GetNativeView()->bounds().size()) :
2265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      gfx::Rect();
227c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
228c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)gfx::NativeView TouchEditableImplAura::GetNativeView() const {
230a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  return rwhva_ ? rwhva_->GetNativeView()->GetToplevelWindow() : NULL;
231c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
232c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
233c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::ConvertPointToScreen(gfx::Point* point) {
234c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!rwhva_)
235c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
236c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* window = rwhva_->GetNativeView();
237c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::client::ScreenPositionClient* screen_position_client =
238c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      aura::client::GetScreenPositionClient(window->GetRootWindow());
239c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (screen_position_client)
240c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screen_position_client->ConvertPointToScreen(window, point);
241c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
242c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
243c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::ConvertPointFromScreen(gfx::Point* point) {
244c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!rwhva_)
245c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
246c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::Window* window = rwhva_->GetNativeView();
247c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  aura::client::ScreenPositionClient* screen_position_client =
248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      aura::client::GetScreenPositionClient(window->GetRootWindow());
249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (screen_position_client)
250c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    screen_position_client->ConvertPointFromScreen(window, point);
251c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
253c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool TouchEditableImplAura::DrawsHandles() {
254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
255c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
256c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
2577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void TouchEditableImplAura::OpenContextMenu(const gfx::Point& anchor) {
258c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!rwhva_)
259c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return;
2607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  gfx::Point point = anchor;
2617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ConvertPointFromScreen(&point);
262c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  RenderWidgetHost* host = rwhva_->GetRenderWidgetHost();
2635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  host->Send(new ViewMsg_ShowContextMenu(
2645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      host->GetRoutingID(), ui::MENU_SOURCE_TOUCH_EDIT_MENU, point));
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EndTouchEditing(false);
266c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
268c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool TouchEditableImplAura::IsCommandIdChecked(int command_id) const {
269c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  NOTREACHED();
270c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
271c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
272c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
273c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool TouchEditableImplAura::IsCommandIdEnabled(int command_id) const {
274c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!rwhva_)
275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return false;
276c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool editable = rwhva_->GetTextInputType() != ui::TEXT_INPUT_TYPE_NONE;
277116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  bool readable = rwhva_->GetTextInputType() != ui::TEXT_INPUT_TYPE_PASSWORD;
27858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  gfx::Range selection_range;
279c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  rwhva_->GetSelectionRange(&selection_range);
280c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  bool has_selection = !selection_range.is_empty();
281c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (command_id) {
282c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_CUT:
283116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return editable && readable && has_selection;
284c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_COPY:
285116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return readable && has_selection;
286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_PASTE: {
287a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      base::string16 result;
288c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      ui::Clipboard::GetForCurrentThread()->ReadText(
2894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)          ui::CLIPBOARD_TYPE_COPY_PASTE, &result);
290c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return editable && !result.empty();
291c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
292c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_DELETE:
293c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return editable && has_selection;
294c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_SELECT_ALL:
295c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return true;
296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      return false;
298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
299c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
300c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
301c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)bool TouchEditableImplAura::GetAcceleratorForCommandId(
302c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    int command_id,
303c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    ui::Accelerator* accelerator) {
304c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return false;
305c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
306c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
307c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::ExecuteCommand(int command_id, int event_flags) {
308c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RenderWidgetHost* host = rwhva_->GetRenderWidgetHost();
309c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  RenderViewHost* rvh = RenderViewHost::From(host);
310c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  WebContents* wc = WebContents::FromRenderViewHost(rvh);
311c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
312c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  switch (command_id) {
313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_CUT:
314c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      wc->Cut();
315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_COPY:
317c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      wc->Copy();
318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_PASTE:
320c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      wc->Paste();
321c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_DELETE:
323c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      wc->Delete();
324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    case IDS_APP_SELECT_ALL:
326c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      wc->SelectAll();
327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    default:
329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      NOTREACHED();
330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      break;
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EndTouchEditing(false);
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
335010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void TouchEditableImplAura::DestroyTouchSelection() {
336010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  EndTouchEditing(false);
337010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
338010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// TouchEditableImplAura, private:
341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TouchEditableImplAura::TouchEditableImplAura()
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    : text_input_type_(ui::TEXT_INPUT_TYPE_NONE),
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      rwhva_(NULL),
3457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)      selection_gesture_in_process_(false),
346a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch      handles_hidden_due_to_scroll_(false),
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scrolls_in_progress_(0),
3480529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch      textfield_was_focused_on_tap_(false) {
349c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
350c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid TouchEditableImplAura::ScrollEnded() {
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scrolls_in_progress_--;
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If there is no scrolling left in progress, show selection handles if they
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // were hidden due to scroll and there is a selection.
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!scrolls_in_progress_ && handles_hidden_due_to_scroll_ &&
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      (selection_anchor_rect_ != selection_focus_rect_ ||
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          text_input_type_ != ui::TEXT_INPUT_TYPE_NONE)) {
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    StartTouchEditing();
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    UpdateEditingController();
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    handles_hidden_due_to_scroll_ = false;
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
364c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)void TouchEditableImplAura::Cleanup() {
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (rwhva_) {
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rwhva_->set_touch_editing_client(NULL);
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    rwhva_ = NULL;
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
36958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  text_input_type_ = ui::TEXT_INPUT_TYPE_NONE;
3705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  EndTouchEditing(true);
3710529e5d033099cbfc42635f6f6183833b09dff6eBen Murdoch  selection_gesture_in_process_ = false;
37258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  handles_hidden_due_to_scroll_ = false;
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scrolls_in_progress_ = 0;
374c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
375c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}  // namespace content
377