Home | History | Annotate | Download | only in win
      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 COMPUTER, 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 COMPUTER, 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/COMPtr.h>
     31 #include <WebCore/PlatformString.h>
     32 
     33 using namespace WebCore;
     34 
     35 // FIXME: move this enum to a separate header file when other code begins to use it.
     36 typedef enum WebExtraNavigationType {
     37     WebNavigationTypePlugInRequest = WebNavigationTypeOther + 1
     38 } WebExtraNavigationType;
     39 
     40 // DefaultPolicyDelegate ----------------------------------------------------------------
     41 
     42 DefaultPolicyDelegate::DefaultPolicyDelegate()
     43     : m_refCount(0)
     44 {
     45     gClassCount++;
     46     gClassNameCount.add("DefaultPolicyDelegate");
     47 }
     48 
     49 DefaultPolicyDelegate::~DefaultPolicyDelegate()
     50 {
     51     gClassCount--;
     52     gClassNameCount.remove("DefaultPolicyDelegate");
     53 }
     54 
     55 DefaultPolicyDelegate* DefaultPolicyDelegate::sharedInstance()
     56 {
     57     static COMPtr<DefaultPolicyDelegate> shared;
     58     if (!shared)
     59         shared.adoptRef(DefaultPolicyDelegate::createInstance());
     60     return shared.get();
     61 }
     62 
     63 DefaultPolicyDelegate* DefaultPolicyDelegate::createInstance()
     64 {
     65     DefaultPolicyDelegate* instance = new DefaultPolicyDelegate();
     66     instance->AddRef();
     67     return instance;
     68 }
     69 
     70 // IUnknown -------------------------------------------------------------------
     71 
     72 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::QueryInterface(REFIID riid, void** ppvObject)
     73 {
     74     *ppvObject = 0;
     75     if (IsEqualGUID(riid, IID_IUnknown))
     76         *ppvObject = static_cast<IUnknown*>(this);
     77     else if (IsEqualGUID(riid, IID_IWebPolicyDelegate))
     78         *ppvObject = static_cast<IWebPolicyDelegate*>(this);
     79     else
     80         return E_NOINTERFACE;
     81 
     82     AddRef();
     83     return S_OK;
     84 }
     85 
     86 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::AddRef()
     87 {
     88     return ++m_refCount;
     89 }
     90 
     91 ULONG STDMETHODCALLTYPE DefaultPolicyDelegate::Release()
     92 {
     93     ULONG newRef = --m_refCount;
     94     if (!newRef)
     95         delete(this);
     96 
     97     return newRef;
     98 }
     99 
    100 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::decidePolicyForNavigationAction(
    101     /*[in]*/ IWebView* webView,
    102     /*[in]*/ IPropertyBag* actionInformation,
    103     /*[in]*/ IWebURLRequest* request,
    104     /*[in]*/ IWebFrame* /*frame*/,
    105     /*[in]*/ IWebPolicyDecisionListener* listener)
    106 {
    107     int navType = 0;
    108     VARIANT var;
    109     if (SUCCEEDED(actionInformation->Read(WebActionNavigationTypeKey, &var, 0))) {
    110         V_VT(&var) = VT_I4;
    111         navType = V_I4(&var);
    112     }
    113     COMPtr<IWebViewPrivate> wvPrivate(Query, webView);
    114     if (wvPrivate) {
    115         BOOL canHandleRequest = FALSE;
    116         if (SUCCEEDED(wvPrivate->canHandleRequest(request, &canHandleRequest)) && canHandleRequest)
    117             listener->use();
    118         else if (navType == WebNavigationTypePlugInRequest)
    119             listener->use();
    120         else {
    121             BSTR url;
    122             // A file URL shouldn't fall through to here, but if it did,
    123             // it would be a security risk to open it.
    124             if (SUCCEEDED(request->URL(&url)) && !String(url, SysStringLen(url)).startsWith("file:")) {
    125                 // 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]
    126                 ;
    127             }
    128             listener->ignore();
    129             SysFreeString(url);
    130         }
    131     }
    132     return S_OK;
    133 }
    134 
    135 HRESULT 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 
    146 HRESULT 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     BSTR 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     SysFreeString(url);
    177     return S_OK;
    178 }
    179 
    180 HRESULT STDMETHODCALLTYPE DefaultPolicyDelegate::unableToImplementPolicyWithError(
    181     /*[in]*/ IWebView* /*webView*/,
    182     /*[in]*/ IWebError* error,
    183     /*[in]*/ IWebFrame* frame)
    184 {
    185     BSTR errorStr;
    186     error->localizedDescription(&errorStr);
    187 
    188     BSTR frameName;
    189     frame->name(&frameName);
    190 
    191     LOG_ERROR("called unableToImplementPolicyWithError:%S inFrame:%S", errorStr ? errorStr : TEXT(""), frameName ? frameName : TEXT(""));
    192     SysFreeString(errorStr);
    193     SysFreeString(frameName);
    194 
    195     return S_OK;
    196 }
    197