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