Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(318)

Side by Side Diff: content/browser/find_request_manager.cc

Issue 2700613003: Enable find-in-page across GuestViews. (Closed)
Patch Set: Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698