Home | History | Annotate | Download | only in win
      1 /*
      2  * Copyright (C) 2005, 2006, 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  *
      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 "UIDelegate.h"
     31 
     32 #include "DumpRenderTree.h"
     33 #include "DraggingInfo.h"
     34 #include "EventSender.h"
     35 #include "LayoutTestController.h"
     36 #include "DRTDesktopNotificationPresenter.h"
     37 
     38 #include <WebCore/COMPtr.h>
     39 #include <wtf/Platform.h>
     40 #include <wtf/Vector.h>
     41 #include <JavaScriptCore/Assertions.h>
     42 #include <JavaScriptCore/JavaScriptCore.h>
     43 #include <WebKit/WebKit.h>
     44 #include <stdio.h>
     45 
     46 using std::wstring;
     47 
     48 class DRTUndoObject {
     49 public:
     50     DRTUndoObject(IWebUndoTarget* target, BSTR actionName, IUnknown* obj)
     51         : m_target(target)
     52         , m_actionName(SysAllocString(actionName))
     53         , m_obj(obj)
     54     {
     55     }
     56 
     57     ~DRTUndoObject()
     58     {
     59         SysFreeString(m_actionName);
     60     }
     61 
     62     void invoke()
     63     {
     64         m_target->invoke(m_actionName, m_obj.get());
     65     }
     66 
     67 private:
     68     IWebUndoTarget* m_target;
     69     BSTR m_actionName;
     70     COMPtr<IUnknown> m_obj;
     71 };
     72 
     73 class DRTUndoStack {
     74 public:
     75     ~DRTUndoStack() { deleteAllValues(m_undoVector); }
     76 
     77     bool isEmpty() const { return m_undoVector.isEmpty(); }
     78     void clear() { deleteAllValues(m_undoVector); m_undoVector.clear(); }
     79 
     80     void push(DRTUndoObject* undoObject) { m_undoVector.append(undoObject); }
     81     DRTUndoObject* pop() { DRTUndoObject* top = m_undoVector.last(); m_undoVector.removeLast(); return top; }
     82 
     83 private:
     84     Vector<DRTUndoObject*> m_undoVector;
     85 };
     86 
     87 class DRTUndoManager {
     88 public:
     89     DRTUndoManager();
     90 
     91     void removeAllActions();
     92     void registerUndoWithTarget(IWebUndoTarget* target, BSTR actionName, IUnknown* obj);
     93     void redo();
     94     void undo();
     95     bool canRedo() { return !m_redoStack->isEmpty(); }
     96     bool canUndo() { return !m_undoStack->isEmpty(); }
     97 
     98 private:
     99     OwnPtr<DRTUndoStack> m_redoStack;
    100     OwnPtr<DRTUndoStack> m_undoStack;
    101     bool m_isRedoing;
    102     bool m_isUndoing;
    103 };
    104 
    105 DRTUndoManager::DRTUndoManager()
    106     : m_redoStack(new DRTUndoStack)
    107     , m_undoStack(new DRTUndoStack)
    108     , m_isRedoing(false)
    109     , m_isUndoing(false)
    110 {
    111 }
    112 
    113 void DRTUndoManager::removeAllActions()
    114 {
    115     m_redoStack->clear();
    116     m_undoStack->clear();
    117 }
    118 
    119 void DRTUndoManager::registerUndoWithTarget(IWebUndoTarget* target, BSTR actionName, IUnknown* obj)
    120 {
    121     if (!m_isUndoing && !m_isRedoing)
    122         m_redoStack->clear();
    123 
    124     DRTUndoStack* stack = m_isUndoing ? m_redoStack.get() : m_undoStack.get();
    125     stack->push(new DRTUndoObject(target, actionName, obj));
    126 }
    127 
    128 void DRTUndoManager::redo()
    129 {
    130     if (!canRedo())
    131         return;
    132 
    133     m_isRedoing = true;
    134 
    135     DRTUndoObject* redoObject = m_redoStack->pop();
    136     redoObject->invoke();
    137     delete redoObject;
    138 
    139     m_isRedoing = false;
    140 }
    141 
    142 void DRTUndoManager::undo()
    143 {
    144     if (!canUndo())
    145         return;
    146 
    147     m_isUndoing = true;
    148 
    149     DRTUndoObject* undoObject = m_undoStack->pop();
    150     undoObject->invoke();
    151     delete undoObject;
    152 
    153     m_isUndoing = false;
    154 }
    155 
    156 UIDelegate::UIDelegate()
    157     : m_refCount(1)
    158     , m_undoManager(new DRTUndoManager)
    159     , m_desktopNotifications(new DRTDesktopNotificationPresenter)
    160 {
    161     m_frame.bottom = 0;
    162     m_frame.top = 0;
    163     m_frame.left = 0;
    164     m_frame.right = 0;
    165 }
    166 
    167 void UIDelegate::resetUndoManager()
    168 {
    169     m_undoManager.set(new DRTUndoManager);
    170 }
    171 
    172 HRESULT STDMETHODCALLTYPE UIDelegate::QueryInterface(REFIID riid, void** ppvObject)
    173 {
    174     *ppvObject = 0;
    175     if (IsEqualGUID(riid, IID_IUnknown))
    176         *ppvObject = static_cast<IWebUIDelegate*>(this);
    177     else if (IsEqualGUID(riid, IID_IWebUIDelegate))
    178         *ppvObject = static_cast<IWebUIDelegate*>(this);
    179     else if (IsEqualGUID(riid, IID_IWebUIDelegate2))
    180         *ppvObject = static_cast<IWebUIDelegate2*>(this);
    181     else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate))
    182         *ppvObject = static_cast<IWebUIDelegatePrivate*>(this);
    183     else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate2))
    184         *ppvObject = static_cast<IWebUIDelegatePrivate2*>(this);
    185     else if (IsEqualGUID(riid, IID_IWebUIDelegatePrivate3))
    186         *ppvObject = static_cast<IWebUIDelegatePrivate3*>(this);
    187     else
    188         return E_NOINTERFACE;
    189 
    190     AddRef();
    191     return S_OK;
    192 }
    193 
    194 ULONG STDMETHODCALLTYPE UIDelegate::AddRef()
    195 {
    196     return ++m_refCount;
    197 }
    198 
    199 ULONG STDMETHODCALLTYPE UIDelegate::Release()
    200 {
    201     ULONG newRef = --m_refCount;
    202     if (!newRef)
    203         delete(this);
    204 
    205     return newRef;
    206 }
    207 
    208 HRESULT STDMETHODCALLTYPE UIDelegate::hasCustomMenuImplementation(
    209         /* [retval][out] */ BOOL *hasCustomMenus)
    210 {
    211     *hasCustomMenus = TRUE;
    212 
    213     return S_OK;
    214 }
    215 
    216 HRESULT STDMETHODCALLTYPE UIDelegate::trackCustomPopupMenu(
    217         /* [in] */ IWebView *sender,
    218         /* [in] */ OLE_HANDLE menu,
    219         /* [in] */ LPPOINT point)
    220 {
    221     // Do nothing
    222     return S_OK;
    223 }
    224 
    225 HRESULT STDMETHODCALLTYPE UIDelegate::registerUndoWithTarget(
    226         /* [in] */ IWebUndoTarget* target,
    227         /* [in] */ BSTR actionName,
    228         /* [in] */ IUnknown* actionArg)
    229 {
    230     m_undoManager->registerUndoWithTarget(target, actionName, actionArg);
    231     return S_OK;
    232 }
    233 
    234 HRESULT STDMETHODCALLTYPE UIDelegate::removeAllActionsWithTarget(
    235         /* [in] */ IWebUndoTarget*)
    236 {
    237     m_undoManager->removeAllActions();
    238     return S_OK;
    239 }
    240 
    241 HRESULT STDMETHODCALLTYPE UIDelegate::setActionTitle(
    242         /* [in] */ BSTR actionTitle)
    243 {
    244     // It is not neccessary to implement this for DRT because there is
    245     // menu to write out the title to.
    246     return S_OK;
    247 }
    248 
    249 HRESULT STDMETHODCALLTYPE UIDelegate::undo()
    250 {
    251     m_undoManager->undo();
    252     return S_OK;
    253 }
    254 
    255 HRESULT STDMETHODCALLTYPE UIDelegate::redo()
    256 {
    257     m_undoManager->redo();
    258     return S_OK;
    259 }
    260 
    261 HRESULT STDMETHODCALLTYPE UIDelegate::canUndo(
    262         /* [retval][out] */ BOOL* result)
    263 {
    264     if (!result)
    265         return E_POINTER;
    266 
    267     *result = m_undoManager->canUndo();
    268     return S_OK;
    269 }
    270 
    271 HRESULT STDMETHODCALLTYPE UIDelegate::canRedo(
    272         /* [retval][out] */ BOOL* result)
    273 {
    274     if (!result)
    275         return E_POINTER;
    276 
    277     *result = m_undoManager->canRedo();
    278     return S_OK;
    279 }
    280 
    281 HRESULT STDMETHODCALLTYPE UIDelegate::printFrame(
    282     /* [in] */ IWebView *webView,
    283     /* [in] */ IWebFrame *frame)
    284 {
    285     return E_NOTIMPL;
    286 }
    287 
    288 HRESULT STDMETHODCALLTYPE UIDelegate::ftpDirectoryTemplatePath(
    289     /* [in] */ IWebView *webView,
    290     /* [retval][out] */ BSTR *path)
    291 {
    292     if (!path)
    293         return E_POINTER;
    294     *path = 0;
    295     return E_NOTIMPL;
    296 }
    297 
    298 
    299 HRESULT STDMETHODCALLTYPE UIDelegate::webViewHeaderHeight(
    300     /* [in] */ IWebView *webView,
    301     /* [retval][out] */ float *result)
    302 {
    303     if (!result)
    304         return E_POINTER;
    305     *result = 0;
    306     return E_NOTIMPL;
    307 }
    308 
    309 HRESULT STDMETHODCALLTYPE UIDelegate::webViewFooterHeight(
    310     /* [in] */ IWebView *webView,
    311     /* [retval][out] */ float *result)
    312 {
    313     if (!result)
    314         return E_POINTER;
    315     *result = 0;
    316     return E_NOTIMPL;
    317 }
    318 
    319 HRESULT STDMETHODCALLTYPE UIDelegate::drawHeaderInRect(
    320     /* [in] */ IWebView *webView,
    321     /* [in] */ RECT *rect,
    322     /* [in] */ OLE_HANDLE drawingContext)
    323 {
    324     return E_NOTIMPL;
    325 }
    326 
    327 HRESULT STDMETHODCALLTYPE UIDelegate::drawFooterInRect(
    328     /* [in] */ IWebView *webView,
    329     /* [in] */ RECT *rect,
    330     /* [in] */ OLE_HANDLE drawingContext,
    331     /* [in] */ UINT pageIndex,
    332     /* [in] */ UINT pageCount)
    333 {
    334     return E_NOTIMPL;
    335 }
    336 
    337 HRESULT STDMETHODCALLTYPE UIDelegate::webViewPrintingMarginRect(
    338     /* [in] */ IWebView *webView,
    339     /* [retval][out] */ RECT *rect)
    340 {
    341     return E_NOTIMPL;
    342 }
    343 
    344 HRESULT STDMETHODCALLTYPE UIDelegate::canRunModal(
    345     /* [in] */ IWebView *webView,
    346     /* [retval][out] */ BOOL *canRunBoolean)
    347 {
    348     return E_NOTIMPL;
    349 }
    350 
    351 HRESULT STDMETHODCALLTYPE UIDelegate::createModalDialog(
    352     /* [in] */ IWebView *sender,
    353     /* [in] */ IWebURLRequest *request,
    354     /* [retval][out] */ IWebView **newWebView)
    355 {
    356     return E_NOTIMPL;
    357 }
    358 
    359 HRESULT STDMETHODCALLTYPE UIDelegate::runModal(
    360     /* [in] */ IWebView *webView)
    361 {
    362     return E_NOTIMPL;
    363 }
    364 
    365 HRESULT STDMETHODCALLTYPE UIDelegate::isMenuBarVisible(
    366     /* [in] */ IWebView *webView,
    367     /* [retval][out] */ BOOL *visible)
    368 {
    369     if (!visible)
    370         return E_POINTER;
    371     *visible = false;
    372     return E_NOTIMPL;
    373 }
    374 
    375 HRESULT STDMETHODCALLTYPE UIDelegate::setMenuBarVisible(
    376     /* [in] */ IWebView *webView,
    377     /* [in] */ BOOL visible)
    378 {
    379     return E_NOTIMPL;
    380 }
    381 
    382 HRESULT STDMETHODCALLTYPE UIDelegate::runDatabaseSizeLimitPrompt(
    383     /* [in] */ IWebView *webView,
    384     /* [in] */ BSTR displayName,
    385     /* [in] */ IWebFrame *initiatedByFrame,
    386     /* [retval][out] */ BOOL *allowed)
    387 {
    388     if (!allowed)
    389         return E_POINTER;
    390     *allowed = false;
    391     return E_NOTIMPL;
    392 }
    393 
    394 HRESULT STDMETHODCALLTYPE UIDelegate::paintCustomScrollbar(
    395     /* [in] */ IWebView *webView,
    396     /* [in] */ HDC hDC,
    397     /* [in] */ RECT rect,
    398     /* [in] */ WebScrollBarControlSize size,
    399     /* [in] */ WebScrollbarControlState state,
    400     /* [in] */ WebScrollbarControlPart pressedPart,
    401     /* [in] */ BOOL vertical,
    402     /* [in] */ float value,
    403     /* [in] */ float proportion,
    404     /* [in] */ WebScrollbarControlPartMask parts)
    405 {
    406     return E_NOTIMPL;
    407 }
    408 
    409 HRESULT STDMETHODCALLTYPE UIDelegate::paintCustomScrollCorner(
    410     /* [in] */ IWebView *webView,
    411     /* [in] */ HDC hDC,
    412     /* [in] */ RECT rect)
    413 {
    414     return E_NOTIMPL;
    415 }
    416 
    417 HRESULT STDMETHODCALLTYPE UIDelegate::setFrame(
    418         /* [in] */ IWebView* /*sender*/,
    419         /* [in] */ RECT* frame)
    420 {
    421     m_frame = *frame;
    422     return S_OK;
    423 }
    424 
    425 HRESULT STDMETHODCALLTYPE UIDelegate::webViewFrame(
    426         /* [in] */ IWebView* /*sender*/,
    427         /* [retval][out] */ RECT* frame)
    428 {
    429     *frame = m_frame;
    430     return S_OK;
    431 }
    432 
    433 HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptAlertPanelWithMessage(
    434         /* [in] */ IWebView* /*sender*/,
    435         /* [in] */ BSTR message)
    436 {
    437     printf("ALERT: %S\n", message ? message : L"");
    438 
    439     return S_OK;
    440 }
    441 
    442 HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptConfirmPanelWithMessage(
    443     /* [in] */ IWebView* sender,
    444     /* [in] */ BSTR message,
    445     /* [retval][out] */ BOOL* result)
    446 {
    447     printf("CONFIRM: %S\n", message ? message : L"");
    448     *result = TRUE;
    449 
    450     return S_OK;
    451 }
    452 
    453 HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptTextInputPanelWithPrompt(
    454     /* [in] */ IWebView *sender,
    455     /* [in] */ BSTR message,
    456     /* [in] */ BSTR defaultText,
    457     /* [retval][out] */ BSTR *result)
    458 {
    459     printf("PROMPT: %S, default text: %S\n", message ? message : L"", defaultText ? defaultText : L"");
    460     *result = SysAllocString(defaultText);
    461 
    462     return S_OK;
    463 }
    464 
    465 HRESULT STDMETHODCALLTYPE UIDelegate::runBeforeUnloadConfirmPanelWithMessage(
    466     /* [in] */ IWebView* /*sender*/,
    467     /* [in] */ BSTR /*message*/,
    468     /* [in] */ IWebFrame* /*initiatedByFrame*/,
    469     /* [retval][out] */ BOOL* result)
    470 {
    471     if (!result)
    472         return E_POINTER;
    473     *result = TRUE;
    474     return E_NOTIMPL;
    475 }
    476 
    477 HRESULT STDMETHODCALLTYPE UIDelegate::webViewAddMessageToConsole(
    478     /* [in] */ IWebView* sender,
    479     /* [in] */ BSTR message,
    480     /* [in] */ int lineNumber,
    481     /* [in] */ BSTR url,
    482     /* [in] */ BOOL isError)
    483 {
    484     wstring newMessage;
    485     if (message) {
    486         newMessage = message;
    487         size_t fileProtocol = newMessage.find(L"file://");
    488         if (fileProtocol != wstring::npos)
    489             newMessage = newMessage.substr(0, fileProtocol) + lastPathComponent(newMessage.substr(fileProtocol));
    490     }
    491 
    492     printf("CONSOLE MESSAGE: line %d: %s\n", lineNumber, toUTF8(newMessage).c_str());
    493     return S_OK;
    494 }
    495 
    496 HRESULT STDMETHODCALLTYPE UIDelegate::doDragDrop(
    497     /* [in] */ IWebView* sender,
    498     /* [in] */ IDataObject* object,
    499     /* [in] */ IDropSource* source,
    500     /* [in] */ DWORD okEffect,
    501     /* [retval][out] */ DWORD* performedEffect)
    502 {
    503     if (!performedEffect)
    504         return E_POINTER;
    505 
    506     *performedEffect = 0;
    507 
    508     draggingInfo = new DraggingInfo(object, source);
    509     HRESULT oleDragAndDropReturnValue = DRAGDROP_S_CANCEL;
    510     replaySavedEvents(&oleDragAndDropReturnValue);
    511     if (draggingInfo) {
    512         *performedEffect = draggingInfo->performedDropEffect();
    513         delete draggingInfo;
    514         draggingInfo = 0;
    515     }
    516     return oleDragAndDropReturnValue;
    517 }
    518 
    519 HRESULT STDMETHODCALLTYPE UIDelegate::webViewGetDlgCode(
    520     /* [in] */ IWebView* /*sender*/,
    521     /* [in] */ UINT /*keyCode*/,
    522     /* [retval][out] */ LONG_PTR *code)
    523 {
    524     if (!code)
    525         return E_POINTER;
    526     *code = 0;
    527     return E_NOTIMPL;
    528 }
    529 
    530 HRESULT STDMETHODCALLTYPE UIDelegate::createWebViewWithRequest(
    531         /* [in] */ IWebView *sender,
    532         /* [in] */ IWebURLRequest *request,
    533         /* [retval][out] */ IWebView **newWebView)
    534 {
    535     if (!::gLayoutTestController->canOpenWindows())
    536         return E_FAIL;
    537     *newWebView = createWebViewAndOffscreenWindow();
    538     return S_OK;
    539 }
    540 
    541 HRESULT STDMETHODCALLTYPE UIDelegate::webViewClose(
    542         /* [in] */ IWebView *sender)
    543 {
    544     HWND hostWindow;
    545     sender->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
    546     DestroyWindow(hostWindow);
    547     return S_OK;
    548 }
    549 
    550 HRESULT STDMETHODCALLTYPE UIDelegate::webViewFocus(
    551         /* [in] */ IWebView *sender)
    552 {
    553     HWND hostWindow;
    554     sender->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
    555     SetForegroundWindow(hostWindow);
    556     return S_OK;
    557 }
    558 
    559 HRESULT STDMETHODCALLTYPE UIDelegate::webViewUnfocus(
    560         /* [in] */ IWebView *sender)
    561 {
    562     SetForegroundWindow(GetDesktopWindow());
    563     return S_OK;
    564 }
    565 
    566 HRESULT STDMETHODCALLTYPE UIDelegate::webViewPainted(
    567         /* [in] */ IWebView *sender)
    568 {
    569     return S_OK;
    570 }
    571 
    572 HRESULT STDMETHODCALLTYPE UIDelegate::exceededDatabaseQuota(
    573         /* [in] */ IWebView *sender,
    574         /* [in] */ IWebFrame *frame,
    575         /* [in] */ IWebSecurityOrigin *origin,
    576         /* [in] */ BSTR databaseIdentifier)
    577 {
    578     BSTR protocol;
    579     BSTR host;
    580     unsigned short port;
    581 
    582     origin->protocol(&protocol);
    583     origin->host(&host);
    584     origin->port(&port);
    585 
    586     if (!done && gLayoutTestController->dumpDatabaseCallbacks())
    587         printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%S, %S, %i} database:%S\n", protocol, host, port, databaseIdentifier);
    588 
    589     SysFreeString(protocol);
    590     SysFreeString(host);
    591 
    592     static const unsigned long long defaultQuota = 5 * 1024 * 1024;
    593     origin->setQuota(defaultQuota);
    594 
    595     return S_OK;
    596 }
    597 
    598 HRESULT STDMETHODCALLTYPE UIDelegate::embeddedViewWithArguments(
    599     /* [in] */ IWebView *sender,
    600     /* [in] */ IWebFrame *frame,
    601     /* [in] */ IPropertyBag *arguments,
    602     /* [retval][out] */ IWebEmbeddedView **view)
    603 {
    604     if (!view)
    605         return E_POINTER;
    606     *view = 0;
    607     return E_NOTIMPL;
    608 }
    609 
    610 HRESULT STDMETHODCALLTYPE UIDelegate::webViewClosing(
    611     /* [in] */ IWebView *sender)
    612 {
    613     return E_NOTIMPL;
    614 }
    615 
    616 HRESULT STDMETHODCALLTYPE UIDelegate::webViewSetCursor(
    617     /* [in] */ IWebView *sender,
    618     /* [in] */ OLE_HANDLE cursor)
    619 {
    620     return E_NOTIMPL;
    621 }
    622 
    623 HRESULT STDMETHODCALLTYPE UIDelegate::webViewDidInvalidate(
    624     /* [in] */ IWebView *sender)
    625 {
    626     return E_NOTIMPL;
    627 }
    628 
    629 HRESULT STDMETHODCALLTYPE UIDelegate::setStatusText(IWebView*, BSTR text)
    630 {
    631     if (gLayoutTestController->dumpStatusCallbacks())
    632         printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", text ? toUTF8(text).c_str() : "");
    633     return S_OK;
    634 }
    635 
    636 HRESULT STDMETHODCALLTYPE UIDelegate::desktopNotificationsDelegate(IWebDesktopNotificationsDelegate** result)
    637 {
    638     m_desktopNotifications.copyRefTo(result);
    639     return S_OK;
    640 }
    641 
    642 HRESULT STDMETHODCALLTYPE UIDelegate::createWebViewWithRequest(IWebView* sender, IWebURLRequest* request, IPropertyBag* windowFeatures, IWebView** newWebView)
    643 {
    644     return E_NOTIMPL;
    645 }
    646 
    647 HRESULT STDMETHODCALLTYPE UIDelegate::drawBackground(IWebView* sender, OLE_HANDLE hdc, const RECT* dirtyRect)
    648 {
    649     return E_NOTIMPL;
    650 }
    651 
    652 HRESULT STDMETHODCALLTYPE UIDelegate::decidePolicyForGeolocationRequest(IWebView* sender, IWebFrame* frame, IWebSecurityOrigin* origin, IWebGeolocationPolicyListener* listener)
    653 {
    654     return E_NOTIMPL;
    655 }
    656 
    657 HRESULT STDMETHODCALLTYPE UIDelegate::didPressMissingPluginButton(IDOMElement* element)
    658 {
    659     printf("MISSING PLUGIN BUTTON PRESSED\n");
    660     return S_OK;
    661 }
    662 
    663