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

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

Issue 1371773003: mandoline: Add find in page. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase to ToT to fix patch failure. 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 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 "components/web_view/web_view_impl.h" 5 #include "components/web_view/web_view_impl.h"
6 6
7 #include <queue>
8
9 #include "base/bind.h"
7 #include "base/command_line.h" 10 #include "base/command_line.h"
8 #include "components/devtools_service/public/cpp/switches.h" 11 #include "components/devtools_service/public/cpp/switches.h"
9 #include "components/mus/public/cpp/scoped_view_ptr.h" 12 #include "components/mus/public/cpp/scoped_view_ptr.h"
10 #include "components/mus/public/cpp/view.h" 13 #include "components/mus/public/cpp/view.h"
11 #include "components/mus/public/cpp/view_tree_connection.h" 14 #include "components/mus/public/cpp/view_tree_connection.h"
12 #include "components/web_view/client_initiated_frame_connection.h" 15 #include "components/web_view/client_initiated_frame_connection.h"
13 #include "components/web_view/frame.h" 16 #include "components/web_view/frame.h"
14 #include "components/web_view/frame_connection.h" 17 #include "components/web_view/frame_connection.h"
15 #include "components/web_view/frame_devtools_agent.h" 18 #include "components/web_view/frame_devtools_agent.h"
16 #include "components/web_view/frame_tree.h" 19 #include "components/web_view/frame_tree.h"
(...skipping 20 matching lines...) Expand all
37 // WebViewImpl, public: 40 // WebViewImpl, public:
38 41
39 WebViewImpl::WebViewImpl(mojo::ApplicationImpl* app, 42 WebViewImpl::WebViewImpl(mojo::ApplicationImpl* app,
40 mojom::WebViewClientPtr client, 43 mojom::WebViewClientPtr client,
41 mojo::InterfaceRequest<mojom::WebView> request) 44 mojo::InterfaceRequest<mojom::WebView> request)
42 : app_(app), 45 : app_(app),
43 client_(client.Pass()), 46 client_(client.Pass()),
44 binding_(this, request.Pass()), 47 binding_(this, request.Pass()),
45 root_(nullptr), 48 root_(nullptr),
46 content_(nullptr), 49 content_(nullptr),
47 navigation_controller_(this) { 50 navigation_controller_(this),
51 current_find_request_(-1) {
48 if (EnableRemoteDebugging()) 52 if (EnableRemoteDebugging())
49 devtools_agent_.reset(new FrameDevToolsAgent(app_, this)); 53 devtools_agent_.reset(new FrameDevToolsAgent(app_, this));
50 OnDidNavigate(); 54 OnDidNavigate();
51 } 55 }
52 56
53 WebViewImpl::~WebViewImpl() { 57 WebViewImpl::~WebViewImpl() {
54 if (content_) 58 if (content_)
55 content_->RemoveObserver(this); 59 content_->RemoveObserver(this);
56 if (root_) { 60 if (root_) {
57 root_->RemoveObserver(this); 61 root_->RemoveObserver(this);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 devtools_agent_->AttachFrame(forward_agent.Pass(), &client_properties); 95 devtools_agent_->AttachFrame(forward_agent.Pass(), &client_properties);
92 } 96 }
93 97
94 mojom::FrameClient* frame_client = frame_connection->frame_client(); 98 mojom::FrameClient* frame_client = frame_connection->frame_client();
95 const uint32_t content_handler_id = frame_connection->GetContentHandlerID(); 99 const uint32_t content_handler_id = frame_connection->GetContentHandlerID();
96 frame_tree_.reset(new FrameTree(content_handler_id, content_, 100 frame_tree_.reset(new FrameTree(content_handler_id, content_,
97 view_tree_client.Pass(), this, frame_client, 101 view_tree_client.Pass(), this, frame_client,
98 frame_connection.Pass(), client_properties)); 102 frame_connection.Pass(), client_properties));
99 } 103 }
100 104
105 std::deque<Frame*> WebViewImpl::GetAllFrames() {
106 std::deque<Frame*> all_frames;
107 std::queue<Frame*> frames_to_search;
108 frames_to_search.push(frame_tree_->root());
109 while (!frames_to_search.empty()) {
110 // TODO(erg): This is not in depth first order. I'm not actually sure how
111 // blink does traversal though.
112 Frame* current = frames_to_search.front();
113 frames_to_search.pop();
114 for (Frame* child : current->children())
115 frames_to_search.push(child);
116 all_frames.push_back(current);
117 }
118 return all_frames;
119 }
120
121 void WebViewImpl::OnContinueFinding(int32_t request_id,
122 const mojo::String& search_text,
123 bool found) {
124 if (!found && !pending_find_frames_.empty()) {
125 // No match found, search on the next frame.
126 Frame* next_frame = pending_find_frames_.front();
127 pending_find_frames_.pop_front();
128 next_frame->Find(request_id, search_text,
129 base::Bind(&WebViewImpl::OnContinueFinding,
130 base::Unretained(this)));
131
132 // TODO(erg): This doesn't deal with wrapping around the document at the
133 // end when there are multiple frames.
134 return;
135 }
136
137 pending_find_frames_.clear();
138
139 // We either found a match or we got the final rejection. Either way, we
140 // alert our caller.
141
142 // If nothing is found, set result to "0 of 0", otherwise, set it to
143 // "-1 of 1" to indicate that we found at least one item, but we don't know
144 // yet what is active.
145 int ordinal = found ? -1 : 0; // -1 here means, we might know more later.
146 int match_count = found ? 1 : 0; // 1 here means possibly more coming.
147
148 // If we find no matches then this will be our last status update.
149 // Otherwise the scoping effort will send more results.
150 bool final_status_update = !found;
151
152 // Send priming messages.
153 client_->ReportFindInPageSelection(request_id, ordinal);
154 client_->ReportFindInPageMatchCount(request_id,
155 match_count, final_status_update);
156
157 // TODO(erg): This doesn't iterate in the same order as the current code
158 // because we don't have the correct iteration primitives.
159 std::deque<Frame*> frames = GetAllFrames();
160 for (Frame* f : frames) {
161 f->CancelPendingScopingEffort();
162
163 if (found) {
164 MatchData& match_data = returned_find_data_[f];
165 match_data.count = 0;
166 match_data.final_update = false;
167 f->ScopeStringMatches(request_id, search_text, true);
168 }
169 }
170 }
171
101 //////////////////////////////////////////////////////////////////////////////// 172 ////////////////////////////////////////////////////////////////////////////////
102 // WebViewImpl, WebView implementation: 173 // WebViewImpl, WebView implementation:
103 174
104 void WebViewImpl::LoadRequest(mojo::URLRequestPtr request) { 175 void WebViewImpl::LoadRequest(mojo::URLRequestPtr request) {
105 navigation_controller_.LoadURL(request.Pass()); 176 navigation_controller_.LoadURL(request.Pass());
106 } 177 }
107 178
108 void WebViewImpl::GetViewTreeClient( 179 void WebViewImpl::GetViewTreeClient(
109 mojo::InterfaceRequest<mojo::ViewTreeClient> view_tree_client) { 180 mojo::InterfaceRequest<mojo::ViewTreeClient> view_tree_client) {
110 mus::ViewTreeConnection::Create(this, view_tree_client.Pass()); 181 mus::ViewTreeConnection::Create(this, view_tree_client.Pass());
111 } 182 }
112 183
184 void WebViewImpl::Find(int32_t request_id, const mojo::String& search_text) {
185 DCHECK(frame_tree_);
186
187 // TODO(erg): While this deals with multiple frames, it does not deal with
188 // going forward or backwards. To do that, we'll have to port all frame
189 // traversal and focusing concepts from blink::WebFrame to mojo::Frame.
190
191 // TODO(erg): This isn't great and causes flashes on character
192 // entry. However, it's needed for now because the internals of TextFinder
193 // still track the entire state of the blink frame tree, and if there are any
194 // frames that have marked text, doing a find clears the results of all
195 // frames _except_ for the first frame that it finds a result on.
196 StopFinding();
197
198 // TODO(erg): This cheap method does not traverse in the order that blink
199 // does.
200 pending_find_frames_ = GetAllFrames();
201
202 current_find_request_ = request_id;
203 returned_find_data_.clear();
204
205 // Prime the continue loop.
206 OnContinueFinding(request_id, search_text, false);
207 }
208
209 void WebViewImpl::StopFinding() {
210 DCHECK(frame_tree_);
211
212 // Don't report any callbacks that we get after this.
213 current_find_request_ = -1;
214
215 for (Frame* f : GetAllFrames())
216 f->StopFinding(true);
217 }
218
113 void WebViewImpl::GoBack() { 219 void WebViewImpl::GoBack() {
114 if (!navigation_controller_.CanGoBack()) 220 if (!navigation_controller_.CanGoBack())
115 return; 221 return;
116 navigation_controller_.GoBack(); 222 navigation_controller_.GoBack();
117 } 223 }
118 224
119 void WebViewImpl::GoForward() { 225 void WebViewImpl::GoForward() {
120 if (!navigation_controller_.CanGoForward()) 226 if (!navigation_controller_.CanGoForward())
121 return; 227 return;
122 navigation_controller_.GoForward(); 228 navigation_controller_.GoForward();
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
196 FrameConnection::CreateConnectionForCanNavigateFrame( 302 FrameConnection::CreateConnectionForCanNavigateFrame(
197 app_, target, request.Pass(), callback); 303 app_, target, request.Pass(), callback);
198 } 304 }
199 305
200 void WebViewImpl::DidStartNavigation(Frame* frame) {} 306 void WebViewImpl::DidStartNavigation(Frame* frame) {}
201 307
202 void WebViewImpl::DidCommitProvisionalLoad(Frame* frame) { 308 void WebViewImpl::DidCommitProvisionalLoad(Frame* frame) {
203 navigation_controller_.FrameDidCommitProvisionalLoad(frame); 309 navigation_controller_.FrameDidCommitProvisionalLoad(frame);
204 } 310 }
205 311
312 void WebViewImpl::DidDestroyFrame(Frame* frame) {
313 auto it = find(pending_find_frames_.begin(), pending_find_frames_.end(),
314 frame);
315 if (it != pending_find_frames_.end())
316 pending_find_frames_.erase(it);
317 }
318
319 void WebViewImpl::OnReportFindInFrameMatchCount(int32_t request_id,
320 Frame* frame,
321 int32_t count,
322 bool final_update) {
323 if (request_id != current_find_request_)
324 return;
325
326 auto it = returned_find_data_.find(frame);
327 if (it == returned_find_data_.end()) {
328 NOTREACHED();
329 return;
330 }
331
332 it->second.count = count;
333 it->second.final_update = final_update;
334
335 int merged_count = 0;
336 bool merged_final_update = true;
337 for (auto const& data : returned_find_data_) {
338 merged_count += data.second.count;
339 merged_final_update = merged_final_update && data.second.final_update;
340 }
341
342 // We can now take the individual FindInFrame messages and construct a
343 // FindInPage message.
344 client_->ReportFindInPageMatchCount(request_id,
345 merged_count,
346 merged_final_update);
347 }
348
349 void WebViewImpl::OnReportFindInPageSelection(int32_t request_id,
350 Frame* frame,
351 int32_t active_match_ordinal) {
352 if (request_id != current_find_request_)
353 return;
354
355 // TODO(erg): This is the one that's really hard. To give an accurate count
356 // here, we need to have all the results for frames that are before the Frame
357 // that contains the selected match so we can add their sums together.
358 //
359 // Thankfully, we don't have to worry about this now. Since there aren't
360 // back/forward controls yet, active_match_ordinal will always be 1.
361 client_->ReportFindInPageSelection(request_id, active_match_ordinal);
362 }
363
206 //////////////////////////////////////////////////////////////////////////////// 364 ////////////////////////////////////////////////////////////////////////////////
207 // WebViewImpl, FrameDevToolsAgentDelegate implementation: 365 // WebViewImpl, FrameDevToolsAgentDelegate implementation:
208 366
209 void WebViewImpl::HandlePageNavigateRequest(const GURL& url) { 367 void WebViewImpl::HandlePageNavigateRequest(const GURL& url) {
210 mojo::URLRequestPtr request(mojo::URLRequest::New()); 368 mojo::URLRequestPtr request(mojo::URLRequest::New());
211 request->url = url.spec(); 369 request->url = url.spec();
212 client_->TopLevelNavigateRequest(request.Pass()); 370 client_->TopLevelNavigateRequest(request.Pass());
213 } 371 }
214 372
215 //////////////////////////////////////////////////////////////////////////////// 373 ////////////////////////////////////////////////////////////////////////////////
216 // WebViewImpl, NavigationControllerDelegate implementation: 374 // WebViewImpl, NavigationControllerDelegate implementation:
217 375
218 void WebViewImpl::OnNavigate(mojo::URLRequestPtr request) { 376 void WebViewImpl::OnNavigate(mojo::URLRequestPtr request) {
219 pending_load_.reset(new PendingWebViewLoad(this)); 377 pending_load_.reset(new PendingWebViewLoad(this));
220 pending_load_->Init(request.Pass()); 378 pending_load_->Init(request.Pass());
221 } 379 }
222 380
223 void WebViewImpl::OnDidNavigate() { 381 void WebViewImpl::OnDidNavigate() {
224 client_->BackForwardChanged(navigation_controller_.CanGoBack() 382 client_->BackForwardChanged(navigation_controller_.CanGoBack()
225 ? ButtonState::BUTTON_STATE_ENABLED 383 ? ButtonState::BUTTON_STATE_ENABLED
226 : ButtonState::BUTTON_STATE_DISABLED, 384 : ButtonState::BUTTON_STATE_DISABLED,
227 navigation_controller_.CanGoForward() 385 navigation_controller_.CanGoForward()
228 ? ButtonState::BUTTON_STATE_ENABLED 386 ? ButtonState::BUTTON_STATE_ENABLED
229 : ButtonState::BUTTON_STATE_DISABLED); 387 : ButtonState::BUTTON_STATE_DISABLED);
230 } 388 }
231 389
232 } // namespace web_view 390 } // namespace web_view
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698