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

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

Issue 1677293002: Bye bye Mandoline (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: moar Created 4 years, 10 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
« no previous file with comments | « components/web_view/find_controller.h ('k') | components/web_view/find_controller_delegate.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 "base/strings/string_util.h"
9 #include "base/trace_event/trace_event.h"
10 #include "components/web_view/find_controller_delegate.h"
11 #include "components/web_view/frame.h"
12
13 namespace web_view {
14
15 FindController::FindController(FindControllerDelegate* delegate)
16 : delegate_(delegate),
17 find_request_id_counter_(0),
18 current_find_request_id_(-1),
19 frame_with_selection_(0),
20 weak_ptr_factory_(this) {}
21
22 FindController::~FindController() {}
23
24 void FindController::Find(const std::string& in_search_string,
25 bool forward_direction) {
26 TRACE_EVENT2("web_view", "FindController::Find",
27 "search_string", in_search_string,
28 "forward_direction", forward_direction);
29 std::string search_string = in_search_string;
30 // Remove the carriage return character, which generally isn't in web content.
31 const char kInvalidChars[] = {'\r', 0};
32 base::RemoveChars(search_string, kInvalidChars, &search_string);
33
34 previous_find_text_ = find_text_;
35
36 // TODO(erg): Do we need to something like |find_op_aborted_|?
37
38 find_frames_in_order_ = delegate_->GetAllFrames();
39
40 uint32_t starting_frame;
41 bool continue_last_find =
42 find_text_ == search_string || search_string.empty();
43 if (!continue_last_find) {
44 current_find_request_id_ = find_request_id_counter_++;
45 frame_with_selection_ = 0;
46 returned_find_data_.clear();
47 starting_frame = find_frames_in_order_.front()->id();
48 } else {
49 starting_frame = frame_with_selection_;
50 }
51
52 if (!search_string.empty())
53 find_text_ = search_string;
54
55 LocalFindOptions options;
56 options.forward = forward_direction;
57 options.continue_last_find = continue_last_find;
58 // Prime the continue loop.
59 OnContinueFinding(current_find_request_id_, search_string, options,
60 starting_frame, 0u, false);
61 }
62
63 void FindController::StopFinding() {
64 // Don't report any callbacks that we get after this.
65 current_find_request_id_ = -1;
66 frame_with_selection_ = 0;
67
68 for (Frame* f : delegate_->GetAllFrames())
69 f->StopFinding(true);
70 }
71
72 void FindController::OnFindInFrameCountUpdated(int32_t request_id,
73 Frame* frame,
74 int32_t count,
75 bool final_update) {
76 if (request_id != current_find_request_id_)
77 return;
78
79 auto it = returned_find_data_.find(frame);
80 if (it == returned_find_data_.end()) {
81 NOTREACHED();
82 return;
83 }
84
85 it->second.count = count;
86 it->second.final_update = final_update;
87
88 int merged_count = 0;
89 bool merged_final_update = true;
90 for (auto const& data : returned_find_data_) {
91 merged_count += data.second.count;
92 merged_final_update = merged_final_update && data.second.final_update;
93 }
94
95 // We can now take the individual FindInFrame messages and construct a
96 // FindInPage message.
97 delegate_->GetWebViewClient()->FindInPageMatchCountUpdated(
98 request_id, merged_count, merged_final_update);
99 }
100
101 void FindController::OnFindInPageSelectionUpdated(
102 int32_t request_id,
103 Frame* frame,
104 int32_t active_match_ordinal) {
105 if (request_id != current_find_request_id_)
106 return;
107
108 // TODO(erg): This is the one that's really hard. To give an accurate count
109 // here, we need to have all the results for frames that are before the Frame
110 // that contains the selected match so we can add their sums together.
111 //
112 // Thankfully, we don't have to worry about this now. Since there aren't
113 // back/forward controls yet, active_match_ordinal will always be 1.
114 delegate_->GetWebViewClient()->FindInPageSelectionUpdated(
115 request_id, active_match_ordinal);
116 }
117
118 void FindController::DidDestroyFrame(Frame* frame) {
119 auto it =
120 find(find_frames_in_order_.begin(), find_frames_in_order_.end(), frame);
121 if (it != find_frames_in_order_.end())
122 find_frames_in_order_.erase(it);
123 }
124
125 void FindController::OnContinueFinding(int32_t request_id,
126 const std::string& search_string,
127 LocalFindOptions options,
128 uint32_t starting_frame,
129 uint32_t current_frame,
130 bool found) {
131 TRACE_EVENT2("web_view", "FindController::OnContinueFinding",
132 "request_id", request_id,
133 "search_string", search_string);
134 if (!found) {
135 // So we need to figure out what the next frame to search is.
136 Frame* next_frame =
137 GetNextFrameToSearch(starting_frame, current_frame, options.forward);
138
139 // If we have one more frame to search:
140 if (next_frame) {
141 bool wrap_within_frame = find_frames_in_order_.size() == 1;
142 next_frame->Find(
143 request_id, mojo::String::From(search_string),
144 mojom::FindOptions::From(options), wrap_within_frame,
145 base::Bind(&FindController::OnContinueFinding,
146 weak_ptr_factory_.GetWeakPtr(), request_id, search_string,
147 options, starting_frame, next_frame->id()));
148
149 // TODO(erg): This doesn't deal with wrapping around the document at the
150 // end when there are multiple frames and the last frame doesn't have a
151 // result.
152 return;
153 }
154 }
155
156 frame_with_selection_ = found ? current_frame : 0;
157
158 if (!options.continue_last_find) {
159 // If nothing is found, set result to "0 of 0", otherwise, set it to
160 // "-1 of 1" to indicate that we found at least one item, but we don't know
161 // yet what is active.
162 int ordinal = found ? -1 : 0; // -1 here means, we might know more later.
163 int match_count = found ? 1 : 0; // 1 here means possibly more coming.
164
165 // If we find no matches then this will be our last status update.
166 // Otherwise the scoping effort will send more results.
167 bool final_status_update = !found;
168
169 // Send priming messages.
170 delegate_->GetWebViewClient()->FindInPageSelectionUpdated(request_id,
171 ordinal);
172 delegate_->GetWebViewClient()->FindInPageMatchCountUpdated(
173 request_id, match_count, final_status_update);
174
175 std::vector<Frame*> frames = delegate_->GetAllFrames();
176 for (Frame* f : frames) {
177 f->StopHighlightingFindResults();
178
179 if (found) {
180 MatchData& match_data = returned_find_data_[f];
181 match_data.count = 0;
182 match_data.final_update = false;
183 f->HighlightFindResults(request_id, mojo::String::From(search_string),
184 mojom::FindOptions::From(options), true);
185 }
186 }
187 }
188 }
189
190 Frame* FindController::GetNextFrameToSearch(uint32_t starting_frame,
191 uint32_t current_frame,
192 bool forward) {
193 std::vector<Frame*>::iterator it;
194 if (current_frame == 0u) {
195 it = GetFrameIteratorById(starting_frame);
196 CHECK(it != find_frames_in_order_.end());
197 return *it;
198 }
199
200 Frame* candidate;
201 it = GetFrameIteratorById(current_frame);
202 if (it == find_frames_in_order_.end()) {
203 // Our current frame has been deleted. There is nothing to be done now; we
204 // will abort.
205 return nullptr;
206 }
207
208 if (forward) {
209 ++it;
210 if (it == find_frames_in_order_.end())
211 it = find_frames_in_order_.begin();
212 candidate = *it;
213 } else {
214 if (it == find_frames_in_order_.begin()) {
215 candidate = find_frames_in_order_.back();
216 } else {
217 --it;
218 candidate = *it;
219 }
220 }
221
222 // If we've looped around the entire frame tree, then we are done and return
223 // null.
224 if (candidate->id() == starting_frame)
225 return nullptr;
226 return candidate;
227 }
228
229 std::vector<Frame*>::iterator FindController::GetFrameIteratorById(
230 uint32_t frame_id) {
231 return find_if(find_frames_in_order_.begin(),
232 find_frames_in_order_.end(),
233 [&frame_id](Frame* f) {
234 return f->id() == frame_id;
235 });
236 }
237
238 } // namespace web_view
OLDNEW
« no previous file with comments | « components/web_view/find_controller.h ('k') | components/web_view/find_controller_delegate.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698