2 * Copyright (C) 2010, 2011, 2012 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
27 #include "WebFrameLoaderClient.h"
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"
39 #include "WKBundleAPICast.h"
40 #include "WebBackForwardListProxy.h"
41 #include "WebCoreArgumentCoders.h"
42 #include "WebDocumentLoader.h"
43 #include "WebErrors.h"
46 #include "WebFrameNetworkingContext.h"
47 #include "WebFullScreenManager.h"
48 #include "WebIconDatabaseMessages.h"
49 #include "WebNavigationDataStore.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/SecurityOriginData.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>
87 using namespace WebCore;
91 WebFrameLoaderClient::WebFrameLoaderClient()
93 , m_hasSentResponseToPluginView(false)
94 , m_didCompletePageTransition(false)
95 , m_frameHasCustomContentProvider(false)
96 , m_frameCameFromPageCache(false)
100 WebFrameLoaderClient::~WebFrameLoaderClient()
104 void WebFrameLoaderClient::frameLoaderDestroyed()
106 m_frame->invalidate();
108 // Balances explicit ref() in WebFrame::create().
112 bool WebFrameLoaderClient::hasHTMLView() const
114 return !m_frameHasCustomContentProvider;
117 bool WebFrameLoaderClient::hasWebView() const
119 return m_frame->page();
122 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
127 void WebFrameLoaderClient::forceLayoutForNonHTML()
132 void WebFrameLoaderClient::setCopiesOnScroll()
137 void WebFrameLoaderClient::detachedFromParent2()
139 WebPage* webPage = m_frame->page();
143 RefPtr<API::Object> userData;
145 // Notify the bundle client.
146 webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
149 void WebFrameLoaderClient::detachedFromParent3()
154 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
156 WebPage* webPage = m_frame->page();
160 bool pageIsProvisionallyLoading = false;
161 if (FrameLoader* frameLoader = loader->frameLoader())
162 pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader;
164 webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading);
165 webPage->addResourceRequest(identifier, request);
168 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
170 WebPage* webPage = m_frame->page();
174 webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse);
177 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
179 WebPage* webPage = m_frame->page();
183 return webPage->injectedBundleResourceLoadClient().shouldUseCredentialStorage(webPage, m_frame, identifier);
186 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
188 // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
189 // Once we do, we might need to make sure authentication fits with our solution.
191 WebPage* webPage = m_frame->page();
195 WebProcess::singleton().supplement<AuthenticationManager>()->didReceiveAuthenticationChallenge(m_frame, challenge);
198 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long /*identifier*/, const AuthenticationChallenge&)
203 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
204 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
206 // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
207 // Once we do, we might need to make sure authentication fits with our solution.
209 WebPage* webPage = m_frame->page();
213 bool canAuthenticate;
214 if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate)))
217 return canAuthenticate;
221 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
223 WebPage* webPage = m_frame->page();
227 webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response);
230 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength)
232 WebPage* webPage = m_frame->page();
236 webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength);
239 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
241 WebPage* webPage = m_frame->page();
245 webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier);
246 webPage->removeResourceRequest(identifier);
249 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
251 WebPage* webPage = m_frame->page();
255 webPage->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error);
256 webPage->removeResourceRequest(identifier);
259 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
265 void WebFrameLoaderClient::dispatchDidDispatchOnloadEvents()
267 WebPage* webPage = m_frame->page();
271 // Notify the bundle client.
272 webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame);
275 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
277 WebPage* webPage = m_frame->page();
281 WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
282 const String& url = documentLoader.url().string();
283 RefPtr<API::Object> userData;
285 // Notify the bundle client.
286 webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData);
288 // Notify the UIProcess.
289 webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), url, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
292 void WebFrameLoaderClient::dispatchDidChangeProvisionalURL()
294 WebPage* webPage = m_frame->page();
298 WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
299 webPage->send(Messages::WebPageProxy::DidChangeProvisionalURLForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.url().string()));
302 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
304 WebPage* webPage = m_frame->page();
308 // Notify the bundle client.
309 webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame);
312 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const URL& url, double interval, double fireDate)
314 WebPage* webPage = m_frame->page();
318 // Notify the bundle client.
319 webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate);
322 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
324 WebPage* webPage = m_frame->page();
328 RefPtr<API::Object> userData;
330 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
332 // Notify the bundle client.
333 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData);
335 // Notify the UIProcess.
336 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
339 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
341 WebPage* webPage = m_frame->page();
345 RefPtr<API::Object> userData;
347 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
349 // Notify the bundle client.
350 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData);
352 // Notify the UIProcess.
353 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
356 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
358 WebPage* webPage = m_frame->page();
362 RefPtr<API::Object> userData;
364 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
366 // Notify the bundle client.
367 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData);
369 // Notify the UIProcess.
370 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
373 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
375 WebPage* webPage = m_frame->page();
379 RefPtr<API::Object> userData;
381 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
383 // Notify the bundle client.
384 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData);
386 // Notify the UIProcess.
387 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
390 void WebFrameLoaderClient::dispatchWillClose()
395 void WebFrameLoaderClient::dispatchDidReceiveIcon()
397 WebProcess::singleton().parentProcessConnection()->send(Messages::WebIconDatabase::DidReceiveIconForPageURL(m_frame->url()), 0);
400 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
402 WebPage* webPage = m_frame->page();
406 #if ENABLE(FULLSCREEN_API)
407 Element* documentElement = m_frame->coreFrame()->document()->documentElement();
408 if (documentElement && documentElement->containsFullScreenElement())
409 webPage->fullScreenManager()->exitFullScreenForElement(webPage->fullScreenManager()->element());
412 webPage->findController().hideFindUI();
413 webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);
415 WebDocumentLoader& provisionalLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
416 const String& url = provisionalLoader.url().string();
417 RefPtr<API::Object> userData;
419 // Notify the bundle client.
420 webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);
422 String unreachableURL = provisionalLoader.unreachableURL().string();
424 // Notify the UIProcess.
425 webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), provisionalLoader.navigationID(), url, unreachableURL, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
428 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
430 WebPage* webPage = m_frame->page();
434 RefPtr<API::Object> userData;
436 // Notify the bundle client.
437 // FIXME: use direction of title.
438 webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData);
440 // Notify the UIProcess.
441 webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
444 void WebFrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType)
449 void WebFrameLoaderClient::dispatchDidCommitLoad()
451 WebPage* webPage = m_frame->page();
455 WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader());
456 RefPtr<API::Object> userData;
458 // Notify the bundle client.
459 webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData);
461 webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
463 // Notify the UIProcess.
465 webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.response().mimeType(), m_frameHasCustomContentProvider, m_frame->handlesPageScaleGesture(), static_cast<uint32_t>(m_frame->coreFrame()->loader().loadType()), documentLoader.response().certificateInfo(), m_frame->coreFrame()->document()->isPluginDocument(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
466 webPage->didCommitLoad(m_frame);
469 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
471 WebPage* webPage = m_frame->page();
475 RefPtr<API::Object> userData;
477 // Notify the bundle client.
478 webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData);
480 webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame);
482 // FIXME: This is gross. This is necessary because if the client calls WKBundlePageStopLoading() from within the didFailProvisionalLoadWithErrorForFrame
483 // injected bundle client call, that will cause the provisional DocumentLoader to be disconnected from the Frame, and didDistroyNavigation message
484 // to be sent to the UIProcess (and the destruction of the DocumentLoader). If that happens, and we had captured the navigationID before injected bundle
485 // client call, the DidFailProvisionalLoadForFrame would send a navigationID of a destroyed Navigation, and the UIProcess would not be able to find it
488 // A better solution to this problem would be find a clean way to postpone the disconnection of the DocumentLoader from the Frame until
489 // the entire FrameLoaderClient function was complete.
490 uint64_t navigationID = 0;
491 if (auto documentLoader = m_frame->coreFrame()->loader().provisionalDocumentLoader())
492 navigationID = static_cast<WebDocumentLoader*>(documentLoader)->navigationID();
494 // Notify the UIProcess.
495 WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr;
496 webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationID, m_frame->coreFrame()->loader().provisionalLoadErrorBeingHandledURL(), error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
498 // If we have a load listener, notify it.
499 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
500 loadListener->didFailLoad(m_frame, error.isCancellation());
503 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
505 WebPage* webPage = m_frame->page();
509 RefPtr<API::Object> userData;
511 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
513 // Notify the bundle client.
514 webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData);
516 // Notify the UIProcess.
517 webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), navigationID, error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
519 // If we have a load listener, notify it.
520 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
521 loadListener->didFailLoad(m_frame, error.isCancellation());
524 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
526 WebPage* webPage = m_frame->page();
530 RefPtr<API::Object> userData;
532 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
534 // Notify the bundle client.
535 webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData);
537 // Notify the UIProcess.
538 webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
541 void WebFrameLoaderClient::dispatchDidFinishLoad()
543 WebPage* webPage = m_frame->page();
547 RefPtr<API::Object> userData;
549 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
551 // Notify the bundle client.
552 webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData);
554 // Notify the UIProcess.
555 webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
557 // If we have a load listener, notify it.
558 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
559 loadListener->didFinishLoad(m_frame);
561 webPage->didFinishLoad(m_frame);
564 void WebFrameLoaderClient::forcePageTransitionIfNeeded()
566 if (m_didCompletePageTransition)
569 WebPage* webPage = m_frame->page();
573 webPage->didCompletePageTransition();
574 m_didCompletePageTransition = true;
577 void WebFrameLoaderClient::dispatchDidLayout(LayoutMilestones milestones)
579 WebPage* webPage = m_frame->page();
583 RefPtr<API::Object> userData;
585 if (milestones & DidFirstLayout) {
586 // FIXME: We should consider removing the old didFirstLayout API since this is doing double duty with the
587 // new didLayout API.
588 webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
589 webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
592 // FIXME: Do this on DidFirstVisuallyNonEmptyLayout when Mac Safari is able to handle it (<rdar://problem/17580021>)
593 if (m_frame->isMainFrame() && !m_didCompletePageTransition && !webPage->corePage()->settings().suppressesIncrementalRendering()) {
594 webPage->didCompletePageTransition();
595 m_didCompletePageTransition = true;
599 #if USE(COORDINATED_GRAPHICS)
600 // Make sure viewport properties are dispatched on the main frame by the time the first layout happens.
601 ASSERT(!webPage->useFixedLayout() || m_frame != m_frame->page()->mainWebFrame() || m_frame->coreFrame()->document()->didDispatchViewportPropertiesChanged());
605 // Send this after DidFirstLayout-specific calls since some clients expect to get those messages first.
606 webPage->dispatchDidLayout(milestones);
608 if (milestones & DidFirstVisuallyNonEmptyLayout) {
609 if (m_frame->isMainFrame() && !m_didCompletePageTransition && !webPage->corePage()->settings().suppressesIncrementalRendering()) {
610 webPage->didCompletePageTransition();
611 m_didCompletePageTransition = true;
614 // FIXME: We should consider removing the old didFirstVisuallyNonEmptyLayoutForFrame API since this is doing
615 // double duty with the new didLayout API.
616 webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
617 webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
621 void WebFrameLoaderClient::dispatchDidLayout()
623 WebPage* webPage = m_frame->page();
627 // Notify the bundle client.
628 webPage->injectedBundleLoaderClient().didLayoutForFrame(webPage, m_frame);
630 webPage->recomputeShortCircuitHorizontalWheelEventsState();
633 webPage->updateSelectionAppearance();
636 // NOTE: Unlike the other layout notifications, this does not notify the
637 // the UIProcess for every call.
639 if (m_frame == m_frame->page()->mainWebFrame()) {
640 // FIXME: Remove at the soonest possible time.
641 webPage->send(Messages::WebPageProxy::SetRenderTreeSize(webPage->renderTreeSize()));
642 webPage->mainFrameDidLayout();
646 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
648 WebPage* webPage = m_frame->page();
652 // Just call through to the chrome client.
653 FrameLoadRequest request(m_frame->coreFrame()->document()->securityOrigin(), navigationAction.resourceRequest(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, navigationAction.shouldOpenExternalURLsPolicy());
654 Page* newPage = webPage->corePage()->chrome().createWindow(m_frame->coreFrame(), request, WindowFeatures(), navigationAction);
658 return &newPage->mainFrame();
661 void WebFrameLoaderClient::dispatchShow()
663 WebPage* webPage = m_frame->page();
670 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, FramePolicyFunction function)
672 WebPage* webPage = m_frame->page();
674 function(PolicyIgnore);
678 if (!request.url().string()) {
683 RefPtr<API::Object> userData;
685 // Notify the bundle client.
686 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData);
687 if (policy == WKBundlePagePolicyActionUse) {
692 bool canShowMIMEType = webPage->canShowMIMEType(response.mimeType());
694 uint64_t listenerID = m_frame->setUpPolicyListener(WTF::move(function));
695 bool receivedPolicyAction;
696 uint64_t policyAction;
697 DownloadID downloadID;
699 unsigned syncSendFlags = IPC::InformPlatformProcessWillSuspend;
700 if (WebPage::synchronousMessagesShouldSpinRunLoop())
701 syncSendFlags |= IPC::SpinRunLoopWhileWaitingForReply;
703 WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr;
704 if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponseSync(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), response, request, canShowMIMEType, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForResponseSync::Reply(receivedPolicyAction, policyAction, downloadID), std::chrono::milliseconds::max(), syncSendFlags)) {
705 m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
709 // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
710 if (receivedPolicyAction)
711 m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), 0, downloadID);
714 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, FramePolicyFunction function)
716 WebPage* webPage = m_frame->page();
718 function(PolicyIgnore);
722 RefPtr<API::Object> userData;
724 RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
726 // Notify the bundle client.
727 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData);
728 if (policy == WKBundlePagePolicyActionUse) {
734 uint64_t listenerID = m_frame->setUpPolicyListener(WTF::move(function));
736 NavigationActionData navigationActionData;
737 navigationActionData.navigationType = action->navigationType();
738 navigationActionData.modifiers = action->modifiers();
739 navigationActionData.mouseButton = action->mouseButton();
740 navigationActionData.isProcessingUserGesture = navigationAction.processingUserGesture();
741 navigationActionData.canHandleRequest = webPage->canHandleRequest(request);
742 navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
744 WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr;
745 webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationActionData, request, frameName, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
748 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> prpFormState, FramePolicyFunction function)
750 WebPage* webPage = m_frame->page();
752 function(PolicyIgnore);
756 // Always ignore requests with empty URLs.
757 if (request.isEmpty()) {
758 function(PolicyIgnore);
762 RefPtr<API::Object> userData;
763 RefPtr<FormState> formState = prpFormState;
765 RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
767 // Notify the bundle client.
768 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
769 if (policy == WKBundlePagePolicyActionUse) {
774 uint64_t listenerID = m_frame->setUpPolicyListener(WTF::move(function));
775 bool receivedPolicyAction;
776 uint64_t newNavigationID;
777 uint64_t policyAction;
778 DownloadID downloadID;
780 RefPtr<WebFrame> originatingFrame;
781 switch (action->navigationType()) {
782 case NavigationType::LinkClicked:
783 if (EventTarget* target = navigationAction.event()->target()) {
784 if (Node* node = target->toNode()) {
785 if (Frame* frame = node->document().frame())
786 originatingFrame = WebFrame::fromCoreFrame(*frame);
790 case NavigationType::FormSubmitted:
791 case NavigationType::FormResubmitted:
793 originatingFrame = WebFrame::fromCoreFrame(*formState->sourceDocument()->frame());
795 case NavigationType::BackForward:
796 case NavigationType::Reload:
797 case NavigationType::Other:
801 NavigationActionData navigationActionData;
802 navigationActionData.navigationType = action->navigationType();
803 navigationActionData.modifiers = action->modifiers();
804 navigationActionData.mouseButton = action->mouseButton();
805 navigationActionData.isProcessingUserGesture = navigationAction.processingUserGesture();
806 navigationActionData.canHandleRequest = webPage->canHandleRequest(request);
807 navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
809 WebCore::Frame* coreFrame = m_frame->coreFrame();
810 WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().policyDocumentLoader());
812 documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
814 // Notify the UIProcess.
815 WebCore::Frame* originatingCoreFrame = originatingFrame ? originatingFrame->coreFrame() : nullptr;
816 if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), documentLoader->navigationID(), navigationActionData, originatingFrame ? originatingFrame->frameID() : 0, SecurityOriginData::fromFrame(originatingCoreFrame), navigationAction.resourceRequest(), request, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, newNavigationID, policyAction, downloadID))) {
817 m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
821 // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
822 if (receivedPolicyAction)
823 m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), newNavigationID, downloadID);
826 void WebFrameLoaderClient::cancelPolicyCheck()
828 m_frame->invalidatePolicyListener();
831 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
833 WebPage* webPage = m_frame->page();
837 RefPtr<API::Object> userData;
839 // Notify the bundle client.
840 webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData);
842 // Notify the UIProcess.
843 webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
846 void WebFrameLoaderClient::dispatchWillSendSubmitEvent(PassRefPtr<FormState> prpFormState)
848 WebPage* webPage = m_frame->page();
852 RefPtr<FormState> formState = prpFormState;
853 HTMLFormElement* form = formState->form();
855 WebFrame* sourceFrame = WebFrame::fromCoreFrame(*formState->sourceDocument()->frame());
858 webPage->injectedBundleFormClient().willSendSubmitEvent(webPage, form, m_frame, sourceFrame, formState->textFieldValues());
861 void WebFrameLoaderClient::dispatchWillSubmitForm(PassRefPtr<FormState> prpFormState, FramePolicyFunction function)
863 WebPage* webPage = m_frame->page();
867 // FIXME: Pass more of the form state.
868 RefPtr<FormState> formState = prpFormState;
870 HTMLFormElement* form = formState->form();
872 WebFrame* sourceFrame = WebFrame::fromCoreFrame(*formState->sourceDocument()->frame());
875 const Vector<std::pair<String, String>>& values = formState->textFieldValues();
877 RefPtr<API::Object> userData;
878 webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData);
881 uint64_t listenerID = m_frame->setUpPolicyListener(WTF::move(function));
883 webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), values, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
886 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
891 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
896 m_pluginView->manualLoadDidFail(error);
897 m_pluginView = nullptr;
898 m_hasSentResponseToPluginView = false;
901 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
906 void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& /* suggestedName */)
908 m_frame->startDownload(request);
911 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
916 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
921 void WebFrameLoaderClient::willReplaceMultipartContent()
923 WebPage* webPage = m_frame->page();
926 webPage->willReplaceMultipartContent(*m_frame);
929 void WebFrameLoaderClient::didReplaceMultipartContent()
931 WebPage* webPage = m_frame->page();
934 webPage->didReplaceMultipartContent(*m_frame);
937 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
940 loader->commitData(data, length);
942 // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
943 // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
944 if (m_frame->coreFrame()->document()->isMediaDocument())
945 loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
947 // Calling commitData did not create the plug-in view.
951 if (!m_hasSentResponseToPluginView) {
952 m_pluginView->manualLoadDidReceiveResponse(loader->response());
953 // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
954 // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
958 m_hasSentResponseToPluginView = true;
960 m_pluginView->manualLoadDidReceiveData(data, length);
963 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
966 if (m_frameHasCustomContentProvider) {
967 WebPage* webPage = m_frame->page();
971 RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData();
972 IPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0);
973 webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomContentProvider(loader->response().suggestedFilename(), dataReference));
979 // If we just received an empty response without any data, we won't have sent a response to the plug-in view.
980 // Make sure to do this before calling manualLoadDidFinishLoading.
981 if (!m_hasSentResponseToPluginView) {
982 m_pluginView->manualLoadDidReceiveResponse(loader->response());
984 // Protect against the above call nulling out the plug-in (by trying to cancel the load for example).
989 m_pluginView->manualLoadDidFinishLoading();
990 m_pluginView = nullptr;
991 m_hasSentResponseToPluginView = false;
994 void WebFrameLoaderClient::updateGlobalHistory()
996 WebPage* webPage = m_frame->page();
997 if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1000 DocumentLoader* loader = m_frame->coreFrame()->loader().documentLoader();
1002 WebNavigationDataStore data;
1003 data.url = loader->url().string();
1004 // FIXME: use direction of title.
1005 data.title = loader->title().string();
1006 data.originalRequest = loader->originalRequestCopy();
1007 data.response = loader->response();
1009 webPage->send(Messages::WebPageProxy::DidNavigateWithNavigationData(data, m_frame->frameID()));
1012 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
1014 WebPage* webPage = m_frame->page();
1015 if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1018 DocumentLoader* loader = m_frame->coreFrame()->loader().documentLoader();
1019 ASSERT(loader->unreachableURL().isEmpty());
1022 if (!loader->clientRedirectSourceForHistory().isNull()) {
1023 webPage->send(Messages::WebPageProxy::DidPerformClientRedirect(
1024 loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()));
1028 if (!loader->serverRedirectSourceForHistory().isNull()) {
1029 webPage->send(Messages::WebPageProxy::DidPerformServerRedirect(
1030 loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()));
1034 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
1036 WebPage* webPage = m_frame->page();
1040 uint64_t itemID = WebBackForwardListProxy::idForItem(item);
1042 // We should never be considering navigating to an item that is not actually in the back/forward list.
1043 ASSERT_NOT_REACHED();
1047 RefPtr<InjectedBundleBackForwardListItem> bundleItem = InjectedBundleBackForwardListItem::create(item);
1048 RefPtr<API::Object> userData;
1050 // Ask the bundle client first
1051 bool shouldGoToBackForwardListItem = webPage->injectedBundleLoaderClient().shouldGoToBackForwardListItem(webPage, bundleItem.get(), userData);
1052 if (!shouldGoToBackForwardListItem)
1055 webPage->send(Messages::WebPageProxy::WillGoToBackForwardListItem(itemID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1059 void WebFrameLoaderClient::didDisplayInsecureContent()
1061 WebPage* webPage = m_frame->page();
1065 RefPtr<API::Object> userData;
1067 webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData);
1069 webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1072 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const URL&)
1074 WebPage* webPage = m_frame->page();
1078 RefPtr<API::Object> userData;
1080 webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData);
1082 webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1085 void WebFrameLoaderClient::didDetectXSS(const URL&, bool)
1087 WebPage* webPage = m_frame->page();
1091 RefPtr<API::Object> userData;
1093 webPage->injectedBundleLoaderClient().didDetectXSSForFrame(webPage, m_frame, userData);
1095 webPage->send(Messages::WebPageProxy::DidDetectXSSForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
1098 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
1100 return WebKit::cancelledError(request);
1103 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
1105 return WebKit::blockedError(request);
1108 ResourceError WebFrameLoaderClient::blockedByContentBlockerError(const ResourceRequest& request)
1110 return WebKit::blockedByContentBlockerError(request);
1113 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
1115 return WebKit::cannotShowURLError(request);
1118 ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request)
1120 return WebKit::interruptedForPolicyChangeError(request);
1123 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
1125 return WebKit::cannotShowMIMETypeError(response);
1128 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
1130 return WebKit::fileDoesNotExistError(response);
1133 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
1135 return WebKit::pluginWillHandleLoadError(response);
1138 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1140 static NeverDestroyed<const ResourceError> cancelledError(this->cancelledError(ResourceRequest()));
1141 static NeverDestroyed<const ResourceError> pluginWillHandleLoadError(this->pluginWillHandleLoadError(ResourceResponse()));
1143 if (error.errorCode() == cancelledError.get().errorCode() && error.domain() == cancelledError.get().domain())
1146 if (error.errorCode() == pluginWillHandleLoadError.get().errorCode() && error.domain() == pluginWillHandleLoadError.get().domain())
1152 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
1158 bool WebFrameLoaderClient::canShowMIMEType(const String& /*MIMEType*/) const
1164 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const
1169 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& /*URLScheme*/) const
1175 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1181 void WebFrameLoaderClient::frameLoadCompleted()
1183 // Note: Can be called multiple times.
1184 WebPage* webPage = m_frame->page();
1188 if (m_frame->isMainFrame() && !m_didCompletePageTransition) {
1189 webPage->didCompletePageTransition();
1190 m_didCompletePageTransition = true;
1194 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem* historyItem)
1196 #if PLATFORM(IOS) || PLATFORM(EFL)
1197 if (m_frame->isMainFrame())
1198 m_frame->page()->savePageState(*historyItem);
1200 UNUSED_PARAM(historyItem);
1204 void WebFrameLoaderClient::restoreViewState()
1206 #if PLATFORM(IOS) || PLATFORM(EFL)
1207 Frame& frame = *m_frame->coreFrame();
1208 HistoryItem* currentItem = frame.loader().history().currentItem();
1209 if (FrameView* view = frame.view()) {
1210 if (m_frame->isMainFrame())
1211 m_frame->page()->restorePageState(*currentItem);
1212 else if (!view->wasScrolledByUser())
1213 view->setScrollPosition(currentItem->scrollPoint());
1216 // Inform the UI process of the scale factor.
1217 double scaleFactor = m_frame->coreFrame()->loader().history().currentItem()->pageScaleFactor();
1219 // A scale factor of 0 means the history item has the default scale factor, thus we do not need to update it.
1221 m_frame->page()->send(Messages::WebPageProxy::PageScaleFactorDidChange(scaleFactor));
1223 // FIXME: This should not be necessary. WebCore should be correctly invalidating
1224 // the view on restores from the back/forward cache.
1225 if (m_frame->page() && m_frame == m_frame->page()->mainWebFrame())
1226 m_frame->page()->drawingArea()->setNeedsDisplay();
1230 void WebFrameLoaderClient::provisionalLoadStarted()
1232 WebPage* webPage = m_frame->page();
1236 if (m_frame->isMainFrame()) {
1237 webPage->didStartPageTransition();
1238 m_didCompletePageTransition = false;
1242 void WebFrameLoaderClient::didFinishLoad()
1244 // If we have a load listener, notify it.
1245 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
1246 loadListener->didFinishLoad(m_frame);
1249 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1254 Ref<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1256 return m_frame->page()->createDocumentLoader(*m_frame->coreFrame(), request, substituteData);
1259 void WebFrameLoaderClient::updateCachedDocumentLoader(WebCore::DocumentLoader& loader)
1261 m_frame->page()->updateCachedDocumentLoader(static_cast<WebDocumentLoader&>(loader), *m_frame->coreFrame());
1264 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const URL& url)
1266 WebPage* webPage = m_frame->page();
1267 if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1270 // FIXME: use direction of title.
1271 webPage->send(Messages::WebPageProxy::DidUpdateHistoryTitle(title.string(), url.string(), m_frame->frameID()));
1274 String WebFrameLoaderClient::userAgent(const URL& url)
1276 WebPage* webPage = m_frame->page();
1280 return webPage->userAgent(m_frame, url);
1283 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
1287 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
1289 const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response();
1290 m_frameHasCustomContentProvider = m_frame->isMainFrame() && m_frame->page()->shouldUseCustomContentProviderForResponse(response);
1291 m_frameCameFromPageCache = true;
1294 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1296 WebPage* webPage = m_frame->page();
1298 Color backgroundColor = webPage->drawsBackground() ? Color::white : Color::transparent;
1299 bool isMainFrame = m_frame->isMainFrame();
1300 bool isTransparent = !webPage->drawsBackground();
1301 bool shouldUseFixedLayout = isMainFrame && webPage->useFixedLayout();
1302 bool shouldDisableScrolling = isMainFrame && !webPage->mainFrameIsScrollable();
1303 bool shouldHideScrollbars = shouldDisableScrolling;
1304 IntRect fixedVisibleContentRect;
1306 #if USE(COORDINATED_GRAPHICS)
1307 if (m_frame->coreFrame()->view())
1308 fixedVisibleContentRect = m_frame->coreFrame()->view()->fixedVisibleContentRect();
1309 if (shouldUseFixedLayout)
1310 shouldHideScrollbars = true;
1313 const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response();
1314 m_frameHasCustomContentProvider = isMainFrame && webPage->shouldUseCustomContentProviderForResponse(response);
1315 m_frameCameFromPageCache = false;
1317 ScrollbarMode defaultScrollbarMode = shouldHideScrollbars ? ScrollbarAlwaysOff : ScrollbarAuto;
1319 m_frame->coreFrame()->createView(webPage->size(), backgroundColor, isTransparent,
1320 webPage->fixedLayoutSize(), fixedVisibleContentRect, shouldUseFixedLayout,
1321 defaultScrollbarMode, /* lock */ shouldHideScrollbars, defaultScrollbarMode, /* lock */ shouldHideScrollbars);
1323 if (int minimumLayoutWidth = webPage->minimumLayoutSize().width()) {
1324 int minimumLayoutHeight = std::max(webPage->minimumLayoutSize().height(), 1);
1325 int maximumSize = std::numeric_limits<int>::max();
1326 m_frame->coreFrame()->view()->enableAutoSizeMode(true, IntSize(minimumLayoutWidth, minimumLayoutHeight), IntSize(maximumSize, maximumSize));
1328 if (webPage->autoSizingShouldExpandToViewHeight())
1329 m_frame->coreFrame()->view()->setAutoSizeFixedMinimumHeight(webPage->size().height());
1332 m_frame->coreFrame()->view()->setProhibitsScrolling(shouldDisableScrolling);
1333 m_frame->coreFrame()->view()->setVisualUpdatesAllowedByClient(!webPage->shouldExtendIncrementalRenderingSuppression());
1335 m_frame->coreFrame()->view()->setExposedRect(webPage->drawingArea()->exposedRect());
1338 m_frame->coreFrame()->view()->setDelegatesScrolling(true);
1341 if (webPage->scrollPinningBehavior() != DoNotPin)
1342 m_frame->coreFrame()->view()->setScrollPinningBehavior(webPage->scrollPinningBehavior());
1344 #if USE(COORDINATED_GRAPHICS)
1345 if (shouldUseFixedLayout) {
1346 m_frame->coreFrame()->view()->setDelegatesScrolling(shouldUseFixedLayout);
1347 m_frame->coreFrame()->view()->setPaintsEntireContents(shouldUseFixedLayout);
1353 void WebFrameLoaderClient::didSaveToPageCache()
1355 WebPage* webPage = m_frame->page();
1359 webPage->send(Messages::WebPageProxy::DidSaveToPageCache());
1362 void WebFrameLoaderClient::didRestoreFromPageCache()
1364 m_frameCameFromPageCache = true;
1367 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
1369 WebPage* webPage = m_frame->page();
1373 webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
1376 bool WebFrameLoaderClient::canCachePage() const
1378 // We cannot cache frames that have custom representations because they are
1379 // rendered in the UIProcess.
1380 return !m_frameHasCustomContentProvider;
1383 void WebFrameLoaderClient::convertMainResourceLoadToDownload(DocumentLoader *documentLoader, SessionID sessionID, const ResourceRequest& request, const ResourceResponse& response)
1385 m_frame->convertMainResourceLoadToDownload(documentLoader, sessionID, request, response);
1388 RefPtr<Frame> WebFrameLoaderClient::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1389 const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
1391 WebPage* webPage = m_frame->page();
1393 RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement);
1395 Frame* coreSubframe = subframe->coreFrame();
1399 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1400 if (!coreSubframe->page())
1403 m_frame->coreFrame()->loader().loadURLIntoChildFrame(url, referrer, coreSubframe);
1405 // The frame's onload handler may have removed it from the document.
1406 if (!subframe->coreFrame())
1408 ASSERT(subframe->coreFrame() == coreSubframe);
1409 if (!coreSubframe->tree().parent())
1412 return coreSubframe;
1415 RefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const URL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1417 ASSERT(paramNames.size() == paramValues.size());
1418 ASSERT(m_frame->page());
1420 Plugin::Parameters parameters;
1421 parameters.url = url;
1422 parameters.names = paramNames;
1423 parameters.values = paramValues;
1424 parameters.mimeType = mimeType;
1425 parameters.isFullFramePlugin = loadManually;
1426 parameters.shouldUseManualLoader = parameters.isFullFramePlugin && !m_frameCameFromPageCache;
1428 parameters.layerHostingMode = m_frame->page()->layerHostingMode();
1431 #if ENABLE(NETSCAPE_PLUGIN_API)
1432 RefPtr<Plugin> plugin = m_frame->page()->createPlugin(m_frame, pluginElement, parameters, parameters.mimeType);
1436 return PluginView::create(pluginElement, plugin.release(), parameters);
1438 UNUSED_PARAM(pluginElement);
1443 void WebFrameLoaderClient::recreatePlugin(Widget* widget)
1445 #if ENABLE(NETSCAPE_PLUGIN_API)
1446 ASSERT(widget && widget->isPluginViewBase());
1447 ASSERT(m_frame->page());
1449 PluginView* pluginView = static_cast<PluginView*>(widget);
1451 RefPtr<Plugin> plugin = m_frame->page()->createPlugin(m_frame, pluginView->pluginElement(), pluginView->initialParameters(), newMIMEType);
1452 pluginView->recreateAndInitialize(plugin.release());
1454 UNUSED_PARAM(widget);
1458 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1461 m_pluginView = static_cast<PluginView*>(pluginWidget);
1465 WebCore::WebGLLoadPolicy WebFrameLoaderClient::webGLPolicyForURL(const String& url) const
1467 if (WebPage* webPage = m_frame->page())
1468 return webPage->webGLPolicyForURL(m_frame, url);
1470 return WebGLAllowCreation;
1473 WebCore::WebGLLoadPolicy WebFrameLoaderClient::resolveWebGLPolicyForURL(const String& url) const
1475 if (WebPage* webPage = m_frame->page())
1476 return webPage->resolveWebGLPolicyForURL(m_frame, url);
1478 return WebGLAllowCreation;
1480 #endif // ENABLE(WEBGL)
1482 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const URL&, const Vector<String>& paramNames, const Vector<String>& paramValues)
1484 #if ENABLE(NETSCAPE_PLUGIN_API)
1485 RefPtr<Widget> plugin = createPlugin(pluginSize, appletElement, URL(), paramNames, paramValues, appletElement->serviceType(), false);
1487 if (WebPage* webPage = m_frame->page()) {
1488 String frameURLString = m_frame->coreFrame()->loader().documentLoader()->responseURL().string();
1489 String pageURLString = webPage->corePage()->mainFrame().loader().documentLoader()->responseURL().string();
1490 webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(appletElement->serviceType(), frameURLString, pageURLString));
1493 return plugin.release();
1495 UNUSED_PARAM(pluginSize);
1496 UNUSED_PARAM(appletElement);
1497 UNUSED_PARAM(paramNames);
1498 UNUSED_PARAM(paramValues);
1503 static bool pluginSupportsExtension(const PluginData& pluginData, const String& extension)
1505 ASSERT(extension.lower() == extension);
1507 Vector<MimeClassInfo> mimes;
1508 Vector<size_t> mimePluginIndices;
1509 pluginData.getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
1510 for (size_t i = 0; i < mimes.size(); ++i) {
1511 const MimeClassInfo& mimeClassInfo = mimes[i];
1513 if (mimeClassInfo.extensions.contains(extension))
1519 ObjectContentType WebFrameLoaderClient::objectContentType(const URL& url, const String& mimeTypeIn)
1521 // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
1524 String mimeType = mimeTypeIn;
1525 if (mimeType.isEmpty()) {
1526 String extension = url.path().substring(url.path().reverseFind('.') + 1).lower();
1528 // Try to guess the MIME type from the extension.
1529 mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1531 if (mimeType.isEmpty()) {
1532 // Check if there's a plug-in around that can handle the extension.
1533 if (WebPage* webPage = m_frame->page()) {
1534 if (pluginSupportsExtension(webPage->corePage()->pluginData(), extension))
1535 return ObjectContentNetscapePlugin;
1540 if (mimeType.isEmpty())
1541 return ObjectContentFrame;
1543 bool plugInSupportsMIMEType = false;
1544 if (WebPage* webPage = m_frame->page()) {
1545 const PluginData& pluginData = webPage->corePage()->pluginData();
1546 if (pluginData.supportsMimeType(mimeType, PluginData::AllPlugins) && webFrame()->coreFrame()->loader().subframeLoader().allowPlugins())
1547 plugInSupportsMIMEType = true;
1548 else if (pluginData.supportsMimeType(mimeType, PluginData::OnlyApplicationPlugins))
1549 plugInSupportsMIMEType = true;
1552 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1553 return ObjectContentImage;
1555 if (plugInSupportsMIMEType)
1556 return ObjectContentNetscapePlugin;
1558 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1559 return ObjectContentFrame;
1562 // iOS can render PDF in <object>/<embed> via PDFDocumentImage.
1563 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType))
1564 return ObjectContentImage;
1567 return ObjectContentNone;
1570 String WebFrameLoaderClient::overrideMediaType() const
1576 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
1578 WebPage* webPage = m_frame->page();
1582 webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1584 #if HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
1585 // Ensure the accessibility hierarchy is updated.
1586 webPage->updateAccessibilityTree();
1591 void WebFrameLoaderClient::dispatchGlobalObjectAvailable(DOMWrapperWorld& world)
1593 WebPage* webPage = m_frame->page();
1597 webPage->injectedBundleLoaderClient().globalObjectIsAvailableForFrame(webPage, m_frame, world);
1600 void WebFrameLoaderClient::dispatchWillDisconnectDOMWindowExtensionFromGlobalObject(WebCore::DOMWindowExtension* extension)
1602 WebPage* webPage = m_frame->page();
1606 webPage->injectedBundleLoaderClient().willDisconnectDOMWindowExtensionFromGlobalObject(webPage, extension);
1609 void WebFrameLoaderClient::dispatchDidReconnectDOMWindowExtensionToGlobalObject(WebCore::DOMWindowExtension* extension)
1611 WebPage* webPage = m_frame->page();
1615 webPage->injectedBundleLoaderClient().didReconnectDOMWindowExtensionToGlobalObject(webPage, extension);
1618 void WebFrameLoaderClient::dispatchWillDestroyGlobalObjectForDOMWindowExtension(WebCore::DOMWindowExtension* extension)
1620 WebPage* webPage = m_frame->page();
1624 webPage->injectedBundleLoaderClient().willDestroyGlobalObjectForDOMWindowExtension(webPage, extension);
1627 void WebFrameLoaderClient::registerForIconNotification(bool /*listen*/)
1634 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject()
1636 WebPage* webPage = m_frame->page();
1640 return webPage->accessibilityRemoteObject();
1643 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1645 WebPage* webPage = m_frame->page();
1649 return webPage->injectedBundleResourceLoadClient().shouldCacheResponse(webPage, m_frame, identifier) ? response : nil;
1652 #endif // PLATFORM(COCOA)
1654 bool WebFrameLoaderClient::shouldAlwaysUsePluginDocument(const String& /*mimeType*/) const
1660 void WebFrameLoaderClient::didChangeScrollOffset()
1662 WebPage* webPage = m_frame->page();
1666 webPage->didChangeScrollOffsetForFrame(m_frame->coreFrame());
1669 bool WebFrameLoaderClient::allowScript(bool enabledPerSettings)
1671 if (!enabledPerSettings)
1674 Frame* coreFrame = m_frame->coreFrame();
1676 if (coreFrame->document()->isPluginDocument()) {
1677 PluginDocument* pluginDocument = static_cast<PluginDocument*>(coreFrame->document());
1679 if (pluginDocument->pluginWidget() && pluginDocument->pluginWidget()->isPluginView()) {
1680 PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
1682 if (!pluginView->shouldAllowScripting())
1690 bool WebFrameLoaderClient::shouldForceUniversalAccessFromLocalURL(const WebCore::URL& url)
1692 WebPage* webPage = m_frame->page();
1696 return webPage->injectedBundleLoaderClient().shouldForceUniversalAccessFromLocalURL(webPage, url.string());
1699 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1701 RefPtr<WebFrameNetworkingContext> context = WebFrameNetworkingContext::create(m_frame);
1702 return context.release();
1705 #if ENABLE(CONTENT_FILTERING)
1706 void WebFrameLoaderClient::contentFilterDidBlockLoad(WebCore::ContentFilterUnblockHandler unblockHandler)
1708 if (!unblockHandler.needsUIProcess()) {
1709 m_frame->coreFrame()->loader().policyChecker().setContentFilterUnblockHandler(WTF::move(unblockHandler));
1713 if (WebPage* webPage { m_frame->page() })
1714 webPage->send(Messages::WebPageProxy::ContentFilterDidBlockLoadForFrame(unblockHandler, m_frame->frameID()));
1718 #if ENABLE(REQUEST_AUTOCOMPLETE)
1719 void WebFrameLoaderClient::didRequestAutocomplete(PassRefPtr<WebCore::FormState>)
1724 void WebFrameLoaderClient::prefetchDNS(const String& hostname)
1726 WebProcess::singleton().prefetchDNS(hostname);
1729 void WebFrameLoaderClient::didRestoreScrollPosition()
1731 WebPage* webPage = m_frame->page();
1735 webPage->didRestoreScrollPosition();
1738 } // namespace WebKit