Chromium Code Reviews| 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 |