initial import
[vuplus_webkit] / Source / WebKit / wince / WebCoreSupport / EditorClientWinCE.cpp
1 /*
2  *  Copyright (C) 2007 Alp Toker <alp@atoker.com>
3  *  Copyright (C) 2008 Nuanti Ltd.
4  *  Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia
5  *  Copyright (C) 2009-2010 ProFUSION embedded systems
6  *  Copyright (C) 2009-2010 Samsung Electronics
7  *  Copyright (C) 2010 Patrick Gansterer <paroga@paroga.com>
8  *
9  *  This library is free software; you can redistribute it and/or
10  *  modify it under the terms of the GNU Lesser General Public
11  *  License as published by the Free Software Foundation; either
12  *  version 2 of the License, or (at your option) any later version.
13  *
14  *  This library is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17  *  Lesser General Public License for more details.
18  *
19  *  You should have received a copy of the GNU Lesser General Public
20  *  License along with this library; if not, write to the Free Software
21  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
22  */
23
24 #include "config.h"
25 #include "EditorClientWinCE.h"
26
27 #include "EditCommand.h"
28 #include "Frame.h"
29 #include "KeyboardEvent.h"
30 #include "NotImplemented.h"
31 #include "PlatformKeyboardEvent.h"
32 #include "Settings.h"
33
34 using namespace WebCore;
35
36 namespace WebKit {
37
38 EditorClientWinCE::EditorClientWinCE(WebView* webView)
39     : m_webView(webView)
40 {
41 }
42
43 EditorClientWinCE::~EditorClientWinCE()
44 {
45 }
46
47 void EditorClientWinCE::setInputMethodState(bool active)
48 {
49     notImplemented();
50 }
51
52 bool EditorClientWinCE::shouldDeleteRange(Range*)
53 {
54     notImplemented();
55     return true;
56 }
57
58 bool EditorClientWinCE::shouldShowDeleteInterface(HTMLElement*)
59 {
60     return false;
61 }
62
63 bool EditorClientWinCE::isContinuousSpellCheckingEnabled()
64 {
65     notImplemented();
66     return false;
67 }
68
69 bool EditorClientWinCE::isGrammarCheckingEnabled()
70 {
71     notImplemented();
72     return false;
73 }
74
75 int EditorClientWinCE::spellCheckerDocumentTag()
76 {
77     notImplemented();
78     return 0;
79 }
80
81 bool EditorClientWinCE::shouldBeginEditing(WebCore::Range*)
82 {
83     notImplemented();
84     return true;
85 }
86
87 bool EditorClientWinCE::shouldEndEditing(WebCore::Range*)
88 {
89     notImplemented();
90     return true;
91 }
92
93 bool EditorClientWinCE::shouldInsertText(const String&, Range*, EditorInsertAction)
94 {
95     notImplemented();
96     return true;
97 }
98
99 bool EditorClientWinCE::shouldChangeSelectedRange(Range*, Range*, EAffinity, bool)
100 {
101     notImplemented();
102     return true;
103 }
104
105 bool EditorClientWinCE::shouldApplyStyle(WebCore::CSSStyleDeclaration*, WebCore::Range*)
106 {
107     notImplemented();
108     return true;
109 }
110
111 bool EditorClientWinCE::shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*)
112 {
113     notImplemented();
114     return true;
115 }
116
117 void EditorClientWinCE::didBeginEditing()
118 {
119     notImplemented();
120 }
121
122 void EditorClientWinCE::respondToChangedContents()
123 {
124     notImplemented();
125 }
126
127 void EditorClientWinCE::respondToChangedSelection()
128 {
129     notImplemented();
130 }
131
132 void EditorClientWinCE::didEndEditing()
133 {
134     notImplemented();
135 }
136
137 void EditorClientWinCE::didWriteSelectionToPasteboard()
138 {
139     notImplemented();
140 }
141
142 void EditorClientWinCE::didSetSelectionTypesForPasteboard()
143 {
144     notImplemented();
145 }
146
147 void EditorClientWinCE::registerCommandForUndo(WTF::PassRefPtr<WebCore::EditCommand> command)
148 {
149     notImplemented();
150 }
151
152 void EditorClientWinCE::registerCommandForRedo(WTF::PassRefPtr<WebCore::EditCommand> command)
153 {
154     notImplemented();
155 }
156
157 void EditorClientWinCE::clearUndoRedoOperations()
158 {
159     notImplemented();
160 }
161
162 bool EditorClientWinCE::canCopyCut(WebCore::Frame*, bool defaultValue) const
163 {
164     return defaultValue;
165 }
166
167 bool EditorClientWinCE::canPaste(WebCore::Frame*, bool defaultValue) const
168 {
169     return defaultValue;
170 }
171
172 bool EditorClientWinCE::canUndo() const
173 {
174     notImplemented();
175     return false;
176 }
177
178 bool EditorClientWinCE::canRedo() const
179 {
180     notImplemented();
181     return false;
182 }
183
184 void EditorClientWinCE::undo()
185 {
186     notImplemented();
187 }
188
189 void EditorClientWinCE::redo()
190 {
191     notImplemented();
192 }
193
194 bool EditorClientWinCE::shouldInsertNode(Node*, Range*, EditorInsertAction)
195 {
196     notImplemented();
197     return true;
198 }
199
200 void EditorClientWinCE::pageDestroyed()
201 {
202     delete this;
203 }
204
205 bool EditorClientWinCE::smartInsertDeleteEnabled()
206 {
207     notImplemented();
208     return false;
209 }
210
211 bool EditorClientWinCE::isSelectTrailingWhitespaceEnabled()
212 {
213     notImplemented();
214     return false;
215 }
216
217 void EditorClientWinCE::toggleContinuousSpellChecking()
218 {
219     notImplemented();
220 }
221
222 void EditorClientWinCE::toggleGrammarChecking()
223 {
224     notImplemented();
225 }
226
227 static const unsigned CtrlKey = 1 << 0;
228 static const unsigned AltKey = 1 << 1;
229 static const unsigned ShiftKey = 1 << 2;
230
231 struct KeyDownEntry {
232     unsigned virtualKey;
233     unsigned modifiers;
234     const char* name;
235 };
236
237 struct KeyPressEntry {
238     unsigned charCode;
239     unsigned modifiers;
240     const char* name;
241 };
242
243 static const KeyDownEntry keyDownEntries[] = {
244     { VK_LEFT,   0,                  "MoveLeft"                                    },
245     { VK_LEFT,   ShiftKey,           "MoveLeftAndModifySelection"                  },
246     { VK_LEFT,   CtrlKey,            "MoveWordLeft"                                },
247     { VK_LEFT,   CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection"              },
248     { VK_RIGHT,  0,                  "MoveRight"                                   },
249     { VK_RIGHT,  ShiftKey,           "MoveRightAndModifySelection"                 },
250     { VK_RIGHT,  CtrlKey,            "MoveWordRight"                               },
251     { VK_RIGHT,  CtrlKey | ShiftKey, "MoveWordRightAndModifySelection"             },
252     { VK_UP,     0,                  "MoveUp"                                      },
253     { VK_UP,     ShiftKey,           "MoveUpAndModifySelection"                    },
254     { VK_PRIOR,  ShiftKey,           "MovePageUpAndModifySelection"                },
255     { VK_DOWN,   0,                  "MoveDown"                                    },
256     { VK_DOWN,   ShiftKey,           "MoveDownAndModifySelection"                  },
257     { VK_NEXT,   ShiftKey,           "MovePageDownAndModifySelection"              },
258     { VK_PRIOR,  0,                  "MovePageUp"                                  },
259     { VK_NEXT,   0,                  "MovePageDown"                                },
260     { VK_HOME,   0,                  "MoveToBeginningOfLine"                       },
261     { VK_HOME,   ShiftKey,           "MoveToBeginningOfLineAndModifySelection"     },
262     { VK_HOME,   CtrlKey,            "MoveToBeginningOfDocument"                   },
263     { VK_HOME,   CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" },
264
265     { VK_END,    0,                  "MoveToEndOfLine"                             },
266     { VK_END,    ShiftKey,           "MoveToEndOfLineAndModifySelection"           },
267     { VK_END,    CtrlKey,            "MoveToEndOfDocument"                         },
268     { VK_END,    CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection"       },
269
270     { VK_BACK,   0,                  "DeleteBackward"                              },
271     { VK_BACK,   ShiftKey,           "DeleteBackward"                              },
272     { VK_DELETE, 0,                  "DeleteForward"                               },
273     { VK_BACK,   CtrlKey,            "DeleteWordBackward"                          },
274     { VK_DELETE, CtrlKey,            "DeleteWordForward"                           },
275
276     { 'B',       CtrlKey,            "ToggleBold"                                  },
277     { 'I',       CtrlKey,            "ToggleItalic"                                },
278
279     { VK_ESCAPE, 0,                  "Cancel"                                      },
280     { VK_TAB,    0,                  "InsertTab"                                   },
281     { VK_TAB,    ShiftKey,           "InsertBacktab"                               },
282     { VK_RETURN, 0,                  "InsertNewline"                               },
283     { VK_RETURN, CtrlKey,            "InsertNewline"                               },
284     { VK_RETURN, AltKey,             "InsertNewline"                               },
285     { VK_RETURN, AltKey | ShiftKey,  "InsertNewline"                               },
286
287     // It's not quite clear whether clipboard shortcuts and Undo/Redo should be handled
288     // in the application or in WebKit. We chose WebKit for now.
289     { 'C',       CtrlKey,            "Copy"                                        },
290     { 'V',       CtrlKey,            "Paste"                                       },
291     { 'X',       CtrlKey,            "Cut"                                         },
292     { 'A',       CtrlKey,            "SelectAll"                                   },
293     { VK_INSERT, CtrlKey,            "Copy"                                        },
294     { VK_DELETE, ShiftKey,           "Cut"                                         },
295     { VK_INSERT, ShiftKey,           "Paste"                                       },
296     { 'Z',       CtrlKey,            "Undo"                                        },
297     { 'Z',       CtrlKey | ShiftKey, "Redo"                                        }
298 };
299
300 static const KeyPressEntry keyPressEntries[] = {
301     { '\t',   0,                  "InsertTab"                                   },
302     { '\t',   ShiftKey,           "InsertBacktab"                               },
303     { '\r',   0,                  "InsertNewline"                               },
304     { '\r',   CtrlKey,            "InsertNewline"                               },
305     { '\r',   AltKey,             "InsertNewline"                               },
306     { '\r',   AltKey | ShiftKey,  "InsertNewline"                               }
307 };
308
309 const char* EditorClientWinCE::interpretKeyEvent(const KeyboardEvent* event)
310 {
311     ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
312
313     static HashMap<int, const char*>* keyDownCommandsMap = 0;
314     static HashMap<int, const char*>* keyPressCommandsMap = 0;
315
316     if (!keyDownCommandsMap) {
317         keyDownCommandsMap = new HashMap<int, const char*>;
318         keyPressCommandsMap = new HashMap<int, const char*>;
319
320         for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyDownEntries); ++i)
321             keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
322
323         for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyPressEntries); ++i)
324             keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
325     }
326
327     unsigned modifiers = 0;
328     if (event->shiftKey())
329         modifiers |= ShiftKey;
330     if (event->altKey())
331         modifiers |= AltKey;
332     if (event->ctrlKey())
333         modifiers |= CtrlKey;
334
335     if (event->type() == eventNames().keydownEvent) {
336         int mapKey = modifiers << 16 | event->keyCode();
337         return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
338     }
339
340     int mapKey = modifiers << 16 | event->charCode();
341     return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
342 }
343
344 bool EditorClientWinCE::handleEditingKeyboardEvent(KeyboardEvent* event)
345 {
346     Node* node = event->target()->toNode();
347     ASSERT(node);
348     Frame* frame = node->document()->frame();
349     ASSERT(frame);
350
351     const PlatformKeyboardEvent* keyEvent = event->keyEvent();
352     if (!keyEvent)
353         return false;
354
355     bool caretBrowsing = frame->settings()->caretBrowsingEnabled();
356     if (caretBrowsing) {
357         switch (keyEvent->windowsVirtualKeyCode()) {
358         case VK_LEFT:
359             frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
360                     DirectionLeft,
361                     keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity,
362                     UserTriggered);
363             return true;
364         case VK_RIGHT:
365             frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
366                     DirectionRight,
367                     keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity,
368                     UserTriggered);
369             return true;
370         case VK_UP:
371             frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
372                     DirectionBackward,
373                     keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity,
374                     UserTriggered);
375             return true;
376         case VK_DOWN:
377             frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
378                     DirectionForward,
379                     keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity,
380                     UserTriggered);
381             return true;
382         }
383     }
384
385     Editor::Command command = frame->editor()->command(interpretKeyEvent(event));
386
387     if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
388         // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
389         // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or let a keypress event be generated
390         // (e.g. Tab that inserts a Tab character, or Enter).
391         return !command.isTextInsertion() && command.execute(event);
392     }
393
394     if (command.execute(event))
395         return true;
396
397     // Don't insert null or control characters as they can result in unexpected behaviour
398     if (event->charCode() < ' ')
399         return false;
400
401     // Don't insert anything if a modifier is pressed
402     if (keyEvent->ctrlKey() || keyEvent->altKey())
403         return false;
404
405     return frame->editor()->insertText(event->keyEvent()->text(), event);
406 }
407
408 void EditorClientWinCE::handleKeyboardEvent(KeyboardEvent* event)
409 {
410     if (handleEditingKeyboardEvent(event))
411         event->setDefaultHandled();
412 }
413
414 void EditorClientWinCE::handleInputMethodKeydown(KeyboardEvent* event)
415 {
416     notImplemented();
417 }
418
419 void EditorClientWinCE::textFieldDidBeginEditing(Element*)
420 {
421 }
422
423 void EditorClientWinCE::textFieldDidEndEditing(Element*)
424 {
425 }
426
427 void EditorClientWinCE::textDidChangeInTextField(Element*)
428 {
429 }
430
431 bool EditorClientWinCE::doTextFieldCommandFromEvent(Element*, KeyboardEvent*)
432 {
433     return false;
434 }
435
436 void EditorClientWinCE::textWillBeDeletedInTextField(Element*)
437 {
438     notImplemented();
439 }
440
441 void EditorClientWinCE::textDidChangeInTextArea(Element*)
442 {
443     notImplemented();
444 }
445
446 void EditorClientWinCE::ignoreWordInSpellDocument(const String& text)
447 {
448     notImplemented();
449 }
450
451 void EditorClientWinCE::learnWord(const String& text)
452 {
453     notImplemented();
454 }
455
456 void EditorClientWinCE::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
457 {
458     notImplemented();
459 }
460
461 String EditorClientWinCE::getAutoCorrectSuggestionForMisspelledWord(const String& inputWord)
462 {
463     // This method can be implemented using customized algorithms for the particular browser.
464     // Currently, it computes an empty string.
465     return String();
466 }
467
468 void EditorClientWinCE::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
469 {
470     notImplemented();
471 }
472
473 void EditorClientWinCE::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&)
474 {
475     notImplemented();
476 }
477
478 void EditorClientWinCE::updateSpellingUIWithMisspelledWord(const String&)
479 {
480     notImplemented();
481 }
482
483 void EditorClientWinCE::showSpellingUI(bool)
484 {
485     notImplemented();
486 }
487
488 bool EditorClientWinCE::spellingUIIsShowing()
489 {
490     notImplemented();
491     return false;
492 }
493
494 void EditorClientWinCE::getGuessesForWord(const String& word, const String& context, WTF::Vector<String>& guesses)
495 {
496     notImplemented();
497 }
498
499 void EditorClientWinCE::willSetInputMethodState()
500 {
501     notImplemented();
502 }
503
504 } // namespace WebKit