2 * Copyright (C) 2010 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.
26 #include "WebFrameLoaderClient.h"
28 #define DISABLE_NOT_IMPLEMENTED_WARNINGS 1
29 #include "NotImplemented.h"
31 #include "AuthenticationManager.h"
32 #include "DataReference.h"
33 #include "InjectedBundleUserMessageCoders.h"
34 #include "PlatformCertificateInfo.h"
35 #include "PluginView.h"
36 #include "StringPairVector.h"
37 #include "WebContextMessages.h"
38 #include "WebCoreArgumentCoders.h"
39 #include "WebErrors.h"
42 #include "WebFrameNetworkingContext.h"
43 #include "WebNavigationDataStore.h"
45 #include "WebPageProxyMessages.h"
46 #include "WebProcess.h"
47 #include "WebProcessProxyMessageKinds.h"
48 #include "WebProcessProxyMessages.h"
49 #include <JavaScriptCore/APICast.h>
50 #include <JavaScriptCore/JSObject.h>
51 #include <WebCore/Chrome.h>
52 #include <WebCore/DOMWrapperWorld.h>
53 #include <WebCore/DocumentLoader.h>
54 #include <WebCore/FormState.h>
55 #include <WebCore/Frame.h>
56 #include <WebCore/FrameLoadRequest.h>
57 #include <WebCore/FrameView.h>
58 #include <WebCore/HTMLAppletElement.h>
59 #include <WebCore/HTMLFormElement.h>
60 #include <WebCore/HistoryItem.h>
61 #include <WebCore/MIMETypeRegistry.h>
62 #include <WebCore/MouseEvent.h>
63 #include <WebCore/Page.h>
64 #include <WebCore/PluginData.h>
65 #include <WebCore/ProgressTracker.h>
66 #include <WebCore/ResourceError.h>
67 #include <WebCore/UIEventWithKeyState.h>
68 #include <WebCore/Widget.h>
69 #include <WebCore/WindowFeatures.h>
71 using namespace WebCore;
75 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* frame)
77 , m_hasSentResponseToPluginView(false)
78 , m_frameHasCustomRepresentation(false)
82 WebFrameLoaderClient::~WebFrameLoaderClient()
86 void WebFrameLoaderClient::frameLoaderDestroyed()
88 m_frame->invalidate();
90 // Balances explicit ref() in WebFrame::createMainFrame and WebFrame::createSubframe.
94 bool WebFrameLoaderClient::hasHTMLView() const
96 return !m_frameHasCustomRepresentation;
99 bool WebFrameLoaderClient::hasWebView() const
101 return m_frame->page();
104 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
109 void WebFrameLoaderClient::forceLayout()
114 void WebFrameLoaderClient::forceLayoutForNonHTML()
119 void WebFrameLoaderClient::setCopiesOnScroll()
124 void WebFrameLoaderClient::detachedFromParent2()
126 WebPage* webPage = m_frame->page();
130 RefPtr<APIObject> userData;
132 // Notify the bundle client.
133 webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
135 // Notify the UIProcess.
136 webPage->send(Messages::WebPageProxy::DidRemoveFrameFromHierarchy(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
140 void WebFrameLoaderClient::detachedFromParent3()
145 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader*, const ResourceRequest& request)
147 WebPage* webPage = m_frame->page();
151 webPage->send(Messages::WebPageProxy::DidInitiateLoadForResource(m_frame->frameID(), identifier, request));
154 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
156 WebPage* webPage = m_frame->page();
160 if (!webPage->injectedBundleLoaderClient().shouldLoadResourceForFrame(webPage, m_frame, request.url().string())) {
161 request = ResourceRequest();
162 // FIXME: We should probably send a message saying we cancelled the request for the resource.
166 webPage->send(Messages::WebPageProxy::DidSendRequestForResource(m_frame->frameID(), identifier, request, redirectResponse));
169 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
174 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
176 // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
177 // Once we do, we might need to make sure authentication fits with our solution.
179 WebPage* webPage = m_frame->page();
183 AuthenticationManager::shared().didReceiveAuthenticationChallenge(m_frame, challenge);
186 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
191 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
192 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
194 // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
195 // Once we do, we might need to make sure authentication fits with our solution.
197 WebPage* webPage = m_frame->page();
201 bool canAuthenticate;
202 if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate)))
205 return canAuthenticate;
209 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
211 WebPage* webPage = m_frame->page();
215 webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response));
218 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int lengthReceived)
220 WebPage* webPage = m_frame->page();
224 webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, lengthReceived));
227 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
229 WebPage* webPage = m_frame->page();
233 webPage->send(Messages::WebPageProxy::DidFinishLoadForResource(m_frame->frameID(), identifier));
236 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
238 WebPage* webPage = m_frame->page();
242 webPage->send(Messages::WebPageProxy::DidFailLoadForResource(m_frame->frameID(), identifier, error));
245 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length)
251 void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const String&)
256 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
258 WebPage* webPage = m_frame->page();
262 // Notify the bundle client.
263 webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame);
266 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
268 WebPage* webPage = m_frame->page();
272 DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
273 const String& url = provisionalLoader->url().string();
274 RefPtr<APIObject> userData;
276 // Notify the bundle client.
277 webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData);
279 // Notify the UIProcess.
280 webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), url, InjectedBundleUserMessageEncoder(userData.get())));
283 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
285 WebPage* webPage = m_frame->page();
289 // Notify the bundle client.
290 webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame);
293 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double interval, double fireDate)
295 WebPage* webPage = m_frame->page();
299 // Notify the bundle client.
300 webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate);
303 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
305 WebPage* webPage = m_frame->page();
309 RefPtr<APIObject> userData;
311 // Notify the bundle client.
312 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData);
314 // Notify the UIProcess.
315 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->loader()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
318 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
320 WebPage* webPage = m_frame->page();
324 RefPtr<APIObject> userData;
326 // Notify the bundle client.
327 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData);
329 // Notify the UIProcess.
330 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->loader()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
333 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
335 WebPage* webPage = m_frame->page();
339 RefPtr<APIObject> userData;
341 // Notify the bundle client.
342 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData);
344 // Notify the UIProcess.
345 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->loader()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
348 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
350 WebPage* webPage = m_frame->page();
354 RefPtr<APIObject> userData;
356 // Notify the bundle client.
357 webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData);
359 // Notify the UIProcess.
360 webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->loader()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
363 void WebFrameLoaderClient::dispatchWillClose()
368 void WebFrameLoaderClient::dispatchDidReceiveIcon()
373 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
375 WebPage* webPage = m_frame->page();
378 webPage->findController().hideFindUI();
380 DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
381 const String& url = provisionalLoader->url().string();
382 RefPtr<APIObject> userData;
384 // Notify the bundle client.
385 webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);
387 bool loadingSubstituteDataForUnreachableURL = !provisionalLoader->unreachableURL().isNull();
389 webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);
391 // Notify the UIProcess.
392 webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, loadingSubstituteDataForUnreachableURL, InjectedBundleUserMessageEncoder(userData.get())));
395 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
397 WebPage* webPage = m_frame->page();
401 RefPtr<APIObject> userData;
403 // Notify the bundle client.
404 webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title, m_frame, userData);
406 // Notify the UIProcess.
407 webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title, InjectedBundleUserMessageEncoder(userData.get())));
410 void WebFrameLoaderClient::dispatchDidChangeIcons()
415 void WebFrameLoaderClient::dispatchDidCommitLoad()
417 WebPage* webPage = m_frame->page();
421 const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response();
422 RefPtr<APIObject> userData;
424 // Notify the bundle client.
425 webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData);
427 webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
429 // Notify the UIProcess.
431 webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), response.mimeType(), m_frameHasCustomRepresentation, PlatformCertificateInfo(response), InjectedBundleUserMessageEncoder(userData.get())));
433 // Only restore the scale factor for standard frame loads (of the main frame).
434 if (m_frame->isMainFrame() && m_frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) {
435 if (m_frame->coreFrame()->pageScaleFactor() != 1)
436 webPage->scaleWebView(1, IntPoint());
440 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
442 WebPage* webPage = m_frame->page();
446 RefPtr<APIObject> userData;
448 // Notify the bundle client.
449 webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData);
451 webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame);
453 // Notify the UIProcess.
454 webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
456 // If we have a load listener, notify it.
457 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
458 loadListener->didFailLoad(m_frame, error.isCancellation());
461 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
463 WebPage* webPage = m_frame->page();
467 RefPtr<APIObject> userData;
469 // Notify the bundle client.
470 webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData);
472 // Notify the UIProcess.
473 webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
475 // If we have a load listener, notify it.
476 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
477 loadListener->didFailLoad(m_frame, error.isCancellation());
480 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
482 WebPage* webPage = m_frame->page();
486 RefPtr<APIObject> userData;
488 // Notify the bundle client.
489 webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData);
491 // Notify the UIProcess.
492 webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
495 void WebFrameLoaderClient::dispatchDidFinishLoad()
497 WebPage* webPage = m_frame->page();
501 RefPtr<APIObject> userData;
503 // Notify the bundle client.
504 webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData);
506 // Notify the UIProcess.
507 webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
509 // If we have a load listener, notify it.
510 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
511 loadListener->didFinishLoad(m_frame);
514 void WebFrameLoaderClient::dispatchDidFirstLayout()
516 WebPage* webPage = m_frame->page();
520 RefPtr<APIObject> userData;
522 // Notify the bundle client.
523 webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
525 // Notify the UIProcess.
526 webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
529 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
531 WebPage* webPage = m_frame->page();
535 RefPtr<APIObject> userData;
537 // Notify the bundle client.
538 webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
540 // Notify the UIProcess.
541 webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
544 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
546 WebPage* webPage = m_frame->page();
550 // Just call through to the chrome client.
551 Page* newPage = webPage->corePage()->chrome()->createWindow(m_frame->coreFrame(), FrameLoadRequest(m_frame->coreFrame()->document()->securityOrigin()), WindowFeatures(), navigationAction);
555 return newPage->mainFrame();
558 void WebFrameLoaderClient::dispatchShow()
560 WebPage* webPage = m_frame->page();
567 uint32_t modifiersForNavigationAction(const NavigationAction& navigationAction)
569 uint32_t modifiers = 0;
570 if (const UIEventWithKeyState* keyStateEvent = findEventWithKeyState(const_cast<Event*>(navigationAction.event()))) {
571 if (keyStateEvent->shiftKey())
572 modifiers |= WebEvent::ShiftKey;
573 if (keyStateEvent->ctrlKey())
574 modifiers |= WebEvent::ControlKey;
575 if (keyStateEvent->altKey())
576 modifiers |= WebEvent::AltKey;
577 if (keyStateEvent->metaKey())
578 modifiers |= WebEvent::MetaKey;
584 static const MouseEvent* findMouseEvent(const Event* event)
586 for (const Event* e = event; e; e = e->underlyingEvent()) {
587 if (e->isMouseEvent())
588 return static_cast<const MouseEvent*>(e);
593 int32_t mouseButtonForNavigationAction(const NavigationAction& navigationAction)
595 const MouseEvent* mouseEvent = findMouseEvent(navigationAction.event());
599 if (!mouseEvent->buttonDown())
602 return mouseEvent->button();
605 void WebFrameLoaderClient::dispatchDecidePolicyForMIMEType(FramePolicyFunction function, const String& MIMEType, const ResourceRequest& request)
607 if (m_frame->coreFrame()->loader()->documentLoader()->url().isEmpty() && request.url() == blankURL()) {
608 // WebKit2 loads initial about:blank documents synchronously, without consulting the policy delegate
609 ASSERT(m_frame->coreFrame()->loader()->stateMachine()->committingFirstRealLoad());
610 (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
614 WebPage* webPage = m_frame->page();
618 uint64_t listenerID = m_frame->setUpPolicyListener(function);
619 const String& url = request.url().string(); // FIXME: Pass entire request.
623 bool receivedPolicyAction;
624 uint64_t policyAction;
626 if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForMIMEType(m_frame->frameID(), MIMEType, url, listenerID), Messages::WebPageProxy::DecidePolicyForMIMEType::Reply(receivedPolicyAction, policyAction, downloadID)))
629 // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
630 if (receivedPolicyAction)
631 m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
634 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState>, const String& frameName)
636 WebPage* webPage = m_frame->page();
640 uint64_t listenerID = m_frame->setUpPolicyListener(function);
642 // FIXME: Pass more than just the navigation action type.
643 // FIXME: Pass the frame name.
644 const String& url = request.url().string(); // FIXME: Pass entire request.
646 uint32_t navigationType = static_cast<uint32_t>(navigationAction.type());
647 uint32_t modifiers = modifiersForNavigationAction(navigationAction);
648 int32_t mouseButton = mouseButtonForNavigationAction(navigationAction);
650 webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), navigationType, modifiers, mouseButton, url, listenerID));
653 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState>)
655 if (m_frame->coreFrame()->loader()->documentLoader()->url().isEmpty() && request.url() == blankURL()) {
656 // WebKit2 loads initial about:blank documents synchronously, without consulting the policy delegate
657 ASSERT(m_frame->coreFrame()->loader()->stateMachine()->committingFirstRealLoad());
658 (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
662 // Always ignore requests with empty URLs.
663 if (request.isEmpty()) {
664 (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyIgnore);
668 WebPage* webPage = m_frame->page();
672 uint64_t listenerID = m_frame->setUpPolicyListener(function);
674 // FIXME: Pass more than just the navigation action type.
675 const String& url = request.url().string(); // FIXME: Pass entire request.
677 uint32_t navigationType = static_cast<uint32_t>(navigationAction.type());
678 uint32_t modifiers = modifiersForNavigationAction(navigationAction);
679 int32_t mouseButton = mouseButtonForNavigationAction(navigationAction);
681 webPage->send(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), navigationType, modifiers, mouseButton, url, listenerID));
684 void WebFrameLoaderClient::cancelPolicyCheck()
686 m_frame->invalidatePolicyListener();
689 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError&)
694 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> prpFormState)
696 WebPage* webPage = m_frame->page();
700 // FIXME: Pass more of the form state.
701 RefPtr<FormState> formState = prpFormState;
703 HTMLFormElement* form = formState->form();
704 WebFrame* sourceFrame = static_cast<WebFrameLoaderClient*>(formState->sourceFrame()->loader()->client())->webFrame();
705 const Vector<std::pair<String, String> >& values = formState->textFieldValues();
707 RefPtr<APIObject> userData;
708 webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData);
711 uint64_t listenerID = m_frame->setUpPolicyListener(function);
712 StringPairVector valuesVector(values);
714 webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), valuesVector, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
717 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
722 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
727 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
732 m_pluginView->manualLoadDidFail(error);
734 m_hasSentResponseToPluginView = false;
737 void WebFrameLoaderClient::willChangeEstimatedProgress()
742 void WebFrameLoaderClient::didChangeEstimatedProgress()
747 void WebFrameLoaderClient::postProgressStartedNotification()
749 if (WebPage* webPage = m_frame->page())
750 webPage->send(Messages::WebPageProxy::DidStartProgress());
753 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
755 if (WebPage* webPage = m_frame->page()) {
756 double progress = webPage->corePage()->progress()->estimatedProgress();
757 webPage->send(Messages::WebPageProxy::DidChangeProgress(progress));
762 void WebFrameLoaderClient::postProgressFinishedNotification()
764 if (WebPage* webPage = m_frame->page())
765 webPage->send(Messages::WebPageProxy::DidFinishProgress());
768 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
773 void WebFrameLoaderClient::startDownload(const ResourceRequest& request)
775 m_frame->startDownload(request);
778 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
783 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
788 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
790 // If we're loading a custom representation, we don't want to hand off the data to WebCore.
791 if (m_frameHasCustomRepresentation)
795 loader->commitData(data, length);
797 // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
798 // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
799 if (m_frame->coreFrame()->document()->isMediaDocument())
800 loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
802 // Calling commitData did not create the plug-in view.
806 if (!m_hasSentResponseToPluginView) {
807 m_pluginView->manualLoadDidReceiveResponse(loader->response());
808 // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
809 // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
813 m_hasSentResponseToPluginView = true;
815 m_pluginView->manualLoadDidReceiveData(data, length);
818 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
821 committedLoad(loader, 0, 0);
823 if (m_frameHasCustomRepresentation) {
824 WebPage* webPage = m_frame->page();
828 RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData();
829 CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0);
831 webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomRepresentation(dataReference));
837 m_pluginView->manualLoadDidFinishLoading();
839 m_hasSentResponseToPluginView = false;
842 void WebFrameLoaderClient::updateGlobalHistory()
844 WebPage* webPage = m_frame->page();
848 DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
850 WebNavigationDataStore data;
851 data.url = loader->urlForHistory().string();
852 data.title = loader->title();
854 WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0);
857 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
859 WebPage* webPage = m_frame->page();
863 DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
864 ASSERT(loader->unreachableURL().isEmpty());
867 if (!loader->clientRedirectSourceForHistory().isNull()) {
868 WebProcess::shared().connection()->send(Messages::WebContext::DidPerformClientRedirect(webPage->pageID(),
869 loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0);
873 if (!loader->serverRedirectSourceForHistory().isNull()) {
874 WebProcess::shared().connection()->send(Messages::WebContext::DidPerformServerRedirect(webPage->pageID(),
875 loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0);
879 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
885 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
890 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
895 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
900 void WebFrameLoaderClient::didDisplayInsecureContent()
902 WebPage* webPage = m_frame->page();
906 RefPtr<APIObject> userData;
908 webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData);
910 webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
913 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*)
915 WebPage* webPage = m_frame->page();
919 RefPtr<APIObject> userData;
921 webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData);
923 webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
926 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
928 return WebKit::cancelledError(request);
931 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
933 return WebKit::blockedError(request);
936 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
938 return WebKit::cannotShowURLError(request);
941 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request)
943 return WebKit::interruptForPolicyChangeError(request);
946 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
948 return WebKit::cannotShowMIMETypeError(response);
951 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
953 return WebKit::fileDoesNotExistError(response);
956 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
958 return WebKit::pluginWillHandleLoadError(response);
961 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
963 DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest())));
964 DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse())));
966 if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain())
969 if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain())
975 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
981 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
987 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
992 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
998 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
1004 void WebFrameLoaderClient::frameLoadCompleted()
1009 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*)
1014 void WebFrameLoaderClient::restoreViewState()
1016 // Inform the UI process of the scale factor.
1017 double scaleFactor = m_frame->coreFrame()->loader()->history()->currentItem()->pageScaleFactor();
1018 m_frame->page()->send(Messages::WebPageProxy::ViewScaleFactorDidChange(scaleFactor));
1021 void WebFrameLoaderClient::provisionalLoadStarted()
1026 void WebFrameLoaderClient::didFinishLoad()
1028 // If we have a load listener, notify it.
1029 if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
1030 loadListener->didFinishLoad(m_frame);
1033 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1038 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& data)
1040 return DocumentLoader::create(request, data);
1043 void WebFrameLoaderClient::setTitle(const String& title, const KURL& url)
1045 WebPage* webPage = m_frame->page();
1049 WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(),
1050 title, url.string(), m_frame->frameID()), 0);
1053 String WebFrameLoaderClient::userAgent(const KURL&)
1055 WebPage* webPage = m_frame->page();
1059 return webPage->userAgent();
1062 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
1066 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
1070 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1072 WebPage* webPage = m_frame->page();
1073 Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white;
1075 bool isMainFrame = webPage->mainFrame() == m_frame;
1077 #if ENABLE(TILED_BACKING_STORE)
1078 IntSize currentVisibleContentSize = m_frame->coreFrame()->view() ? m_frame->coreFrame()->view()->actualVisibleContentRect().size() : IntSize();
1079 m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, webPage->resizesToContentsLayoutSize(), isMainFrame && webPage->resizesToContentsEnabled());
1081 if (isMainFrame && webPage->resizesToContentsEnabled()) {
1082 m_frame->coreFrame()->view()->setDelegatesScrolling(true);
1083 m_frame->coreFrame()->view()->setPaintsEntireContents(true);
1086 // The HistoryController will update the scroll position later if needed.
1087 m_frame->coreFrame()->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize));
1089 const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType();
1090 m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType);
1092 m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, IntSize(), false);
1095 m_frame->coreFrame()->view()->setTransparent(!webPage->drawsBackground());
1098 void WebFrameLoaderClient::didSaveToPageCache()
1100 WebPage* webPage = m_frame->page();
1104 if (m_frame->isMainFrame())
1107 webPage->send(Messages::WebPageProxy::DidSaveFrameToPageCache(m_frame->frameID()));
1110 void WebFrameLoaderClient::didRestoreFromPageCache()
1112 WebPage* webPage = m_frame->page();
1116 if (m_frame->isMainFrame())
1119 WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(m_frame->coreFrame()->tree()->parent()->loader()->client())->webFrame();
1120 webPage->send(Messages::WebPageProxy::DidRestoreFrameFromPageCache(m_frame->frameID(), parentFrame->frameID()));
1123 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
1125 WebPage* webPage = m_frame->page();
1129 webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
1132 bool WebFrameLoaderClient::canCachePage() const
1134 // We cannot cache frames that have custom representations because they are
1135 // rendered in the UIProcess.
1136 return !m_frameHasCustomRepresentation;
1139 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
1141 m_frame->convertHandleToDownload(handle, request, initialRequest, response);
1144 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1145 const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1147 WebPage* webPage = m_frame->page();
1149 RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement);
1151 Frame* coreSubframe = subframe->coreFrame();
1153 // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1154 m_frame->coreFrame()->loader()->loadURLIntoChildFrame(url, referrer, coreSubframe);
1156 // The frame's onload handler may have removed it from the document.
1157 if (!coreSubframe->tree()->parent())
1160 return coreSubframe;
1163 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*)
1168 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*)
1173 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1175 ASSERT(paramNames.size() == paramValues.size());
1177 WebPage* webPage = m_frame->page();
1180 Plugin::Parameters parameters;
1181 parameters.url = url;
1182 parameters.names = paramNames;
1183 parameters.values = paramValues;
1184 parameters.mimeType = mimeType;
1185 parameters.loadManually = loadManually;
1187 // <rdar://problem/8440903>: AppleConnect has a bug where it does not
1188 // understand the parameter names specified in the <object> element that
1189 // embeds its plug-in. This hack works around the issue by converting the
1190 // parameter names to lowercase before passing them to the plug-in.
1191 // FIXME: This workaround should be dependent on site-specific quirks being
1192 // enabled. This requires adding this setting to WebKit2's WebPreferences
1193 // implementation. See <https://bugs.webkit.org/show_bug.cgi?id=46076>.
1194 if (equalIgnoringCase(mimeType, "application/x-snkp")) {
1195 for (size_t i = 0; i < paramNames.size(); ++i)
1196 parameters.names[i] = paramNames[i].lower();
1199 RefPtr<Plugin> plugin = webPage->createPlugin(parameters);
1203 return PluginView::create(pluginElement, plugin.release(), parameters);
1206 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1208 ASSERT(!m_pluginView);
1209 ASSERT(pluginWidget);
1211 m_pluginView = static_cast<PluginView*>(pluginWidget);
1214 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues)
1216 return createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, "application/x-java-applet", false);
1219 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn)
1221 // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
1224 String mimeType = mimeTypeIn;
1225 if (mimeType.isEmpty())
1226 mimeType = MIMETypeRegistry::getMIMETypeForExtension(url.path().substring(url.path().reverseFind('.') + 1));
1228 if (mimeType.isEmpty())
1229 return ObjectContentFrame;
1231 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1232 return WebCore::ObjectContentImage;
1234 if (WebPage* webPage = m_frame->page()) {
1235 if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1236 if (pluginData->supportsMimeType(mimeType))
1237 return ObjectContentNetscapePlugin;
1241 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1242 return ObjectContentFrame;
1244 return ObjectContentNone;
1247 String WebFrameLoaderClient::overrideMediaType() const
1253 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1255 WebPage* webPage = m_frame->page();
1259 webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1262 void WebFrameLoaderClient::documentElementAvailable()
1267 void WebFrameLoaderClient::didPerformFirstNavigation() const
1272 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1279 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject()
1281 return m_frame->page()->accessibilityRemoteObject();
1284 #if ENABLE(MAC_JAVA_BRIDGE)
1285 jobject WebFrameLoaderClient::javaApplet(NSView*) { return 0; }
1287 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1294 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length)
1301 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& /*mimeType*/) const
1307 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1309 return WebFrameNetworkingContext::create(m_frame->coreFrame());
1312 } // namespace WebKit