1 /* 2 * Copyright (C) 2007, 2008 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 "WebActionPropertyBag.h" 29 30 #include "COMPtr.h" 31 #include "DOMCoreClasses.h" 32 #include "WebElementPropertyBag.h" 33 #include "WebKit.h" 34 35 #pragma warning(push, 0) 36 #include <WebCore/BString.h> 37 #include <WebCore/EventHandler.h> 38 #include <WebCore/MouseEvent.h> 39 #include <WebCore/HitTestResult.h> 40 #pragma warning(pop) 41 42 using namespace WebCore; 43 44 // WebActionPropertyBag ------------------------------------------------ 45 46 WebActionPropertyBag::WebActionPropertyBag(const NavigationAction& action, PassRefPtr<HTMLFormElement> form, PassRefPtr<Frame> frame) 47 : m_refCount(0) 48 , m_action(action) 49 , m_form(form) 50 , m_frame(frame) 51 { 52 gClassCount++; 53 gClassNameCount.add("WebActionPropertyBag"); 54 } 55 56 WebActionPropertyBag::~WebActionPropertyBag() 57 { 58 gClassCount--; 59 gClassNameCount.remove("WebActionPropertyBag"); 60 } 61 62 WebActionPropertyBag* WebActionPropertyBag::createInstance(const NavigationAction& action, PassRefPtr<HTMLFormElement> form, PassRefPtr<Frame> frame) 63 { 64 WebActionPropertyBag* instance = new WebActionPropertyBag(action, form, frame); 65 instance->AddRef(); 66 return instance; 67 } 68 69 // IUnknown ------------------------------------------------------------------- 70 71 HRESULT STDMETHODCALLTYPE WebActionPropertyBag::QueryInterface(REFIID riid, void** ppvObject) 72 { 73 *ppvObject = 0; 74 if (IsEqualGUID(riid, IID_IUnknown)) 75 *ppvObject = static_cast<IPropertyBag*>(this); 76 else if (IsEqualGUID(riid, IID_IPropertyBag)) 77 *ppvObject = static_cast<IPropertyBag*>(this); 78 else 79 return E_NOINTERFACE; 80 81 AddRef(); 82 return S_OK; 83 } 84 85 ULONG STDMETHODCALLTYPE WebActionPropertyBag::AddRef() 86 { 87 return ++m_refCount; 88 } 89 90 ULONG STDMETHODCALLTYPE WebActionPropertyBag::Release() 91 { 92 ULONG newRef = --m_refCount; 93 if (!newRef) 94 delete this; 95 96 return newRef; 97 } 98 99 static bool isEqual(LPCWSTR s1, LPCWSTR s2) 100 { 101 return !wcscmp(s1, s2); 102 } 103 104 static const MouseEvent* findMouseEvent(const Event* event) 105 { 106 for (const Event* e = event; e; e = e->underlyingEvent()) 107 if (e->isMouseEvent()) 108 return static_cast<const MouseEvent*>(e); 109 return 0; 110 } 111 112 HRESULT STDMETHODCALLTYPE WebActionPropertyBag::Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog * /*pErrorLog*/) 113 { 114 if (!pszPropName) 115 return E_POINTER; 116 117 VariantClear(pVar); 118 119 if (isEqual(pszPropName, WebActionNavigationTypeKey)) { 120 V_VT(pVar) = VT_I4; 121 V_I4(pVar) = m_action.type(); 122 return S_OK; 123 } 124 if (isEqual(pszPropName, WebActionElementKey)) { 125 if (const MouseEvent* mouseEvent = findMouseEvent(m_action.event())) { 126 V_VT(pVar) = VT_UNKNOWN; 127 V_UNKNOWN(pVar) = WebElementPropertyBag::createInstance(m_frame->eventHandler()->hitTestResultAtPoint(mouseEvent->absoluteLocation(), false)); 128 return S_OK; 129 } 130 } 131 if (isEqual(pszPropName, WebActionButtonKey)) { 132 if (const MouseEvent* mouseEvent = findMouseEvent(m_action.event())) { 133 V_VT(pVar) = VT_I4; 134 V_I4(pVar) = mouseEvent->button(); 135 return S_OK; 136 } 137 } 138 if (isEqual(pszPropName, WebActionOriginalURLKey)) { 139 V_VT(pVar) = VT_BSTR; 140 V_BSTR(pVar) = BString(m_action.url().string()).release(); 141 return S_OK; 142 } 143 if (isEqual(pszPropName, WebActionModifierFlagsKey)) { 144 if (const UIEventWithKeyState* keyEvent = findEventWithKeyState(const_cast<Event*>(m_action.event()))) { 145 unsigned modifiers = 0; 146 147 if (keyEvent->ctrlKey()) 148 modifiers |= MK_CONTROL; 149 if (keyEvent->shiftKey()) 150 modifiers |= MK_SHIFT; 151 if (keyEvent->altKey()) 152 modifiers |= MK_ALT; 153 154 V_VT(pVar) = VT_UI4; 155 V_UI4(pVar) = modifiers; 156 return S_OK; 157 } 158 } 159 if (isEqual(pszPropName, WebActionFormKey)) { 160 IDOMNode* form = DOMNode::createInstance(m_form.get()); 161 V_VT(pVar) = VT_UNKNOWN; 162 V_UNKNOWN(pVar) = form; 163 return S_OK; 164 } 165 return E_INVALIDARG; 166 } 167 168 HRESULT STDMETHODCALLTYPE WebActionPropertyBag::Write(LPCOLESTR pszPropName, VARIANT* pVar) 169 { 170 if (!pszPropName || !pVar) 171 return E_POINTER; 172 173 return E_FAIL; 174 } 175