1/* 2 * Copyright (C) 2007 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. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "WebKitDLL.h" 28#include "DefaultPolicyDelegate.h" 29 30#include <WebCore/BString.h> 31#include <WebCore/COMPtr.h> 32#include <wtf/text/WTFString.h> 33 34using namespace WebCore; 35 36// FIXME: move this enum to a separate header file when other code begins to use it. 37typedef enum WebExtraNavigationType { 38 WebNavigationTypePlugInRequest = WebNavigationTypeOther + 1 39} WebExtraNavigationType; 40 41// DefaultPolicyDelegate ---------------------------------------------------------------- 42 43DefaultPolicyDelegate::DefaultPolicyDelegate() 44 : m_refCount(0) 45{ 46 gClassCount++; 47 gClassNameCount.add("DefaultPolicyDelegate"); 48} 49 50DefaultPolicyDelegate::~DefaultPolicyDelegate() 51{ 52 gClassCount--; 53 gClassNameCount.remove("DefaultPolicyDelegate"); 54} 55 56DefaultPolicyDelegate* DefaultPolicyDelegate::sharedInstance() 57{ 58 static COMPtr<DefaultPolicyDelegate> shared; 59 if (!shared) 60 shared.adoptRef(DefaultPolicyDelegate::createInstance()); 61 return shared.get(); 62} 63 64DefaultPolicyDelegate* DefaultPolicyDelegate::createInstance() 65{ 66 DefaultPolicyDelegate* instance = new DefaultPolicyDelegate(); 67 instance->AddRef(); 68 return instance; 69} 70 71// IUnknown ------------------------------------------------------------------- 72 73HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::QueryInterface(REFIID riid, void** ppvObject) 74{ 75 *ppvObject = 0; 76 if (IsEqualGUID(riid, IID_IUnknown)) 77 *ppvObject = static_cast<IUnknown*>(this); 78 else if (IsEqualGUID(riid, IID_IWebPolicyDelegate)) 79 *ppvObject = static_cast<IWebPolicyDelegate*>(this); 80 else 81 return E_NOINTERFACE; 82 83 AddRef(); 84 return S_OK; 85} 86 87ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::AddRef() 88{ 89 return ++m_refCount; 90} 91 92ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::Release() 93{ 94 ULONG newRef = --m_refCount; 95 if (!newRef) 96 delete(this); 97 98 return newRef; 99} 100 101HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNavigationAction( 102 /*[in]*/ IWebView* webView, 103 /*[in]*/ IPropertyBag* actionInformation, 104 /*[in]*/ IWebURLRequest* request, 105 /*[in]*/ IWebFrame* /*frame*/, 106 /*[in]*/ IWebPolicyDecisionListener* listener) 107{ 108 int navType = 0; 109 VARIANT var; 110 if (SUCCEEDED(actionInformation->Read(WebActionNavigationTypeKey, &var, 0))) { 111 V_VT(&var) = VT_I4; 112 navType = V_I4(&var); 113 } 114 COMPtr<IWebViewPrivate> wvPrivate(Query, webView); 115 if (wvPrivate) { 116 BOOL canHandleRequest = FALSE; 117 if (SUCCEEDED(wvPrivate->canHandleRequest(request, &canHandleRequest)) && canHandleRequest) 118 listener->use(); 119 else if (navType == WebNavigationTypePlugInRequest) 120 listener->use(); 121 else { 122 BString url; 123 // A file URL shouldn't fall through to here, but if it did, 124 // it would be a security risk to open it. 125 if (SUCCEEDED(request->URL(&url)) && !String(url, SysStringLen(url)).startsWith("file:")) { 126 // FIXME: Open the URL not by means of a webframe, but by handing it over to the system and letting it determine how to open that particular URL scheme. See documentation for [NSWorkspace openURL] 127 ; 128 } 129 listener->ignore(); 130 } 131 } 132 return S_OK; 133} 134 135HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNewWindowAction( 136 /*[in]*/ IWebView* /*webView*/, 137 /*[in]*/ IPropertyBag* /*actionInformation*/, 138 /*[in]*/ IWebURLRequest* /*request*/, 139 /*[in]*/ BSTR /*frameName*/, 140 /*[in]*/ IWebPolicyDecisionListener* listener) 141{ 142 listener->use(); 143 return S_OK; 144} 145 146HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForMIMEType( 147 /*[in]*/ IWebView* webView, 148 /*[in]*/ BSTR type, 149 /*[in]*/ IWebURLRequest* request, 150 /*[in]*/ IWebFrame* /*frame*/, 151 /*[in]*/ IWebPolicyDecisionListener* listener) 152{ 153 BOOL canShowMIMEType; 154 if (FAILED(webView->canShowMIMEType(type, &canShowMIMEType))) 155 canShowMIMEType = FALSE; 156 157 BString url; 158 request->URL(&url); 159 160 if (String(url, SysStringLen(url)).startsWith("file:")) { 161 BOOL isDirectory = FALSE; 162 WIN32_FILE_ATTRIBUTE_DATA attrs; 163 if (GetFileAttributesEx(url, GetFileExInfoStandard, &attrs)) 164 isDirectory = !!(attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); 165 166 if (isDirectory) 167 listener->ignore(); 168 else if(canShowMIMEType) 169 listener->use(); 170 else 171 listener->ignore(); 172 } else if (canShowMIMEType) 173 listener->use(); 174 else 175 listener->ignore(); 176 return S_OK; 177} 178 179HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::unableToImplementPolicyWithError( 180 /*[in]*/ IWebView* /*webView*/, 181 /*[in]*/ IWebError* error, 182 /*[in]*/ IWebFrame* frame) 183{ 184 BString errorStr; 185 error->localizedDescription(&errorStr); 186 187 BString frameName; 188 frame->name(&frameName); 189 190 LOG_ERROR("called unableToImplementPolicyWithError:%S inFrame:%S", errorStr ? errorStr : TEXT(""), frameName ? frameName : TEXT("")); 191 192 return S_OK; 193} 194