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()421 void WebFrameLoaderClient::dispatchDidChangeIcons()
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 return createPlugin(pluginSize, appletElement, KURL(), paramNames, paramValues, "application/x-java-applet", false);
1258 }
1259
pluginSupportsExtension(PluginData * pluginData,const String & extension)1260 static bool pluginSupportsExtension(PluginData* pluginData, const String& extension)
1261 {
1262 ASSERT(extension.lower() == extension);
1263
1264 for (size_t i = 0; i < pluginData->mimes().size(); ++i) {
1265 const MimeClassInfo& mimeClassInfo = pluginData->mimes()[i];
1266
1267 if (mimeClassInfo.extensions.contains(extension))
1268 return true;
1269 }
1270 return false;
1271 }
1272
objectContentType(const KURL & url,const String & mimeTypeIn,bool shouldPreferPlugInsForImages)1273 ObjectContentType WebFrameLoaderClient::objectContentType(const KURL& url, const String& mimeTypeIn, bool shouldPreferPlugInsForImages)
1274 {
1275 // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
1276 // is consolidated.
1277
1278 String mimeType = mimeTypeIn;
1279 if (mimeType.isEmpty()) {
1280 String extension = url.path().substring(url.path().reverseFind('.') + 1).lower();
1281
1282 // Try to guess the MIME type from the extension.
1283 mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
1284
1285 if (mimeType.isEmpty()) {
1286 // Check if there's a plug-in around that can handle the extension.
1287 if (WebPage* webPage = m_frame->page()) {
1288 if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1289 if (pluginSupportsExtension(pluginData, extension))
1290 return ObjectContentNetscapePlugin;
1291 }
1292 }
1293 }
1294 }
1295
1296 if (mimeType.isEmpty())
1297 return ObjectContentFrame;
1298
1299 bool plugInSupportsMIMEType = false;
1300 if (WebPage* webPage = m_frame->page()) {
1301 if (PluginData* pluginData = webPage->corePage()->pluginData()) {
1302 if (pluginData->supportsMimeType(mimeType))
1303 plugInSupportsMIMEType = true;
1304 }
1305 }
1306
1307 if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
1308 return shouldPreferPlugInsForImages && plugInSupportsMIMEType ? ObjectContentNetscapePlugin : ObjectContentImage;
1309
1310 if (plugInSupportsMIMEType)
1311 return ObjectContentNetscapePlugin;
1312
1313 if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
1314 return ObjectContentFrame;
1315
1316 return ObjectContentNone;
1317 }
1318
overrideMediaType() const1319 String WebFrameLoaderClient::overrideMediaType() const
1320 {
1321 notImplemented();
1322 return String();
1323 }
1324
dispatchDidClearWindowObjectInWorld(DOMWrapperWorld * world)1325 void WebFrameLoaderClient::dispatchDidClearWindowObjectInWorld(DOMWrapperWorld* world)
1326 {
1327 WebPage* webPage = m_frame->page();
1328 if (!webPage)
1329 return;
1330
1331 webPage->injectedBundleLoaderClient().didClearWindowObjectForFrame(webPage, m_frame, world);
1332 }
1333
documentElementAvailable()1334 void WebFrameLoaderClient::documentElementAvailable()
1335 {
1336 notImplemented();
1337 }
1338
didPerformFirstNavigation() const1339 void WebFrameLoaderClient::didPerformFirstNavigation() const
1340 {
1341 notImplemented();
1342 }
1343
registerForIconNotification(bool listen)1344 void WebFrameLoaderClient::registerForIconNotification(bool listen)
1345 {
1346 notImplemented();
1347 }
1348
1349 #if PLATFORM(MAC)
1350
accessibilityRemoteObject()1351 RemoteAXObjectRef WebFrameLoaderClient::accessibilityRemoteObject()
1352 {
1353 return m_frame->page()->accessibilityRemoteObject();
1354 }
1355
1356 #if ENABLE(MAC_JAVA_BRIDGE)
javaApplet(NSView *)1357 jobject WebFrameLoaderClient::javaApplet(NSView*) { return 0; }
1358 #endif
willCacheResponse(DocumentLoader *,unsigned long identifier,NSCachedURLResponse * response) const1359 NSCachedURLResponse* WebFrameLoaderClient::willCacheResponse(DocumentLoader*, unsigned long identifier, NSCachedURLResponse* response) const
1360 {
1361 return response;
1362 }
1363
1364 #endif
1365 #if USE(CFNETWORK)
shouldCacheResponse(DocumentLoader *,unsigned long identifier,const ResourceResponse &,const unsigned char * data,unsigned long long length)1366 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader*, unsigned long identifier, const ResourceResponse&, const unsigned char* data, unsigned long long length)
1367 {
1368 return true;
1369 }
1370
1371 #endif
1372
shouldUsePluginDocument(const String &) const1373 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& /*mimeType*/) const
1374 {
1375 notImplemented();
1376 return false;
1377 }
1378
didChangeScrollOffset()1379 void WebFrameLoaderClient::didChangeScrollOffset()
1380 {
1381 WebPage* webPage = m_frame->page();
1382 if (!webPage)
1383 return;
1384
1385 if (!m_frame->isMainFrame())
1386 return;
1387
1388 // If this is called when tearing down a FrameView, the WebCore::Frame's
1389 // current FrameView will be null.
1390 if (!m_frame->coreFrame()->view())
1391 return;
1392
1393 webPage->didChangeScrollOffsetForMainFrame();
1394 }
1395
createNetworkingContext()1396 PassRefPtr<FrameNetworkingContext> WebFrameLoaderClient::createNetworkingContext()
1397 {
1398 return WebFrameNetworkingContext::create(m_frame->coreFrame());
1399 }
1400
1401 } // namespace WebKit
1402