Add a NavigationActionData object for easy storage of navigation action data
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebCoreSupport / WebFrameLoaderClient.cpp
1 /*
2  * Copyright (C) 2010, 2011, 2012 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 "InjectedBundle.h"
32 #include "InjectedBundleBackForwardListItem.h"
33 #include "InjectedBundleDOMWindowExtension.h"
34 #include "InjectedBundleNavigationAction.h"
35 #include "InjectedBundleUserMessageCoders.h"
36 #include "NavigationActionData.h"
37 #include "PluginView.h"
38 #include "WebBackForwardListProxy.h"
39 #include "WebContextMessages.h"
40 #include "WebCoreArgumentCoders.h"
41 #include "WebErrors.h"
42 #include "WebEvent.h"
43 #include "WebFrame.h"
44 #include "WebFrameNetworkingContext.h"
45 #include "WebFullScreenManager.h"
46 #include "WebIconDatabaseMessages.h"
47 #include "WebNavigationDataStore.h"
48 #include "WebPage.h"
49 #include "WebPageProxyMessages.h"
50 #include "WebProcess.h"
51 #include "WebProcessProxyMessages.h"
52 #include <JavaScriptCore/APICast.h>
53 #include <JavaScriptCore/JSObject.h>
54 #include <WebCore/AXObjectCache.h>
55 #include <WebCore/CertificateInfo.h>
56 #include <WebCore/Chrome.h>
57 #include <WebCore/DOMWrapperWorld.h>
58 #include <WebCore/DocumentLoader.h>
59 #include <WebCore/FormState.h>
60 #include <WebCore/FrameLoadRequest.h>
61 #include <WebCore/FrameLoader.h>
62 #include <WebCore/FrameView.h>
63 #include <WebCore/HTMLAppletElement.h>
64 #include <WebCore/HTMLFormElement.h>
65 #include <WebCore/HistoryController.h>
66 #include <WebCore/HistoryItem.h>
67 #include <WebCore/MIMETypeRegistry.h>
68 #include <WebCore/MainFrame.h>
69 #include <WebCore/MouseEvent.h>
70 #include <WebCore/NotImplemented.h>
71 #include <WebCore/Page.h>
72 #include <WebCore/PluginData.h>
73 #include <WebCore/PluginDocument.h>
74 #include <WebCore/ProgressTracker.h>
75 #include <WebCore/ResourceBuffer.h>
76 #include <WebCore/ResourceError.h>
77 #include <WebCore/Settings.h>
78 #include <WebCore/SubframeLoader.h>
79 #include <WebCore/UIEventWithKeyState.h>
80 #include <WebCore/Widget.h>
81 #include <WebCore/WindowFeatures.h>
82 #include <wtf/NeverDestroyed.h>
83
84 using namespace WebCore;
85
86 namespace WebKit {
87
88 WebFrameLoaderClient::WebFrameLoaderClient()
89     : m_frame(0)
90     , m_hasSentResponseToPluginView(false)
91     , m_didCompletePageTransitionAlready(false)
92     , m_frameCameFromPageCache(false)
93 {
94 }
95
96 WebFrameLoaderClient::~WebFrameLoaderClient()
97 {
98 }
99     
100 void WebFrameLoaderClient::frameLoaderDestroyed()
101 {
102     if (WebPage* webPage = m_frame->page())
103         webPage->injectedBundleLoaderClient().willDestroyFrame(webPage, m_frame);
104
105     m_frame->invalidate();
106
107     // Balances explicit ref() in WebFrame::create().
108     m_frame->deref();
109 }
110
111 bool WebFrameLoaderClient::hasWebView() const
112 {
113     return m_frame->page();
114 }
115
116 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
117 {
118     notImplemented();
119 }
120
121 void WebFrameLoaderClient::forceLayout()
122 {
123     notImplemented();
124 }
125
126 void WebFrameLoaderClient::forceLayoutForNonHTML()
127 {
128     notImplemented();
129 }
130
131 void WebFrameLoaderClient::setCopiesOnScroll()
132 {
133     notImplemented();
134 }
135
136 void WebFrameLoaderClient::detachedFromParent2()
137 {
138     WebPage* webPage = m_frame->page();
139     if (!webPage)
140         return;
141
142     RefPtr<API::Object> userData;
143
144     // Notify the bundle client.
145     webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
146
147     // Notify the UIProcess.
148     webPage->send(Messages::WebPageProxy::DidRemoveFrameFromHierarchy(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
149
150 }
151
152 void WebFrameLoaderClient::detachedFromParent3()
153 {
154     notImplemented();
155 }
156
157 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
158 {
159     WebPage* webPage = m_frame->page();
160     if (!webPage)
161         return;
162
163     bool pageIsProvisionallyLoading = false;
164     if (FrameLoader* frameLoader = loader->frameLoader())
165         pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader;
166
167     webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading);
168 }
169
170 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
171 {
172     WebPage* webPage = m_frame->page();
173     if (!webPage)
174         return;
175
176     webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse);
177 }
178
179 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
180 {
181     WebPage* webPage = m_frame->page();
182     if (!webPage)
183         return true;
184
185     return webPage->injectedBundleResourceLoadClient().shouldUseCredentialStorage(webPage, m_frame, identifier);
186 }
187
188 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
189 {
190     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
191     // Once we do, we might need to make sure authentication fits with our solution.
192
193     WebPage* webPage = m_frame->page();
194     if (!webPage)
195         return;
196
197     WebProcess::shared().supplement<AuthenticationManager>()->didReceiveAuthenticationChallenge(m_frame, challenge);
198 }
199
200 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long /*identifier*/, const AuthenticationChallenge&)    
201 {
202     notImplemented();
203 }
204
205 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
206 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
207 {
208     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
209     // Once we do, we might need to make sure authentication fits with our solution.
210     
211     WebPage* webPage = m_frame->page();
212     if (!webPage)
213         return false;
214         
215     bool canAuthenticate;
216     if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate)))
217         return false;
218     
219     return canAuthenticate;
220 }
221 #endif
222
223 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
224 {
225     WebPage* webPage = m_frame->page();
226     if (!webPage)
227         return;
228
229     webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response);
230 }
231
232 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength)
233 {
234     WebPage* webPage = m_frame->page();
235     if (!webPage)
236         return;
237
238     webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength);
239 }
240
241 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
242 {
243     WebPage* webPage = m_frame->page();
244     if (!webPage)
245         return;
246
247     webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, 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 }
258
259 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
260 {
261     notImplemented();
262     return false;
263 }
264
265 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
266 {
267     WebPage* webPage = m_frame->page();
268     if (!webPage)
269         return;
270
271     // Notify the bundle client.
272     webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame);
273 }
274
275 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
276 {
277     WebPage* webPage = m_frame->page();
278     if (!webPage)
279         return;
280
281     DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader().provisionalDocumentLoader();
282     const String& url = provisionalLoader->url().string();
283     RefPtr<API::Object> userData;
284
285     // Notify the bundle client.
286     webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData);
287
288     // Notify the UIProcess.
289     webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), url, InjectedBundleUserMessageEncoder(userData.get())));
290 }
291
292 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
293 {
294     WebPage* webPage = m_frame->page();
295     if (!webPage)
296         return;
297
298     // Notify the bundle client.
299     webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame);
300 }
301
302 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const URL& url, double interval, double fireDate)
303 {
304     WebPage* webPage = m_frame->page();
305     if (!webPage)
306         return;
307
308     // Notify the bundle client.
309     webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate);
310 }
311
312 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
313 {
314     WebPage* webPage = m_frame->page();
315     if (!webPage)
316         return;
317
318     RefPtr<API::Object> userData;
319
320     // Notify the bundle client.
321     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData);
322
323     // Notify the UIProcess.
324     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
325 }
326
327 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
328 {
329     WebPage* webPage = m_frame->page();
330     if (!webPage)
331         return;
332
333     RefPtr<API::Object> userData;
334
335     // Notify the bundle client.
336     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData);
337
338     // Notify the UIProcess.
339     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
340 }
341
342 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
343 {
344     WebPage* webPage = m_frame->page();
345     if (!webPage)
346         return;
347
348     RefPtr<API::Object> userData;
349
350     // Notify the bundle client.
351     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData);
352
353     // Notify the UIProcess.
354     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
355 }
356
357 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
358 {
359     WebPage* webPage = m_frame->page();
360     if (!webPage)
361         return;
362
363     RefPtr<API::Object> userData;
364
365     // Notify the bundle client.
366     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData);
367
368     // Notify the UIProcess.
369     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
370 }
371
372 void WebFrameLoaderClient::dispatchWillClose()
373 {
374     notImplemented();
375 }
376
377 void WebFrameLoaderClient::dispatchDidReceiveIcon()
378 {
379     WebProcess::shared().parentProcessConnection()->send(Messages::WebIconDatabase::DidReceiveIconForPageURL(m_frame->url()), 0);
380 }
381
382 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
383 {
384     WebPage* webPage = m_frame->page();
385     if (!webPage)
386         return;
387
388 #if ENABLE(FULLSCREEN_API)
389     Element* documentElement = m_frame->coreFrame()->document()->documentElement();
390     if (documentElement && documentElement->containsFullScreenElement())
391         webPage->fullScreenManager()->exitFullScreenForElement(webPage->fullScreenManager()->element());
392 #endif
393
394     webPage->findController().hideFindUI();
395     webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);
396
397     DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader().provisionalDocumentLoader();
398     const String& url = provisionalLoader->url().string();
399     RefPtr<API::Object> userData;
400
401     // Notify the bundle client.
402     webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);
403
404     String unreachableURL = provisionalLoader->unreachableURL().string();
405
406     // Notify the UIProcess.
407     webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, unreachableURL, InjectedBundleUserMessageEncoder(userData.get())));
408 }
409
410 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
411 {
412     WebPage* webPage = m_frame->page();
413     if (!webPage)
414         return;
415
416     RefPtr<API::Object> userData;
417
418     // Notify the bundle client.
419     // FIXME: use direction of title.
420     webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData);
421
422     // Notify the UIProcess.
423     webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), InjectedBundleUserMessageEncoder(userData.get())));
424 }
425
426 void WebFrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType)
427 {
428     notImplemented();
429 }
430
431 void WebFrameLoaderClient::dispatchDidCommitLoad()
432 {
433     WebPage* webPage = m_frame->page();
434     if (!webPage)
435         return;
436
437     const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response();
438     RefPtr<API::Object> userData;
439
440     // Notify the bundle client.
441     webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData);
442
443     webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
444
445     // Notify the UIProcess.
446
447     webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), response.mimeType(), m_frame->coreFrame()->loader().loadType(), CertificateInfo(response), InjectedBundleUserMessageEncoder(userData.get())));
448
449     webPage->didCommitLoad(m_frame);
450 }
451
452 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
453 {
454     WebPage* webPage = m_frame->page();
455     if (!webPage)
456         return;
457
458     RefPtr<API::Object> 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<API::Object> 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<API::Object> 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<API::Object> 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     webPage->didFinishLoad(m_frame);
526 }
527
528 void WebFrameLoaderClient::forcePageTransitionIfNeeded()
529 {
530     if (m_didCompletePageTransitionAlready)
531         return;
532
533     WebPage* webPage = m_frame->page();
534     if (!webPage)
535         return;
536
537     webPage->didCompletePageTransition();
538     m_didCompletePageTransitionAlready = true;
539 }
540
541 void WebFrameLoaderClient::dispatchDidLayout(LayoutMilestones milestones)
542 {
543     WebPage* webPage = m_frame->page();
544     if (!webPage)
545         return;
546
547     RefPtr<API::Object> userData;
548
549     if (milestones & DidFirstLayout) {
550         // FIXME: We should consider removing the old didFirstLayout API since this is doing double duty with the
551         // new didLayout API.
552         webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
553         webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
554
555         if (m_frame == m_frame->page()->mainWebFrame()) {
556             if (!webPage->corePage()->settings().suppressesIncrementalRendering() && !m_didCompletePageTransitionAlready) {
557                 webPage->didCompletePageTransition();
558                 m_didCompletePageTransitionAlready = true;
559             }
560         }
561     
562 #if USE(TILED_BACKING_STORE)
563         // Make sure viewport properties are dispatched on the main frame by the time the first layout happens.
564         ASSERT(!webPage->useFixedLayout() || m_frame != m_frame->page()->mainWebFrame() || m_frame->coreFrame()->document()->didDispatchViewportPropertiesChanged());
565 #endif
566     }
567
568     // Send this after DidFirstLayout-specific calls since some clients expect to get those messages first.
569     webPage->injectedBundleLoaderClient().didLayout(webPage, milestones, userData);
570     webPage->send(Messages::WebPageProxy::DidLayout(milestones, InjectedBundleUserMessageEncoder(userData.get())));
571
572     if (milestones & DidFirstVisuallyNonEmptyLayout) {
573         // FIXME: We should consider removing the old didFirstVisuallyNonEmptyLayoutForFrame API since this is doing
574         // double duty with the new didLayout API.
575         webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
576         webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
577     }
578 }
579
580 void WebFrameLoaderClient::dispatchDidLayout()
581 {
582     WebPage* webPage = m_frame->page();
583     if (!webPage)
584         return;
585
586     // Notify the bundle client.
587     webPage->injectedBundleLoaderClient().didLayoutForFrame(webPage, m_frame);
588
589     webPage->recomputeShortCircuitHorizontalWheelEventsState();
590
591     // NOTE: Unlike the other layout notifications, this does not notify the
592     // the UIProcess for every call.
593
594     if (m_frame == m_frame->page()->mainWebFrame()) {
595         // FIXME: Remove at the soonest possible time.
596         webPage->send(Messages::WebPageProxy::SetRenderTreeSize(webPage->renderTreeSize()));
597         webPage->mainFrameDidLayout();
598     }
599 }
600
601 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
602 {
603     WebPage* webPage = m_frame->page();
604     if (!webPage)
605         return 0;
606
607     // Just call through to the chrome client.
608     Page* newPage = webPage->corePage()->chrome().createWindow(m_frame->coreFrame(), FrameLoadRequest(m_frame->coreFrame()->document()->securityOrigin()), WindowFeatures(), navigationAction);
609     if (!newPage)
610         return 0;
611     
612     return &newPage->mainFrame();
613 }
614
615 void WebFrameLoaderClient::dispatchShow()
616 {
617     WebPage* webPage = m_frame->page();
618     if (!webPage)
619         return;
620
621     webPage->show();
622 }
623
624 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, FramePolicyFunction function)
625 {
626     WebPage* webPage = m_frame->page();
627     if (!webPage)
628         return;
629
630     if (!request.url().string()) {
631         function(PolicyUse);
632         return;
633     }
634
635     RefPtr<API::Object> userData;
636
637     // Notify the bundle client.
638     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData);
639     if (policy == WKBundlePagePolicyActionUse) {
640         function(PolicyUse);
641         return;
642     }
643
644     bool canShowMIMEType = webPage->canShowMIMEType(response.mimeType());
645
646     uint64_t listenerID = m_frame->setUpPolicyListener(std::move(function));
647     bool receivedPolicyAction;
648     uint64_t policyAction;
649     uint64_t downloadID;
650
651     // Notify the UIProcess.
652     // FIXME (126021): It is not good to change IPC behavior conditionally, and SpinRunLoopWhileWaitingForReply was known to cause trouble in other similar cases.
653     unsigned syncSendFlags = (WebCore::AXObjectCache::accessibilityEnabled()) ? IPC::SpinRunLoopWhileWaitingForReply : 0;
654     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), response, request, canShowMIMEType, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(receivedPolicyAction, policyAction, downloadID), std::chrono::milliseconds::max(), syncSendFlags))
655         return;
656
657     // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
658     if (receivedPolicyAction)
659         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
660 }
661
662 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, FramePolicyFunction function)
663 {
664     WebPage* webPage = m_frame->page();
665     if (!webPage)
666         return;
667
668     RefPtr<API::Object> userData;
669
670     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
671
672     // Notify the bundle client.
673     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData);
674     if (policy == WKBundlePagePolicyActionUse) {
675         function(PolicyUse);
676         return;
677     }
678
679
680     uint64_t listenerID = m_frame->setUpPolicyListener(std::move(function));
681
682     NavigationActionData navigationActionData;
683     navigationActionData.navigationType = action->navigationType();
684     navigationActionData.modifiers = action->modifiers();
685     navigationActionData.mouseButton = action->mouseButton();
686
687     webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), navigationActionData, request, frameName, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
688 }
689
690 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> prpFormState, FramePolicyFunction function)
691 {
692     WebPage* webPage = m_frame->page();
693     if (!webPage)
694         return;
695
696     // Always ignore requests with empty URLs. 
697     if (request.isEmpty()) {
698         function(PolicyIgnore);
699         return;
700     }
701
702     RefPtr<API::Object> userData;
703     RefPtr<FormState> formState = prpFormState;
704
705     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
706
707     // Notify the bundle client.
708     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
709     if (policy == WKBundlePagePolicyActionUse) {
710         function(PolicyUse);
711         return;
712     }
713     
714     uint64_t listenerID = m_frame->setUpPolicyListener(std::move(function));
715     bool receivedPolicyAction;
716     uint64_t policyAction;
717     uint64_t downloadID;
718
719     RefPtr<WebFrame> originatingFrame;
720     switch (action->navigationType()) {
721     case NavigationTypeLinkClicked:
722         originatingFrame = action->hitTestResult()->frame();
723         break;
724     case NavigationTypeFormSubmitted:
725     case NavigationTypeFormResubmitted:
726         if (formState) {
727             if (WebFrameLoaderClient* originatingFrameLoaderClient = toWebFrameLoaderClient(formState->sourceDocument()->frame()->loader().client()))
728                 originatingFrame = originatingFrameLoaderClient->webFrame();
729         }
730         break;
731     case NavigationTypeBackForward:
732     case NavigationTypeReload:
733     case NavigationTypeOther:
734         break;
735     }
736
737     NavigationActionData navigationActionData;
738     navigationActionData.navigationType = action->navigationType();
739     navigationActionData.modifiers = action->modifiers();
740     navigationActionData.mouseButton = action->mouseButton();
741
742     // Notify the UIProcess.
743     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), navigationActionData, originatingFrame ? originatingFrame->frameID() : 0, navigationAction.resourceRequest(), request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, policyAction, downloadID)))
744         return;
745
746     // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
747     if (receivedPolicyAction)
748         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
749 }
750
751 void WebFrameLoaderClient::cancelPolicyCheck()
752 {
753     m_frame->invalidatePolicyListener();
754 }
755
756 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
757 {
758     WebPage* webPage = m_frame->page();
759     if (!webPage)
760         return;
761
762     RefPtr<API::Object> userData;
763
764     // Notify the bundle client.
765     webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData);
766
767     // Notify the UIProcess.
768     webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
769 }
770
771 void WebFrameLoaderClient::dispatchWillSendSubmitEvent(PassRefPtr<FormState> prpFormState)
772 {
773     WebPage* webPage = m_frame->page();
774     if (!webPage)
775         return;
776
777     RefPtr<FormState> formState = prpFormState;
778     HTMLFormElement* form = formState->form();
779
780     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(formState->sourceDocument()->frame()->loader().client());
781     WebFrame* sourceFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
782     ASSERT(sourceFrame);
783
784     webPage->injectedBundleFormClient().willSendSubmitEvent(webPage, form, m_frame, sourceFrame, formState->textFieldValues());
785 }
786
787 void WebFrameLoaderClient::dispatchWillSubmitForm(PassRefPtr<FormState> prpFormState, FramePolicyFunction function)
788 {
789     WebPage* webPage = m_frame->page();
790     if (!webPage)
791         return;
792
793     // FIXME: Pass more of the form state.
794     RefPtr<FormState> formState = prpFormState;
795     
796     HTMLFormElement* form = formState->form();
797
798     WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(formState->sourceDocument()->frame()->loader().client());
799     WebFrame* sourceFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
800     ASSERT(sourceFrame);
801
802     const Vector<std::pair<String, String>>& values = formState->textFieldValues();
803
804     RefPtr<API::Object> userData;
805     webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData);
806
807
808     uint64_t listenerID = m_frame->setUpPolicyListener(std::move(function));
809
810     webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), values, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
811 }
812
813 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
814 {
815     notImplemented();
816 }
817
818 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
819 {
820     if (!m_pluginView)
821         return;
822     
823     m_pluginView->manualLoadDidFail(error);
824     m_pluginView = 0;
825     m_hasSentResponseToPluginView = false;
826 }
827
828 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
829 {
830     notImplemented();
831 }
832
833 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
834 {
835     m_frame->startDownload(request);
836 }
837
838 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
839 {
840     notImplemented();
841 }
842
843 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
844 {
845     notImplemented();
846 }
847
848 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
849 {
850     if (!m_pluginView)
851         loader->commitData(data, length);
852
853     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
854     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
855     if (m_frame->coreFrame()->document()->isMediaDocument())
856         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
857
858     // Calling commitData did not create the plug-in view.
859     if (!m_pluginView)
860         return;
861
862     if (!m_hasSentResponseToPluginView) {
863         m_pluginView->manualLoadDidReceiveResponse(loader->response());
864         // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
865         // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
866         // to null
867         if (!m_pluginView)
868             return;
869         m_hasSentResponseToPluginView = true;
870     }
871     m_pluginView->manualLoadDidReceiveData(data, length);
872 }
873
874 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
875 {
876     if (!m_pluginView)
877         return;
878
879     // If we just received an empty response without any data, we won't have sent a response to the plug-in view.
880     // Make sure to do this before calling manualLoadDidFinishLoading.
881     if (!m_hasSentResponseToPluginView) {
882         m_pluginView->manualLoadDidReceiveResponse(loader->response());
883
884         // Protect against the above call nulling out the plug-in (by trying to cancel the load for example).
885         if (!m_pluginView)
886             return;
887     }
888
889     m_pluginView->manualLoadDidFinishLoading();
890     m_pluginView = 0;
891     m_hasSentResponseToPluginView = false;
892 }
893
894 void WebFrameLoaderClient::updateGlobalHistory()
895 {
896     WebPage* webPage = m_frame->page();
897     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
898         return;
899
900     DocumentLoader* loader = m_frame->coreFrame()->loader().documentLoader();
901
902     WebNavigationDataStore data;
903     data.url = loader->url().string();
904     // FIXME: use direction of title.
905     data.title = loader->title().string();
906     data.originalRequest = loader->originalRequestCopy();
907     data.response = loader->response();
908
909     WebProcess::shared().parentProcessConnection()->send(Messages::WebProcessProxy::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0);
910 }
911
912 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
913 {
914     WebPage* webPage = m_frame->page();
915     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
916         return;
917
918     DocumentLoader* loader = m_frame->coreFrame()->loader().documentLoader();
919     ASSERT(loader->unreachableURL().isEmpty());
920
921     // Client redirect
922     if (!loader->clientRedirectSourceForHistory().isNull()) {
923         WebProcess::shared().parentProcessConnection()->send(Messages::WebProcessProxy::DidPerformClientRedirect(webPage->pageID(),
924             loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0);
925     }
926
927     // Server redirect
928     if (!loader->serverRedirectSourceForHistory().isNull()) {
929         WebProcess::shared().parentProcessConnection()->send(Messages::WebProcessProxy::DidPerformServerRedirect(webPage->pageID(),
930             loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0);
931     }
932 }
933
934 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
935 {
936     WebPage* webPage = m_frame->page();
937     if (!webPage)
938         return false;
939     
940     uint64_t itemID = WebBackForwardListProxy::idForItem(item);
941     if (!itemID) {
942         // We should never be considering navigating to an item that is not actually in the back/forward list.
943         ASSERT_NOT_REACHED();
944         return false;
945     }
946
947     RefPtr<InjectedBundleBackForwardListItem> bundleItem = InjectedBundleBackForwardListItem::create(item);
948     RefPtr<API::Object> userData;
949
950     // Ask the bundle client first
951     bool shouldGoToBackForwardListItem = webPage->injectedBundleLoaderClient().shouldGoToBackForwardListItem(webPage, bundleItem.get(), userData);
952     if (!shouldGoToBackForwardListItem)
953         return false;
954     
955     webPage->send(Messages::WebPageProxy::WillGoToBackForwardListItem(itemID, InjectedBundleUserMessageEncoder(userData.get())));
956     return true;
957 }
958
959 void WebFrameLoaderClient::didDisplayInsecureContent()
960 {
961     WebPage* webPage = m_frame->page();
962     if (!webPage)
963         return;
964
965     RefPtr<API::Object> userData;
966
967     webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData);
968
969     webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
970 }
971
972 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const URL&)
973 {
974     WebPage* webPage = m_frame->page();
975     if (!webPage)
976         return;
977
978     RefPtr<API::Object> userData;
979
980     webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData);
981
982     webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
983 }
984
985 void WebFrameLoaderClient::didDetectXSS(const URL&, bool)
986 {
987     WebPage* webPage = m_frame->page();
988     if (!webPage)
989         return;
990
991     RefPtr<API::Object> userData;
992
993     webPage->injectedBundleLoaderClient().didDetectXSSForFrame(webPage, m_frame, userData);
994
995     webPage->send(Messages::WebPageProxy::DidDetectXSSForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
996 }
997
998 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
999 {
1000     return WebKit::cancelledError(request);
1001 }
1002
1003 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
1004 {
1005     return WebKit::blockedError(request);
1006 }
1007
1008 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
1009 {
1010     return WebKit::cannotShowURLError(request);
1011 }
1012
1013 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
1014 {
1015     return WebKit::interruptedForPolicyChangeError(request);
1016 }
1017
1018 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
1019 {
1020     return WebKit::cannotShowMIMETypeError(response);
1021 }
1022
1023 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
1024 {
1025     return WebKit::fileDoesNotExistError(response);
1026 }
1027
1028 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
1029 {
1030     return WebKit::pluginWillHandleLoadError(response);
1031 }
1032
1033 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1034 {
1035     static NeverDestroyed<const ResourceError> cancelledError(this->cancelledError(ResourceRequest()));
1036     static NeverDestroyed<const ResourceError> pluginWillHandleLoadError(this->pluginWillHandleLoadError(ResourceResponse()));
1037
1038     if (error.errorCode() == cancelledError.get().errorCode() && error.domain() == cancelledError.get().domain())
1039         return false;
1040
1041     if (error.errorCode() == pluginWillHandleLoadError.get().errorCode() && error.domain() == pluginWillHandleLoadError.get().domain())
1042         return false;
1043
1044     return true;
1045 }
1046
1047 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
1048 {
1049     notImplemented();
1050     return true;
1051 }
1052
1053 bool WebFrameLoaderClient::canShowMIMEType(const String& /*MIMEType*/) const
1054 {
1055     notImplemented();
1056     return true;
1057 }
1058
1059 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const
1060 {
1061     return true;
1062 }
1063
1064 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& /*URLScheme*/) const
1065 {
1066     notImplemented();
1067     return false;
1068 }
1069
1070 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1071 {
1072     notImplemented();
1073     return String();
1074 }
1075
1076 void WebFrameLoaderClient::frameLoadCompleted()
1077 {
1078     // Note: Can be called multiple times.
1079     WebPage* webPage = m_frame->page();
1080     if (!webPage)
1081         return;
1082
1083     if (m_frame == m_frame->page()->mainWebFrame() && !m_didCompletePageTransitionAlready) {
1084         webPage->didCompletePageTransition();
1085         m_didCompletePageTransitionAlready = true;
1086     }
1087 }
1088
1089 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*)
1090 {
1091     notImplemented();
1092 }
1093
1094 void WebFrameLoaderClient::restoreViewState()
1095 {
1096     // Inform the UI process of the scale factor.
1097     double scaleFactor = m_frame->coreFrame()->loader().history().currentItem()->pageScaleFactor();
1098
1099     // A scale factor of 0 means the history item has the default scale factor, thus we do not need to update it.
1100     if (scaleFactor)
1101         m_frame->page()->send(Messages::WebPageProxy::PageScaleFactorDidChange(scaleFactor));
1102
1103     // FIXME: This should not be necessary. WebCore should be correctly invalidating
1104     // the view on restores from the back/forward cache.
1105     if (m_frame == m_frame->page()->mainWebFrame())
1106         m_frame->page()->drawingArea()->setNeedsDisplay();
1107 }
1108
1109 void WebFrameLoaderClient::provisionalLoadStarted()
1110 {
1111     WebPage* webPage = m_frame->page();
1112     if (!webPage)
1113         return;
1114
1115     if (m_frame == m_frame->page()->mainWebFrame()) {
1116         webPage->didStartPageTransition();
1117         m_didCompletePageTransitionAlready = false;
1118     }
1119 }
1120
1121 void WebFrameLoaderClient::didFinishLoad()
1122 {
1123     // If we have a load listener, notify it.
1124     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
1125         loadListener->didFinishLoad(m_frame);
1126 }
1127
1128 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1129 {
1130     notImplemented();
1131 }
1132
1133 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& data)
1134 {
1135     return DocumentLoader::create(request, data);
1136 }
1137
1138 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const URL& url)
1139 {
1140     WebPage* webPage = m_frame->page();
1141     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1142         return;
1143
1144     // FIXME: use direction of title.
1145     WebProcess::shared().parentProcessConnection()->send(Messages::WebProcessProxy::DidUpdateHistoryTitle(webPage->pageID(),
1146         title.string(), url.string(), m_frame->frameID()), 0);
1147 }
1148
1149 String WebFrameLoaderClient::userAgent(const URL&)
1150 {
1151     WebPage* webPage = m_frame->page();
1152     if (!webPage)
1153         return String();
1154
1155     return webPage->userAgent();
1156 }
1157
1158 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
1159 {
1160 }
1161
1162 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
1163 {
1164 }
1165
1166 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1167 {
1168     WebPage* webPage = m_frame->page();
1169
1170     Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white;
1171     bool isMainFrame = webPage->mainWebFrame() == m_frame;
1172     bool isTransparent = !webPage->drawsBackground();
1173     bool shouldUseFixedLayout = isMainFrame && webPage->useFixedLayout();
1174     bool shouldDisableScrolling = isMainFrame && !webPage->mainFrameIsScrollable();
1175     bool shouldHideScrollbars = shouldUseFixedLayout || shouldDisableScrolling;
1176     IntRect fixedVisibleContentRect;
1177
1178 #if USE(TILED_BACKING_STORE)
1179     if (m_frame->coreFrame()->view())
1180         fixedVisibleContentRect = m_frame->coreFrame()->view()->fixedVisibleContentRect();
1181 #endif
1182
1183     m_frameCameFromPageCache = false;
1184
1185     ScrollbarMode defaultScrollbarMode = shouldHideScrollbars ? ScrollbarAlwaysOff : ScrollbarAuto;
1186
1187     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, isTransparent,
1188         IntSize(), fixedVisibleContentRect, shouldUseFixedLayout,
1189         defaultScrollbarMode, /* lock */ shouldHideScrollbars, defaultScrollbarMode, /* lock */ shouldHideScrollbars);
1190
1191     if (int minimumLayoutWidth = webPage->minimumLayoutSize().width()) {
1192         int minimumLayoutHeight = std::max(webPage->minimumLayoutSize().height(), 1);
1193         int maximumSize = std::numeric_limits<int>::max();
1194         m_frame->coreFrame()->view()->enableAutoSizeMode(true, IntSize(minimumLayoutWidth, minimumLayoutHeight), IntSize(maximumSize, maximumSize));
1195         m_frame->coreFrame()->view()->setAutoSizeFixedMinimumHeight(webPage->size().height());
1196     }
1197
1198     m_frame->coreFrame()->view()->setProhibitsScrolling(shouldDisableScrolling);
1199     m_frame->coreFrame()->view()->setVisualUpdatesAllowedByClient(!webPage->shouldExtendIncrementalRenderingSuppression());
1200 #if PLATFORM(MAC)
1201     m_frame->coreFrame()->view()->setExposedRect(webPage->drawingArea()->exposedRect());
1202 #endif
1203 #if PLATFORM(IOS)
1204     m_frame->coreFrame()->view()->setDelegatesScrolling(true);
1205 #endif
1206
1207     if (webPage->scrollPinningBehavior() != DoNotPin)
1208         m_frame->coreFrame()->view()->setScrollPinningBehavior(webPage->scrollPinningBehavior());
1209
1210 #if USE(TILED_BACKING_STORE)
1211     if (shouldUseFixedLayout) {
1212         m_frame->coreFrame()->view()->setDelegatesScrolling(shouldUseFixedLayout);
1213         m_frame->coreFrame()->view()->setPaintsEntireContents(shouldUseFixedLayout);
1214         return;
1215     }
1216 #endif
1217 }
1218
1219 void WebFrameLoaderClient::didSaveToPageCache()
1220 {
1221     WebPage* webPage = m_frame->page();
1222     if (!webPage)
1223         return;
1224
1225     webPage->send(Messages::WebPageProxy::DidSaveToPageCache());
1226 }
1227
1228 void WebFrameLoaderClient::didRestoreFromPageCache()
1229 {
1230     m_frameCameFromPageCache = true;
1231 }
1232
1233 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
1234 {
1235     WebPage* webPage = m_frame->page();
1236     if (!webPage)
1237         return;
1238
1239     webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
1240 }
1241
1242 void WebFrameLoaderClient::convertMainResourceLoadToDownload(DocumentLoader *documentLoader, const ResourceRequest& request, const ResourceResponse& response)
1243 {
1244     m_frame->convertMainResourceLoadToDownload(documentLoader, request, response);
1245 }
1246
1247 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1248                                                     const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
1249 {
1250     WebPage* webPage = m_frame->page();
1251
1252     RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement);
1253
1254     Frame* coreSubframe = subframe->coreFrame();
1255     if (!coreSubframe)
1256         return 0;
1257
1258     // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1259     if (!coreSubframe->page())
1260         return 0;
1261
1262     m_frame->coreFrame()->loader().loadURLIntoChildFrame(url, referrer, coreSubframe);
1263
1264     // The frame's onload handler may have removed it from the document.
1265     if (!subframe->coreFrame())
1266         return 0;
1267     ASSERT(subframe->coreFrame() == coreSubframe);
1268     if (!coreSubframe->tree().parent())
1269         return 0;
1270
1271     return coreSubframe;
1272 }
1273
1274 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const URL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1275 {
1276     ASSERT(paramNames.size() == paramValues.size());
1277     ASSERT(m_frame->page());
1278
1279     Plugin::Parameters parameters;
1280     parameters.url = url;
1281     parameters.names = paramNames;
1282     parameters.values = paramValues;
1283     parameters.mimeType = mimeType;
1284     parameters.isFullFramePlugin = loadManually;
1285     parameters.shouldUseManualLoader = parameters.isFullFramePlugin && !m_frameCameFromPageCache;
1286 #if PLATFORM(MAC)
1287     parameters.layerHostingMode = m_frame->page()->layerHostingMode();
1288 #endif
1289
1290 #if PLUGIN_ARCHITECTURE(X11)
1291     // FIXME: This should really be X11-specific plug-in quirks.
1292     if (equalIgnoringCase(mimeType, "application/x-shockwave-flash")) {
1293         // Currently we don't support transparency and windowed mode.
1294         // Inject wmode=opaque to make Flash work in these conditions.
1295         size_t wmodeIndex = parameters.names.find("wmode");
1296         if (wmodeIndex == notFound) {
1297             parameters.names.append("wmode");
1298             parameters.values.append("opaque");
1299         } else if (equalIgnoringCase(parameters.values[wmodeIndex], "window"))
1300             parameters.values[wmodeIndex] = "opaque";
1301     } else if (equalIgnoringCase(mimeType, "application/x-webkit-test-netscape")) {
1302         parameters.names.append("windowedPlugin");
1303         parameters.values.append("false");
1304     }
1305 #endif
1306
1307 #if ENABLE(NETSCAPE_PLUGIN_API)
1308     RefPtr<Plugin> plugin = m_frame->page()->createPlugin(m_frame, pluginElement, parameters, parameters.mimeType);
1309     if (!plugin)
1310         return 0;
1311
1312     return PluginView::create(pluginElement, plugin.release(), parameters);
1313 #else
1314     UNUSED_PARAM(pluginElement);
1315     return 0;
1316 #endif
1317 }
1318
1319 void WebFrameLoaderClient::recreatePlugin(Widget* widget)
1320 {
1321 #if ENABLE(NETSCAPE_PLUGIN_API)
1322     ASSERT(widget && widget->isPluginViewBase());
1323     ASSERT(m_frame->page());
1324
1325     PluginView* pluginView = static_cast<PluginView*>(widget);
1326     String newMIMEType;
1327     RefPtr<Plugin> plugin = m_frame->page()->createPlugin(m_frame, pluginView->pluginElement(), pluginView->initialParameters(), newMIMEType);
1328     pluginView->recreateAndInitialize(plugin.release());
1329 #else
1330     UNUSED_PARAM(widget);
1331 #endif
1332 }
1333
1334 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1335 {
1336     if (pluginWidget)
1337         m_pluginView = static_cast<PluginView*>(pluginWidget);
1338 }
1339
1340 #if ENABLE(WEBGL)
1341 WebCore::WebGLLoadPolicy WebFrameLoaderClient::webGLPolicyForURL(const String& url) const
1342 {
1343     if (WebPage* webPage = m_frame->page())
1344         return webPage->webGLPolicyForURL(m_frame, url);
1345
1346     return WebGLAllow;
1347 }
1348 #endif // ENABLE(WEBGL)
1349
1350 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const URL&, const Vector<String>& paramNames, const Vector<String>& paramValues)
1351 {
1352 #if ENABLE(NETSCAPE_PLUGIN_API)
1353     RefPtr<Widget> plugin = createPlugin(pluginSize, appletElement, URL(), paramNames, paramValues, appletElement->serviceType(), false);
1354     if (!plugin) {
1355         if (WebPage* webPage = m_frame->page()) {
1356             String frameURLString = m_frame->coreFrame()->loader().documentLoader()->responseURL().string();
1357             String pageURLString = webPage->corePage()->mainFrame().loader().documentLoader()->responseURL().string();
1358             webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(appletElement->serviceType(), frameURLString, pageURLString));
1359         }
1360     }
1361     return plugin.release();
1362 #else
1363     UNUSED_PARAM(pluginSize);
1364     UNUSED_PARAM(appletElement);
1365     UNUSED_PARAM(paramNames);
1366     UNUSED_PARAM(paramValues);
1367     return 0;
1368 #endif
1369 }
1370
1371 #if ENABLE(PLUGIN_PROXY_FOR_VIDEO)
1372 PassRefPtr<Widget> WebFrameLoaderClient::createMediaPlayerProxyPlugin(const IntSize&, HTMLMediaElement*, const URL&, const Vector<String>&, const Vector<String>&, const String&)
1373 {
1374     notImplemented();
1375     return 0;
1376 }
1377
1378 void WebFrameLoaderClient::hideMediaPlayerProxyPlugin(Widget*)
1379 {
1380     notImplemented();
1381 }
1382
1383 void WebFrameLoaderClient::showMediaPlayerProxyPlugin(Widget*)
1384 {
1385     notImplemented();
1386 }
1387 #endif
1388
1389 static bool pluginSupportsExtension(const PluginData& pluginData, const String& extension)
1390 {
1391     ASSERT(extension.lower() == extension);
1392
1393     for (size_t i = 0; i < pluginData.mimes().size(); ++i) {
1394         const MimeClassInfo& mimeClassInfo = pluginData.mimes()[i];
1395
1396         if (mimeClassInfo.extensions.contains(extension))
1397             return true;
1398     }
1399     return false;
1400 }
1401
1402 ObjectContentType WebFrameLoaderClient::objectContentType(const URL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
1403 {
1404     // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
1405     // is consolidated.
1406
1407     String mimeType = mimeTypeIn;
1408     if (mimeType.isEmpty()) {
1409         String extension = url.path().substring(url.path().reverseFind('.') + 1).lower();
1410
1411         // Try to guess the MIME type from the extension.
1412         mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1413
1414         if (mimeType.isEmpty()) {
1415             // Check if there's a plug-in around that can handle the extension.
1416             if (WebPage* webPage = m_frame->page()) {
1417                 if (pluginSupportsExtension(webPage->corePage()->pluginData(), extension))
1418                     return ObjectContentNetscapePlugin;
1419             }
1420         }
1421     }
1422
1423     if (mimeType.isEmpty())
1424         return ObjectContentFrame;
1425
1426     bool plugInSupportsMIMEType = false;
1427     if (WebPage* webPage = m_frame->page()) {
1428         const PluginData& pluginData = webPage->corePage()->pluginData();
1429         if (pluginData.supportsMimeType(mimeType, PluginData::AllPlugins) && webFrame()->coreFrame()->loader().subframeLoader().allowPlugins(NotAboutToInstantiatePlugin))
1430             plugInSupportsMIMEType = true;
1431         else if (pluginData.supportsMimeType(mimeType, PluginData::OnlyApplicationPlugins))
1432             plugInSupportsMIMEType = true;
1433     }
1434     
1435     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1436         return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage;
1437
1438     if (plugInSupportsMIMEType)
1439         return ObjectContentNetscapePlugin;
1440
1441     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1442         return ObjectContentFrame;
1443
1444     return ObjectContentNone;
1445 }
1446
1447 String WebFrameLoaderClient::overrideMediaType() const
1448 {
1449     notImplemented();
1450     return String();
1451 }
1452
1453 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
1454 {
1455     WebPage* webPage = m_frame->page();
1456     if (!webPage)
1457         return;
1458
1459     webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1460
1461 #if HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
1462     // Ensure the accessibility hierarchy is updated.
1463     webPage->updateAccessibilityTree();
1464 #endif
1465 }
1466
1467
1468 void WebFrameLoaderClient::dispatchGlobalObjectAvailable(DOMWrapperWorld& world)
1469 {
1470     WebPage* webPage = m_frame->page();
1471     if (!webPage)
1472         return;
1473     
1474     webPage->injectedBundleLoaderClient().globalObjectIsAvailableForFrame(webPage, m_frame, world);
1475 }
1476
1477 void WebFrameLoaderClient::dispatchWillDisconnectDOMWindowExtensionFromGlobalObject(WebCore::DOMWindowExtension* extension)
1478 {
1479     WebPage* webPage = m_frame->page();
1480     if (!webPage)
1481         return;
1482         
1483     webPage->injectedBundleLoaderClient().willDisconnectDOMWindowExtensionFromGlobalObject(webPage, extension);
1484 }
1485
1486 void WebFrameLoaderClient::dispatchDidReconnectDOMWindowExtensionToGlobalObject(WebCore::DOMWindowExtension* extension)
1487 {
1488     WebPage* webPage = m_frame->page();
1489     if (!webPage)
1490         return;
1491         
1492     webPage->injectedBundleLoaderClient().didReconnectDOMWindowExtensionToGlobalObject(webPage, extension);
1493 }
1494
1495 void WebFrameLoaderClient::dispatchWillDestroyGlobalObjectForDOMWindowExtension(WebCore::DOMWindowExtension* extension)
1496 {
1497     WebPage* webPage = m_frame->page();
1498     if (!webPage)
1499         return;
1500         
1501     webPage->injectedBundleLoaderClient().willDestroyGlobalObjectForDOMWindowExtension(webPage, extension);
1502 }
1503
1504 void WebFrameLoaderClient::registerForIconNotification(bool /*listen*/)
1505 {
1506     notImplemented();
1507 }
1508
1509 #if PLATFORM(MAC)
1510     
1511 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject() 
1512 {
1513     WebPage* webPage = m_frame->page();
1514     if (!webPage)
1515         return 0;
1516     
1517     return webPage->accessibilityRemoteObject();
1518 }
1519     
1520 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1521 {
1522     WebPage* webPage = m_frame->page();
1523     if (!webPage)
1524         return response;
1525
1526     return webPage->injectedBundleResourceLoadClient().shouldCacheResponse(webPage, m_frame, identifier) ? response : nil;
1527 }
1528
1529 #endif // PLATFORM(MAC)
1530
1531 bool WebFrameLoaderClient::shouldAlwaysUsePluginDocument(const String& /*mimeType*/) const
1532 {
1533     notImplemented();
1534     return false;
1535 }
1536
1537 void WebFrameLoaderClient::didChangeScrollOffset()
1538 {
1539     WebPage* webPage = m_frame->page();
1540     if (!webPage)
1541         return;
1542
1543     webPage->drawingArea()->didChangeScrollOffsetForAnyFrame();
1544
1545     if (!m_frame->isMainFrame())
1546         return;
1547
1548     // If this is called when tearing down a FrameView, the WebCore::Frame's
1549     // current FrameView will be null.
1550     if (!m_frame->coreFrame()->view())
1551         return;
1552
1553     webPage->updateMainFrameScrollOffsetPinning();
1554 }
1555
1556 bool WebFrameLoaderClient::allowScript(bool enabledPerSettings)
1557 {
1558     if (!enabledPerSettings)
1559         return false;
1560
1561     Frame* coreFrame = m_frame->coreFrame();
1562
1563     if (coreFrame->document()->isPluginDocument()) {
1564         PluginDocument* pluginDocument = static_cast<PluginDocument*>(coreFrame->document());
1565
1566         if (pluginDocument->pluginWidget() && pluginDocument->pluginWidget()->isPluginView()) {
1567             PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
1568
1569             if (!pluginView->shouldAllowScripting())
1570                 return false;
1571         }
1572     }
1573
1574     return true;
1575 }
1576
1577 bool WebFrameLoaderClient::shouldForceUniversalAccessFromLocalURL(const WebCore::URL& url)
1578 {
1579     WebPage* webPage = m_frame->page();
1580     if (!webPage)
1581         return false;
1582
1583     return webPage->injectedBundleLoaderClient().shouldForceUniversalAccessFromLocalURL(webPage, url.string());
1584 }
1585
1586 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1587 {
1588     RefPtr<WebFrameNetworkingContext> context = WebFrameNetworkingContext::create(m_frame);
1589     return context.release();
1590 }
1591
1592 } // namespace WebKit