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