Home | History | Annotate | Download | only in win
      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 
     42 EditingDelegate::EditingDelegate()
     43     : m_refCount(1)
     44     , m_acceptsEditing(true)
     45 {
     46 }
     47 
     48 // IUnknown
     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 
     63 ULONG STDMETHODCALLTYPE EditingDelegate::AddRef(void)
     64 {
     65     return ++m_refCount;
     66 }
     67 
     68 ULONG STDMETHODCALLTYPE EditingDelegate::Release(void)
     69 {
     70     ULONG newRef = --m_refCount;
     71     if (!newRef)
     72         delete this;
     73 
     74     return newRef;
     75 }
     76 
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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