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