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