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