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

Side by Side Diff: webkit/glue/webframeloaderclient_impl.cc

Issue 341030: Moves webview_impl.cc, webframe_impl.cc and webframeloaderclient_impl.cc into... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 11 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « webkit/glue/webframeloaderclient_impl.h ('k') | webkit/glue/webkit_glue.cc » ('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 (c) 2006-2009 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 "config.h"
6
7 #include "Chrome.h"
8 #include "CString.h"
9 #include "Document.h"
10 #include "DocumentLoader.h"
11 #include "HTMLAppletElement.h"
12 #include "HTMLFormElement.h" // needed by FormState.h
13 #include "HTMLNames.h"
14 #include "FormState.h"
15 #include "FrameLoader.h"
16 #include "FrameLoadRequest.h"
17 #include "HitTestResult.h"
18 #include "MIMETypeRegistry.h"
19 #include "MouseEvent.h"
20 #include "Page.h"
21 #include "PlatformString.h"
22 #include "PluginData.h"
23 #include "StringExtras.h"
24 #include "WindowFeatures.h"
25 #undef LOG
26
27 #include "net/base/mime_util.h"
28 #include "webkit/api/public/WebForm.h"
29 #include "webkit/api/public/WebFrameClient.h"
30 #include "webkit/api/public/WebNode.h"
31 #include "webkit/api/public/WebPlugin.h"
32 #include "webkit/api/public/WebPluginParams.h"
33 #include "webkit/api/public/WebSecurityOrigin.h"
34 #include "webkit/api/public/WebURL.h"
35 #include "webkit/api/public/WebURLError.h"
36 #include "webkit/api/public/WebVector.h"
37 #include "webkit/api/public/WebViewClient.h"
38 #include "webkit/api/src/WebDataSourceImpl.h"
39 #include "webkit/api/src/WebPluginContainerImpl.h"
40 #include "webkit/api/src/WebPluginLoadObserver.h"
41 #include "webkit/api/src/WrappedResourceRequest.h"
42 #include "webkit/api/src/WrappedResourceResponse.h"
43 #include "webkit/glue/glue_util.h"
44 #include "webkit/glue/webdevtoolsagent_impl.h"
45 #include "webkit/glue/webframe_impl.h"
46 #include "webkit/glue/webframeloaderclient_impl.h"
47 #include "webkit/glue/webkit_glue.h"
48 #include "webkit/glue/webview_impl.h"
49
50 using namespace WebCore;
51
52 using WebKit::WebData;
53 using WebKit::WebDataSourceImpl;
54 using WebKit::WebNavigationType;
55 using WebKit::WebNavigationPolicy;
56 using WebKit::WebNode;
57 using WebKit::WebPlugin;
58 using WebKit::WebPluginContainerImpl;
59 using WebKit::WebPluginLoadObserver;
60 using WebKit::WebPluginParams;
61 using WebKit::WebString;
62 using WebKit::WebURL;
63 using WebKit::WebURLError;
64 using WebKit::WebURLRequest;
65 using WebKit::WebVector;
66 using WebKit::WrappedResourceRequest;
67 using WebKit::WrappedResourceResponse;
68
69 // Domain for internal error codes.
70 static const char kInternalErrorDomain[] = "WebKit";
71
72 // An internal error code. Used to note a policy change error resulting from
73 // dispatchDecidePolicyForMIMEType not passing the PolicyUse option.
74 enum {
75 ERR_POLICY_CHANGE = -10000,
76 };
77
78 static void CopyStringVector(
79 const Vector<String>& input, WebVector<WebString>* output) {
80 WebVector<WebString> result(input.size());
81 for (size_t i = 0; i < input.size(); ++i)
82 result[i] = webkit_glue::StringToWebString(input[i]);
83 output->swap(result);
84 }
85
86 WebFrameLoaderClient::WebFrameLoaderClient(WebFrameImpl* frame)
87 : webframe_(frame),
88 has_representation_(false),
89 sent_initial_response_to_plugin_(false),
90 next_navigation_policy_(WebKit::WebNavigationPolicyIgnore) {
91 }
92
93 WebFrameLoaderClient::~WebFrameLoaderClient() {
94 }
95
96 void WebFrameLoaderClient::frameLoaderDestroyed() {
97 // When the WebFrame was created, it had an extra reference given to it on
98 // behalf of the Frame. Since the WebFrame owns us, this extra ref also
99 // serves to keep us alive until the FrameLoader is done with us. The
100 // FrameLoader calls this method when it's going away. Therefore, we balance
101 // out that extra reference, which may cause 'this' to be deleted.
102 webframe_->Closing();
103 webframe_->deref();
104 }
105
106 void WebFrameLoaderClient::windowObjectCleared() {
107 if (webframe_->client())
108 webframe_->client()->didClearWindowObject(webframe_);
109
110 WebViewImpl* webview = webframe_->GetWebViewImpl();
111 if (webview) {
112 WebDevToolsAgentImpl* tools_agent = webview->GetWebDevToolsAgentImpl();
113 if (tools_agent)
114 tools_agent->WindowObjectCleared(webframe_);
115 }
116 }
117
118 void WebFrameLoaderClient::documentElementAvailable() {
119 if (webframe_->client())
120 webframe_->client()->didCreateDocumentElement(webframe_);
121 }
122
123 void WebFrameLoaderClient::didCreateScriptContextForFrame() {
124 if (webframe_->client())
125 webframe_->client()->didCreateScriptContext(webframe_);
126 }
127
128 void WebFrameLoaderClient::didDestroyScriptContextForFrame() {
129 if (webframe_->client())
130 webframe_->client()->didDestroyScriptContext(webframe_);
131 }
132
133 void WebFrameLoaderClient::didCreateIsolatedScriptContext() {
134 if (webframe_->client())
135 webframe_->client()->didCreateIsolatedScriptContext(webframe_);
136 }
137
138 void WebFrameLoaderClient::didPerformFirstNavigation() const {
139 }
140
141 void WebFrameLoaderClient::registerForIconNotification(bool listen){
142 }
143
144 bool WebFrameLoaderClient::hasWebView() const {
145 return webframe_->GetWebViewImpl() != NULL;
146 }
147
148 bool WebFrameLoaderClient::hasFrameView() const {
149 // The Mac port has this notion of a WebFrameView, which seems to be
150 // some wrapper around an NSView. Since our equivalent is HWND, I guess
151 // we have a "frameview" whenever we have the toplevel HWND.
152 return webframe_->GetWebViewImpl() != NULL;
153 }
154
155 void WebFrameLoaderClient::makeDocumentView() {
156 webframe_->CreateFrameView();
157 }
158
159 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*) {
160 has_representation_ = true;
161 }
162
163 void WebFrameLoaderClient::forceLayout() {
164 // FIXME
165 }
166 void WebFrameLoaderClient::forceLayoutForNonHTML() {
167 // FIXME
168 }
169
170 void WebFrameLoaderClient::setCopiesOnScroll() {
171 // FIXME
172 }
173
174 void WebFrameLoaderClient::detachedFromParent2() {
175 // Nothing to do here.
176 }
177
178 void WebFrameLoaderClient::detachedFromParent3() {
179 // Close down the proxy. The purpose of this change is to make the
180 // call to ScriptController::clearWindowShell a no-op when called from
181 // Frame::pageDestroyed. Without this change, this call to clearWindowShell
182 // will cause a crash. If you remove/modify this, just ensure that you can
183 // go to a page and then navigate to a new page without getting any asserts
184 // or crashes.
185 webframe_->frame()->script()->proxy()->clearForClose();
186 }
187
188 // This function is responsible for associating the |identifier| with a given
189 // subresource load. The following functions that accept an |identifier| are
190 // called for each subresource, so they should not be dispatched to the
191 // WebFrame.
192 void WebFrameLoaderClient::assignIdentifierToInitialRequest(
193 unsigned long identifier, DocumentLoader* loader,
194 const ResourceRequest& request) {
195 if (webframe_->client()) {
196 WrappedResourceRequest webreq(request);
197 webframe_->client()->assignIdentifierToRequest(
198 webframe_, identifier, webreq);
199 }
200 }
201
202 // Determines whether the request being loaded by |loader| is a frame or a
203 // subresource. A subresource in this context is anything other than a frame --
204 // this includes images and xmlhttp requests. It is important to note that a
205 // subresource is NOT limited to stuff loaded through the frame's subresource
206 // loader. Synchronous xmlhttp requests for example, do not go through the
207 // subresource loader, but we still label them as TargetIsSubResource.
208 //
209 // The important edge cases to consider when modifying this function are
210 // how synchronous resource loads are treated during load/unload threshold.
211 static ResourceRequest::TargetType DetermineTargetTypeFromLoader(
212 DocumentLoader* loader) {
213 if (loader == loader->frameLoader()->provisionalDocumentLoader()) {
214 if (loader->frameLoader()->isLoadingMainFrame()) {
215 return ResourceRequest::TargetIsMainFrame;
216 } else {
217 return ResourceRequest::TargetIsSubFrame;
218 }
219 }
220 return ResourceRequest::TargetIsSubResource;
221 }
222
223 void WebFrameLoaderClient::dispatchWillSendRequest(
224 DocumentLoader* loader, unsigned long identifier, ResourceRequest& request,
225 const ResourceResponse& redirect_response) {
226
227 if (loader) {
228 // We want to distinguish between a request for a document to be loaded into
229 // the main frame, a sub-frame, or the sub-objects in that document.
230 request.setTargetType(DetermineTargetTypeFromLoader(loader));
231 }
232
233 // FrameLoader::loadEmptyDocumentSynchronously() creates an empty document
234 // with no URL. We don't like that, so we'll rename it to about:blank.
235 if (request.url().isEmpty())
236 request.setURL(KURL(ParsedURLString, "about:blank"));
237 if (request.firstPartyForCookies().isEmpty())
238 request.setFirstPartyForCookies(KURL(ParsedURLString, "about:blank"));
239
240 // Give the WebFrameClient a crack at the request.
241 if (webframe_->client()) {
242 WrappedResourceRequest webreq(request);
243 WrappedResourceResponse webresp(redirect_response);
244 webframe_->client()->willSendRequest(
245 webframe_, identifier, webreq, webresp);
246 }
247 }
248
249 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*,
250 unsigned long identifier) {
251 // FIXME
252 // Intended to pass through to a method on the resource load delegate.
253 // If implemented, that method controls whether the browser should ask the
254 // networking layer for a stored default credential for the page (say from
255 // the Mac OS keychain). If the method returns false, the user should be
256 // presented with an authentication challenge whether or not the networking
257 // layer has a credential stored.
258 // This returns true for backward compatibility: the ability to override the
259 // system credential store is new. (Actually, not yet fully implemented in
260 // WebKit, as of this writing.)
261 return true;
262 }
263
264 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(
265 DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) {
266 // FIXME
267 }
268
269 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(
270 DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&) {
271 // FIXME
272 }
273
274 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader,
275 unsigned long identifier,
276 const ResourceResponse& re sponse) {
277 if (webframe_->client()) {
278 WrappedResourceResponse webresp(response);
279 webframe_->client()->didReceiveResponse(webframe_, identifier, webresp);
280 }
281 }
282
283 void WebFrameLoaderClient::dispatchDidReceiveContentLength(
284 DocumentLoader* loader,
285 unsigned long identifier,
286 int length_received) {
287 }
288
289 // Called when a particular resource load completes
290 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader,
291 unsigned long identifier) {
292 if (webframe_->client())
293 webframe_->client()->didFinishResourceLoad(webframe_, identifier);
294 }
295
296 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader,
297 unsigned long identifier,
298 const ResourceError& error) {
299 if (webframe_->client()) {
300 webframe_->client()->didFailResourceLoad(
301 webframe_, identifier, webkit_glue::ResourceErrorToWebURLError(error));
302 }
303 }
304
305 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad() {
306 // A frame may be reused. This call ensures we don't hold on to our password
307 // listeners and their associated HTMLInputElements.
308 webframe_->ClearPasswordListeners();
309
310 if (webframe_->client())
311 webframe_->client()->didFinishDocumentLoad(webframe_);
312 }
313
314 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(
315 DocumentLoader* loader,
316 const ResourceRequest& request,
317 const ResourceResponse& response,
318 int length) {
319 if (webframe_->client()) {
320 WrappedResourceRequest webreq(request);
321 WrappedResourceResponse webresp(response);
322 webframe_->client()->didLoadResourceFromMemoryCache(
323 webframe_, webreq, webresp);
324 }
325 return false; // Do not suppress remaining notifications
326 }
327
328 void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(
329 unsigned long identifier,
330 const ScriptString& source) {
331 }
332
333 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents() {
334 if (webframe_->client())
335 webframe_->client()->didHandleOnloadEvents(webframe_);
336 }
337
338 // Redirect Tracking
339 // =================
340 // We want to keep track of the chain of redirects that occur during page
341 // loading. There are two types of redirects, server redirects which are HTTP
342 // response codes, and client redirects which are document.location= and meta
343 // refreshes.
344 //
345 // This outlines the callbacks that we get in different redirect situations,
346 // and how each call modifies the redirect chain.
347 //
348 // Normal page load
349 // ----------------
350 // dispatchDidStartProvisionalLoad() -> adds URL to the redirect list
351 // dispatchDidCommitLoad() -> DISPATCHES & clears list
352 //
353 // Server redirect (success)
354 // -------------------------
355 // dispatchDidStartProvisionalLoad() -> adds source URL
356 // dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL
357 // dispatchDidCommitLoad() -> DISPATCHES
358 //
359 // Client redirect (success)
360 // -------------------------
361 // (on page)
362 // dispatchWillPerformClientRedirect() -> saves expected redirect
363 // dispatchDidStartProvisionalLoad() -> appends redirect source (since
364 // it matches the expected redirect)
365 // and the current page as the dest)
366 // dispatchDidCancelClientRedirect() -> clears expected redirect
367 // dispatchDidCommitLoad() -> DISPATCHES
368 //
369 // Client redirect (cancelled)
370 // (e.g meta-refresh trumped by manual doc.location change, or just cancelled
371 // because a link was clicked that requires the meta refresh to be rescheduled
372 // (the SOURCE URL may have changed).
373 // ---------------------------
374 // dispatchDidCancelClientRedirect() -> clears expected redire ct
375 // dispatchDidStartProvisionalLoad() -> adds only URL to redir ect list
376 // dispatchDidCommitLoad() -> DISPATCHES & clears li st
377 // rescheduled ? dispatchWillPerformClientRedirect() -> saves expected redirec t
378 // : nothing
379
380 // Client redirect (failure)
381 // -------------------------
382 // (on page)
383 // dispatchWillPerformClientRedirect() -> saves expected redirect
384 // dispatchDidStartProvisionalLoad() -> appends redirect source (since
385 // it matches the expected redirect)
386 // and the current page as the dest)
387 // dispatchDidCancelClientRedirect()
388 // dispatchDidFailProvisionalLoad()
389 //
390 // Load 1 -> Server redirect to 2 -> client redirect to 3 -> server redirect to 4
391 // ----------------------------------------------------------------------------- -
392 // dispatchDidStartProvisionalLoad() -> adds source URL 1
393 // dispatchDidReceiveServerRedirectForProvisionalLoad() -> adds dest URL 2
394 // dispatchDidCommitLoad() -> DISPATCHES 1+2
395 // -- begin client redirect and NEW DATA SOURCE
396 // dispatchWillPerformClientRedirect() -> saves expected redi rect
397 // dispatchDidStartProvisionalLoad() -> appends URL 2 and U RL 3
398 // dispatchDidReceiveServerRedirectForProvisionalLoad() -> appends destination URL 4
399 // dispatchDidCancelClientRedirect() -> clears expected red irect
400 // dispatchDidCommitLoad() -> DISPATCHES
401 //
402 // Interesting case with multiple location changes involving anchors.
403 // Load page 1 containing future client-redirect (back to 1, e.g meta refresh) > Click
404 // on a link back to the same page (i.e an anchor href) >
405 // client-redirect finally fires (with new source, set to 1#anchor)
406 // -----------------------------------------------------------------------------
407 // dispatchWillPerformClientRedirect(non-zero 'interval' param) -> saves expec ted redirect
408 // -- click on anchor href
409 // dispatchDidCancelClientRedirect() -> clears expe cted redirect
410 // dispatchDidStartProvisionalLoad() -> adds 1#anch or source
411 // dispatchDidCommitLoad() -> DISPATCHES 1#anchor
412 // dispatchWillPerformClientRedirect() -> saves exp. source (1#anchor)
413 // -- redirect timer fires
414 // dispatchDidStartProvisionalLoad() -> appends 1#a nchor (src) and 1 (dest)
415 // dispatchDidCancelClientRedirect() -> clears expe cted redirect
416 // dispatchDidCommitLoad() -> DISPATCHES 1#anchor + 1
417 //
418 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad() {
419 WebDataSourceImpl* ds = webframe_->GetProvisionalDataSourceImpl();
420 if (!ds) {
421 // Got a server redirect when there is no provisional DS!
422 ASSERT_NOT_REACHED();
423 return;
424 }
425
426 // The server redirect may have been blocked.
427 if (ds->request().isNull())
428 return;
429
430 // A provisional load should have started already, which should have put an
431 // entry in our redirect chain.
432 ASSERT(ds->hasRedirectChain());
433
434 // The URL of the destination is on the provisional data source. We also need
435 // to update the redirect chain to account for this addition (we do this
436 // before the callback so the callback can look at the redirect chain to see
437 // what happened).
438 ds->appendRedirect(webkit_glue::WebURLToKURL(ds->request().url()));
439
440 if (webframe_->client())
441 webframe_->client()->didReceiveServerRedirectForProvisionalLoad(webframe_);
442 }
443
444 // Called on both success and failure of a client redirect.
445 void WebFrameLoaderClient::dispatchDidCancelClientRedirect() {
446 // No longer expecting a client redirect.
447 if (webframe_->client()) {
448 expected_client_redirect_src_ = KURL();
449 expected_client_redirect_dest_ = KURL();
450 webframe_->client()->didCancelClientRedirect(webframe_);
451 }
452
453 // No need to clear the redirect chain, since that data source has already
454 // been deleted by the time this function is called.
455 }
456
457 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(
458 const KURL& url,
459 double interval,
460 double fire_date) {
461 // Tells dispatchDidStartProvisionalLoad that if it sees this item it is a
462 // redirect and the source item should be added as the start of the chain.
463 expected_client_redirect_src_ = webkit_glue::WebURLToKURL(webframe_->url());
464 expected_client_redirect_dest_ = url;
465
466 // TODO(timsteele): bug 1135512. Webkit does not properly notify us of
467 // cancelling http > file client redirects. Since the FrameLoader's policy
468 // is to never carry out such a navigation anyway, the best thing we can do
469 // for now to not get confused is ignore this notification.
470 if (expected_client_redirect_dest_.isLocalFile() &&
471 expected_client_redirect_src_.protocolInHTTPFamily()) {
472 expected_client_redirect_src_ = KURL();
473 expected_client_redirect_dest_ = KURL();
474 return;
475 }
476
477 if (webframe_->client()) {
478 webframe_->client()->willPerformClientRedirect(
479 webframe_,
480 webkit_glue::KURLToWebURL(expected_client_redirect_src_),
481 webkit_glue::KURLToWebURL(expected_client_redirect_dest_),
482 static_cast<unsigned int>(interval),
483 static_cast<unsigned int>(fire_date));
484 }
485 }
486
487 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage() {
488 // Anchor fragment navigations are not normal loads, so we need to synthesize
489 // some events for our delegate.
490 WebViewImpl* webview = webframe_->GetWebViewImpl();
491 if (webview->client())
492 webview->client()->didStartLoading();
493
494 WebDataSourceImpl* ds = webframe_->GetDataSourceImpl();
495 ASSERT(ds); // Should not be null when navigating to a reference fragment!
496 if (ds) {
497 KURL url = webkit_glue::WebURLToKURL(ds->request().url());
498 KURL chain_end;
499 if (ds->hasRedirectChain()) {
500 chain_end = ds->endOfRedirectChain();
501 ds->clearRedirectChain();
502 }
503
504 // Figure out if this location change is because of a JS-initiated client
505 // redirect (e.g onload/setTimeout document.location.href=).
506 // TODO(timsteele): (bugs 1085325, 1046841) We don't get proper redirect
507 // performed/cancelled notifications across anchor navigations, so the
508 // other redirect-tracking code in this class (see dispatch*ClientRedirect()
509 // and dispatchDidStartProvisionalLoad) is insufficient to catch and
510 // properly flag these transitions. Once a proper fix for this bug is
511 // identified and applied the following block may no longer be required.
512 bool was_client_redirect =
513 (url == expected_client_redirect_dest_ &&
514 chain_end == expected_client_redirect_src_) ||
515 !webframe_->isProcessingUserGesture();
516
517 if (was_client_redirect) {
518 if (webframe_->client()) {
519 webframe_->client()->didCompleteClientRedirect(
520 webframe_, webkit_glue::KURLToWebURL(chain_end));
521 }
522 ds->appendRedirect(chain_end);
523 // Make sure we clear the expected redirect since we just effectively
524 // completed it.
525 expected_client_redirect_src_ = KURL();
526 expected_client_redirect_dest_ = KURL();
527 }
528
529 // Regardless of how we got here, we are navigating to a URL so we need to
530 // add it to the redirect chain.
531 ds->appendRedirect(url);
532 }
533
534 bool is_new_navigation;
535 webview->DidCommitLoad(&is_new_navigation);
536 if (webframe_->client()) {
537 webframe_->client()->didChangeLocationWithinPage(
538 webframe_, is_new_navigation);
539 }
540
541 if (webview->client())
542 webview->client()->didStopLoading();
543 }
544
545 void WebFrameLoaderClient::dispatchWillClose() {
546 if (webframe_->client())
547 webframe_->client()->willClose(webframe_);
548 }
549
550 void WebFrameLoaderClient::dispatchDidReceiveIcon() {
551 // The icon database is disabled, so this should never be called.
552 ASSERT_NOT_REACHED();
553 }
554
555 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad() {
556 // In case a redirect occurs, we need this to be set so that the redirect
557 // handling code can tell where the redirect came from. Server redirects
558 // will occur on the provisional load, so we need to keep track of the most
559 // recent provisional load URL.
560 // See dispatchDidReceiveServerRedirectForProvisionalLoad.
561 WebDataSourceImpl* ds = webframe_->GetProvisionalDataSourceImpl();
562 if (!ds) {
563 ASSERT_NOT_REACHED();
564 return;
565 }
566 KURL url = webkit_glue::WebURLToKURL(ds->request().url());
567
568 // Since the provisional load just started, we should have not gotten
569 // any redirects yet.
570 ASSERT(!ds->hasRedirectChain());
571
572 // If this load is what we expected from a client redirect, treat it as a
573 // redirect from that original page. The expected redirect urls will be
574 // cleared by DidCancelClientRedirect.
575 bool completing_client_redirect = false;
576 if (expected_client_redirect_src_.isValid()) {
577 // expected_client_redirect_dest_ could be something like
578 // "javascript:history.go(-1)" thus we need to exclude url starts with
579 // "javascript:". See bug: 1080873
580 ASSERT(expected_client_redirect_dest_.protocolIs("javascript") ||
581 expected_client_redirect_dest_ == url);
582 ds->appendRedirect(expected_client_redirect_src_);
583 completing_client_redirect = true;
584 }
585 ds->appendRedirect(url);
586
587 if (webframe_->client()) {
588 // As the comment for DidCompleteClientRedirect in webview_delegate.h
589 // points out, whatever information its invocation contains should only
590 // be considered relevant until the next provisional load has started.
591 // So we first tell the delegate that the load started, and then tell it
592 // about the client redirect the load is responsible for completing.
593 webframe_->client()->didStartProvisionalLoad(webframe_);
594 if (completing_client_redirect)
595 webframe_->client()->didCompleteClientRedirect(
596 webframe_, webkit_glue::KURLToWebURL(expected_client_redirect_src_));
597 }
598 }
599
600 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title) {
601 if (webframe_->client()) {
602 webframe_->client()->didReceiveTitle(
603 webframe_, webkit_glue::StringToWebString(title));
604 }
605 }
606
607 void WebFrameLoaderClient::dispatchDidCommitLoad() {
608 WebViewImpl* webview = webframe_->GetWebViewImpl();
609 bool is_new_navigation;
610 webview->DidCommitLoad(&is_new_navigation);
611
612 if (webframe_->client()) {
613 webframe_->client()->didCommitProvisionalLoad(
614 webframe_, is_new_navigation);
615 }
616
617 WebDevToolsAgentImpl* tools_agent = webview->GetWebDevToolsAgentImpl();
618 if (tools_agent) {
619 tools_agent->DidCommitLoadForFrame(webview, webframe_, is_new_navigation);
620 }
621 }
622
623 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(
624 const ResourceError& error) {
625 // If a policy change occured, then we do not want to inform the plugin
626 // delegate. See bug 907789 for details.
627 // TODO(darin): This means the plugin won't receive NPP_URLNotify, which
628 // seems like it could result in a memory leak in the plugin!!
629 if (error.domain() == kInternalErrorDomain &&
630 error.errorCode() == ERR_POLICY_CHANGE) {
631 webframe_->DidFail(cancelledError(error.failingURL()), true);
632 return;
633 }
634
635 OwnPtr<WebPluginLoadObserver> plugin_load_observer = GetPluginLoadObserver();
636 webframe_->DidFail(error, true);
637 if (plugin_load_observer)
638 plugin_load_observer->didFailLoading(error);
639 }
640
641 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error) {
642 OwnPtr<WebPluginLoadObserver> plugin_load_observer = GetPluginLoadObserver();
643 webframe_->DidFail(error, false);
644 if (plugin_load_observer)
645 plugin_load_observer->didFailLoading(error);
646
647 // Don't clear the redirect chain, this will happen in the middle of client
648 // redirects, and we need the context. The chain will be cleared when the
649 // provisional load succeeds or fails, not the "real" one.
650 }
651
652 void WebFrameLoaderClient::dispatchDidFinishLoad() {
653 OwnPtr<WebPluginLoadObserver> plugin_load_observer = GetPluginLoadObserver();
654
655 if (webframe_->client())
656 webframe_->client()->didFinishLoad(webframe_);
657
658 if (plugin_load_observer)
659 plugin_load_observer->didFinishLoading();
660
661 // Don't clear the redirect chain, this will happen in the middle of client
662 // redirects, and we need the context. The chain will be cleared when the
663 // provisional load succeeds or fails, not the "real" one.
664 }
665
666 void WebFrameLoaderClient::dispatchDidFirstLayout() {
667 }
668
669 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout() {
670 // FIXME: called when webkit finished layout of a page that was visually
671 // non-empty.
672 // All resources have not necessarily finished loading.
673 }
674
675 Frame* WebFrameLoaderClient::dispatchCreatePage() {
676 struct WebCore::WindowFeatures features;
677 Page* new_page = webframe_->frame()->page()->chrome()->createWindow(
678 webframe_->frame(), FrameLoadRequest(), features);
679
680 // Make sure that we have a valid disposition. This should have been set in
681 // the preceeding call to dispatchDecidePolicyForNewWindowAction.
682 ASSERT(next_navigation_policy_ != WebKit::WebNavigationPolicyIgnore);
683 WebNavigationPolicy policy = next_navigation_policy_;
684 next_navigation_policy_ = WebKit::WebNavigationPolicyIgnore;
685
686 // createWindow can return NULL (e.g., popup blocker denies the window).
687 if (!new_page)
688 return NULL;
689
690 WebViewImpl::FromPage(new_page)->set_initial_navigation_policy(policy);
691 return new_page->mainFrame();
692 }
693
694 void WebFrameLoaderClient::dispatchShow() {
695 WebViewImpl* webview = webframe_->GetWebViewImpl();
696 if (webview && webview->client())
697 webview->client()->show(webview->initial_navigation_policy());
698 }
699
700 static bool TreatAsAttachment(const ResourceResponse& response) {
701 const String& content_disposition =
702 response.httpHeaderField("Content-Disposition");
703 if (content_disposition.isEmpty())
704 return false;
705
706 // Some broken sites just send
707 // Content-Disposition: ; filename="file"
708 // screen those out here.
709 if (content_disposition.startsWith(";"))
710 return false;
711
712 if (content_disposition.startsWith("inline", false))
713 return false;
714
715 // Some broken sites just send
716 // Content-Disposition: filename="file"
717 // without a disposition token... screen those out.
718 if (content_disposition.startsWith("filename", false))
719 return false;
720
721 // Also in use is Content-Disposition: name="file"
722 if (content_disposition.startsWith("name", false))
723 return false;
724
725 // We have a content-disposition of "attachment" or unknown.
726 // RFC 2183, section 2.8 says that an unknown disposition
727 // value should be treated as "attachment"
728 return true;
729 }
730
731 void WebFrameLoaderClient::dispatchDecidePolicyForMIMEType(
732 FramePolicyFunction function,
733 const String& mime_type,
734 const ResourceRequest&) {
735 const ResourceResponse& response =
736 webframe_->frame()->loader()->activeDocumentLoader()->response();
737
738 PolicyAction action;
739
740 int status_code = response.httpStatusCode();
741 if (status_code == 204 || status_code == 205) {
742 // The server does not want us to replace the page contents.
743 action = PolicyIgnore;
744 } else if (TreatAsAttachment(response)) {
745 // The server wants us to download instead of replacing the page contents.
746 // Downloading is handled by the embedder, but we still get the initial
747 // response so that we can ignore it and clean up properly.
748 action = PolicyIgnore;
749 } else if (!canShowMIMEType(mime_type)) {
750 // Make sure that we can actually handle this type internally.
751 action = PolicyIgnore;
752 } else {
753 // OK, we will render this page.
754 action = PolicyUse;
755 }
756
757 // NOTE: ERR_POLICY_CHANGE will be generated when action is not PolicyUse.
758 (webframe_->frame()->loader()->policyChecker()->*function)(action);
759 }
760
761 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(
762 WebCore::FramePolicyFunction function,
763 const WebCore::NavigationAction& action,
764 const WebCore::ResourceRequest& request,
765 PassRefPtr<WebCore::FormState> form_state,
766 const WebCore::String& frame_name) {
767 WebNavigationPolicy navigation_policy;
768 if (!ActionSpecifiesNavigationPolicy(action, &navigation_policy))
769 navigation_policy = WebKit::WebNavigationPolicyNewForegroundTab;
770
771 PolicyAction policy_action;
772 if (navigation_policy == WebKit::WebNavigationPolicyDownload) {
773 policy_action = PolicyDownload;
774 } else {
775 policy_action = PolicyUse;
776
777 // Remember the disposition for when dispatchCreatePage is called. It is
778 // unfortunate that WebCore does not provide us with any context when
779 // creating or showing the new window that would allow us to avoid having
780 // to keep this state.
781 next_navigation_policy_ = navigation_policy;
782 }
783 (webframe_->frame()->loader()->policyChecker()->*function)(policy_action);
784 }
785
786 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(
787 WebCore::FramePolicyFunction function,
788 const WebCore::NavigationAction& action,
789 const WebCore::ResourceRequest& request,
790 PassRefPtr<WebCore::FormState> form_state) {
791 PolicyAction policy_action = PolicyIgnore;
792
793 // It is valid for this function to be invoked in code paths where the
794 // the webview is closed.
795 // The NULL check here is to fix a crash that seems strange
796 // (see - https://bugs.webkit.org/show_bug.cgi?id=23554).
797 if (webframe_->client() && !request.url().isNull()) {
798 WebNavigationPolicy navigation_policy =
799 WebKit::WebNavigationPolicyCurrentTab;
800 ActionSpecifiesNavigationPolicy(action, &navigation_policy);
801
802 // Give the delegate a chance to change the navigation policy.
803 const WebDataSourceImpl* ds = webframe_->GetProvisionalDataSourceImpl();
804 if (ds) {
805 KURL url = webkit_glue::WebURLToKURL(ds->request().url());
806 if (url.protocolIs(WebKit::backForwardNavigationScheme)) {
807 HandleBackForwardNavigation(url);
808 navigation_policy = WebKit::WebNavigationPolicyIgnore;
809 } else {
810 bool is_redirect = ds->hasRedirectChain();
811
812 WebNavigationType webnav_type =
813 WebDataSourceImpl::toWebNavigationType(action.type());
814
815 RefPtr<WebCore::Node> node;
816 for (const Event* event = action.event(); event;
817 event = event->underlyingEvent()) {
818 if (event->isMouseEvent()) {
819 const MouseEvent* mouse_event =
820 static_cast<const MouseEvent*>(event);
821 node = webframe_->frame()->eventHandler()->hitTestResultAtPoint(
822 mouse_event->absoluteLocation(), false).innerNonSharedNode();
823 break;
824 }
825 }
826 WebNode originating_node = webkit_glue::NodeToWebNode(node);
827
828 navigation_policy = webframe_->client()->decidePolicyForNavigation(
829 webframe_, ds->request(), webnav_type, originating_node,
830 navigation_policy, is_redirect);
831 }
832 }
833
834 if (navigation_policy == WebKit::WebNavigationPolicyCurrentTab) {
835 policy_action = PolicyUse;
836 } else if (navigation_policy == WebKit::WebNavigationPolicyDownload) {
837 policy_action = PolicyDownload;
838 } else {
839 if (navigation_policy != WebKit::WebNavigationPolicyIgnore) {
840 WrappedResourceRequest webreq(request);
841 webframe_->client()->loadURLExternally(
842 webframe_, webreq, navigation_policy);
843 }
844 policy_action = PolicyIgnore;
845 }
846 }
847
848 (webframe_->frame()->loader()->policyChecker()->*function)(policy_action);
849 }
850
851 void WebFrameLoaderClient::cancelPolicyCheck() {
852 // FIXME
853 }
854
855 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(
856 const ResourceError& error) {
857 WebKit::WebURLError url_error =
858 webkit_glue::ResourceErrorToWebURLError(error);
859 webframe_->client()->unableToImplementPolicyWithError(webframe_, url_error);
860 }
861
862 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function,
863 PassRefPtr<FormState> form_ref) {
864 if (webframe_->client()) {
865 webframe_->client()->willSubmitForm(
866 webframe_, webkit_glue::HTMLFormElementToWebForm(form_ref->form()));
867 }
868 (webframe_->frame()->loader()->policyChecker()->*function)(PolicyUse);
869 }
870
871 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*) {
872 // FIXME
873 }
874
875 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*) {
876 has_representation_ = true;
877 }
878
879 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*,
880 const ResourceError& error) {
881 if (plugin_widget_.get()) {
882 if (sent_initial_response_to_plugin_) {
883 plugin_widget_->didFailLoading(error);
884 sent_initial_response_to_plugin_ = false;
885 }
886 plugin_widget_ = NULL;
887 }
888 }
889
890 void WebFrameLoaderClient::postProgressStartedNotification() {
891 WebViewImpl* webview = webframe_->GetWebViewImpl();
892 if (webview && webview->client())
893 webview->client()->didStartLoading();
894 }
895
896 void WebFrameLoaderClient::postProgressEstimateChangedNotification() {
897 // FIXME
898 }
899
900 void WebFrameLoaderClient::postProgressFinishedNotification() {
901 // TODO(ericroman): why might the webview be null?
902 // http://b/1234461
903 WebViewImpl* webview = webframe_->GetWebViewImpl();
904 if (webview && webview->client())
905 webview->client()->didStopLoading();
906 }
907
908 void WebFrameLoaderClient::setMainFrameDocumentReady(bool ready) {
909 // FIXME
910 }
911
912 // Creates a new connection and begins downloading from that (contrast this
913 // with |download|).
914 void WebFrameLoaderClient::startDownload(const ResourceRequest& request) {
915 if (webframe_->client()) {
916 WrappedResourceRequest webreq(request);
917 webframe_->client()->loadURLExternally(
918 webframe_, webreq, WebKit::WebNavigationPolicyDownload);
919 }
920 }
921
922 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*) {
923 // FIXME
924 }
925
926 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*) {
927 // FIXME
928 }
929
930 // Called whenever data is received.
931 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* dat a, int length) {
932 if (!plugin_widget_.get()) {
933 if (webframe_->client()) {
934 bool preventDefault = false;
935 webframe_->client()->didReceiveDocumentData(webframe_, data, length, preve ntDefault);
936 if (!preventDefault)
937 webframe_->commitDocumentData(data, length);
938 }
939 }
940
941 // If we are sending data to WebCore::MediaDocument, we should stop here
942 // and cancel the request.
943 if (webframe_->frame()->document() &&
944 webframe_->frame()->document()->isMediaDocument()) {
945 loader->cancelMainResourceLoad(
946 pluginWillHandleLoadError(loader->response()));
947 }
948
949 // The plugin widget could have been created in the webframe_->DidReceiveData
950 // function.
951 if (plugin_widget_.get()) {
952 if (!sent_initial_response_to_plugin_) {
953 sent_initial_response_to_plugin_ = true;
954 plugin_widget_->didReceiveResponse(
955 webframe_->frame()->loader()->activeDocumentLoader()->response());
956 }
957 plugin_widget_->didReceiveData(data, length);
958 }
959 }
960
961 void WebFrameLoaderClient::finishedLoading(DocumentLoader* dl) {
962 if (plugin_widget_.get()) {
963 plugin_widget_->didFinishLoading();
964 plugin_widget_ = NULL;
965 sent_initial_response_to_plugin_ = false;
966 } else {
967 // This is necessary to create an empty document. See bug 634004.
968 // However, we only want to do this if makeRepresentation has been called, t o
969 // match the behavior on the Mac.
970 if (has_representation_)
971 dl->frameLoader()->setEncoding("", false);
972 }
973 }
974
975 void WebFrameLoaderClient::updateGlobalHistory() {
976 }
977
978 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() {
979 }
980
981 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const {
982 // FIXME
983 return true;
984 }
985
986 void WebFrameLoaderClient::didDisplayInsecureContent() {
987 if (webframe_->client())
988 webframe_->client()->didDisplayInsecureContent(webframe_);
989 }
990
991 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin* origin) {
992 if (webframe_->client()) {
993 webframe_->client()->didRunInsecureContent(webframe_,
994 webkit_glue::SecurityOriginToWebSecurityOrigin(origin));
995 }
996 }
997
998 ResourceError WebFrameLoaderClient::blockedError(const WebCore::ResourceRequest& ) {
999 // FIXME
1000 return ResourceError();
1001 }
1002
1003 ResourceError WebFrameLoaderClient::cancelledError(
1004 const ResourceRequest& request) {
1005 if (!webframe_->client())
1006 return ResourceError();
1007
1008 return webkit_glue::WebURLErrorToResourceError(
1009 webframe_->client()->cancelledError(
1010 webframe_, WrappedResourceRequest(request)));
1011 }
1012
1013 ResourceError WebFrameLoaderClient::cannotShowURLError(
1014 const ResourceRequest& request) {
1015 if (!webframe_->client())
1016 return ResourceError();
1017
1018 return webkit_glue::WebURLErrorToResourceError(
1019 webframe_->client()->cannotHandleRequestError(
1020 webframe_, WrappedResourceRequest(request)));
1021 }
1022
1023 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(
1024 const ResourceRequest& request) {
1025 return ResourceError(kInternalErrorDomain, ERR_POLICY_CHANGE,
1026 request.url().string(), String());
1027 }
1028
1029 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceRespon se&) {
1030 // FIXME
1031 return ResourceError();
1032 }
1033
1034 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse &) {
1035 // FIXME
1036 return ResourceError();
1037 }
1038
1039 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const WebCore::Res ourceResponse&) {
1040 // FIXME
1041 return ResourceError();
1042 }
1043
1044 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error) {
1045 // This method is called when we fail to load the URL for an <object> tag
1046 // that has fallback content (child elements) and is being loaded as a frame.
1047 // The error parameter indicates the reason for the load failure.
1048 // We should let the fallback content load only if this wasn't a cancelled
1049 // request.
1050 // Note: The mac version also has a case for "WebKitErrorPluginWillHandleLoad"
1051 ResourceError cancelled_error = cancelledError(ResourceRequest());
1052 return error.errorCode() != cancelled_error.errorCode() ||
1053 error.domain() != cancelled_error.domain();
1054 }
1055
1056 bool WebFrameLoaderClient::canHandleRequest(
1057 const ResourceRequest& request) const {
1058 return webframe_->client()->canHandleRequest(
1059 webframe_, WrappedResourceRequest(request));
1060 }
1061
1062 bool WebFrameLoaderClient::canShowMIMEType(const String& mime_type) const {
1063 // This method is called to determine if the media type can be shown
1064 // "internally" (i.e. inside the browser) regardless of whether or not the
1065 // browser or a plugin is doing the rendering.
1066
1067 // mime_type strings are supposed to be ASCII, but if they are not for some
1068 // reason, then it just means that the mime type will fail all of these "is
1069 // supported" checks and go down the path of an unhandled mime type.
1070 if (net::IsSupportedMimeType(
1071 webkit_glue::CStringToStdString(mime_type.latin1())))
1072 return true;
1073
1074 // If Chrome is started with the --disable-plugins switch, pluginData is null.
1075 WebCore::PluginData* plugin_data = webframe_->frame()->page()->pluginData();
1076
1077 // See if the type is handled by an installed plugin, if so, we can show it.
1078 // TODO(beng): (http://b/1085524) This is the place to stick a preference to
1079 // disable full page plugins (optionally for certain types!)
1080 return !mime_type.isEmpty() && plugin_data && plugin_data->supportsMimeType(mi me_type);
1081 }
1082
1083 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLSch eme) const {
1084 // FIXME
1085 return false;
1086 }
1087
1088 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLSche me) const {
1089 // This appears to generate MIME types for protocol handlers that are handled
1090 // internally. The only place I can find in the WebKit code that uses this
1091 // function is WebView::registerViewClass, where it is used as part of the
1092 // process by which custom view classes for certain document representations
1093 // are registered.
1094 String mimetype("x-apple-web-kit/");
1095 mimetype.append(URLScheme.lower());
1096 return mimetype;
1097 }
1098
1099 void WebFrameLoaderClient::frameLoadCompleted() {
1100 // FIXME: the mac port also conditionally calls setDrawsBackground:YES on
1101 // it's ScrollView here.
1102
1103 // This comment from the Mac port:
1104 // Note: Can be called multiple times.
1105 // Even if already complete, we might have set a previous item on a frame that
1106 // didn't do any data loading on the past transaction. Make sure to clear thes e out.
1107
1108 // FIXME: setPreviousHistoryItem() no longer exists. http://crbug.com/8566
1109 // webframe_->frame()->loader()->setPreviousHistoryItem(0);
1110 }
1111
1112 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*) {
1113 // FIXME
1114 }
1115
1116
1117 void WebFrameLoaderClient::restoreViewState() {
1118 // FIXME: probably scrolls to last position when you go back or forward
1119 }
1120
1121 void WebFrameLoaderClient::provisionalLoadStarted() {
1122 // FIXME: On mac, this does various caching stuff
1123 }
1124
1125 void WebFrameLoaderClient::didFinishLoad() {
1126 OwnPtr<WebPluginLoadObserver> plugin_load_observer = GetPluginLoadObserver();
1127 if (plugin_load_observer)
1128 plugin_load_observer->didFinishLoading();
1129 }
1130
1131 void WebFrameLoaderClient::prepareForDataSourceReplacement() {
1132 // FIXME
1133 }
1134
1135 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(
1136 const ResourceRequest& request,
1137 const SubstituteData& data) {
1138 RefPtr<WebDataSourceImpl> ds = WebDataSourceImpl::create(request, data);
1139 if (webframe_->client())
1140 webframe_->client()->didCreateDataSource(webframe_, ds.get());
1141 return ds.release();
1142 }
1143
1144 void WebFrameLoaderClient::setTitle(const String& title, const KURL& url) {
1145 // FIXME: monitor for changes in WebFrameLoaderClient.mm
1146 // FIXME: Set the title of the current history item. HistoryItemImpl's setter
1147 // will notify its clients (e.g. the history database) that the title
1148 // has changed.
1149 //
1150 // e.g.:
1151 // WebHistoryItem* item =
1152 // webframe_->GetWebViewImpl()->GetBackForwardList()->GetCurrentItem();
1153 // WebHistoryItemImpl* item_impl = static_cast<WebHistoryItemImpl*>(item);
1154 //
1155 // item_impl->SetTitle(webkit_glue::StringToStdWString(title));
1156 }
1157
1158 String WebFrameLoaderClient::userAgent(const KURL& url) {
1159 return webkit_glue::StdStringToString(
1160 webkit_glue::GetUserAgent(webkit_glue::KURLToGURL(url)));
1161 }
1162
1163 void WebFrameLoaderClient::savePlatformDataToCachedFrame(WebCore::CachedFrame*) {
1164 // The page cache should be disabled.
1165 ASSERT_NOT_REACHED();
1166 }
1167
1168 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(WebCore::CachedF rame*) {
1169 ASSERT_NOT_REACHED();
1170 }
1171
1172 // Called when the FrameLoader goes into a state in which a new page load
1173 // will occur.
1174 void WebFrameLoaderClient::transitionToCommittedForNewPage() {
1175 makeDocumentView();
1176 }
1177
1178 bool WebFrameLoaderClient::canCachePage() const {
1179 // Since we manage the cache, always report this page as non-cacheable to
1180 // FrameLoader.
1181 return false;
1182 }
1183
1184 // Downloading is handled in the browser process, not WebKit. If we get to this
1185 // point, our download detection code in the ResourceDispatcherHost is broken!
1186 void WebFrameLoaderClient::download(ResourceHandle* handle,
1187 const ResourceRequest& request,
1188 const ResourceRequest& initialRequest,
1189 const ResourceResponse& response) {
1190 ASSERT_NOT_REACHED();
1191 }
1192
1193 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(
1194 const KURL& url,
1195 const String& name,
1196 HTMLFrameOwnerElement* owner_element,
1197 const String& referrer,
1198 bool allows_scrolling,
1199 int margin_width,
1200 int margin_height) {
1201 FrameLoadRequest frame_request(ResourceRequest(url, referrer), name);
1202 return webframe_->CreateChildFrame(frame_request, owner_element);
1203 }
1204
1205 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(
1206 const IntSize& size, // TODO(erikkay): how do we use this?
1207 HTMLPlugInElement* element,
1208 const KURL& url,
1209 const Vector<String>& param_names,
1210 const Vector<String>& param_values,
1211 const String& mime_type,
1212 bool load_manually) {
1213 #if !PLATFORM(WIN_OS)
1214 // WebCore asks us to make a plugin even if we don't have a
1215 // registered handler, with a comment saying it's so we can display
1216 // the broken plugin icon. In Chromium, we normally register a
1217 // fallback plugin handler that allows you to install a missing
1218 // plugin. Since we don't yet have a default plugin handler, we
1219 // need to return NULL here rather than going through all the
1220 // plugin-creation IPCs only to discover we don't have a plugin
1221 // registered, which causes a crash.
1222 // TODO(evanm): remove me once we have a default plugin.
1223 if (objectContentType(url, mime_type) != ObjectContentNetscapePlugin)
1224 return NULL;
1225 #endif
1226
1227 if (!webframe_->client())
1228 return NULL;
1229
1230 WebPluginParams params;
1231 params.url = webkit_glue::KURLToWebURL(url);
1232 params.mimeType = webkit_glue::StringToWebString(mime_type);
1233 CopyStringVector(param_names, &params.attributeNames);
1234 CopyStringVector(param_values, &params.attributeValues);
1235 params.loadManually = load_manually;
1236
1237 WebPlugin* webplugin = webframe_->client()->createPlugin(webframe_, params);
1238 if (!webplugin)
1239 return NULL;
1240
1241 // The container takes ownership of the WebPlugin.
1242 RefPtr<WebPluginContainerImpl> container =
1243 WebPluginContainerImpl::create(element, webplugin);
1244
1245 if (!webplugin->initialize(container.get()))
1246 return NULL;
1247
1248 // The element might have been removed during plugin initialization!
1249 if (!element->renderer())
1250 return NULL;
1251
1252 return container;
1253 }
1254
1255 // This method gets called when a plugin is put in place of html content
1256 // (e.g., acrobat reader).
1257 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget) {
1258 plugin_widget_ = static_cast<WebPluginContainerImpl*>(pluginWidget);
1259 ASSERT(plugin_widget_.get());
1260 }
1261
1262 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(
1263 const IntSize& size,
1264 HTMLAppletElement* element,
1265 const KURL& /* base_url */,
1266 const Vector<String>& param_names,
1267 const Vector<String>& param_values) {
1268 return createPlugin(size, element, KURL(), param_names, param_values,
1269 "application/x-java-applet", false);
1270 }
1271
1272 ObjectContentType WebFrameLoaderClient::objectContentType(
1273 const KURL& url,
1274 const String& explicit_mime_type) {
1275 // This code is based on Apple's implementation from
1276 // WebCoreSupport/WebFrameBridge.mm.
1277
1278 String mime_type = explicit_mime_type;
1279 if (mime_type.isEmpty()) {
1280 // Try to guess the MIME type based off the extension.
1281 String filename = url.lastPathComponent();
1282 int extension_pos = filename.reverseFind('.');
1283 if (extension_pos >= 0)
1284 mime_type = MIMETypeRegistry::getMIMETypeForPath(url.path());
1285
1286 if (mime_type.isEmpty())
1287 return ObjectContentFrame;
1288 }
1289
1290 if (MIMETypeRegistry::isSupportedImageMIMEType(mime_type))
1291 return ObjectContentImage;
1292
1293 // If Chrome is started with the --disable-plugins switch, pluginData is null.
1294 PluginData* plugin_data = webframe_->frame()->page()->pluginData();
1295 if (plugin_data && plugin_data->supportsMimeType(mime_type))
1296 return ObjectContentNetscapePlugin;
1297
1298 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mime_type))
1299 return ObjectContentFrame;
1300
1301 return ObjectContentNone;
1302 }
1303
1304 String WebFrameLoaderClient::overrideMediaType() const {
1305 // FIXME
1306 return String();
1307 }
1308
1309 bool WebFrameLoaderClient::ActionSpecifiesNavigationPolicy(
1310 const WebCore::NavigationAction& action,
1311 WebNavigationPolicy* policy) {
1312 if ((action.type() != NavigationTypeLinkClicked) ||
1313 !action.event()->isMouseEvent())
1314 return false;
1315
1316 const MouseEvent* event = static_cast<const MouseEvent*>(action.event());
1317 return WebViewImpl::NavigationPolicyFromMouseEvent(event->button(),
1318 event->ctrlKey(), event->shiftKey(), event->altKey(), event->metaKey(),
1319 policy);
1320 }
1321
1322 void WebFrameLoaderClient::HandleBackForwardNavigation(const KURL& url) {
1323 ASSERT(url.protocolIs(WebKit::backForwardNavigationScheme));
1324
1325 bool ok;
1326 int offset = url.lastPathComponent().toIntStrict(&ok);
1327 if (!ok)
1328 return;
1329
1330 WebViewImpl* webview = webframe_->GetWebViewImpl();
1331 if (webview->client())
1332 webview->client()->navigateBackForwardSoon(offset);
1333 }
1334
1335 PassOwnPtr<WebPluginLoadObserver> WebFrameLoaderClient::GetPluginLoadObserver() {
1336 WebDataSourceImpl* ds = WebDataSourceImpl::fromDocumentLoader(
1337 webframe_->frame()->loader()->activeDocumentLoader());
1338 return ds->releasePluginLoadObserver();
1339 }
OLDNEW
« no previous file with comments | « webkit/glue/webframeloaderclient_impl.h ('k') | webkit/glue/webkit_glue.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698