📄 webframeloaderclient.mm
字号:
/* * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of * its contributors may be used to endorse or promote products derived * from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#import "WebFrameLoaderClient.h"// Terrible hack; lets us get at the WebFrame private structure.#define private public#import "WebFrame.h"#undef private#import "DOMElementInternal.h"#import "WebBackForwardList.h"#import "WebCachedFramePlatformData.h"#import "WebChromeClient.h"#import "WebDataSourceInternal.h"#import "WebDocumentInternal.h"#import "WebDocumentLoaderMac.h"#import "WebDownloadInternal.h"#import "WebDynamicScrollBarsViewInternal.h"#import "WebElementDictionary.h"#import "WebFormDelegate.h"#import "WebFrameInternal.h"#import "WebFrameLoadDelegate.h"#import "WebFrameViewInternal.h"#import "WebHTMLRepresentationPrivate.h"#import "WebHTMLViewInternal.h"#import "WebHistoryItemInternal.h"#import "WebHistoryInternal.h"#import "WebIconDatabaseInternal.h"#import "WebKitErrorsPrivate.h"#import "WebKitLogging.h"#import "WebKitNSStringExtras.h"#import "WebNSURLExtras.h"#import "WebNetscapePluginView.h"#import "WebNetscapePluginPackage.h"#import "WebNullPluginView.h"#import "WebPanelAuthenticationHandler.h"#import "WebPluginController.h"#import "WebPluginPackage.h"#import "WebPluginViewFactoryPrivate.h"#import "WebPolicyDelegate.h"#import "WebPolicyDelegatePrivate.h"#import "WebPreferences.h"#import "WebResourceLoadDelegate.h"#import "WebUIDelegate.h"#import "WebUIDelegatePrivate.h"#import "WebViewInternal.h"#import <WebKitSystemInterface.h>#import <WebCore/AuthenticationMac.h>#import <WebCore/BlockExceptions.h>#import <WebCore/CachedFrame.h>#import <WebCore/Chrome.h>#import <WebCore/Document.h>#import <WebCore/DocumentLoader.h>#import <WebCore/EventHandler.h>#import <WebCore/FormState.h>#import <WebCore/Frame.h>#import <WebCore/FrameLoader.h>#import <WebCore/FrameLoaderTypes.h>#import <WebCore/FrameTree.h>#import <WebCore/FrameView.h>#import <WebCore/HTMLAppletElement.h>#import <WebCore/HTMLHeadElement.h>#import <WebCore/HTMLFormElement.h>#import <WebCore/HTMLFrameElement.h>#import <WebCore/HTMLFrameOwnerElement.h>#import <WebCore/HTMLNames.h>#import <WebCore/HTMLPlugInElement.h>#import <WebCore/HistoryItem.h>#import <WebCore/HitTestResult.h>#import <WebCore/IconDatabase.h>#import <WebCore/LoaderNSURLExtras.h>#import <WebCore/MIMETypeRegistry.h>#import <WebCore/MouseEvent.h>#import <WebCore/Page.h>#import <WebCore/PlatformString.h>#import <WebCore/ResourceError.h>#import <WebCore/ResourceHandle.h>#import <WebCore/ResourceLoader.h>#import <WebCore/ResourceRequest.h>#import <WebCore/ScriptController.h>#import <WebCore/SharedBuffer.h>#import <WebCore/WebCoreObjCExtras.h>#import <WebCore/Widget.h>#import <WebKit/DOMElement.h>#import <WebKit/DOMHTMLFormElement.h>#import <runtime/InitializeThreading.h>#import <wtf/PassRefPtr.h>#if ENABLE(MAC_JAVA_BRIDGE)#import "WebJavaPlugIn.h"#endif#if USE(PLUGIN_HOST_PROCESS)#import "WebHostedNetscapePluginView.h"#endifusing namespace WebCore;using namespace HTMLNames;#if ENABLE(MAC_JAVA_BRIDGE)@interface NSView (WebJavaPluginDetails)- (jobject)pollForAppletInWindow:(NSWindow *)window;@end#endif@interface NSURLDownload (WebNSURLDownloadDetails)- (void)_setOriginatingURL:(NSURL *)originatingURL;@end// For backwards compatibility with older WebKit plug-ins.NSString *WebPluginBaseURLKey = @"WebPluginBaseURL";NSString *WebPluginAttributesKey = @"WebPluginAttributes";NSString *WebPluginContainerKey = @"WebPluginContainer";@interface WebFramePolicyListener : NSObject <WebPolicyDecisionListener, WebFormSubmissionListener> { Frame* m_frame;}- (id)initWithWebCoreFrame:(Frame*)frame;- (void)invalidate;@endstatic inline WebDataSource *dataSource(DocumentLoader* loader){ return loader ? static_cast<WebDocumentLoaderMac*>(loader)->dataSource() : nil;}// Quirk for the Apple Dictionary application.//// If a top level frame has a <script> element in its <head> for a script named MainPageJavaScript.js,// then for that frame's document, ignore changes to the scrolling attribute of frames. That script// has a bug in it where it sets the scrolling attribute on frames, and that erroneous scrolling// attribute needs to be ignored to avoid showing extra scroll bars in the window.// This quirk can be removed when Apple Dictionary is fixed (see <rdar://problem/6471058>).static void applyAppleDictionaryApplicationQuirkNonInlinePart(WebFrameLoaderClient* client, const ResourceRequest& request){ if (!request.url().isLocalFile()) return; if (!request.url().string().endsWith("MainPageJavaScript.js")) return; Frame* frame = core(client->webFrame()); if (!frame) return; if (frame->tree()->parent()) return; Document* document = frame->document(); if (!document) return; HTMLHeadElement* head = document->head(); if (!head) return; for (Node* c = head->firstChild(); c; c = c->nextSibling()) { if (c->hasTagName(scriptTag) && static_cast<Element*>(c)->getAttribute(srcAttr) == "MainPageJavaScript.js") { document->setFrameElementsShouldIgnoreScrolling(true); return; } }}static inline void applyAppleDictionaryApplicationQuirk(WebFrameLoaderClient* client, const ResourceRequest& request){ // Use a one-time-initialized global variable so we can quickly determine there's nothing to do in // all applications other than Apple Dictionary. static bool isAppleDictionary = [[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.Dictionary"]; if (isAppleDictionary) applyAppleDictionaryApplicationQuirkNonInlinePart(client, request);}WebFrameLoaderClient::WebFrameLoaderClient(WebFrame *webFrame) : m_webFrame(webFrame) , m_policyFunction(0){}void WebFrameLoaderClient::frameLoaderDestroyed(){ [m_webFrame.get() _clearCoreFrame]; delete this;}bool WebFrameLoaderClient::hasWebView() const{ return [m_webFrame.get() webView] != nil;}void WebFrameLoaderClient::makeRepresentation(DocumentLoader* loader){ [dataSource(loader) _makeRepresentation];}bool WebFrameLoaderClient::hasHTMLView() const{ NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView]; return [view isKindOfClass:[WebHTMLView class]];}void WebFrameLoaderClient::forceLayout(){ NSView <WebDocumentView> *view = [m_webFrame->_private->webFrameView documentView]; if ([view isKindOfClass:[WebHTMLView class]]) [(WebHTMLView *)view setNeedsToApplyStyles:YES]; [view setNeedsLayout:YES]; [view layout];}void WebFrameLoaderClient::forceLayoutForNonHTML(){ WebFrameView *thisView = m_webFrame->_private->webFrameView; if (!thisView) // Viewless mode. return; NSView <WebDocumentView> *thisDocumentView = [thisView documentView]; ASSERT(thisDocumentView != nil); // Tell the just loaded document to layout. This may be necessary // for non-html content that needs a layout message. if (!([[m_webFrame.get() _dataSource] _isDocumentHTML])) { [thisDocumentView setNeedsLayout:YES]; [thisDocumentView layout]; [thisDocumentView setNeedsDisplay:YES]; }}void WebFrameLoaderClient::setCopiesOnScroll(){ [[[m_webFrame->_private->webFrameView _scrollView] contentView] setCopiesOnScroll:YES];}void WebFrameLoaderClient::detachedFromParent2(){ //remove any NetScape plugins that are children of this frame because they are about to be detached WebView *webView = getWebView(m_webFrame.get()); [webView removePluginInstanceViewsFor:(m_webFrame.get())]; [m_webFrame->_private->webFrameView _setWebFrame:nil]; // needed for now to be compatible w/ old behavior}void WebFrameLoaderClient::detachedFromParent3(){ [m_webFrame->_private->webFrameView release]; m_webFrame->_private->webFrameView = nil;}void WebFrameLoaderClient::download(ResourceHandle* handle, const ResourceRequest& request, const ResourceRequest& initialRequest, const ResourceResponse& response){ id proxy = handle->releaseProxy(); ASSERT(proxy); WebView *webView = getWebView(m_webFrame.get()); WebDownload *download = [WebDownload _downloadWithLoadingConnection:handle->connection() request:request.nsURLRequest() response:response.nsURLResponse() delegate:[webView downloadDelegate] proxy:proxy]; setOriginalURLForDownload(download, initialRequest); }void WebFrameLoaderClient::setOriginalURLForDownload(WebDownload *download, const ResourceRequest& initialRequest) const{ NSURLRequest *initialURLRequest = initialRequest.nsURLRequest(); NSURL *originalURL = nil; // If there was no referrer, don't traverse the back/forward history // since this download was initiated directly. <rdar://problem/5294691> if ([initialURLRequest valueForHTTPHeaderField:@"Referer"]) { // find the first item in the history that was originated by the user WebView *webView = getWebView(m_webFrame.get()); WebBackForwardList *history = [webView backForwardList]; int backListCount = [history backListCount]; for (int backIndex = 0; backIndex <= backListCount && !originalURL; backIndex++) { // FIXME: At one point we had code here to check a "was user gesture" flag. // Do we need to restore that logic? originalURL = [[history itemAtIndex:-backIndex] URL]; } } if (!originalURL) originalURL = [initialURLRequest URL]; if ([download respondsToSelector:@selector(_setOriginatingURL:)]) { NSString *scheme = [originalURL scheme]; NSString *host = [originalURL host]; if (scheme && host && [scheme length] && [host length]) { NSNumber *port = [originalURL port]; if (port && [port intValue] < 0) port = nil; NSString *hostOnlyURLString; if (port) hostOnlyURLString = [[NSString alloc] initWithFormat:@"%@://%@:%d", scheme, host, [port intValue]];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -