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