OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_ | 5 #ifndef CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_ |
6 #define CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_ | 6 #define CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_ |
7 | 7 |
8 #include <map> | |
9 #include <queue> | |
8 #include <set> | 10 #include <set> |
11 #include <utility> | |
9 #include <vector> | 12 #include <vector> |
10 | 13 |
14 #include "content/common/content_export.h" | |
15 #include "content/public/browser/web_contents_observer.h" | |
11 #include "content/public/common/stop_find_action.h" | 16 #include "content/public/common/stop_find_action.h" |
12 #include "third_party/WebKit/public/web/WebFindOptions.h" | 17 #include "third_party/WebKit/public/web/WebFindOptions.h" |
13 #include "ui/gfx/geometry/rect.h" | 18 #include "ui/gfx/geometry/rect.h" |
14 #include "ui/gfx/geometry/rect_f.h" | 19 #include "ui/gfx/geometry/rect_f.h" |
15 | 20 |
16 namespace content { | 21 namespace content { |
ncarter (slow)
2016/05/23 21:59:17
I patched this in. It works great and it handled e
paulmeyer
2016/05/30 15:08:23
Thanks!
| |
17 | 22 |
18 class RenderFrameHost; | 23 class RenderFrameHost; |
19 class WebContentsImpl; | 24 class WebContentsImpl; |
20 | 25 |
21 // FindRequestManager manages all of the find-in-page requests/replies | 26 // FindRequestManager manages all of the find-in-page requests/replies |
22 // initiated/received through a WebContents. It coordinates searching across | 27 // initiated/received through a WebContents. It coordinates searching across |
23 // multiple (potentially out-of-process) frames, handles the aggregation of find | 28 // multiple (potentially out-of-process) frames, handles the aggregation of find |
24 // results from each frame, and facilitates active match traversal. It is | 29 // results from each frame, and facilitates active match traversal. It is |
25 // instantiated once per WebContents, and is owned by that WebContents. | 30 // instantiated once per WebContents, and is owned by that WebContents. |
26 // | 31 class CONTENT_EXPORT FindRequestManager : public WebContentsObserver { |
27 // TODO(paulmeyer): FindRequestManager is currently incomplete and does not do | |
28 // all of these things yet, but will soon. | |
29 class FindRequestManager { | |
30 public: | 32 public: |
33 // Frames can be uniquely identified by a (process ID, frame ID) pair. | |
34 using FrameKey = std::pair<int, int>; | |
ncarter (slow)
2016/05/23 21:59:17
Some places have started to use content/browser/lo
paulmeyer
2016/05/30 15:08:23
I'm usually wary of holding onto pointers, but sin
| |
35 | |
31 explicit FindRequestManager(WebContentsImpl* web_contents); | 36 explicit FindRequestManager(WebContentsImpl* web_contents); |
32 ~FindRequestManager(); | 37 ~FindRequestManager() override; |
33 | 38 |
34 // Initiates a find operation for |search_text| with the options specified in | 39 // Initiates a find operation for |search_text| with the options specified in |
35 // |options|. |request_id| uniquely identifies the find request. | 40 // |options|. |request_id| uniquely identifies the find request. |
36 void Find(int request_id, | 41 void Find(int request_id, |
37 const base::string16& search_text, | 42 const base::string16& search_text, |
38 const blink::WebFindOptions& options); | 43 const blink::WebFindOptions& options); |
39 | 44 |
40 // Stops the active find session and clears the general highlighting of the | 45 // Stops the active find session and clears the general highlighting of the |
41 // matches. |action| determines whether the last active match (if any) will be | 46 // matches. |action| determines whether the last active match (if any) will be |
42 // activated, cleared, or remain highlighted. | 47 // activated, cleared, or remain highlighted. |
43 void StopFinding(StopFindAction action); | 48 void StopFinding(StopFindAction action); |
44 | 49 |
45 // Called when a reply is received from a frame with the results from a | 50 // Called when a reply is received from a frame with the results from a |
46 // find request. | 51 // find request. |
47 void OnFindReply(RenderFrameHost* rfh, | 52 void OnFindReply(RenderFrameHost* rfh, |
48 int request_id, | 53 int request_id, |
49 int number_of_matches, | 54 int number_of_matches, |
50 const gfx::Rect& selection_rect, | 55 const gfx::Rect& selection_rect, |
51 int active_match_ordinal, | 56 int active_match_ordinal, |
52 bool final_update); | 57 bool final_update); |
53 | 58 |
59 // Removes a frame from the set of frames being searched. This should be | |
60 // called whenever a frame is discovered to no longer exist. | |
61 void RemoveFrame(RenderFrameHost* rfh); | |
62 void RemoveFrame(const FrameKey& frame_key); | |
63 | |
54 #if defined(OS_ANDROID) | 64 #if defined(OS_ANDROID) |
55 // Selects and zooms to the find result nearest to the point (x,y) defined in | 65 // Selects and zooms to the find result nearest to the point (x,y) defined in |
56 // find-in-page coordinates. | 66 // find-in-page coordinates. |
57 void ActivateNearestFindResult(float x, float y); | 67 void ActivateNearestFindResult(float x, float y); |
58 | 68 |
69 // Called when a reply is received from a frame in response to the | |
70 // GetNearestFindResult IPC. | |
71 void GetNearestFindResultReply(RenderFrameHost* rfh, | |
72 int nearest_find_result_request_id, | |
73 float distance); | |
74 | |
59 // Requests the rects of the current find matches from the renderer process. | 75 // Requests the rects of the current find matches from the renderer process. |
60 void RequestFindMatchRects(int current_version); | 76 void RequestFindMatchRects(int current_version); |
61 | 77 |
62 // Called when a reply is received in response to a request for find match | 78 // Called when a reply is received from a frame in response to a request for |
63 // rects. | 79 // find match rects. |
64 void OnFindMatchRectsReply(RenderFrameHost* rfh, | 80 void OnFindMatchRectsReply(RenderFrameHost* rfh, |
65 int version, | 81 int version, |
66 const std::vector<gfx::RectF>& rects, | 82 const std::vector<gfx::RectF>& rects, |
67 const gfx::RectF& active_rect); | 83 const gfx::RectF& active_rect); |
68 #endif | 84 #endif |
69 | 85 |
70 private: | 86 private: |
71 // An invalid ID. This value is invalid for any render process ID, render | 87 // An invalid ID. This value is invalid for any render process ID, render |
72 // frame ID, or find request ID. | 88 // frame ID, or find request ID. |
73 static const int kInvalidId; | 89 static const int kInvalidId; |
74 | 90 |
75 // The request data for a single find request. | 91 // The request data for a single find request. |
76 struct FindRequest { | 92 struct FindRequest { |
77 // The find request ID that uniquely identifies this find request. | 93 // The find request ID that uniquely identifies this find request. |
78 int id = kInvalidId; | 94 int id = kInvalidId; |
79 | 95 |
80 // The text that is being searched for in this find request. | 96 // The text that is being searched for in this find request. |
81 base::string16 search_text; | 97 base::string16 search_text; |
82 | 98 |
83 // The set of find options in effect for this find request. | 99 // The set of find options in effect for this find request. |
84 blink::WebFindOptions options; | 100 blink::WebFindOptions options; |
85 | 101 |
86 FindRequest() = default; | 102 FindRequest() = default; |
87 FindRequest(int id, | 103 FindRequest(int id, |
88 const base::string16& search_text, | 104 const base::string16& search_text, |
89 const blink::WebFindOptions& options) | 105 const blink::WebFindOptions& options) |
90 : id(id), search_text(search_text), options(options) {} | 106 : id(id), search_text(search_text), options(options) {} |
91 }; | 107 }; |
92 | 108 |
93 // Send a find IPC containing the find request |request| to the RenderFrame | 109 // WebContentsObserver implementation. |
110 void RenderFrameDeleted(RenderFrameHost* rfh) override; | |
111 void FrameDeleted(RenderFrameHost* rfh) override; | |
112 | |
113 // Resets all of the per-session state for a new find-in-page session. | |
114 void Reset(const FindRequest& initial_request); | |
115 | |
116 // Called internally as find requests come up in the queue. | |
117 void FindInternal(const FindRequest& request); | |
118 | |
119 // Called when an informative response (a response with enough information to | |
120 // be able to route subsequent find requests) comes in for the find request | |
121 // with ID |request_id|. Advances the queue if appropriate. | |
122 void AdvanceQueue(int request_id); | |
123 | |
124 // Sends a find IPC containing the find request |request| to the RenderFrame | |
94 // associated with |rfh|. | 125 // associated with |rfh|. |
95 void SendFindIPC(const FindRequest& request, RenderFrameHost* rfh); | 126 void SendFindIPC(const FindRequest& request, RenderFrameHost* rfh); |
96 | 127 |
97 // Send a stop finding IPC to the RenderFrame associated with |rfh|. | 128 // Sends a stop finding IPC to the RenderFrame associated with |rfh|. |
98 void SendStopFindingIPC(StopFindAction action, RenderFrameHost* rfh) const; | 129 void SendStopFindingIPC(StopFindAction action, RenderFrameHost* rfh) const; |
99 | 130 |
100 // Reset all of the per-session state for a new find-in-page session. | 131 // Sends the find results (as they currently are) to the WebContents. |
101 void Reset(const FindRequest& initial_request); | |
102 | |
103 // Send the find results (as they currently are) to the WebContents. | |
104 void NotifyFindReply(int request_id, bool final_update) const; | 132 void NotifyFindReply(int request_id, bool final_update) const; |
105 | 133 |
134 // Returns the initial frame in search order. This will be either the first | |
135 // frame, if searching forward, or the last frame, if searching backward. | |
136 RenderFrameHost* GetInitialFrame(bool forward) const; | |
137 | |
138 // Traverses the frame tree to find and return the next RenderFrameHost after | |
139 // |rfh| in search order. |forward| indicates whether the frame tree should be | |
140 // traversed forward (if true) or backward (if false). If |matches_only| is | |
141 // set, then the frame tree will be traversed until the first frame is found | |
142 // for which matches have been found. If |wrap| is set, then the traversal can | |
143 // wrap around past the last frame to the first one (or vice-versa, if | |
144 // |forward| == false). If no frame can be found under these conditions, | |
145 // nullptr is returned. | |
146 RenderFrameHost* Traverse(RenderFrameHost* rfh, | |
147 bool forward, | |
148 bool matches_only, | |
149 bool wrap) const; | |
150 | |
151 // Adds a frame to the set of frames that are being searched. The new frame | |
152 // will automatically be searched when added, using the same options (stored | |
153 // in |current_request_.options|). | |
154 void AddFrame(RenderFrameHost* rfh); | |
155 | |
156 // Returns whether the frame associated with |rfh| is in the set of frames | |
157 // being searched in the current find session. | |
158 bool CheckFrame(RenderFrameHost* rfh) const; | |
159 bool CheckFrame(const FrameKey& frame_key) const; | |
160 | |
161 // Computes and updates |active_match_ordinal_| based on | |
162 // |relative_active_match_ordinal_|. | |
163 void UpdateActiveMatchOrdinal(); | |
164 | |
165 // Called when all pending find replies have been received. | |
166 void FinalUpdate(int request_id, RenderFrameHost* rfh); | |
167 | |
106 #if defined(OS_ANDROID) | 168 #if defined(OS_ANDROID) |
107 // Request the latest find match rects from a frame. | 169 // Requests the distance to the nearest find result in the frame associated |
170 // with |rfh| from the point (x,y) defined in find-in-page coordinates. | |
171 void SendGetNearestFindResultIPC(RenderFrameHost* rfh); | |
172 | |
173 // Called when a nearest find result reply is no longer pending for a frame. | |
174 void RemoveNearestFindResultPendingReply(FrameKey frame_key); | |
175 | |
176 // Requests the latest find match rects from a frame. | |
108 void SendFindMatchRectsIPC(RenderFrameHost* rfh); | 177 void SendFindMatchRectsIPC(RenderFrameHost* rfh); |
109 | 178 |
179 // Called when a find match rects reply is no longer pending for a frame. | |
180 void RemoveFindMatchRectsPendingReply(FrameKey frame_key); | |
181 | |
182 // State related to ActivateNearestFindResult requests. | |
183 struct ActivateNearestFindResultState { | |
184 // An ID to uniquely identify the current nearest find result request and | |
185 // its replies. | |
186 int current_request_id = kInvalidId; | |
187 | |
188 // The x value of the requested point, in find-in-page coordinates. | |
189 float x = 0.0f; | |
190 | |
191 // The y value of the requested point, in find-in-page coordinates. | |
192 float y = 0.0f; | |
193 | |
194 // The distance to the nearest result found so far. | |
195 float nearest_distance = FLT_MAX; | |
196 | |
197 // The frame containing the nearest result found so far. | |
198 FrameKey nearest_frame = std::make_pair(kInvalidId, kInvalidId); | |
199 | |
200 // Nearest find result replies are still pending for these frames. | |
201 std::set<FrameKey> pending_replies; | |
202 | |
203 ActivateNearestFindResultState(); | |
204 ActivateNearestFindResultState(float x, float y); | |
205 ~ActivateNearestFindResultState(); | |
206 | |
207 static int GetNextID() { | |
208 static int next_id = 0; | |
209 return next_id++; | |
210 } | |
211 } activate_; | |
212 | |
110 // State related to FindMatchRects requests. | 213 // State related to FindMatchRects requests. |
111 struct FindMatchRectsState { | 214 struct FindMatchRectsState { |
112 // The latest find match rects version known by the requester. | 215 // The latest find match rects version known by the requester. This will be |
216 // compared to |known_version_| after polling frames for updates to their | |
217 // match rects, in order to determine if the requester already has the | |
218 // latest version of rects or not. | |
113 int request_version = kInvalidId; | 219 int request_version = kInvalidId; |
220 | |
221 // The current overall find match rects version known by FindRequestManager. | |
222 int known_version = 0; | |
223 | |
224 // A map from each frame to its find match rects and the version number for | |
225 // those rects. | |
226 using RectData = std::pair<int, std::vector<gfx::RectF>>; | |
ncarter (slow)
2016/05/23 21:59:16
Sometimes we need a pair as a key for a data struc
paulmeyer
2016/05/30 15:08:23
Done.
| |
227 std::map<FrameKey, RectData> rects; | |
228 | |
229 // The active find match rect. | |
230 gfx::RectF active_rect; | |
231 | |
232 // Find match rects replies are still pending for these frames. | |
233 std::set<FrameKey> pending_replies; | |
234 | |
235 FindMatchRectsState(); | |
236 ~FindMatchRectsState(); | |
114 } match_rects_; | 237 } match_rects_; |
115 #endif | 238 #endif |
116 | 239 |
117 // The WebContents that owns this FindRequestManager. | 240 // The WebContents that owns this FindRequestManager. |
118 WebContentsImpl* const contents_; | 241 WebContentsImpl* const contents_; |
119 | 242 |
120 // The request ID of the initial find request in the current find-in-page | 243 // The request ID of the initial find request in the current find-in-page |
121 // session, which uniquely identifies this session. Request IDs are included | 244 // session, which uniquely identifies this session. Request IDs are included |
122 // in all find-related IPCs, which allows reply IPCs containing results from | 245 // in all find-related IPCs, which allows reply IPCs containing results from |
123 // previous sessions (with |request_id| < |current_session_id_|) to be easily | 246 // previous sessions (with |request_id| < |current_session_id_|) to be easily |
124 // identified and ignored. | 247 // identified and ignored. |
125 int current_session_id_; | 248 int current_session_id_; |
126 | 249 |
127 // The current find request. | 250 // The current find request. |
128 FindRequest current_request_; | 251 FindRequest current_request_; |
129 | 252 |
130 // The total number of matches found in the current find-in-page session. | 253 // The set of frames that are still expected to reply to a pending find |
254 // request. Frames are removed from |pending_replies_| when their reply with | |
255 // |final_update| set to true is received. | |
256 std::set<FrameKey> pending_replies_; | |
ncarter (slow)
2016/05/23 21:59:17
Consider making this a std::unordered_set.
paulmeyer
2016/05/30 15:08:23
Done.
| |
257 | |
258 // Indicates whether an update to the active match ordinal is expected. The | |
259 // value is the ID of the request for which the ordinal is pending, or | |
260 // kInvalidId otherwise. | |
ncarter (slow)
2016/05/23 21:59:16
This member is somewhat confusing to me. It is a r
paulmeyer
2016/05/30 15:08:23
It was originally a bool, representing whether the
| |
261 int pending_active_match_ordinal_; | |
ncarter (slow)
2016/05/23 21:59:17
Under what circumstances can pending_active_match_
paulmeyer
2016/05/30 15:08:23
It won't be different anymore. I'll change this ba
| |
262 | |
263 // The number of matches found in each frame, stored by a (process ID, frame | |
264 // ID) pair that uniquely identifies each frame. There will necessarily be | |
265 // entries in this map for every frame that is being (or has been) searched in | |
266 // the current find session, and no other frames. | |
267 std::map<FrameKey, int> matches_per_frame_; | |
ncarter (slow)
2016/05/23 21:59:17
I see four different data structures keyed by Fram
paulmeyer
2016/05/30 15:08:23
I think I like these better separately, because so
| |
268 | |
269 // The total number of matches found in the current find-in-page session. This | |
270 // should always be equal to the sum of all the entries in | |
271 // |matches_per_frame_|. | |
131 int number_of_matches_; | 272 int number_of_matches_; |
132 | 273 |
274 // The active match ordinal relative to the matches found in its own frame. | |
275 std::pair<FrameKey, int> relative_active_match_ordinal_; | |
ncarter (slow)
2016/05/23 21:59:17
For the same reasons as the other pair, this would
paulmeyer
2016/05/30 15:08:23
Done.
| |
276 | |
133 // The overall active match ordinal for the current find-in-page session. | 277 // The overall active match ordinal for the current find-in-page session. |
134 int active_match_ordinal_; | 278 int active_match_ordinal_; |
135 | 279 |
136 // The rectangle around the active match, in screen coordinates. | 280 // The rectangle around the active match, in screen coordinates. |
137 gfx::Rect selection_rect_; | 281 gfx::Rect selection_rect_; |
282 | |
283 // Find requests are queued here when previous requests need to be handled | |
284 // before these ones can be properly routed. | |
285 std::queue<FindRequest> find_request_queue_; | |
138 }; | 286 }; |
139 | 287 |
140 } // namespace content | 288 } // namespace content |
141 | 289 |
142 #endif // CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_ | 290 #endif // CONTENT_BROWSER_FIND_REQUEST_MANAGER_H_ |
OLD | NEW |