| 1 | /* |
| 2 | * Copyright (C) 2010-2018 Apple Inc. All rights reserved. |
| 3 | * |
| 4 | * Redistribution and use in source and binary forms, with or without |
| 5 | * modification, are permitted provided that the following conditions |
| 6 | * are met: |
| 7 | * 1. Redistributions of source code must retain the above copyright |
| 8 | * notice, this list of conditions and the following disclaimer. |
| 9 | * 2. Redistributions in binary form must reproduce the above copyright |
| 10 | * notice, this list of conditions and the following disclaimer in the |
| 11 | * documentation and/or other materials provided with the distribution. |
| 12 | * |
| 13 | * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| 14 | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| 15 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| 16 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| 17 | * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| 18 | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| 19 | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| 20 | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| 21 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| 22 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| 23 | * THE POSSIBILITY OF SUCH DAMAGE. |
| 24 | */ |
| 25 | |
| 26 | #include "config.h" |
| 27 | #include "WebFrameLoaderClient.h" |
| 28 | |
| 29 | #include "AuthenticationManager.h" |
| 30 | #include "DataReference.h" |
| 31 | #include "DrawingArea.h" |
| 32 | #include "FindController.h" |
| 33 | #include "FormDataReference.h" |
| 34 | #include "FrameInfoData.h" |
| 35 | #include "InjectedBundle.h" |
| 36 | #include "InjectedBundleDOMWindowExtension.h" |
| 37 | #include "InjectedBundleNavigationAction.h" |
| 38 | #include "Logging.h" |
| 39 | #include "NavigationActionData.h" |
| 40 | #include "NetworkConnectionToWebProcessMessages.h" |
| 41 | #include "NetworkProcessConnection.h" |
| 42 | #include "PluginView.h" |
| 43 | #include "UserData.h" |
| 44 | #include "WKBundleAPICast.h" |
| 45 | #include "WebAutomationSessionProxy.h" |
| 46 | #include "WebBackForwardListProxy.h" |
| 47 | #include "WebCoreArgumentCoders.h" |
| 48 | #include "WebDocumentLoader.h" |
| 49 | #include "WebErrors.h" |
| 50 | #include "WebEvent.h" |
| 51 | #include "WebFrame.h" |
| 52 | #include "WebFrameNetworkingContext.h" |
| 53 | #include "WebFullScreenManager.h" |
| 54 | #include "WebNavigationDataStore.h" |
| 55 | #include "WebPage.h" |
| 56 | #include "WebPageGroupProxy.h" |
| 57 | #include "WebPageProxyMessages.h" |
| 58 | #include "WebProcess.h" |
| 59 | #include "WebProcessPoolMessages.h" |
| 60 | #include "WebsitePoliciesData.h" |
| 61 | #include <JavaScriptCore/APICast.h> |
| 62 | #include <JavaScriptCore/JSObject.h> |
| 63 | #include <WebCore/CachedFrame.h> |
| 64 | #include <WebCore/CertificateInfo.h> |
| 65 | #include <WebCore/Chrome.h> |
| 66 | #include <WebCore/DOMWrapperWorld.h> |
| 67 | #include <WebCore/DocumentLoader.h> |
| 68 | #include <WebCore/FormState.h> |
| 69 | #include <WebCore/Frame.h> |
| 70 | #include <WebCore/FrameLoadRequest.h> |
| 71 | #include <WebCore/FrameLoader.h> |
| 72 | #include <WebCore/FrameLoaderTypes.h> |
| 73 | #include <WebCore/FrameView.h> |
| 74 | #include <WebCore/HTMLAppletElement.h> |
| 75 | #include <WebCore/HTMLFormElement.h> |
| 76 | #include <WebCore/HistoryController.h> |
| 77 | #include <WebCore/HistoryItem.h> |
| 78 | #include <WebCore/MIMETypeRegistry.h> |
| 79 | #include <WebCore/MouseEvent.h> |
| 80 | #include <WebCore/NotImplemented.h> |
| 81 | #include <WebCore/Page.h> |
| 82 | #include <WebCore/PluginData.h> |
| 83 | #include <WebCore/PluginDocument.h> |
| 84 | #include <WebCore/PolicyChecker.h> |
| 85 | #include <WebCore/ProgressTracker.h> |
| 86 | #include <WebCore/ResourceError.h> |
| 87 | #include <WebCore/ResourceRequest.h> |
| 88 | #include <WebCore/ScriptController.h> |
| 89 | #include <WebCore/SecurityOriginData.h> |
| 90 | #include <WebCore/Settings.h> |
| 91 | #include <WebCore/SubframeLoader.h> |
| 92 | #include <WebCore/UIEventWithKeyState.h> |
| 93 | #include <WebCore/Widget.h> |
| 94 | #include <WebCore/WindowFeatures.h> |
| 95 | #include <wtf/NeverDestroyed.h> |
| 96 | #include <wtf/ProcessID.h> |
| 97 | #include <wtf/ProcessPrivilege.h> |
| 98 | |
| 99 | namespace WebKit { |
| 100 | using namespace WebCore; |
| 101 | |
| 102 | WebFrameLoaderClient::WebFrameLoaderClient() |
| 103 | : m_frame(0) |
| 104 | , m_hasSentResponseToPluginView(false) |
| 105 | , m_didCompletePageTransition(false) |
| 106 | , m_frameHasCustomContentProvider(false) |
| 107 | , m_frameCameFromPageCache(false) |
| 108 | { |
| 109 | } |
| 110 | |
| 111 | WebFrameLoaderClient::~WebFrameLoaderClient() |
| 112 | { |
| 113 | } |
| 114 | |
| 115 | Optional<uint64_t> WebFrameLoaderClient::pageID() const |
| 116 | { |
| 117 | if (m_frame && m_frame->page()) |
| 118 | return m_frame->page()->pageID(); |
| 119 | |
| 120 | return WTF::nullopt; |
| 121 | } |
| 122 | |
| 123 | Optional<uint64_t> WebFrameLoaderClient::frameID() const |
| 124 | { |
| 125 | if (m_frame) |
| 126 | return m_frame->frameID(); |
| 127 | |
| 128 | return WTF::nullopt; |
| 129 | } |
| 130 | |
| 131 | PAL::SessionID WebFrameLoaderClient::sessionID() const |
| 132 | { |
| 133 | return m_frame && m_frame->page() ? m_frame->page()->sessionID() : PAL::SessionID::defaultSessionID(); |
| 134 | } |
| 135 | |
| 136 | void WebFrameLoaderClient::frameLoaderDestroyed() |
| 137 | { |
| 138 | m_frame->invalidate(); |
| 139 | |
| 140 | // Balances explicit ref() in WebFrame::create(). |
| 141 | m_frame->deref(); |
| 142 | } |
| 143 | |
| 144 | bool WebFrameLoaderClient::hasHTMLView() const |
| 145 | { |
| 146 | return !m_frameHasCustomContentProvider; |
| 147 | } |
| 148 | |
| 149 | bool WebFrameLoaderClient::hasWebView() const |
| 150 | { |
| 151 | return m_frame->page(); |
| 152 | } |
| 153 | |
| 154 | void WebFrameLoaderClient::makeRepresentation(DocumentLoader*) |
| 155 | { |
| 156 | notImplemented(); |
| 157 | } |
| 158 | |
| 159 | void WebFrameLoaderClient::forceLayoutForNonHTML() |
| 160 | { |
| 161 | notImplemented(); |
| 162 | } |
| 163 | |
| 164 | void WebFrameLoaderClient::setCopiesOnScroll() |
| 165 | { |
| 166 | notImplemented(); |
| 167 | } |
| 168 | |
| 169 | void WebFrameLoaderClient::detachedFromParent2() |
| 170 | { |
| 171 | WebPage* webPage = m_frame->page(); |
| 172 | if (!webPage) |
| 173 | return; |
| 174 | |
| 175 | #if ENABLE(RESOURCE_LOAD_STATISTICS) |
| 176 | if (m_hasFrameSpecificStorageAccess) { |
| 177 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::RemoveStorageAccessForFrame(sessionID(), frameID().value(), pageID().value()), 0); |
| 178 | m_hasFrameSpecificStorageAccess = false; |
| 179 | } |
| 180 | #endif |
| 181 | |
| 182 | RefPtr<API::Object> userData; |
| 183 | |
| 184 | // Notify the bundle client. |
| 185 | webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(*webPage, *m_frame, userData); |
| 186 | } |
| 187 | |
| 188 | void WebFrameLoaderClient::detachedFromParent3() |
| 189 | { |
| 190 | notImplemented(); |
| 191 | } |
| 192 | |
| 193 | void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request) |
| 194 | { |
| 195 | WebPage* webPage = m_frame->page(); |
| 196 | if (!webPage) |
| 197 | return; |
| 198 | |
| 199 | bool pageIsProvisionallyLoading = false; |
| 200 | if (FrameLoader* frameLoader = loader->frameLoader()) |
| 201 | pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader; |
| 202 | |
| 203 | webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(*webPage, *m_frame, identifier, request, pageIsProvisionallyLoading); |
| 204 | webPage->addResourceRequest(identifier, request); |
| 205 | } |
| 206 | |
| 207 | void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse) |
| 208 | { |
| 209 | WebPage* webPage = m_frame->page(); |
| 210 | if (!webPage) |
| 211 | return; |
| 212 | |
| 213 | // The API can return a completely new request. We should ensure that at least the requester |
| 214 | // is kept, so that if this is a main resource load it's still considered as such. |
| 215 | auto requester = request.requester(); |
| 216 | webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(*webPage, *m_frame, identifier, request, redirectResponse); |
| 217 | if (!request.isNull()) |
| 218 | request.setRequester(requester); |
| 219 | } |
| 220 | |
| 221 | bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier) |
| 222 | { |
| 223 | WebPage* webPage = m_frame->page(); |
| 224 | if (!webPage) |
| 225 | return true; |
| 226 | |
| 227 | return webPage->injectedBundleResourceLoadClient().shouldUseCredentialStorage(*webPage, *m_frame, identifier); |
| 228 | } |
| 229 | |
| 230 | void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge&) |
| 231 | { |
| 232 | ASSERT_NOT_REACHED(); |
| 233 | } |
| 234 | |
| 235 | #if USE(PROTECTION_SPACE_AUTH_CALLBACK) |
| 236 | bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace) |
| 237 | { |
| 238 | // The WebKit 2 Networking process asks the UIProcess directly, so the WebContent process should never receive this callback. |
| 239 | ASSERT_NOT_REACHED(); |
| 240 | return false; |
| 241 | } |
| 242 | #endif |
| 243 | |
| 244 | void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response) |
| 245 | { |
| 246 | WebPage* webPage = m_frame->page(); |
| 247 | if (!webPage) |
| 248 | return; |
| 249 | |
| 250 | webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(*webPage, *m_frame, identifier, response); |
| 251 | } |
| 252 | |
| 253 | void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength) |
| 254 | { |
| 255 | WebPage* webPage = m_frame->page(); |
| 256 | if (!webPage) |
| 257 | return; |
| 258 | |
| 259 | webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(*webPage, *m_frame, identifier, dataLength); |
| 260 | } |
| 261 | |
| 262 | #if ENABLE(DATA_DETECTION) |
| 263 | void WebFrameLoaderClient::dispatchDidFinishDataDetection(NSArray *detectionResults) |
| 264 | { |
| 265 | WebPage* webPage = m_frame->page(); |
| 266 | if (!webPage) |
| 267 | return; |
| 268 | webPage->setDataDetectionResults(detectionResults); |
| 269 | } |
| 270 | #endif |
| 271 | |
| 272 | void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier) |
| 273 | { |
| 274 | WebPage* webPage = m_frame->page(); |
| 275 | if (!webPage) |
| 276 | return; |
| 277 | |
| 278 | webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(*webPage, *m_frame, identifier); |
| 279 | webPage->removeResourceRequest(identifier); |
| 280 | } |
| 281 | |
| 282 | void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error) |
| 283 | { |
| 284 | WebPage* webPage = m_frame->page(); |
| 285 | if (!webPage) |
| 286 | return; |
| 287 | |
| 288 | webPage->injectedBundleResourceLoadClient().didFailLoadForResource(*webPage, *m_frame, identifier, error); |
| 289 | webPage->removeResourceRequest(identifier); |
| 290 | } |
| 291 | |
| 292 | bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int /*length*/) |
| 293 | { |
| 294 | notImplemented(); |
| 295 | return false; |
| 296 | } |
| 297 | |
| 298 | void WebFrameLoaderClient::dispatchDidDispatchOnloadEvents() |
| 299 | { |
| 300 | WebPage* webPage = m_frame->page(); |
| 301 | if (!webPage) |
| 302 | return; |
| 303 | |
| 304 | // Notify the bundle client. |
| 305 | webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(*webPage, *m_frame); |
| 306 | } |
| 307 | |
| 308 | void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad() |
| 309 | { |
| 310 | WebPage* webPage = m_frame->page(); |
| 311 | if (!webPage) |
| 312 | return; |
| 313 | |
| 314 | WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader()); |
| 315 | RefPtr<API::Object> userData; |
| 316 | |
| 317 | LOG(Loading, "WebProcess %i - dispatchDidReceiveServerRedirectForProvisionalLoad to request url %s" , getCurrentProcessID(), documentLoader.request().url().string().utf8().data()); |
| 318 | |
| 319 | // Notify the bundle client. |
| 320 | webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(*webPage, *m_frame, userData); |
| 321 | |
| 322 | // Notify the UIProcess. |
| 323 | webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.request(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 324 | } |
| 325 | |
| 326 | void WebFrameLoaderClient::dispatchDidChangeProvisionalURL() |
| 327 | { |
| 328 | WebPage* webPage = m_frame->page(); |
| 329 | if (!webPage) |
| 330 | return; |
| 331 | |
| 332 | WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader()); |
| 333 | webPage->send(Messages::WebPageProxy::DidChangeProvisionalURLForFrame(m_frame->frameID(), documentLoader.navigationID(), documentLoader.url())); |
| 334 | } |
| 335 | |
| 336 | void WebFrameLoaderClient::dispatchDidCancelClientRedirect() |
| 337 | { |
| 338 | WebPage* webPage = m_frame->page(); |
| 339 | if (!webPage) |
| 340 | return; |
| 341 | |
| 342 | // Notify the bundle client. |
| 343 | webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(*webPage, *m_frame); |
| 344 | |
| 345 | // Notify the UIProcess. |
| 346 | webPage->send(Messages::WebPageProxy::DidCancelClientRedirectForFrame(m_frame->frameID())); |
| 347 | } |
| 348 | |
| 349 | void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const URL& url, double interval, WallTime fireDate, LockBackForwardList lockBackForwardList) |
| 350 | { |
| 351 | WebPage* webPage = m_frame->page(); |
| 352 | if (!webPage) |
| 353 | return; |
| 354 | |
| 355 | // Notify the bundle client. |
| 356 | webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(*webPage, *m_frame, url, interval, fireDate); |
| 357 | |
| 358 | // Notify the UIProcess. |
| 359 | webPage->send(Messages::WebPageProxy::WillPerformClientRedirectForFrame(m_frame->frameID(), url.string(), interval, lockBackForwardList)); |
| 360 | } |
| 361 | |
| 362 | void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage() |
| 363 | { |
| 364 | WebPage* webPage = m_frame->page(); |
| 365 | if (!webPage) |
| 366 | return; |
| 367 | |
| 368 | RefPtr<API::Object> userData; |
| 369 | |
| 370 | auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID(); |
| 371 | |
| 372 | // Notify the bundle client. |
| 373 | webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(*webPage, *m_frame, SameDocumentNavigationAnchorNavigation, userData); |
| 374 | |
| 375 | // Notify the UIProcess. |
| 376 | webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 377 | } |
| 378 | |
| 379 | void WebFrameLoaderClient::dispatchDidChangeMainDocument() |
| 380 | { |
| 381 | WebPage* webPage = m_frame->page(); |
| 382 | if (!webPage) |
| 383 | return; |
| 384 | |
| 385 | webPage->send(Messages::WebPageProxy::DidChangeMainDocument(m_frame->frameID())); |
| 386 | } |
| 387 | |
| 388 | void WebFrameLoaderClient::dispatchWillChangeDocument(const URL& currentUrl, const URL& newUrl) |
| 389 | { |
| 390 | #if ENABLE(RESOURCE_LOAD_STATISTICS) |
| 391 | if (m_frame->isMainFrame()) |
| 392 | return; |
| 393 | |
| 394 | WebPage* webPage = m_frame->page(); |
| 395 | if (!webPage) |
| 396 | return; |
| 397 | |
| 398 | if (m_hasFrameSpecificStorageAccess && !WebCore::areRegistrableDomainsEqual(currentUrl, newUrl)) { |
| 399 | WebProcess::singleton().ensureNetworkProcessConnection().connection().send(Messages::NetworkConnectionToWebProcess::RemoveStorageAccessForFrame(sessionID(), frameID().value(), pageID().value()), 0); |
| 400 | m_hasFrameSpecificStorageAccess = false; |
| 401 | } |
| 402 | #endif |
| 403 | } |
| 404 | |
| 405 | void WebFrameLoaderClient::dispatchDidPushStateWithinPage() |
| 406 | { |
| 407 | WebPage* webPage = m_frame->page(); |
| 408 | if (!webPage) |
| 409 | return; |
| 410 | |
| 411 | RefPtr<API::Object> userData; |
| 412 | |
| 413 | auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID(); |
| 414 | |
| 415 | // Notify the bundle client. |
| 416 | webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(*webPage, *m_frame, SameDocumentNavigationSessionStatePush, userData); |
| 417 | |
| 418 | // Notify the UIProcess. |
| 419 | webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 420 | } |
| 421 | |
| 422 | void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage() |
| 423 | { |
| 424 | WebPage* webPage = m_frame->page(); |
| 425 | if (!webPage) |
| 426 | return; |
| 427 | |
| 428 | RefPtr<API::Object> userData; |
| 429 | |
| 430 | auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID(); |
| 431 | |
| 432 | // Notify the bundle client. |
| 433 | webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(*webPage, *m_frame, SameDocumentNavigationSessionStateReplace, userData); |
| 434 | |
| 435 | // Notify the UIProcess. |
| 436 | webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 437 | } |
| 438 | |
| 439 | void WebFrameLoaderClient::dispatchDidPopStateWithinPage() |
| 440 | { |
| 441 | WebPage* webPage = m_frame->page(); |
| 442 | if (!webPage) |
| 443 | return; |
| 444 | |
| 445 | RefPtr<API::Object> userData; |
| 446 | |
| 447 | auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID(); |
| 448 | |
| 449 | // Notify the bundle client. |
| 450 | webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(*webPage, *m_frame, SameDocumentNavigationSessionStatePop, userData); |
| 451 | |
| 452 | // Notify the UIProcess. |
| 453 | webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), navigationID, SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 454 | } |
| 455 | |
| 456 | void WebFrameLoaderClient::dispatchWillClose() |
| 457 | { |
| 458 | notImplemented(); |
| 459 | } |
| 460 | |
| 461 | void WebFrameLoaderClient::dispatchDidExplicitOpen(const URL& url) |
| 462 | { |
| 463 | auto* webPage = m_frame->page(); |
| 464 | if (!webPage) |
| 465 | return; |
| 466 | |
| 467 | // Notify the UIProcess. |
| 468 | webPage->send(Messages::WebPageProxy::DidExplicitOpenForFrame(m_frame->frameID(), url)); |
| 469 | } |
| 470 | |
| 471 | void WebFrameLoaderClient::dispatchDidStartProvisionalLoad() |
| 472 | { |
| 473 | WebPage* webPage = m_frame->page(); |
| 474 | if (!webPage) |
| 475 | return; |
| 476 | |
| 477 | #if ENABLE(FULLSCREEN_API) |
| 478 | Element* documentElement = m_frame->coreFrame()->document()->documentElement(); |
| 479 | if (documentElement && documentElement->containsFullScreenElement()) |
| 480 | webPage->fullScreenManager()->exitFullScreenForElement(webPage->fullScreenManager()->element()); |
| 481 | #endif |
| 482 | |
| 483 | webPage->findController().hideFindUI(); |
| 484 | webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame); |
| 485 | |
| 486 | WebDocumentLoader& provisionalLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().provisionalDocumentLoader()); |
| 487 | auto& url = provisionalLoader.url(); |
| 488 | RefPtr<API::Object> userData; |
| 489 | |
| 490 | // Notify the bundle client. |
| 491 | webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(*webPage, *m_frame, userData); |
| 492 | |
| 493 | auto& unreachableURL = provisionalLoader.unreachableURL(); |
| 494 | |
| 495 | // Notify the UIProcess. |
| 496 | webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), provisionalLoader.navigationID(), url, unreachableURL, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 497 | } |
| 498 | |
| 499 | static constexpr unsigned maxTitleLength = 1000; // Closest power of 10 above the W3C recommendation for Title length. |
| 500 | |
| 501 | void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title) |
| 502 | { |
| 503 | WebPage* webPage = m_frame->page(); |
| 504 | if (!webPage) |
| 505 | return; |
| 506 | |
| 507 | auto truncatedTitle = truncateFromEnd(title, maxTitleLength); |
| 508 | |
| 509 | RefPtr<API::Object> userData; |
| 510 | |
| 511 | // Notify the bundle client. |
| 512 | // FIXME: Use direction of title. |
| 513 | webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(*webPage, truncatedTitle.string, *m_frame, userData); |
| 514 | |
| 515 | // Notify the UIProcess. |
| 516 | webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), truncatedTitle.string, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 517 | } |
| 518 | |
| 519 | void WebFrameLoaderClient::dispatchDidCommitLoad(Optional<HasInsecureContent> hasInsecureContent) |
| 520 | { |
| 521 | WebPage* webPage = m_frame->page(); |
| 522 | if (!webPage) |
| 523 | return; |
| 524 | |
| 525 | WebDocumentLoader& documentLoader = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()); |
| 526 | RefPtr<API::Object> userData; |
| 527 | |
| 528 | // Notify the bundle client. |
| 529 | webPage->injectedBundleLoaderClient().didCommitLoadForFrame(*webPage, *m_frame, userData); |
| 530 | |
| 531 | webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame); |
| 532 | |
| 533 | // Notify the UIProcess. |
| 534 | 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()))); |
| 535 | webPage->didCommitLoad(m_frame); |
| 536 | } |
| 537 | |
| 538 | void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error, WillContinueLoading willContinueLoading) |
| 539 | { |
| 540 | WebPage* webPage = m_frame->page(); |
| 541 | if (!webPage) |
| 542 | return; |
| 543 | |
| 544 | RELEASE_LOG(Network, "%p - WebFrameLoaderClient::dispatchDidFailProvisionalLoad: (pageID = %" PRIu64 ", frameID = %" PRIu64 ")" , this, webPage->pageID(), m_frame->frameID()); |
| 545 | |
| 546 | RefPtr<API::Object> userData; |
| 547 | |
| 548 | // Notify the bundle client. |
| 549 | webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(*webPage, *m_frame, error, userData); |
| 550 | |
| 551 | webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame); |
| 552 | |
| 553 | // FIXME: This is gross. This is necessary because if the client calls WKBundlePageStopLoading() from within the didFailProvisionalLoadWithErrorForFrame |
| 554 | // injected bundle client call, that will cause the provisional DocumentLoader to be disconnected from the Frame, and didDistroyNavigation message |
| 555 | // to be sent to the UIProcess (and the destruction of the DocumentLoader). If that happens, and we had captured the navigationID before injected bundle |
| 556 | // client call, the DidFailProvisionalLoadForFrame would send a navigationID of a destroyed Navigation, and the UIProcess would not be able to find it |
| 557 | // in its table. |
| 558 | // |
| 559 | // A better solution to this problem would be find a clean way to postpone the disconnection of the DocumentLoader from the Frame until |
| 560 | // the entire FrameLoaderClient function was complete. |
| 561 | uint64_t navigationID = 0; |
| 562 | if (auto documentLoader = m_frame->coreFrame()->loader().provisionalDocumentLoader()) |
| 563 | navigationID = static_cast<WebDocumentLoader*>(documentLoader)->navigationID(); |
| 564 | |
| 565 | // Notify the UIProcess. |
| 566 | WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr; |
| 567 | webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), navigationID, m_frame->coreFrame()->loader().provisionalLoadErrorBeingHandledURL(), error, willContinueLoading, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 568 | |
| 569 | // If we have a load listener, notify it. |
| 570 | if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) |
| 571 | loadListener->didFailLoad(m_frame, error.isCancellation()); |
| 572 | } |
| 573 | |
| 574 | void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error) |
| 575 | { |
| 576 | WebPage* webPage = m_frame->page(); |
| 577 | if (!webPage) |
| 578 | return; |
| 579 | |
| 580 | RELEASE_LOG(Network, "%p - WebFrameLoaderClient::dispatchDidFailLoad: (pageID = %" PRIu64 ", frameID = %" PRIu64 ")" , this, webPage->pageID(), m_frame->frameID()); |
| 581 | |
| 582 | RefPtr<API::Object> userData; |
| 583 | |
| 584 | auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID(); |
| 585 | |
| 586 | // Notify the bundle client. |
| 587 | webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(*webPage, *m_frame, error, userData); |
| 588 | |
| 589 | // Notify the UIProcess. |
| 590 | webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), navigationID, error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 591 | |
| 592 | // If we have a load listener, notify it. |
| 593 | if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) |
| 594 | loadListener->didFailLoad(m_frame, error.isCancellation()); |
| 595 | } |
| 596 | |
| 597 | void WebFrameLoaderClient::dispatchDidFinishDocumentLoad() |
| 598 | { |
| 599 | WebPage* webPage = m_frame->page(); |
| 600 | if (!webPage) |
| 601 | return; |
| 602 | |
| 603 | RefPtr<API::Object> userData; |
| 604 | |
| 605 | auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID(); |
| 606 | |
| 607 | // Notify the bundle client. |
| 608 | webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(*webPage, *m_frame, userData); |
| 609 | |
| 610 | // Notify the UIProcess. |
| 611 | webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 612 | |
| 613 | webPage->didFinishDocumentLoad(*m_frame); |
| 614 | } |
| 615 | |
| 616 | void WebFrameLoaderClient::dispatchDidFinishLoad() |
| 617 | { |
| 618 | WebPage* webPage = m_frame->page(); |
| 619 | if (!webPage) |
| 620 | return; |
| 621 | |
| 622 | RefPtr<API::Object> userData; |
| 623 | |
| 624 | auto navigationID = static_cast<WebDocumentLoader&>(*m_frame->coreFrame()->loader().documentLoader()).navigationID(); |
| 625 | |
| 626 | // Notify the bundle client. |
| 627 | webPage->injectedBundleLoaderClient().didFinishLoadForFrame(*webPage, *m_frame, userData); |
| 628 | |
| 629 | // Notify the UIProcess. |
| 630 | webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), navigationID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 631 | |
| 632 | // If we have a load listener, notify it. |
| 633 | if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) |
| 634 | loadListener->didFinishLoad(m_frame); |
| 635 | |
| 636 | webPage->didFinishLoad(*m_frame); |
| 637 | } |
| 638 | |
| 639 | void WebFrameLoaderClient::forcePageTransitionIfNeeded() |
| 640 | { |
| 641 | if (m_didCompletePageTransition) |
| 642 | return; |
| 643 | |
| 644 | WebPage* webPage = m_frame->page(); |
| 645 | if (!webPage) |
| 646 | return; |
| 647 | |
| 648 | webPage->didCompletePageTransition(); |
| 649 | m_didCompletePageTransition = true; |
| 650 | } |
| 651 | |
| 652 | void WebFrameLoaderClient::dispatchDidReachLayoutMilestone(OptionSet<WebCore::LayoutMilestone> milestones) |
| 653 | { |
| 654 | WebPage* webPage = m_frame->page(); |
| 655 | if (!webPage) |
| 656 | return; |
| 657 | |
| 658 | RefPtr<API::Object> userData; |
| 659 | |
| 660 | if (milestones & DidFirstLayout) { |
| 661 | RELEASE_LOG(Layout, "%p - WebFrameLoaderClient::dispatchDidReachLayoutMilestone: dispatching DidFirstLayoutForFrame, page = %p" , this, webPage); |
| 662 | |
| 663 | // FIXME: We should consider removing the old didFirstLayout API since this is doing double duty with the |
| 664 | // new didLayout API. |
| 665 | webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(*webPage, *m_frame, userData); |
| 666 | webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 667 | |
| 668 | #if PLATFORM(MAC) |
| 669 | // FIXME: Do this on DidFirstVisuallyNonEmptyLayout when Mac Safari is able to handle it (<rdar://problem/17580021>) |
| 670 | if (m_frame->isMainFrame() && !m_didCompletePageTransition && !webPage->corePage()->settings().suppressesIncrementalRendering()) { |
| 671 | RELEASE_LOG(Layout, "%p - WebFrameLoaderClient::dispatchDidReachLayoutMilestone: dispatching didCompletePageTransition, page = %p" , this, webPage); |
| 672 | webPage->didCompletePageTransition(); |
| 673 | m_didCompletePageTransition = true; |
| 674 | } |
| 675 | #endif |
| 676 | |
| 677 | #if USE(COORDINATED_GRAPHICS) |
| 678 | // Make sure viewport properties are dispatched on the main frame by the time the first layout happens. |
| 679 | ASSERT(!webPage->useFixedLayout() || m_frame != m_frame->page()->mainWebFrame() || m_frame->coreFrame()->document()->didDispatchViewportPropertiesChanged()); |
| 680 | #endif |
| 681 | } |
| 682 | |
| 683 | #if !RELEASE_LOG_DISABLED |
| 684 | StringBuilder builder; |
| 685 | auto addIfSet = [&milestones, &builder] (WebCore::LayoutMilestone milestone, const String& toAdd) { |
| 686 | if (milestones.contains(milestone)) { |
| 687 | if (!builder.isEmpty()) |
| 688 | builder.append(", " ); |
| 689 | builder.append(toAdd); |
| 690 | } |
| 691 | }; |
| 692 | |
| 693 | addIfSet(DidFirstLayout, "DidFirstLayout"_s ); |
| 694 | addIfSet(DidFirstVisuallyNonEmptyLayout, "DidFirstVisuallyNonEmptyLayout"_s ); |
| 695 | addIfSet(DidHitRelevantRepaintedObjectsAreaThreshold, "DidHitRelevantRepaintedObjectsAreaThreshold"_s ); |
| 696 | addIfSet(DidFirstFlushForHeaderLayer, "DidFirstFlushForHeaderLayer"_s ); |
| 697 | addIfSet(DidFirstLayoutAfterSuppressedIncrementalRendering, "DidFirstLayoutAfterSuppressedIncrementalRendering"_s ); |
| 698 | addIfSet(DidFirstPaintAfterSuppressedIncrementalRendering, "DidFirstPaintAfterSuppressedIncrementalRendering"_s ); |
| 699 | addIfSet(ReachedSessionRestorationRenderTreeSizeThreshold, "ReachedSessionRestorationRenderTreeSizeThreshold"_s ); |
| 700 | addIfSet(DidRenderSignificantAmountOfText, "DidRenderSignificantAmountOfText"_s ); |
| 701 | addIfSet(DidFirstMeaningfulPaint, "DidFirstMeaningfulPaint"_s ); |
| 702 | |
| 703 | RELEASE_LOG(Layout, "%p - WebFrameLoaderClient::dispatchDidReachLayoutMilestone: dispatching DidReachLayoutMilestone, page = %p, milestones = %{public}s" , this, webPage, builder.toString().utf8().data()); |
| 704 | #endif |
| 705 | |
| 706 | // Send this after DidFirstLayout-specific calls since some clients expect to get those messages first. |
| 707 | webPage->dispatchDidReachLayoutMilestone(milestones); |
| 708 | |
| 709 | if (milestones & DidFirstVisuallyNonEmptyLayout) { |
| 710 | if (m_frame->isMainFrame() && !m_didCompletePageTransition && !webPage->corePage()->settings().suppressesIncrementalRendering()) { |
| 711 | RELEASE_LOG(Layout, "%p - WebFrameLoaderClient::dispatchDidReachLayoutMilestone: dispatching didCompletePageTransition, page = %p" , this, webPage); |
| 712 | webPage->didCompletePageTransition(); |
| 713 | m_didCompletePageTransition = true; |
| 714 | } |
| 715 | |
| 716 | // FIXME: We should consider removing the old didFirstVisuallyNonEmptyLayoutForFrame API since this is doing |
| 717 | // double duty with the new didLayout API. |
| 718 | RELEASE_LOG(Layout, "%p - WebFrameLoaderClient::dispatchDidReachLayoutMilestone: dispatching DidFirstVisuallyNonEmptyLayoutForFrame, page = %p" , this, webPage); |
| 719 | webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(*webPage, *m_frame, userData); |
| 720 | webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 721 | } |
| 722 | } |
| 723 | |
| 724 | void WebFrameLoaderClient::dispatchDidLayout() |
| 725 | { |
| 726 | WebPage* webPage = m_frame->page(); |
| 727 | if (!webPage) |
| 728 | return; |
| 729 | |
| 730 | // Notify the bundle client. |
| 731 | webPage->injectedBundleLoaderClient().didLayoutForFrame(*webPage, *m_frame); |
| 732 | |
| 733 | webPage->recomputeShortCircuitHorizontalWheelEventsState(); |
| 734 | |
| 735 | #if PLATFORM(IOS_FAMILY) |
| 736 | webPage->updateSelectionAppearance(); |
| 737 | #endif |
| 738 | |
| 739 | // NOTE: Unlike the other layout notifications, this does not notify the |
| 740 | // the UIProcess for every call. |
| 741 | |
| 742 | if (m_frame == m_frame->page()->mainWebFrame()) { |
| 743 | // FIXME: Remove at the soonest possible time. |
| 744 | webPage->send(Messages::WebPageProxy::SetRenderTreeSize(webPage->renderTreeSize())); |
| 745 | webPage->mainFrameDidLayout(); |
| 746 | } |
| 747 | } |
| 748 | |
| 749 | Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction) |
| 750 | { |
| 751 | WebPage* webPage = m_frame->page(); |
| 752 | if (!webPage) |
| 753 | return nullptr; |
| 754 | |
| 755 | // Just call through to the chrome client. |
| 756 | FrameLoadRequest frameLoadRequest { *m_frame->coreFrame()->document(), m_frame->coreFrame()->document()->securityOrigin(), navigationAction.resourceRequest(), { }, LockHistory::No, LockBackForwardList::No, MaybeSendReferrer, AllowNavigationToInvalidURL::Yes, NewFrameOpenerPolicy::Allow, navigationAction.shouldOpenExternalURLsPolicy(), InitiatedByMainFrame::Unknown }; |
| 757 | Page* newPage = webPage->corePage()->chrome().createWindow(*m_frame->coreFrame(), frameLoadRequest, { }, navigationAction); |
| 758 | if (!newPage) |
| 759 | return nullptr; |
| 760 | |
| 761 | return &newPage->mainFrame(); |
| 762 | } |
| 763 | |
| 764 | void WebFrameLoaderClient::dispatchShow() |
| 765 | { |
| 766 | WebPage* webPage = m_frame->page(); |
| 767 | if (!webPage) |
| 768 | return; |
| 769 | |
| 770 | webPage->show(); |
| 771 | } |
| 772 | |
| 773 | void WebFrameLoaderClient::dispatchDecidePolicyForResponse(const ResourceResponse& response, const ResourceRequest& request, WebCore::PolicyCheckIdentifier identifier, const String& downloadAttribute, FramePolicyFunction&& function) |
| 774 | { |
| 775 | WebPage* webPage = m_frame ? m_frame->page() : nullptr; |
| 776 | if (!webPage) { |
| 777 | function(PolicyAction::Ignore, identifier); |
| 778 | return; |
| 779 | } |
| 780 | |
| 781 | if (!request.url().string()) { |
| 782 | function(PolicyAction::Use, identifier); |
| 783 | return; |
| 784 | } |
| 785 | |
| 786 | RefPtr<API::Object> userData; |
| 787 | |
| 788 | // Notify the bundle client. |
| 789 | WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData); |
| 790 | if (policy == WKBundlePagePolicyActionUse) { |
| 791 | function(PolicyAction::Use, identifier); |
| 792 | return; |
| 793 | } |
| 794 | |
| 795 | bool canShowResponse = webPage->canShowResponse(response); |
| 796 | |
| 797 | WebCore::Frame* coreFrame = m_frame->coreFrame(); |
| 798 | auto* policyDocumentLoader = coreFrame ? coreFrame->loader().provisionalDocumentLoader() : nullptr; |
| 799 | auto navigationID = policyDocumentLoader ? static_cast<WebDocumentLoader&>(*policyDocumentLoader).navigationID() : 0; |
| 800 | |
| 801 | Ref<WebFrame> protector(*m_frame); |
| 802 | uint64_t listenerID = m_frame->setUpPolicyListener(identifier, WTFMove(function), WebFrame::ForNavigationAction::No); |
| 803 | if (!webPage->send(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), identifier, navigationID, response, request, |
| 804 | canShowResponse, downloadAttribute, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())))) |
| 805 | m_frame->didReceivePolicyDecision(listenerID, identifier, PolicyAction::Ignore, 0, { }, { }); |
| 806 | } |
| 807 | |
| 808 | void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(const NavigationAction& navigationAction, const ResourceRequest& request, |
| 809 | FormState* formState, const String& frameName, WebCore::PolicyCheckIdentifier identifier, FramePolicyFunction&& function) |
| 810 | { |
| 811 | WebPage* webPage = m_frame ? m_frame->page() : nullptr; |
| 812 | if (!webPage) { |
| 813 | function(PolicyAction::Ignore, identifier); |
| 814 | return; |
| 815 | } |
| 816 | |
| 817 | RefPtr<API::Object> userData; |
| 818 | |
| 819 | auto action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState); |
| 820 | |
| 821 | // Notify the bundle client. |
| 822 | WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.ptr(), request, frameName, userData); |
| 823 | if (policy == WKBundlePagePolicyActionUse) { |
| 824 | function(PolicyAction::Use, identifier); |
| 825 | return; |
| 826 | } |
| 827 | |
| 828 | uint64_t listenerID = m_frame->setUpPolicyListener(identifier, WTFMove(function), WebFrame::ForNavigationAction::No); |
| 829 | |
| 830 | NavigationActionData navigationActionData; |
| 831 | navigationActionData.navigationType = action->navigationType(); |
| 832 | navigationActionData.modifiers = action->modifiers(); |
| 833 | navigationActionData.mouseButton = action->mouseButton(); |
| 834 | navigationActionData.syntheticClickType = action->syntheticClickType(); |
| 835 | navigationActionData.clickLocationInRootViewCoordinates = action->clickLocationInRootViewCoordinates(); |
| 836 | navigationActionData.userGestureTokenIdentifier = WebProcess::singleton().userGestureTokenIdentifier(navigationAction.userGestureToken()); |
| 837 | navigationActionData.canHandleRequest = webPage->canHandleRequest(request); |
| 838 | navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy(); |
| 839 | navigationActionData.downloadAttribute = navigationAction.downloadAttribute(); |
| 840 | |
| 841 | WebCore::Frame* coreFrame = m_frame ? m_frame->coreFrame() : nullptr; |
| 842 | webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), identifier, navigationActionData, request, |
| 843 | frameName, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 844 | } |
| 845 | |
| 846 | void WebFrameLoaderClient::applyToDocumentLoader(WebsitePoliciesData&& websitePolicies) |
| 847 | { |
| 848 | if (!m_frame) |
| 849 | return; |
| 850 | auto* coreFrame = m_frame->coreFrame(); |
| 851 | if (!coreFrame) |
| 852 | return; |
| 853 | WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().policyDocumentLoader()); |
| 854 | if (!documentLoader) |
| 855 | documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().provisionalDocumentLoader()); |
| 856 | if (!documentLoader) |
| 857 | documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader()); |
| 858 | if (!documentLoader) |
| 859 | return; |
| 860 | |
| 861 | WebsitePoliciesData::applyToDocumentLoader(WTFMove(websitePolicies), *documentLoader); |
| 862 | } |
| 863 | |
| 864 | void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(const NavigationAction& navigationAction, const ResourceRequest& request, const ResourceResponse& redirectResponse, |
| 865 | FormState* formState, PolicyDecisionMode policyDecisionMode, WebCore::PolicyCheckIdentifier requestIdentifier, FramePolicyFunction&& function) |
| 866 | { |
| 867 | WebPage* webPage = m_frame ? m_frame->page() : nullptr; |
| 868 | if (!webPage) { |
| 869 | function(PolicyAction::Ignore, requestIdentifier); |
| 870 | return; |
| 871 | } |
| 872 | |
| 873 | LOG(Loading, "WebProcess %i - dispatchDecidePolicyForNavigationAction to request url %s" , getCurrentProcessID(), request.url().string().utf8().data()); |
| 874 | |
| 875 | // Always ignore requests with empty URLs. |
| 876 | if (request.isEmpty()) { |
| 877 | function(PolicyAction::Ignore, requestIdentifier); |
| 878 | return; |
| 879 | } |
| 880 | |
| 881 | RefPtr<API::Object> userData; |
| 882 | |
| 883 | Ref<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState); |
| 884 | |
| 885 | // Notify the bundle client. |
| 886 | WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.ptr(), request, userData); |
| 887 | if (policy == WKBundlePagePolicyActionUse) { |
| 888 | function(PolicyAction::Use, requestIdentifier); |
| 889 | return; |
| 890 | } |
| 891 | |
| 892 | uint64_t listenerID = m_frame->setUpPolicyListener(requestIdentifier, WTFMove(function), WebFrame::ForNavigationAction::Yes); |
| 893 | |
| 894 | ASSERT(navigationAction.requester()); |
| 895 | auto requester = navigationAction.requester().value(); |
| 896 | |
| 897 | FrameInfoData originatingFrameInfoData; |
| 898 | originatingFrameInfoData.isMainFrame = navigationAction.initiatedByMainFrame() == InitiatedByMainFrame::Yes; |
| 899 | originatingFrameInfoData.request = ResourceRequest { requester.url() }; |
| 900 | originatingFrameInfoData.securityOrigin = requester.securityOrigin().data(); |
| 901 | if (requester.frameID() && WebProcess::singleton().webFrame(requester.frameID())) |
| 902 | originatingFrameInfoData.frameID = requester.frameID(); |
| 903 | |
| 904 | uint64_t originatingPageID = requester.pageID() && WebProcess::singleton().webPage(requester.pageID()) ? requester.pageID() : 0; |
| 905 | |
| 906 | NavigationActionData navigationActionData; |
| 907 | navigationActionData.navigationType = action->navigationType(); |
| 908 | navigationActionData.modifiers = action->modifiers(); |
| 909 | navigationActionData.mouseButton = action->mouseButton(); |
| 910 | navigationActionData.syntheticClickType = action->syntheticClickType(); |
| 911 | navigationActionData.clickLocationInRootViewCoordinates = action->clickLocationInRootViewCoordinates(); |
| 912 | navigationActionData.userGestureTokenIdentifier = WebProcess::singleton().userGestureTokenIdentifier(navigationAction.userGestureToken()); |
| 913 | navigationActionData.canHandleRequest = webPage->canHandleRequest(request); |
| 914 | navigationActionData.shouldOpenExternalURLsPolicy = navigationAction.shouldOpenExternalURLsPolicy(); |
| 915 | navigationActionData.downloadAttribute = navigationAction.downloadAttribute(); |
| 916 | navigationActionData.isRedirect = !redirectResponse.isNull(); |
| 917 | navigationActionData.treatAsSameOriginNavigation = navigationAction.treatAsSameOriginNavigation(); |
| 918 | navigationActionData.hasOpenedFrames = navigationAction.hasOpenedFrames(); |
| 919 | navigationActionData.openedByDOMWithOpener = navigationAction.openedByDOMWithOpener(); |
| 920 | if (auto& requester = navigationAction.requester()) |
| 921 | navigationActionData.requesterOrigin = requester->securityOrigin().data(); |
| 922 | navigationActionData.targetBackForwardItemIdentifier = navigationAction.targetBackForwardItemIdentifier(); |
| 923 | navigationActionData.sourceBackForwardItemIdentifier = navigationAction.sourceBackForwardItemIdentifier(); |
| 924 | navigationActionData.lockHistory = navigationAction.lockHistory(); |
| 925 | navigationActionData.lockBackForwardList = navigationAction.lockBackForwardList(); |
| 926 | navigationActionData.adClickAttribution = navigationAction.adClickAttribution(); |
| 927 | |
| 928 | WebCore::Frame* coreFrame = m_frame->coreFrame(); |
| 929 | if (!coreFrame) |
| 930 | return function(PolicyAction::Ignore, requestIdentifier); |
| 931 | WebDocumentLoader* documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().policyDocumentLoader()); |
| 932 | if (!documentLoader) { |
| 933 | // FIXME: When we receive a redirect after the navigation policy has been decided for the initial request, |
| 934 | // the provisional load's DocumentLoader needs to receive navigation policy decisions. We need a better model for this state. |
| 935 | documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().provisionalDocumentLoader()); |
| 936 | } |
| 937 | if (!documentLoader) |
| 938 | documentLoader = static_cast<WebDocumentLoader*>(coreFrame->loader().documentLoader()); |
| 939 | |
| 940 | navigationActionData.clientRedirectSourceForHistory = documentLoader->clientRedirectSourceForHistory(); |
| 941 | |
| 942 | // Notify the UIProcess. |
| 943 | Ref<WebFrame> protect(*m_frame); |
| 944 | |
| 945 | if (policyDecisionMode == PolicyDecisionMode::Synchronous) { |
| 946 | uint64_t newNavigationID; |
| 947 | WebCore::PolicyCheckIdentifier responseIdentifier; |
| 948 | PolicyAction policyAction; |
| 949 | DownloadID downloadID; |
| 950 | Optional<WebsitePoliciesData> websitePolicies; |
| 951 | |
| 952 | if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationActionSync(m_frame->frameID(), m_frame->isMainFrame(), SecurityOriginData::fromFrame(coreFrame), |
| 953 | requestIdentifier, documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingPageID, navigationAction.resourceRequest(), request, |
| 954 | IPC::FormDataReference { request.httpBody() }, redirectResponse, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get())), |
| 955 | Messages::WebPageProxy::DecidePolicyForNavigationActionSync::Reply(responseIdentifier, policyAction, newNavigationID, downloadID, websitePolicies))) { |
| 956 | m_frame->didReceivePolicyDecision(listenerID, requestIdentifier, PolicyAction::Ignore, 0, { }, { }); |
| 957 | return; |
| 958 | } |
| 959 | |
| 960 | m_frame->didReceivePolicyDecision(listenerID, responseIdentifier, policyAction, 0, downloadID, { }); |
| 961 | return; |
| 962 | } |
| 963 | |
| 964 | ASSERT(policyDecisionMode == PolicyDecisionMode::Asynchronous); |
| 965 | if (!webPage->send(Messages::WebPageProxy::DecidePolicyForNavigationActionAsync(m_frame->frameID(), SecurityOriginData::fromFrame(coreFrame), |
| 966 | requestIdentifier, documentLoader->navigationID(), navigationActionData, originatingFrameInfoData, originatingPageID, navigationAction.resourceRequest(), request, |
| 967 | IPC::FormDataReference { request.httpBody() }, redirectResponse, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()), listenerID))) |
| 968 | m_frame->didReceivePolicyDecision(listenerID, requestIdentifier, PolicyAction::Ignore, 0, { }, { }); |
| 969 | } |
| 970 | |
| 971 | void WebFrameLoaderClient::cancelPolicyCheck() |
| 972 | { |
| 973 | m_frame->invalidatePolicyListener(); |
| 974 | } |
| 975 | |
| 976 | void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error) |
| 977 | { |
| 978 | WebPage* webPage = m_frame->page(); |
| 979 | if (!webPage) |
| 980 | return; |
| 981 | |
| 982 | RefPtr<API::Object> userData; |
| 983 | |
| 984 | // Notify the bundle client. |
| 985 | webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData); |
| 986 | |
| 987 | // Notify the UIProcess. |
| 988 | webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 989 | } |
| 990 | |
| 991 | void WebFrameLoaderClient::dispatchWillSendSubmitEvent(Ref<FormState>&& formState) |
| 992 | { |
| 993 | auto* webPage = m_frame->page(); |
| 994 | if (!webPage) |
| 995 | return; |
| 996 | |
| 997 | auto& form = formState->form(); |
| 998 | |
| 999 | ASSERT(formState->sourceDocument().frame()); |
| 1000 | auto* sourceFrame = WebFrame::fromCoreFrame(*formState->sourceDocument().frame()); |
| 1001 | ASSERT(sourceFrame); |
| 1002 | |
| 1003 | webPage->injectedBundleFormClient().willSendSubmitEvent(webPage, &form, m_frame, sourceFrame, formState->textFieldValues()); |
| 1004 | } |
| 1005 | |
| 1006 | void WebFrameLoaderClient::dispatchWillSubmitForm(FormState& formState, CompletionHandler<void()>&& completionHandler) |
| 1007 | { |
| 1008 | WebPage* webPage = m_frame->page(); |
| 1009 | if (!webPage) { |
| 1010 | completionHandler(); |
| 1011 | return; |
| 1012 | } |
| 1013 | |
| 1014 | auto& form = formState.form(); |
| 1015 | |
| 1016 | auto* sourceCoreFrame = formState.sourceDocument().frame(); |
| 1017 | if (!sourceCoreFrame) |
| 1018 | return completionHandler(); |
| 1019 | auto* sourceFrame = WebFrame::fromCoreFrame(*sourceCoreFrame); |
| 1020 | if (!sourceFrame) |
| 1021 | return completionHandler(); |
| 1022 | |
| 1023 | auto& values = formState.textFieldValues(); |
| 1024 | |
| 1025 | RefPtr<API::Object> userData; |
| 1026 | webPage->injectedBundleFormClient().willSubmitForm(webPage, &form, m_frame, sourceFrame, values, userData); |
| 1027 | |
| 1028 | uint64_t listenerID = m_frame->setUpWillSubmitFormListener(WTFMove(completionHandler)); |
| 1029 | |
| 1030 | webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), values, listenerID, UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 1031 | } |
| 1032 | |
| 1033 | void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*) |
| 1034 | { |
| 1035 | notImplemented(); |
| 1036 | } |
| 1037 | |
| 1038 | void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error) |
| 1039 | { |
| 1040 | if (!m_pluginView) |
| 1041 | return; |
| 1042 | |
| 1043 | m_pluginView->manualLoadDidFail(error); |
| 1044 | m_pluginView = nullptr; |
| 1045 | m_hasSentResponseToPluginView = false; |
| 1046 | } |
| 1047 | |
| 1048 | void WebFrameLoaderClient::setMainFrameDocumentReady(bool) |
| 1049 | { |
| 1050 | notImplemented(); |
| 1051 | } |
| 1052 | |
| 1053 | void WebFrameLoaderClient::startDownload(const ResourceRequest& request, const String& suggestedName) |
| 1054 | { |
| 1055 | m_frame->startDownload(request, suggestedName); |
| 1056 | } |
| 1057 | |
| 1058 | void WebFrameLoaderClient::willChangeTitle(DocumentLoader*) |
| 1059 | { |
| 1060 | notImplemented(); |
| 1061 | } |
| 1062 | |
| 1063 | void WebFrameLoaderClient::didChangeTitle(DocumentLoader*) |
| 1064 | { |
| 1065 | notImplemented(); |
| 1066 | } |
| 1067 | |
| 1068 | void WebFrameLoaderClient::willReplaceMultipartContent() |
| 1069 | { |
| 1070 | WebPage* webPage = m_frame->page(); |
| 1071 | if (!webPage) |
| 1072 | return; |
| 1073 | webPage->willReplaceMultipartContent(*m_frame); |
| 1074 | } |
| 1075 | |
| 1076 | void WebFrameLoaderClient::didReplaceMultipartContent() |
| 1077 | { |
| 1078 | WebPage* webPage = m_frame->page(); |
| 1079 | if (!webPage) |
| 1080 | return; |
| 1081 | webPage->didReplaceMultipartContent(*m_frame); |
| 1082 | } |
| 1083 | |
| 1084 | void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length) |
| 1085 | { |
| 1086 | if (!m_pluginView) |
| 1087 | loader->commitData(data, length); |
| 1088 | |
| 1089 | // If the document is a stand-alone media document, now is the right time to cancel the WebKit load. |
| 1090 | // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>. |
| 1091 | if (m_frame->coreFrame()->document()->isMediaDocument()) |
| 1092 | loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response())); |
| 1093 | |
| 1094 | // Calling commitData did not create the plug-in view. |
| 1095 | if (!m_pluginView) |
| 1096 | return; |
| 1097 | |
| 1098 | if (!m_hasSentResponseToPluginView) { |
| 1099 | m_pluginView->manualLoadDidReceiveResponse(loader->response()); |
| 1100 | // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in |
| 1101 | // setting up this stream can cause the main document load to be cancelled, setting m_pluginView |
| 1102 | // to null |
| 1103 | if (!m_pluginView) |
| 1104 | return; |
| 1105 | m_hasSentResponseToPluginView = true; |
| 1106 | } |
| 1107 | m_pluginView->manualLoadDidReceiveData(data, length); |
| 1108 | } |
| 1109 | |
| 1110 | void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader) |
| 1111 | { |
| 1112 | if (!m_pluginView) { |
| 1113 | if (m_frameHasCustomContentProvider) { |
| 1114 | WebPage* webPage = m_frame->page(); |
| 1115 | if (!webPage) |
| 1116 | return; |
| 1117 | |
| 1118 | RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData(); |
| 1119 | IPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0); |
| 1120 | webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomContentProvider(loader->response().suggestedFilename(), dataReference)); |
| 1121 | } |
| 1122 | |
| 1123 | return; |
| 1124 | } |
| 1125 | |
| 1126 | // If we just received an empty response without any data, we won't have sent a response to the plug-in view. |
| 1127 | // Make sure to do this before calling manualLoadDidFinishLoading. |
| 1128 | if (!m_hasSentResponseToPluginView) { |
| 1129 | m_pluginView->manualLoadDidReceiveResponse(loader->response()); |
| 1130 | |
| 1131 | // Protect against the above call nulling out the plug-in (by trying to cancel the load for example). |
| 1132 | if (!m_pluginView) |
| 1133 | return; |
| 1134 | } |
| 1135 | |
| 1136 | m_pluginView->manualLoadDidFinishLoading(); |
| 1137 | m_pluginView = nullptr; |
| 1138 | m_hasSentResponseToPluginView = false; |
| 1139 | } |
| 1140 | |
| 1141 | void WebFrameLoaderClient::updateGlobalHistory() |
| 1142 | { |
| 1143 | WebPage* webPage = m_frame->page(); |
| 1144 | if (!webPage) |
| 1145 | return; |
| 1146 | |
| 1147 | DocumentLoader* loader = m_frame->coreFrame()->loader().documentLoader(); |
| 1148 | |
| 1149 | WebNavigationDataStore data; |
| 1150 | data.url = loader->url().string(); |
| 1151 | // FIXME: Use direction of title. |
| 1152 | data.title = loader->title().string; |
| 1153 | data.originalRequest = loader->originalRequestCopy(); |
| 1154 | data.response = loader->response(); |
| 1155 | |
| 1156 | webPage->send(Messages::WebPageProxy::DidNavigateWithNavigationData(data, m_frame->frameID())); |
| 1157 | } |
| 1158 | |
| 1159 | void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks() |
| 1160 | { |
| 1161 | WebPage* webPage = m_frame->page(); |
| 1162 | if (!webPage) |
| 1163 | return; |
| 1164 | |
| 1165 | DocumentLoader* loader = m_frame->coreFrame()->loader().documentLoader(); |
| 1166 | ASSERT(loader->unreachableURL().isEmpty()); |
| 1167 | |
| 1168 | // Client redirect |
| 1169 | if (!loader->clientRedirectSourceForHistory().isNull()) { |
| 1170 | webPage->send(Messages::WebPageProxy::DidPerformClientRedirect( |
| 1171 | loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID())); |
| 1172 | } |
| 1173 | |
| 1174 | // Server redirect |
| 1175 | if (!loader->serverRedirectSourceForHistory().isNull()) { |
| 1176 | webPage->send(Messages::WebPageProxy::DidPerformServerRedirect( |
| 1177 | loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID())); |
| 1178 | } |
| 1179 | } |
| 1180 | |
| 1181 | bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem& item) const |
| 1182 | { |
| 1183 | WebPage* webPage = m_frame->page(); |
| 1184 | if (!webPage) |
| 1185 | return false; |
| 1186 | webPage->send(Messages::WebPageProxy::WillGoToBackForwardListItem(item.identifier(), item.isInPageCache())); |
| 1187 | return true; |
| 1188 | } |
| 1189 | |
| 1190 | void WebFrameLoaderClient::didDisplayInsecureContent() |
| 1191 | { |
| 1192 | WebPage* webPage = m_frame->page(); |
| 1193 | if (!webPage) |
| 1194 | return; |
| 1195 | |
| 1196 | RefPtr<API::Object> userData; |
| 1197 | |
| 1198 | webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(*webPage, *m_frame, userData); |
| 1199 | |
| 1200 | webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 1201 | } |
| 1202 | |
| 1203 | void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin&, const URL&) |
| 1204 | { |
| 1205 | WebPage* webPage = m_frame->page(); |
| 1206 | if (!webPage) |
| 1207 | return; |
| 1208 | |
| 1209 | RefPtr<API::Object> userData; |
| 1210 | |
| 1211 | webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(*webPage, *m_frame, userData); |
| 1212 | |
| 1213 | webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 1214 | } |
| 1215 | |
| 1216 | void WebFrameLoaderClient::didDetectXSS(const URL&, bool) |
| 1217 | { |
| 1218 | WebPage* webPage = m_frame->page(); |
| 1219 | if (!webPage) |
| 1220 | return; |
| 1221 | |
| 1222 | RefPtr<API::Object> userData; |
| 1223 | |
| 1224 | webPage->injectedBundleLoaderClient().didDetectXSSForFrame(*webPage, *m_frame, userData); |
| 1225 | |
| 1226 | webPage->send(Messages::WebPageProxy::DidDetectXSSForFrame(m_frame->frameID(), UserData(WebProcess::singleton().transformObjectsToHandles(userData.get()).get()))); |
| 1227 | } |
| 1228 | |
| 1229 | ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request) |
| 1230 | { |
| 1231 | return WebKit::cancelledError(request); |
| 1232 | } |
| 1233 | |
| 1234 | ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request) |
| 1235 | { |
| 1236 | return WebKit::blockedError(request); |
| 1237 | } |
| 1238 | |
| 1239 | ResourceError WebFrameLoaderClient::blockedByContentBlockerError(const ResourceRequest& request) |
| 1240 | { |
| 1241 | return WebKit::blockedByContentBlockerError(request); |
| 1242 | } |
| 1243 | |
| 1244 | ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request) |
| 1245 | { |
| 1246 | return WebKit::cannotShowURLError(request); |
| 1247 | } |
| 1248 | |
| 1249 | ResourceError WebFrameLoaderClient::interruptedForPolicyChangeError(const ResourceRequest& request) |
| 1250 | { |
| 1251 | return WebKit::interruptedForPolicyChangeError(request); |
| 1252 | } |
| 1253 | |
| 1254 | #if ENABLE(CONTENT_FILTERING) |
| 1255 | ResourceError WebFrameLoaderClient::blockedByContentFilterError(const ResourceRequest& request) |
| 1256 | { |
| 1257 | return WebKit::blockedByContentFilterError(request); |
| 1258 | } |
| 1259 | #endif |
| 1260 | |
| 1261 | ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response) |
| 1262 | { |
| 1263 | return WebKit::cannotShowMIMETypeError(response); |
| 1264 | } |
| 1265 | |
| 1266 | ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response) |
| 1267 | { |
| 1268 | return WebKit::fileDoesNotExistError(response); |
| 1269 | } |
| 1270 | |
| 1271 | ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response) |
| 1272 | { |
| 1273 | return WebKit::pluginWillHandleLoadError(response); |
| 1274 | } |
| 1275 | |
| 1276 | bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error) |
| 1277 | { |
| 1278 | static NeverDestroyed<const ResourceError> cancelledError(this->cancelledError(ResourceRequest())); |
| 1279 | static NeverDestroyed<const ResourceError> pluginWillHandleLoadError(this->pluginWillHandleLoadError(ResourceResponse())); |
| 1280 | |
| 1281 | if (error.errorCode() == cancelledError.get().errorCode() && error.domain() == cancelledError.get().domain()) |
| 1282 | return false; |
| 1283 | |
| 1284 | if (error.errorCode() == pluginWillHandleLoadError.get().errorCode() && error.domain() == pluginWillHandleLoadError.get().domain()) |
| 1285 | return false; |
| 1286 | |
| 1287 | return true; |
| 1288 | } |
| 1289 | |
| 1290 | bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const |
| 1291 | { |
| 1292 | notImplemented(); |
| 1293 | return true; |
| 1294 | } |
| 1295 | |
| 1296 | bool WebFrameLoaderClient::canShowMIMEType(const String& /*MIMEType*/) const |
| 1297 | { |
| 1298 | notImplemented(); |
| 1299 | return true; |
| 1300 | } |
| 1301 | |
| 1302 | bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& /*MIMEType*/) const |
| 1303 | { |
| 1304 | return true; |
| 1305 | } |
| 1306 | |
| 1307 | bool WebFrameLoaderClient::representationExistsForURLScheme(const String& /*URLScheme*/) const |
| 1308 | { |
| 1309 | notImplemented(); |
| 1310 | return false; |
| 1311 | } |
| 1312 | |
| 1313 | String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& /*URLScheme*/) const |
| 1314 | { |
| 1315 | notImplemented(); |
| 1316 | return String(); |
| 1317 | } |
| 1318 | |
| 1319 | void WebFrameLoaderClient::frameLoadCompleted() |
| 1320 | { |
| 1321 | // Note: Can be called multiple times. |
| 1322 | WebPage* webPage = m_frame->page(); |
| 1323 | if (!webPage) |
| 1324 | return; |
| 1325 | |
| 1326 | if (m_frame->isMainFrame() && !m_didCompletePageTransition) { |
| 1327 | webPage->didCompletePageTransition(); |
| 1328 | m_didCompletePageTransition = true; |
| 1329 | } |
| 1330 | } |
| 1331 | |
| 1332 | void WebFrameLoaderClient::saveViewStateToItem(HistoryItem& historyItem) |
| 1333 | { |
| 1334 | #if PLATFORM(IOS_FAMILY) |
| 1335 | if (m_frame->isMainFrame()) |
| 1336 | m_frame->page()->savePageState(historyItem); |
| 1337 | #else |
| 1338 | UNUSED_PARAM(historyItem); |
| 1339 | #endif |
| 1340 | } |
| 1341 | |
| 1342 | void WebFrameLoaderClient::restoreViewState() |
| 1343 | { |
| 1344 | #if PLATFORM(IOS_FAMILY) |
| 1345 | Frame& frame = *m_frame->coreFrame(); |
| 1346 | HistoryItem* currentItem = frame.loader().history().currentItem(); |
| 1347 | if (FrameView* view = frame.view()) { |
| 1348 | if (m_frame->isMainFrame()) |
| 1349 | m_frame->page()->restorePageState(*currentItem); |
| 1350 | else if (!view->wasScrolledByUser()) |
| 1351 | view->setScrollPosition(currentItem->scrollPosition()); |
| 1352 | } |
| 1353 | #else |
| 1354 | // Inform the UI process of the scale factor. |
| 1355 | double scaleFactor = m_frame->coreFrame()->loader().history().currentItem()->pageScaleFactor(); |
| 1356 | |
| 1357 | // A scale factor of 0 means the history item has the default scale factor, thus we do not need to update it. |
| 1358 | if (scaleFactor) |
| 1359 | m_frame->page()->send(Messages::WebPageProxy::PageScaleFactorDidChange(scaleFactor)); |
| 1360 | |
| 1361 | // FIXME: This should not be necessary. WebCore should be correctly invalidating |
| 1362 | // the view on restores from the back/forward cache. |
| 1363 | if (m_frame->page() && m_frame == m_frame->page()->mainWebFrame()) |
| 1364 | m_frame->page()->drawingArea()->setNeedsDisplay(); |
| 1365 | #endif |
| 1366 | } |
| 1367 | |
| 1368 | void WebFrameLoaderClient::provisionalLoadStarted() |
| 1369 | { |
| 1370 | WebPage* webPage = m_frame->page(); |
| 1371 | if (!webPage) |
| 1372 | return; |
| 1373 | |
| 1374 | if (m_frame->isMainFrame()) { |
| 1375 | webPage->didStartPageTransition(); |
| 1376 | m_didCompletePageTransition = false; |
| 1377 | } |
| 1378 | } |
| 1379 | |
| 1380 | void WebFrameLoaderClient::didFinishLoad() |
| 1381 | { |
| 1382 | // If we have a load listener, notify it. |
| 1383 | if (WebFrame::LoadListener* loadListener = m_frame->loadListener()) |
| 1384 | loadListener->didFinishLoad(m_frame); |
| 1385 | } |
| 1386 | |
| 1387 | void WebFrameLoaderClient::prepareForDataSourceReplacement() |
| 1388 | { |
| 1389 | notImplemented(); |
| 1390 | } |
| 1391 | |
| 1392 | Ref<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData) |
| 1393 | { |
| 1394 | return m_frame->page()->createDocumentLoader(*m_frame->coreFrame(), request, substituteData); |
| 1395 | } |
| 1396 | |
| 1397 | void WebFrameLoaderClient::updateCachedDocumentLoader(WebCore::DocumentLoader& loader) |
| 1398 | { |
| 1399 | m_frame->page()->updateCachedDocumentLoader(static_cast<WebDocumentLoader&>(loader), *m_frame->coreFrame()); |
| 1400 | } |
| 1401 | |
| 1402 | void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const URL& url) |
| 1403 | { |
| 1404 | WebPage* webPage = m_frame->page(); |
| 1405 | if (!webPage) |
| 1406 | return; |
| 1407 | |
| 1408 | // FIXME: Use direction of title. |
| 1409 | webPage->send(Messages::WebPageProxy::DidUpdateHistoryTitle(title.string, url.string(), m_frame->frameID())); |
| 1410 | } |
| 1411 | |
| 1412 | String WebFrameLoaderClient::userAgent(const URL& url) |
| 1413 | { |
| 1414 | auto* webPage = m_frame->page(); |
| 1415 | if (!webPage) |
| 1416 | return String(); |
| 1417 | |
| 1418 | return webPage->userAgent(url); |
| 1419 | } |
| 1420 | |
| 1421 | String WebFrameLoaderClient::overrideContentSecurityPolicy() const |
| 1422 | { |
| 1423 | WebPage* webPage = m_frame->page(); |
| 1424 | if (!webPage) |
| 1425 | return String(); |
| 1426 | |
| 1427 | return webPage->overrideContentSecurityPolicy(); |
| 1428 | } |
| 1429 | |
| 1430 | void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame) |
| 1431 | { |
| 1432 | WebPage* webPage = m_frame->page(); |
| 1433 | if (!webPage) |
| 1434 | return; |
| 1435 | |
| 1436 | HasInsecureContent hasInsecureContent; |
| 1437 | if (webPage->sendSync(Messages::WebPageProxy::HasInsecureContent(), Messages::WebPageProxy::HasInsecureContent::Reply(hasInsecureContent))) |
| 1438 | cachedFrame->setHasInsecureContent(hasInsecureContent); |
| 1439 | } |
| 1440 | |
| 1441 | void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*) |
| 1442 | { |
| 1443 | const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response(); |
| 1444 | m_frameHasCustomContentProvider = m_frame->isMainFrame() && m_frame->page()->shouldUseCustomContentProviderForResponse(response); |
| 1445 | m_frameCameFromPageCache = true; |
| 1446 | } |
| 1447 | |
| 1448 | void WebFrameLoaderClient::transitionToCommittedForNewPage() |
| 1449 | { |
| 1450 | WebPage* webPage = m_frame->page(); |
| 1451 | |
| 1452 | bool isMainFrame = m_frame->isMainFrame(); |
| 1453 | bool shouldUseFixedLayout = isMainFrame && webPage->useFixedLayout(); |
| 1454 | bool shouldDisableScrolling = isMainFrame && !webPage->mainFrameIsScrollable(); |
| 1455 | bool shouldHideScrollbars = shouldDisableScrolling; |
| 1456 | IntRect fixedVisibleContentRect; |
| 1457 | |
| 1458 | #if USE(COORDINATED_GRAPHICS) |
| 1459 | if (m_frame->coreFrame()->view()) |
| 1460 | fixedVisibleContentRect = m_frame->coreFrame()->view()->fixedVisibleContentRect(); |
| 1461 | if (shouldUseFixedLayout) |
| 1462 | shouldHideScrollbars = true; |
| 1463 | #endif |
| 1464 | |
| 1465 | const ResourceResponse& response = m_frame->coreFrame()->loader().documentLoader()->response(); |
| 1466 | m_frameHasCustomContentProvider = isMainFrame && webPage->shouldUseCustomContentProviderForResponse(response); |
| 1467 | m_frameCameFromPageCache = false; |
| 1468 | |
| 1469 | ScrollbarMode defaultScrollbarMode = shouldHideScrollbars ? ScrollbarAlwaysOff : ScrollbarAuto; |
| 1470 | |
| 1471 | ScrollbarMode horizontalScrollbarMode = webPage->alwaysShowsHorizontalScroller() ? ScrollbarAlwaysOn : defaultScrollbarMode; |
| 1472 | ScrollbarMode verticalScrollbarMode = webPage->alwaysShowsVerticalScroller() ? ScrollbarAlwaysOn : defaultScrollbarMode; |
| 1473 | |
| 1474 | bool horizontalLock = shouldHideScrollbars || webPage->alwaysShowsHorizontalScroller(); |
| 1475 | bool verticalLock = shouldHideScrollbars || webPage->alwaysShowsVerticalScroller(); |
| 1476 | |
| 1477 | m_frame->coreFrame()->createView(webPage->size(), webPage->backgroundColor(), |
| 1478 | webPage->fixedLayoutSize(), fixedVisibleContentRect, shouldUseFixedLayout, |
| 1479 | horizontalScrollbarMode, horizontalLock, verticalScrollbarMode, verticalLock); |
| 1480 | |
| 1481 | if (int viewLayoutWidth = webPage->viewLayoutSize().width()) { |
| 1482 | int viewLayoutHeight = std::max(webPage->viewLayoutSize().height(), 1); |
| 1483 | m_frame->coreFrame()->view()->enableAutoSizeMode(true, { viewLayoutWidth, viewLayoutHeight }); |
| 1484 | |
| 1485 | if (webPage->autoSizingShouldExpandToViewHeight()) |
| 1486 | m_frame->coreFrame()->view()->setAutoSizeFixedMinimumHeight(webPage->size().height()); |
| 1487 | } |
| 1488 | |
| 1489 | if (auto viewportSizeForViewportUnits = webPage->viewportSizeForCSSViewportUnits()) |
| 1490 | m_frame->coreFrame()->view()->setViewportSizeForCSSViewportUnits(*viewportSizeForViewportUnits); |
| 1491 | m_frame->coreFrame()->view()->setProhibitsScrolling(shouldDisableScrolling); |
| 1492 | m_frame->coreFrame()->view()->setVisualUpdatesAllowedByClient(!webPage->shouldExtendIncrementalRenderingSuppression()); |
| 1493 | #if PLATFORM(COCOA) |
| 1494 | m_frame->coreFrame()->view()->setViewExposedRect(webPage->drawingArea()->viewExposedRect()); |
| 1495 | #endif |
| 1496 | #if PLATFORM(IOS_FAMILY) |
| 1497 | if (isMainFrame) |
| 1498 | m_frame->coreFrame()->view()->setDelegatesScrolling(true); |
| 1499 | #endif |
| 1500 | |
| 1501 | if (webPage->scrollPinningBehavior() != DoNotPin) |
| 1502 | m_frame->coreFrame()->view()->setScrollPinningBehavior(webPage->scrollPinningBehavior()); |
| 1503 | |
| 1504 | #if USE(COORDINATED_GRAPHICS) |
| 1505 | if (shouldUseFixedLayout) { |
| 1506 | m_frame->coreFrame()->view()->setDelegatesScrolling(shouldUseFixedLayout); |
| 1507 | m_frame->coreFrame()->view()->setPaintsEntireContents(shouldUseFixedLayout); |
| 1508 | return; |
| 1509 | } |
| 1510 | #endif |
| 1511 | } |
| 1512 | |
| 1513 | void WebFrameLoaderClient::didSaveToPageCache() |
| 1514 | { |
| 1515 | WebPage* webPage = m_frame->page(); |
| 1516 | if (!webPage) |
| 1517 | return; |
| 1518 | |
| 1519 | if (m_frame->isMainFrame()) |
| 1520 | webPage->send(Messages::WebPageProxy::DidSaveToPageCache()); |
| 1521 | } |
| 1522 | |
| 1523 | void WebFrameLoaderClient::didRestoreFromPageCache() |
| 1524 | { |
| 1525 | m_frameCameFromPageCache = true; |
| 1526 | } |
| 1527 | |
| 1528 | void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value) |
| 1529 | { |
| 1530 | WebPage* webPage = m_frame->page(); |
| 1531 | if (!webPage) |
| 1532 | return; |
| 1533 | |
| 1534 | webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value)); |
| 1535 | } |
| 1536 | |
| 1537 | bool WebFrameLoaderClient::canCachePage() const |
| 1538 | { |
| 1539 | // We cannot cache frames that have custom representations because they are |
| 1540 | // rendered in the UIProcess. |
| 1541 | return !m_frameHasCustomContentProvider; |
| 1542 | } |
| 1543 | |
| 1544 | void WebFrameLoaderClient::convertMainResourceLoadToDownload(DocumentLoader *documentLoader, PAL::SessionID sessionID, const ResourceRequest& request, const ResourceResponse& response) |
| 1545 | { |
| 1546 | m_frame->convertMainResourceLoadToDownload(documentLoader, sessionID, request, response); |
| 1547 | } |
| 1548 | |
| 1549 | RefPtr<Frame> WebFrameLoaderClient::createFrame(const URL& url, const String& name, HTMLFrameOwnerElement& ownerElement, |
| 1550 | const String& referrer) |
| 1551 | { |
| 1552 | auto* webPage = m_frame->page(); |
| 1553 | |
| 1554 | auto subframe = WebFrame::createSubframe(webPage, name, &ownerElement); |
| 1555 | auto* coreSubframe = subframe->coreFrame(); |
| 1556 | if (!coreSubframe) |
| 1557 | return nullptr; |
| 1558 | |
| 1559 | // The creation of the frame may have run arbitrary JavaScript that removed it from the page already. |
| 1560 | if (!coreSubframe->page()) |
| 1561 | return nullptr; |
| 1562 | |
| 1563 | m_frame->coreFrame()->loader().loadURLIntoChildFrame(url, referrer, coreSubframe); |
| 1564 | |
| 1565 | // The frame's onload handler may have removed it from the document. |
| 1566 | if (!subframe->coreFrame()) |
| 1567 | return nullptr; |
| 1568 | ASSERT(subframe->coreFrame() == coreSubframe); |
| 1569 | if (!coreSubframe->tree().parent()) |
| 1570 | return nullptr; |
| 1571 | |
| 1572 | return coreSubframe; |
| 1573 | } |
| 1574 | |
| 1575 | RefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement& pluginElement, const URL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually) |
| 1576 | { |
| 1577 | ASSERT(paramNames.size() == paramValues.size()); |
| 1578 | ASSERT(m_frame->page()); |
| 1579 | |
| 1580 | Plugin::Parameters parameters; |
| 1581 | parameters.url = url; |
| 1582 | parameters.names = paramNames; |
| 1583 | parameters.values = paramValues; |
| 1584 | parameters.mimeType = mimeType; |
| 1585 | parameters.isFullFramePlugin = loadManually; |
| 1586 | parameters.shouldUseManualLoader = parameters.isFullFramePlugin && !m_frameCameFromPageCache; |
| 1587 | #if PLATFORM(COCOA) |
| 1588 | parameters.layerHostingMode = m_frame->page()->layerHostingMode(); |
| 1589 | #endif |
| 1590 | |
| 1591 | #if ENABLE(NETSCAPE_PLUGIN_API) |
| 1592 | auto plugin = m_frame->page()->createPlugin(m_frame, &pluginElement, parameters, parameters.mimeType); |
| 1593 | if (!plugin) |
| 1594 | return nullptr; |
| 1595 | |
| 1596 | return PluginView::create(pluginElement, plugin.releaseNonNull(), parameters); |
| 1597 | #else |
| 1598 | UNUSED_PARAM(pluginElement); |
| 1599 | return nullptr; |
| 1600 | #endif |
| 1601 | } |
| 1602 | |
| 1603 | void WebFrameLoaderClient::redirectDataToPlugin(Widget& pluginWidget) |
| 1604 | { |
| 1605 | m_pluginView = static_cast<PluginView*>(&pluginWidget); |
| 1606 | } |
| 1607 | |
| 1608 | #if ENABLE(WEBGL) |
| 1609 | |
| 1610 | WebCore::WebGLLoadPolicy WebFrameLoaderClient::webGLPolicyForURL(const URL& url) const |
| 1611 | { |
| 1612 | if (auto* webPage = m_frame->page()) |
| 1613 | return webPage->webGLPolicyForURL(m_frame, url); |
| 1614 | |
| 1615 | return WebGLAllowCreation; |
| 1616 | } |
| 1617 | |
| 1618 | WebCore::WebGLLoadPolicy WebFrameLoaderClient::resolveWebGLPolicyForURL(const URL& url) const |
| 1619 | { |
| 1620 | if (auto* webPage = m_frame->page()) |
| 1621 | return webPage->resolveWebGLPolicyForURL(m_frame, url); |
| 1622 | |
| 1623 | return WebGLAllowCreation; |
| 1624 | } |
| 1625 | |
| 1626 | #endif |
| 1627 | |
| 1628 | RefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement& appletElement, const URL&, const Vector<String>& paramNames, const Vector<String>& paramValues) |
| 1629 | { |
| 1630 | #if ENABLE(NETSCAPE_PLUGIN_API) |
| 1631 | auto plugin = createPlugin(pluginSize, appletElement, URL(), paramNames, paramValues, appletElement.serviceType(), false); |
| 1632 | if (!plugin) { |
| 1633 | if (auto* webPage = m_frame->page()) { |
| 1634 | auto frameURLString = m_frame->coreFrame()->loader().documentLoader()->responseURL().string(); |
| 1635 | auto pageURLString = webPage->corePage()->mainFrame().loader().documentLoader()->responseURL().string(); |
| 1636 | webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(appletElement.serviceType(), frameURLString, pageURLString)); |
| 1637 | } |
| 1638 | } |
| 1639 | return plugin; |
| 1640 | #else |
| 1641 | UNUSED_PARAM(pluginSize); |
| 1642 | UNUSED_PARAM(appletElement); |
| 1643 | UNUSED_PARAM(paramNames); |
| 1644 | UNUSED_PARAM(paramValues); |
| 1645 | return nullptr; |
| 1646 | #endif |
| 1647 | } |
| 1648 | |
| 1649 | static bool pluginSupportsExtension(const PluginData& pluginData, const String& extension) |
| 1650 | { |
| 1651 | ASSERT(extension.convertToASCIILowercase() == extension); |
| 1652 | Vector<MimeClassInfo> mimes; |
| 1653 | Vector<size_t> mimePluginIndices; |
| 1654 | pluginData.getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices); |
| 1655 | for (auto& mimeClassInfo : mimes) { |
| 1656 | if (mimeClassInfo.extensions.contains(extension)) |
| 1657 | return true; |
| 1658 | } |
| 1659 | return false; |
| 1660 | } |
| 1661 | |
| 1662 | ObjectContentType WebFrameLoaderClient::objectContentType(const URL& url, const String& mimeTypeIn) |
| 1663 | { |
| 1664 | // FIXME: This should eventually be merged with WebCore::FrameLoader::defaultObjectContentType. |
| 1665 | |
| 1666 | String mimeType = mimeTypeIn; |
| 1667 | if (mimeType.isEmpty()) { |
| 1668 | String path = url.path(); |
| 1669 | auto dotPosition = path.reverseFind('.'); |
| 1670 | if (dotPosition == notFound) |
| 1671 | return ObjectContentType::Frame; |
| 1672 | String extension = path.substring(dotPosition + 1).convertToASCIILowercase(); |
| 1673 | |
| 1674 | // Try to guess the MIME type from the extension. |
| 1675 | mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension); |
| 1676 | if (mimeType.isEmpty()) { |
| 1677 | // Check if there's a plug-in around that can handle the extension. |
| 1678 | if (WebPage* webPage = m_frame->page()) { |
| 1679 | if (pluginSupportsExtension(webPage->corePage()->pluginData(), extension)) |
| 1680 | return ObjectContentType::PlugIn; |
| 1681 | } |
| 1682 | return ObjectContentType::Frame; |
| 1683 | } |
| 1684 | } |
| 1685 | |
| 1686 | if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType)) |
| 1687 | return ObjectContentType::Image; |
| 1688 | |
| 1689 | if (WebPage* webPage = m_frame->page()) { |
| 1690 | auto allowedPluginTypes = webFrame()->coreFrame()->loader().subframeLoader().allowPlugins() |
| 1691 | ? PluginData::AllPlugins : PluginData::OnlyApplicationPlugins; |
| 1692 | if (webPage->corePage()->pluginData().supportsMimeType(mimeType, allowedPluginTypes)) |
| 1693 | return ObjectContentType::PlugIn; |
| 1694 | } |
| 1695 | |
| 1696 | if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType)) |
| 1697 | return ObjectContentType::Frame; |
| 1698 | |
| 1699 | #if PLATFORM(IOS_FAMILY) |
| 1700 | // iOS can render PDF in <object>/<embed> via PDFDocumentImage. |
| 1701 | if (MIMETypeRegistry::isPDFOrPostScriptMIMEType(mimeType)) |
| 1702 | return ObjectContentType::Image; |
| 1703 | #endif |
| 1704 | |
| 1705 | return ObjectContentType::None; |
| 1706 | } |
| 1707 | |
| 1708 | String WebFrameLoaderClient::overrideMediaType() const |
| 1709 | { |
| 1710 | notImplemented(); |
| 1711 | return String(); |
| 1712 | } |
| 1713 | |
| 1714 | void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld& world) |
| 1715 | { |
| 1716 | WebPage* webPage = m_frame->page(); |
| 1717 | if (!webPage) |
| 1718 | return; |
| 1719 | |
| 1720 | webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(*webPage, *m_frame, world); |
| 1721 | |
| 1722 | WebAutomationSessionProxy* automationSessionProxy = WebProcess::singleton().automationSessionProxy(); |
| 1723 | if (automationSessionProxy && world.isNormal()) |
| 1724 | automationSessionProxy->didClearWindowObjectForFrame(*m_frame); |
| 1725 | } |
| 1726 | |
| 1727 | void WebFrameLoaderClient::dispatchGlobalObjectAvailable(DOMWrapperWorld& world) |
| 1728 | { |
| 1729 | WebPage* webPage = m_frame->page(); |
| 1730 | if (!webPage) |
| 1731 | return; |
| 1732 | |
| 1733 | webPage->injectedBundleLoaderClient().globalObjectIsAvailableForFrame(*webPage, *m_frame, world); |
| 1734 | } |
| 1735 | |
| 1736 | void WebFrameLoaderClient::willInjectUserScript(DOMWrapperWorld& world) |
| 1737 | { |
| 1738 | WebPage* webPage = m_frame->page(); |
| 1739 | if (!webPage) |
| 1740 | return; |
| 1741 | |
| 1742 | webPage->injectedBundleLoaderClient().willInjectUserScriptForFrame(*webPage, *m_frame, world); |
| 1743 | } |
| 1744 | |
| 1745 | void WebFrameLoaderClient::dispatchWillDisconnectDOMWindowExtensionFromGlobalObject(WebCore::DOMWindowExtension* extension) |
| 1746 | { |
| 1747 | WebPage* webPage = m_frame->page(); |
| 1748 | if (!webPage) |
| 1749 | return; |
| 1750 | |
| 1751 | webPage->injectedBundleLoaderClient().willDisconnectDOMWindowExtensionFromGlobalObject(*webPage, extension); |
| 1752 | } |
| 1753 | |
| 1754 | void WebFrameLoaderClient::dispatchDidReconnectDOMWindowExtensionToGlobalObject(WebCore::DOMWindowExtension* extension) |
| 1755 | { |
| 1756 | WebPage* webPage = m_frame->page(); |
| 1757 | if (!webPage) |
| 1758 | return; |
| 1759 | |
| 1760 | webPage->injectedBundleLoaderClient().didReconnectDOMWindowExtensionToGlobalObject(*webPage, extension); |
| 1761 | } |
| 1762 | |
| 1763 | void WebFrameLoaderClient::dispatchWillDestroyGlobalObjectForDOMWindowExtension(WebCore::DOMWindowExtension* extension) |
| 1764 | { |
| 1765 | WebPage* webPage = m_frame->page(); |
| 1766 | if (!webPage) |
| 1767 | return; |
| 1768 | |
| 1769 | webPage->injectedBundleLoaderClient().willDestroyGlobalObjectForDOMWindowExtension(*webPage, extension); |
| 1770 | } |
| 1771 | |
| 1772 | #if PLATFORM(COCOA) |
| 1773 | |
| 1774 | RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject() |
| 1775 | { |
| 1776 | WebPage* webPage = m_frame->page(); |
| 1777 | if (!webPage) |
| 1778 | return 0; |
| 1779 | |
| 1780 | return webPage->accessibilityRemoteObject(); |
| 1781 | } |
| 1782 | |
| 1783 | void WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response, CompletionHandler<void(NSCachedURLResponse *)>&& completionHandler) const |
| 1784 | { |
| 1785 | WebPage* webPage = m_frame->page(); |
| 1786 | if (!webPage) |
| 1787 | return completionHandler(response); |
| 1788 | |
| 1789 | return completionHandler(webPage->injectedBundleResourceLoadClient().shouldCacheResponse(*webPage, *m_frame, identifier) ? response : nil); |
| 1790 | } |
| 1791 | |
| 1792 | NSDictionary *WebFrameLoaderClient::dataDetectionContext() |
| 1793 | { |
| 1794 | WebPage* webPage = m_frame->page(); |
| 1795 | if (!webPage) |
| 1796 | return nil; |
| 1797 | |
| 1798 | return webPage->dataDetectionContext(); |
| 1799 | } |
| 1800 | |
| 1801 | #endif // PLATFORM(COCOA) |
| 1802 | |
| 1803 | void WebFrameLoaderClient::didChangeScrollOffset() |
| 1804 | { |
| 1805 | WebPage* webPage = m_frame->page(); |
| 1806 | if (!webPage) |
| 1807 | return; |
| 1808 | |
| 1809 | webPage->didChangeScrollOffsetForFrame(m_frame->coreFrame()); |
| 1810 | } |
| 1811 | |
| 1812 | bool WebFrameLoaderClient::allowScript(bool enabledPerSettings) |
| 1813 | { |
| 1814 | if (!enabledPerSettings) |
| 1815 | return false; |
| 1816 | |
| 1817 | auto* pluginView = WebPage::pluginViewForFrame(m_frame->coreFrame()); |
| 1818 | return !pluginView || !pluginView->shouldAllowScripting(); |
| 1819 | } |
| 1820 | |
| 1821 | bool WebFrameLoaderClient::shouldForceUniversalAccessFromLocalURL(const URL& url) |
| 1822 | { |
| 1823 | WebPage* webPage = m_frame->page(); |
| 1824 | if (!webPage) |
| 1825 | return false; |
| 1826 | |
| 1827 | return webPage->injectedBundleLoaderClient().shouldForceUniversalAccessFromLocalURL(*webPage, url); |
| 1828 | } |
| 1829 | |
| 1830 | Ref<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext() |
| 1831 | { |
| 1832 | ASSERT(!hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies)); |
| 1833 | return WebFrameNetworkingContext::create(m_frame); |
| 1834 | } |
| 1835 | |
| 1836 | #if ENABLE(CONTENT_FILTERING) |
| 1837 | |
| 1838 | void WebFrameLoaderClient::contentFilterDidBlockLoad(WebCore::ContentFilterUnblockHandler unblockHandler) |
| 1839 | { |
| 1840 | if (!unblockHandler.needsUIProcess()) { |
| 1841 | m_frame->coreFrame()->loader().policyChecker().setContentFilterUnblockHandler(WTFMove(unblockHandler)); |
| 1842 | return; |
| 1843 | } |
| 1844 | |
| 1845 | if (WebPage* webPage { m_frame->page() }) |
| 1846 | webPage->send(Messages::WebPageProxy::ContentFilterDidBlockLoadForFrame(unblockHandler, m_frame->frameID())); |
| 1847 | } |
| 1848 | |
| 1849 | #endif |
| 1850 | |
| 1851 | void WebFrameLoaderClient::prefetchDNS(const String& hostname) |
| 1852 | { |
| 1853 | WebProcess::singleton().prefetchDNS(hostname); |
| 1854 | } |
| 1855 | |
| 1856 | void WebFrameLoaderClient::didRestoreScrollPosition() |
| 1857 | { |
| 1858 | WebPage* webPage = m_frame->page(); |
| 1859 | if (!webPage) |
| 1860 | return; |
| 1861 | |
| 1862 | webPage->didRestoreScrollPosition(); |
| 1863 | } |
| 1864 | |
| 1865 | void WebFrameLoaderClient::getLoadDecisionForIcons(const Vector<std::pair<WebCore::LinkIcon&, uint64_t>>& icons) |
| 1866 | { |
| 1867 | auto* webPage = m_frame->page(); |
| 1868 | if (!webPage) |
| 1869 | return; |
| 1870 | |
| 1871 | for (auto& icon : icons) |
| 1872 | webPage->send(Messages::WebPageProxy::GetLoadDecisionForIcon(icon.first, CallbackID::fromInteger(icon.second))); |
| 1873 | } |
| 1874 | |
| 1875 | void WebFrameLoaderClient::finishedLoadingIcon(uint64_t callbackIdentifier, SharedBuffer* data) |
| 1876 | { |
| 1877 | auto callbackID = CallbackID::fromInteger(callbackIdentifier); |
| 1878 | if (WebPage* webPage { m_frame->page() }) { |
| 1879 | if (data) |
| 1880 | webPage->send(Messages::WebPageProxy::FinishedLoadingIcon(callbackID, { reinterpret_cast<const uint8_t*>(data->data()), data->size() })); |
| 1881 | else |
| 1882 | webPage->send(Messages::WebPageProxy::FinishedLoadingIcon(callbackID, { nullptr, 0 })); |
| 1883 | } |
| 1884 | } |
| 1885 | |
| 1886 | void WebFrameLoaderClient::didCreateWindow(DOMWindow& window) |
| 1887 | { |
| 1888 | auto* webPage = m_frame->page(); |
| 1889 | if (!webPage) |
| 1890 | return; |
| 1891 | |
| 1892 | webPage->send(Messages::WebPageProxy::DidCreateWindow(m_frame->frameID(), window.identifier())); |
| 1893 | } |
| 1894 | |
| 1895 | #if ENABLE(APPLICATION_MANIFEST) |
| 1896 | void WebFrameLoaderClient::finishedLoadingApplicationManifest(uint64_t callbackIdentifier, const Optional<WebCore::ApplicationManifest>& manifest) |
| 1897 | { |
| 1898 | WebPage* webPage = m_frame->page(); |
| 1899 | if (!webPage) |
| 1900 | return; |
| 1901 | |
| 1902 | webPage->didFinishLoadingApplicationManifest(callbackIdentifier, manifest); |
| 1903 | } |
| 1904 | #endif // ENABLE(APPLICATION_MANIFEST) |
| 1905 | |
| 1906 | } // namespace WebKit |
| 1907 | |