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

Side by Side Diff: webkit/api/src/FrameLoaderClientImpl.cpp

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

Powered by Google App Engine
This is Rietveld 408576698