📄 webframeloaderclient.cpp
字号:
void WebFrameLoaderClient::postProgressStartedNotification(){ static BSTR progressStartedName = SysAllocString(WebViewProgressStartedNotification); IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal(); notifyCenter->postNotificationName(progressStartedName, static_cast<IWebView*>(m_webFrame->webView()), 0);}void WebFrameLoaderClient::postProgressEstimateChangedNotification(){ static BSTR progressEstimateChangedName = SysAllocString(WebViewProgressEstimateChangedNotification); IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal(); notifyCenter->postNotificationName(progressEstimateChangedName, static_cast<IWebView*>(m_webFrame->webView()), 0);}void WebFrameLoaderClient::postProgressFinishedNotification(){ static BSTR progressFinishedName = SysAllocString(WebViewProgressFinishedNotification); IWebNotificationCenter* notifyCenter = WebNotificationCenter::defaultCenterInternal(); notifyCenter->postNotificationName(progressFinishedName, static_cast<IWebView*>(m_webFrame->webView()), 0);}void WebFrameLoaderClient::committedLoad(DocumentLoader* loader, const char* data, int length){ // FIXME: This should probably go through the data source. const String& textEncoding = loader->response().textEncodingName(); if (!m_manualLoader) receivedData(data, length, textEncoding); if (!m_manualLoader) return; if (!m_hasSentResponseToPlugin) { m_manualLoader->didReceiveResponse(core(m_webFrame)->loader()->documentLoader()->response()); // didReceiveResponse sets up a new stream to the plug-in. on a full-page plug-in, a failure in // setting up this stream can cause the main document load to be cancelled, setting m_manualLoader // to null if (!m_manualLoader) return; m_hasSentResponseToPlugin = true; } m_manualLoader->didReceiveData(data, length);}void WebFrameLoaderClient::receivedData(const char* data, int length, const String& textEncoding){ Frame* coreFrame = core(m_webFrame); if (!coreFrame) return; // Set the encoding. This only needs to be done once, but it's harmless to do it again later. String encoding = coreFrame->loader()->documentLoader()->overrideEncoding(); bool userChosen = !encoding.isNull(); if (encoding.isNull()) encoding = textEncoding; coreFrame->loader()->setEncoding(encoding, userChosen); coreFrame->loader()->addData(data, length);}void WebFrameLoaderClient::finishedLoading(DocumentLoader* loader){ // Telling the frame we received some data and passing 0 as the data is our // way to get work done that is normally done when the first bit of data is // received, even for the case of a document with no data (like about:blank) if (!m_manualLoader) { committedLoad(loader, 0, 0); return; } m_manualLoader->didFinishLoading(); m_manualLoader = 0; m_hasSentResponseToPlugin = false;}void WebFrameLoaderClient::updateGlobalHistory(){ WebHistory* history = WebHistory::sharedHistory(); if (!history) return; DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader(); history->visitedURL(loader->urlForHistory(), loader->title(), loader->originalRequestCopy().httpMethod(), loader->urlForHistoryReflectsFailure()); updateGlobalHistoryRedirectLinks();}void WebFrameLoaderClient::updateGlobalHistoryRedirectLinks(){ WebHistory* history = WebHistory::sharedHistory(); if (!history) return; DocumentLoader* loader = core(m_webFrame)->loader()->documentLoader(); if (!loader->clientRedirectSourceForHistory().isNull()) { if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->clientRedirectSourceForHistory())) { COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem); webHistoryItem->historyItem()->addRedirectURL(loader->clientRedirectDestinationForHistory()); } } if (!loader->serverRedirectSourceForHistory().isNull()) { if (COMPtr<IWebHistoryItem> iWebHistoryItem = history->itemForURLString(loader->serverRedirectSourceForHistory())) { COMPtr<WebHistoryItem> webHistoryItem(Query, iWebHistoryItem); webHistoryItem->historyItem()->addRedirectURL(loader->serverRedirectDestinationForHistory()); } }}bool WebFrameLoaderClient::shouldGoToHistoryItem(HistoryItem*) const{ return true;}PassRefPtr<DocumentLoader> WebFrameLoaderClient::createDocumentLoader(const ResourceRequest& request, const SubstituteData& substituteData){ RefPtr<WebDocumentLoader> loader = WebDocumentLoader::create(request, substituteData); COMPtr<WebDataSource> dataSource(AdoptCOM, WebDataSource::createInstance(loader.get())); loader->setDataSource(dataSource.get()); return loader.release();}void WebFrameLoaderClient::setTitle(const String& title, const KURL& url){ BOOL privateBrowsingEnabled = FALSE; COMPtr<IWebPreferences> preferences; if (SUCCEEDED(m_webFrame->webView()->preferences(&preferences))) preferences->privateBrowsingEnabled(&privateBrowsingEnabled); if (privateBrowsingEnabled) return; // update title in global history COMPtr<WebHistory> history = webHistory(); if (!history) return; COMPtr<IWebHistoryItem> item; if (FAILED(history->itemForURL(BString(url.string()), &item))) return; COMPtr<IWebHistoryItemPrivate> itemPrivate(Query, item); if (!itemPrivate) return; itemPrivate->setTitle(BString(title));}void WebFrameLoaderClient::savePlatformDataToCachedFrame(CachedFrame* cachedFrame){#if USE(CFNETWORK) Frame* coreFrame = core(m_webFrame); if (!coreFrame) return; ASSERT(coreFrame->loader()->documentLoader() == cachedFrame->documentLoader()); WebCachedFramePlatformData* webPlatformData = new WebCachedFramePlatformData(static_cast<IWebDataSource*>(getWebDataSource(coreFrame->loader()->documentLoader()))); cachedFrame->setCachedFramePlatformData(webPlatformData);#else notImplemented();#endif}void WebFrameLoaderClient::transitionToCommittedFromCachedFrame(CachedFrame*){}void WebFrameLoaderClient::transitionToCommittedForNewPage(){ WebView* view = m_webFrame->webView(); RECT rect; view->frameRect(&rect); bool transparent = view->transparent(); Color backgroundColor = transparent ? Color::transparent : Color::white; core(m_webFrame)->createView(IntRect(rect).size(), backgroundColor, transparent, IntSize(), false);}bool WebFrameLoaderClient::canCachePage() const{ return true;}PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& url, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer, bool /*allowsScrolling*/, int /*marginWidth*/, int /*marginHeight*/){ RefPtr<Frame> result = createFrame(url, name, ownerElement, referrer); if (!result) return 0; return result.release();}PassRefPtr<Frame> WebFrameLoaderClient::createFrame(const KURL& URL, const String& name, HTMLFrameOwnerElement* ownerElement, const String& referrer){ Frame* coreFrame = core(m_webFrame); ASSERT(coreFrame); COMPtr<WebFrame> webFrame(AdoptCOM, WebFrame::createInstance()); RefPtr<Frame> childFrame = webFrame->init(m_webFrame->webView(), coreFrame->page(), ownerElement); coreFrame->tree()->appendChild(childFrame); childFrame->tree()->setName(name); childFrame->init(); loadURLIntoChild(URL, referrer, webFrame.get()); // The frame's onload handler may have removed it from the document. if (!childFrame->tree()->parent()) return 0; return childFrame.release();}void WebFrameLoaderClient::loadURLIntoChild(const KURL& originalURL, const String& referrer, WebFrame* childFrame){ ASSERT(childFrame); ASSERT(core(childFrame)); Frame* coreFrame = core(m_webFrame); ASSERT(coreFrame); HistoryItem* parentItem = coreFrame->loader()->currentHistoryItem(); FrameLoadType loadType = coreFrame->loader()->loadType(); FrameLoadType childLoadType = FrameLoadTypeRedirectWithLockedBackForwardList; KURL url = originalURL; // If we're moving in the backforward list, we might want to replace the content // of this child frame with whatever was there at that point. // Reload will maintain the frame contents, LoadSame will not. if (parentItem && parentItem->children().size() && isBackForwardLoadType(loadType)) { if (HistoryItem* childItem = parentItem->childItemWithName(core(childFrame)->tree()->name())) { // Use the original URL to ensure we get all the side-effects, such as // onLoad handlers, of any redirects that happened. An example of where // this is needed is Radar 3213556. url = childItem->originalURL(); // These behaviors implied by these loadTypes should apply to the child frames childLoadType = loadType; if (isBackForwardLoadType(loadType)) // For back/forward, remember this item so we can traverse any child items as child frames load core(childFrame)->loader()->setProvisionalHistoryItem(childItem); else // For reload, just reinstall the current item, since a new child frame was created but we won't be creating a new BF item core(childFrame)->loader()->setCurrentHistoryItem(childItem); } } // FIXME: Handle loading WebArchives here String frameName = core(childFrame)->tree()->name(); core(childFrame)->loader()->loadURL(url, referrer, frameName, false, childLoadType, 0, 0);}Widget* WebFrameLoaderClient::createPlugin(const IntSize& pluginSize, HTMLPlugInElement* element, const KURL& url, const Vector<String>& paramNames, const Vector<String>& paramValues, const String& mimeType, bool loadManually){ WebView* webView = m_webFrame->webView(); COMPtr<IWebUIDelegate> ui; if (SUCCEEDED(webView->uiDelegate(&ui)) && ui) { COMPtr<IWebUIDelegatePrivate4> uiPrivate(Query, ui); if (uiPrivate) { // Assemble the view arguments in a property bag. HashMap<String, String> viewArguments; for (unsigned i = 0; i < paramNames.size(); i++) viewArguments.set(paramNames[i], paramValues[i]); COMPtr<IPropertyBag> viewArgumentsBag(AdoptCOM, COMPropertyBag<String>::adopt(viewArguments)); COMPtr<IDOMElement> containingElement(AdoptCOM, DOMElement::createInstance(element)); HashMap<String, COMVariant> arguments; arguments.set(WebEmbeddedViewAttributesKey, viewArgumentsBag); arguments.set(WebEmbeddedViewBaseURLKey, url.string()); arguments.set(WebEmbeddedViewContainingElementKey, containingElement); arguments.set(WebEmbeddedViewMIMETypeKey, mimeType); COMPtr<IPropertyBag> argumentsBag(AdoptCOM, COMPropertyBag<COMVariant>::adopt(arguments)); COMPtr<IWebEmbeddedView> view; HRESULT result = uiPrivate->embeddedViewWithArguments(webView, m_webFrame, argumentsBag.get(), &view); if (SUCCEEDED(result)) { HWND parentWindow; HRESULT hr = webView->viewWindow((OLE_HANDLE*)&parentWindow); ASSERT(SUCCEEDED(hr)); return EmbeddedWidget::create(view.get(), element, parentWindow, pluginSize); } } } Frame* frame = core(m_webFrame); PluginView* pluginView = PluginView::create(frame, pluginSize, element, url, paramNames, paramValues, mimeType, loadManually); if (pluginView->status() == PluginStatusLoadedSuccessfully) return pluginView; COMPtr<IWebResourceLoadDelegate> resourceLoadDelegate; if (FAILED(webView->resourceLoadDelegate(&resourceLoadDelegate))) return pluginView; RetainPtr<CFMutableDictionaryRef> userInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); unsigned count = (unsigned)paramNames.size(); for (unsigned i = 0; i < count; i++) { if (paramNames[i] == "pluginspage") { static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInPageURLStringKey); RetainPtr<CFStringRef> str(AdoptCF, paramValues[i].createCFString()); CFDictionarySetValue(userInfo.get(), key, str.get()); break; } } if (!mimeType.isNull()) { static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorMIMETypeKey); RetainPtr<CFStringRef> str(AdoptCF, mimeType.createCFString()); CFDictionarySetValue(userInfo.get(), key, str.get()); } String pluginName; if (pluginView->plugin()) pluginName = pluginView->plugin()->name(); if (!pluginName.isNull()) { static CFStringRef key = MarshallingHelpers::LPCOLESTRToCFStringRef(WebKitErrorPlugInNameKey); RetainPtr<CFStringRef> str(AdoptCF, pluginName.createCFString()); CFDictionarySetValue(userInfo.get(), key, str.get()); } COMPtr<CFDictionaryPropertyBag> userInfoBag(AdoptCOM, CFDictionaryPropertyBag::createInstance()); userInfoBag->setDictionary(userInfo.get()); int errorCode = 0; switch (pluginView->status()) { case PluginStatusCanNotFindPlugin: errorCode = WebKitErrorCannotFindPlugIn; break; case PluginStatusCanNotLoadPlugin: errorCode = WebKitErrorCannotLoadPlugIn; break; default: ASSERT_NOT_REACHED(); } ResourceError resourceError(String(WebKitErrorDomain), errorCode, url.string(), String()); COMPtr<IWebError> error(AdoptCOM, WebError::createInstance(resourceError, userInfoBag.get())); resourceLoadDelegate->plugInFailedWithError(webView, error.get(), getWebDataSource(frame->loader()->documentLoader())); return pluginView;}void WebFrameLoaderClient::redirectDataToPlugin(Widget* pluginWidget){ // Ideally, this function shouldn't be necessary, see <rdar://problem/4852889> if (pluginWidget->isPluginView()) m_manualLoader = static_cast<PluginView*>(pluginWidget); else m_manualLoader = static_cast<EmbeddedWidget*>(pluginWidget);}WebHistory* WebFrameLoaderClient::webHistory() const{ if (m_webFrame != m_webFrame->webView()->topLevelFrame()) return 0; return WebHistory::sharedHistory();}bool WebFrameLoaderClient::shouldUsePluginDocument(const String& mimeType) const{ WebView* webView = m_webFrame->webView(); if (!webView) return false; return webView->shouldUseEmbeddedView(mimeType);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -