blob: 1232aa0fe635f6bb3e19861e0bee8a80da9ba358 [file] [log] [blame]
ekaramadadd882292016-06-08 15:22:561// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_MANAGER_H__
6#define CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_MANAGER_H__
7
8#include <unordered_map>
ekaramadfcce0882016-07-07 02:44:519#include <utility>
ekaramadadd882292016-06-08 15:22:5610
11#include "base/observer_list.h"
ekaramad6f1786b2016-07-21 21:10:5812#include "base/strings/string16.h"
ekaramadadd882292016-06-08 15:22:5613#include "content/common/content_export.h"
14#include "content/common/text_input_state.h"
ekaramadfcce0882016-07-07 02:44:5115#include "ui/gfx/geometry/rect.h"
ekaramad6f1786b2016-07-21 21:10:5816#include "ui/gfx/range/range.h"
ekaramadfcce0882016-07-07 02:44:5117#include "ui/gfx/selection_bound.h"
18
19struct ViewHostMsg_SelectionBounds_Params;
ekaramadadd882292016-06-08 15:22:5620
ekaramadadd882292016-06-08 15:22:5621namespace content {
ekaramadb8e23a96c2016-07-13 01:21:1522
ekaramad8cba78862016-06-24 19:42:3123class RenderWidgetHostImpl;
ekaramadadd882292016-06-08 15:22:5624class RenderWidgetHostView;
25class RenderWidgetHostViewBase;
26class WebContents;
27
28// A class which receives updates of TextInputState from multiple sources and
29// decides what the new TextInputState is. It also notifies the observers when
30// text input state is updated.
31class CONTENT_EXPORT TextInputManager {
32 public:
33 // The tab's top-level RWHV should be an observer of TextInputManager to get
34 // notifications about changes in TextInputState or other IME related state
35 // for child frames.
36 class CONTENT_EXPORT Observer {
37 public:
38 // Called when a view has called UpdateTextInputState on TextInputManager.
39 // If the call has led to a change in TextInputState, |did_update_state| is
40 // true. In some plaforms, we need this update even when the state has not
41 // changed (e.g., Aura for updating IME).
42 virtual void OnUpdateTextInputStateCalled(
43 TextInputManager* text_input_manager,
44 RenderWidgetHostViewBase* updated_view,
45 bool did_update_state) {}
ekaramad50ee2032016-06-29 02:18:2546 // Called when |updated_view| has called ImeCancelComposition on
47 // TextInputManager.
48 virtual void OnImeCancelComposition(
49 TextInputManager* text_input_manager,
50 RenderWidgetHostViewBase* updated_view) {}
ekaramadb8e23a96c2016-07-13 01:21:1551 // Called when |updated_view| has changed its SelectionRegion.
ekaramadfcce0882016-07-07 02:44:5152 virtual void OnSelectionBoundsChanged(
53 TextInputManager* text_input_manager,
54 RenderWidgetHostViewBase* updated_view) {}
ekaramadb8e23a96c2016-07-13 01:21:1555 // Called when |updated_view| has changed its CompositionRangeInfo.
56 virtual void OnImeCompositionRangeChanged(
57 TextInputManager* text_input_manager,
58 RenderWidgetHostViewBase* updated_view) {}
ekaramad6f1786b2016-07-21 21:10:5859 // Called when the text selection for the |updated_view_| has changed.
60 virtual void OnTextSelectionChanged(
61 TextInputManager* text_input_manager,
62 RenderWidgetHostViewBase* updated_view) {}
63 };
64
ekaramad2f520092016-08-22 23:10:2465 // Text selection bounds.
66 struct SelectionRegion {
67 SelectionRegion();
68 SelectionRegion(const SelectionRegion& other);
69
70 // The following variables are only used on Aura platforms.
71 // The begining of the selection region.
72 gfx::SelectionBound anchor;
73 // The end of the selection region (caret position).
74 gfx::SelectionBound focus;
75
76 // The following variables are only used on Mac platform.
77 // The current caret bounds.
78 gfx::Rect caret_rect;
79 // The current first selection bounds.
80 gfx::Rect first_selection_rect;
81 };
82
83 // Composition range information.
84 struct CompositionRangeInfo {
85 CompositionRangeInfo();
86 CompositionRangeInfo(const CompositionRangeInfo& other);
87 ~CompositionRangeInfo();
88
89 std::vector<gfx::Rect> character_bounds;
90 gfx::Range range;
91 };
92
ekaramad6f1786b2016-07-21 21:10:5893 // This struct is used to store text selection related information for views.
94 struct TextSelection {
95 TextSelection();
96 TextSelection(const TextSelection& other);
97 ~TextSelection();
98
ekaramad65cf5592016-08-18 21:44:5399 // If text selection is valid, |text| will be populated with the selected
100 // text and the method will return true. Otherwise, it will return false.
101 bool GetSelectedText(base::string16* text) const;
102
ekaramad6f1786b2016-07-21 21:10:58103 // The offset of the text stored in |text| relative to the start of the web
104 // page.
105 size_t offset;
106
107 // The current selection range relative to the start of the web page.
108 gfx::Range range;
109
110 // The text inside and around the current selection range.
111 base::string16 text;
ekaramadadd882292016-06-08 15:22:56112 };
113
ekaramadadd882292016-06-08 15:22:56114 TextInputManager();
115 ~TextInputManager();
116
ekaramad8cba78862016-06-24 19:42:31117 // Returns the currently active widget, i.e., the RWH which is associated with
118 // |active_view_|.
119 RenderWidgetHostImpl* GetActiveWidget() const;
ekaramadadd882292016-06-08 15:22:56120
ekaramadb8e23a96c2016-07-13 01:21:15121 // ---------------------------------------------------------------------------
122 // The following methods can be used to obtain information about IME-related
123 // state for the active RenderWidgetHost. If the active widget is nullptr, the
124 // methods below will return nullptr as well.
125 // Users of these methods should not hold on to the pointers as they become
126 // dangling if the TextInputManager or |active_view_| are destroyed.
127
128 // Returns the currently stored TextInputState. An state of nullptr can be
129 // interpreted as a ui::TextInputType of ui::TEXT_INPUT_TYPE_NONE.
ekaramad4cfc03e2016-07-21 17:34:21130 const TextInputState* GetTextInputState() const;
ekaramadadd882292016-06-08 15:22:56131
ekaramad2f520092016-08-22 23:10:24132 // Returns the selection bounds information for |view|. If |view| == nullptr,
133 // it will return the corresponding information for |active_view_| or nullptr
134 // if there are no active views.
135 const SelectionRegion* GetSelectionRegion(
136 RenderWidgetHostViewBase* view = nullptr) const;
ekaramadfcce0882016-07-07 02:44:51137
ekaramadd773ff42016-08-12 19:30:40138 // Returns the composition range and character bounds information for the
139 // |view|. If |view| == nullptr, it will assume |active_view_| and return its
140 // state. If |active_view_| == nullptr, this method will return nullptr.
141 const TextInputManager::CompositionRangeInfo* GetCompositionRangeInfo(
142 RenderWidgetHostViewBase* view = nullptr) const;
ekaramadb8e23a96c2016-07-13 01:21:15143
ekaramad6f1786b2016-07-21 21:10:58144 // The following method returns the text selection state for the given |view|.
145 // If |view| == nullptr, it will assume |active_view_| and return its state.
146 // In the case of |active_view_| == nullptr, the method will return nullptr.
147 const TextSelection* GetTextSelection(
148 RenderWidgetHostViewBase* view = nullptr) const;
149
ekaramad8cba78862016-06-24 19:42:31150 // ---------------------------------------------------------------------------
151 // The following methods are called by RWHVs on the tab to update their IME-
152 // related state.
153
ekaramadadd882292016-06-08 15:22:56154 // Updates the TextInputState for |view|.
155 void UpdateTextInputState(RenderWidgetHostViewBase* view,
156 const TextInputState& state);
157
ekaramad50ee2032016-06-29 02:18:25158 // The current IME composition has been cancelled on the renderer side for
159 // the widget corresponding to |view|.
160 void ImeCancelComposition(RenderWidgetHostViewBase* view);
161
ekaramadfcce0882016-07-07 02:44:51162 // Updates the selection bounds for the |view|. In Aura, selection bounds are
163 // used to provide the InputMethod with the position of the caret, e.g., in
164 // setting the position of the ui::ImeWindow.
165 void SelectionBoundsChanged(RenderWidgetHostViewBase* view,
166 const ViewHostMsg_SelectionBounds_Params& params);
167
ekaramadb8e23a96c2016-07-13 01:21:15168 // Called when the composition range and/or character bounds have changed.
169 void ImeCompositionRangeChanged(
170 RenderWidgetHostViewBase* view,
171 const gfx::Range& range,
172 const std::vector<gfx::Rect>& character_bounds);
173
ekaramad6f1786b2016-07-21 21:10:58174 // Updates the new text selection information for the |view|.
175 void SelectionChanged(RenderWidgetHostViewBase* view,
176 const base::string16& text,
177 size_t offset,
178 const gfx::Range& range);
179
ekaramadadd882292016-06-08 15:22:56180 // Registers the given |view| for tracking its TextInputState. This is called
181 // by any view which has updates in its TextInputState (whether tab's RWHV or
182 // that of a child frame). The |view| must unregister itself before being
183 // destroyed (i.e., call TextInputManager::Unregister).
184 void Register(RenderWidgetHostViewBase* view);
185
186 // Clears the TextInputState from the |view|. If |view == active_view_|, this
187 // call will lead to a TextInputState update since the TextInputState.type
188 // should be reset to none.
189 void Unregister(RenderWidgetHostViewBase* view);
190
191 // Returns true if |view| is already registered.
192 bool IsRegistered(RenderWidgetHostViewBase* view) const;
193
194 // Add and remove observers for notifications regarding updates in the
195 // TextInputState. Clients must be sure to remove themselves before they go
196 // away.
197 // Only the tab's RWHV should observer TextInputManager. In tests, however,
198 // in addition to the tab's RWHV, one or more test observers might observe
199 // TextInputManager.
200 void AddObserver(Observer* observer);
201 void RemoveObserver(Observer* observer);
ekaramadfd5f5a892016-08-12 04:33:10202 bool HasObserver(Observer* observer) const;
ekaramadadd882292016-06-08 15:22:56203
ekaramad8cba78862016-06-24 19:42:31204 RenderWidgetHostViewBase* active_view_for_testing() { return active_view_; }
ekaramad936536d2016-06-29 05:44:44205 size_t GetRegisteredViewsCountForTesting();
206 ui::TextInputType GetTextInputTypeForViewForTesting(
207 RenderWidgetHostViewBase* view);
ekaramad8cba78862016-06-24 19:42:31208
ekaramadadd882292016-06-08 15:22:56209 private:
ekaramadfcce0882016-07-07 02:44:51210 // This class is used to create maps which hold specific IME state for a
211 // view.
212 template <class Value>
213 class ViewMap : public std::unordered_map<RenderWidgetHostViewBase*, Value> {
214 };
215
ekaramadadd882292016-06-08 15:22:56216 void NotifyObserversAboutInputStateUpdate(RenderWidgetHostViewBase* view,
217 bool did_update_state);
218
ekaramad8cba78862016-06-24 19:42:31219 // The view with active text input state, i.e., a focused <input> element.
220 // It will be nullptr if no such view exists. Note that the active view
221 // cannot have a |TextInputState.type| of ui::TEXT_INPUT_TYPE_NONE.
ekaramadadd882292016-06-08 15:22:56222 RenderWidgetHostViewBase* active_view_;
223
ekaramad4cfc03e2016-07-21 17:34:21224 // The following maps track corresponding IME state for views. For each view,
225 // the values in the map are initialized and cleared in Register and
226 // Unregister methods, respectively.
ekaramadfcce0882016-07-07 02:44:51227 ViewMap<TextInputState> text_input_state_map_;
ekaramadfcce0882016-07-07 02:44:51228 ViewMap<SelectionRegion> selection_region_map_;
ekaramadb8e23a96c2016-07-13 01:21:15229 ViewMap<CompositionRangeInfo> composition_range_info_map_;
ekaramad6f1786b2016-07-21 21:10:58230 ViewMap<TextSelection> text_selection_map_;
ekaramadadd882292016-06-08 15:22:56231
232 base::ObserverList<Observer> observer_list_;
233
234 DISALLOW_COPY_AND_ASSIGN(TextInputManager);
235};
236}
237
ekaramadb8e23a96c2016-07-13 01:21:15238#endif // CONTENT_BROWSER_RENDERER_HOST_TEXT_INPUT_MANAGER_H__