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