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