1563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
20bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch * Copyright (C) 2007, 2009 Apple Inc. All rights reserved.
3563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *
4563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Redistribution and use in source and binary forms, with or without
5563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * modification, are permitted provided that the following conditions
6563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * are met:
7563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *
8563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 1.  Redistributions of source code must retain the above copyright
9563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     notice, this list of conditions and the following disclaimer.
10563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 2.  Redistributions in binary form must reproduce the above copyright
11563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     notice, this list of conditions and the following disclaimer in the
12563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     documentation and/or other materials provided with the distribution.
13563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     its contributors may be used to endorse or promote products derived
15563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     from this software without specific prior written permission.
16563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *
17563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
28563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
29563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "config.h"
30563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "PolicyDelegate.h"
31563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
32563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "DumpRenderTree.h"
330bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch#include "LayoutTestController.h"
34563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <string>
35563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
36563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkusing std::wstring;
37563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdochstatic wstring dumpPath(IDOMNode* node)
390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    ASSERT(node);
410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    wstring result;
430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    BSTR name;
450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (FAILED(node->nodeName(&name)))
460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        return result;
470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    result.assign(name, SysStringLen(name));
480bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    SysFreeString(name);
490bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
500bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    COMPtr<IDOMNode> parent;
510bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (SUCCEEDED(node->parentNode(&parent)))
520bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        result += TEXT(" > ") + dumpPath(parent.get());
530bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
540bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return result;
550bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
57563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkPolicyDelegate::PolicyDelegate()
58563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    : m_refCount(1)
59563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    , m_permissiveDelegate(false)
600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    , m_controllerToNotifyDone(0)
61563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
62563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
63563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
64563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark// IUnknown
65563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE PolicyDelegate::QueryInterface(REFIID riid, void** ppvObject)
66563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
67563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *ppvObject = 0;
68563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (IsEqualGUID(riid, IID_IUnknown))
69563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        *ppvObject = static_cast<IWebPolicyDelegate*>(this);
70563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    else if (IsEqualGUID(riid, IID_IWebPolicyDelegate))
71563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        *ppvObject = static_cast<IWebPolicyDelegate*>(this);
72563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    else
73563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_NOINTERFACE;
74563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
75563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    AddRef();
76563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
77563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
78563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
79563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkULONG STDMETHODCALLTYPE PolicyDelegate::AddRef(void)
80563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
81563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return ++m_refCount;
82563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
83563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
84563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkULONG STDMETHODCALLTYPE PolicyDelegate::Release(void)
85563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
86563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    ULONG newRef = --m_refCount;
87563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!newRef)
88563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        delete this;
89563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
90563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return newRef;
91563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
92563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
93563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE PolicyDelegate::decidePolicyForNavigationAction(
94563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /*[in]*/ IWebView* /*webView*/,
95563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /*[in]*/ IPropertyBag* actionInformation,
96563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /*[in]*/ IWebURLRequest* request,
97563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /*[in]*/ IWebFrame* frame,
98563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /*[in]*/ IWebPolicyDecisionListener* listener)
99563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
100563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    BSTR url;
101563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    request->URL(&url);
1020bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    wstring wurl = urlSuitableForTestResult(wstring(url, SysStringLen(url)));
103563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
104563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    int navType = 0;
105563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    VARIANT var;
106563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (SUCCEEDED(actionInformation->Read(WebActionNavigationTypeKey, &var, 0))) {
107563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        V_VT(&var) = VT_I4;
108563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        navType = V_I4(&var);
109563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
110563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
1110bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    LPCTSTR typeDescription;
112563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    switch (navType) {
113563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        case WebNavigationTypeLinkClicked:
1140bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            typeDescription = TEXT("link clicked");
115563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark            break;
116563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        case WebNavigationTypeFormSubmitted:
1170bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            typeDescription = TEXT("form submitted");
118563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark            break;
119563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        case WebNavigationTypeBackForward:
1200bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            typeDescription = TEXT("back/forward");
121563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark            break;
122563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        case WebNavigationTypeReload:
1230bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            typeDescription = TEXT("reload");
124563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark            break;
125563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        case WebNavigationTypeFormResubmitted:
1260bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            typeDescription = TEXT("form resubmitted");
127563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark            break;
128563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        case WebNavigationTypeOther:
1290bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            typeDescription = TEXT("other");
130563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark            break;
131563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        default:
1320bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            typeDescription = TEXT("illegal value");
133563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
1340bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1350bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    wstring message = TEXT("Policy delegate: attempt to load ") + wurl + TEXT(" with navigation type '") + typeDescription + TEXT("'");
1360bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1370bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    VARIANT actionElementVar;
1380bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (SUCCEEDED(actionInformation->Read(WebActionElementKey, &actionElementVar, 0))) {
1390bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        COMPtr<IPropertyBag> actionElement(Query, V_UNKNOWN(&actionElementVar));
1400bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        VARIANT originatingNodeVar;
1410bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        if (SUCCEEDED(actionElement->Read(WebElementDOMNodeKey, &originatingNodeVar, 0))) {
1420bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            COMPtr<IDOMNode> originatingNode(Query, V_UNKNOWN(&originatingNodeVar));
1430bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch            message += TEXT(" originating from ") + dumpPath(originatingNode.get());
1440bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        }
1450bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1460bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1470bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    printf("%S\n", message.c_str());
148563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
149563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    SysFreeString(url);
150563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
151563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (m_permissiveDelegate)
152563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        listener->use();
153563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    else
154563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        listener->ignore();
155563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
1560bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    if (m_controllerToNotifyDone) {
1570bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_controllerToNotifyDone->notifyDone();
1580bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch        m_controllerToNotifyDone = 0;
1590bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    }
1600bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1610bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    return S_OK;
1620bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch}
1630bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1640bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1650bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben MurdochHRESULT STDMETHODCALLTYPE PolicyDelegate::unableToImplementPolicyWithError(
1660bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    /*[in]*/ IWebView* /*webView*/,
1670bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    /*[in]*/ IWebError* error,
1680bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    /*[in]*/ IWebFrame* frame)
1690bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch{
1700bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    BSTR domainStr;
1710bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    error->domain(&domainStr);
1720bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    wstring domainMessage = domainStr;
1730bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1740bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    int code;
1750bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    error->code(&code);
1760bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1770bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    BSTR frameName;
1780bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    frame->name(&frameName);
1790bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    wstring frameNameMessage = frameName;
1800bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1810bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    printf("Policy delegate: unable to implement policy with error domain '%S', error code %d, in frame '%S'", domainMessage.c_str(), code, frameNameMessage.c_str());
1820bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
1830bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    SysFreeString(domainStr);
1840bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch    SysFreeString(frameName);
1850bf48ef3be53ddaa52bbead65dfd75bf90e7a2b5Ben Murdoch
186563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
187563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
188