1/* 2 * Copyright (C) 2007, 2009 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 * 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. 16 * 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. 27 */ 28 29#include "config.h" 30#include "PolicyDelegate.h" 31 32#include "DumpRenderTree.h" 33#include "LayoutTestController.h" 34#include <string> 35 36using std::wstring; 37 38static wstring dumpPath(IDOMNode* node) 39{ 40 ASSERT(node); 41 42 wstring result; 43 44 BSTR name; 45 if (FAILED(node->nodeName(&name))) 46 return result; 47 result.assign(name, SysStringLen(name)); 48 SysFreeString(name); 49 50 COMPtr<IDOMNode> parent; 51 if (SUCCEEDED(node->parentNode(&parent))) 52 result += TEXT(" > ") + dumpPath(parent.get()); 53 54 return result; 55} 56 57PolicyDelegate::PolicyDelegate() 58 : m_refCount(1) 59 , m_permissiveDelegate(false) 60 , m_controllerToNotifyDone(0) 61{ 62} 63 64// IUnknown 65HRESULT STDMETHODCALLTYPE PolicyDelegate::QueryInterface(REFIID riid, void** ppvObject) 66{ 67 *ppvObject = 0; 68 if (IsEqualGUID(riid, IID_IUnknown)) 69 *ppvObject = static_cast<IWebPolicyDelegate*>(this); 70 else if (IsEqualGUID(riid, IID_IWebPolicyDelegate)) 71 *ppvObject = static_cast<IWebPolicyDelegate*>(this); 72 else 73 return E_NOINTERFACE; 74 75 AddRef(); 76 return S_OK; 77} 78 79ULONG STDMETHODCALLTYPE PolicyDelegate::AddRef(void) 80{ 81 return ++m_refCount; 82} 83 84ULONG STDMETHODCALLTYPE PolicyDelegate::Release(void) 85{ 86 ULONG newRef = --m_refCount; 87 if (!newRef) 88 delete this; 89 90 return newRef; 91} 92 93HRESULT STDMETHODCALLTYPE PolicyDelegate::decidePolicyForNavigationAction( 94 /*[in]*/ IWebView* /*webView*/, 95 /*[in]*/ IPropertyBag* actionInformation, 96 /*[in]*/ IWebURLRequest* request, 97 /*[in]*/ IWebFrame* frame, 98 /*[in]*/ IWebPolicyDecisionListener* listener) 99{ 100 BSTR url; 101 request->URL(&url); 102 wstring wurl = urlSuitableForTestResult(wstring(url, SysStringLen(url))); 103 104 int navType = 0; 105 VARIANT var; 106 if (SUCCEEDED(actionInformation->Read(WebActionNavigationTypeKey, &var, 0))) { 107 V_VT(&var) = VT_I4; 108 navType = V_I4(&var); 109 } 110 111 LPCTSTR typeDescription; 112 switch (navType) { 113 case WebNavigationTypeLinkClicked: 114 typeDescription = TEXT("link clicked"); 115 break; 116 case WebNavigationTypeFormSubmitted: 117 typeDescription = TEXT("form submitted"); 118 break; 119 case WebNavigationTypeBackForward: 120 typeDescription = TEXT("back/forward"); 121 break; 122 case WebNavigationTypeReload: 123 typeDescription = TEXT("reload"); 124 break; 125 case WebNavigationTypeFormResubmitted: 126 typeDescription = TEXT("form resubmitted"); 127 break; 128 case WebNavigationTypeOther: 129 typeDescription = TEXT("other"); 130 break; 131 default: 132 typeDescription = TEXT("illegal value"); 133 } 134 135 wstring message = TEXT("Policy delegate: attempt to load ") + wurl + TEXT(" with navigation type '") + typeDescription + TEXT("'"); 136 137 VARIANT actionElementVar; 138 if (SUCCEEDED(actionInformation->Read(WebActionElementKey, &actionElementVar, 0))) { 139 COMPtr<IPropertyBag> actionElement(Query, V_UNKNOWN(&actionElementVar)); 140 VARIANT originatingNodeVar; 141 if (SUCCEEDED(actionElement->Read(WebElementDOMNodeKey, &originatingNodeVar, 0))) { 142 COMPtr<IDOMNode> originatingNode(Query, V_UNKNOWN(&originatingNodeVar)); 143 message += TEXT(" originating from ") + dumpPath(originatingNode.get()); 144 } 145 } 146 147 printf("%S\n", message.c_str()); 148 149 SysFreeString(url); 150 151 if (m_permissiveDelegate) 152 listener->use(); 153 else 154 listener->ignore(); 155 156 if (m_controllerToNotifyDone) { 157 m_controllerToNotifyDone->notifyDone(); 158 m_controllerToNotifyDone = 0; 159 } 160 161 return S_OK; 162} 163 164 165HRESULT STDMETHODCALLTYPE PolicyDelegate::unableToImplementPolicyWithError( 166 /*[in]*/ IWebView* /*webView*/, 167 /*[in]*/ IWebError* error, 168 /*[in]*/ IWebFrame* frame) 169{ 170 BSTR domainStr; 171 error->domain(&domainStr); 172 wstring domainMessage = domainStr; 173 174 int code; 175 error->code(&code); 176 177 BSTR frameName; 178 frame->name(&frameName); 179 wstring frameNameMessage = frameName; 180 181 printf("Policy delegate: unable to implement policy with error domain '%S', error code %d, in frame '%S'", domainMessage.c_str(), code, frameNameMessage.c_str()); 182 183 SysFreeString(domainStr); 184 SysFreeString(frameName); 185 186 return S_OK; 187} 188