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

Side by Side Diff: components/web_view/find_controller.cc

Issue 1371773003: mandoline: Add find in page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Further patch cleanup; use a WeakPtrFactory in FindController. Created 5 years, 2 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "components/web_view/find_controller.h"
6
7 #include "base/bind.h"
8 #include "components/web_view/find_controller_delegate.h"
9 #include "components/web_view/frame.h"
10
11 namespace web_view {
12
13 FindController::FindController(FindControllerDelegate* delegate)
14 : delegate_(delegate),
15 current_find_request_(-1),
16 weak_ptr_factory_(this) {}
17
18 FindController::~FindController() {}
19
20 void FindController::Find(int32_t request_id, const mojo::String& search_text) {
21 // TODO(erg): While this deals with multiple frames, it does not deal with
22 // going forward or backwards. To do that, we'll have to port all frame
23 // traversal and focusing concepts from blink::WebFrame to mojo::Frame.
24
25 // TODO(erg): This isn't great and causes flashes on character
26 // entry. However, it's needed for now because the internals of TextFinder
27 // still track the entire state of the blink frame tree, and if there are any
28 // frames that have marked text, doing a find clears the results of all
29 // frames _except_ for the first frame that it finds a result on.
30 StopFinding();
31
32 // TODO(erg): This cheap method does not traverse in the order that blink
33 // does.
34 pending_find_frames_ = delegate_->GetAllFrames();
35
36 current_find_request_ = request_id;
37 returned_find_data_.clear();
38
39 // Prime the continue loop.
40 OnContinueFinding(request_id, search_text, false);
41 }
42
43 void FindController::StopFinding() {
44 // Don't report any callbacks that we get after this.
45 current_find_request_ = -1;
46
47 for (Frame* f : delegate_->GetAllFrames())
48 f->StopFinding(true);
49 }
50
51 void FindController::OnReportFindInFrameMatchCount(int32_t request_id,
52 Frame* frame,
53 int32_t count,
54 bool final_update) {
55 if (request_id != current_find_request_)
56 return;
57
58 auto it = returned_find_data_.find(frame);
59 if (it == returned_find_data_.end()) {
60 NOTREACHED();
61 return;
62 }
63
64 it->second.count = count;
65 it->second.final_update = final_update;
66
67 int merged_count = 0;
68 bool merged_final_update = true;
69 for (auto const& data : returned_find_data_) {
70 merged_count += data.second.count;
71 merged_final_update = merged_final_update && data.second.final_update;
72 }
73
74 // We can now take the individual FindInFrame messages and construct a
75 // FindInPage message.
76 delegate_->GetWebViewClient()->ReportFindInPageMatchCount(
77 request_id, merged_count, merged_final_update);
78 }
79
80 void FindController::OnReportFindInPageSelection(int32_t request_id,
81 Frame* frame,
82 int32_t active_match_ordinal) {
83 if (request_id != current_find_request_)
84 return;
85
86 // TODO(erg): This is the one that's really hard. To give an accurate count
87 // here, we need to have all the results for frames that are before the Frame
88 // that contains the selected match so we can add their sums together.
89 //
90 // Thankfully, we don't have to worry about this now. Since there aren't
91 // back/forward controls yet, active_match_ordinal will always be 1.
92 delegate_->GetWebViewClient()->ReportFindInPageSelection(
93 request_id, active_match_ordinal);
94 }
95
96 void FindController::DidDestroyFrame(Frame* frame) {
97 auto it =
98 find(pending_find_frames_.begin(), pending_find_frames_.end(), frame);
99 if (it != pending_find_frames_.end())
100 pending_find_frames_.erase(it);
101 }
102
103 void FindController::OnContinueFinding(int32_t request_id,
104 const mojo::String& search_text,
105 bool found) {
106 if (!found && !pending_find_frames_.empty()) {
107 // No match found, search on the next frame.
108 Frame* next_frame = pending_find_frames_.front();
109 pending_find_frames_.pop_front();
110 next_frame->Find(
111 request_id, search_text,
112 base::Bind(&FindController::OnContinueFinding,
113 weak_ptr_factory_.GetWeakPtr(),
114 request_id,
115 search_text));
116
117 // TODO(erg): This doesn't deal with wrapping around the document at the
118 // end when there are multiple frames.
119 return;
120 }
121
122 pending_find_frames_.clear();
123
124 // We either found a match or we got the final rejection. Either way, we
125 // alert our caller.
126
127 // If nothing is found, set result to "0 of 0", otherwise, set it to
128 // "-1 of 1" to indicate that we found at least one item, but we don't know
129 // yet what is active.
130 int ordinal = found ? -1 : 0; // -1 here means, we might know more later.
131 int match_count = found ? 1 : 0; // 1 here means possibly more coming.
132
133 // If we find no matches then this will be our last status update.
134 // Otherwise the scoping effort will send more results.
135 bool final_status_update = !found;
136
137 // Send priming messages.
138 delegate_->GetWebViewClient()->ReportFindInPageSelection(request_id, ordinal);
139 delegate_->GetWebViewClient()->ReportFindInPageMatchCount(
140 request_id, match_count, final_status_update);
141
142 // TODO(erg): This doesn't iterate in the same order as the current code
143 // because we don't have the correct iteration primitives.
144 std::deque<Frame*> frames = delegate_->GetAllFrames();
145 for (Frame* f : frames) {
146 f->CancelPendingScopingEffort();
147
148 if (found) {
149 MatchData& match_data = returned_find_data_[f];
150 match_data.count = 0;
151 match_data.final_update = false;
152 f->ScopeStringMatches(request_id, search_text, true);
153 }
154 }
155 }
156
157 } // namespace web_view
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698