Clean up ChunkedUpdateDrawingAreaProxy
[WebKit-https.git] / Tools / DumpRenderTree / win / UIDelegate.cpp
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) + urlSuitableForTestResult(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