2 * Copyright (C) 2010-2016 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 "WebAutomationSessionProxy.h"
41 #include "WebBackForwardListProxy.h"
42 #include "WebCoreArgumentCoders.h"
43 #include "WebDocumentLoader.h"
44 #include "WebErrors.h"
47 #include "WebFrameNetworkingContext.h"
48 #include "WebFullScreenManager.h"
49 #include "WebIconDatabaseMessages.h"
50 #include "WebNavigationDataStore.h"
52 #include "WebPageGroupProxy.h"
53 #include "WebPageProxyMessages.h"
54 #include "WebProcess.h"
55 #include "WebProcessPoolMessages.h"
56 #include "WebsitePolicies.h"
57 #include <JavaScriptCore/APICast.h>
58 #include <JavaScriptCore/JSObject.h>
59 #include <WebCore/CachedFrame.h>
60 #include <WebCore/CertificateInfo.h>
61 #include <WebCore/Chrome.h>
62 #include <WebCore/DOMWrapperWorld.h>
63 #include <WebCore/DocumentLoader.h>
64 #include <WebCore/FormState.h>
65 #include <WebCore/FrameLoadRequest.h>
66 #include <WebCore/FrameLoader.h>
67 #include <WebCore/FrameView.h>
68 #include <WebCore/HTMLAppletElement.h>
69 #include <WebCore/HTMLFormElement.h>
70 #include <WebCore/HistoryController.h>
71 #include <WebCore/HistoryItem.h>
72 #include <WebCore/MIMETypeRegistry.h>
73 #include <WebCore/MainFrame.h>
74 #include <WebCore/MouseEvent.h>
75 #include <WebCore/NotImplemented.h>
76 #include <WebCore/Page.h>
77 #include <WebCore/PluginData.h>
78 #include <WebCore/PluginDocument.h>
79 #include <WebCore/ProgressTracker.h>
80 #include <WebCore/ResourceError.h>
81 #include <WebCore/ScriptController.h>
82 #include <WebCore/SecurityOriginData.h>
83 #include <WebCore/Settings.h>
84 #include <WebCore/SubframeLoader.h>
85 #include <WebCore/UIEventWithKeyState.h>
86 #include <WebCore/Widget.h>
87 #include <WebCore/WindowFeatures.h>
88 #include <wtf/NeverDestroyed.h>
90 using namespace WebCore;
94 WebFrameLoaderClient::WebFrameLoaderClient()
96 , m_hasSentResponseToPluginView(false)
97 , m_didCompletePageTransition(false)
98 , m_frameHasCustomContentProvider(false)
99 , m_frameCameFromPageCache(false)
103 WebFrameLoaderClient::~WebFrameLoaderClient()
107 void WebFrameLoaderClient::frameLoaderDestroyed()
109 m_frame->invalidate();
111 // Balances explicit ref() in WebFrame::create().
115 bool WebFrameLoaderClient::hasHTMLView() const
117 return !m_frameHasCustomContentProvider;
120 bool WebFrameLoaderClient::hasWebView() const
122 return m_frame->page();
125 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
130 void WebFrameLoaderClient::forceLayoutForNonHTML()
135 void WebFrameLoaderClient::setCopiesOnScroll()
140 void WebFrameLoaderClient::detachedFromParent2()
142 WebPage* webPage = m_frame->page();
146 RefPtr<API::Object> userData;
148 // Notify the bundle client.
149 webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
152 void WebFrameLoaderClient::detachedFromParent3()
157 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
159 WebPage* webPage = m_frame->page();
163 bool pageIsProvisionallyLoading = false;
164 if (FrameLoader* frameLoader = loader->frameLoader())
165 pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader;
167 webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading);
168 webPage->addResourceRequest(identifier, request);
171 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
173 WebPage* webPage = m_frame->page();
177 webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse);
180 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
182 WebPage* webPage = m_frame->page();
186 return webPage->injectedBundleResourceLoadClient().shouldUseCredentialStorage(webPage, m_frame, identifier);
189 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
191 // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
192 // Once we do, we might need to make sure authentication fits with our solution.
194 WebPage* webPage = m_frame->page();
198 WebProcess::singleton().supplement<AuthenticationManager>()->didReceiveAuthenticationChallenge(m_frame, challenge);
201 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
202 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
204 // The WebKit 2 Networking process asks the UIProcess directly, so the WebContent process should never receive this callback.
205 ASSERT_NOT_REACHED();
210 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
212 WebPage* webPage = m_frame->page();
216 webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response);
219 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength)
221 WebPage* webPage = m_frame->page();
225 webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength);
228 #if ENABLE(DATA_DETECTION)
229 void WebFrameLoaderClient::dispatchDidFinishDataDetection(NSArray *detectionResults)
231 WebPage* webPage = m_frame->page();
234 webPage->setDataDetectionResults(detectionResults);
238 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
240 WebPage* webPage = m_frame->page();
244 webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier);
245 webPage->removeResourceRequest(identifier);
248 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
250 WebPage* webPage = m_frame->page();
254 webPage->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error);
255 webPage->removeResourceRequest(identifier);
258 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/)
264 void WebFrameLoaderClient::dispatchDidDispatchOnloadEvents()
266 WebPage* webPage = m_frame->page();
270 // Notify the bundle client.
271 webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame);
274 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
276 WebPage* webPage = m_frame->page();
280 WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
281 const String& url = documentLoader.url().string();
282 RefPtr<API::Object> userData;
284 // Notify the bundle client.
285 webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData);
287 // Notify the UIProcess.
288 webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), url, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
291 void WebFrameLoaderClient::dispatchDidChangeProvisionalURL()
293 WebPage* webPage = m_frame->page();
297 WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
298 webPage->send(Messages::WebPageProxy::DidChangeProvisionalURLForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.url().string()));
301 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
303 WebPage* webPage = m_frame->page();
307 // Notify the bundle client.
308 webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame);
311 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const URL& url, double interval, double fireDate)
313 WebPage* webPage = m_frame->page();
317 // Notify the bundle client.
318 webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate);
321 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
323 WebPage* webPage = m_frame->page();
327 RefPtr<API::Object> userData;
329 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
331 // Notify the bundle client.
332 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData);
334 // Notify the UIProcess.
335 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
338 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
340 WebPage* webPage = m_frame->page();
344 RefPtr<API::Object> userData;
346 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
348 // Notify the bundle client.
349 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData);
351 // Notify the UIProcess.
352 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
355 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
357 WebPage* webPage = m_frame->page();
361 RefPtr<API::Object> userData;
363 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
365 // Notify the bundle client.
366 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData);
368 // Notify the UIProcess.
369 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
372 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
374 WebPage* webPage = m_frame->page();
378 RefPtr<API::Object> userData;
380 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
382 // Notify the bundle client.
383 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData);
385 // Notify the UIProcess.
386 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url().string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
389 void WebFrameLoaderClient::dispatchWillClose()
394 void WebFrameLoaderClient::dispatchDidReceiveIcon()
396 WebProcess::singleton().parentProcessConnection()->send(Messages::WebIconDatabase::DidReceiveIconForPageURL(m_frame->url()), 0);
399 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
401 WebPage* webPage = m_frame->page();
405 #if ENABLE(FULLSCREEN_API)
406 Element* documentElement = m_frame->coreFrame()->document()->documentElement();
407 if (documentElement && documentElement->containsFullScreenElement())
408 webPage->fullScreenManager()->exitFullScreenForElement(webPage->fullScreenManager()->element());
411 webPage->findController().hideFindUI();
412 webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);
414 WebDocumentLoader& provisionalLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader());
415 const String& url = provisionalLoader.url().string();
416 RefPtr<API::Object> userData;
418 // Notify the bundle client.
419 webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);
421 String unreachableURL = provisionalLoader.unreachableURL().string();
423 // Notify the UIProcess.
424 webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), provisionalLoader.navigationID(), url, unreachableURL, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
427 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
429 WebPage* webPage = m_frame->page();
433 RefPtr<API::Object> userData;
435 // Notify the bundle client.
436 // FIXME: use direction of title.
437 webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData);
439 // Notify the UIProcess.
440 webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
443 void WebFrameLoaderClient::dispatchDidCommitLoad(std::optional<HasInsecureContent> hasInsecureContent)
445 WebPage* webPage = m_frame->page();
449 WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader());
450 RefPtr<API::Object> userData;
452 // Notify the bundle client.
453 webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData);
455 webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
457 // Notify the UIProcess.
458 webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.response().mimeType(), m_frameHasCustomContentProvider, static_cast<uint32_t>(m_frame->coreFrame()->loader().loadType()), valueOrCompute(documentLoader.response().certificateInfo(), [] { return CertificateInfo(); }), m_frame->coreFrame()->document()->isPluginDocument(), hasInsecureContent, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
459 webPage->didCommitLoad(m_frame);
462 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
464 WebPage* webPage = m_frame->page();
468 RefPtr<API::Object> userData;
470 // Notify the bundle client.
471 webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData);
473 webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame);
475 // FIXME: This is gross. This is necessary because if the client calls WKBundlePageStopLoading() from within the didFailProvisionalLoadWithErrorForFrame
476 // injected bundle client call, that will cause the provisional DocumentLoader to be disconnected from the Frame, and didDistroyNavigation message
477 // to be sent to the UIProcess (and the destruction of the DocumentLoader). If that happens, and we had captured the navigationID before injected bundle
478 // client call, the DidFailProvisionalLoadForFrame would send a navigationID of a destroyed Navigation, and the UIProcess would not be able to find it
481 // A better solution to this problem would be find a clean way to postpone the disconnection of the DocumentLoader from the Frame until
482 // the entire FrameLoaderClient function was complete.
483 uint64_t navigationID = 0;
484 if (auto documentLoader = m_frame->coreFrame()->loader().provisionalDocumentLoader())
485 navigationID = static_cast<WebDocumentLoader*>(documentLoader)->navigationID();
487 // Notify the UIProcess.
488 WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr;
489 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())));
491 // If we have a load listener, notify it.
492 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
493 loadListener->didFailLoad(m_frame, error.isCancellation());
496 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
498 WebPage* webPage = m_frame->page();
502 RefPtr<API::Object> userData;
504 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
506 // Notify the bundle client.
507 webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData);
509 // Notify the UIProcess.
510 webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), navigationID, error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
512 // If we have a load listener, notify it.
513 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
514 loadListener->didFailLoad(m_frame, error.isCancellation());
517 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
519 WebPage* webPage = m_frame->page();
523 RefPtr<API::Object> userData;
525 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
527 // Notify the bundle client.
528 webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData);
530 // Notify the UIProcess.
531 webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
534 void WebFrameLoaderClient::dispatchDidFinishLoad()
536 WebPage* webPage = m_frame->page();
540 RefPtr<API::Object> userData;
542 auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID();
544 // Notify the bundle client.
545 webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData);
547 // Notify the UIProcess.
548 webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
550 // If we have a load listener, notify it.
551 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
552 loadListener->didFinishLoad(m_frame);
554 webPage->didFinishLoad(m_frame);
557 void WebFrameLoaderClient::forcePageTransitionIfNeeded()
559 if (m_didCompletePageTransition)
562 WebPage* webPage = m_frame->page();
566 webPage->didCompletePageTransition();
567 m_didCompletePageTransition = true;
570 void WebFrameLoaderClient::dispatchDidReachLayoutMilestone(LayoutMilestones milestones)
572 WebPage* webPage = m_frame->page();
576 RefPtr<API::Object> userData;
578 if (milestones & DidFirstLayout) {
579 // FIXME: We should consider removing the old didFirstLayout API since this is doing double duty with the
580 // new didLayout API.
581 webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
582 webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
585 // FIXME: Do this on DidFirstVisuallyNonEmptyLayout when Mac Safari is able to handle it (<rdar://problem/17580021>)
586 if (m_frame->isMainFrame() && !m_didCompletePageTransition && !webPage->corePage()->settings().suppressesIncrementalRendering()) {
587 webPage->didCompletePageTransition();
588 m_didCompletePageTransition = true;
592 #if USE(COORDINATED_GRAPHICS)
593 // Make sure viewport properties are dispatched on the main frame by the time the first layout happens.
594 ASSERT(!webPage->useFixedLayout() || m_frame != m_frame->page()->mainWebFrame() || m_frame->coreFrame()->document()->didDispatchViewportPropertiesChanged());
598 // Send this after DidFirstLayout-specific calls since some clients expect to get those messages first.
599 webPage->dispatchDidReachLayoutMilestone(milestones);
601 if (milestones & DidFirstVisuallyNonEmptyLayout) {
602 if (m_frame->isMainFrame() && !m_didCompletePageTransition && !webPage->corePage()->settings().suppressesIncrementalRendering()) {
603 webPage->didCompletePageTransition();
604 m_didCompletePageTransition = true;
607 // FIXME: We should consider removing the old didFirstVisuallyNonEmptyLayoutForFrame API since this is doing
608 // double duty with the new didLayout API.
609 webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
610 webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
614 void WebFrameLoaderClient::dispatchDidLayout()
616 WebPage* webPage = m_frame->page();
620 // Notify the bundle client.
621 webPage->injectedBundleLoaderClient().didLayoutForFrame(webPage, m_frame);
623 webPage->recomputeShortCircuitHorizontalWheelEventsState();
626 webPage->updateSelectionAppearance();
629 // NOTE: Unlike the other layout notifications, this does not notify the
630 // the UIProcess for every call.
632 if (m_frame == m_frame->page()->mainWebFrame()) {
633 // FIXME: Remove at the soonest possible time.
634 webPage->send(Messages::WebPageProxy::SetRenderTreeSize(webPage->renderTreeSize()));
635 webPage->mainFrameDidLayout();
639 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
641 WebPage* webPage = m_frame->page();
645 // Just call through to the chrome client.
646 FrameLoadRequest request(m_frame->coreFrame()->document()->securityOrigin(), navigationAction.resourceRequest(), LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, navigationAction.shouldOpenExternalURLsPolicy());
647 Page* newPage = webPage->corePage()->chrome().createWindow(m_frame->coreFrame(), request, WindowFeatures(), navigationAction);
651 return &newPage->mainFrame();
654 void WebFrameLoaderClient::dispatchShow()
656 WebPage* webPage = m_frame->page();
663 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, FramePolicyFunction function)
665 WebPage* webPage = m_frame->page();
667 function(PolicyIgnore);
671 if (!request.url().string()) {
676 RefPtr<API::Object> userData;
678 // Notify the bundle client.
679 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData);
680 if (policy == WKBundlePagePolicyActionUse) {
685 bool canShowMIMEType = webPage->canShowMIMEType(response.mimeType());
687 uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
688 bool receivedPolicyAction;
689 uint64_t policyAction;
690 DownloadID downloadID;
692 Ref<WebFrame> protect(*m_frame);
693 WebCore::Frame* coreFrame = m_frame->coreFrame();
694 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), Seconds::infinity(), IPC::SendSyncOption::InformPlatformProcessWillSuspend)) {
695 m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
699 // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
700 if (receivedPolicyAction)
701 m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), 0, downloadID);
704 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName, FramePolicyFunction function)
706 WebPage* webPage = m_frame->page();
708 function(PolicyIgnore);
712 RefPtr<API::Object> userData;
714 RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
716 // Notify the bundle client.
717 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData);
718 if (policy == WKBundlePagePolicyActionUse) {
724 uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
726 NavigationActionData navigationActionData;
727 navigationActionData.navigationType = action->navigationType();
728 navigationActionData.modifiers = action->modifiers();
729 navigationActionData.mouseButton = action->mouseButton();
730 navigationActionData.syntheticClickType = action->syntheticClickType();
731 navigationActionData.userGestureTokenIdentifier = WebProcess::singleton().userGestureTokenIdentifier(navigationAction.userGestureToken());
732 navigationActionData.canHandleRequest = webPage->canHandleRequest(request);
733 navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
734 navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
736 WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr;
737 webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationActionData, request, frameName, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())));
740 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> prpFormState, FramePolicyFunction function)
742 WebPage* webPage = m_frame->page();
744 function(PolicyIgnore);
748 // Always ignore requests with empty URLs.
749 if (request.isEmpty()) {
750 function(PolicyIgnore);
754 RefPtr<API::Object> userData;
755 RefPtr<FormState> formState = prpFormState;
757 RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
759 // Notify the bundle client.
760 WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
761 if (policy == WKBundlePagePolicyActionUse) {
766 uint64_t listenerID = m_frame->setUpPolicyListener(WTFMove(function));
767 bool receivedPolicyAction;
768 uint64_t newNavigationID;
769 uint64_t policyAction;
770 DownloadID downloadID;
772 RefPtr<WebFrame> originatingFrame;
773 switch (action->navigationType()) {
774 case NavigationType::LinkClicked:
775 if (EventTarget* target = navigationAction.event()->target()) {
776 if (Node* node = target->toNode()) {
777 if (Frame* frame = node->document().frame())
778 originatingFrame = WebFrame::fromCoreFrame(*frame);
782 case NavigationType::FormSubmitted:
783 case NavigationType::FormResubmitted:
785 originatingFrame = WebFrame::fromCoreFrame(*formState->sourceDocument()->frame());
787 case NavigationType::BackForward:
788 case NavigationType::Reload:
789 case NavigationType::Other:
793 NavigationActionData navigationActionData;
794 navigationActionData.navigationType = action->navigationType();
795 navigationActionData.modifiers = action->modifiers();
796 navigationActionData.mouseButton = action->mouseButton();
797 navigationActionData.syntheticClickType = action->syntheticClickType();
798 navigationActionData.userGestureTokenIdentifier = WebProcess::singleton().userGestureTokenIdentifier(navigationAction.userGestureToken());
799 navigationActionData.canHandleRequest = webPage->canHandleRequest(request);
800 navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy();
801 navigationActionData.downloadAttribute = navigationAction.downloadAttribute();
803 WebCore::Frame* coreFrame = m_frame->coreFrame();
804 WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().policyDocumentLoader());
806 documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader());
808 // Notify the UIProcess.
809 Ref<WebFrame> protect(*m_frame);
810 WebCore::Frame* originatingCoreFrame = originatingFrame ? originatingFrame->coreFrame() : nullptr;
811 WebsitePolicies websitePolicies;
812 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, websitePolicies))) {
813 m_frame->didReceivePolicyDecision(listenerID, PolicyIgnore, 0, { });
817 // Only setUserContentExtensionsEnabled if it hasn't already been disabled by reloading without content blockers.
818 if (documentLoader->userContentExtensionsEnabled())
819 documentLoader->setUserContentExtensionsEnabled(websitePolicies.contentBlockersEnabled);
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(WTFMove(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, suggestedName);
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 #if ENABLE(CONTENT_FILTERING)
1124 ResourceError WebFrameLoaderClient::blockedByContentFilterError(const ResourceRequest& request)
1126 return WebKit::blockedByContentFilterError(request);
1130 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
1132 return WebKit::cannotShowMIMETypeError(response);
1135 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
1137 return WebKit::fileDoesNotExistError(response);
1140 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
1142 return WebKit::pluginWillHandleLoadError(response);
1145 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
1147 static NeverDestroyed<const ResourceError> cancelledError(this->cancelledError(ResourceRequest()));
1148 static NeverDestroyed<const ResourceError> pluginWillHandleLoadError(this->pluginWillHandleLoadError(ResourceResponse()));
1150 if (error.errorCode() == cancelledError.get().errorCode() && error.domain() == cancelledError.get().domain())
1153 if (error.errorCode() == pluginWillHandleLoadError.get().errorCode() && error.domain() == pluginWillHandleLoadError.get().domain())
1159 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
1165 bool WebFrameLoaderClient::canShowMIMEType(const String& /*MIMEType*/) const
1171 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const
1176 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& /*URLScheme*/) const
1182 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const
1188 void WebFrameLoaderClient::frameLoadCompleted()
1190 // Note: Can be called multiple times.
1191 WebPage* webPage = m_frame->page();
1195 if (m_frame->isMainFrame() && !m_didCompletePageTransition) {
1196 webPage->didCompletePageTransition();
1197 m_didCompletePageTransition = true;
1201 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem& historyItem)
1203 #if PLATFORM(IOS) || PLATFORM(EFL)
1204 if (m_frame->isMainFrame())
1205 m_frame->page()->savePageState(historyItem);
1207 UNUSED_PARAM(historyItem);
1211 void WebFrameLoaderClient::restoreViewState()
1213 #if PLATFORM(IOS) || PLATFORM(EFL)
1214 Frame& frame = *m_frame->coreFrame();
1215 HistoryItem* currentItem = frame.loader().history().currentItem();
1216 if (FrameView* view = frame.view()) {
1217 if (m_frame->isMainFrame())
1218 m_frame->page()->restorePageState(*currentItem);
1219 else if (!view->wasScrolledByUser())
1220 view->setScrollPosition(currentItem->scrollPosition());
1223 // Inform the UI process of the scale factor.
1224 double scaleFactor = m_frame->coreFrame()->loader().history().currentItem()->pageScaleFactor();
1226 // A scale factor of 0 means the history item has the default scale factor, thus we do not need to update it.
1228 m_frame->page()->send(Messages::WebPageProxy::PageScaleFactorDidChange(scaleFactor));
1230 // FIXME: This should not be necessary. WebCore should be correctly invalidating
1231 // the view on restores from the back/forward cache.
1232 if (m_frame->page() && m_frame == m_frame->page()->mainWebFrame())
1233 m_frame->page()->drawingArea()->setNeedsDisplay();
1237 void WebFrameLoaderClient::provisionalLoadStarted()
1239 WebPage* webPage = m_frame->page();
1243 if (m_frame->isMainFrame()) {
1244 webPage->didStartPageTransition();
1245 m_didCompletePageTransition = false;
1249 void WebFrameLoaderClient::didFinishLoad()
1251 // If we have a load listener, notify it.
1252 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
1253 loadListener->didFinishLoad(m_frame);
1256 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1261 Ref<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
1263 return m_frame->page()->createDocumentLoader(*m_frame->coreFrame(), request, substituteData);
1266 void WebFrameLoaderClient::updateCachedDocumentLoader(WebCore::DocumentLoader& loader)
1268 m_frame->page()->updateCachedDocumentLoader(static_cast<WebDocumentLoader&>(loader), *m_frame->coreFrame());
1271 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const URL& url)
1273 WebPage* webPage = m_frame->page();
1274 if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1277 // FIXME: use direction of title.
1278 webPage->send(Messages::WebPageProxy::DidUpdateHistoryTitle(title.string(), url.string(), m_frame->frameID()));
1281 String WebFrameLoaderClient::userAgent(const URL& url)
1283 WebPage* webPage = m_frame->page();
1287 return webPage->userAgent(m_frame, url);
1290 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
1292 WebPage* webPage = m_frame->page();
1296 HasInsecureContent hasInsecureContent;
1297 if (webPage->sendSync(Messages::WebPageProxy::HasInsecureContent(), Messages::WebPageProxy::HasInsecureContent::Reply(hasInsecureContent)))
1298 cachedFrame->setHasInsecureContent(hasInsecureContent);
1301 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
1303 const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response();
1304 m_frameHasCustomContentProvider = m_frame->isMainFrame() && m_frame->page()->shouldUseCustomContentProviderForResponse(response);
1305 m_frameCameFromPageCache = true;
1308 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1310 WebPage* webPage = m_frame->page();
1312 Color backgroundColor = webPage->drawsBackground() ? Color::white : Color::transparent;
1313 bool isMainFrame = m_frame->isMainFrame();
1314 bool isTransparent = !webPage->drawsBackground();
1315 bool shouldUseFixedLayout = isMainFrame && webPage->useFixedLayout();
1316 bool shouldDisableScrolling = isMainFrame && !webPage->mainFrameIsScrollable();
1317 bool shouldHideScrollbars = shouldDisableScrolling;
1318 IntRect fixedVisibleContentRect;
1320 #if USE(COORDINATED_GRAPHICS)
1321 if (m_frame->coreFrame()->view())
1322 fixedVisibleContentRect = m_frame->coreFrame()->view()->fixedVisibleContentRect();
1323 if (shouldUseFixedLayout)
1324 shouldHideScrollbars = true;
1327 const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response();
1328 m_frameHasCustomContentProvider = isMainFrame && webPage->shouldUseCustomContentProviderForResponse(response);
1329 m_frameCameFromPageCache = false;
1331 ScrollbarMode defaultScrollbarMode = shouldHideScrollbars ? ScrollbarAlwaysOff : ScrollbarAuto;
1333 m_frame->coreFrame()->createView(webPage->size(), backgroundColor, isTransparent,
1334 webPage->fixedLayoutSize(), fixedVisibleContentRect, shouldUseFixedLayout,
1335 defaultScrollbarMode, /* lock */ shouldHideScrollbars, defaultScrollbarMode, /* lock */ shouldHideScrollbars);
1337 if (int minimumLayoutWidth = webPage->minimumLayoutSize().width()) {
1338 int minimumLayoutHeight = std::max(webPage->minimumLayoutSize().height(), 1);
1339 int maximumSize = std::numeric_limits<int>::max();
1340 m_frame->coreFrame()->view()->enableAutoSizeMode(true, IntSize(minimumLayoutWidth, minimumLayoutHeight), IntSize(maximumSize, maximumSize));
1342 if (webPage->autoSizingShouldExpandToViewHeight())
1343 m_frame->coreFrame()->view()->setAutoSizeFixedMinimumHeight(webPage->size().height());
1346 m_frame->coreFrame()->view()->setProhibitsScrolling(shouldDisableScrolling);
1347 m_frame->coreFrame()->view()->setVisualUpdatesAllowedByClient(!webPage->shouldExtendIncrementalRenderingSuppression());
1349 m_frame->coreFrame()->view()->setViewExposedRect(webPage->drawingArea()->viewExposedRect());
1352 m_frame->coreFrame()->view()->setDelegatesScrolling(true);
1355 if (webPage->scrollPinningBehavior() != DoNotPin)
1356 m_frame->coreFrame()->view()->setScrollPinningBehavior(webPage->scrollPinningBehavior());
1358 #if USE(COORDINATED_GRAPHICS)
1359 if (shouldUseFixedLayout) {
1360 m_frame->coreFrame()->view()->setDelegatesScrolling(shouldUseFixedLayout);
1361 m_frame->coreFrame()->view()->setPaintsEntireContents(shouldUseFixedLayout);
1367 void WebFrameLoaderClient::didSaveToPageCache()
1369 WebPage* webPage = m_frame->page();
1373 if (m_frame->isMainFrame())
1374 webPage->send(Messages::WebPageProxy::DidSaveToPageCache());
1377 void WebFrameLoaderClient::didRestoreFromPageCache()
1379 m_frameCameFromPageCache = true;
1382 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
1384 WebPage* webPage = m_frame->page();
1388 webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
1391 bool WebFrameLoaderClient::canCachePage() const
1393 // We cannot cache frames that have custom representations because they are
1394 // rendered in the UIProcess.
1395 return !m_frameHasCustomContentProvider;
1398 void WebFrameLoaderClient::convertMainResourceLoadToDownload(DocumentLoader *documentLoader, SessionID sessionID, const ResourceRequest& request, const ResourceResponse& response)
1400 m_frame->convertMainResourceLoadToDownload(documentLoader, sessionID, request, response);
1403 RefPtr<Frame> WebFrameLoaderClient::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1404 const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
1406 WebPage* webPage = m_frame->page();
1408 RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement);
1410 Frame* coreSubframe = subframe->coreFrame();
1414 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1415 if (!coreSubframe->page())
1418 m_frame->coreFrame()->loader().loadURLIntoChildFrame(url, referrer, coreSubframe);
1420 // The frame's onload handler may have removed it from the document.
1421 if (!subframe->coreFrame())
1423 ASSERT(subframe->coreFrame() == coreSubframe);
1424 if (!coreSubframe->tree().parent())
1427 return coreSubframe;
1430 RefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const URL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1432 ASSERT(paramNames.size() == paramValues.size());
1433 ASSERT(m_frame->page());
1435 Plugin::Parameters parameters;
1436 parameters.url = url;
1437 parameters.names = paramNames;
1438 parameters.values = paramValues;
1439 parameters.mimeType = mimeType;
1440 parameters.isFullFramePlugin = loadManually;
1441 parameters.shouldUseManualLoader = parameters.isFullFramePlugin && !m_frameCameFromPageCache;
1443 parameters.layerHostingMode = m_frame->page()->layerHostingMode();
1446 #if ENABLE(NETSCAPE_PLUGIN_API)
1447 auto plugin = m_frame->page()->createPlugin(m_frame, pluginElement, parameters, parameters.mimeType);
1451 return PluginView::create(pluginElement, WTFMove(plugin), parameters);
1453 UNUSED_PARAM(pluginElement);
1458 void WebFrameLoaderClient::recreatePlugin(Widget* widget)
1460 #if ENABLE(NETSCAPE_PLUGIN_API)
1461 ASSERT(widget && widget->isPluginViewBase());
1462 ASSERT(m_frame->page());
1464 PluginView* pluginView = static_cast<PluginView*>(widget);
1466 auto plugin = m_frame->page()->createPlugin(m_frame, pluginView->pluginElement(), pluginView->initialParameters(), newMIMEType);
1467 pluginView->recreateAndInitialize(WTFMove(plugin));
1469 UNUSED_PARAM(widget);
1473 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1476 m_pluginView = static_cast<PluginView*>(pluginWidget);
1480 WebCore::WebGLLoadPolicy WebFrameLoaderClient::webGLPolicyForURL(const String& url) const
1482 if (WebPage* webPage = m_frame->page())
1483 return webPage->webGLPolicyForURL(m_frame, url);
1485 return WebGLAllowCreation;
1488 WebCore::WebGLLoadPolicy WebFrameLoaderClient::resolveWebGLPolicyForURL(const String& url) const
1490 if (WebPage* webPage = m_frame->page())
1491 return webPage->resolveWebGLPolicyForURL(m_frame, url);
1493 return WebGLAllowCreation;
1495 #endif // ENABLE(WEBGL)
1497 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const URL&, const Vector<String>& paramNames, const Vector<String>& paramValues)
1499 #if ENABLE(NETSCAPE_PLUGIN_API)
1500 auto plugin = createPlugin(pluginSize, appletElement, URL(), paramNames, paramValues, appletElement->serviceType(), false);
1502 if (WebPage* webPage = m_frame->page()) {
1503 String frameURLString = m_frame->coreFrame()->loader().documentLoader()->responseURL().string();
1504 String pageURLString = webPage->corePage()->mainFrame().loader().documentLoader()->responseURL().string();
1505 webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(appletElement->serviceType(), frameURLString, pageURLString));
1508 return WTFMove(plugin);
1510 UNUSED_PARAM(pluginSize);
1511 UNUSED_PARAM(appletElement);
1512 UNUSED_PARAM(paramNames);
1513 UNUSED_PARAM(paramValues);
1518 static bool pluginSupportsExtension(const PluginData& pluginData, const String& extension)
1520 ASSERT(extension.convertToASCIILowercase() == extension);
1521 Vector<MimeClassInfo> mimes;
1522 Vector<size_t> mimePluginIndices;
1523 pluginData.getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
1524 for (auto& mimeClassInfo : mimes) {
1525 if (mimeClassInfo.extensions.contains(extension))
1531 ObjectContentType WebFrameLoaderClient::objectContentType(const URL& url, const String& mimeTypeIn)
1533 // FIXME: This should eventually be merged with WebCore::FrameLoader::defaultObjectContentType.
1535 String mimeType = mimeTypeIn;
1536 if (mimeType.isEmpty()) {
1537 String path = url.path();
1538 auto dotPosition = path.reverseFind('.');
1539 if (dotPosition == notFound)
1540 return ObjectContentType::Frame;
1541 String extension = path.substring(dotPosition + 1).convertToASCIILowercase();
1543 // Try to guess the MIME type from the extension.
1544 mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1545 if (mimeType.isEmpty()) {
1546 // Check if there's a plug-in around that can handle the extension.
1547 if (WebPage* webPage = m_frame->page()) {
1548 if (pluginSupportsExtension(webPage->corePage()->pluginData(), extension))
1549 return ObjectContentType::PlugIn;
1551 return ObjectContentType::Frame;
1555 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1556 return ObjectContentType::Image;
1558 if (WebPage* webPage = m_frame->page()) {
1559 auto allowedPluginTypes = webFrame()->coreFrame()->loader().subframeLoader().allowPlugins()
1560 ? PluginData::AllPlugins : PluginData::OnlyApplicationPlugins;
1561 if (webPage->corePage()->pluginData().supportsMimeType(mimeType, allowedPluginTypes))
1562 return ObjectContentType::PlugIn;
1565 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1566 return ObjectContentType::Frame;
1569 // iOS can render PDF in <object>/<embed> via PDFDocumentImage.
1570 if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType))
1571 return ObjectContentType::Image;
1574 return ObjectContentType::None;
1577 String WebFrameLoaderClient::overrideMediaType() const
1583 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world)
1585 WebPage* webPage = m_frame->page();
1589 webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1592 WebAutomationSessionProxy* automationSessionProxy = WebProcess::singleton().automationSessionProxy();
1593 if (automationSessionProxy && world.isNormal())
1594 automationSessionProxy->didClearWindowObjectForFrame(*m_frame);
1596 #if HAVE(ACCESSIBILITY) && (PLATFORM(GTK) || PLATFORM(EFL))
1597 // Ensure the accessibility hierarchy is updated.
1598 webPage->updateAccessibilityTree();
1603 void WebFrameLoaderClient::dispatchGlobalObjectAvailable(DOMWrapperWorld& world)
1605 WebPage* webPage = m_frame->page();
1609 webPage->injectedBundleLoaderClient().globalObjectIsAvailableForFrame(webPage, m_frame, world);
1612 void WebFrameLoaderClient::dispatchWillDisconnectDOMWindowExtensionFromGlobalObject(WebCore::DOMWindowExtension* extension)
1614 WebPage* webPage = m_frame->page();
1618 webPage->injectedBundleLoaderClient().willDisconnectDOMWindowExtensionFromGlobalObject(webPage, extension);
1621 void WebFrameLoaderClient::dispatchDidReconnectDOMWindowExtensionToGlobalObject(WebCore::DOMWindowExtension* extension)
1623 WebPage* webPage = m_frame->page();
1627 webPage->injectedBundleLoaderClient().didReconnectDOMWindowExtensionToGlobalObject(webPage, extension);
1630 void WebFrameLoaderClient::dispatchWillDestroyGlobalObjectForDOMWindowExtension(WebCore::DOMWindowExtension* extension)
1632 WebPage* webPage = m_frame->page();
1636 webPage->injectedBundleLoaderClient().willDestroyGlobalObjectForDOMWindowExtension(webPage, extension);
1639 void WebFrameLoaderClient::registerForIconNotification(bool /*listen*/)
1646 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject()
1648 WebPage* webPage = m_frame->page();
1652 return webPage->accessibilityRemoteObject();
1655 NSCachedURLResponse *WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1657 WebPage* webPage = m_frame->page();
1661 return webPage->injectedBundleResourceLoadClient().shouldCacheResponse(webPage, m_frame, identifier) ? response : nil;
1664 NSDictionary *WebFrameLoaderClient::dataDetectionContext()
1666 WebPage* webPage = m_frame->page();
1670 return webPage->dataDetectionContext();
1673 #endif // PLATFORM(COCOA)
1675 bool WebFrameLoaderClient::shouldAlwaysUsePluginDocument(const String& /*mimeType*/) const
1681 void WebFrameLoaderClient::didChangeScrollOffset()
1683 WebPage* webPage = m_frame->page();
1687 webPage->didChangeScrollOffsetForFrame(m_frame->coreFrame());
1690 bool WebFrameLoaderClient::allowScript(bool enabledPerSettings)
1692 if (!enabledPerSettings)
1695 Frame* coreFrame = m_frame->coreFrame();
1697 if (coreFrame->document()->isPluginDocument()) {
1698 PluginDocument* pluginDocument = static_cast<PluginDocument*>(coreFrame->document());
1700 if (pluginDocument->pluginWidget() && pluginDocument->pluginWidget()->isPluginView()) {
1701 PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
1703 if (!pluginView->shouldAllowScripting())
1711 bool WebFrameLoaderClient::shouldForceUniversalAccessFromLocalURL(const WebCore::URL& url)
1713 WebPage* webPage = m_frame->page();
1717 return webPage->injectedBundleLoaderClient().shouldForceUniversalAccessFromLocalURL(webPage, url.string());
1720 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1722 auto context = WebFrameNetworkingContext::create(m_frame);
1723 return WTFMove(context);
1726 #if ENABLE(CONTENT_FILTERING)
1727 void WebFrameLoaderClient::contentFilterDidBlockLoad(WebCore::ContentFilterUnblockHandler unblockHandler)
1729 if (!unblockHandler.needsUIProcess()) {
1730 m_frame->coreFrame()->loader().policyChecker().setContentFilterUnblockHandler(WTFMove(unblockHandler));
1734 if (WebPage* webPage { m_frame->page() })
1735 webPage->send(Messages::WebPageProxy::ContentFilterDidBlockLoadForFrame(unblockHandler, m_frame->frameID()));
1739 #if ENABLE(REQUEST_AUTOCOMPLETE)
1740 void WebFrameLoaderClient::didRequestAutocomplete(PassRefPtr<WebCore::FormState>)
1745 void WebFrameLoaderClient::prefetchDNS(const String& hostname)
1747 WebProcess::singleton().prefetchDNS(hostname);
1750 void WebFrameLoaderClient::didRestoreScrollPosition()
1752 WebPage* webPage = m_frame->page();
1756 webPage->didRestoreScrollPosition();
1759 bool WebFrameLoaderClient::useIconLoadingClient()
1761 return m_useIconLoadingClient;
1764 void WebFrameLoaderClient::getLoadDecisionForIcon(const LinkIcon& icon, uint64_t callbackID)
1766 if (WebPage* webPage { m_frame->page() })
1767 webPage->send(Messages::WebPageProxy::GetLoadDecisionForIcon(icon, callbackID));
1770 void WebFrameLoaderClient::finishedLoadingIcon(uint64_t loadIdentifier, SharedBuffer* data)
1772 if (WebPage* webPage { m_frame->page() }) {
1774 webPage->send(Messages::WebPageProxy::FinishedLoadingIcon(loadIdentifier, { reinterpret_cast<const uint8_t*>(data->data()), data->size() }));
1776 webPage->send(Messages::WebPageProxy::FinishedLoadingIcon(loadIdentifier, { nullptr, 0 }));
1780 } // namespace WebKit