2
* Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
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.
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.
30
#include "UIDelegate.h"
32
#include "DumpRenderTree.h"
33
#include "DraggingInfo.h"
34
#include "EventSender.h"
35
#include "DRTDesktopNotificationPresenter.h"
36
#include "TestRunner.h"
37
#include <WebCore/COMPtr.h>
38
#include <wtf/Assertions.h>
39
#include <wtf/PassOwnPtr.h>
40
#include <wtf/Platform.h>
41
#include <wtf/Vector.h>
42
#include <JavaScriptCore/JavaScriptCore.h>
43
#include <WebKit/WebKit.h>
50
DRTUndoObject(IWebUndoTarget* target, BSTR actionName, IUnknown* obj)
52
, m_actionName(SysAllocString(actionName))
59
SysFreeString(m_actionName);
64
m_target->invoke(m_actionName, m_obj.get());
68
IWebUndoTarget* m_target;
70
COMPtr<IUnknown> m_obj;
75
~DRTUndoStack() { deleteAllValues(m_undoVector); }
77
bool isEmpty() const { return m_undoVector.isEmpty(); }
78
void clear() { deleteAllValues(m_undoVector); m_undoVector.clear(); }
80
void push(DRTUndoObject* undoObject) { m_undoVector.append(undoObject); }
81
DRTUndoObject* pop() { DRTUndoObject* top = m_undoVector.last(); m_undoVector.removeLast(); return top; }
84
Vector<DRTUndoObject*> m_undoVector;
87
class DRTUndoManager {
91
void removeAllActions();
92
void registerUndoWithTarget(IWebUndoTarget* target, BSTR actionName, IUnknown* obj);
95
bool canRedo() { return !m_redoStack->isEmpty(); }
96
bool canUndo() { return !m_undoStack->isEmpty(); }
99
OwnPtr<DRTUndoStack> m_redoStack;
100
OwnPtr<DRTUndoStack> m_undoStack;
105
DRTUndoManager::DRTUndoManager()
106
: m_redoStack(adoptPtr(new DRTUndoStack))
107
, m_undoStack(adoptPtr(new DRTUndoStack))
113
void DRTUndoManager::removeAllActions()
115
m_redoStack->clear();
116
m_undoStack->clear();
119
void DRTUndoManager::registerUndoWithTarget(IWebUndoTarget* target, BSTR actionName, IUnknown* obj)
121
if (!m_isUndoing && !m_isRedoing)
122
m_redoStack->clear();
124
DRTUndoStack* stack = m_isUndoing ? m_redoStack.get() : m_undoStack.get();
125
stack->push(new DRTUndoObject(target, actionName, obj));
128
void DRTUndoManager::redo()
135
DRTUndoObject* redoObject = m_redoStack->pop();
136
redoObject->invoke();
142
void DRTUndoManager::undo()
149
DRTUndoObject* undoObject = m_undoStack->pop();
150
undoObject->invoke();
156
UIDelegate::UIDelegate()
158
, m_undoManager(adoptPtr(new DRTUndoManager))
159
, m_desktopNotifications(new DRTDesktopNotificationPresenter)
167
void UIDelegate::resetUndoManager()
169
m_undoManager = adoptPtr(new DRTUndoManager);
172
HRESULT STDMETHODCALLTYPE UIDelegate::QueryInterface(REFIID riid, void** ppvObject)
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);
188
return E_NOINTERFACE;
194
ULONG STDMETHODCALLTYPE UIDelegate::AddRef()
199
ULONG STDMETHODCALLTYPE UIDelegate::Release()
201
ULONG newRef = --m_refCount;
208
HRESULT STDMETHODCALLTYPE UIDelegate::hasCustomMenuImplementation(
209
/* [retval][out] */ BOOL *hasCustomMenus)
211
*hasCustomMenus = TRUE;
216
HRESULT STDMETHODCALLTYPE UIDelegate::trackCustomPopupMenu(
217
/* [in] */ IWebView *sender,
218
/* [in] */ OLE_HANDLE menu,
219
/* [in] */ LPPOINT point)
225
HRESULT STDMETHODCALLTYPE UIDelegate::registerUndoWithTarget(
226
/* [in] */ IWebUndoTarget* target,
227
/* [in] */ BSTR actionName,
228
/* [in] */ IUnknown* actionArg)
230
m_undoManager->registerUndoWithTarget(target, actionName, actionArg);
234
HRESULT STDMETHODCALLTYPE UIDelegate::removeAllActionsWithTarget(
235
/* [in] */ IWebUndoTarget*)
237
m_undoManager->removeAllActions();
241
HRESULT STDMETHODCALLTYPE UIDelegate::setActionTitle(
242
/* [in] */ BSTR actionTitle)
244
// It is not neccessary to implement this for DRT because there is
245
// menu to write out the title to.
249
HRESULT STDMETHODCALLTYPE UIDelegate::undo()
251
m_undoManager->undo();
255
HRESULT STDMETHODCALLTYPE UIDelegate::redo()
257
m_undoManager->redo();
261
HRESULT STDMETHODCALLTYPE UIDelegate::canUndo(
262
/* [retval][out] */ BOOL* result)
267
*result = m_undoManager->canUndo();
271
HRESULT STDMETHODCALLTYPE UIDelegate::canRedo(
272
/* [retval][out] */ BOOL* result)
277
*result = m_undoManager->canRedo();
281
HRESULT STDMETHODCALLTYPE UIDelegate::printFrame(
282
/* [in] */ IWebView *webView,
283
/* [in] */ IWebFrame *frame)
288
HRESULT STDMETHODCALLTYPE UIDelegate::ftpDirectoryTemplatePath(
289
/* [in] */ IWebView *webView,
290
/* [retval][out] */ BSTR *path)
299
HRESULT STDMETHODCALLTYPE UIDelegate::webViewHeaderHeight(
300
/* [in] */ IWebView *webView,
301
/* [retval][out] */ float *result)
309
HRESULT STDMETHODCALLTYPE UIDelegate::webViewFooterHeight(
310
/* [in] */ IWebView *webView,
311
/* [retval][out] */ float *result)
319
HRESULT STDMETHODCALLTYPE UIDelegate::drawHeaderInRect(
320
/* [in] */ IWebView *webView,
321
/* [in] */ RECT *rect,
322
/* [in] */ OLE_HANDLE drawingContext)
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)
337
HRESULT STDMETHODCALLTYPE UIDelegate::webViewPrintingMarginRect(
338
/* [in] */ IWebView *webView,
339
/* [retval][out] */ RECT *rect)
344
HRESULT STDMETHODCALLTYPE UIDelegate::canRunModal(
345
/* [in] */ IWebView *webView,
346
/* [retval][out] */ BOOL *canRunBoolean)
351
HRESULT STDMETHODCALLTYPE UIDelegate::createModalDialog(
352
/* [in] */ IWebView *sender,
353
/* [in] */ IWebURLRequest *request,
354
/* [retval][out] */ IWebView **newWebView)
359
HRESULT STDMETHODCALLTYPE UIDelegate::runModal(
360
/* [in] */ IWebView *webView)
365
HRESULT STDMETHODCALLTYPE UIDelegate::isMenuBarVisible(
366
/* [in] */ IWebView *webView,
367
/* [retval][out] */ BOOL *visible)
375
HRESULT STDMETHODCALLTYPE UIDelegate::setMenuBarVisible(
376
/* [in] */ IWebView *webView,
377
/* [in] */ BOOL visible)
382
HRESULT STDMETHODCALLTYPE UIDelegate::runDatabaseSizeLimitPrompt(
383
/* [in] */ IWebView *webView,
384
/* [in] */ BSTR displayName,
385
/* [in] */ IWebFrame *initiatedByFrame,
386
/* [retval][out] */ BOOL *allowed)
394
HRESULT STDMETHODCALLTYPE UIDelegate::paintCustomScrollbar(
395
/* [in] */ IWebView *webView,
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)
409
HRESULT STDMETHODCALLTYPE UIDelegate::paintCustomScrollCorner(
410
/* [in] */ IWebView *webView,
412
/* [in] */ RECT rect)
417
HRESULT STDMETHODCALLTYPE UIDelegate::setFrame(
418
/* [in] */ IWebView* /*sender*/,
419
/* [in] */ RECT* frame)
425
HRESULT STDMETHODCALLTYPE UIDelegate::webViewFrame(
426
/* [in] */ IWebView* /*sender*/,
427
/* [retval][out] */ RECT* frame)
433
HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptAlertPanelWithMessage(
434
/* [in] */ IWebView* /*sender*/,
435
/* [in] */ BSTR message)
437
printf("ALERT: %S\n", message ? message : L"");
443
HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptConfirmPanelWithMessage(
444
/* [in] */ IWebView* sender,
445
/* [in] */ BSTR message,
446
/* [retval][out] */ BOOL* result)
448
printf("CONFIRM: %S\n", message ? message : L"");
454
HRESULT STDMETHODCALLTYPE UIDelegate::runJavaScriptTextInputPanelWithPrompt(
455
/* [in] */ IWebView *sender,
456
/* [in] */ BSTR message,
457
/* [in] */ BSTR defaultText,
458
/* [retval][out] */ BSTR *result)
460
printf("PROMPT: %S, default text: %S\n", message ? message : L"", defaultText ? defaultText : L"");
461
*result = SysAllocString(defaultText);
466
HRESULT STDMETHODCALLTYPE UIDelegate::runBeforeUnloadConfirmPanelWithMessage(
467
/* [in] */ IWebView* /*sender*/,
468
/* [in] */ BSTR message,
469
/* [in] */ IWebFrame* /*initiatedByFrame*/,
470
/* [retval][out] */ BOOL* result)
474
printf("CONFIRM NAVIGATION: %S\n", message ? message : L"");
475
*result = !gTestRunner->shouldStayOnPageAfterHandlingBeforeUnload();
479
HRESULT STDMETHODCALLTYPE UIDelegate::webViewAddMessageToConsole(
480
/* [in] */ IWebView* sender,
481
/* [in] */ BSTR message,
482
/* [in] */ int lineNumber,
484
/* [in] */ BOOL isError)
488
newMessage = message;
489
size_t fileProtocol = newMessage.find(L"file://");
490
if (fileProtocol != wstring::npos)
491
newMessage = newMessage.substr(0, fileProtocol) + lastPathComponent(newMessage.substr(fileProtocol));
494
printf("CONSOLE MESSAGE: ");
496
printf("line %d: ", lineNumber);
497
printf("%s\n", toUTF8(newMessage).c_str());
501
HRESULT STDMETHODCALLTYPE UIDelegate::doDragDrop(
502
/* [in] */ IWebView* sender,
503
/* [in] */ IDataObject* object,
504
/* [in] */ IDropSource* source,
505
/* [in] */ DWORD okEffect,
506
/* [retval][out] */ DWORD* performedEffect)
508
if (!performedEffect)
511
*performedEffect = 0;
513
draggingInfo = new DraggingInfo(object, source);
514
HRESULT oleDragAndDropReturnValue = DRAGDROP_S_CANCEL;
515
replaySavedEvents(&oleDragAndDropReturnValue);
517
*performedEffect = draggingInfo->performedDropEffect();
521
return oleDragAndDropReturnValue;
524
HRESULT STDMETHODCALLTYPE UIDelegate::webViewGetDlgCode(
525
/* [in] */ IWebView* /*sender*/,
526
/* [in] */ UINT /*keyCode*/,
527
/* [retval][out] */ LONG_PTR *code)
535
HRESULT STDMETHODCALLTYPE UIDelegate::createWebViewWithRequest(
536
/* [in] */ IWebView *sender,
537
/* [in] */ IWebURLRequest *request,
538
/* [retval][out] */ IWebView **newWebView)
540
if (!::gTestRunner->canOpenWindows())
542
*newWebView = createWebViewAndOffscreenWindow();
546
HRESULT STDMETHODCALLTYPE UIDelegate::webViewClose(
547
/* [in] */ IWebView *sender)
550
sender->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
551
DestroyWindow(hostWindow);
555
HRESULT STDMETHODCALLTYPE UIDelegate::webViewFocus(
556
/* [in] */ IWebView *sender)
559
sender->hostWindow(reinterpret_cast<OLE_HANDLE*>(&hostWindow));
560
SetForegroundWindow(hostWindow);
564
HRESULT STDMETHODCALLTYPE UIDelegate::webViewUnfocus(
565
/* [in] */ IWebView *sender)
567
SetForegroundWindow(GetDesktopWindow());
571
HRESULT STDMETHODCALLTYPE UIDelegate::webViewPainted(
572
/* [in] */ IWebView *sender)
577
HRESULT STDMETHODCALLTYPE UIDelegate::exceededDatabaseQuota(
578
/* [in] */ IWebView *sender,
579
/* [in] */ IWebFrame *frame,
580
/* [in] */ IWebSecurityOrigin *origin,
581
/* [in] */ BSTR databaseIdentifier)
587
origin->protocol(&protocol);
591
if (!done && gTestRunner->dumpDatabaseCallbacks())
592
printf("UI DELEGATE DATABASE CALLBACK: exceededDatabaseQuotaForSecurityOrigin:{%S, %S, %i} database:%S\n", protocol, host, port, databaseIdentifier);
594
SysFreeString(protocol);
597
static const unsigned long long defaultQuota = 5 * 1024 * 1024;
598
origin->setQuota(defaultQuota);
603
HRESULT STDMETHODCALLTYPE UIDelegate::embeddedViewWithArguments(
604
/* [in] */ IWebView *sender,
605
/* [in] */ IWebFrame *frame,
606
/* [in] */ IPropertyBag *arguments,
607
/* [retval][out] */ IWebEmbeddedView **view)
615
HRESULT STDMETHODCALLTYPE UIDelegate::webViewClosing(
616
/* [in] */ IWebView *sender)
621
HRESULT STDMETHODCALLTYPE UIDelegate::webViewSetCursor(
622
/* [in] */ IWebView *sender,
623
/* [in] */ OLE_HANDLE cursor)
628
HRESULT STDMETHODCALLTYPE UIDelegate::webViewDidInvalidate(
629
/* [in] */ IWebView *sender)
634
HRESULT STDMETHODCALLTYPE UIDelegate::setStatusText(IWebView*, BSTR text)
636
if (gTestRunner->dumpStatusCallbacks())
637
printf("UI DELEGATE STATUS CALLBACK: setStatusText:%s\n", text ? toUTF8(text).c_str() : "");
641
HRESULT STDMETHODCALLTYPE UIDelegate::desktopNotificationsDelegate(IWebDesktopNotificationsDelegate** result)
643
m_desktopNotifications.copyRefTo(result);
647
HRESULT STDMETHODCALLTYPE UIDelegate::createWebViewWithRequest(IWebView* sender, IWebURLRequest* request, IPropertyBag* windowFeatures, IWebView** newWebView)
652
HRESULT STDMETHODCALLTYPE UIDelegate::drawBackground(IWebView* sender, OLE_HANDLE hdc, const RECT* dirtyRect)
657
HRESULT STDMETHODCALLTYPE UIDelegate::decidePolicyForGeolocationRequest(IWebView* sender, IWebFrame* frame, IWebSecurityOrigin* origin, IWebGeolocationPolicyListener* listener)
662
HRESULT STDMETHODCALLTYPE UIDelegate::didPressMissingPluginButton(IDOMElement* element)
664
printf("MISSING PLUGIN BUTTON PRESSED\n");