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>
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.
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.
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
25 #include "EditorClientWinCE.h"
27 #include "EditCommand.h"
29 #include "KeyboardEvent.h"
30 #include "NotImplemented.h"
31 #include "PlatformKeyboardEvent.h"
34 using namespace WebCore;
38 EditorClientWinCE::EditorClientWinCE(WebView* webView)
43 EditorClientWinCE::~EditorClientWinCE()
47 void EditorClientWinCE::setInputMethodState(bool active)
52 bool EditorClientWinCE::shouldDeleteRange(Range*)
58 bool EditorClientWinCE::shouldShowDeleteInterface(HTMLElement*)
63 bool EditorClientWinCE::isContinuousSpellCheckingEnabled()
69 bool EditorClientWinCE::isGrammarCheckingEnabled()
75 int EditorClientWinCE::spellCheckerDocumentTag()
81 bool EditorClientWinCE::shouldBeginEditing(WebCore::Range*)
87 bool EditorClientWinCE::shouldEndEditing(WebCore::Range*)
93 bool EditorClientWinCE::shouldInsertText(const String&, Range*, EditorInsertAction)
99 bool EditorClientWinCE::shouldChangeSelectedRange(Range*, Range*, EAffinity, bool)
105 bool EditorClientWinCE::shouldApplyStyle(WebCore::CSSStyleDeclaration*, WebCore::Range*)
111 bool EditorClientWinCE::shouldMoveRangeAfterDelete(WebCore::Range*, WebCore::Range*)
117 void EditorClientWinCE::didBeginEditing()
122 void EditorClientWinCE::respondToChangedContents()
127 void EditorClientWinCE::respondToChangedSelection()
132 void EditorClientWinCE::didEndEditing()
137 void EditorClientWinCE::didWriteSelectionToPasteboard()
142 void EditorClientWinCE::didSetSelectionTypesForPasteboard()
147 void EditorClientWinCE::registerCommandForUndo(WTF::PassRefPtr<WebCore::EditCommand> command)
152 void EditorClientWinCE::registerCommandForRedo(WTF::PassRefPtr<WebCore::EditCommand> command)
157 void EditorClientWinCE::clearUndoRedoOperations()
162 bool EditorClientWinCE::canCopyCut(WebCore::Frame*, bool defaultValue) const
167 bool EditorClientWinCE::canPaste(WebCore::Frame*, bool defaultValue) const
172 bool EditorClientWinCE::canUndo() const
178 bool EditorClientWinCE::canRedo() const
184 void EditorClientWinCE::undo()
189 void EditorClientWinCE::redo()
194 bool EditorClientWinCE::shouldInsertNode(Node*, Range*, EditorInsertAction)
200 void EditorClientWinCE::pageDestroyed()
205 bool EditorClientWinCE::smartInsertDeleteEnabled()
211 bool EditorClientWinCE::isSelectTrailingWhitespaceEnabled()
217 void EditorClientWinCE::toggleContinuousSpellChecking()
222 void EditorClientWinCE::toggleGrammarChecking()
227 static const unsigned CtrlKey = 1 << 0;
228 static const unsigned AltKey = 1 << 1;
229 static const unsigned ShiftKey = 1 << 2;
231 struct KeyDownEntry {
237 struct KeyPressEntry {
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" },
265 { VK_END, 0, "MoveToEndOfLine" },
266 { VK_END, ShiftKey, "MoveToEndOfLineAndModifySelection" },
267 { VK_END, CtrlKey, "MoveToEndOfDocument" },
268 { VK_END, CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection" },
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" },
276 { 'B', CtrlKey, "ToggleBold" },
277 { 'I', CtrlKey, "ToggleItalic" },
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" },
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" }
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" }
309 const char* EditorClientWinCE::interpretKeyEvent(const KeyboardEvent* event)
311 ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
313 static HashMap<int, const char*>* keyDownCommandsMap = 0;
314 static HashMap<int, const char*>* keyPressCommandsMap = 0;
316 if (!keyDownCommandsMap) {
317 keyDownCommandsMap = new HashMap<int, const char*>;
318 keyPressCommandsMap = new HashMap<int, const char*>;
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);
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);
327 unsigned modifiers = 0;
328 if (event->shiftKey())
329 modifiers |= ShiftKey;
332 if (event->ctrlKey())
333 modifiers |= CtrlKey;
335 if (event->type() == eventNames().keydownEvent) {
336 int mapKey = modifiers << 16 | event->keyCode();
337 return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
340 int mapKey = modifiers << 16 | event->charCode();
341 return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
344 bool EditorClientWinCE::handleEditingKeyboardEvent(KeyboardEvent* event)
346 Node* node = event->target()->toNode();
348 Frame* frame = node->document()->frame();
351 const PlatformKeyboardEvent* keyEvent = event->keyEvent();
355 bool caretBrowsing = frame->settings()->caretBrowsingEnabled();
357 switch (keyEvent->windowsVirtualKeyCode()) {
359 frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
361 keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity,
365 frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
367 keyEvent->ctrlKey() ? WordGranularity : CharacterGranularity,
371 frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
373 keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity,
377 frame->selection()->modify(keyEvent->shiftKey() ? FrameSelection::AlterationExtend : FrameSelection::AlterationMove,
379 keyEvent->ctrlKey() ? ParagraphGranularity : LineGranularity,
385 Editor::Command command = frame->editor()->command(interpretKeyEvent(event));
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);
394 if (command.execute(event))
397 // Don't insert null or control characters as they can result in unexpected behaviour
398 if (event->charCode() < ' ')
401 // Don't insert anything if a modifier is pressed
402 if (keyEvent->ctrlKey() || keyEvent->altKey())
405 return frame->editor()->insertText(event->keyEvent()->text(), event);
408 void EditorClientWinCE::handleKeyboardEvent(KeyboardEvent* event)
410 if (handleEditingKeyboardEvent(event))
411 event->setDefaultHandled();
414 void EditorClientWinCE::handleInputMethodKeydown(KeyboardEvent* event)
419 void EditorClientWinCE::textFieldDidBeginEditing(Element*)
423 void EditorClientWinCE::textFieldDidEndEditing(Element*)
427 void EditorClientWinCE::textDidChangeInTextField(Element*)
431 bool EditorClientWinCE::doTextFieldCommandFromEvent(Element*, KeyboardEvent*)
436 void EditorClientWinCE::textWillBeDeletedInTextField(Element*)
441 void EditorClientWinCE::textDidChangeInTextArea(Element*)
446 void EditorClientWinCE::ignoreWordInSpellDocument(const String& text)
451 void EditorClientWinCE::learnWord(const String& text)
456 void EditorClientWinCE::checkSpellingOfString(const UChar* text, int length, int* misspellingLocation, int* misspellingLength)
461 String EditorClientWinCE::getAutoCorrectSuggestionForMisspelledWord(const String& inputWord)
463 // This method can be implemented using customized algorithms for the particular browser.
464 // Currently, it computes an empty string.
468 void EditorClientWinCE::checkGrammarOfString(const UChar*, int, Vector<GrammarDetail>&, int*, int*)
473 void EditorClientWinCE::updateSpellingUIWithGrammarString(const String&, const GrammarDetail&)
478 void EditorClientWinCE::updateSpellingUIWithMisspelledWord(const String&)
483 void EditorClientWinCE::showSpellingUI(bool)
488 bool EditorClientWinCE::spellingUIIsShowing()
494 void EditorClientWinCE::getGuessesForWord(const String& word, const String& context, WTF::Vector<String>& guesses)
499 void EditorClientWinCE::willSetInputMethodState()
504 } // namespace WebKit