<rdar://problem/9523192> REGRESSION (5.0.5-ToT, WebKit2): Flash to white when navigat...
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebCoreSupport / WebFrameLoaderClient.cpp
1 /*
2  * Copyright (C) 2010, 2011 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebFrameLoaderClient.h"
28
29 #include "AuthenticationManager.h"
30 #include "DataReference.h"
31 #include "InjectedBundleNavigationAction.h"
32 #include "InjectedBundleUserMessageCoders.h"
33 #include "PlatformCertificateInfo.h"
34 #include "PluginView.h"
35 #include "StringPairVector.h"
36 #include "WebBackForwardListProxy.h"
37 #include "WebContextMessages.h"
38 #include "WebCoreArgumentCoders.h"
39 #include "WebErrors.h"
40 #include "WebEvent.h"
41 #include "WebFrame.h"
42 #include "WebFrameNetworkingContext.h"
43 #include "WebNavigationDataStore.h"
44 #include "WebPage.h"
45 #include "WebPageProxyMessages.h"
46 #include "WebProcess.h"
47 #include "WebProcessProxyMessages.h"
48 #include <JavaScriptCore/APICast.h>
49 #include <JavaScriptCore/JSObject.h>
50 #include <WebCore/Chrome.h>
51 #include <WebCore/DOMWrapperWorld.h>
52 #include <WebCore/DocumentLoader.h>
53 #include <WebCore/FormState.h>
54 #include <WebCore/Frame.h>
55 #include <WebCore/FrameLoadRequest.h>
56 #include <WebCore/FrameView.h>
57 #include <WebCore/HTMLAppletElement.h>
58 #include <WebCore/HTMLFormElement.h>
59 #include <WebCore/HistoryItem.h>
60 #include <WebCore/MIMETypeRegistry.h>
61 #include <WebCore/MouseEvent.h>
62 #include <WebCore/NotImplemented.h>
63 #include <WebCore/Page.h>
64 #include <WebCore/PluginData.h>
65 #include <WebCore/ProgressTracker.h>
66 #include <WebCore/ResourceError.h>
67 #include <WebCore/UIEventWithKeyState.h>
68 #include <WebCore/Widget.h>
69 #include <WebCore/WindowFeatures.h>
70
71 using namespace WebCore;
72
73 namespace WebKit {
74
75 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* frame)
76     : m_frame(frame)
77     , m_hasSentResponseToPluginView(false)
78     , m_frameHasCustomRepresentation(false)
79 {
80 }
81
82 WebFrameLoaderClient::~WebFrameLoaderClient()
83 {
84 }
85     
86 void WebFrameLoaderClient::frameLoaderDestroyed()
87 {
88     m_frame->invalidate();
89
90     // Balances explicit ref() in WebFrame::createMainFrame and WebFrame::createSubframe.
91     m_frame->deref();
92 }
93
94 bool WebFrameLoaderClient::hasHTMLView() const
95 {
96     return !m_frameHasCustomRepresentation;
97 }
98
99 bool WebFrameLoaderClient::hasWebView() const
100 {
101     return m_frame->page();
102 }
103
104 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
105 {
106     notImplemented();
107 }
108
109 void WebFrameLoaderClient::forceLayout()
110 {
111     notImplemented();
112 }
113
114 void WebFrameLoaderClient::forceLayoutForNonHTML()
115 {
116     notImplemented();
117 }
118
119 void WebFrameLoaderClient::setCopiesOnScroll()
120 {
121     notImplemented();
122 }
123
124 void WebFrameLoaderClient::detachedFromParent2()
125 {
126     WebPage* webPage = m_frame->page();
127     if (!webPage)
128         return;
129
130     RefPtr<APIObject> userData;
131
132     // Notify the bundle client.
133     webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
134
135     // Notify the UIProcess.
136     webPage->send(Messages::WebPageProxy::DidRemoveFrameFromHierarchy(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
137
138 }
139
140 void WebFrameLoaderClient::detachedFromParent3()
141 {
142     notImplemented();
143 }
144
145 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
146 {
147     WebPage* webPage = m_frame->page();
148     if (!webPage)
149         return;
150
151     bool pageIsProvisionallyLoading = false;
152     if (FrameLoader* frameLoader = loader->frameLoader())
153         pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader;
154
155     webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading);
156     webPage->send(Messages::WebPageProxy::DidInitiateLoadForResource(m_frame->frameID(), identifier, request, pageIsProvisionallyLoading));
157 }
158
159 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
160 {
161     WebPage* webPage = m_frame->page();
162     if (!webPage)
163         return;
164
165     webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse);
166
167     if (request.isNull()) {
168         // FIXME: We should probably send a message saying we cancelled the request for the resource.
169         return;
170     }
171
172     webPage->send(Messages::WebPageProxy::DidSendRequestForResource(m_frame->frameID(), identifier, request, redirectResponse));
173 }
174
175 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
176 {
177     return true;
178 }
179
180 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
181 {
182     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
183     // Once we do, we might need to make sure authentication fits with our solution.
184
185     WebPage* webPage = m_frame->page();
186     if (!webPage)
187         return;
188
189     AuthenticationManager::shared().didReceiveAuthenticationChallenge(m_frame, challenge);
190 }
191
192 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)    
193 {
194     notImplemented();
195 }
196
197 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
198 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
199 {
200     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
201     // Once we do, we might need to make sure authentication fits with our solution.
202     
203     WebPage* webPage = m_frame->page();
204     if (!webPage)
205         return false;
206         
207     bool canAuthenticate;
208     if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate)))
209         return false;
210     
211     return canAuthenticate;
212 }
213 #endif
214
215 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
216 {
217     WebPage* webPage = m_frame->page();
218     if (!webPage)
219         return;
220
221     webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response);
222     webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response));
223 }
224
225 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength)
226 {
227     WebPage* webPage = m_frame->page();
228     if (!webPage)
229         return;
230
231     webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength);
232     webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, dataLength));
233 }
234
235 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
236 {
237     WebPage* webPage = m_frame->page();
238     if (!webPage)
239         return;
240
241     webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier);
242     webPage->send(Messages::WebPageProxy::DidFinishLoadForResource(m_frame->frameID(), identifier));
243 }
244
245 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
246 {
247     WebPage* webPage = m_frame->page();
248     if (!webPage)
249         return;
250
251     webPage->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error);
252     webPage->send(Messages::WebPageProxy::DidFailLoadForResource(m_frame->frameID(), identifier, error));
253 }
254
255 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length)
256 {
257     notImplemented();
258     return false;
259 }
260
261 void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const String&)
262 {
263     notImplemented();
264 }
265
266 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
267 {
268     WebPage* webPage = m_frame->page();
269     if (!webPage)
270         return;
271
272     // Notify the bundle client.
273     webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame);
274 }
275
276 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
277 {
278     WebPage* webPage = m_frame->page();
279     if (!webPage)
280         return;
281
282     DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
283     const String& url = provisionalLoader->url().string();
284     RefPtr<APIObject> userData;
285
286     // Notify the bundle client.
287     webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData);
288
289     // Notify the UIProcess.
290     webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), url, InjectedBundleUserMessageEncoder(userData.get())));
291 }
292
293 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
294 {
295     WebPage* webPage = m_frame->page();
296     if (!webPage)
297         return;
298
299     // Notify the bundle client.
300     webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame);
301 }
302
303 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double interval, double fireDate)
304 {
305     WebPage* webPage = m_frame->page();
306     if (!webPage)
307         return;
308
309     // Notify the bundle client.
310     webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate);
311 }
312
313 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
314 {
315     WebPage* webPage = m_frame->page();
316     if (!webPage)
317         return;
318
319     RefPtr<APIObject> userData;
320
321     // Notify the bundle client.
322     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData);
323
324     // Notify the UIProcess.
325     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
326 }
327
328 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
329 {
330     WebPage* webPage = m_frame->page();
331     if (!webPage)
332         return;
333
334     RefPtr<APIObject> userData;
335
336     // Notify the bundle client.
337     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData);
338
339     // Notify the UIProcess.
340     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
341 }
342
343 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
344 {
345     WebPage* webPage = m_frame->page();
346     if (!webPage)
347         return;
348
349     RefPtr<APIObject> userData;
350
351     // Notify the bundle client.
352     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData);
353
354     // Notify the UIProcess.
355     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
356 }
357
358 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
359 {
360     WebPage* webPage = m_frame->page();
361     if (!webPage)
362         return;
363
364     RefPtr<APIObject> userData;
365
366     // Notify the bundle client.
367     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData);
368
369     // Notify the UIProcess.
370     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
371 }
372
373 void WebFrameLoaderClient::dispatchWillClose()
374 {
375     notImplemented();
376 }
377
378 void WebFrameLoaderClient::dispatchDidReceiveIcon()
379 {
380     notImplemented();
381 }
382
383 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
384 {
385     WebPage* webPage = m_frame->page();
386     if (!webPage)
387         return;
388
389     webPage->findController().hideFindUI();
390     webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);
391
392     DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
393     const String& url = provisionalLoader->url().string();
394     RefPtr<APIObject> userData;
395
396     // Notify the bundle client.
397     webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);
398
399     String unreachableURL = provisionalLoader->unreachableURL().string();
400
401     // Notify the UIProcess.
402     webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, unreachableURL, InjectedBundleUserMessageEncoder(userData.get())));
403 }
404
405 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
406 {
407     WebPage* webPage = m_frame->page();
408     if (!webPage)
409         return;
410
411     RefPtr<APIObject> userData;
412
413     // Notify the bundle client.
414     // FIXME: use direction of title.
415     webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData);
416
417     // Notify the UIProcess.
418     webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), InjectedBundleUserMessageEncoder(userData.get())));
419 }
420
421 void WebFrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType)
422 {
423     notImplemented();
424 }
425
426 void WebFrameLoaderClient::dispatchDidCommitLoad()
427 {
428     WebPage* webPage = m_frame->page();
429     if (!webPage)
430         return;
431
432     const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response();
433     RefPtr<APIObject> userData;
434
435     // Notify the bundle client.
436     webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData);
437
438     webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
439
440     // Notify the UIProcess.
441
442     webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), response.mimeType(), m_frameHasCustomRepresentation, PlatformCertificateInfo(response), InjectedBundleUserMessageEncoder(userData.get())));
443
444     // Only restore the scale factor for standard frame loads (of the main frame).
445     if (m_frame->isMainFrame() && m_frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) {
446         if (m_frame->coreFrame()->pageScaleFactor() != 1)
447             webPage->scaleWebView(1, IntPoint());
448     }
449 }
450
451 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
452 {
453     WebPage* webPage = m_frame->page();
454     if (!webPage)
455         return;
456
457     RefPtr<APIObject> userData;
458
459     // Notify the bundle client.
460     webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData);
461
462     webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame);
463
464     // Notify the UIProcess.
465     webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
466     
467     // If we have a load listener, notify it.
468     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
469         loadListener->didFailLoad(m_frame, error.isCancellation());
470 }
471
472 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
473 {
474     WebPage* webPage = m_frame->page();
475     if (!webPage)
476         return;
477
478     RefPtr<APIObject> userData;
479
480     // Notify the bundle client.
481     webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData);
482
483     // Notify the UIProcess.
484     webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
485
486     // If we have a load listener, notify it.
487     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
488         loadListener->didFailLoad(m_frame, error.isCancellation());
489 }
490
491 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
492 {
493     WebPage* webPage = m_frame->page();
494     if (!webPage)
495         return;
496
497     RefPtr<APIObject> userData;
498
499     // Notify the bundle client.
500     webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData);
501
502     // Notify the UIProcess.
503     webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
504 }
505
506 void WebFrameLoaderClient::dispatchDidFinishLoad()
507 {
508     WebPage* webPage = m_frame->page();
509     if (!webPage)
510         return;
511
512     RefPtr<APIObject> userData;
513
514     // Notify the bundle client.
515     webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData);
516
517     // Notify the UIProcess.
518     webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
519
520     // If we have a load listener, notify it.
521     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
522         loadListener->didFinishLoad(m_frame);
523 }
524
525 void WebFrameLoaderClient::dispatchDidFirstLayout()
526 {
527     WebPage* webPage = m_frame->page();
528     if (!webPage)
529         return;
530
531     RefPtr<APIObject> userData;
532
533     // Notify the bundle client.
534     webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
535
536     // Notify the UIProcess.
537     webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
538
539     if (m_frame == m_frame->page()->mainFrame())
540         webPage->drawingArea()->setLayerTreeStateIsFrozen(false);
541 }
542
543 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
544 {
545     WebPage* webPage = m_frame->page();
546     if (!webPage)
547         return;
548
549     RefPtr<APIObject> userData;
550
551     // Notify the bundle client.
552     webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
553
554     // Notify the UIProcess.
555     webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
556 }
557
558 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
559 {
560     WebPage* webPage = m_frame->page();
561     if (!webPage)
562         return 0;
563
564     // Just call through to the chrome client.
565     Page* newPage = webPage->corePage()->chrome()->createWindow(m_frame->coreFrame(), FrameLoadRequest(m_frame->coreFrame()->document()->securityOrigin()), WindowFeatures(), navigationAction);
566     if (!newPage)
567         return 0;
568     
569     return newPage->mainFrame();
570 }
571
572 void WebFrameLoaderClient::dispatchShow()
573 {
574     WebPage* webPage = m_frame->page();
575     if (!webPage)
576         return;
577
578     webPage->show();
579 }
580
581 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& request)
582 {
583     WebPage* webPage = m_frame->page();
584     if (!webPage)
585         return;
586
587     if (!request.url().string())
588         return;
589
590     RefPtr<APIObject> userData;
591
592     // Notify the bundle client.
593     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData);
594     if (policy == WKBundlePagePolicyActionUse) {
595         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
596         return;
597     }
598
599     uint64_t listenerID = m_frame->setUpPolicyListener(function);
600     bool receivedPolicyAction;
601     uint64_t policyAction;
602     uint64_t downloadID;
603
604     // Notify the UIProcess.
605     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), response, request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForResponse::Reply(receivedPolicyAction, policyAction, downloadID)))
606         return;
607
608     // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
609     if (receivedPolicyAction)
610         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
611 }
612
613 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
614 {
615     WebPage* webPage = m_frame->page();
616     if (!webPage)
617         return;
618
619     RefPtr<APIObject> userData;
620
621     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
622
623     // Notify the bundle client.
624     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData);
625     if (policy == WKBundlePagePolicyActionUse) {
626         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
627         return;
628     }
629
630
631     uint64_t listenerID = m_frame->setUpPolicyListener(function);
632
633     // Notify the UIProcess.
634     webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, frameName, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
635 }
636
637 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState)
638 {
639     WebPage* webPage = m_frame->page();
640     if (!webPage)
641         return;
642
643     // Always ignore requests with empty URLs. 
644     if (request.isEmpty()) { 
645         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyIgnore); 
646         return; 
647     }
648
649     RefPtr<APIObject> userData;
650
651     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
652
653     // Notify the bundle client.
654     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
655     if (policy == WKBundlePagePolicyActionUse) {
656         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
657         return;
658     }
659     
660     uint64_t listenerID = m_frame->setUpPolicyListener(function);
661     bool receivedPolicyAction;
662     uint64_t policyAction;
663     uint64_t downloadID;
664
665     // Notify the UIProcess.
666     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, policyAction, downloadID)))
667         return;
668
669     // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
670     if (receivedPolicyAction)
671         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
672 }
673
674 void WebFrameLoaderClient::cancelPolicyCheck()
675 {
676     m_frame->invalidatePolicyListener();
677 }
678
679 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
680 {
681     WebPage* webPage = m_frame->page();
682     if (!webPage)
683         return;
684
685     RefPtr<APIObject> userData;
686
687     // Notify the bundle client.
688     webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData);
689
690     // Notify the UIProcess.
691     webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
692 }
693
694 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> prpFormState)
695 {
696     WebPage* webPage = m_frame->page();
697     if (!webPage)
698         return;
699
700     // FIXME: Pass more of the form state.
701     RefPtr<FormState> formState = prpFormState;
702     
703     HTMLFormElement* form = formState->form();
704     WebFrame* sourceFrame = static_cast<WebFrameLoaderClient*>(formState->sourceFrame()->loader()->client())->webFrame();    
705     const Vector<std::pair<String, String> >& values = formState->textFieldValues();
706
707     RefPtr<APIObject> userData;
708     webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData);
709
710
711     uint64_t listenerID = m_frame->setUpPolicyListener(function);
712     StringPairVector valuesVector(values);
713
714     webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), valuesVector, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
715 }
716
717 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
718 {
719     notImplemented();
720 }
721
722 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
723 {
724     notImplemented();
725 }
726
727 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
728 {
729     if (!m_pluginView)
730         return;
731     
732     m_pluginView->manualLoadDidFail(error);
733     m_pluginView = 0;
734     m_hasSentResponseToPluginView = false;
735 }
736
737 void WebFrameLoaderClient::willChangeEstimatedProgress()
738 {
739     notImplemented();
740 }
741
742 void WebFrameLoaderClient::didChangeEstimatedProgress()
743 {
744     notImplemented();
745 }
746
747 void WebFrameLoaderClient::postProgressStartedNotification()
748 {
749     if (WebPage* webPage = m_frame->page())
750         webPage->send(Messages::WebPageProxy::DidStartProgress());
751 }
752
753 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
754 {
755     if (WebPage* webPage = m_frame->page()) {
756         double progress = webPage->corePage()->progress()->estimatedProgress();
757         webPage->send(Messages::WebPageProxy::DidChangeProgress(progress));
758
759     }
760 }
761
762 void WebFrameLoaderClient::postProgressFinishedNotification()
763 {
764     if (WebPage* webPage = m_frame->page())
765         webPage->send(Messages::WebPageProxy::DidFinishProgress());
766 }
767
768 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
769 {
770     notImplemented();
771 }
772
773 void WebFrameLoaderClient::startDownload(const ResourceRequest& request)
774 {
775     m_frame->startDownload(request);
776 }
777
778 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
779 {
780     notImplemented();
781 }
782
783 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
784 {
785     notImplemented();
786 }
787
788 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
789 {
790     // If we're loading a custom representation, we don't want to hand off the data to WebCore.
791     if (m_frameHasCustomRepresentation)
792         return;
793
794     if (!m_pluginView)
795         loader->commitData(data, length);
796
797     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
798     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
799     if (m_frame->coreFrame()->document()->isMediaDocument())
800         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
801
802     // Calling commitData did not create the plug-in view.
803     if (!m_pluginView)
804         return;
805
806     if (!m_hasSentResponseToPluginView) {
807         m_pluginView->manualLoadDidReceiveResponse(loader->response());
808         // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
809         // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
810         // to null
811         if (!m_pluginView)
812             return;
813         m_hasSentResponseToPluginView = true;
814     }
815     m_pluginView->manualLoadDidReceiveData(data, length);
816 }
817
818 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
819 {
820     if (!m_pluginView) {
821         committedLoad(loader, 0, 0);
822
823         if (m_frameHasCustomRepresentation) {
824             WebPage* webPage = m_frame->page();
825             if (!webPage)
826                 return;
827
828             RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData();
829             CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0);
830             
831             webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomRepresentation(loader->response().suggestedFilename(), dataReference));
832         }
833
834         return;
835     }
836
837     m_pluginView->manualLoadDidFinishLoading();
838     m_pluginView = 0;
839     m_hasSentResponseToPluginView = false;
840 }
841
842 void WebFrameLoaderClient::updateGlobalHistory()
843 {
844     WebPage* webPage = m_frame->page();
845     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
846         return;
847
848     DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
849
850     WebNavigationDataStore data;
851     data.url = loader->urlForHistory().string();
852     // FIXME: use direction of title.
853     data.title = loader->title().string();
854
855     WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0);
856 }
857
858 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
859 {
860     WebPage* webPage = m_frame->page();
861     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
862         return;
863
864     DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
865     ASSERT(loader->unreachableURL().isEmpty());
866
867     // Client redirect
868     if (!loader->clientRedirectSourceForHistory().isNull()) {
869         WebProcess::shared().connection()->send(Messages::WebContext::DidPerformClientRedirect(webPage->pageID(),
870             loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0);
871     }
872
873     // Server redirect
874     if (!loader->serverRedirectSourceForHistory().isNull()) {
875         WebProcess::shared().connection()->send(Messages::WebContext::DidPerformServerRedirect(webPage->pageID(),
876             loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0);
877     }
878 }
879
880 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
881 {
882     WebPage* webPage = m_frame->page();
883     if (!webPage)
884         return false;
885     
886     uint64_t itemID = WebBackForwardListProxy::idForItem(item);
887     if (!itemID) {
888         // We should never be considering navigating to an item that is not actually in the back/forward list.
889         ASSERT_NOT_REACHED();
890         return false;
891     }
892     
893     bool shouldGoToBackForwardListItem;
894     if (!webPage->sendSync(Messages::WebPageProxy::ShouldGoToBackForwardListItem(itemID), Messages::WebPageProxy::ShouldGoToBackForwardListItem::Reply(shouldGoToBackForwardListItem)))
895         return false;
896     
897     return shouldGoToBackForwardListItem;
898 }
899
900 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
901 {
902     return true;
903 }
904
905 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
906 {
907     notImplemented();
908 }
909
910 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
911 {
912     notImplemented();
913 }
914
915 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
916 {
917     notImplemented();
918 }
919
920 void WebFrameLoaderClient::didDisplayInsecureContent()
921 {
922     WebPage* webPage = m_frame->page();
923     if (!webPage)
924         return;
925
926     RefPtr<APIObject> userData;
927
928     webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData);
929
930     webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
931 }
932
933 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const KURL&)
934 {
935     WebPage* webPage = m_frame->page();
936     if (!webPage)
937         return;
938
939     RefPtr<APIObject> userData;
940
941     webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData);
942
943     webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
944 }
945
946 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
947 {
948     return WebKit::cancelledError(request);
949 }
950
951 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
952 {
953     return WebKit::blockedError(request);
954 }
955
956 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
957 {
958     return WebKit::cannotShowURLError(request);
959 }
960
961 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request)
962 {
963     return WebKit::interruptForPolicyChangeError(request);
964 }
965
966 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
967 {
968     return WebKit::cannotShowMIMETypeError(response);
969 }
970
971 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
972 {
973     return WebKit::fileDoesNotExistError(response);
974 }
975
976 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
977 {
978     return WebKit::pluginWillHandleLoadError(response);
979 }
980
981 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
982 {
983     DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest())));
984     DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse())));
985
986     if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain())
987         return false;
988
989     if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain())
990         return false;
991
992     return true;
993 }
994
995 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
996 {
997     notImplemented();
998     return true;
999 }
1000
1001 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
1002 {
1003     notImplemented();
1004     return true;
1005 }
1006
1007 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
1008 {
1009     return true;
1010 }
1011
1012 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
1013 {
1014     notImplemented();
1015     return false;
1016 }
1017
1018 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
1019 {
1020     notImplemented();
1021     return String();
1022 }
1023
1024 void WebFrameLoaderClient::frameLoadCompleted()
1025 {
1026     WebPage* webPage = m_frame->page();
1027     if (!webPage)
1028         return;
1029
1030     if (m_frame == m_frame->page()->mainFrame())
1031         webPage->drawingArea()->setLayerTreeStateIsFrozen(false);
1032 }
1033
1034 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*)
1035 {
1036     notImplemented();
1037 }
1038
1039 void WebFrameLoaderClient::restoreViewState()
1040 {
1041     // Inform the UI process of the scale factor.
1042     double scaleFactor = m_frame->coreFrame()->loader()->history()->currentItem()->pageScaleFactor();
1043     m_frame->page()->send(Messages::WebPageProxy::ViewScaleFactorDidChange(scaleFactor));
1044
1045     // FIXME: This should not be necessary. WebCore should be correctly invalidating
1046     // the view on restores from the back/forward cache.
1047     if (m_frame == m_frame->page()->mainFrame())
1048         m_frame->page()->drawingArea()->setNeedsDisplay(m_frame->page()->bounds());
1049 }
1050
1051 void WebFrameLoaderClient::provisionalLoadStarted()
1052 {
1053     WebPage* webPage = m_frame->page();
1054     if (!webPage)
1055         return;
1056
1057     if (m_frame == m_frame->page()->mainFrame())
1058         webPage->drawingArea()->setLayerTreeStateIsFrozen(true);
1059 }
1060
1061 void WebFrameLoaderClient::didFinishLoad()
1062 {
1063     // If we have a load listener, notify it.
1064     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
1065         loadListener->didFinishLoad(m_frame);
1066 }
1067
1068 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1069 {
1070     notImplemented();
1071 }
1072
1073 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& data)
1074 {
1075     return DocumentLoader::create(request, data);
1076 }
1077
1078 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
1079 {
1080     WebPage* webPage = m_frame->page();
1081     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1082         return;
1083
1084     // FIXME: use direction of title.
1085     WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(),
1086         title.string(), url.string(), m_frame->frameID()), 0);
1087 }
1088
1089 String WebFrameLoaderClient::userAgent(const KURL&)
1090 {
1091     WebPage* webPage = m_frame->page();
1092     if (!webPage)
1093         return String();
1094
1095     return webPage->userAgent();
1096 }
1097
1098 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
1099 {
1100 }
1101
1102 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
1103 {
1104     WebPage* webPage = m_frame->page();
1105     bool isMainFrame = webPage->mainFrame() == m_frame;
1106     
1107     const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType();
1108     m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType);
1109 }
1110
1111 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1112 {
1113     WebPage* webPage = m_frame->page();
1114     Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white;
1115
1116     bool isMainFrame = webPage->mainFrame() == m_frame;
1117
1118 #if ENABLE(TILED_BACKING_STORE)
1119     IntSize currentVisibleContentSize = m_frame->coreFrame()->view() ? m_frame->coreFrame()->view()->actualVisibleContentRect().size() : IntSize();
1120     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, webPage->resizesToContentsLayoutSize(), isMainFrame && webPage->resizesToContentsEnabled());
1121
1122     if (isMainFrame && webPage->resizesToContentsEnabled()) {
1123         m_frame->coreFrame()->view()->setDelegatesScrolling(true);
1124         m_frame->coreFrame()->view()->setPaintsEntireContents(true);
1125     }
1126
1127     // The HistoryController will update the scroll position later if needed.
1128     m_frame->coreFrame()->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize));
1129 #else
1130     const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType();
1131     m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType);
1132
1133     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, IntSize(), false);
1134 #endif
1135
1136     m_frame->coreFrame()->view()->setTransparent(!webPage->drawsBackground());
1137 }
1138
1139 void WebFrameLoaderClient::didSaveToPageCache()
1140 {
1141     WebPage* webPage = m_frame->page();
1142     if (!webPage)
1143         return;
1144
1145     if (m_frame->isMainFrame())
1146         return;
1147
1148     webPage->send(Messages::WebPageProxy::DidSaveFrameToPageCache(m_frame->frameID()));
1149 }
1150
1151 void WebFrameLoaderClient::didRestoreFromPageCache()
1152 {
1153     WebPage* webPage = m_frame->page();
1154     if (!webPage)
1155         return;
1156
1157     if (m_frame->isMainFrame())
1158         return;
1159
1160     WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(m_frame->coreFrame()->tree()->parent()->loader()->client())->webFrame();
1161     webPage->send(Messages::WebPageProxy::DidRestoreFrameFromPageCache(m_frame->frameID(), parentFrame->frameID()));
1162 }
1163
1164 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
1165 {
1166     WebPage* webPage = m_frame->page();
1167     if (!webPage)
1168         return;
1169
1170     webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
1171 }
1172
1173 bool WebFrameLoaderClient::canCachePage() const
1174 {
1175     // We cannot cache frames that have custom representations because they are
1176     // rendered in the UIProcess. 
1177     return !m_frameHasCustomRepresentation;
1178 }
1179
1180 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
1181 {
1182     m_frame->convertHandleToDownload(handle, request, initialRequest, response);
1183 }
1184
1185 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1186                                                     const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1187 {
1188     WebPage* webPage = m_frame->page();
1189
1190     RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement);
1191
1192     Frame* coreSubframe = subframe->coreFrame();
1193
1194      // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1195     m_frame->coreFrame()->loader()->loadURLIntoChildFrame(url, referrer, coreSubframe);
1196
1197     // The frame's onload handler may have removed it from the document.
1198     if (!coreSubframe->tree()->parent())
1199         return 0;
1200
1201     return coreSubframe;
1202 }
1203
1204 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*)
1205 {
1206     notImplemented();
1207 }
1208
1209 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*)
1210 {
1211     notImplemented();
1212 }
1213
1214 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1215 {
1216     ASSERT(paramNames.size() == paramValues.size());
1217     
1218     WebPage* webPage = m_frame->page();
1219     ASSERT(webPage);
1220     
1221     Plugin::Parameters parameters;
1222     parameters.url = url;
1223     parameters.names = paramNames;
1224     parameters.values = paramValues;
1225     parameters.mimeType = mimeType;
1226     parameters.loadManually = loadManually;
1227     parameters.documentURL = m_frame->coreFrame()->document()->url().string();
1228
1229     Frame* mainFrame = webPage->mainFrame()->coreFrame();
1230     if (m_frame->coreFrame() == mainFrame)
1231         parameters.toplevelDocumentURL = parameters.documentURL;
1232     else if (m_frame->coreFrame()->document()->securityOrigin()->canAccess(mainFrame->document()->securityOrigin())) {
1233         // We only want to set the toplevel document URL if the plug-in has access to it.
1234         parameters.toplevelDocumentURL = mainFrame->document()->url().string();
1235     }
1236
1237     // <rdar://problem/8440903>: AppleConnect has a bug where it does not
1238     // understand the parameter names specified in the <object> element that
1239     // embeds its plug-in. This hack works around the issue by converting the
1240     // parameter names to lowercase before passing them to the plug-in.
1241     // FIXME: This workaround should be dependent on site-specific quirks being
1242     // enabled. This requires adding this setting to WebKit2's WebPreferences
1243     // implementation. See <https://bugs.webkit.org/show_bug.cgi?id=46076>.
1244     if (equalIgnoringCase(mimeType, "application/x-snkp")) {
1245         for (size_t i = 0; i < paramNames.size(); ++i)
1246             parameters.names[i] = paramNames[i].lower();
1247     }
1248
1249 #if PLUGIN_ARCHITECTURE(X11)
1250     if (equalIgnoringCase(mimeType, "application/x-shockwave-flash")) {
1251         // Currently we don't support transparency and windowed mode.
1252         // Inject wmode=opaque to make Flash work in these conditions.
1253         size_t wmodeIndex = parameters.names.find("wmode");
1254         if (wmodeIndex == -1) {
1255             parameters.names.append("wmode");
1256             parameters.values.append("opaque");
1257         } else if (equalIgnoringCase(parameters.values[wmodeIndex], "window"))
1258             parameters.values[wmodeIndex] = "opaque";
1259     }
1260 #endif
1261
1262     RefPtr<Plugin> plugin = webPage->createPlugin(parameters);
1263     if (!plugin)
1264         return 0;
1265     
1266     return PluginView::create(pluginElement, plugin.release(), parameters);
1267 }
1268
1269 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1270 {
1271     ASSERT(!m_pluginView);
1272     ASSERT(pluginWidget);
1273     
1274     m_pluginView = static_cast<PluginView*>(pluginWidget);
1275 }
1276
1277 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues)
1278 {
1279     const String mimeType = "application/x-java-applet";
1280     RefPtr<Widget> plugin = createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, mimeType, false);
1281     if (!plugin) {
1282         if (WebPage* webPage = m_frame->page())
1283             webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(mimeType));
1284     }
1285     return plugin.release();
1286 }
1287
1288 static bool pluginSupportsExtension(PluginData* pluginData, const String& extension)
1289 {
1290     ASSERT(extension.lower() == extension);
1291
1292     for (size_t i = 0; i < pluginData->mimes().size(); ++i) {
1293         const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i];
1294
1295         if (mimeClassInfo.extensions.contains(extension))
1296             return true;
1297     }
1298     return false;
1299 }
1300
1301 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
1302 {
1303     // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
1304     // is consolidated.
1305
1306     String mimeType = mimeTypeIn;
1307     if (mimeType.isEmpty()) {
1308         String extension = url.path().substring(url.path().reverseFind('.') + 1).lower();
1309
1310         // Try to guess the MIME type from the extension.
1311         mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1312
1313         if (mimeType.isEmpty()) {
1314             // Check if there's a plug-in around that can handle the extension.
1315             if (WebPage* webPage = m_frame->page()) {
1316                 if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1317                     if (pluginSupportsExtension(pluginData, extension))
1318                         return ObjectContentNetscapePlugin;
1319                 }
1320             }
1321         }
1322     }
1323
1324     if (mimeType.isEmpty())
1325         return ObjectContentFrame;
1326
1327     bool plugInSupportsMIMEType = false;
1328     if (WebPage* webPage = m_frame->page()) {
1329         if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1330             if (pluginData->supportsMimeType(mimeType))
1331                 plugInSupportsMIMEType = true;
1332         }
1333     }
1334     
1335     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1336         return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage;
1337
1338     if (plugInSupportsMIMEType)
1339         return ObjectContentNetscapePlugin;
1340
1341     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1342         return ObjectContentFrame;
1343
1344     return ObjectContentNone;
1345 }
1346
1347 String WebFrameLoaderClient::overrideMediaType() const
1348 {
1349     notImplemented();
1350     return String();
1351 }
1352
1353 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1354 {
1355     WebPage* webPage = m_frame->page();
1356     if (!webPage)
1357         return;
1358
1359     webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1360 }
1361
1362 void WebFrameLoaderClient::documentElementAvailable()
1363 {
1364     notImplemented();
1365 }
1366
1367 void WebFrameLoaderClient::didPerformFirstNavigation() const
1368 {
1369     notImplemented();
1370 }
1371
1372 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1373 {
1374     notImplemented();
1375 }
1376
1377 #if PLATFORM(MAC)
1378     
1379 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject() 
1380 {
1381     return m_frame->page()->accessibilityRemoteObject();
1382 }
1383     
1384 #if ENABLE(MAC_JAVA_BRIDGE)
1385 jobject WebFrameLoaderClient::javaApplet(NSView*) { return 0; }
1386 #endif
1387 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1388 {
1389     return response;
1390 }
1391
1392 #endif
1393 #if PLATFORM(WIN) && USE(CFNETWORK)
1394 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length)
1395 {
1396     return true;
1397 }
1398
1399 #endif
1400
1401 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& /*mimeType*/) const
1402 {
1403     notImplemented();
1404     return false;
1405 }
1406
1407 void WebFrameLoaderClient::didChangeScrollOffset()
1408 {
1409     WebPage* webPage = m_frame->page();
1410     if (!webPage)
1411         return;
1412
1413     if (!m_frame->isMainFrame())
1414         return;
1415
1416     // If this is called when tearing down a FrameView, the WebCore::Frame's
1417     // current FrameView will be null.
1418     if (!m_frame->coreFrame()->view())
1419         return;
1420
1421     webPage->didChangeScrollOffsetForMainFrame();
1422 }
1423
1424 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1425 {
1426     return WebFrameNetworkingContext::create(m_frame->coreFrame());
1427 }
1428
1429 } // namespace WebKit