1 /*
2  * Copyright (C) 2010, 2011 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 "InjectedBundleNavigationAction.h"
32 #include "InjectedBundleUserMessageCoders.h"
33 #include "PlatformCertificateInfo.h"
34 #include "PluginView.h"
35 #include "StringPairVector.h"
36 #include "WebBackForwardListProxy.h"
37 #include "WebContextMessages.h"
38 #include "WebCoreArgumentCoders.h"
39 #include "WebErrors.h"
40 #include "WebEvent.h"
41 #include "WebFrame.h"
42 #include "WebFrameNetworkingContext.h"
43 #include "WebNavigationDataStore.h"
44 #include "WebPage.h"
45 #include "WebPageProxyMessages.h"
46 #include "WebProcess.h"
47 #include "WebProcessProxyMessages.h"
48 #include <JavaScriptCore/APICast.h>
49 #include <JavaScriptCore/JSObject.h>
50 #include <WebCore/Chrome.h>
51 #include <WebCore/DOMWrapperWorld.h>
52 #include <WebCore/DocumentLoader.h>
53 #include <WebCore/FormState.h>
54 #include <WebCore/Frame.h>
55 #include <WebCore/FrameLoadRequest.h>
56 #include <WebCore/FrameView.h>
57 #include <WebCore/HTMLAppletElement.h>
58 #include <WebCore/HTMLFormElement.h>
59 #include <WebCore/HistoryItem.h>
60 #include <WebCore/MIMETypeRegistry.h>
61 #include <WebCore/MouseEvent.h>
62 #include <WebCore/NotImplemented.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>
70 
71 using namespace WebCore;
72 
73 namespace WebKit {
74 
WebFrameLoaderClient(WebFrame * frame)75 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* frame)
76     : m_frame(frame)
77     , m_hasSentResponseToPluginView(false)
78     , m_frameHasCustomRepresentation(false)
79 {
80 }
81 
~WebFrameLoaderClient()82 WebFrameLoaderClient::~WebFrameLoaderClient()
83 {
84 }
85 
frameLoaderDestroyed()86 void WebFrameLoaderClient::frameLoaderDestroyed()
87 {
88     m_frame->invalidate();
89 
90     // Balances explicit ref() in WebFrame::createMainFrame and WebFrame::createSubframe.
91     m_frame->deref();
92 }
93 
hasHTMLView() const94 bool WebFrameLoaderClient::hasHTMLView() const
95 {
96     return !m_frameHasCustomRepresentation;
97 }
98 
hasWebView() const99 bool WebFrameLoaderClient::hasWebView() const
100 {
101     return m_frame->page();
102 }
103 
makeRepresentation(DocumentLoader *)104 void WebFrameLoaderClient::makeRepresentation(DocumentLoader*)
105 {
106     notImplemented();
107 }
108 
forceLayout()109 void WebFrameLoaderClient::forceLayout()
110 {
111     notImplemented();
112 }
113 
forceLayoutForNonHTML()114 void WebFrameLoaderClient::forceLayoutForNonHTML()
115 {
116     notImplemented();
117 }
118 
setCopiesOnScroll()119 void WebFrameLoaderClient::setCopiesOnScroll()
120 {
121     notImplemented();
122 }
123 
detachedFromParent2()124 void WebFrameLoaderClient::detachedFromParent2()
125 {
126     WebPage* webPage = m_frame->page();
127     if (!webPage)
128         return;
129 
130     RefPtr<APIObject> userData;
131 
132     // Notify the bundle client.
133     webPage->injectedBundleLoaderClient().didRemoveFrameFromHierarchy(webPage, m_frame, userData);
134 
135     // Notify the UIProcess.
136     webPage->send(Messages::WebPageProxy::DidRemoveFrameFromHierarchy(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
137 
138 }
139 
detachedFromParent3()140 void WebFrameLoaderClient::detachedFromParent3()
141 {
142     notImplemented();
143 }
144 
assignIdentifierToInitialRequest(unsigned long identifier,DocumentLoader * loader,const ResourceRequest & request)145 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
146 {
147     WebPage* webPage = m_frame->page();
148     if (!webPage)
149         return;
150 
151     bool pageIsProvisionallyLoading = false;
152     if (FrameLoader* frameLoader = loader->frameLoader())
153         pageIsProvisionallyLoading = frameLoader->provisionalDocumentLoader() == loader;
154 
155     webPage->injectedBundleResourceLoadClient().didInitiateLoadForResource(webPage, m_frame, identifier, request, pageIsProvisionallyLoading);
156     webPage->send(Messages::WebPageProxy::DidInitiateLoadForResource(m_frame->frameID(), identifier, request, pageIsProvisionallyLoading));
157 }
158 
dispatchWillSendRequest(DocumentLoader *,unsigned long identifier,ResourceRequest & request,const ResourceResponse & redirectResponse)159 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader*, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
160 {
161     WebPage* webPage = m_frame->page();
162     if (!webPage)
163         return;
164 
165     webPage->injectedBundleResourceLoadClient().willSendRequestForFrame(webPage, m_frame, identifier, request, redirectResponse);
166 
167     if (request.isNull()) {
168         // FIXME: We should probably send a message saying we cancelled the request for the resource.
169         return;
170     }
171 
172     webPage->send(Messages::WebPageProxy::DidSendRequestForResource(m_frame->frameID(), identifier, request, redirectResponse));
173 }
174 
shouldUseCredentialStorage(DocumentLoader *,unsigned long identifier)175 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader*, unsigned long identifier)
176 {
177     return true;
178 }
179 
dispatchDidReceiveAuthenticationChallenge(DocumentLoader *,unsigned long,const AuthenticationChallenge & challenge)180 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader*, unsigned long, const AuthenticationChallenge& challenge)
181 {
182     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
183     // Once we do, we might need to make sure authentication fits with our solution.
184 
185     WebPage* webPage = m_frame->page();
186     if (!webPage)
187         return;
188 
189     AuthenticationManager::shared().didReceiveAuthenticationChallenge(m_frame, challenge);
190 }
191 
dispatchDidCancelAuthenticationChallenge(DocumentLoader *,unsigned long identifier,const AuthenticationChallenge &)192 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader*, unsigned long identifier, const AuthenticationChallenge&)
193 {
194     notImplemented();
195 }
196 
197 #if USE(PROTECTION_SPACE_AUTH_CALLBACK)
canAuthenticateAgainstProtectionSpace(DocumentLoader *,unsigned long,const ProtectionSpace & protectionSpace)198 bool WebFrameLoaderClient::canAuthenticateAgainstProtectionSpace(DocumentLoader*, unsigned long, const ProtectionSpace& protectionSpace)
199 {
200     // FIXME: Authentication is a per-resource concept, but we don't do per-resource handling in the UIProcess at the API level quite yet.
201     // Once we do, we might need to make sure authentication fits with our solution.
202 
203     WebPage* webPage = m_frame->page();
204     if (!webPage)
205         return false;
206 
207     bool canAuthenticate;
208     if (!webPage->sendSync(Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame(m_frame->frameID(), protectionSpace), Messages::WebPageProxy::CanAuthenticateAgainstProtectionSpaceInFrame::Reply(canAuthenticate)))
209         return false;
210 
211     return canAuthenticate;
212 }
213 #endif
214 
dispatchDidReceiveResponse(DocumentLoader *,unsigned long identifier,const ResourceResponse & response)215 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse& response)
216 {
217     WebPage* webPage = m_frame->page();
218     if (!webPage)
219         return;
220 
221     webPage->injectedBundleResourceLoadClient().didReceiveResponseForResource(webPage, m_frame, identifier, response);
222     webPage->send(Messages::WebPageProxy::DidReceiveResponseForResource(m_frame->frameID(), identifier, response));
223 }
224 
dispatchDidReceiveContentLength(DocumentLoader *,unsigned long identifier,int dataLength)225 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader*, unsigned long identifier, int dataLength)
226 {
227     WebPage* webPage = m_frame->page();
228     if (!webPage)
229         return;
230 
231     webPage->injectedBundleResourceLoadClient().didReceiveContentLengthForResource(webPage, m_frame, identifier, dataLength);
232     webPage->send(Messages::WebPageProxy::DidReceiveContentLengthForResource(m_frame->frameID(), identifier, dataLength));
233 }
234 
dispatchDidFinishLoading(DocumentLoader *,unsigned long identifier)235 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader*, unsigned long identifier)
236 {
237     WebPage* webPage = m_frame->page();
238     if (!webPage)
239         return;
240 
241     webPage->injectedBundleResourceLoadClient().didFinishLoadForResource(webPage, m_frame, identifier);
242     webPage->send(Messages::WebPageProxy::DidFinishLoadForResource(m_frame->frameID(), identifier));
243 }
244 
dispatchDidFailLoading(DocumentLoader *,unsigned long identifier,const ResourceError & error)245 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader*, unsigned long identifier, const ResourceError& error)
246 {
247     WebPage* webPage = m_frame->page();
248     if (!webPage)
249         return;
250 
251     webPage->injectedBundleResourceLoadClient().didFailLoadForResource(webPage, m_frame, identifier, error);
252     webPage->send(Messages::WebPageProxy::DidFailLoadForResource(m_frame->frameID(), identifier, error));
253 }
254 
dispatchDidLoadResourceFromMemoryCache(DocumentLoader *,const ResourceRequest &,const ResourceResponse &,int length)255 bool WebFrameLoaderClient::dispatchDidLoadResourceFromMemoryCache(DocumentLoader*, const ResourceRequest&, const ResourceResponse&, int length)
256 {
257     notImplemented();
258     return false;
259 }
260 
dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier,const String &)261 void WebFrameLoaderClient::dispatchDidLoadResourceByXMLHttpRequest(unsigned long identifier, const String&)
262 {
263     notImplemented();
264 }
265 
dispatchDidHandleOnloadEvents()266 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
267 {
268     WebPage* webPage = m_frame->page();
269     if (!webPage)
270         return;
271 
272     // Notify the bundle client.
273     webPage->injectedBundleLoaderClient().didHandleOnloadEventsForFrame(webPage, m_frame);
274 }
275 
dispatchDidReceiveServerRedirectForProvisionalLoad()276 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
277 {
278     WebPage* webPage = m_frame->page();
279     if (!webPage)
280         return;
281 
282     DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
283     const String& url = provisionalLoader->url().string();
284     RefPtr<APIObject> userData;
285 
286     // Notify the bundle client.
287     webPage->injectedBundleLoaderClient().didReceiveServerRedirectForProvisionalLoadForFrame(webPage, m_frame, userData);
288 
289     // Notify the UIProcess.
290     webPage->send(Messages::WebPageProxy::DidReceiveServerRedirectForProvisionalLoadForFrame(m_frame->frameID(), url, InjectedBundleUserMessageEncoder(userData.get())));
291 }
292 
dispatchDidCancelClientRedirect()293 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
294 {
295     WebPage* webPage = m_frame->page();
296     if (!webPage)
297         return;
298 
299     // Notify the bundle client.
300     webPage->injectedBundleLoaderClient().didCancelClientRedirectForFrame(webPage, m_frame);
301 }
302 
dispatchWillPerformClientRedirect(const KURL & url,double interval,double fireDate)303 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double interval, double fireDate)
304 {
305     WebPage* webPage = m_frame->page();
306     if (!webPage)
307         return;
308 
309     // Notify the bundle client.
310     webPage->injectedBundleLoaderClient().willPerformClientRedirectForFrame(webPage, m_frame, url.string(), interval, fireDate);
311 }
312 
dispatchDidChangeLocationWithinPage()313 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
314 {
315     WebPage* webPage = m_frame->page();
316     if (!webPage)
317         return;
318 
319     RefPtr<APIObject> userData;
320 
321     // Notify the bundle client.
322     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationAnchorNavigation, userData);
323 
324     // Notify the UIProcess.
325     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationAnchorNavigation, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
326 }
327 
dispatchDidPushStateWithinPage()328 void WebFrameLoaderClient::dispatchDidPushStateWithinPage()
329 {
330     WebPage* webPage = m_frame->page();
331     if (!webPage)
332         return;
333 
334     RefPtr<APIObject> userData;
335 
336     // Notify the bundle client.
337     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePush, userData);
338 
339     // Notify the UIProcess.
340     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePush, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
341 }
342 
dispatchDidReplaceStateWithinPage()343 void WebFrameLoaderClient::dispatchDidReplaceStateWithinPage()
344 {
345     WebPage* webPage = m_frame->page();
346     if (!webPage)
347         return;
348 
349     RefPtr<APIObject> userData;
350 
351     // Notify the bundle client.
352     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStateReplace, userData);
353 
354     // Notify the UIProcess.
355     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStateReplace, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
356 }
357 
dispatchDidPopStateWithinPage()358 void WebFrameLoaderClient::dispatchDidPopStateWithinPage()
359 {
360     WebPage* webPage = m_frame->page();
361     if (!webPage)
362         return;
363 
364     RefPtr<APIObject> userData;
365 
366     // Notify the bundle client.
367     webPage->injectedBundleLoaderClient().didSameDocumentNavigationForFrame(webPage, m_frame, SameDocumentNavigationSessionStatePop, userData);
368 
369     // Notify the UIProcess.
370     webPage->send(Messages::WebPageProxy::DidSameDocumentNavigationForFrame(m_frame->frameID(), SameDocumentNavigationSessionStatePop, m_frame->coreFrame()->document()->url().string(), InjectedBundleUserMessageEncoder(userData.get())));
371 }
372 
dispatchWillClose()373 void WebFrameLoaderClient::dispatchWillClose()
374 {
375     notImplemented();
376 }
377 
dispatchDidReceiveIcon()378 void WebFrameLoaderClient::dispatchDidReceiveIcon()
379 {
380     notImplemented();
381 }
382 
dispatchDidStartProvisionalLoad()383 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
384 {
385     WebPage* webPage = m_frame->page();
386     if (!webPage)
387         return;
388 
389     webPage->findController().hideFindUI();
390     webPage->sandboxExtensionTracker().didStartProvisionalLoad(m_frame);
391 
392     DocumentLoader* provisionalLoader = m_frame->coreFrame()->loader()->provisionalDocumentLoader();
393     const String& url = provisionalLoader->url().string();
394     RefPtr<APIObject> userData;
395 
396     // Notify the bundle client.
397     webPage->injectedBundleLoaderClient().didStartProvisionalLoadForFrame(webPage, m_frame, userData);
398 
399     String unreachableURL = provisionalLoader->unreachableURL().string();
400 
401     // Notify the UIProcess.
402     webPage->send(Messages::WebPageProxy::DidStartProvisionalLoadForFrame(m_frame->frameID(), url, unreachableURL, InjectedBundleUserMessageEncoder(userData.get())));
403 }
404 
dispatchDidReceiveTitle(const StringWithDirection & title)405 void WebFrameLoaderClient::dispatchDidReceiveTitle(const StringWithDirection& title)
406 {
407     WebPage* webPage = m_frame->page();
408     if (!webPage)
409         return;
410 
411     RefPtr<APIObject> userData;
412 
413     // Notify the bundle client.
414     // FIXME: use direction of title.
415     webPage->injectedBundleLoaderClient().didReceiveTitleForFrame(webPage, title.string(), m_frame, userData);
416 
417     // Notify the UIProcess.
418     webPage->send(Messages::WebPageProxy::DidReceiveTitleForFrame(m_frame->frameID(), title.string(), InjectedBundleUserMessageEncoder(userData.get())));
419 }
420 
dispatchDidChangeIcons(WebCore::IconType)421 void WebFrameLoaderClient::dispatchDidChangeIcons(WebCore::IconType)
422 {
423     notImplemented();
424 }
425 
dispatchDidCommitLoad()426 void WebFrameLoaderClient::dispatchDidCommitLoad()
427 {
428     WebPage* webPage = m_frame->page();
429     if (!webPage)
430         return;
431 
432     const ResourceResponse& response = m_frame->coreFrame()->loader()->documentLoader()->response();
433     RefPtr<APIObject> userData;
434 
435     // Notify the bundle client.
436     webPage->injectedBundleLoaderClient().didCommitLoadForFrame(webPage, m_frame, userData);
437 
438     webPage->sandboxExtensionTracker().didCommitProvisionalLoad(m_frame);
439 
440     // Notify the UIProcess.
441 
442     webPage->send(Messages::WebPageProxy::DidCommitLoadForFrame(m_frame->frameID(), response.mimeType(), m_frameHasCustomRepresentation, PlatformCertificateInfo(response), InjectedBundleUserMessageEncoder(userData.get())));
443 
444     // Only restore the scale factor for standard frame loads (of the main frame).
445     if (m_frame->isMainFrame() && m_frame->coreFrame()->loader()->loadType() == FrameLoadTypeStandard) {
446         if (m_frame->coreFrame()->pageScaleFactor() != 1)
447             webPage->scaleWebView(1, IntPoint());
448     }
449 }
450 
dispatchDidFailProvisionalLoad(const ResourceError & error)451 void WebFrameLoaderClient::dispatchDidFailProvisionalLoad(const ResourceError& error)
452 {
453     WebPage* webPage = m_frame->page();
454     if (!webPage)
455         return;
456 
457     RefPtr<APIObject> userData;
458 
459     // Notify the bundle client.
460     webPage->injectedBundleLoaderClient().didFailProvisionalLoadWithErrorForFrame(webPage, m_frame, error, userData);
461 
462     webPage->sandboxExtensionTracker().didFailProvisionalLoad(m_frame);
463 
464     // Notify the UIProcess.
465     webPage->send(Messages::WebPageProxy::DidFailProvisionalLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
466 
467     // If we have a load listener, notify it.
468     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
469         loadListener->didFailLoad(m_frame, error.isCancellation());
470 }
471 
dispatchDidFailLoad(const ResourceError & error)472 void WebFrameLoaderClient::dispatchDidFailLoad(const ResourceError& error)
473 {
474     WebPage* webPage = m_frame->page();
475     if (!webPage)
476         return;
477 
478     RefPtr<APIObject> userData;
479 
480     // Notify the bundle client.
481     webPage->injectedBundleLoaderClient().didFailLoadWithErrorForFrame(webPage, m_frame, error, userData);
482 
483     // Notify the UIProcess.
484     webPage->send(Messages::WebPageProxy::DidFailLoadForFrame(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
485 
486     // If we have a load listener, notify it.
487     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
488         loadListener->didFailLoad(m_frame, error.isCancellation());
489 }
490 
dispatchDidFinishDocumentLoad()491 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
492 {
493     WebPage* webPage = m_frame->page();
494     if (!webPage)
495         return;
496 
497     RefPtr<APIObject> userData;
498 
499     // Notify the bundle client.
500     webPage->injectedBundleLoaderClient().didFinishDocumentLoadForFrame(webPage, m_frame, userData);
501 
502     // Notify the UIProcess.
503     webPage->send(Messages::WebPageProxy::DidFinishDocumentLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
504 }
505 
dispatchDidFinishLoad()506 void WebFrameLoaderClient::dispatchDidFinishLoad()
507 {
508     WebPage* webPage = m_frame->page();
509     if (!webPage)
510         return;
511 
512     RefPtr<APIObject> userData;
513 
514     // Notify the bundle client.
515     webPage->injectedBundleLoaderClient().didFinishLoadForFrame(webPage, m_frame, userData);
516 
517     // Notify the UIProcess.
518     webPage->send(Messages::WebPageProxy::DidFinishLoadForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
519 
520     // If we have a load listener, notify it.
521     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
522         loadListener->didFinishLoad(m_frame);
523 }
524 
dispatchDidFirstLayout()525 void WebFrameLoaderClient::dispatchDidFirstLayout()
526 {
527     WebPage* webPage = m_frame->page();
528     if (!webPage)
529         return;
530 
531     RefPtr<APIObject> userData;
532 
533     // Notify the bundle client.
534     webPage->injectedBundleLoaderClient().didFirstLayoutForFrame(webPage, m_frame, userData);
535 
536     // Notify the UIProcess.
537     webPage->send(Messages::WebPageProxy::DidFirstLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
538 }
539 
dispatchDidFirstVisuallyNonEmptyLayout()540 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
541 {
542     WebPage* webPage = m_frame->page();
543     if (!webPage)
544         return;
545 
546     RefPtr<APIObject> userData;
547 
548     // Notify the bundle client.
549     webPage->injectedBundleLoaderClient().didFirstVisuallyNonEmptyLayoutForFrame(webPage, m_frame, userData);
550 
551     // Notify the UIProcess.
552     webPage->send(Messages::WebPageProxy::DidFirstVisuallyNonEmptyLayoutForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
553 }
554 
dispatchCreatePage(const NavigationAction & navigationAction)555 Frame* WebFrameLoaderClient::dispatchCreatePage(const NavigationAction& navigationAction)
556 {
557     WebPage* webPage = m_frame->page();
558     if (!webPage)
559         return 0;
560 
561     // Just call through to the chrome client.
562     Page* newPage = webPage->corePage()->chrome()->createWindow(m_frame->coreFrame(), FrameLoadRequest(m_frame->coreFrame()->document()->securityOrigin()), WindowFeatures(), navigationAction);
563     if (!newPage)
564         return 0;
565 
566     return newPage->mainFrame();
567 }
568 
dispatchShow()569 void WebFrameLoaderClient::dispatchShow()
570 {
571     WebPage* webPage = m_frame->page();
572     if (!webPage)
573         return;
574 
575     webPage->show();
576 }
577 
dispatchDecidePolicyForResponse(FramePolicyFunction function,const ResourceResponse & response,const ResourceRequest & request)578 void WebFrameLoaderClient::dispatchDecidePolicyForResponse(FramePolicyFunction function, const ResourceResponse& response, const ResourceRequest& request)
579 {
580     WebPage* webPage = m_frame->page();
581     if (!webPage)
582         return;
583 
584     if (!request.url().string())
585         return;
586 
587     RefPtr<APIObject> userData;
588 
589     // Notify the bundle client.
590     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForResponse(webPage, m_frame, response, request, userData);
591     if (policy == WKBundlePagePolicyActionUse) {
592         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
593         return;
594     }
595 
596     uint64_t listenerID = m_frame->setUpPolicyListener(function);
597     bool receivedPolicyAction;
598     uint64_t policyAction;
599     uint64_t downloadID;
600 
601     // Notify the UIProcess.
602     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForResponse(m_frame->frameID(), response, request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForResponse::Reply(receivedPolicyAction, policyAction, downloadID)))
603         return;
604 
605     // We call this synchronously because CFNetwork can only convert a loading connection to a download from its didReceiveResponse callback.
606     if (receivedPolicyAction)
607         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
608 }
609 
dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function,const NavigationAction & navigationAction,const ResourceRequest & request,PassRefPtr<FormState> formState,const String & frameName)610 void WebFrameLoaderClient::dispatchDecidePolicyForNewWindowAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState, const String& frameName)
611 {
612     WebPage* webPage = m_frame->page();
613     if (!webPage)
614         return;
615 
616     RefPtr<APIObject> userData;
617 
618     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
619 
620     // Notify the bundle client.
621     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNewWindowAction(webPage, m_frame, action.get(), request, frameName, userData);
622     if (policy == WKBundlePagePolicyActionUse) {
623         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
624         return;
625     }
626 
627 
628     uint64_t listenerID = m_frame->setUpPolicyListener(function);
629 
630     // Notify the UIProcess.
631     webPage->send(Messages::WebPageProxy::DecidePolicyForNewWindowAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, frameName, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
632 }
633 
dispatchDecidePolicyForNavigationAction(FramePolicyFunction function,const NavigationAction & navigationAction,const ResourceRequest & request,PassRefPtr<FormState> formState)634 void WebFrameLoaderClient::dispatchDecidePolicyForNavigationAction(FramePolicyFunction function, const NavigationAction& navigationAction, const ResourceRequest& request, PassRefPtr<FormState> formState)
635 {
636     WebPage* webPage = m_frame->page();
637     if (!webPage)
638         return;
639 
640     // Always ignore requests with empty URLs.
641     if (request.isEmpty()) {
642         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyIgnore);
643         return;
644     }
645 
646     RefPtr<APIObject> userData;
647 
648     RefPtr<InjectedBundleNavigationAction> action = InjectedBundleNavigationAction::create(m_frame, navigationAction, formState);
649 
650     // Notify the bundle client.
651     WKBundlePagePolicyAction policy = webPage->injectedBundlePolicyClient().decidePolicyForNavigationAction(webPage, m_frame, action.get(), request, userData);
652     if (policy == WKBundlePagePolicyActionUse) {
653         (m_frame->coreFrame()->loader()->policyChecker()->*function)(PolicyUse);
654         return;
655     }
656 
657     uint64_t listenerID = m_frame->setUpPolicyListener(function);
658     bool receivedPolicyAction;
659     uint64_t policyAction;
660     uint64_t downloadID;
661 
662     // Notify the UIProcess.
663     if (!webPage->sendSync(Messages::WebPageProxy::DecidePolicyForNavigationAction(m_frame->frameID(), action->navigationType(), action->modifiers(), action->mouseButton(), request, listenerID, InjectedBundleUserMessageEncoder(userData.get())), Messages::WebPageProxy::DecidePolicyForNavigationAction::Reply(receivedPolicyAction, policyAction, downloadID)))
664         return;
665 
666     // We call this synchronously because WebCore cannot gracefully handle a frame load without a synchronous navigation policy reply.
667     if (receivedPolicyAction)
668         m_frame->didReceivePolicyDecision(listenerID, static_cast<PolicyAction>(policyAction), downloadID);
669 }
670 
cancelPolicyCheck()671 void WebFrameLoaderClient::cancelPolicyCheck()
672 {
673     m_frame->invalidatePolicyListener();
674 }
675 
dispatchUnableToImplementPolicy(const ResourceError & error)676 void WebFrameLoaderClient::dispatchUnableToImplementPolicy(const ResourceError& error)
677 {
678     WebPage* webPage = m_frame->page();
679     if (!webPage)
680         return;
681 
682     RefPtr<APIObject> userData;
683 
684     // Notify the bundle client.
685     webPage->injectedBundlePolicyClient().unableToImplementPolicy(webPage, m_frame, error, userData);
686 
687     // Notify the UIProcess.
688     webPage->send(Messages::WebPageProxy::UnableToImplementPolicy(m_frame->frameID(), error, InjectedBundleUserMessageEncoder(userData.get())));
689 }
690 
dispatchWillSubmitForm(FramePolicyFunction function,PassRefPtr<FormState> prpFormState)691 void WebFrameLoaderClient::dispatchWillSubmitForm(FramePolicyFunction function, PassRefPtr<FormState> prpFormState)
692 {
693     WebPage* webPage = m_frame->page();
694     if (!webPage)
695         return;
696 
697     // FIXME: Pass more of the form state.
698     RefPtr<FormState> formState = prpFormState;
699 
700     HTMLFormElement* form = formState->form();
701     WebFrame* sourceFrame = static_cast<WebFrameLoaderClient*>(formState->sourceFrame()->loader()->client())->webFrame();
702     const Vector<std::pair<String, String> >& values = formState->textFieldValues();
703 
704     RefPtr<APIObject> userData;
705     webPage->injectedBundleFormClient().willSubmitForm(webPage, form, m_frame, sourceFrame, values, userData);
706 
707 
708     uint64_t listenerID = m_frame->setUpPolicyListener(function);
709     StringPairVector valuesVector(values);
710 
711     webPage->send(Messages::WebPageProxy::WillSubmitForm(m_frame->frameID(), sourceFrame->frameID(), valuesVector, listenerID, InjectedBundleUserMessageEncoder(userData.get())));
712 }
713 
dispatchDidLoadMainResource(DocumentLoader *)714 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
715 {
716     notImplemented();
717 }
718 
revertToProvisionalState(DocumentLoader *)719 void WebFrameLoaderClient::revertToProvisionalState(DocumentLoader*)
720 {
721     notImplemented();
722 }
723 
setMainDocumentError(DocumentLoader *,const ResourceError & error)724 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
725 {
726     if (!m_pluginView)
727         return;
728 
729     m_pluginView->manualLoadDidFail(error);
730     m_pluginView = 0;
731     m_hasSentResponseToPluginView = false;
732 }
733 
willChangeEstimatedProgress()734 void WebFrameLoaderClient::willChangeEstimatedProgress()
735 {
736     notImplemented();
737 }
738 
didChangeEstimatedProgress()739 void WebFrameLoaderClient::didChangeEstimatedProgress()
740 {
741     notImplemented();
742 }
743 
postProgressStartedNotification()744 void WebFrameLoaderClient::postProgressStartedNotification()
745 {
746     if (WebPage* webPage = m_frame->page())
747         webPage->send(Messages::WebPageProxy::DidStartProgress());
748 }
749 
postProgressEstimateChangedNotification()750 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
751 {
752     if (WebPage* webPage = m_frame->page()) {
753         double progress = webPage->corePage()->progress()->estimatedProgress();
754         webPage->send(Messages::WebPageProxy::DidChangeProgress(progress));
755 
756     }
757 }
758 
postProgressFinishedNotification()759 void WebFrameLoaderClient::postProgressFinishedNotification()
760 {
761     if (WebPage* webPage = m_frame->page())
762         webPage->send(Messages::WebPageProxy::DidFinishProgress());
763 }
764 
setMainFrameDocumentReady(bool)765 void WebFrameLoaderClient::setMainFrameDocumentReady(bool)
766 {
767     notImplemented();
768 }
769 
startDownload(const ResourceRequest & request)770 void WebFrameLoaderClient::startDownload(const ResourceRequest& request)
771 {
772     m_frame->startDownload(request);
773 }
774 
willChangeTitle(DocumentLoader *)775 void WebFrameLoaderClient::willChangeTitle(DocumentLoader*)
776 {
777     notImplemented();
778 }
779 
didChangeTitle(DocumentLoader *)780 void WebFrameLoaderClient::didChangeTitle(DocumentLoader*)
781 {
782     notImplemented();
783 }
784 
committedLoad(DocumentLoader * loader,const char * data,int length)785 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
786 {
787     // If we're loading a custom representation, we don't want to hand off the data to WebCore.
788     if (m_frameHasCustomRepresentation)
789         return;
790 
791     if (!m_pluginView)
792         loader->commitData(data, length);
793 
794     // If the document is a stand-alone media document, now is the right time to cancel the WebKit load.
795     // FIXME: This code should be shared across all ports. <http://webkit.org/b/48762>.
796     if (m_frame->coreFrame()->document()->isMediaDocument())
797         loader->cancelMainResourceLoad(pluginWillHandleLoadError(loader->response()));
798 
799     // Calling commitData did not create the plug-in view.
800     if (!m_pluginView)
801         return;
802 
803     if (!m_hasSentResponseToPluginView) {
804         m_pluginView->manualLoadDidReceiveResponse(loader->response());
805         // manualLoadDidReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
806         // setting up this stream can cause the main document load to be cancelled, setting m_pluginView
807         // to null
808         if (!m_pluginView)
809             return;
810         m_hasSentResponseToPluginView = true;
811     }
812     m_pluginView->manualLoadDidReceiveData(data, length);
813 }
814 
finishedLoading(DocumentLoader * loader)815 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
816 {
817     if (!m_pluginView) {
818         committedLoad(loader, 0, 0);
819 
820         if (m_frameHasCustomRepresentation) {
821             WebPage* webPage = m_frame->page();
822             if (!webPage)
823                 return;
824 
825             RefPtr<SharedBuffer> mainResourceData = loader->mainResourceData();
826             CoreIPC::DataReference dataReference(reinterpret_cast<const uint8_t*>(mainResourceData ? mainResourceData->data() : 0), mainResourceData ? mainResourceData->size() : 0);
827 
828             webPage->send(Messages::WebPageProxy::DidFinishLoadingDataForCustomRepresentation(loader->response().suggestedFilename(), dataReference));
829         }
830 
831         return;
832     }
833 
834     m_pluginView->manualLoadDidFinishLoading();
835     m_pluginView = 0;
836     m_hasSentResponseToPluginView = false;
837 }
838 
updateGlobalHistory()839 void WebFrameLoaderClient::updateGlobalHistory()
840 {
841     WebPage* webPage = m_frame->page();
842     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
843         return;
844 
845     DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
846 
847     WebNavigationDataStore data;
848     data.url = loader->urlForHistory().string();
849     // FIXME: use direction of title.
850     data.title = loader->title().string();
851 
852     WebProcess::shared().connection()->send(Messages::WebContext::DidNavigateWithNavigationData(webPage->pageID(), data, m_frame->frameID()), 0);
853 }
854 
updateGlobalHistoryRedirectLinks()855 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
856 {
857     WebPage* webPage = m_frame->page();
858     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
859         return;
860 
861     DocumentLoader* loader = m_frame->coreFrame()->loader()->documentLoader();
862     ASSERT(loader->unreachableURL().isEmpty());
863 
864     // Client redirect
865     if (!loader->clientRedirectSourceForHistory().isNull()) {
866         WebProcess::shared().connection()->send(Messages::WebContext::DidPerformClientRedirect(webPage->pageID(),
867             loader->clientRedirectSourceForHistory(), loader->clientRedirectDestinationForHistory(), m_frame->frameID()), 0);
868     }
869 
870     // Server redirect
871     if (!loader->serverRedirectSourceForHistory().isNull()) {
872         WebProcess::shared().connection()->send(Messages::WebContext::DidPerformServerRedirect(webPage->pageID(),
873             loader->serverRedirectSourceForHistory(), loader->serverRedirectDestinationForHistory(), m_frame->frameID()), 0);
874     }
875 }
876 
shouldGoToHistoryItem(HistoryItem * item) const877 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem* item) const
878 {
879     WebPage* webPage = m_frame->page();
880     if (!webPage)
881         return false;
882 
883     uint64_t itemID = WebBackForwardListProxy::idForItem(item);
884     if (!itemID) {
885         // We should never be considering navigating to an item that is not actually in the back/forward list.
886         ASSERT_NOT_REACHED();
887         return false;
888     }
889 
890     bool shouldGoToBackForwardListItem;
891     if (!webPage->sendSync(Messages::WebPageProxy::ShouldGoToBackForwardListItem(itemID), Messages::WebPageProxy::ShouldGoToBackForwardListItem::Reply(shouldGoToBackForwardListItem)))
892         return false;
893 
894     return shouldGoToBackForwardListItem;
895 }
896 
shouldStopLoadingForHistoryItem(HistoryItem * item) const897 bool WebFrameLoaderClient::shouldStopLoadingForHistoryItem(HistoryItem* item) const
898 {
899     return true;
900 }
901 
dispatchDidAddBackForwardItem(HistoryItem *) const902 void WebFrameLoaderClient::dispatchDidAddBackForwardItem(HistoryItem*) const
903 {
904     notImplemented();
905 }
906 
dispatchDidRemoveBackForwardItem(HistoryItem *) const907 void WebFrameLoaderClient::dispatchDidRemoveBackForwardItem(HistoryItem*) const
908 {
909     notImplemented();
910 }
911 
dispatchDidChangeBackForwardIndex() const912 void WebFrameLoaderClient::dispatchDidChangeBackForwardIndex() const
913 {
914     notImplemented();
915 }
916 
didDisplayInsecureContent()917 void WebFrameLoaderClient::didDisplayInsecureContent()
918 {
919     WebPage* webPage = m_frame->page();
920     if (!webPage)
921         return;
922 
923     RefPtr<APIObject> userData;
924 
925     webPage->injectedBundleLoaderClient().didDisplayInsecureContentForFrame(webPage, m_frame, userData);
926 
927     webPage->send(Messages::WebPageProxy::DidDisplayInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
928 }
929 
didRunInsecureContent(SecurityOrigin *,const KURL &)930 void WebFrameLoaderClient::didRunInsecureContent(SecurityOrigin*, const KURL&)
931 {
932     WebPage* webPage = m_frame->page();
933     if (!webPage)
934         return;
935 
936     RefPtr<APIObject> userData;
937 
938     webPage->injectedBundleLoaderClient().didRunInsecureContentForFrame(webPage, m_frame, userData);
939 
940     webPage->send(Messages::WebPageProxy::DidRunInsecureContentForFrame(m_frame->frameID(), InjectedBundleUserMessageEncoder(userData.get())));
941 }
942 
cancelledError(const ResourceRequest & request)943 ResourceError WebFrameLoaderClient::cancelledError(const ResourceRequest& request)
944 {
945     return WebKit::cancelledError(request);
946 }
947 
blockedError(const ResourceRequest & request)948 ResourceError WebFrameLoaderClient::blockedError(const ResourceRequest& request)
949 {
950     return WebKit::blockedError(request);
951 }
952 
cannotShowURLError(const ResourceRequest & request)953 ResourceError WebFrameLoaderClient::cannotShowURLError(const ResourceRequest& request)
954 {
955     return WebKit::cannotShowURLError(request);
956 }
957 
interruptForPolicyChangeError(const ResourceRequest & request)958 ResourceError WebFrameLoaderClient::interruptForPolicyChangeError(const ResourceRequest& request)
959 {
960     return WebKit::interruptForPolicyChangeError(request);
961 }
962 
cannotShowMIMETypeError(const ResourceResponse & response)963 ResourceError WebFrameLoaderClient::cannotShowMIMETypeError(const ResourceResponse& response)
964 {
965     return WebKit::cannotShowMIMETypeError(response);
966 }
967 
fileDoesNotExistError(const ResourceResponse & response)968 ResourceError WebFrameLoaderClient::fileDoesNotExistError(const ResourceResponse& response)
969 {
970     return WebKit::fileDoesNotExistError(response);
971 }
972 
pluginWillHandleLoadError(const ResourceResponse & response)973 ResourceError WebFrameLoaderClient::pluginWillHandleLoadError(const ResourceResponse& response)
974 {
975     return WebKit::pluginWillHandleLoadError(response);
976 }
977 
shouldFallBack(const ResourceError & error)978 bool WebFrameLoaderClient::shouldFallBack(const ResourceError& error)
979 {
980     DEFINE_STATIC_LOCAL(const ResourceError, cancelledError, (this->cancelledError(ResourceRequest())));
981     DEFINE_STATIC_LOCAL(const ResourceError, pluginWillHandleLoadError, (this->pluginWillHandleLoadError(ResourceResponse())));
982 
983     if (error.errorCode() == cancelledError.errorCode() && error.domain() == cancelledError.domain())
984         return false;
985 
986     if (error.errorCode() == pluginWillHandleLoadError.errorCode() && error.domain() == pluginWillHandleLoadError.domain())
987         return false;
988 
989     return true;
990 }
991 
canHandleRequest(const ResourceRequest &) const992 bool WebFrameLoaderClient::canHandleRequest(const ResourceRequest&) const
993 {
994     notImplemented();
995     return true;
996 }
997 
canShowMIMEType(const String & MIMEType) const998 bool WebFrameLoaderClient::canShowMIMEType(const String& MIMEType) const
999 {
1000     notImplemented();
1001     return true;
1002 }
1003 
canShowMIMETypeAsHTML(const String & MIMEType) const1004 bool WebFrameLoaderClient::canShowMIMETypeAsHTML(const String& MIMEType) const
1005 {
1006     return true;
1007 }
1008 
representationExistsForURLScheme(const String & URLScheme) const1009 bool WebFrameLoaderClient::representationExistsForURLScheme(const String& URLScheme) const
1010 {
1011     notImplemented();
1012     return false;
1013 }
1014 
generatedMIMETypeForURLScheme(const String & URLScheme) const1015 String WebFrameLoaderClient::generatedMIMETypeForURLScheme(const String& URLScheme) const
1016 {
1017     notImplemented();
1018     return String();
1019 }
1020 
frameLoadCompleted()1021 void WebFrameLoaderClient::frameLoadCompleted()
1022 {
1023     notImplemented();
1024 }
1025 
saveViewStateToItem(HistoryItem *)1026 void WebFrameLoaderClient::saveViewStateToItem(HistoryItem*)
1027 {
1028     notImplemented();
1029 }
1030 
restoreViewState()1031 void WebFrameLoaderClient::restoreViewState()
1032 {
1033     // Inform the UI process of the scale factor.
1034     double scaleFactor = m_frame->coreFrame()->loader()->history()->currentItem()->pageScaleFactor();
1035     m_frame->page()->send(Messages::WebPageProxy::ViewScaleFactorDidChange(scaleFactor));
1036 
1037     // FIXME: This should not be necessary. WebCore should be correctly invalidating
1038     // the view on restores from the back/forward cache.
1039     if (m_frame == m_frame->page()->mainFrame())
1040         m_frame->page()->drawingArea()->setNeedsDisplay(m_frame->page()->bounds());
1041 }
1042 
provisionalLoadStarted()1043 void WebFrameLoaderClient::provisionalLoadStarted()
1044 {
1045     notImplemented();
1046 }
1047 
didFinishLoad()1048 void WebFrameLoaderClient::didFinishLoad()
1049 {
1050     // If we have a load listener, notify it.
1051     if (WebFrame::LoadListener* loadListener = m_frame->loadListener())
1052         loadListener->didFinishLoad(m_frame);
1053 }
1054 
prepareForDataSourceReplacement()1055 void WebFrameLoaderClient::prepareForDataSourceReplacement()
1056 {
1057     notImplemented();
1058 }
1059 
createDocumentLoader(const ResourceRequest & request,const SubstituteData & data)1060 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& data)
1061 {
1062     return DocumentLoader::create(request, data);
1063 }
1064 
setTitle(const StringWithDirection & title,const KURL & url)1065 void WebFrameLoaderClient::setTitle(const StringWithDirection& title, const KURL& url)
1066 {
1067     WebPage* webPage = m_frame->page();
1068     if (!webPage || !webPage->pageGroup()->isVisibleToHistoryClient())
1069         return;
1070 
1071     // FIXME: use direction of title.
1072     WebProcess::shared().connection()->send(Messages::WebContext::DidUpdateHistoryTitle(webPage->pageID(),
1073         title.string(), url.string(), m_frame->frameID()), 0);
1074 }
1075 
userAgent(const KURL &)1076 String WebFrameLoaderClient::userAgent(const KURL&)
1077 {
1078     WebPage* webPage = m_frame->page();
1079     if (!webPage)
1080         return String();
1081 
1082     return webPage->userAgent();
1083 }
1084 
savePlatformDataToCachedFrame(CachedFrame *)1085 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame*)
1086 {
1087 }
1088 
transitionToCommittedFromCachedFrame(CachedFrame *)1089 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
1090 {
1091     WebPage* webPage = m_frame->page();
1092     bool isMainFrame = webPage->mainFrame() == m_frame;
1093 
1094     const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType();
1095     m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType);
1096 }
1097 
transitionToCommittedForNewPage()1098 void WebFrameLoaderClient::transitionToCommittedForNewPage()
1099 {
1100     WebPage* webPage = m_frame->page();
1101     Color backgroundColor = webPage->drawsTransparentBackground() ? Color::transparent : Color::white;
1102 
1103     bool isMainFrame = webPage->mainFrame() == m_frame;
1104 
1105 #if ENABLE(TILED_BACKING_STORE)
1106     IntSize currentVisibleContentSize = m_frame->coreFrame()->view() ? m_frame->coreFrame()->view()->actualVisibleContentRect().size() : IntSize();
1107     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, webPage->resizesToContentsLayoutSize(), isMainFrame && webPage->resizesToContentsEnabled());
1108 
1109     if (isMainFrame && webPage->resizesToContentsEnabled()) {
1110         m_frame->coreFrame()->view()->setDelegatesScrolling(true);
1111         m_frame->coreFrame()->view()->setPaintsEntireContents(true);
1112     }
1113 
1114     // The HistoryController will update the scroll position later if needed.
1115     m_frame->coreFrame()->view()->setActualVisibleContentRect(IntRect(IntPoint::zero(), currentVisibleContentSize));
1116 #else
1117     const String& mimeType = m_frame->coreFrame()->loader()->documentLoader()->response().mimeType();
1118     m_frameHasCustomRepresentation = isMainFrame && WebProcess::shared().shouldUseCustomRepresentationForMIMEType(mimeType);
1119 
1120     m_frame->coreFrame()->createView(webPage->size(), backgroundColor, false, IntSize(), false);
1121 #endif
1122 
1123     m_frame->coreFrame()->view()->setTransparent(!webPage->drawsBackground());
1124 }
1125 
didSaveToPageCache()1126 void WebFrameLoaderClient::didSaveToPageCache()
1127 {
1128     WebPage* webPage = m_frame->page();
1129     if (!webPage)
1130         return;
1131 
1132     if (m_frame->isMainFrame())
1133         return;
1134 
1135     webPage->send(Messages::WebPageProxy::DidSaveFrameToPageCache(m_frame->frameID()));
1136 }
1137 
didRestoreFromPageCache()1138 void WebFrameLoaderClient::didRestoreFromPageCache()
1139 {
1140     WebPage* webPage = m_frame->page();
1141     if (!webPage)
1142         return;
1143 
1144     if (m_frame->isMainFrame())
1145         return;
1146 
1147     WebFrame* parentFrame = static_cast<WebFrameLoaderClient*>(m_frame->coreFrame()->tree()->parent()->loader()->client())->webFrame();
1148     webPage->send(Messages::WebPageProxy::DidRestoreFrameFromPageCache(m_frame->frameID(), parentFrame->frameID()));
1149 }
1150 
dispatchDidBecomeFrameset(bool value)1151 void WebFrameLoaderClient::dispatchDidBecomeFrameset(bool value)
1152 {
1153     WebPage* webPage = m_frame->page();
1154     if (!webPage)
1155         return;
1156 
1157     webPage->send(Messages::WebPageProxy::FrameDidBecomeFrameSet(m_frame->frameID(), value));
1158 }
1159 
canCachePage() const1160 bool WebFrameLoaderClient::canCachePage() const
1161 {
1162     // We cannot cache frames that have custom representations because they are
1163     // rendered in the UIProcess.
1164     return !m_frameHasCustomRepresentation;
1165 }
1166 
download(ResourceHandle * handle,const ResourceRequest & request,const ResourceRequest & initialRequest,const ResourceResponse & response)1167 void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response)
1168 {
1169     m_frame->convertHandleToDownload(handle, request, initialRequest, response);
1170 }
1171 
createFrame(const KURL & url,const String & name,HTMLFrameOwnerElement * ownerElement,const String & referrer,bool allowsScrolling,int marginWidth,int marginHeight)1172 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
1173                                                     const String& referrer, bool allowsScrolling, int marginWidth, int marginHeight)
1174 {
1175     WebPage* webPage = m_frame->page();
1176 
1177     RefPtr<WebFrame> subframe = WebFrame::createSubframe(webPage, name, ownerElement);
1178 
1179     Frame* coreSubframe = subframe->coreFrame();
1180 
1181      // The creation of the frame may have run arbitrary JavaScript that removed it from the page already.
1182     m_frame->coreFrame()->loader()->loadURLIntoChildFrame(url, referrer, coreSubframe);
1183 
1184     // The frame's onload handler may have removed it from the document.
1185     if (!coreSubframe->tree()->parent())
1186         return 0;
1187 
1188     return coreSubframe;
1189 }
1190 
didTransferChildFrameToNewDocument(Page *)1191 void WebFrameLoaderClient::didTransferChildFrameToNewDocument(Page*)
1192 {
1193     notImplemented();
1194 }
1195 
transferLoadingResourceFromPage(unsigned long,DocumentLoader *,const ResourceRequest &,Page *)1196 void WebFrameLoaderClient::transferLoadingResourceFromPage(unsigned long, DocumentLoader*, const ResourceRequest&, Page*)
1197 {
1198     notImplemented();
1199 }
1200 
createPlugin(const IntSize &,HTMLPlugInElement * pluginElement,const KURL & url,const Vector<String> & paramNames,const Vector<String> & paramValues,const String & mimeType,bool loadManually)1201 PassRefPtr<Widget> WebFrameLoaderClient::createPlugin(const IntSize&, HTMLPlugInElement* pluginElement, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
1202 {
1203     ASSERT(paramNames.size() == paramValues.size());
1204 
1205     WebPage* webPage = m_frame->page();
1206     ASSERT(webPage);
1207 
1208     Plugin::Parameters parameters;
1209     parameters.url = url;
1210     parameters.names = paramNames;
1211     parameters.values = paramValues;
1212     parameters.mimeType = mimeType;
1213     parameters.loadManually = loadManually;
1214 
1215     // <rdar://problem/8440903>: AppleConnect has a bug where it does not
1216     // understand the parameter names specified in the <object> element that
1217     // embeds its plug-in. This hack works around the issue by converting the
1218     // parameter names to lowercase before passing them to the plug-in.
1219     // FIXME: This workaround should be dependent on site-specific quirks being
1220     // enabled. This requires adding this setting to WebKit2's WebPreferences
1221     // implementation. See <https://bugs.webkit.org/show_bug.cgi?id=46076>.
1222     if (equalIgnoringCase(mimeType, "application/x-snkp")) {
1223         for (size_t i = 0; i < paramNames.size(); ++i)
1224             parameters.names[i] = paramNames[i].lower();
1225     }
1226 
1227 #if PLUGIN_ARCHITECTURE(X11)
1228     if (equalIgnoringCase(mimeType, "application/x-shockwave-flash")) {
1229         // Currently we don't support transparency and windowed mode.
1230         // Inject wmode=opaque to make Flash work in these conditions.
1231         size_t wmodeIndex = parameters.names.find("wmode");
1232         if (wmodeIndex == -1) {
1233             parameters.names.append("wmode");
1234             parameters.values.append("opaque");
1235         } else if (equalIgnoringCase(parameters.values[wmodeIndex], "window"))
1236             parameters.values[wmodeIndex] = "opaque";
1237     }
1238 #endif
1239 
1240     RefPtr<Plugin> plugin = webPage->createPlugin(parameters);
1241     if (!plugin)
1242         return 0;
1243 
1244     return PluginView::create(pluginElement, plugin.release(), parameters);
1245 }
1246 
redirectDataToPlugin(Widget * pluginWidget)1247 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
1248 {
1249     ASSERT(!m_pluginView);
1250     ASSERT(pluginWidget);
1251 
1252     m_pluginView = static_cast<PluginView*>(pluginWidget);
1253 }
1254 
createJavaAppletWidget(const IntSize & pluginSize,HTMLAppletElement * appletElement,const KURL & baseURL,const Vector<String> & paramNames,const Vector<String> & paramValues)1255 PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& pluginSize, HTMLAppletElement* appletElement, const KURL& baseURL, const Vector<String>& paramNames, const Vector<String>& paramValues)
1256 {
1257     const String mimeType = "application/x-java-applet";
1258     RefPtr<Widget> plugin = createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, mimeType, false);
1259     if (!plugin) {
1260         if (WebPage* webPage = m_frame->page())
1261             webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(mimeType));
1262     }
1263     return plugin.release();
1264 }
1265 
pluginSupportsExtension(PluginData * pluginData,const String & extension)1266 static bool pluginSupportsExtension(PluginData* pluginData, const String& extension)
1267 {
1268     ASSERT(extension.lower() == extension);
1269 
1270     for (size_t i = 0; i < pluginData->mimes().size(); ++i) {
1271         const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i];
1272 
1273         if (mimeClassInfo.extensions.contains(extension))
1274             return true;
1275     }
1276     return false;
1277 }
1278 
objectContentType(const KURL & url,const String & mimeTypeIn,bool shouldPreferPlugInsForImages)1279 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
1280 {
1281     // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
1282     // is consolidated.
1283 
1284     String mimeType = mimeTypeIn;
1285     if (mimeType.isEmpty()) {
1286         String extension = url.path().substring(url.path().reverseFind('.') + 1).lower();
1287 
1288         // Try to guess the MIME type from the extension.
1289         mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1290 
1291         if (mimeType.isEmpty()) {
1292             // Check if there's a plug-in around that can handle the extension.
1293             if (WebPage* webPage = m_frame->page()) {
1294                 if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1295                     if (pluginSupportsExtension(pluginData, extension))
1296                         return ObjectContentNetscapePlugin;
1297                 }
1298             }
1299         }
1300     }
1301 
1302     if (mimeType.isEmpty())
1303         return ObjectContentFrame;
1304 
1305     bool plugInSupportsMIMEType = false;
1306     if (WebPage* webPage = m_frame->page()) {
1307         if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1308             if (pluginData->supportsMimeType(mimeType))
1309                 plugInSupportsMIMEType = true;
1310         }
1311     }
1312 
1313     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1314         return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage;
1315 
1316     if (plugInSupportsMIMEType)
1317         return ObjectContentNetscapePlugin;
1318 
1319     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1320         return ObjectContentFrame;
1321 
1322     return ObjectContentNone;
1323 }
1324 
overrideMediaType() const1325 String WebFrameLoaderClient::overrideMediaType() const
1326 {
1327     notImplemented();
1328     return String();
1329 }
1330 
dispatchDidClearWindowObjectInWorld(DOMWrapperWorld * world)1331 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1332 {
1333     WebPage* webPage = m_frame->page();
1334     if (!webPage)
1335         return;
1336 
1337     webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1338 }
1339 
documentElementAvailable()1340 void WebFrameLoaderClient::documentElementAvailable()
1341 {
1342     notImplemented();
1343 }
1344 
didPerformFirstNavigation() const1345 void WebFrameLoaderClient::didPerformFirstNavigation() const
1346 {
1347     notImplemented();
1348 }
1349 
registerForIconNotification(bool listen)1350 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1351 {
1352     notImplemented();
1353 }
1354 
1355 #if PLATFORM(MAC)
1356 
accessibilityRemoteObject()1357 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject()
1358 {
1359     return m_frame->page()->accessibilityRemoteObject();
1360 }
1361 
1362 #if ENABLE(MAC_JAVA_BRIDGE)
javaApplet(NSView *)1363 jobject WebFrameLoaderClient::javaApplet(NSView*) { return 0; }
1364 #endif
willCacheResponse(DocumentLoader *,unsigned long identifier,NSCachedURLResponse * response) const1365 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1366 {
1367     return response;
1368 }
1369 
1370 #endif
1371 #if PLATFORM(WIN) && USE(CFNETWORK)
shouldCacheResponse(DocumentLoader *,unsigned long identifier,const ResourceResponse &,const unsigned char * data,unsigned long long length)1372 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length)
1373 {
1374     return true;
1375 }
1376 
1377 #endif
1378 
shouldUsePluginDocument(const String &) const1379 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& /*mimeType*/) const
1380 {
1381     notImplemented();
1382     return false;
1383 }
1384 
didChangeScrollOffset()1385 void WebFrameLoaderClient::didChangeScrollOffset()
1386 {
1387     WebPage* webPage = m_frame->page();
1388     if (!webPage)
1389         return;
1390 
1391     if (!m_frame->isMainFrame())
1392         return;
1393 
1394     // If this is called when tearing down a FrameView, the WebCore::Frame's
1395     // current FrameView will be null.
1396     if (!m_frame->coreFrame()->view())
1397         return;
1398 
1399     webPage->didChangeScrollOffsetForMainFrame();
1400 }
1401 
createNetworkingContext()1402 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1403 {
1404     return WebFrameNetworkingContext::create(m_frame->coreFrame());
1405 }
1406 
1407 } // namespace WebKit
1408