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 #include "content/browser/find_request_manager.h" | 5 #include "content/browser/find_request_manager.h" |
6 | 6 |
7 #include <algorithm> | |
8 | |
9 #include "content/browser/frame_host/render_frame_host_impl.h" | 7 #include "content/browser/frame_host/render_frame_host_impl.h" |
10 #include "content/browser/web_contents/web_contents_impl.h" | 8 #include "content/browser/web_contents/web_contents_impl.h" |
11 #include "content/common/frame_messages.h" | 9 #include "content/common/frame_messages.h" |
12 #include "content/common/input_messages.h" | 10 #include "content/common/input_messages.h" |
13 #include "content/public/browser/guest_mode.h" | |
14 | 11 |
15 namespace content { | 12 namespace content { |
16 | 13 |
17 namespace { | 14 namespace { |
18 | 15 |
19 // The following functions allow traversal over all frames, including those | |
20 // across WebContentses. | |
21 // | |
22 // Note that there are currently two different ways in which an inner | |
23 // WebContents may be embedded in an outer WebContents: | |
24 // | |
25 // 1) As a guest of the outer WebContents's BrowserPluginEmbedder. | |
26 // 2) Within an inner WebContentsTreeNode of the outer WebContents's | |
27 // WebContentsTreeNode. | |
28 | |
29 // Returns all child frames of |node|. | |
30 std::vector<FrameTreeNode*> GetChildren(FrameTreeNode* node) { | |
31 std::vector<FrameTreeNode*> children(node->child_count()); | |
32 for (size_t i = 0; i != node->child_count(); ++i) | |
33 children[i] = node->child_at(i); | |
34 | |
35 if (auto* inner_contents = WebContentsImpl::FromOuterFrameTreeNode(node)) { | |
36 children.push_back(inner_contents->GetMainFrame()->frame_tree_node()); | |
37 } else { | |
38 auto* contents = WebContentsImpl::FromFrameTreeNode(node); | |
39 if (node->IsMainFrame() && contents->GetBrowserPluginEmbedder()) { | |
40 for (auto* inner_contents : contents->GetInnerWebContents()) { | |
41 children.push_back(inner_contents->GetMainFrame()->frame_tree_node()); | |
42 } | |
43 } | |
44 } | |
45 | |
46 return children; | |
47 } | |
48 | |
49 // Returns the first child FrameTreeNode under |node|, if |node| has a child, or | |
50 // nullptr otherwise. | |
51 FrameTreeNode* GetFirstChild(FrameTreeNode* node) { | |
52 auto children = GetChildren(node); | |
53 if (!children.empty()) | |
54 return children.front(); | |
55 return nullptr; | |
56 } | |
57 | |
58 // Returns the last child FrameTreeNode under |node|, if |node| has a child, or | |
59 // nullptr otherwise. | |
60 FrameTreeNode* GetLastChild(FrameTreeNode* node) { | |
61 auto children = GetChildren(node); | |
62 if (!children.empty()) | |
63 return children.back(); | |
64 return nullptr; | |
65 } | |
66 | |
67 // Returns the deepest last child frame under |node|/|rfh| in the frame tree. | 16 // Returns the deepest last child frame under |node|/|rfh| in the frame tree. |
68 FrameTreeNode* GetDeepestLastChild(FrameTreeNode* node) { | 17 FrameTreeNode* GetDeepestLastChild(FrameTreeNode* node) { |
69 while (FrameTreeNode* last_child = GetLastChild(node)) | 18 while (node->child_count()) |
70 node = last_child; | 19 node = node->child_at(node->child_count() - 1); |
71 return node; | 20 return node; |
72 } | 21 } |
73 RenderFrameHost* GetDeepestLastChild(RenderFrameHost* rfh) { | 22 RenderFrameHost* GetDeepestLastChild(RenderFrameHost* rfh) { |
74 FrameTreeNode* node = | 23 FrameTreeNode* node = |
75 static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node(); | 24 static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node(); |
76 return GetDeepestLastChild(node)->current_frame_host(); | 25 return GetDeepestLastChild(node)->current_frame_host(); |
77 } | 26 } |
78 | 27 |
79 // Returns the parent FrameTreeNode of |node|, if |node| has a parent, or | |
80 // nullptr otherwise. | |
81 FrameTreeNode* GetParent(FrameTreeNode* node) { | |
82 if (node->parent()) | |
83 return node->parent(); | |
84 | |
85 // The parent frame may be in another WebContents. | |
86 if (node->IsMainFrame()) { | |
87 auto* contents = WebContentsImpl::FromFrameTreeNode(node); | |
88 if (GuestMode::IsCrossProcessFrameGuest(contents)) { | |
89 int node_id = contents->GetOuterDelegateFrameTreeNodeId(); | |
90 if (node_id != FrameTreeNode::kFrameTreeNodeInvalidId) | |
91 return FrameTreeNode::GloballyFindByID(node_id); | |
92 } else if (auto* outer_contents = contents->GetOuterWebContents()) { | |
93 return outer_contents->GetMainFrame()->frame_tree_node(); | |
94 } | |
95 } | |
96 | |
97 return nullptr; | |
98 } | |
99 | |
100 // Returns the previous sibling FrameTreeNode of |node|, if one exists, or | |
101 // nullptr otherwise. | |
102 FrameTreeNode* GetPreviousSibling(FrameTreeNode* node) { | |
103 if (FrameTreeNode* previous_sibling = node->PreviousSibling()) | |
104 return previous_sibling; | |
105 | |
106 // The previous sibling may be in another WebContents. | |
107 if (FrameTreeNode* parent = GetParent(node)) { | |
108 auto children = GetChildren(parent); | |
109 auto it = std::find(children.begin(), children.end(), node); | |
110 // It is odd that this node may not be a child of its parent, but this is | |
111 // actually possible during teardown, hence the need for the check for | |
112 // "it != children.end()". | |
113 if (it != children.end() && it != children.begin()) | |
114 return *--it; | |
115 } | |
116 | |
117 return nullptr; | |
118 } | |
119 | |
120 // Returns the next sibling FrameTreeNode of |node|, if one exists, or nullptr | |
121 // otherwise. | |
122 FrameTreeNode* GetNextSibling(FrameTreeNode* node) { | |
123 if (FrameTreeNode* next_sibling = node->NextSibling()) | |
124 return next_sibling; | |
125 | |
126 // The next sibling may be in another WebContents. | |
127 if (FrameTreeNode* parent = GetParent(node)) { | |
128 auto children = GetChildren(parent); | |
129 auto it = std::find(children.begin(), children.end(), node); | |
130 // It is odd that this node may not be a child of its parent, but this is | |
131 // actually possible during teardown, hence the need for the check for | |
132 // "it != children.end()". | |
133 if (it != children.end() && ++it != children.end()) | |
134 return *it; | |
135 } | |
136 | |
137 return nullptr; | |
138 } | |
139 | |
140 // Returns the FrameTreeNode directly after |node| in the frame tree in search | 28 // Returns the FrameTreeNode directly after |node| in the frame tree in search |
141 // order, or nullptr if one does not exist. If |wrap| is set, then wrapping | 29 // order, or nullptr if one does not exist. If |wrap| is set, then wrapping |
142 // between the first and last frames is permitted. Note that this traversal | 30 // between the first and last frames is permitted. Note that this traversal |
143 // follows the same ordering as in blink::FrameTree::traverseNextWithWrap(). | 31 // follows the same ordering as in blink::FrameTree::traverseNextWithWrap(). |
144 FrameTreeNode* TraverseNext(FrameTreeNode* node, bool wrap) { | 32 FrameTreeNode* TraverseNext(FrameTreeNode* node, bool wrap) { |
145 if (FrameTreeNode* first_child = GetFirstChild(node)) | 33 if (node->child_count()) |
146 return first_child; | 34 return node->child_at(0); |
147 | 35 |
148 FrameTreeNode* sibling = GetNextSibling(node); | 36 FrameTreeNode* sibling = node->NextSibling(); |
149 while (!sibling) { | 37 while (!sibling) { |
150 FrameTreeNode* parent = GetParent(node); | 38 if (!node->parent()) |
151 if (!parent) | |
152 return wrap ? node : nullptr; | 39 return wrap ? node : nullptr; |
153 node = parent; | 40 node = node->parent(); |
154 sibling = GetNextSibling(node); | 41 sibling = node->NextSibling(); |
155 } | 42 } |
156 return sibling; | 43 return sibling; |
157 } | 44 } |
158 | 45 |
159 // Returns the FrameTreeNode directly before |node| in the frame tree in search | 46 // Returns the FrameTreeNode directly before |node| in the frame tree in search |
160 // order, or nullptr if one does not exist. If |wrap| is set, then wrapping | 47 // order, or nullptr if one does not exist. If |wrap| is set, then wrapping |
161 // between the first and last frames is permitted. Note that this traversal | 48 // between the first and last frames is permitted. Note that this traversal |
162 // follows the same ordering as in blink::FrameTree::traversePreviousWithWrap(). | 49 // follows the same ordering as in blink::FrameTree::traversePreviousWithWrap(). |
163 FrameTreeNode* TraversePrevious(FrameTreeNode* node, bool wrap) { | 50 FrameTreeNode* TraversePrevious(FrameTreeNode* node, bool wrap) { |
164 if (FrameTreeNode* previous_sibling = GetPreviousSibling(node)) | 51 if (FrameTreeNode* previous_sibling = node->PreviousSibling()) |
165 return GetDeepestLastChild(previous_sibling); | 52 return GetDeepestLastChild(previous_sibling); |
166 if (FrameTreeNode* parent = GetParent(node)) | 53 if (node->parent()) |
167 return parent; | 54 return node->parent(); |
168 return wrap ? GetDeepestLastChild(node) : nullptr; | 55 return wrap ? GetDeepestLastChild(node) : nullptr; |
169 } | 56 } |
170 | 57 |
171 // The same as either TraverseNext() or TraversePrevious(), depending on | 58 // The same as either TraverseNext() or TraversePrevious() depending on |
172 // |forward|. | 59 // |forward|. |
173 FrameTreeNode* TraverseNode(FrameTreeNode* node, bool forward, bool wrap) { | 60 FrameTreeNode* TraverseNode(FrameTreeNode* node, bool forward, bool wrap) { |
174 return forward ? TraverseNext(node, wrap) : TraversePrevious(node, wrap); | 61 return forward ? TraverseNext(node, wrap) : TraversePrevious(node, wrap); |
175 } | 62 } |
176 | 63 |
177 } // namespace | 64 } // namespace |
178 | 65 |
179 // Observes searched WebContentses for frame changes, including deletion, | |
180 // creation, and navigation. | |
181 class FindRequestManager::FrameObserver : public WebContentsObserver { | |
182 public: | |
183 FrameObserver(WebContentsImpl* web_contents, FindRequestManager* manager) | |
184 : WebContentsObserver(web_contents), manager_(manager) {} | |
185 | |
186 ~FrameObserver() override {} | |
187 | |
188 void DidFinishLoad(RenderFrameHost* rfh, const GURL& validated_url) override { | |
189 if (manager_->current_session_id_ == kInvalidId) | |
190 return; | |
191 | |
192 manager_->RemoveFrame(rfh); | |
193 manager_->AddFrame(rfh, true /* force */); | |
194 } | |
195 | |
196 void RenderFrameDeleted(RenderFrameHost* rfh) override { | |
197 manager_->RemoveFrame(rfh); | |
198 } | |
199 | |
200 void RenderFrameHostChanged(RenderFrameHost* old_host, | |
201 RenderFrameHost* new_host) override { | |
202 manager_->RemoveFrame(old_host); | |
203 } | |
204 | |
205 void FrameDeleted(RenderFrameHost* rfh) override { | |
206 manager_->RemoveFrame(rfh); | |
207 } | |
208 | |
209 private: | |
210 // The FindRequestManager that owns this FrameObserver. | |
211 FindRequestManager* const manager_; | |
212 | |
213 DISALLOW_COPY_AND_ASSIGN(FrameObserver); | |
214 }; | |
215 | |
216 #if defined(OS_ANDROID) | 66 #if defined(OS_ANDROID) |
217 FindRequestManager::ActivateNearestFindResultState:: | 67 FindRequestManager::ActivateNearestFindResultState:: |
218 ActivateNearestFindResultState() = default; | 68 ActivateNearestFindResultState() = default; |
219 FindRequestManager::ActivateNearestFindResultState:: | 69 FindRequestManager::ActivateNearestFindResultState:: |
220 ActivateNearestFindResultState(float x, float y) | 70 ActivateNearestFindResultState(float x, float y) |
221 : current_request_id(GetNextID()), | 71 : current_request_id(GetNextID()), |
222 x(x), | 72 x(x), |
223 y(y) {} | 73 y(y) {} |
224 FindRequestManager::ActivateNearestFindResultState:: | 74 FindRequestManager::ActivateNearestFindResultState:: |
225 ~ActivateNearestFindResultState() {} | 75 ~ActivateNearestFindResultState() {} |
226 | 76 |
227 FindRequestManager::FrameRects::FrameRects() = default; | 77 FindRequestManager::FrameRects::FrameRects() = default; |
228 FindRequestManager::FrameRects::FrameRects(const std::vector<gfx::RectF>& rects, | 78 FindRequestManager::FrameRects::FrameRects(const std::vector<gfx::RectF>& rects, |
229 int version) | 79 int version) |
230 : rects(rects), version(version) {} | 80 : rects(rects), version(version) {} |
231 FindRequestManager::FrameRects::~FrameRects() {} | 81 FindRequestManager::FrameRects::~FrameRects() {} |
232 | 82 |
233 FindRequestManager::FindMatchRectsState::FindMatchRectsState() = default; | 83 FindRequestManager::FindMatchRectsState::FindMatchRectsState() = default; |
234 FindRequestManager::FindMatchRectsState::~FindMatchRectsState() {} | 84 FindRequestManager::FindMatchRectsState::~FindMatchRectsState() {} |
235 #endif | 85 #endif |
236 | 86 |
237 // static | 87 // static |
238 const int FindRequestManager::kInvalidId = -1; | 88 const int FindRequestManager::kInvalidId = -1; |
239 | 89 |
240 FindRequestManager::FindRequestManager(WebContentsImpl* web_contents) | 90 FindRequestManager::FindRequestManager(WebContentsImpl* web_contents) |
241 : contents_(web_contents), | 91 : WebContentsObserver(web_contents), |
| 92 contents_(web_contents), |
242 current_session_id_(kInvalidId), | 93 current_session_id_(kInvalidId), |
243 pending_find_next_reply_(nullptr), | 94 pending_find_next_reply_(nullptr), |
244 pending_active_match_ordinal_(false), | 95 pending_active_match_ordinal_(false), |
245 number_of_matches_(0), | 96 number_of_matches_(0), |
246 active_frame_(nullptr), | 97 active_frame_(nullptr), |
247 relative_active_match_ordinal_(0), | 98 relative_active_match_ordinal_(0), |
248 active_match_ordinal_(0), | 99 active_match_ordinal_(0), |
249 last_reported_id_(kInvalidId) {} | 100 last_reported_id_(kInvalidId) {} |
250 | 101 |
251 FindRequestManager::~FindRequestManager() {} | 102 FindRequestManager::~FindRequestManager() {} |
(...skipping 10 matching lines...) Expand all Loading... |
262 // If this is a new find session, clear any queued requests from last session. | 113 // If this is a new find session, clear any queued requests from last session. |
263 if (!options.find_next) | 114 if (!options.find_next) |
264 find_request_queue_ = std::queue<FindRequest>(); | 115 find_request_queue_ = std::queue<FindRequest>(); |
265 | 116 |
266 find_request_queue_.emplace(request_id, search_text, options); | 117 find_request_queue_.emplace(request_id, search_text, options); |
267 if (find_request_queue_.size() == 1) | 118 if (find_request_queue_.size() == 1) |
268 FindInternal(find_request_queue_.front()); | 119 FindInternal(find_request_queue_.front()); |
269 } | 120 } |
270 | 121 |
271 void FindRequestManager::StopFinding(StopFindAction action) { | 122 void FindRequestManager::StopFinding(StopFindAction action) { |
272 for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) { | 123 contents_->SendToAllFrames( |
273 contents->SendToAllFrames( | 124 new FrameMsg_StopFinding(MSG_ROUTING_NONE, action)); |
274 new FrameMsg_StopFinding(MSG_ROUTING_NONE, action)); | |
275 } | |
276 | 125 |
277 current_session_id_ = kInvalidId; | 126 current_session_id_ = kInvalidId; |
278 #if defined(OS_ANDROID) | 127 #if defined(OS_ANDROID) |
279 // It is important that these pending replies are cleared whenever a find | 128 // It is important that these pending replies are cleared whenever a find |
280 // session ends, so that subsequent replies for the old session are ignored. | 129 // session ends, so that subsequent replies for the old session are ignored. |
281 activate_.pending_replies.clear(); | 130 activate_.pending_replies.clear(); |
282 match_rects_.pending_replies.clear(); | 131 match_rects_.pending_replies.clear(); |
283 #endif | 132 #endif |
284 } | 133 } |
285 | 134 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
437 | 286 |
438 #if defined(OS_ANDROID) | 287 #if defined(OS_ANDROID) |
439 void FindRequestManager::ActivateNearestFindResult(float x, float y) { | 288 void FindRequestManager::ActivateNearestFindResult(float x, float y) { |
440 if (current_session_id_ == kInvalidId) | 289 if (current_session_id_ == kInvalidId) |
441 return; | 290 return; |
442 | 291 |
443 activate_ = ActivateNearestFindResultState(x, y); | 292 activate_ = ActivateNearestFindResultState(x, y); |
444 | 293 |
445 // Request from each frame the distance to the nearest find result (in that | 294 // Request from each frame the distance to the nearest find result (in that |
446 // frame) from the point (x, y), defined in find-in-page coordinates. | 295 // frame) from the point (x, y), defined in find-in-page coordinates. |
447 for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) { | 296 for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) { |
448 for (FrameTreeNode* node : contents->GetFrameTree()->Nodes()) { | 297 RenderFrameHost* rfh = node->current_frame_host(); |
449 RenderFrameHost* rfh = node->current_frame_host(); | |
450 | 298 |
451 if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive()) | 299 if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive()) |
452 continue; | 300 continue; |
453 | 301 |
454 activate_.pending_replies.insert(rfh); | 302 activate_.pending_replies.insert(rfh); |
455 rfh->Send(new FrameMsg_GetNearestFindResult(rfh->GetRoutingID(), | 303 rfh->Send(new FrameMsg_GetNearestFindResult( |
456 activate_.current_request_id, | 304 rfh->GetRoutingID(), activate_.current_request_id, |
457 activate_.x, activate_.y)); | 305 activate_.x, activate_.y)); |
458 } | |
459 } | 306 } |
460 } | 307 } |
461 | 308 |
462 void FindRequestManager::OnGetNearestFindResultReply(RenderFrameHost* rfh, | 309 void FindRequestManager::OnGetNearestFindResultReply(RenderFrameHost* rfh, |
463 int request_id, | 310 int request_id, |
464 float distance) { | 311 float distance) { |
465 if (request_id != activate_.current_request_id || | 312 if (request_id != activate_.current_request_id || |
466 !activate_.pending_replies.count(rfh)) { | 313 !activate_.pending_replies.count(rfh)) { |
467 return; | 314 return; |
468 } | 315 } |
469 | 316 |
470 // Check if this frame has a nearer find result than the current nearest. | 317 // Check if this frame has a nearer find result than the current nearest. |
471 if (distance < activate_.nearest_distance) { | 318 if (distance < activate_.nearest_distance) { |
472 activate_.nearest_frame = rfh; | 319 activate_.nearest_frame = rfh; |
473 activate_.nearest_distance = distance; | 320 activate_.nearest_distance = distance; |
474 } | 321 } |
475 | 322 |
476 RemoveNearestFindResultPendingReply(rfh); | 323 RemoveNearestFindResultPendingReply(rfh); |
477 } | 324 } |
478 | 325 |
479 void FindRequestManager::RequestFindMatchRects(int current_version) { | 326 void FindRequestManager::RequestFindMatchRects(int current_version) { |
480 match_rects_.pending_replies.clear(); | 327 match_rects_.pending_replies.clear(); |
481 match_rects_.request_version = current_version; | 328 match_rects_.request_version = current_version; |
482 | 329 |
483 // Request the latest find match rects from each frame. | 330 // Request the latest find match rects from each frame. |
484 for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) { | 331 for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) { |
485 for (FrameTreeNode* node : contents->GetFrameTree()->Nodes()) { | 332 RenderFrameHost* rfh = node->current_frame_host(); |
486 RenderFrameHost* rfh = node->current_frame_host(); | |
487 | 333 |
488 if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive()) | 334 if (!CheckFrame(rfh) || !rfh->IsRenderFrameLive()) |
489 continue; | 335 continue; |
490 | 336 |
491 match_rects_.pending_replies.insert(rfh); | 337 match_rects_.pending_replies.insert(rfh); |
492 auto it = match_rects_.frame_rects.find(rfh); | 338 auto it = match_rects_.frame_rects.find(rfh); |
493 int version = (it != match_rects_.frame_rects.end()) ? it->second.version | 339 int version = (it != match_rects_.frame_rects.end()) |
494 : kInvalidId; | 340 ? it->second.version : kInvalidId; |
495 rfh->Send(new FrameMsg_FindMatchRects(rfh->GetRoutingID(), version)); | 341 rfh->Send(new FrameMsg_FindMatchRects(rfh->GetRoutingID(), version)); |
496 } | |
497 } | 342 } |
498 } | 343 } |
499 | 344 |
500 void FindRequestManager::OnFindMatchRectsReply( | 345 void FindRequestManager::OnFindMatchRectsReply( |
501 RenderFrameHost* rfh, | 346 RenderFrameHost* rfh, |
502 int version, | 347 int version, |
503 const std::vector<gfx::RectF>& rects, | 348 const std::vector<gfx::RectF>& rects, |
504 const gfx::RectF& active_rect) { | 349 const gfx::RectF& active_rect) { |
505 auto it = match_rects_.frame_rects.find(rfh); | 350 auto it = match_rects_.frame_rects.find(rfh); |
506 if (it == match_rects_.frame_rects.end() || it->second.version != version) { | 351 if (it == match_rects_.frame_rects.end() || it->second.version != version) { |
507 // New version of rects has been received, so update the data. | 352 // New version of rects has been received, so update the data. |
508 match_rects_.frame_rects[rfh] = FrameRects(rects, version); | 353 match_rects_.frame_rects[rfh] = FrameRects(rects, version); |
509 ++match_rects_.known_version; | 354 ++match_rects_.known_version; |
510 } | 355 } |
511 if (!active_rect.IsEmpty()) | 356 if (!active_rect.IsEmpty()) |
512 match_rects_.active_rect = active_rect; | 357 match_rects_.active_rect = active_rect; |
513 RemoveFindMatchRectsPendingReply(rfh); | 358 RemoveFindMatchRectsPendingReply(rfh); |
514 } | 359 } |
515 #endif | 360 #endif |
516 | 361 |
| 362 void FindRequestManager::DidFinishLoad(RenderFrameHost* rfh, |
| 363 const GURL& validated_url) { |
| 364 if (current_session_id_ == kInvalidId) |
| 365 return; |
| 366 |
| 367 RemoveFrame(rfh); |
| 368 AddFrame(rfh, true /* force */); |
| 369 } |
| 370 |
| 371 void FindRequestManager::RenderFrameDeleted(RenderFrameHost* rfh) { |
| 372 RemoveFrame(rfh); |
| 373 } |
| 374 |
| 375 void FindRequestManager::RenderFrameHostChanged(RenderFrameHost* old_host, |
| 376 RenderFrameHost* new_host) { |
| 377 RemoveFrame(old_host); |
| 378 } |
| 379 |
| 380 void FindRequestManager::FrameDeleted(RenderFrameHost* rfh) { |
| 381 RemoveFrame(rfh); |
| 382 } |
| 383 |
517 void FindRequestManager::Reset(const FindRequest& initial_request) { | 384 void FindRequestManager::Reset(const FindRequest& initial_request) { |
518 current_session_id_ = initial_request.id; | 385 current_session_id_ = initial_request.id; |
519 current_request_ = initial_request; | 386 current_request_ = initial_request; |
520 pending_initial_replies_.clear(); | 387 pending_initial_replies_.clear(); |
521 pending_find_next_reply_ = nullptr; | 388 pending_find_next_reply_ = nullptr; |
522 pending_active_match_ordinal_ = true; | 389 pending_active_match_ordinal_ = true; |
523 matches_per_frame_.clear(); | 390 matches_per_frame_.clear(); |
524 number_of_matches_ = 0; | 391 number_of_matches_ = 0; |
525 active_frame_ = nullptr; | 392 active_frame_ = nullptr; |
526 relative_active_match_ordinal_ = 0; | 393 relative_active_match_ordinal_ = 0; |
527 active_match_ordinal_ = 0; | 394 active_match_ordinal_ = 0; |
528 selection_rect_ = gfx::Rect(); | 395 selection_rect_ = gfx::Rect(); |
529 last_reported_id_ = kInvalidId; | 396 last_reported_id_ = kInvalidId; |
530 frame_observers_.clear(); | |
531 #if defined(OS_ANDROID) | 397 #if defined(OS_ANDROID) |
532 activate_ = ActivateNearestFindResultState(); | 398 activate_ = ActivateNearestFindResultState(); |
533 match_rects_.pending_replies.clear(); | 399 match_rects_.pending_replies.clear(); |
534 #endif | 400 #endif |
535 } | 401 } |
536 | 402 |
537 void FindRequestManager::FindInternal(const FindRequest& request) { | 403 void FindRequestManager::FindInternal(const FindRequest& request) { |
538 DCHECK_GT(request.id, current_request_.id); | 404 DCHECK_GT(request.id, current_request_.id); |
539 DCHECK_GT(request.id, current_session_id_); | 405 DCHECK_GT(request.id, current_session_id_); |
540 | 406 |
541 if (request.options.find_next) { | 407 if (request.options.find_next) { |
542 // This is a find next operation. | 408 // This is a find next operation. |
543 | 409 |
544 // This implies that there is an ongoing find session with the same search | 410 // This implies that there is an ongoing find session with the same search |
545 // text. | 411 // text. |
546 DCHECK_GE(current_session_id_, 0); | 412 DCHECK_GE(current_session_id_, 0); |
547 DCHECK_EQ(request.search_text, current_request_.search_text); | 413 DCHECK_EQ(request.search_text, current_request_.search_text); |
548 | 414 |
549 // The find next request will be directed at the focused frame if there is | 415 // The find next request will be directed at the focused frame if there is |
550 // one, or the first frame with matches otherwise. | 416 // one, or the first frame with matches otherwise. |
551 RenderFrameHost* target_rfh = | 417 RenderFrameHost* target_rfh = contents_->GetFocusedFrame(); |
552 contents_->GetFocusedWebContents()->GetFocusedFrame(); | |
553 if (!target_rfh || !CheckFrame(target_rfh)) | 418 if (!target_rfh || !CheckFrame(target_rfh)) |
554 target_rfh = GetInitialFrame(request.options.forward); | 419 target_rfh = GetInitialFrame(request.options.forward); |
555 | 420 |
556 SendFindIPC(request, target_rfh); | 421 SendFindIPC(request, target_rfh); |
557 current_request_ = request; | 422 current_request_ = request; |
558 pending_active_match_ordinal_ = true; | 423 pending_active_match_ordinal_ = true; |
559 return; | 424 return; |
560 } | 425 } |
561 | 426 |
562 // This is an initial find operation. | 427 // This is an initial find operation. |
563 Reset(request); | 428 Reset(request); |
564 for (WebContentsImpl* contents : contents_->GetWebContentsAndAllInner()) { | 429 for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) |
565 frame_observers_.push_back(base::MakeUnique<FrameObserver>(contents, this)); | 430 AddFrame(node->current_frame_host(), false /* force */); |
566 for (FrameTreeNode* node : contents->GetFrameTree()->Nodes()) { | |
567 AddFrame(node->current_frame_host(), false /* force */); | |
568 } | |
569 } | |
570 } | 431 } |
571 | 432 |
572 void FindRequestManager::AdvanceQueue(int request_id) { | 433 void FindRequestManager::AdvanceQueue(int request_id) { |
573 if (find_request_queue_.empty() || | 434 if (find_request_queue_.empty() || |
574 request_id != find_request_queue_.front().id) { | 435 request_id != find_request_queue_.front().id) { |
575 return; | 436 return; |
576 } | 437 } |
577 | 438 |
578 find_request_queue_.pop(); | 439 find_request_queue_.pop(); |
579 if (!find_request_queue_.empty()) | 440 if (!find_request_queue_.empty()) |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 if (!forward) | 478 if (!forward) |
618 rfh = GetDeepestLastChild(rfh); | 479 rfh = GetDeepestLastChild(rfh); |
619 | 480 |
620 return rfh; | 481 return rfh; |
621 } | 482 } |
622 | 483 |
623 RenderFrameHost* FindRequestManager::Traverse(RenderFrameHost* from_rfh, | 484 RenderFrameHost* FindRequestManager::Traverse(RenderFrameHost* from_rfh, |
624 bool forward, | 485 bool forward, |
625 bool matches_only, | 486 bool matches_only, |
626 bool wrap) const { | 487 bool wrap) const { |
627 DCHECK(from_rfh); | |
628 FrameTreeNode* node = | 488 FrameTreeNode* node = |
629 static_cast<RenderFrameHostImpl*>(from_rfh)->frame_tree_node(); | 489 static_cast<RenderFrameHostImpl*>(from_rfh)->frame_tree_node(); |
630 | 490 |
631 while ((node = TraverseNode(node, forward, wrap)) != nullptr) { | 491 while ((node = TraverseNode(node, forward, wrap)) != nullptr) { |
632 if (!CheckFrame(node->current_frame_host())) | 492 if (!CheckFrame(node->current_frame_host())) |
633 continue; | 493 continue; |
634 RenderFrameHost* current_rfh = node->current_frame_host(); | 494 RenderFrameHost* current_rfh = node->current_frame_host(); |
635 if (!matches_only || matches_per_frame_.find(current_rfh)->second || | 495 if (!matches_only || matches_per_frame_.find(current_rfh)->second || |
636 pending_initial_replies_.count(current_rfh)) { | 496 pending_initial_replies_.count(current_rfh)) { |
637 // Note that if there is still a pending reply expected for this frame, | 497 // Note that if there is still a pending reply expected for this frame, |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
705 // request must be sent. | 565 // request must be sent. |
706 | 566 |
707 RenderFrameHost* target_rfh; | 567 RenderFrameHost* target_rfh; |
708 if (request_id == current_request_.id && current_request_.options.find_next) { | 568 if (request_id == current_request_.id && current_request_.options.find_next) { |
709 // If this was a find next operation, then the active match will be in the | 569 // If this was a find next operation, then the active match will be in the |
710 // next frame with matches after this one. | 570 // next frame with matches after this one. |
711 target_rfh = Traverse(rfh, | 571 target_rfh = Traverse(rfh, |
712 current_request_.options.forward, | 572 current_request_.options.forward, |
713 true /* matches_only */, | 573 true /* matches_only */, |
714 true /* wrap */); | 574 true /* wrap */); |
715 } else if ((target_rfh = | 575 } else if ((target_rfh = contents_->GetFocusedFrame()) != nullptr) { |
716 contents_->GetFocusedWebContents()->GetFocusedFrame()) != | |
717 nullptr) { | |
718 // Otherwise, if there is a focused frame, then the active match will be in | 576 // Otherwise, if there is a focused frame, then the active match will be in |
719 // the next frame with matches after that one. | 577 // the next frame with matches after that one. |
720 target_rfh = Traverse(target_rfh, | 578 target_rfh = Traverse(target_rfh, |
721 current_request_.options.forward, | 579 current_request_.options.forward, |
722 true /* matches_only */, | 580 true /* matches_only */, |
723 true /* wrap */); | 581 true /* wrap */); |
724 } else { | 582 } else { |
725 // Otherwise, the first frame with matches will have the active match. | 583 // Otherwise, the first frame with matches will have the active match. |
726 target_rfh = GetInitialFrame(current_request_.options.forward); | 584 target_rfh = GetInitialFrame(current_request_.options.forward); |
727 if (!CheckFrame(target_rfh) || !matches_per_frame_[target_rfh]) { | 585 if (!CheckFrame(target_rfh) || !matches_per_frame_[target_rfh]) { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 aggregate_rects.end(), frame_rects.begin(), frame_rects.end()); | 642 aggregate_rects.end(), frame_rects.begin(), frame_rects.end()); |
785 } | 643 } |
786 } | 644 } |
787 contents_->NotifyFindMatchRectsReply( | 645 contents_->NotifyFindMatchRectsReply( |
788 match_rects_.known_version, aggregate_rects, match_rects_.active_rect); | 646 match_rects_.known_version, aggregate_rects, match_rects_.active_rect); |
789 } | 647 } |
790 } | 648 } |
791 #endif | 649 #endif |
792 | 650 |
793 } // namespace content | 651 } // namespace content |
OLD | NEW |