1563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark/*
2563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Copyright (C) 2007 Apple Inc.  All rights reserved.
3563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *
4563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * Redistribution and use in source and binary forms, with or without
5563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * modification, are permitted provided that the following conditions
6563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * are met:
7563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *
8563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 1.  Redistributions of source code must retain the above copyright
9563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     notice, this list of conditions and the following disclaimer.
10563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 2.  Redistributions in binary form must reproduce the above copyright
11563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     notice, this list of conditions and the following disclaimer in the
12563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     documentation and/or other materials provided with the distribution.
13563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
14563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     its contributors may be used to endorse or promote products derived
15563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *     from this software without specific prior written permission.
16563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark *
17563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
18563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
21563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark */
28563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
29563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "config.h"
30563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "EditingDelegate.h"
31563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
32563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "DumpRenderTree.h"
33563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include "LayoutTestController.h"
34563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <WebCore/COMPtr.h>
35563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <wtf/Platform.h>
36563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <JavaScriptCore/Assertions.h>
37563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <string>
38563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark#include <tchar.h>
39563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
40563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkusing std::wstring;
41563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
42563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkEditingDelegate::EditingDelegate()
43563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    : m_refCount(1)
44563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    , m_acceptsEditing(true)
45563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
46563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
47563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
48563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark// IUnknown
49563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::QueryInterface(REFIID riid, void** ppvObject)
50563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
51563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *ppvObject = 0;
52563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (IsEqualGUID(riid, IID_IUnknown))
53563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        *ppvObject = static_cast<IWebEditingDelegate*>(this);
54563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    else if (IsEqualGUID(riid, IID_IWebEditingDelegate))
55563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        *ppvObject = static_cast<IWebEditingDelegate*>(this);
56563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    else
57563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_NOINTERFACE;
58563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
59563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    AddRef();
60563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
61563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
62563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
63563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkULONG STDMETHODCALLTYPE EditingDelegate::AddRef(void)
64563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
65563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return ++m_refCount;
66563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
67563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
68563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkULONG STDMETHODCALLTYPE EditingDelegate::Release(void)
69563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
70563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    ULONG newRef = --m_refCount;
71563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!newRef)
72563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        delete this;
73563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
74563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return newRef;
75563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
76563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
77563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic wstring dumpPath(IDOMNode* node)
78563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
79563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    ASSERT(node);
80563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
81563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    wstring result;
82563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
83563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    BSTR name;
84563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (FAILED(node->nodeName(&name)))
85563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return result;
86563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    result.assign(name, SysStringLen(name));
87563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    SysFreeString(name);
88563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
89563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    COMPtr<IDOMNode> parent;
90563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (SUCCEEDED(node->parentNode(&parent)))
91563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        result += TEXT(" > ") + dumpPath(parent.get());
92563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
93563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return result;
94563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
95563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
96563af33bc48281d19dce701398dbb88cb54fd7ecCary Clarkstatic wstring dump(IDOMRange* range)
97563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
98563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    ASSERT(range);
99563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
100563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    int startOffset;
101563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (FAILED(range->startOffset(&startOffset)))
102563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return 0;
103563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
104563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    int endOffset;
105563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (FAILED(range->endOffset(&endOffset)))
106563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return 0;
107563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
108563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    COMPtr<IDOMNode> startContainer;
109563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (FAILED(range->startContainer(&startContainer)))
110563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return 0;
111563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
112563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    COMPtr<IDOMNode> endContainer;
113563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (FAILED(range->endContainer(&endContainer)))
114563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return 0;
115563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
116563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    wchar_t buffer[1024];
117563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    _snwprintf(buffer, ARRAYSIZE(buffer), L"range from %ld of %s to %ld of %s", startOffset, dumpPath(startContainer.get()), endOffset, dumpPath(endContainer.get()));
118563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return buffer;
119563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
120563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
121563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::shouldBeginEditingInDOMRange(
122563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView* webView,
123563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMRange* range,
124563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [retval][out] */ BOOL* result)
125563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
126563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!result) {
127563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        ASSERT_NOT_REACHED();
128563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_POINTER;
129563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
130563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
131563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
132563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: shouldBeginEditingInDOMRange:%s\n"), dump(range));
133563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
134563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *result = m_acceptsEditing;
135563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
136563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
137563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
138563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::shouldEndEditingInDOMRange(
139563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView* webView,
140563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMRange* range,
141563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [retval][out] */ BOOL* result)
142563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
143563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!result) {
144563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        ASSERT_NOT_REACHED();
145563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_POINTER;
146563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
147563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
148563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
149563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: shouldEndEditingInDOMRange:%s\n"), dump(range));
150563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
151563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *result = m_acceptsEditing;
152563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
153563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
154563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
155563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertNode(
156563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView* webView,
157563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMNode* node,
158563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMRange* range,
159563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ WebViewInsertAction action)
160563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
161563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    static LPCTSTR insertactionstring[] = {
162563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("WebViewInsertActionTyped"),
163563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("WebViewInsertActionPasted"),
164563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("WebViewInsertActionDropped"),
165563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    };
166563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
167563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
168563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: shouldInsertNode:%s replacingDOMRange:%s givenAction:%s\n"), dumpPath(node), dump(range), insertactionstring[action]);
169563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
170563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
171563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
172563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
173563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::shouldInsertText(
174563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView* webView,
175563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ BSTR text,
176563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMRange* range,
177563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ WebViewInsertAction action,
178563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [retval][out] */ BOOL* result)
179563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
180563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!result) {
181563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        ASSERT_NOT_REACHED();
182563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_POINTER;
183563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
184563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
185563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    static LPCTSTR insertactionstring[] = {
186563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("WebViewInsertActionTyped"),
187563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("WebViewInsertActionPasted"),
188563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("WebViewInsertActionDropped"),
189563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    };
190563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
191563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
192563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: shouldInsertText:%s replacingDOMRange:%s givenAction:%s\n"), text ? text : TEXT(""), dump(range), insertactionstring[action]);
193563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
194563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *result = m_acceptsEditing;
195563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
196563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
197563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
198563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::shouldDeleteDOMRange(
199563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView* webView,
200563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMRange* range,
201563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [retval][out] */ BOOL* result)
202563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
203563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!result) {
204563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        ASSERT_NOT_REACHED();
205563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_POINTER;
206563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
207563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
208563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
209563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: shouldDeleteDOMRange:%s\n"), dump(range));
210563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
211563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *result = m_acceptsEditing;
212563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
213563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
214563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
215563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeSelectedDOMRange(
216563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView* webView,
217563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMRange* currentRange,
218563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMRange* proposedRange,
219563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ WebSelectionAffinity selectionAffinity,
220563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ BOOL stillSelecting,
221563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [retval][out] */ BOOL* result)
222563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
223563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!result) {
224563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        ASSERT_NOT_REACHED();
225563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_POINTER;
226563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
227563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
228563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    static LPCTSTR affinitystring[] = {
229563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("NSSelectionAffinityUpstream"),
230563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("NSSelectionAffinityDownstream")
231563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    };
232563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    static LPCTSTR boolstring[] = {
233563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("FALSE"),
234563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        TEXT("TRUE")
235563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    };
236563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
237563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
238563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: shouldChangeSelectedDOMRange:%s toDOMRange:%s affinity:%s stillSelecting:%s\n"), dump(currentRange), dump(proposedRange), affinitystring[selectionAffinity], boolstring[stillSelecting]);
239563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
240563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *result = m_acceptsEditing;
241563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
242563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
243563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
244563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::shouldApplyStyle(
245563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView* webView,
246563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMCSSStyleDeclaration* style,
247563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMRange* range,
248563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [retval][out] */ BOOL* result)
249563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
250563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!result) {
251563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        ASSERT_NOT_REACHED();
252563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_POINTER;
253563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
254563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
255563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
256563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: shouldApplyStyle:%s toElementsInDOMRange:%s\n"), TEXT("'style description'")/*[[style description] UTF8String]*/, dump(range));
257563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
258563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *result = m_acceptsEditing;
259563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
260563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
261563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
262563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::shouldChangeTypingStyle(
263563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView* webView,
264563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMCSSStyleDeclaration* currentStyle,
265563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IDOMCSSStyleDeclaration* proposedStyle,
266563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [retval][out] */ BOOL* result)
267563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
268563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!result) {
269563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        ASSERT_NOT_REACHED();
270563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_POINTER;
271563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
272563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
273563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
274563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: shouldChangeTypingStyle:%s toStyle:%s\n"), TEXT("'currentStyle description'"), TEXT("'proposedStyle description'"));
275563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
276563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *result = m_acceptsEditing;
277563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
278563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
279563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
280563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::doPlatformCommand(
281563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebView *webView,
282563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ BSTR command,
283563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [retval][out] */ BOOL *result)
284563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
285563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (!result) {
286563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        ASSERT_NOT_REACHED();
287563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        return E_POINTER;
288563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
289563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
290563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done)
291563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: doPlatformCommand:%s\n"), command ? command : TEXT(""));
292563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
293563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    *result = m_acceptsEditing;
294563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
295563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
296563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
297563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidBeginEditing(
298563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebNotification* notification)
299563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
300563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
301563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        BSTR name;
302563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        notification->name(&name);
303563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
304563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        SysFreeString(name);
305563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
306563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
307563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
308563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
309563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChange(
310563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebNotification *notification)
311563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
312563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
313563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        BSTR name;
314563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        notification->name(&name);
315563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: webViewDidBeginEditing:%s\n"), name ? name : TEXT(""));
316563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        SysFreeString(name);
317563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
318563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
319563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
320563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
321563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidEndEditing(
322563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebNotification *notification)
323563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
324563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
325563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        BSTR name;
326563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        notification->name(&name);
327563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: webViewDidEndEditing:%s\n"), name ? name : TEXT(""));
328563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        SysFreeString(name);
329563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
330563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
331563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
332563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
333563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeTypingStyle(
334563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebNotification *notification)
335563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
336563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
337563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        BSTR name;
338563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        notification->name(&name);
339563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeTypingStyle:%s\n"), name ? name : TEXT(""));
340563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        SysFreeString(name);
341563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
342563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
343563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
344563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark
345563af33bc48281d19dce701398dbb88cb54fd7ecCary ClarkHRESULT STDMETHODCALLTYPE EditingDelegate::webViewDidChangeSelection(
346563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    /* [in] */ IWebNotification *notification)
347563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark{
348563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    if (::gLayoutTestController->dumpEditingCallbacks() && !done) {
349563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        BSTR name;
350563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        notification->name(&name);
351563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        _tprintf(TEXT("EDITING DELEGATE: webViewDidChangeSelection:%s\n"), name ? name : TEXT(""));
352563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark        SysFreeString(name);
353563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    }
354563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark    return S_OK;
355563af33bc48281d19dce701398dbb88cb54fd7ecCary Clark}
356e14391e94c850b8bd03680c23b38978db68687a8John Reck
357e14391e94c850b8bd03680c23b38978db68687a8John Reckstatic int indexOfFirstWordCharacter(const TCHAR* text)
358e14391e94c850b8bd03680c23b38978db68687a8John Reck{
359e14391e94c850b8bd03680c23b38978db68687a8John Reck    const TCHAR* cursor = text;
36081bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (*cursor && !iswalpha(*cursor))
361e14391e94c850b8bd03680c23b38978db68687a8John Reck        ++cursor;
362e14391e94c850b8bd03680c23b38978db68687a8John Reck    return *cursor ? (cursor - text) : -1;
363e14391e94c850b8bd03680c23b38978db68687a8John Reck};
364e14391e94c850b8bd03680c23b38978db68687a8John Reck
365e14391e94c850b8bd03680c23b38978db68687a8John Reckstatic int wordLength(const TCHAR* text)
366e14391e94c850b8bd03680c23b38978db68687a8John Reck{
367e14391e94c850b8bd03680c23b38978db68687a8John Reck    const TCHAR* cursor = text;
36881bc750723a18f21cd17d1b173cd2a4dda9cea6eBen Murdoch    while (*cursor && iswalpha(*cursor))
369e14391e94c850b8bd03680c23b38978db68687a8John Reck        ++cursor;
370e14391e94c850b8bd03680c23b38978db68687a8John Reck    return cursor - text;
371e14391e94c850b8bd03680c23b38978db68687a8John Reck};
372e14391e94c850b8bd03680c23b38978db68687a8John Reck
373e14391e94c850b8bd03680c23b38978db68687a8John ReckHRESULT STDMETHODCALLTYPE EditingDelegate::checkSpellingOfString(
374e14391e94c850b8bd03680c23b38978db68687a8John Reck            /* [in] */ IWebView* view,
375e14391e94c850b8bd03680c23b38978db68687a8John Reck            /* [in] */ LPCTSTR text,
376e14391e94c850b8bd03680c23b38978db68687a8John Reck            /* [in] */ int length,
377e14391e94c850b8bd03680c23b38978db68687a8John Reck            /* [out] */ int* misspellingLocation,
378e14391e94c850b8bd03680c23b38978db68687a8John Reck            /* [out] */ int* misspellingLength)
379e14391e94c850b8bd03680c23b38978db68687a8John Reck{
380e14391e94c850b8bd03680c23b38978db68687a8John Reck    static const TCHAR* misspelledWords[] = {
381e14391e94c850b8bd03680c23b38978db68687a8John Reck        // These words are known misspelled words in webkit tests.
382e14391e94c850b8bd03680c23b38978db68687a8John Reck        // If there are other misspelled words in webkit tests, please add them in
383e14391e94c850b8bd03680c23b38978db68687a8John Reck        // this array.
384e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("foo"),
385e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("Foo"),
386e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("baz"),
387e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("fo"),
388e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("LibertyF"),
389e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("chello"),
390e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("xxxtestxxx"),
391e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("XXxxx"),
392e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("Textx"),
393e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("blockquoted"),
394e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("asd"),
395e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("Lorem"),
396e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("Nunc"),
397e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("Curabitur"),
398e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("eu"),
399e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("adlj"),
400e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("adaasj"),
401e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("sdklj"),
402e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("jlkds"),
403e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("jsaada"),
404e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("jlda"),
405e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("zz"),
406e14391e94c850b8bd03680c23b38978db68687a8John Reck        TEXT("contentEditable"),
407e14391e94c850b8bd03680c23b38978db68687a8John Reck        0,
408e14391e94c850b8bd03680c23b38978db68687a8John Reck    };
409e14391e94c850b8bd03680c23b38978db68687a8John Reck
410e14391e94c850b8bd03680c23b38978db68687a8John Reck    wstring textString(text, length);
411e14391e94c850b8bd03680c23b38978db68687a8John Reck    int wordStart = indexOfFirstWordCharacter(textString.c_str());
412e14391e94c850b8bd03680c23b38978db68687a8John Reck    if (-1 == wordStart)
413e14391e94c850b8bd03680c23b38978db68687a8John Reck        return S_OK;
414e14391e94c850b8bd03680c23b38978db68687a8John Reck    wstring word = textString.substr(wordStart, wordLength(textString.c_str() + wordStart));
415e14391e94c850b8bd03680c23b38978db68687a8John Reck    for (size_t i = 0; misspelledWords[i]; ++i) {
416e14391e94c850b8bd03680c23b38978db68687a8John Reck        if (word == misspelledWords[i]) {
417e14391e94c850b8bd03680c23b38978db68687a8John Reck            *misspellingLocation = wordStart;
418e14391e94c850b8bd03680c23b38978db68687a8John Reck            *misspellingLength = word.size();
419e14391e94c850b8bd03680c23b38978db68687a8John Reck            break;
420e14391e94c850b8bd03680c23b38978db68687a8John Reck        }
421e14391e94c850b8bd03680c23b38978db68687a8John Reck    }
422e14391e94c850b8bd03680c23b38978db68687a8John Reck
423e14391e94c850b8bd03680c23b38978db68687a8John Reck    return S_OK;
424e14391e94c850b8bd03680c23b38978db68687a8John Reck}
425