• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 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 "EditingDelegate.h"
31 
32 #include "DumpRenderTree.h"
33 #include "LayoutTestController.h"
34 #include <WebCore/COMPtr.h>
35 #include <wtf/Platform.h>
36 #include <JavaScriptCore/Assertions.h>
37 #include <string>
38 #include <tchar.h>
39 
40 using std::wstring;
41 
EditingDelegate()42 EditingDelegate::EditingDelegate()
43     : m_refCount(1)
44     , m_acceptsEditing(true)
45 {
46 }
47 
48 // IUnknown
QueryInterface(REFIID riid,void ** ppvObject)49 HRESULT STDMETHODCALLTYPE EditingDelegate::QueryInterface(REFIID riid, void** ppvObject)
50 {
51     *ppvObject = 0;
52     if (IsEqualGUID(riid, IID_IUnknown))
53         *ppvObject = static_cast<IWebEditingDelegate*>(this);
54     else if (IsEqualGUID(riid, IID_IWebEditingDelegate))
55         *ppvObject = static_cast<IWebEditingDelegate*>(this);
56     else
57         return E_NOINTERFACE;
58 
59     AddRef();
60     return S_OK;
61 }
62 
AddRef(void)63 ULONG STDMETHODCALLTYPE EditingDelegate::AddRef(void)
64 {
65     return ++m_refCount;
66 }
67 
Release(void)68 ULONG STDMETHODCALLTYPE EditingDelegate::Release(void)
69 {
70     ULONG newRef = --m_refCount;
71     if (!newRef)
72         delete this;
73 
74     return newRef;
75 }
76 
dumpPath(IDOMNode * node)77 static wstring dumpPath(IDOMNode* node)
78 {
79     ASSERT(node);
80 
81     wstring result;
82 
83     BSTR name;
84     if (FAILED(node->nodeName(&name)))
85         return result;
86     result.assign(name, SysStringLen(name));
87     SysFreeString(name);
88 
89     COMPtr<IDOMNode> parent;
90     if (SUCCEEDED(node->parentNode(&parent)))
91         result += TEXT(" > ") + dumpPath(parent.get());
92 
93     return result;
94 }
95 
dump(IDOMRange * range)96 static wstring dump(IDOMRange* range)
97 {
98     ASSERT(range);
99 
100     int startOffset;
101     if (FAILED(range->startOffset(&startOffset)))
102         return 0;
103 
104     int endOffset;
105     if (FAILED(range->endOffset(&endOffset)))
106         return 0;
107 
108     COMPtr<IDOMNode> startContainer;
109     if (FAILED(range->startContainer(&startContainer)))
110         return 0;
111 
112     COMPtr<IDOMNode> endContainer;
113     if (FAILED(range->endContainer(&endContainer)))
114         return 0;
115 
116     wchar_t buffer[1024];
117     _snwprintf(buffer, ARRAYSIZE(buffer), L"range from %ld of %s to %ld of %s", startOffset, dumpPath(startContainer.get()), endOffset, dumpPath(endContainer.get()));
118     return buffer;
119 }
120 
shouldBeginEditingInDOMRange(IWebView * webView,IDOMRange * range,BOOL * result)121 HRESULT STDMETHODCALLTYPE EditingDelegate::shouldBeginEditingInDOMRange(
122     /* [in] */ IWebView* webView,
123     /* [in] */ IDOMRange* range,
124     /* [retval][out] */ BOOL* result)
125 {
126     if (!result) {
127         ASSERT_NOT_REACHED();
128         return E_POINTER;
129     }
130 
131     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
132         _tprintf(TEXT("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n"), dump(range));
133 
134     *result = m_acceptsEditing;
135     return S_OK;
136 }
137 
shouldEndEditingInDOMRange(IWebView * webView,IDOMRange * range,BOOL * result)138 HRESULT STDMETHODCALLTYPE EditingDelegate::shouldEndEditingInDOMRange(
139     /* [in] */ IWebView* webView,
140     /* [in] */ IDOMRange* range,
141     /* [retval][out] */ BOOL* result)
142 {
143     if (!result) {
144         ASSERT_NOT_REACHED();
145         return E_POINTER;
146     }
147 
148     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
149         _tprintf(TEXT("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n"), dump(range));
150 
151     *result = m_acceptsEditing;
152     return S_OK;
153 }
154 
shouldInsertNode(IWebView * webView,IDOMNode * node,IDOMRange * range,WebViewInsertAction action)155 HRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertNode(
156     /* [in] */ IWebView* webView,
157     /* [in] */ IDOMNode* node,
158     /* [in] */ IDOMRange* range,
159     /* [in] */ WebViewInsertAction action)
160 {
161     static LPCTSTR insertactionstring[] = {
162         TEXT("WebViewInsertActionTyped"),
163         TEXT("WebViewInsertActionPasted"),
164         TEXT("WebViewInsertActionDropped"),
165     };
166 
167     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
168         _tprintf(TEXT("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n"), dumpPath(node), dump(range), insertactionstring[action]);
169 
170     return S_OK;
171 }
172 
shouldInsertText(IWebView * webView,BSTR text,IDOMRange * range,WebViewInsertAction action,BOOL * result)173 HRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertText(
174     /* [in] */ IWebView* webView,
175     /* [in] */ BSTR text,
176     /* [in] */ IDOMRange* range,
177     /* [in] */ WebViewInsertAction action,
178     /* [retval][out] */ BOOL* result)
179 {
180     if (!result) {
181         ASSERT_NOT_REACHED();
182         return E_POINTER;
183     }
184 
185     static LPCTSTR insertactionstring[] = {
186         TEXT("WebViewInsertActionTyped"),
187         TEXT("WebViewInsertActionPasted"),
188         TEXT("WebViewInsertActionDropped"),
189     };
190 
191     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
192         _tprintf(TEXT("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n"), text ? text : TEXT(""), dump(range), insertactionstring[action]);
193 
194     *result = m_acceptsEditing;
195     return S_OK;
196 }
197 
shouldDeleteDOMRange(IWebView * webView,IDOMRange * range,BOOL * result)198 HRESULT STDMETHODCALLTYPE EditingDelegate::shouldDeleteDOMRange(
199     /* [in] */ IWebView* webView,
200     /* [in] */ IDOMRange* range,
201     /* [retval][out] */ BOOL* result)
202 {
203     if (!result) {
204         ASSERT_NOT_REACHED();
205         return E_POINTER;
206     }
207 
208     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
209         _tprintf(TEXT("EDITING DELEGATE: shouldDeleteDOMRange:%s\n"), dump(range));
210 
211     *result = m_acceptsEditing;
212     return S_OK;
213 }
214 
shouldChangeSelectedDOMRange(IWebView * webView,IDOMRange * currentRange,IDOMRange * proposedRange,WebSelectionAffinity selectionAffinity,BOOL stillSelecting,BOOL * result)215 HRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeSelectedDOMRange(
216     /* [in] */ IWebView* webView,
217     /* [in] */ IDOMRange* currentRange,
218     /* [in] */ IDOMRange* proposedRange,
219     /* [in] */ WebSelectionAffinity selectionAffinity,
220     /* [in] */ BOOL stillSelecting,
221     /* [retval][out] */ BOOL* result)
222 {
223     if (!result) {
224         ASSERT_NOT_REACHED();
225         return E_POINTER;
226     }
227 
228     static LPCTSTR affinitystring[] = {
229         TEXT("NSSelectionAffinityUpstream"),
230         TEXT("NSSelectionAffinityDownstream")
231     };
232     static LPCTSTR boolstring[] = {
233         TEXT("FALSE"),
234         TEXT("TRUE")
235     };
236 
237     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
238         _tprintf(TEXT("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n"), dump(currentRange), dump(proposedRange), affinitystring[selectionAffinity], boolstring[stillSelecting]);
239 
240     *result = m_acceptsEditing;
241     return S_OK;
242 }
243 
shouldApplyStyle(IWebView * webView,IDOMCSSStyleDeclaration * style,IDOMRange * range,BOOL * result)244 HRESULT STDMETHODCALLTYPE EditingDelegate::shouldApplyStyle(
245     /* [in] */ IWebView* webView,
246     /* [in] */ IDOMCSSStyleDeclaration* style,
247     /* [in] */ IDOMRange* range,
248     /* [retval][out] */ BOOL* result)
249 {
250     if (!result) {
251         ASSERT_NOT_REACHED();
252         return E_POINTER;
253     }
254 
255     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
256         _tprintf(TEXT("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n"), TEXT("'style description'")/*[[style description] UTF8String]*/, dump(range));
257 
258     *result = m_acceptsEditing;
259     return S_OK;
260 }
261 
shouldChangeTypingStyle(IWebView * webView,IDOMCSSStyleDeclaration * currentStyle,IDOMCSSStyleDeclaration * proposedStyle,BOOL * result)262 HRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeTypingStyle(
263     /* [in] */ IWebView* webView,
264     /* [in] */ IDOMCSSStyleDeclaration* currentStyle,
265     /* [in] */ IDOMCSSStyleDeclaration* proposedStyle,
266     /* [retval][out] */ BOOL* result)
267 {
268     if (!result) {
269         ASSERT_NOT_REACHED();
270         return E_POINTER;
271     }
272 
273     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
274         _tprintf(TEXT("EDITING DELEGATE: shouldChangeTypingStyle:%s toStyle:%s\n"), TEXT("'currentStyle description'"), TEXT("'proposedStyle description'"));
275 
276     *result = m_acceptsEditing;
277     return S_OK;
278 }
279 
doPlatformCommand(IWebView * webView,BSTR command,BOOL * result)280 HRESULT STDMETHODCALLTYPE EditingDelegate::doPlatformCommand(
281     /* [in] */ IWebView *webView,
282     /* [in] */ BSTR command,
283     /* [retval][out] */ BOOL *result)
284 {
285     if (!result) {
286         ASSERT_NOT_REACHED();
287         return E_POINTER;
288     }
289 
290     if (::gLayoutTestController->dumpEditingCallbacks() && !done)
291         _tprintf(TEXT("EDITING DELEGATE: doPlatformCommand:%s\n"), command ? command : TEXT(""));
292 
293     *result = m_acceptsEditing;
294     return S_OK;
295 }
296 
webViewDidBeginEditing(IWebNotification * notification)297 HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidBeginEditing(
298     /* [in] */ IWebNotification* notification)
299 {
300     if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
301         BSTR name;
302         notification->name(&name);
303         _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
304         SysFreeString(name);
305     }
306     return S_OK;
307 }
308 
webViewDidChange(IWebNotification * notification)309 HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChange(
310     /* [in] */ IWebNotification *notification)
311 {
312     if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
313         BSTR name;
314         notification->name(&name);
315         _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
316         SysFreeString(name);
317     }
318     return S_OK;
319 }
320 
webViewDidEndEditing(IWebNotification * notification)321 HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidEndEditing(
322     /* [in] */ IWebNotification *notification)
323 {
324     if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
325         BSTR name;
326         notification->name(&name);
327         _tprintf(TEXT("EDITING DELEGATE: webViewDidEndEditing:%s\n"), name ? name : TEXT(""));
328         SysFreeString(name);
329     }
330     return S_OK;
331 }
332 
webViewDidChangeTypingStyle(IWebNotification * notification)333 HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeTypingStyle(
334     /* [in] */ IWebNotification *notification)
335 {
336     if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
337         BSTR name;
338         notification->name(&name);
339         _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeTypingStyle:%s\n"), name ? name : TEXT(""));
340         SysFreeString(name);
341     }
342     return S_OK;
343 }
344 
webViewDidChangeSelection(IWebNotification * notification)345 HRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeSelection(
346     /* [in] */ IWebNotification *notification)
347 {
348     if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
349         BSTR name;
350         notification->name(&name);
351         _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeSelection:%s\n"), name ? name : TEXT(""));
352         SysFreeString(name);
353     }
354     return S_OK;
355 }
356