2395fa3ab49a2d630b7976f968149f7966dfca50
[WebKit-https.git] / Source / WebKit2 / WebProcess / WebCoreSupport / WebEditorClient.cpp
1 /*
2  * Copyright (C) 2010 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  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WebEditorClient.h"
28
29 #include "SelectionState.h"
30 #include "WebCoreArgumentCoders.h"
31 #include "WebFrameLoaderClient.h"
32 #include "WebPage.h"
33 #include "WebPageProxyMessages.h"
34 #include "WebProcess.h"
35 #include <WebCore/ArchiveResource.h>
36 #include <WebCore/DocumentFragment.h>
37 #include <WebCore/EditCommand.h>
38 #include <WebCore/FocusController.h>
39 #include <WebCore/Frame.h>
40 #include <WebCore/HTMLInputElement.h>
41 #include <WebCore/HTMLNames.h>
42 #include <WebCore/HTMLTextAreaElement.h>
43 #include <WebCore/KeyboardEvent.h>
44 #include <WebCore/NotImplemented.h>
45 #include <WebCore/Page.h>
46 #include <WebCore/UserTypingGestureIndicator.h>
47
48 using namespace WebCore;
49 using namespace HTMLNames;
50
51 namespace WebKit {
52
53 void WebEditorClient::pageDestroyed()
54 {
55     delete this;
56 }
57
58 bool WebEditorClient::shouldDeleteRange(Range* range)
59 {
60     bool result = m_page->injectedBundleEditorClient().shouldDeleteRange(m_page, range);
61     notImplemented();
62     return result;
63 }
64
65 bool WebEditorClient::shouldShowDeleteInterface(HTMLElement*)
66 {
67     notImplemented();
68     return false;
69 }
70
71 bool WebEditorClient::smartInsertDeleteEnabled()
72 {
73     // FIXME: Why isn't this Mac specific like toggleSmartInsertDeleteEnabled?
74 #if PLATFORM(MAC)
75     return m_page->isSmartInsertDeleteEnabled();
76 #else
77     return true;
78 #endif
79 }
80  
81 bool WebEditorClient::isSelectTrailingWhitespaceEnabled()
82 {
83     notImplemented();
84     return false;
85 }
86
87 bool WebEditorClient::isContinuousSpellCheckingEnabled()
88 {
89     return WebProcess::shared().textCheckerState().isContinuousSpellCheckingEnabled;
90 }
91
92 void WebEditorClient::toggleContinuousSpellChecking()
93 {
94     notImplemented();
95 }
96
97 bool WebEditorClient::isGrammarCheckingEnabled()
98 {
99     return WebProcess::shared().textCheckerState().isGrammarCheckingEnabled;
100 }
101
102 void WebEditorClient::toggleGrammarChecking()
103 {
104     notImplemented();
105 }
106
107 int WebEditorClient::spellCheckerDocumentTag()
108 {
109     notImplemented();
110     return false;
111 }
112
113     
114 bool WebEditorClient::isEditable()
115 {
116     notImplemented();
117     return false;
118 }
119
120
121 bool WebEditorClient::shouldBeginEditing(Range* range)
122 {
123     bool result = m_page->injectedBundleEditorClient().shouldBeginEditing(m_page, range);
124     notImplemented();
125     return result;
126 }
127
128 bool WebEditorClient::shouldEndEditing(Range* range)
129 {
130     bool result = m_page->injectedBundleEditorClient().shouldEndEditing(m_page, range);
131     notImplemented();
132     return result;
133 }
134
135 bool WebEditorClient::shouldInsertNode(Node* node, Range* rangeToReplace, EditorInsertAction action)
136 {
137     bool result = m_page->injectedBundleEditorClient().shouldInsertNode(m_page, node, rangeToReplace, action);
138     notImplemented();
139     return result;
140 }
141
142 bool WebEditorClient::shouldInsertText(const String& text, Range* rangeToReplace, EditorInsertAction action)
143 {
144     bool result = m_page->injectedBundleEditorClient().shouldInsertText(m_page, text.impl(), rangeToReplace, action);
145     notImplemented();
146     return result;
147 }
148
149 bool WebEditorClient::shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity affinity, bool stillSelecting)
150 {
151     bool result = m_page->injectedBundleEditorClient().shouldChangeSelectedRange(m_page, fromRange, toRange, affinity, stillSelecting);
152     notImplemented();
153     return result;
154 }
155     
156 bool WebEditorClient::shouldApplyStyle(CSSStyleDeclaration* style, Range* range)
157 {
158     bool result = m_page->injectedBundleEditorClient().shouldApplyStyle(m_page, style, range);
159     notImplemented();
160     return result;
161 }
162
163 bool WebEditorClient::shouldMoveRangeAfterDelete(Range*, Range*)
164 {
165     notImplemented();
166     return true;
167 }
168
169 void WebEditorClient::didBeginEditing()
170 {
171     // FIXME: What good is a notification name, if it's always the same?
172     static const String WebViewDidBeginEditingNotification = "WebViewDidBeginEditingNotification";
173     m_page->injectedBundleEditorClient().didBeginEditing(m_page, WebViewDidBeginEditingNotification.impl());
174     notImplemented();
175 }
176
177 void WebEditorClient::respondToChangedContents()
178 {
179     static const String WebViewDidChangeNotification = "WebViewDidChangeNotification";
180     m_page->injectedBundleEditorClient().didChange(m_page, WebViewDidChangeNotification.impl());
181     notImplemented();
182 }
183
184 void WebEditorClient::respondToChangedSelection()
185 {
186     static const String WebViewDidChangeSelectionNotification = "WebViewDidChangeSelectionNotification";
187     m_page->injectedBundleEditorClient().didChangeSelection(m_page, WebViewDidChangeSelectionNotification.impl());
188     Frame* frame = m_page->corePage()->focusController()->focusedFrame();
189     if (!frame)
190         return;
191
192     SelectionState selectionState;
193     selectionState.isNone = frame->selection()->isNone();
194     selectionState.isContentEditable = frame->selection()->isContentEditable();
195     selectionState.isContentRichlyEditable = frame->selection()->isContentRichlyEditable();
196     selectionState.isInPasswordField = frame->selection()->isInPasswordField();
197     selectionState.hasComposition = frame->editor()->hasComposition();
198
199     WebPage::getLocationAndLengthFromRange(frame->selection()->toNormalizedRange().get(), selectionState.selectedRangeStart, selectionState.selectedRangeLength);
200
201     m_page->send(Messages::WebPageProxy::SelectionStateChanged(selectionState));
202
203 #if PLATFORM(WIN)
204     // FIXME: This should also go into the selection state.
205     if (!frame->editor()->hasComposition() || frame->editor()->ignoreCompositionSelectionChange())
206         return;
207
208     unsigned start;
209     unsigned end;
210     m_page->send(Messages::WebPageProxy::DidChangeCompositionSelection(frame->editor()->getCompositionSelection(start, end)));
211 #endif
212 }
213     
214 void WebEditorClient::didEndEditing()
215 {
216     static const String WebViewDidEndEditingNotification = "WebViewDidEndEditingNotification";
217     m_page->injectedBundleEditorClient().didEndEditing(m_page, WebViewDidEndEditingNotification.impl());
218     notImplemented();
219 }
220
221 void WebEditorClient::didWriteSelectionToPasteboard()
222 {
223     notImplemented();
224 }
225
226 void WebEditorClient::didSetSelectionTypesForPasteboard()
227 {
228     notImplemented();
229 }
230
231 void WebEditorClient::registerCommandForUndo(PassRefPtr<EditCommand> command)
232 {
233     // FIXME: Add assertion that the command being reapplied is the same command that is
234     // being passed to us.
235     if (m_page->isInRedo())
236         return;
237
238     RefPtr<WebEditCommand> webCommand = WebEditCommand::create(command);
239     m_page->addWebEditCommand(webCommand->commandID(), webCommand.get());
240     uint32_t editAction = static_cast<uint32_t>(webCommand->command()->editingAction());
241
242     m_page->send(Messages::WebPageProxy::RegisterEditCommandForUndo(webCommand->commandID(), editAction));
243 }
244
245 void WebEditorClient::registerCommandForRedo(PassRefPtr<EditCommand>)
246 {
247 }
248
249 void WebEditorClient::clearUndoRedoOperations()
250 {
251     m_page->send(Messages::WebPageProxy::ClearAllEditCommands());
252 }
253
254 bool WebEditorClient::canCopyCut(bool defaultValue) const
255 {
256     return defaultValue;
257 }
258
259 bool WebEditorClient::canPaste(bool defaultValue) const
260 {
261     return defaultValue;
262 }
263
264 bool WebEditorClient::canUndo() const
265 {
266     notImplemented();
267     return false;
268 }
269
270 bool WebEditorClient::canRedo() const
271 {
272     notImplemented();
273     return false;
274 }
275
276 void WebEditorClient::undo()
277 {
278     notImplemented();
279 }
280
281 void WebEditorClient::redo()
282 {
283     notImplemented();
284 }
285
286 #if !PLATFORM(MAC)
287 void WebEditorClient::handleKeyboardEvent(KeyboardEvent* event)
288 {
289     if (m_page->handleEditingKeyboardEvent(event))
290         event->setDefaultHandled();
291 }
292
293 void WebEditorClient::handleInputMethodKeydown(KeyboardEvent*)
294 {
295     notImplemented();
296 }
297 #endif
298
299 void WebEditorClient::textFieldDidBeginEditing(Element* element)
300 {
301     if (!element->hasTagName(inputTag))
302         return;
303
304     WebFrame* webFrame =  static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame();
305     m_page->injectedBundleFormClient().textFieldDidBeginEditing(m_page, static_cast<HTMLInputElement*>(element), webFrame);
306 }
307
308 void WebEditorClient::textFieldDidEndEditing(Element* element)
309 {
310     if (!element->hasTagName(inputTag))
311         return;
312
313     WebFrame* webFrame =  static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame();
314     m_page->injectedBundleFormClient().textFieldDidEndEditing(m_page, static_cast<HTMLInputElement*>(element), webFrame);
315 }
316
317 void WebEditorClient::textDidChangeInTextField(Element* element)
318 {
319     if (!element->hasTagName(inputTag))
320         return;
321
322     if (!UserTypingGestureIndicator::processingUserTypingGesture() || UserTypingGestureIndicator::focusedElementAtGestureStart() != element)
323         return;
324
325     WebFrame* webFrame =  static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame();
326     m_page->injectedBundleFormClient().textDidChangeInTextField(m_page, static_cast<HTMLInputElement*>(element), webFrame);
327 }
328
329 void WebEditorClient::textDidChangeInTextArea(Element* element)
330 {
331     if (!element->hasTagName(textareaTag))
332         return;
333
334     WebFrame* webFrame =  static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame();
335     m_page->injectedBundleFormClient().textDidChangeInTextArea(m_page, static_cast<HTMLTextAreaElement*>(element), webFrame);
336 }
337
338 static bool getActionTypeForKeyEvent(KeyboardEvent* event, WKInputFieldActionType& type)
339 {
340     String key = event->keyIdentifier();
341     if (key == "Up")
342         type = WKInputFieldActionTypeMoveUp;
343     else if (key == "Down")
344         type = WKInputFieldActionTypeMoveDown;
345     else if (key == "U+001B")
346         type = WKInputFieldActionTypeCancel;
347     else if (key == "U+0009") {
348         if (event->shiftKey())
349             type = WKInputFieldActionTypeInsertBacktab;
350         else
351             type = WKInputFieldActionTypeInsertTab;
352     } else if (key == "Enter")
353         type = WKInputFieldActionTypeInsertNewline;
354     else
355         return false;
356
357     return true;
358 }
359
360 bool WebEditorClient::doTextFieldCommandFromEvent(Element* element, KeyboardEvent* event)
361 {
362     if (!element->hasTagName(inputTag))
363         return false;
364
365     WKInputFieldActionType actionType = static_cast<WKInputFieldActionType>(0);
366     if (!getActionTypeForKeyEvent(event, actionType))
367         return false;
368
369     WebFrame* webFrame =  static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame();
370     return m_page->injectedBundleFormClient().shouldPerformActionInTextField(m_page, static_cast<HTMLInputElement*>(element), actionType, webFrame);
371 }
372
373 void WebEditorClient::textWillBeDeletedInTextField(Element* element)
374 {
375     if (!element->hasTagName(inputTag))
376         return;
377
378     WebFrame* webFrame =  static_cast<WebFrameLoaderClient*>(element->document()->frame()->loader()->client())->webFrame();
379     m_page->injectedBundleFormClient().shouldPerformActionInTextField(m_page, static_cast<HTMLInputElement*>(element), WKInputFieldActionTypeInsertDelete, webFrame);
380 }
381
382 void WebEditorClient::ignoreWordInSpellDocument(const String& word)
383 {
384     m_page->send(Messages::WebPageProxy::IgnoreWord(word));
385 }
386
387 void WebEditorClient::learnWord(const String& word)
388 {
389     m_page->send(Messages::WebPageProxy::LearnWord(word));
390 }
391
392 void WebEditorClient::checkSpellingOfString(const UChar*, int, int*, int*)
393 {
394     notImplemented();
395 }
396
397 String WebEditorClient::getAutoCorrectSuggestionForMisspelledWord(const String&)
398 {
399     notImplemented();
400     return String();
401 }
402
403 void WebEditorClient::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
404 {
405     notImplemented();
406 }
407
408 void WebEditorClient::updateSpellingUIWithGrammarString(const String& badGrammarPhrase, const GrammarDetail& grammarDetail)
409 {
410     m_page->send(Messages::WebPageProxy::UpdateSpellingUIWithGrammarString(badGrammarPhrase, grammarDetail));
411 }
412
413 void WebEditorClient::updateSpellingUIWithMisspelledWord(const String& misspelledWord)
414 {
415     m_page->send(Messages::WebPageProxy::UpdateSpellingUIWithMisspelledWord(misspelledWord));
416 }
417
418 void WebEditorClient::showSpellingUI(bool)
419 {
420     notImplemented();
421 }
422
423 bool WebEditorClient::spellingUIIsShowing()
424 {
425     notImplemented();
426     return false;
427 }
428
429 void WebEditorClient::getGuessesForWord(const String& word, const String& context, Vector<String>& guesses)
430 {
431     m_page->sendSync(Messages::WebPageProxy::GetGuessesForWord(word, context), Messages::WebPageProxy::GetGuessesForWord::Reply(guesses));
432 }
433
434 void WebEditorClient::willSetInputMethodState()
435 {
436     notImplemented();
437 }
438
439 void WebEditorClient::setInputMethodState(bool)
440 {
441     notImplemented();
442 }
443
444 void WebEditorClient::requestCheckingOfString(WebCore::SpellChecker*, int, const WTF::String&)
445 {
446     notImplemented();
447 }
448
449 } // namespace WebKit