2 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14 * its contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "WebFrameLoaderClient.h"
32 #include "CFDictionaryPropertyBag.h"
33 #include "COMPropertyBag.h"
34 #include "DOMHTMLClasses.h"
35 #include "EmbeddedWidget.h"
36 #include "MarshallingHelpers.h"
37 #include "NotImplemented.h"
38 #include "WebCachedFramePlatformData.h"
39 #include "WebChromeClient.h"
40 #include "WebDocumentLoader.h"
43 #include "WebHistory.h"
44 #include "WebHistoryItem.h"
45 #include "WebMutableURLRequest.h"
46 #include "WebNotificationCenter.h"
47 #include "WebScriptDebugServer.h"
48 #include "WebURLAuthenticationChallenge.h"
49 #include "WebURLResponse.h"
51 #pragma warning(push, 0)
52 #include <WebCore/CachedFrame.h>
53 #include <WebCore/DocumentLoader.h>
54 #include <WebCore/FrameLoader.h>
55 #include <WebCore/FrameTree.h>
56 #include <WebCore/FrameView.h>
57 #include <WebCore/HTMLAppletElement.h>
58 #include <WebCore/HTMLFrameElement.h>
59 #include <WebCore/HTMLFrameOwnerElement.h>
60 #include <WebCore/HTMLNames.h>
61 #include <WebCore/HTMLPlugInElement.h>
62 #include <WebCore/HistoryItem.h>
63 #include <WebCore/Page.h>
64 #include <WebCore/PluginPackage.h>
65 #include <WebCore/PluginView.h>
66 #include <WebCore/RenderPart.h>
67 #include <WebCore/ResourceHandle.h>
70 using namespace WebCore;
71 using namespace HTMLNames;
73 static WebDataSource* getWebDataSource(DocumentLoader* loader)
75 return loader ? static_cast<WebDocumentLoader*>(loader)->dataSource() : 0;
78 WebFrameLoaderClient::WebFrameLoaderClient(WebFrame* webFrame)
79 : m_webFrame(webFrame)
81 , m_hasSentResponseToPlugin(false)
83 ASSERT_ARG(webFrame, webFrame);
86 WebFrameLoaderClient::~WebFrameLoaderClient()
90 bool WebFrameLoaderClient::hasWebView() const
92 return m_webFrame->webView();
95 void WebFrameLoaderClient::forceLayout()
97 FrameView* view = core(m_webFrame)->view();
99 view->forceLayout(true);
102 void WebFrameLoaderClient::assignIdentifierToInitialRequest(unsigned long identifier, DocumentLoader* loader, const ResourceRequest& request)
104 WebView* webView = m_webFrame->webView();
105 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
106 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
109 COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
110 resourceLoadDelegate->identifierForInitialRequest(webView, webURLRequest.get(), getWebDataSource(loader), identifier);
113 bool WebFrameLoaderClient::shouldUseCredentialStorage(DocumentLoader* loader, unsigned long identifier)
115 WebView* webView = m_webFrame->webView();
116 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
117 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
120 COMPtr<IWebResourceLoadDelegatePrivate2> resourceLoadDelegatePrivate;
121 if (FAILED(resourceLoadDelegate->QueryInterface(IID_IWebResourceLoadDelegatePrivate2, reinterpret_cast<void**>(&resourceLoadDelegatePrivate))))
125 if (SUCCEEDED(resourceLoadDelegatePrivate->shouldUseCredentialStorage(webView, identifier, getWebDataSource(loader), &shouldUse)))
131 void WebFrameLoaderClient::dispatchDidReceiveAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
134 ASSERT(challenge.sourceHandle());
136 WebView* webView = m_webFrame->webView();
137 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
138 if (SUCCEEDED(webView->resourceLoadDelegate(&resourceLoadDelegate))) {
139 COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
140 if (SUCCEEDED(resourceLoadDelegate->didReceiveAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader))))
144 // If the ResourceLoadDelegate doesn't exist or fails to handle the call, we tell the ResourceHandle
145 // to continue without credential - this is the best approximation of Mac behavior
146 challenge.sourceHandle()->receivedRequestToContinueWithoutCredential(challenge);
152 void WebFrameLoaderClient::dispatchDidCancelAuthenticationChallenge(DocumentLoader* loader, unsigned long identifier, const AuthenticationChallenge& challenge)
154 WebView* webView = m_webFrame->webView();
155 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
156 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
159 COMPtr<WebURLAuthenticationChallenge> webChallenge(AdoptCOM, WebURLAuthenticationChallenge::createInstance(challenge));
160 resourceLoadDelegate->didCancelAuthenticationChallenge(webView, identifier, webChallenge.get(), getWebDataSource(loader));
163 void WebFrameLoaderClient::dispatchWillSendRequest(DocumentLoader* loader, unsigned long identifier, ResourceRequest& request, const ResourceResponse& redirectResponse)
165 WebView* webView = m_webFrame->webView();
166 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
167 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
170 COMPtr<WebMutableURLRequest> webURLRequest(AdoptCOM, WebMutableURLRequest::createInstance(request));
171 COMPtr<WebURLResponse> webURLRedirectResponse(AdoptCOM, WebURLResponse::createInstance(redirectResponse));
173 COMPtr<IWebURLRequest> newWebURLRequest;
174 if (FAILED(resourceLoadDelegate->willSendRequest(webView, identifier, webURLRequest.get(), webURLRedirectResponse.get(), getWebDataSource(loader), &newWebURLRequest)))
177 if (webURLRequest == newWebURLRequest)
180 COMPtr<WebMutableURLRequest> newWebURLRequestImpl(Query, newWebURLRequest);
181 if (!newWebURLRequestImpl)
184 request = newWebURLRequestImpl->resourceRequest();
187 void WebFrameLoaderClient::dispatchDidReceiveResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response)
189 WebView* webView = m_webFrame->webView();
190 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
191 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
194 COMPtr<WebURLResponse> webURLResponse(AdoptCOM, WebURLResponse::createInstance(response));
195 resourceLoadDelegate->didReceiveResponse(webView, identifier, webURLResponse.get(), getWebDataSource(loader));
198 void WebFrameLoaderClient::dispatchDidReceiveContentLength(DocumentLoader* loader, unsigned long identifier, int length)
200 WebView* webView = m_webFrame->webView();
201 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
202 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
205 resourceLoadDelegate->didReceiveContentLength(webView, identifier, length, getWebDataSource(loader));
208 void WebFrameLoaderClient::dispatchDidFinishLoading(DocumentLoader* loader, unsigned long identifier)
210 WebView* webView = m_webFrame->webView();
211 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
212 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
215 resourceLoadDelegate->didFinishLoadingFromDataSource(webView, identifier, getWebDataSource(loader));
218 void WebFrameLoaderClient::dispatchDidFailLoading(DocumentLoader* loader, unsigned long identifier, const ResourceError& error)
220 WebView* webView = m_webFrame->webView();
221 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
222 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
225 COMPtr<WebError> webError(AdoptCOM, WebError::createInstance(error));
226 resourceLoadDelegate->didFailLoadingWithError(webView, identifier, webError.get(), getWebDataSource(loader));
229 bool WebFrameLoaderClient::shouldCacheResponse(DocumentLoader* loader, unsigned long identifier, const ResourceResponse& response, const unsigned char* data, const unsigned long long length)
231 WebView* webView = m_webFrame->webView();
232 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
233 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
236 COMPtr<IWebResourceLoadDelegatePrivate3> resourceLoadDelegatePrivate(Query, resourceLoadDelegate);
237 if (!resourceLoadDelegatePrivate)
240 COMPtr<IWebURLResponse> urlResponse(WebURLResponse::createInstance(response));
242 if (SUCCEEDED(resourceLoadDelegatePrivate->shouldCacheResponse(webView, identifier, urlResponse.get(), data, length, getWebDataSource(loader), &shouldCache)))
248 void WebFrameLoaderClient::dispatchDidHandleOnloadEvents()
250 WebView* webView = m_webFrame->webView();
251 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
252 if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
253 frameLoadDelegatePriv->didHandleOnloadEventsForFrame(webView, m_webFrame);
256 void WebFrameLoaderClient::dispatchDidReceiveServerRedirectForProvisionalLoad()
258 WebView* webView = m_webFrame->webView();
259 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
260 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
261 frameLoadDelegate->didReceiveServerRedirectForProvisionalLoadForFrame(webView, m_webFrame);
264 void WebFrameLoaderClient::dispatchDidCancelClientRedirect()
266 WebView* webView = m_webFrame->webView();
267 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
268 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
269 frameLoadDelegate->didCancelClientRedirectForFrame(webView, m_webFrame);
272 void WebFrameLoaderClient::dispatchWillPerformClientRedirect(const KURL& url, double delay, double fireDate)
274 WebView* webView = m_webFrame->webView();
275 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
276 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
277 frameLoadDelegate->willPerformClientRedirectToURL(webView, BString(url.string()), delay, MarshallingHelpers::CFAbsoluteTimeToDATE(fireDate), m_webFrame);
280 void WebFrameLoaderClient::dispatchDidChangeLocationWithinPage()
282 WebView* webView = m_webFrame->webView();
283 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
284 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
285 frameLoadDelegate->didChangeLocationWithinPageForFrame(webView, m_webFrame);
288 void WebFrameLoaderClient::dispatchWillClose()
290 WebView* webView = m_webFrame->webView();
291 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
292 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
293 frameLoadDelegate->willCloseFrame(webView, m_webFrame);
296 void WebFrameLoaderClient::dispatchDidReceiveIcon()
298 m_webFrame->webView()->dispatchDidReceiveIconFromWebFrame(m_webFrame);
301 void WebFrameLoaderClient::dispatchDidStartProvisionalLoad()
303 WebView* webView = m_webFrame->webView();
304 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
305 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
306 frameLoadDelegate->didStartProvisionalLoadForFrame(webView, m_webFrame);
309 void WebFrameLoaderClient::dispatchDidReceiveTitle(const String& title)
311 WebView* webView = m_webFrame->webView();
312 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
313 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
314 frameLoadDelegate->didReceiveTitle(webView, BString(title), m_webFrame);
317 void WebFrameLoaderClient::dispatchDidCommitLoad()
319 WebView* webView = m_webFrame->webView();
320 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
321 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
322 frameLoadDelegate->didCommitLoadForFrame(webView, m_webFrame);
325 void WebFrameLoaderClient::dispatchDidFinishDocumentLoad()
327 WebView* webView = m_webFrame->webView();
328 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
329 if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
330 frameLoadDelegatePriv->didFinishDocumentLoadForFrame(webView, m_webFrame);
333 void WebFrameLoaderClient::dispatchDidFinishLoad()
335 WebView* webView = m_webFrame->webView();
336 COMPtr<IWebFrameLoadDelegate> frameLoadDelegate;
337 if (SUCCEEDED(webView->frameLoadDelegate(&frameLoadDelegate)))
338 frameLoadDelegate->didFinishLoadForFrame(webView, m_webFrame);
341 void WebFrameLoaderClient::dispatchDidFirstLayout()
343 WebView* webView = m_webFrame->webView();
344 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePriv;
345 if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePriv)) && frameLoadDelegatePriv)
346 frameLoadDelegatePriv->didFirstLayoutInFrame(webView, m_webFrame);
349 void WebFrameLoaderClient::dispatchDidFirstVisuallyNonEmptyLayout()
351 WebView* webView = m_webFrame->webView();
352 COMPtr<IWebFrameLoadDelegatePrivate> frameLoadDelegatePrivate;
353 if (SUCCEEDED(webView->frameLoadDelegatePrivate(&frameLoadDelegatePrivate)) && frameLoadDelegatePrivate) {
354 COMPtr<IWebFrameLoadDelegatePrivate2> frameLoadDelegatePrivate2(Query, frameLoadDelegatePrivate);
355 if (frameLoadDelegatePrivate2)
356 frameLoadDelegatePrivate2->didFirstVisuallyNonEmptyLayoutInFrame(webView, m_webFrame);
360 Frame* WebFrameLoaderClient::dispatchCreatePage()
362 WebView* webView = m_webFrame->webView();
364 COMPtr<IWebUIDelegate> ui;
365 if (FAILED(webView->uiDelegate(&ui)))
368 COMPtr<IWebView> newWebView;
369 if (FAILED(ui->createWebViewWithRequest(webView, 0, &newWebView)))
372 COMPtr<IWebFrame> mainFrame;
373 if (FAILED(newWebView->mainFrame(&mainFrame)))
376 COMPtr<WebFrame> mainFrameImpl(Query, mainFrame);
377 return core(mainFrameImpl.get());
380 void WebFrameLoaderClient::dispatchShow()
382 WebView* webView = m_webFrame->webView();
383 COMPtr<IWebUIDelegate> ui;
384 if (SUCCEEDED(webView->uiDelegate(&ui)))
385 ui->webViewShow(webView);
388 void WebFrameLoaderClient::dispatchDidLoadMainResource(DocumentLoader*)
392 void WebFrameLoaderClient::setMainDocumentError(DocumentLoader*, const ResourceError& error)
397 m_manualLoader->didFail(error);
399 m_hasSentResponseToPlugin = false;
402 void WebFrameLoaderClient::postProgressStartedNotification()
404 static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification);
405 IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
406 notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
409 void WebFrameLoaderClient::postProgressEstimateChangedNotification()
411 static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification);
412 IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
413 notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
416 void WebFrameLoaderClient::postProgressFinishedNotification()
418 static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification);
419 IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal();
420 notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);
423 void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length)
425 // FIXME: This should probably go through the data source.
426 const String& textEncoding = loader->response().textEncodingName();
429 receivedData(data, length, textEncoding);
434 if (!m_hasSentResponseToPlugin) {
435 m_manualLoader->didReceiveResponse(core(m_webFrame)->loader()->documentLoader()->response());
436 // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in
437 // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader
441 m_hasSentResponseToPlugin = true;
443 m_manualLoader->didReceiveData(data, length);
446 void WebFrameLoaderClient::receivedData(const char* data, int length, const String& textEncoding)
448 Frame* coreFrame = core(m_webFrame);
452 // Set the encoding. This only needs to be done once, but it's harmless to do it again later.
453 String encoding = coreFrame->loader()->documentLoader()->overrideEncoding();
454 bool userChosen = !encoding.isNull();
455 if (encoding.isNull())
456 encoding = textEncoding;
457 coreFrame->loader()->setEncoding(encoding, userChosen);
459 coreFrame->loader()->addData(data, length);
462 void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader)
464 // Telling the frame we received some data and passing 0 as the data is our
465 // way to get work done that is normally done when the first bit of data is
466 // received, even for the case of a document with no data (like about:blank)
467 if (!m_manualLoader) {
468 committedLoad(loader, 0, 0);
472 m_manualLoader->didFinishLoading();
474 m_hasSentResponseToPlugin = false;
477 void WebFrameLoaderClient::updateGlobalHistory()
479 WebHistory* history = WebHistory::sharedHistory();
483 DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
484 history->visitedURL(loader->urlForHistory(), loader->title(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure());
485 updateGlobalHistoryRedirectLinks();
488 void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks()
490 WebHistory* history = WebHistory::sharedHistory();
494 DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader();
496 if (!loader->clientRedirectSourceForHistory().isNull()) {
497 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) {
498 COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
499 webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory());
503 if (!loader->serverRedirectSourceForHistory().isNull()) {
504 if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) {
505 COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem);
506 webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory());
511 bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const
516 PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData)
518 RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData);
520 COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.get()));
522 loader->setDataSource(dataSource.get());
523 return loader.release();
526 void WebFrameLoaderClient::setTitle(const String& title, const KURL& url)
528 BOOL privateBrowsingEnabled = FALSE;
529 COMPtr<IWebPreferences> preferences;
530 if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences)))
531 preferences->privateBrowsingEnabled(&privateBrowsingEnabled);
532 if (privateBrowsingEnabled)
535 // update title in global history
536 COMPtr<WebHistory> history = webHistory();
540 COMPtr<IWebHistoryItem> item;
541 if (FAILED(history->itemForURL(BString(url.string()), &item)))
544 COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item);
548 itemPrivate->setTitle(BString(title));
551 void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame)
554 Frame* coreFrame = core(m_webFrame);
558 ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader());
560 WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader())));
561 cachedFrame->setCachedFramePlatformData(webPlatformData);
567 void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*)
571 void WebFrameLoaderClient::transitionToCommittedForNewPage()
573 WebView* view = m_webFrame->webView();
576 view->frameRect(&rect);
577 bool transparent = view->transparent();
578 Color backgroundColor = transparent ? Color::transparent : Color::white;
579 core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false);
582 bool WebFrameLoaderClient::canCachePage() const
587 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement,
588 const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/)
590 RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer);
593 return result.release();
596 PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer)
598 Frame* coreFrame = core(m_webFrame);
601 COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance());
603 RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement);
605 coreFrame->tree()->appendChild(childFrame);
606 childFrame->tree()->setName(name);
609 loadURLIntoChild(URL, referrer, webFrame.get());
611 // The frame's onload handler may have removed it from the document.
612 if (!childFrame->tree()->parent())
615 return childFrame.release();
618 void WebFrameLoaderClient::loadURLIntoChild(const KURL& originalURL, const String& referrer, WebFrame* childFrame)
621 ASSERT(core(childFrame));
623 Frame* coreFrame = core(m_webFrame);
626 HistoryItem* parentItem = coreFrame->loader()->currentHistoryItem();
627 FrameLoadType loadType = coreFrame->loader()->loadType();
628 FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedBackForwardList;
630 KURL url = originalURL;
632 // If we're moving in the backforward list, we might want to replace the content
633 // of this child frame with whatever was there at that point.
634 // Reload will maintain the frame contents, LoadSame will not.
635 if (parentItem && parentItem->children().size() && isBackForwardLoadType(loadType)) {
636 if (HistoryItem* childItem = parentItem->childItemWithName(core(childFrame)->tree()->name())) {
637 // Use the original URL to ensure we get all the side-effects, such as
638 // onLoad handlers, of any redirects that happened. An example of where
639 // this is needed is Radar 3213556.
640 url = childItem->originalURL();
641 // These behaviors implied by these loadTypes should apply to the child frames
642 childLoadType = loadType;
644 if (isBackForwardLoadType(loadType))
645 // For back/forward, remember this item so we can traverse any child items as child frames load
646 core(childFrame)->loader()->setProvisionalHistoryItem(childItem);
648 // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item
649 core(childFrame)->loader()->setCurrentHistoryItem(childItem);
653 // FIXME: Handle loading WebArchives here
654 String frameName = core(childFrame)->tree()->name();
655 core(childFrame)->loader()->loadURL(url, referrer, frameName, false, childLoadType, 0, 0);
658 Widget* WebFrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually)
660 WebView* webView = m_webFrame->webView();
662 COMPtr<IWebUIDelegate> ui;
663 if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) {
664 COMPtr<IWebUIDelegatePrivate4> uiPrivate(Query, ui);
667 // Assemble the view arguments in a property bag.
668 HashMap<String, String> viewArguments;
669 for (unsigned i = 0; i < paramNames.size(); i++)
670 viewArguments.set(paramNames[i], paramValues[i]);
671 COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments));
672 COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element));
674 HashMap<String, COMVariant> arguments;
676 arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag);
677 arguments.set(WebEmbeddedViewBaseURLKey, url.string());
678 arguments.set(WebEmbeddedViewContainingElementKey, containingElement);
679 arguments.set(WebEmbeddedViewMIMETypeKey, mimeType);
681 COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments));
683 COMPtr<IWebEmbeddedView> view;
684 HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view);
685 if (SUCCEEDED(result)) {
687 HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow);
688 ASSERT(SUCCEEDED(hr));
690 return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize);
695 Frame* frame = core(m_webFrame);
696 PluginView* pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually);
698 if (pluginView->status() == PluginStatusLoadedSuccessfully)
701 COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate;
703 if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate)))
706 RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
708 unsigned count = (unsigned)paramNames.size();
709 for (unsigned i = 0; i < count; i++) {
710 if (paramNames[i] == "pluginspage") {
711 static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey);
712 RetainPtr<CFStringRef> str(AdoptCF, paramValues[i].createCFString());
713 CFDictionarySetValue(userInfo.get(), key, str.get());
718 if (!mimeType.isNull()) {
719 static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey);
721 RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString());
722 CFDictionarySetValue(userInfo.get(), key, str.get());
726 if (pluginView->plugin())
727 pluginName = pluginView->plugin()->name();
728 if (!pluginName.isNull()) {
729 static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey);
730 RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString());
731 CFDictionarySetValue(userInfo.get(), key, str.get());
734 COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance());
735 userInfoBag->setDictionary(userInfo.get());
738 switch (pluginView->status()) {
739 case PluginStatusCanNotFindPlugin:
740 errorCode = WebKitErrorCannotFindPlugIn;
742 case PluginStatusCanNotLoadPlugin:
743 errorCode = WebKitErrorCannotLoadPlugIn;
746 ASSERT_NOT_REACHED();
749 ResourceError resourceError(String(WebKitErrorDomain), errorCode, url.string(), String());
750 COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get()));
752 resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader()));
757 void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget)
759 // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889>
761 if (pluginWidget->isPluginView())
762 m_manualLoader = static_cast<PluginView*>(pluginWidget);
764 m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);
767 WebHistory* WebFrameLoaderClient::webHistory() const
769 if (m_webFrame != m_webFrame->webView()->topLevelFrame())
772 return WebHistory::sharedHistory();
775 bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const
777 WebView* webView = m_webFrame->webView();
781 return webView->shouldUseEmbeddedView(mimeType);