| Index: content/browser/find_request_manager.cc
|
| diff --git a/content/browser/find_request_manager.cc b/content/browser/find_request_manager.cc
|
| index 915ecf8d9fd51fead4daa96df981924bbf1d753a..ba97753698a77a8e8f00fe80181909fb083d17a5 100644
|
| --- a/content/browser/find_request_manager.cc
|
| +++ b/content/browser/find_request_manager.cc
|
| @@ -11,13 +11,90 @@
|
|
|
| namespace content {
|
|
|
| +namespace {
|
| +
|
| +// Returns the deepest last child frame under |node|/|rfh| in the frame tree.
|
| +FrameTreeNode* GetDeepestLastChild(FrameTreeNode* node) {
|
| + while (node->child_count())
|
| + node = node->child_at(node->child_count() - 1);
|
| + return node;
|
| +}
|
| +RenderFrameHost* GetDeepestLastChild(RenderFrameHost* rfh) {
|
| + FrameTreeNode* node =
|
| + static_cast<RenderFrameHostImpl*>(rfh)->frame_tree_node();
|
| + return GetDeepestLastChild(node)->current_frame_host();
|
| +}
|
| +
|
| +// Returns the FrameTreeNode directly after |node| in the frame tree in search
|
| +// order, or nullptr if one does not exist. If |wrap| is set, then wrapping
|
| +// between the first and last frames is permitted. Note that this traversal
|
| +// follows the same ordering as in blink::FrameTree::traverseNextWithWrap().
|
| +FrameTreeNode* TraverseNext(FrameTreeNode* node, bool wrap) {
|
| + if (node->child_count())
|
| + return node->child_at(0);
|
| +
|
| + FrameTreeNode* sibling = node->NextSibling();
|
| + while (!sibling) {
|
| + if (!node->parent())
|
| + return wrap ? node : nullptr;
|
| + node = node->parent();
|
| + sibling = node->NextSibling();
|
| + }
|
| + return sibling;
|
| +}
|
| +
|
| +// Returns the FrameTreeNode directly before |node| in the frame tree in search
|
| +// order, or nullptr if one does not exist. If |wrap| is set, then wrapping
|
| +// between the first and last frames is permitted. Note that this traversal
|
| +// follows the same ordering as in blink::FrameTree::traversePreviousWithWrap().
|
| +FrameTreeNode* TraversePrevious(FrameTreeNode* node, bool wrap) {
|
| + if (FrameTreeNode* previous_sibling = node->PreviousSibling())
|
| + return GetDeepestLastChild(previous_sibling);
|
| + if (node->parent())
|
| + return node->parent();
|
| + return wrap ? GetDeepestLastChild(node) : nullptr;
|
| +}
|
| +
|
| +// The same as either TraverseNext() or TraversePrevious() depending on
|
| +// |forward|.
|
| +FrameTreeNode* TraverseNode(FrameTreeNode* node, bool forward, bool wrap) {
|
| + return forward ? TraverseNext(node, wrap) : TraversePrevious(node, wrap);
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +#if defined(OS_ANDROID)
|
| +FindRequestManager::ActivateNearestFindResultState::
|
| +ActivateNearestFindResultState() = default;
|
| +FindRequestManager::ActivateNearestFindResultState::
|
| +ActivateNearestFindResultState(float x, float y)
|
| + : current_request_id(GetNextID()),
|
| + x(x),
|
| + y(y) {}
|
| +FindRequestManager::ActivateNearestFindResultState::
|
| +~ActivateNearestFindResultState() {}
|
| +
|
| +FindRequestManager::FrameRects::FrameRects() = default;
|
| +FindRequestManager::FrameRects::FrameRects(const std::vector<gfx::RectF>& rects,
|
| + int version)
|
| + : rects(rects), version(version) {}
|
| +FindRequestManager::FrameRects::~FrameRects() {}
|
| +
|
| +FindRequestManager::FindMatchRectsState::FindMatchRectsState() = default;
|
| +FindRequestManager::FindMatchRectsState::~FindMatchRectsState() {}
|
| +#endif
|
| +
|
| // static
|
| const int FindRequestManager::kInvalidId = -1;
|
|
|
| FindRequestManager::FindRequestManager(WebContentsImpl* web_contents)
|
| - : contents_(web_contents),
|
| + : WebContentsObserver(web_contents),
|
| + contents_(web_contents),
|
| current_session_id_(kInvalidId),
|
| + pending_active_match_ordinal_(false),
|
| number_of_matches_(0),
|
| + active_frame_(nullptr),
|
| + relative_active_match_ordinal_(0),
|
| active_match_ordinal_(0) {}
|
|
|
| FindRequestManager::~FindRequestManager() {}
|
| @@ -31,28 +108,26 @@ void FindRequestManager::Find(int request_id,
|
| DCHECK_GT(request_id, current_request_.id);
|
| DCHECK_GT(request_id, current_session_id_);
|
|
|
| - FindRequest request(request_id, search_text, options);
|
| -
|
| - if (options.findNext) {
|
| - // This is a find next operation.
|
| -
|
| - // This implies that there is an ongoing find session with the same search
|
| - // text.
|
| - DCHECK_GE(current_session_id_, 0);
|
| - DCHECK_EQ(request.search_text, current_request_.search_text);
|
| -
|
| - current_request_ = request;
|
| - } else {
|
| - // This is an initial find operation.
|
| - Reset(request);
|
| - }
|
| + // If this is a new find session, clear any queued requests from last session.
|
| + if (!options.findNext)
|
| + find_request_queue_ = std::queue<FindRequest>();
|
|
|
| - SendFindIPC(request, contents_->GetMainFrame());
|
| + find_request_queue_.emplace(request_id, search_text, options);
|
| + if (find_request_queue_.size() == 1)
|
| + FindInternal(find_request_queue_.front());
|
| }
|
|
|
| void FindRequestManager::StopFinding(StopFindAction action) {
|
| - SendStopFindingIPC(action, contents_->GetMainFrame());
|
| + contents_->SendToAllFrames(
|
| + new FrameMsg_StopFinding(MSG_ROUTING_NONE, action));
|
| +
|
| current_session_id_ = kInvalidId;
|
| +#if defined(OS_ANDROID)
|
| + // It is important that these pending replies are cleared whenever a find
|
| + // session ends, so that subsequent replies for the old session are ignored.
|
| + activate_.pending_replies.clear();
|
| + match_rects_.pending_replies.clear();
|
| +#endif
|
| }
|
|
|
| void FindRequestManager::OnFindReply(RenderFrameHost* rfh,
|
| @@ -64,29 +139,175 @@ void FindRequestManager::OnFindReply(RenderFrameHost* rfh,
|
| // Ignore stale replies from abandoned find sessions.
|
| if (current_session_id_ == kInvalidId || request_id < current_session_id_)
|
| return;
|
| + DCHECK(CheckFrame(rfh));
|
| +
|
| + // Update the stored find results.
|
| +
|
| + DCHECK_GE(number_of_matches, -1);
|
| + DCHECK_GE(active_match_ordinal, -1);
|
|
|
| - // Update the stored results.
|
| - number_of_matches_ = number_of_matches;
|
| - selection_rect_ = selection_rect;
|
| - active_match_ordinal_ = active_match_ordinal;
|
| + // Check for an update to the number of matches.
|
| + if (number_of_matches != -1) {
|
| + DCHECK_GE(number_of_matches, 0);
|
| + // Increment the global number of matches by the number of additional
|
| + // matches found for this frame.
|
| + auto matches_per_frame_it = matches_per_frame_.find(rfh);
|
| + number_of_matches_ += number_of_matches - matches_per_frame_it->second;
|
| + matches_per_frame_it->second = number_of_matches;
|
| + }
|
| +
|
| + // Check for an update to the selection rect.
|
| + if (!selection_rect.IsEmpty())
|
| + selection_rect_ = selection_rect;
|
| +
|
| + // Check for an update to the active match ordinal.
|
| + if (active_match_ordinal > 0) {
|
| + if (rfh == active_frame_) {
|
| + active_match_ordinal_ +=
|
| + active_match_ordinal - relative_active_match_ordinal_;
|
| + relative_active_match_ordinal_ = active_match_ordinal;
|
| + } else {
|
| + if (active_frame_) {
|
| + // The new active match is in a different frame than the previous, so
|
| + // the previous active frame needs to be informed (to clear its active
|
| + // match highlighting).
|
| + active_frame_->Send(new FrameMsg_ClearActiveFindMatch(
|
| + active_frame_->GetRoutingID()));
|
| + }
|
| + active_frame_ = rfh;
|
| + relative_active_match_ordinal_ = active_match_ordinal;
|
| + UpdateActiveMatchOrdinal();
|
| + }
|
| + if (pending_active_match_ordinal_ && request_id == current_request_.id)
|
| + pending_active_match_ordinal_ = false;
|
| + AdvanceQueue(request_id);
|
| + }
|
|
|
| - NotifyFindReply(request_id, final_update);
|
| + if (!final_update) {
|
| + NotifyFindReply(request_id, false /* final_update */);
|
| + return;
|
| + }
|
| +
|
| + // This is the final update for this frame for the current find operation.
|
| +
|
| + pending_replies_.erase(rfh);
|
| + if (request_id == current_session_id_ && !pending_replies_.empty()) {
|
| + NotifyFindReply(request_id, false /* final_update */);
|
| + return;
|
| + }
|
| + DCHECK(request_id == current_session_id_ ||
|
| + current_request_.options.findNext);
|
| +
|
| + // This is the final update for the current find operation.
|
| + FinalUpdate(request_id, rfh);
|
| }
|
|
|
| +void FindRequestManager::RemoveFrame(RenderFrameHost* rfh) {
|
| + if (current_session_id_ == kInvalidId || !CheckFrame(rfh))
|
| + return;
|
| +
|
| + // If matches are counted for the frame that is being removed, decrement the
|
| + // match total before erasing that entry.
|
| + auto it = matches_per_frame_.find(rfh);
|
| + if (it != matches_per_frame_.end()) {
|
| + number_of_matches_ -= it->second;
|
| + matches_per_frame_.erase(it);
|
| + }
|
| +
|
| + // Update the active match ordinal, since it may have changed.
|
| + if (active_frame_ == rfh) {
|
| + active_frame_ = nullptr;
|
| + relative_active_match_ordinal_ = 0;
|
| + }
|
| + UpdateActiveMatchOrdinal();
|
| +
|
| #if defined(OS_ANDROID)
|
| -void FindRequestManager::ActivateNearestFindResult(float x,
|
| - float y) {
|
| + // The removed frame may contain the nearest find result known so far. Note
|
| + // that once all queried frames have responded, if this result was the overall
|
| + // nearest, then no activation will occur.
|
| + if (rfh == activate_.nearest_frame)
|
| + activate_.nearest_frame = nullptr;
|
| +
|
| + // Match rects in the removed frame are no longer relevant.
|
| + if (match_rects_.frame_rects.count(rfh)) {
|
| + match_rects_.frame_rects.erase(rfh);
|
| + ++match_rects_.known_version;
|
| + }
|
| +
|
| + // A reply should not be expected from the removed frame.
|
| + RemoveNearestFindResultPendingReply(rfh);
|
| + RemoveFindMatchRectsPendingReply(rfh);
|
| +#endif
|
| +
|
| + if (pending_replies_.count(rfh)) {
|
| + // A reply should not be expected from the removed frame.
|
| + pending_replies_.erase(rfh);
|
| + if (pending_replies_.empty()) {
|
| + FinalUpdate(current_request_.id, rfh);
|
| + return;
|
| + }
|
| + }
|
| +
|
| + NotifyFindReply(current_session_id_,
|
| + pending_replies_.empty() /* final_update */);
|
| +}
|
| +
|
| +#if defined(OS_ANDROID)
|
| +void FindRequestManager::ActivateNearestFindResult(float x, float y) {
|
| if (current_session_id_ == kInvalidId)
|
| return;
|
|
|
| - auto rfh = contents_->GetMainFrame();
|
| - rfh->Send(new InputMsg_ActivateNearestFindResult(
|
| - rfh->GetRoutingID(), current_session_id_, x, y));
|
| + activate_ = ActivateNearestFindResultState(x, y);
|
| +
|
| + // Request from each frame the distance to the nearest find result (in that
|
| + // frame) from the point (x, y), defined in find-in-page coordinates.
|
| + for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) {
|
| + RenderFrameHost* rfh = node->current_frame_host();
|
| +
|
| + if (!CheckFrame(rfh))
|
| + continue;
|
| +
|
| + activate_.pending_replies.insert(rfh);
|
| + rfh->Send(new FrameMsg_GetNearestFindResult(
|
| + rfh->GetRoutingID(), activate_.current_request_id,
|
| + activate_.x, activate_.y));
|
| + }
|
| +}
|
| +
|
| +void FindRequestManager::OnGetNearestFindResultReply(RenderFrameHost* rfh,
|
| + int request_id,
|
| + float distance) {
|
| + if (request_id != activate_.current_request_id ||
|
| + !activate_.pending_replies.count(rfh)) {
|
| + return;
|
| + }
|
| +
|
| + // Check if this frame has a nearer find result than the current nearest.
|
| + if (distance < activate_.nearest_distance) {
|
| + activate_.nearest_frame = rfh;
|
| + activate_.nearest_distance = distance;
|
| + }
|
| +
|
| + RemoveNearestFindResultPendingReply(rfh);
|
| }
|
|
|
| void FindRequestManager::RequestFindMatchRects(int current_version) {
|
| + match_rects_.pending_replies.clear();
|
| match_rects_.request_version = current_version;
|
| - SendFindMatchRectsIPC(contents_->GetMainFrame());
|
| +
|
| + // Request the latest find match rects from each frame.
|
| + for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes()) {
|
| + RenderFrameHost* rfh = node->current_frame_host();
|
| +
|
| + if (!CheckFrame(rfh))
|
| + continue;
|
| +
|
| + match_rects_.pending_replies.insert(rfh);
|
| + auto it = match_rects_.frame_rects.find(rfh);
|
| + int version = (it != match_rects_.frame_rects.end())
|
| + ? it->second.version : kInvalidId;
|
| + rfh->Send(new FrameMsg_FindMatchRects(rfh->GetRoutingID(), version));
|
| + }
|
| }
|
|
|
| void FindRequestManager::OnFindMatchRectsReply(
|
| @@ -94,32 +315,96 @@ void FindRequestManager::OnFindMatchRectsReply(
|
| int version,
|
| const std::vector<gfx::RectF>& rects,
|
| const gfx::RectF& active_rect) {
|
| - contents_->NotifyFindMatchRectsReply(version, rects, active_rect);
|
| + auto it = match_rects_.frame_rects.find(rfh);
|
| + if (it == match_rects_.frame_rects.end() || it->second.version != version) {
|
| + // New version of rects has been received, so update the data.
|
| + match_rects_.frame_rects[rfh] = FrameRects(rects, version);
|
| + ++match_rects_.known_version;
|
| + }
|
| + if (!active_rect.IsEmpty())
|
| + match_rects_.active_rect = active_rect;
|
| + RemoveFindMatchRectsPendingReply(rfh);
|
| }
|
| #endif
|
|
|
| +void FindRequestManager::RenderFrameDeleted(RenderFrameHost* rfh) {
|
| + RemoveFrame(rfh);
|
| +}
|
| +
|
| +void FindRequestManager::RenderFrameHostChanged(RenderFrameHost* old_host,
|
| + RenderFrameHost* new_host) {
|
| + RemoveFrame(old_host);
|
| +}
|
| +
|
| +void FindRequestManager::FrameDeleted(RenderFrameHost* rfh) {
|
| + RemoveFrame(rfh);
|
| +}
|
| +
|
| void FindRequestManager::Reset(const FindRequest& initial_request) {
|
| current_session_id_ = initial_request.id;
|
| current_request_ = initial_request;
|
| + pending_replies_.clear();
|
| + pending_active_match_ordinal_ = true;
|
| + matches_per_frame_.clear();
|
| number_of_matches_ = 0;
|
| + active_frame_ = nullptr;
|
| + relative_active_match_ordinal_ = 0;
|
| active_match_ordinal_ = 0;
|
| selection_rect_ = gfx::Rect();
|
| #if defined(OS_ANDROID)
|
| - match_rects_ = FindMatchRectsState();
|
| + activate_ = ActivateNearestFindResultState();
|
| + match_rects_.pending_replies.clear();
|
| #endif
|
| }
|
|
|
| +void FindRequestManager::FindInternal(const FindRequest& request) {
|
| + DCHECK_GT(request.id, current_request_.id);
|
| + DCHECK_GT(request.id, current_session_id_);
|
| +
|
| + if (request.options.findNext) {
|
| + // This is a find next operation.
|
| +
|
| + // This implies that there is an ongoing find session with the same search
|
| + // text.
|
| + DCHECK_GE(current_session_id_, 0);
|
| + DCHECK_EQ(request.search_text, current_request_.search_text);
|
| +
|
| + // The find next request will be directed at the focused frame if there is
|
| + // one, or the first frame with matches otherwise.
|
| + RenderFrameHost* target_rfh = contents_->GetFocusedFrame();
|
| + if (!target_rfh || !CheckFrame(target_rfh))
|
| + target_rfh = GetInitialFrame(request.options.forward);
|
| +
|
| + SendFindIPC(request, target_rfh);
|
| + current_request_ = request;
|
| + pending_active_match_ordinal_ = true;
|
| + return;
|
| + }
|
| +
|
| + // This is an initial find operation.
|
| + Reset(request);
|
| + for (FrameTreeNode* node : contents_->GetFrameTree()->Nodes())
|
| + AddFrame(node->current_frame_host());
|
| +}
|
| +
|
| +void FindRequestManager::AdvanceQueue(int request_id) {
|
| + if (find_request_queue_.empty() ||
|
| + request_id != find_request_queue_.front().id) {
|
| + return;
|
| + }
|
| +
|
| + find_request_queue_.pop();
|
| + if (!find_request_queue_.empty())
|
| + FindInternal(find_request_queue_.front());
|
| +}
|
| +
|
| void FindRequestManager::SendFindIPC(const FindRequest& request,
|
| RenderFrameHost* rfh) {
|
| + pending_replies_.insert(rfh);
|
| rfh->Send(new FrameMsg_Find(rfh->GetRoutingID(), request.id,
|
| request.search_text, request.options));
|
| }
|
|
|
| -void FindRequestManager::SendStopFindingIPC(StopFindAction action,
|
| - RenderFrameHost* rfh) const {
|
| - rfh->Send(new FrameMsg_StopFinding(rfh->GetRoutingID(), action));
|
| -}
|
| -
|
| void FindRequestManager::NotifyFindReply(int request_id,
|
| bool final_update) const {
|
| if (request_id == kInvalidId) {
|
| @@ -131,10 +416,173 @@ void FindRequestManager::NotifyFindReply(int request_id,
|
| active_match_ordinal_, final_update);
|
| }
|
|
|
| +RenderFrameHost* FindRequestManager::GetInitialFrame(bool forward) const {
|
| + RenderFrameHost* rfh = contents_->GetMainFrame();
|
| +
|
| + if (!forward)
|
| + rfh = GetDeepestLastChild(rfh);
|
| +
|
| + return rfh;
|
| +}
|
| +
|
| +RenderFrameHost* FindRequestManager::Traverse(RenderFrameHost* from_rfh,
|
| + bool forward,
|
| + bool matches_only,
|
| + bool wrap) const {
|
| + FrameTreeNode* node =
|
| + static_cast<RenderFrameHostImpl*>(from_rfh)->frame_tree_node();
|
| +
|
| + while ((node = TraverseNode(node, forward, wrap)) != nullptr) {
|
| + if (!CheckFrame(node->current_frame_host()))
|
| + continue;
|
| + RenderFrameHost* current_rfh = node->current_frame_host();
|
| + if (!matches_only || matches_per_frame_.find(current_rfh)->second ||
|
| + pending_replies_.count(current_rfh)) {
|
| + // Note that if there is still a pending reply expected for this frame,
|
| + // then it may have unaccounted matches and will not be skipped via
|
| + // |matches_only|.
|
| + return node->current_frame_host();
|
| + }
|
| + if (wrap && node->current_frame_host() == from_rfh)
|
| + return nullptr;
|
| + }
|
| +
|
| + return nullptr;
|
| +}
|
| +
|
| +void FindRequestManager::AddFrame(RenderFrameHost* rfh) {
|
| + if (!rfh || !rfh->IsRenderFrameLive())
|
| + return;
|
| +
|
| + // A frame that is already being searched should not be added again.
|
| + DCHECK(!CheckFrame(rfh));
|
| +
|
| + matches_per_frame_[rfh] = 0;
|
| +
|
| + FindRequest request = current_request_;
|
| + request.id = current_session_id_;
|
| + request.options.findNext = false;
|
| + SendFindIPC(request, rfh);
|
| +}
|
| +
|
| +bool FindRequestManager::CheckFrame(RenderFrameHost* rfh) const {
|
| + return rfh && rfh->IsRenderFrameLive() && matches_per_frame_.count(rfh);
|
| +}
|
| +
|
| +void FindRequestManager::UpdateActiveMatchOrdinal() {
|
| + active_match_ordinal_ = 0;
|
| +
|
| + if (!active_frame_ || !relative_active_match_ordinal_) {
|
| + DCHECK(!active_frame_ && !relative_active_match_ordinal_);
|
| + return;
|
| + }
|
| +
|
| + // Traverse the frame tree backwards (in search order) and count all of the
|
| + // matches in frames before the frame with the active match, in order to
|
| + // determine the overall active match ordinal.
|
| + RenderFrameHost* frame = active_frame_;
|
| + while ((frame = Traverse(frame,
|
| + false /* forward */,
|
| + true /* matches_only */,
|
| + false /* wrap */)) != nullptr) {
|
| + active_match_ordinal_ += matches_per_frame_[frame];
|
| + }
|
| + active_match_ordinal_ += relative_active_match_ordinal_;
|
| +}
|
| +
|
| +void FindRequestManager::FinalUpdate(int request_id, RenderFrameHost* rfh) {
|
| + if (!number_of_matches_ ||
|
| + !pending_active_match_ordinal_ ||
|
| + request_id != current_request_.id) {
|
| + NotifyFindReply(request_id, true /* final_update */);
|
| + AdvanceQueue(request_id);
|
| + return;
|
| + }
|
| +
|
| + // There are matches, but no active match was returned, so another find next
|
| + // request must be sent.
|
| +
|
| + RenderFrameHost* target_rfh;
|
| + if (current_request_.options.findNext) {
|
| + // If this was a find next operation, then the active match will be in the
|
| + // next frame with matches after this one.
|
| + target_rfh = Traverse(rfh,
|
| + current_request_.options.forward,
|
| + true /* matches_only */,
|
| + true /* wrap */);
|
| + } else if ((target_rfh = contents_->GetFocusedFrame()) != nullptr) {
|
| + // Otherwise, if there is a focused frame, then the active match will be in
|
| + // the next frame with matches after that one.
|
| + target_rfh = Traverse(target_rfh,
|
| + current_request_.options.forward,
|
| + true /* matches_only */,
|
| + true /* wrap */);
|
| + } else {
|
| + // Otherwise, the first frame with matches will have the active match.
|
| + target_rfh = GetInitialFrame(current_request_.options.forward);
|
| + if (!CheckFrame(target_rfh) || !matches_per_frame_[target_rfh]) {
|
| + target_rfh = Traverse(target_rfh,
|
| + current_request_.options.forward,
|
| + true /* matches_only */,
|
| + false /* wrap */);
|
| + }
|
| + }
|
| + DCHECK(target_rfh);
|
| +
|
| + // Forward the find reply without |final_update| set because the active match
|
| + // has not yet been found.
|
| + NotifyFindReply(request_id, false /* final_update */);
|
| +
|
| + current_request_.options.findNext = true;
|
| + SendFindIPC(current_request_, target_rfh);
|
| +}
|
| +
|
| #if defined(OS_ANDROID)
|
| -void FindRequestManager::SendFindMatchRectsIPC(RenderFrameHost* rfh) {
|
| - rfh->Send(new FrameMsg_FindMatchRects(rfh->GetRoutingID(),
|
| - match_rects_.request_version));
|
| +void FindRequestManager::RemoveNearestFindResultPendingReply(
|
| + RenderFrameHost* rfh) {
|
| + auto it = activate_.pending_replies.find(rfh);
|
| + if (it == activate_.pending_replies.end())
|
| + return;
|
| +
|
| + activate_.pending_replies.erase(it);
|
| + if (activate_.pending_replies.empty() &&
|
| + CheckFrame(activate_.nearest_frame)) {
|
| + activate_.nearest_frame->Send(new FrameMsg_ActivateNearestFindResult(
|
| + activate_.nearest_frame->GetRoutingID(),
|
| + current_session_id_, activate_.x, activate_.y));
|
| + }
|
| +}
|
| +
|
| +void FindRequestManager::RemoveFindMatchRectsPendingReply(
|
| + RenderFrameHost* rfh) {
|
| + auto it = match_rects_.pending_replies.find(rfh);
|
| + if (it == match_rects_.pending_replies.end())
|
| + return;
|
| +
|
| + match_rects_.pending_replies.erase(it);
|
| + if (match_rects_.pending_replies.empty()) {
|
| + // All replies are in.
|
| + std::vector<gfx::RectF> aggregate_rects;
|
| + if (match_rects_.request_version != match_rects_.known_version) {
|
| + // Request version is stale, so aggregate and report the newer find
|
| + // match rects. The rects should be aggregated in search order.
|
| + for (RenderFrameHost* frame = GetInitialFrame(true /* forward */); frame;
|
| + frame = Traverse(frame,
|
| + true /* forward */,
|
| + true /* matches_only */,
|
| + false /* wrap */)) {
|
| + auto it = match_rects_.frame_rects.find(frame);
|
| + if (it == match_rects_.frame_rects.end())
|
| + continue;
|
| +
|
| + std::vector<gfx::RectF>& frame_rects = it->second.rects;
|
| + aggregate_rects.insert(
|
| + aggregate_rects.end(), frame_rects.begin(), frame_rects.end());
|
| + }
|
| + }
|
| + contents_->NotifyFindMatchRectsReply(
|
| + match_rects_.known_version, aggregate_rects, match_rects_.active_rect);
|
| + }
|
| }
|
| #endif
|
|
|
|
|