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