<rdar://problem/10809525> WebKit2’s WebFrameLoaderClient::shouldUseCredentialStorage...
[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/Settings.h>
68 #include <WebCore/UIEventWithKeyState.h>
69 #include <WebCore/Widget.h>
70 #include <WebCore/WindowFeatures.h>
71
72 using namespace WebCore;
73
74 namespace WebKit {
75
76 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* frame)
77     : m_frame(frame)
78     , m_hasSentResponseToPluginView(false)
79     , m_frameHasCustomRepresentation(false)
80 {
81 }
82
83 WebFrameLoaderClient::~WebFrameLoaderClient()
84 {
85 }
86     
87 void WebFrameLoaderClient::frameLoaderDestroyed()
88 {
89     m_frame->invalidate();
90
91     // Balances explicit ref() in WebFrame::createMainFrame and WebFrame::createSubframe.
92     m_frame->deref();
93 }
94
95 bool WebFrameLoaderClient::hasHTMLView() const
96 {
97     return !m_frameHasCustomRepresentation;
98 }
99
100 bool WebFrameLoaderClient::hasWebView() const
101 {
102     return m_frame->page();
103 }
104
105 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
106 {
107     notImplemented();
108 }
109
110 void WebFrameLoaderClient::forceLayout()
111 {
112     notImplemented();
113 }
114
115 void WebFrameLoaderClient::forceLayoutForNonHTML()
116 {
117     notImplemented();
118 }
119
120 void WebFrameLoaderClient::setCopiesOnScroll()
121 {
122     notImplemented();
123 }
124
125 void WebFrameLoaderClient::detachedFromParent2()
126 {
127     WebPage* webPage = m_frame->page();
128     if (!webPage)
129         return;
130
131     RefPtr<APIObject> userData;
132
133     // Notify the bundle client.
134     webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
135
136     // Notify the UIProcess.
137     webPage->send(Messages::WebPageProxy::DidRemoveFrameFromHierarchy(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
138
139 }
140
141 void WebFrameLoaderClient::detachedFromParent3()
142 {
143     notImplemented();
144 }
145
146 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
147 {
148     WebPage* webPage = m_frame->page();
149     if (!webPage)
150         return;
151
152     bool pageIsProvisionallyLoading = false;
153     if (FrameLoader* frameLoader = loader->frameLoader())
154         pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader;
155
156     webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading);
157     webPage->send(Messages::WebPageProxy::DidInitiateLoadForResource(m_frame->frameID(), identifier, request, pageIsProvisionallyLoading));
158 }
159
160 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
161 {
162     WebPage* webPage = m_frame->page();
163     if (!webPage)
164         return;
165
166     webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse);
167
168     if (request.isNull()) {
169         // FIXME: We should probably send a message saying we cancelled the request for the resource.
170         return;
171     }
172
173     webPage->send(Messages::WebPageProxy::DidSendRequestForResource(m_frame->frameID(), identifier, request, redirectResponse));
174 }
175
176 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
177 {
178     WebPage* webPage = m_frame->page();
179     if (!webPage)
180         return true;
181
182     return webPage->injectedBundleResourceLoadClient().shouldUseCredentialStorage(webPage, m_frame, identifier);
183 }
184
185 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
186 {
187     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
188     // Once we do, we might need to make sure authentication fits with our solution.
189
190     WebPage* webPage = m_frame->page();
191     if (!webPage)
192         return;
193
194     AuthenticationManager::shared().didReceiveAuthenticationChallenge(m_frame, challenge);
195 }
196
197 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)    
198 {
199     notImplemented();
200 }
201
202 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
203 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
204 {
205     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
206     // Once we do, we might need to make sure authentication fits with our solution.
207     
208     WebPage* webPage = m_frame->page();
209     if (!webPage)
210         return false;
211         
212     bool canAuthenticate;
213     if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate)))
214         return false;
215     
216     return canAuthenticate;
217 }
218 #endif
219
220 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
221 {
222     WebPage* webPage = m_frame->page();
223     if (!webPage)
224         return;
225
226     webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response);
227     webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response));
228 }
229
230 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength)
231 {
232     WebPage* webPage = m_frame->page();
233     if (!webPage)
234         return;
235
236     webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength);
237     webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, dataLength));
238 }
239
240 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
241 {
242     WebPage* webPage = m_frame->page();
243     if (!webPage)
244         return;
245
246     webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier);
247     webPage->send(Messages::WebPageProxy::DidFinishLoadForResource(m_frame->frameID(), identifier));
248 }
249
250 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
251 {
252     WebPage* webPage = m_frame->page();
253     if (!webPage)
254         return;
255
256     webPage->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error);
257     webPage->send(Messages::WebPageProxy::DidFailLoadForResource(m_frame->frameID(), identifier, error));
258 }
259
260 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length)
261 {
262     notImplemented();
263     return false;
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         Page* page = m_frame->coreFrame()->page();
447         if (page && page->pageScaleFactor() != 1)
448             webPage->scalePage(1, IntPoint());
449     }
450 }
451
452 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
453 {
454     WebPage* webPage = m_frame->page();
455     if (!webPage)
456         return;
457
458     RefPtr<APIObject> userData;
459
460     // Notify the bundle client.
461     webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData);
462
463     webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame);
464
465     // Notify the UIProcess.
466     webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
467     
468     // If we have a load listener, notify it.
469     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
470         loadListener->didFailLoad(m_frame, error.isCancellation());
471 }
472
473 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
474 {
475     WebPage* webPage = m_frame->page();
476     if (!webPage)
477         return;
478
479     RefPtr<APIObject> userData;
480
481     // Notify the bundle client.
482     webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData);
483
484     // Notify the UIProcess.
485     webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
486
487     // If we have a load listener, notify it.
488     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
489         loadListener->didFailLoad(m_frame, error.isCancellation());
490 }
491
492 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
493 {
494     WebPage* webPage = m_frame->page();
495     if (!webPage)
496         return;
497
498     RefPtr<APIObject> userData;
499
500     // Notify the bundle client.
501     webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData);
502
503     // Notify the UIProcess.
504     webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
505 }
506
507 void WebFrameLoaderClient::dispatchDidFinishLoad()
508 {
509     WebPage* webPage = m_frame->page();
510     if (!webPage)
511         return;
512
513     RefPtr<APIObject> userData;
514
515     // Notify the bundle client.
516     webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData);
517
518     // Notify the UIProcess.
519     webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
520
521     // If we have a load listener, notify it.
522     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
523         loadListener->didFinishLoad(m_frame);
524 }
525
526 void WebFrameLoaderClient::dispatchDidFirstLayout()
527 {
528     WebPage* webPage = m_frame->page();
529     if (!webPage)
530         return;
531
532     RefPtr<APIObject> userData;
533
534     // Notify the bundle client.
535     webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
536
537     // Notify the UIProcess.
538     webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
539
540     if (m_frame == m_frame->page()->mainWebFrame() && !webPage->corePage()->settings()->suppressIncrementalRendering())
541         webPage->drawingArea()->setLayerTreeStateIsFrozen(false);
542 }
543
544 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
545 {
546     WebPage* webPage = m_frame->page();
547     if (!webPage)
548         return;
549
550     RefPtr<APIObject> userData;
551
552     // Notify the bundle client.
553     webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
554
555     // Notify the UIProcess.
556     webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
557 }
558
559 void WebFrameLoaderClient::dispatchDidNewFirstVisuallyNonEmptyLayout()
560 {
561     WebPage* webPage = m_frame->page();
562     if (!webPage)
563         return;
564
565     RefPtr<APIObject> userData;
566
567     // Notify the UIProcess.
568     webPage->send(Messages::WebPageProxy::DidNewFirstVisuallyNonEmptyLayout(InjectedBundleUserMessageEncoder(userData.get())));
569 }
570
571 void WebFrameLoaderClient::dispatchDidLayout()
572 {
573     WebPage* webPage = m_frame->page();
574     if (!webPage)
575         return;
576
577     // Notify the bundle client.
578     webPage->injectedBundleLoaderClient().didLayoutForFrame(webPage, m_frame);
579
580     // NOTE: Unlike the other layout notifications, this does not notify the
581     // the UIProcess for every call.
582
583     if (m_frame == m_frame->page()->mainWebFrame()) {
584         // FIXME: Remove at the soonest possible time.
585         webPage->send(Messages::WebPageProxy::SetRenderTreeSize(webPage->renderTreeSize()));
586         webPage->mainFrameDidLayout();
587     }
588 }
589
590 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
591 {
592     WebPage* webPage = m_frame->page();
593     if (!webPage)
594         return 0;
595
596     // Just call through to the chrome client.
597     Page* newPage = webPage->corePage()->chrome()->createWindow(m_frame->coreFrame(), FrameLoadRequest(m_frame->coreFrame()->document()->securityOrigin()), WindowFeatures(), navigationAction);
598     if (!newPage)
599         return 0;
600     
601     return newPage->mainFrame();
602 }
603
604 void WebFrameLoaderClient::dispatchShow()
605 {
606     WebPage* webPage = m_frame->page();
607     if (!webPage)
608         return;
609
610     webPage->show();
611 }
612
613 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& request)
614 {
615     WebPage* webPage = m_frame->page();
616     if (!webPage)
617         return;
618
619     if (!request.url().string()) {
620         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
621         return;
622     }
623
624     RefPtr<APIObject> userData;
625
626     // Notify the bundle client.
627     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData);
628     if (policy == WKBundlePagePolicyActionUse) {
629         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
630         return;
631     }
632
633     uint64_t listenerID = m_frame->setUpPolicyListener(function);
634     bool receivedPolicyAction;
635     uint64_t policyAction;
636     uint64_t downloadID;
637
638     // Notify the UIProcess.
639     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), response, request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForResponse::Reply(receivedPolicyAction, policyAction, downloadID)))
640         return;
641
642     // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
643     if (receivedPolicyAction)
644         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
645 }
646
647 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
648 {
649     WebPage* webPage = m_frame->page();
650     if (!webPage)
651         return;
652
653     RefPtr<APIObject> userData;
654
655     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
656
657     // Notify the bundle client.
658     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData);
659     if (policy == WKBundlePagePolicyActionUse) {
660         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
661         return;
662     }
663
664
665     uint64_t listenerID = m_frame->setUpPolicyListener(function);
666
667     // Notify the UIProcess.
668     webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, frameName, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
669 }
670
671 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState)
672 {
673     WebPage* webPage = m_frame->page();
674     if (!webPage)
675         return;
676
677     // Always ignore requests with empty URLs. 
678     if (request.isEmpty()) { 
679         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyIgnore); 
680         return; 
681     }
682
683     RefPtr<APIObject> userData;
684
685     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
686
687     // Notify the bundle client.
688     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
689     if (policy == WKBundlePagePolicyActionUse) {
690         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
691         return;
692     }
693     
694     uint64_t listenerID = m_frame->setUpPolicyListener(function);
695     bool receivedPolicyAction;
696     uint64_t policyAction;
697     uint64_t downloadID;
698
699     // Notify the UIProcess.
700     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)))
701         return;
702
703     // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
704     if (receivedPolicyAction)
705         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
706 }
707
708 void WebFrameLoaderClient::cancelPolicyCheck()
709 {
710     m_frame->invalidatePolicyListener();
711 }
712
713 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
714 {
715     WebPage* webPage = m_frame->page();
716     if (!webPage)
717         return;
718
719     RefPtr<APIObject> userData;
720
721     // Notify the bundle client.
722     webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData);
723
724     // Notify the UIProcess.
725     webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
726 }
727
728 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> prpFormState)
729 {
730     WebPage* webPage = m_frame->page();
731     if (!webPage)
732         return;
733
734     // FIXME: Pass more of the form state.
735     RefPtr<FormState> formState = prpFormState;
736     
737     HTMLFormElement* form = formState->form();
738     WebFrame* sourceFrame = static_cast<WebFrameLoaderClient*>(formState->sourceFrame()->loader()->client())->webFrame();    
739     const Vector<std::pair<String, String> >& values = formState->textFieldValues();
740
741     RefPtr<APIObject> userData;
742     webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData);
743
744
745     uint64_t listenerID = m_frame->setUpPolicyListener(function);
746     StringPairVector valuesVector(values);
747
748     webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), valuesVector, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
749 }
750
751 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
752 {
753     notImplemented();
754 }
755
756 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
757 {
758     notImplemented();
759 }
760
761 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
762 {
763     if (!m_pluginView)
764         return;
765     
766     m_pluginView->manualLoadDidFail(error);
767     m_pluginView = 0;
768     m_hasSentResponseToPluginView = false;
769 }
770
771 void WebFrameLoaderClient::willChangeEstimatedProgress()
772 {
773     notImplemented();
774 }
775
776 void WebFrameLoaderClient::didChangeEstimatedProgress()
777 {
778     notImplemented();
779 }
780
781 void WebFrameLoaderClient::postProgressStartedNotification()
782 {
783     if (WebPage* webPage = m_frame->page()) {
784         if (m_frame->isMainFrame())
785             webPage->send(Messages::WebPageProxy::DidStartProgress());
786     }
787 }
788
789 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
790 {
791     if (WebPage* webPage = m_frame->page()) {
792         if (m_frame->isMainFrame()) {
793             double progress = webPage->corePage()->progress()->estimatedProgress();
794             webPage->send(Messages::WebPageProxy::DidChangeProgress(progress));
795         }
796     }
797 }
798
799 void WebFrameLoaderClient::postProgressFinishedNotification()
800 {
801     if (WebPage* webPage = m_frame->page()) {
802         if (m_frame->isMainFrame())
803             webPage->send(Messages::WebPageProxy::DidFinishProgress());
804     }
805 }
806
807 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
808 {
809     notImplemented();
810 }
811
812 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
813 {
814     m_frame->startDownload(request);
815 }
816
817 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
818 {
819     notImplemented();
820 }
821
822 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
823 {
824     notImplemented();
825 }
826
827 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
828 {
829     // If we're loading a custom representation, we don't want to hand off the data to WebCore.
830     if (m_frameHasCustomRepresentation)
831         return;
832
833     if (!m_pluginView)
834         loader->commitData(data, length);
835
836     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
837     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
838     if (m_frame->coreFrame()->document()->isMediaDocument())
839         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
840
841     // Calling commitData did not create the plug-in view.
842     if (!m_pluginView)
843         return;
844
845     if (!m_hasSentResponseToPluginView) {
846         m_pluginView->manualLoadDidReceiveResponse(loader->response());
847         // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
848         // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
849         // to null
850         if (!m_pluginView)
851             return;
852         m_hasSentResponseToPluginView = true;
853     }
854     m_pluginView->manualLoadDidReceiveData(data, length);
855 }
856
857 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
858 {
859     if (!m_pluginView) {
860         committedLoad(loader, 0, 0);
861
862         if (m_frameHasCustomRepresentation) {
863             WebPage* webPage = m_frame->page();
864             if (!webPage)
865                 return;
866
867             RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData();
868             CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0);
869             
870             webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomRepresentation(loader->response().suggestedFilename(), dataReference));
871         }
872
873         return;
874     }
875
876     m_pluginView->manualLoadDidFinishLoading();
877     m_pluginView = 0;
878     m_hasSentResponseToPluginView = false;
879 }
880
881 void WebFrameLoaderClient::updateGlobalHistory()
882 {
883     WebPage* webPage = m_frame->page();
884     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
885         return;
886
887     DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
888
889     WebNavigationDataStore data;
890     data.url = loader->urlForHistory().string();
891     // FIXME: use direction of title.
892     data.title = loader->title().string();
893     data.originalRequest = loader->originalRequestCopy();
894
895     WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0);
896 }
897
898 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
899 {
900     WebPage* webPage = m_frame->page();
901     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
902         return;
903
904     DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
905     ASSERT(loader->unreachableURL().isEmpty());
906
907     // Client redirect
908     if (!loader->clientRedirectSourceForHistory().isNull()) {
909         WebProcess::shared().connection()->send(Messages::WebContext::DidPerformClientRedirect(webPage->pageID(),
910             loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0);
911     }
912
913     // Server redirect
914     if (!loader->serverRedirectSourceForHistory().isNull()) {
915         WebProcess::shared().connection()->send(Messages::WebContext::DidPerformServerRedirect(webPage->pageID(),
916             loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0);
917     }
918 }
919
920 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
921 {
922     WebPage* webPage = m_frame->page();
923     if (!webPage)
924         return false;
925     
926     uint64_t itemID = WebBackForwardListProxy::idForItem(item);
927     if (!itemID) {
928         // We should never be considering navigating to an item that is not actually in the back/forward list.
929         ASSERT_NOT_REACHED();
930         return false;
931     }
932     
933     bool shouldGoToBackForwardListItem;
934     if (!webPage->sendSync(Messages::WebPageProxy::ShouldGoToBackForwardListItem(itemID), Messages::WebPageProxy::ShouldGoToBackForwardListItem::Reply(shouldGoToBackForwardListItem)))
935         return false;
936     
937     return shouldGoToBackForwardListItem;
938 }
939
940 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
941 {
942     return true;
943 }
944
945 void WebFrameLoaderClient::didDisplayInsecureContent()
946 {
947     WebPage* webPage = m_frame->page();
948     if (!webPage)
949         return;
950
951     RefPtr<APIObject> userData;
952
953     webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData);
954
955     webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
956 }
957
958 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const KURL&)
959 {
960     WebPage* webPage = m_frame->page();
961     if (!webPage)
962         return;
963
964     RefPtr<APIObject> userData;
965
966     webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData);
967
968     webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
969 }
970
971 void WebFrameLoaderClient::didDetectXSS(const KURL&, bool)
972 {
973     WebPage* webPage = m_frame->page();
974     if (!webPage)
975         return;
976
977     RefPtr<APIObject> userData;
978
979     webPage->injectedBundleLoaderClient().didDetectXSSForFrame(webPage, m_frame, userData);
980
981     webPage->send(Messages::WebPageProxy::DidDetectXSSForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
982 }
983
984 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
985 {
986     return WebKit::cancelledError(request);
987 }
988
989 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
990 {
991     return WebKit::blockedError(request);
992 }
993
994 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
995 {
996     return WebKit::cannotShowURLError(request);
997 }
998
999 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
1000 {
1001     return WebKit::interruptedForPolicyChangeError(request);
1002 }
1003
1004 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
1005 {
1006     return WebKit::cannotShowMIMETypeError(response);
1007 }
1008
1009 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
1010 {
1011     return WebKit::fileDoesNotExistError(response);
1012 }
1013
1014 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
1015 {
1016     return WebKit::pluginWillHandleLoadError(response);
1017 }
1018
1019 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1020 {
1021     DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest())));
1022     DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse())));
1023
1024     if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain())
1025         return false;
1026
1027     if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain())
1028         return false;
1029
1030 #if PLATFORM(QT)
1031     DEFINE_STATIC_LOCAL(const ResourceError, errorInterruptedForPolicyChange, (this->interruptedForPolicyChangeError(ResourceRequest())));
1032
1033     if (error.errorCode() == errorInterruptedForPolicyChange.errorCode() && error.domain() == errorInterruptedForPolicyChange.domain())
1034         return false;
1035 #endif
1036
1037     return true;
1038 }
1039
1040 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
1041 {
1042     notImplemented();
1043     return true;
1044 }
1045
1046 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
1047 {
1048     notImplemented();
1049     return true;
1050 }
1051
1052 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
1053 {
1054     return true;
1055 }
1056
1057 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
1058 {
1059     notImplemented();
1060     return false;
1061 }
1062
1063 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
1064 {
1065     notImplemented();
1066     return String();
1067 }
1068
1069 void WebFrameLoaderClient::frameLoadCompleted()
1070 {
1071     WebPage* webPage = m_frame->page();
1072     if (!webPage)
1073         return;
1074
1075     if (m_frame == m_frame->page()->mainWebFrame())
1076         webPage->drawingArea()->setLayerTreeStateIsFrozen(false);
1077 }
1078
1079 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*)
1080 {
1081     notImplemented();
1082 }
1083
1084 void WebFrameLoaderClient::restoreViewState()
1085 {
1086     // Inform the UI process of the scale factor.
1087     double scaleFactor = m_frame->coreFrame()->loader()->history()->currentItem()->pageScaleFactor();
1088     m_frame->page()->send(Messages::WebPageProxy::PageScaleFactorDidChange(scaleFactor));
1089
1090     // FIXME: This should not be necessary. WebCore should be correctly invalidating
1091     // the view on restores from the back/forward cache.
1092     if (m_frame == m_frame->page()->mainWebFrame())
1093         m_frame->page()->drawingArea()->setNeedsDisplay(m_frame->page()->bounds());
1094 }
1095
1096 void WebFrameLoaderClient::provisionalLoadStarted()
1097 {
1098     WebPage* webPage = m_frame->page();
1099     if (!webPage)
1100         return;
1101
1102     if (m_frame == m_frame->page()->mainWebFrame())
1103         webPage->drawingArea()->setLayerTreeStateIsFrozen(true);
1104 }
1105
1106 void WebFrameLoaderClient::didFinishLoad()
1107 {
1108     // If we have a load listener, notify it.
1109     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
1110         loadListener->didFinishLoad(m_frame);
1111 }
1112
1113 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1114 {
1115     notImplemented();
1116 }
1117
1118 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& data)
1119 {
1120     return DocumentLoader::create(request, data);
1121 }
1122
1123 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
1124 {
1125     WebPage* webPage = m_frame->page();
1126     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1127         return;
1128
1129     // FIXME: use direction of title.
1130     WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(),
1131         title.string(), url.string(), m_frame->frameID()), 0);
1132 }
1133
1134 String WebFrameLoaderClient::userAgent(const KURL&)
1135 {
1136     WebPage* webPage = m_frame->page();
1137     if (!webPage)
1138         return String();
1139
1140     return webPage->userAgent();
1141 }
1142
1143 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
1144 {
1145 }
1146
1147 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
1148 {
1149     WebPage* webPage = m_frame->page();
1150     bool isMainFrame = webPage->mainWebFrame() == m_frame;
1151     
1152     const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response();
1153     m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForResponse(response);
1154 }
1155
1156 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1157 {
1158     WebPage* webPage = m_frame->page();
1159
1160     Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white;
1161     bool isMainFrame = webPage->mainWebFrame() == m_frame;
1162     bool shouldUseFixedLayout = isMainFrame && webPage->useFixedLayout();
1163
1164 #if !USE(TILED_BACKING_STORE)
1165     const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response();
1166     m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForResponse(response);
1167 #endif
1168
1169     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, /* transparent */ false, IntSize(), shouldUseFixedLayout);
1170     m_frame->coreFrame()->view()->setTransparent(!webPage->drawsBackground());
1171 }
1172
1173 void WebFrameLoaderClient::didSaveToPageCache()
1174 {
1175     WebPage* webPage = m_frame->page();
1176     if (!webPage)
1177         return;
1178
1179     if (m_frame->isMainFrame())
1180         return;
1181
1182     webPage->send(Messages::WebPageProxy::DidSaveFrameToPageCache(m_frame->frameID()));
1183 }
1184
1185 void WebFrameLoaderClient::didRestoreFromPageCache()
1186 {
1187     WebPage* webPage = m_frame->page();
1188     if (!webPage)
1189         return;
1190
1191     if (m_frame->isMainFrame())
1192         return;
1193
1194     WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(m_frame->coreFrame()->tree()->parent()->loader()->client())->webFrame();
1195     webPage->send(Messages::WebPageProxy::DidRestoreFrameFromPageCache(m_frame->frameID(), parentFrame->frameID()));
1196 }
1197
1198 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
1199 {
1200     WebPage* webPage = m_frame->page();
1201     if (!webPage)
1202         return;
1203
1204     webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
1205 }
1206
1207 bool WebFrameLoaderClient::canCachePage() const
1208 {
1209     // We cannot cache frames that have custom representations because they are
1210     // rendered in the UIProcess. 
1211     return !m_frameHasCustomRepresentation;
1212 }
1213
1214 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceResponse& response)
1215 {
1216     m_frame->convertHandleToDownload(handle, request, response);
1217 }
1218
1219 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1220                                                     const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1221 {
1222     WebPage* webPage = m_frame->page();
1223
1224     RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement);
1225
1226     Frame* coreSubframe = subframe->coreFrame();
1227     if (!coreSubframe)
1228         return 0;
1229
1230     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1231     if (!coreSubframe->page())
1232         return 0;
1233
1234     m_frame->coreFrame()->loader()->loadURLIntoChildFrame(url, referrer, coreSubframe);
1235
1236     // The frame's onload handler may have removed it from the document.
1237     if (!coreSubframe->tree()->parent())
1238         return 0;
1239
1240     return coreSubframe;
1241 }
1242
1243 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*)
1244 {
1245     notImplemented();
1246 }
1247
1248 void WebFrameLoaderClient::transferLoadingResourceFromPage(ResourceLoader*, const ResourceRequest&, Page*)
1249 {
1250     notImplemented();
1251 }
1252
1253 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1254 {
1255     ASSERT(paramNames.size() == paramValues.size());
1256     
1257     WebPage* webPage = m_frame->page();
1258     ASSERT(webPage);
1259     
1260     Plugin::Parameters parameters;
1261     parameters.url = url;
1262     parameters.names = paramNames;
1263     parameters.values = paramValues;
1264     parameters.mimeType = mimeType;
1265     parameters.loadManually = loadManually;
1266     parameters.documentURL = m_frame->coreFrame()->document()->url().string();
1267
1268     Frame* mainFrame = webPage->mainWebFrame()->coreFrame();
1269     if (m_frame->coreFrame() == mainFrame)
1270         parameters.toplevelDocumentURL = parameters.documentURL;
1271     else if (m_frame->coreFrame()->document()->securityOrigin()->canAccess(mainFrame->document()->securityOrigin())) {
1272         // We only want to set the toplevel document URL if the plug-in has access to it.
1273         parameters.toplevelDocumentURL = mainFrame->document()->url().string();
1274     }
1275
1276 #if PLUGIN_ARCHITECTURE(X11)
1277     // FIXME: This should really be X11-specific plug-in quirks.
1278     if (equalIgnoringCase(mimeType, "application/x-shockwave-flash")) {
1279         // Currently we don't support transparency and windowed mode.
1280         // Inject wmode=opaque to make Flash work in these conditions.
1281         size_t wmodeIndex = parameters.names.find("wmode");
1282         if (wmodeIndex == notFound) {
1283             parameters.names.append("wmode");
1284             parameters.values.append("opaque");
1285         } else if (equalIgnoringCase(parameters.values[wmodeIndex], "window"))
1286             parameters.values[wmodeIndex] = "opaque";
1287     } else if (equalIgnoringCase(mimeType, "application/x-webkit-test-netscape")) {
1288         parameters.names.append("windowedPlugin");
1289         parameters.values.append("false");
1290     }
1291 #endif
1292
1293     RefPtr<Plugin> plugin = webPage->createPlugin(m_frame, parameters);
1294     if (!plugin)
1295         return 0;
1296     
1297     return PluginView::create(pluginElement, plugin.release(), parameters);
1298 }
1299
1300 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1301 {
1302     ASSERT(!m_pluginView);
1303     ASSERT(pluginWidget);
1304     
1305     m_pluginView = static_cast<PluginView*>(pluginWidget);
1306 }
1307
1308 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues)
1309 {
1310     const String mimeType = "application/x-java-applet";
1311     RefPtr<Widget> plugin = createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, mimeType, false);
1312     if (!plugin) {
1313         if (WebPage* webPage = m_frame->page())
1314             webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(mimeType));
1315     }
1316     return plugin.release();
1317 }
1318
1319 static bool pluginSupportsExtension(PluginData* pluginData, const String& extension)
1320 {
1321     ASSERT(extension.lower() == extension);
1322
1323     for (size_t i = 0; i < pluginData->mimes().size(); ++i) {
1324         const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i];
1325
1326         if (mimeClassInfo.extensions.contains(extension))
1327             return true;
1328     }
1329     return false;
1330 }
1331
1332 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
1333 {
1334     // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
1335     // is consolidated.
1336
1337     String mimeType = mimeTypeIn;
1338     if (mimeType.isEmpty()) {
1339         String extension = url.path().substring(url.path().reverseFind('.') + 1).lower();
1340
1341         // Try to guess the MIME type from the extension.
1342         mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1343
1344         if (mimeType.isEmpty()) {
1345             // Check if there's a plug-in around that can handle the extension.
1346             if (WebPage* webPage = m_frame->page()) {
1347                 if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1348                     if (pluginSupportsExtension(pluginData, extension))
1349                         return ObjectContentNetscapePlugin;
1350                 }
1351             }
1352         }
1353     }
1354
1355     if (mimeType.isEmpty())
1356         return ObjectContentFrame;
1357
1358     bool plugInSupportsMIMEType = false;
1359     if (WebPage* webPage = m_frame->page()) {
1360         if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1361             if (pluginData->supportsMimeType(mimeType))
1362                 plugInSupportsMIMEType = true;
1363         }
1364     }
1365     
1366     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1367         return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage;
1368
1369     if (plugInSupportsMIMEType)
1370         return ObjectContentNetscapePlugin;
1371
1372     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1373         return ObjectContentFrame;
1374
1375     return ObjectContentNone;
1376 }
1377
1378 String WebFrameLoaderClient::overrideMediaType() const
1379 {
1380     notImplemented();
1381     return String();
1382 }
1383
1384 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1385 {
1386     WebPage* webPage = m_frame->page();
1387     if (!webPage)
1388         return;
1389
1390     webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1391
1392 #if PLATFORM(GTK)
1393     // Ensure the accessibility hierarchy is updated.
1394     webPage->updateAccessibilityTree();
1395 #endif
1396 }
1397
1398 void WebFrameLoaderClient::documentElementAvailable()
1399 {
1400     notImplemented();
1401 }
1402
1403 void WebFrameLoaderClient::didPerformFirstNavigation() const
1404 {
1405     notImplemented();
1406 }
1407
1408 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1409 {
1410     notImplemented();
1411 }
1412
1413 #if PLATFORM(MAC)
1414     
1415 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject() 
1416 {
1417     return m_frame->page()->accessibilityRemoteObject();
1418 }
1419     
1420 #if ENABLE(MAC_JAVA_BRIDGE)
1421 jobject WebFrameLoaderClient::javaApplet(NSView*) { return 0; }
1422 #endif
1423
1424 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1425 {
1426     WebPage* webPage = m_frame->page();
1427     if (!webPage)
1428         return response;
1429
1430     return webPage->injectedBundleResourceLoadClient().shouldCacheResponse(webPage, m_frame, identifier) ? response : nil;
1431 }
1432
1433 #endif // PLATFORM(MAC)
1434
1435 #if PLATFORM(WIN) && USE(CFNETWORK)
1436 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length)
1437 {
1438     WebPage* webPage = m_frame->page();
1439     if (!webPage)
1440         return true;
1441
1442     return webPage->injectedBundleResourceLoadClient().shouldCacheResponse(webPage, m_frame, identifier);
1443 }
1444 #endif // PLATFORM(WIN) && USE(CFNETWORK)
1445
1446 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& /*mimeType*/) const
1447 {
1448     notImplemented();
1449     return false;
1450 }
1451
1452 void WebFrameLoaderClient::didChangeScrollOffset()
1453 {
1454     WebPage* webPage = m_frame->page();
1455     if (!webPage)
1456         return;
1457
1458     if (!m_frame->isMainFrame())
1459         return;
1460
1461     // If this is called when tearing down a FrameView, the WebCore::Frame's
1462     // current FrameView will be null.
1463     if (!m_frame->coreFrame()->view())
1464         return;
1465
1466     webPage->didChangeScrollOffsetForMainFrame();
1467 }
1468
1469 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1470 {
1471     RefPtr<WebFrameNetworkingContext> context = WebFrameNetworkingContext::create(m_frame);
1472     return context.release();
1473 }
1474
1475 } // namespace WebKit