summaryrefslogtreecommitdiffstats
path: root/WebKit/wx/WebKitSupport/EditorClientWx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebKit/wx/WebKitSupport/EditorClientWx.cpp')
-rw-r--r--WebKit/wx/WebKitSupport/EditorClientWx.cpp208
1 files changed, 151 insertions, 57 deletions
diff --git a/WebKit/wx/WebKitSupport/EditorClientWx.cpp b/WebKit/wx/WebKitSupport/EditorClientWx.cpp
index 6c443ed..3808bfe 100644
--- a/WebKit/wx/WebKitSupport/EditorClientWx.cpp
+++ b/WebKit/wx/WebKitSupport/EditorClientWx.cpp
@@ -49,6 +49,81 @@
namespace WebCore {
+static const unsigned CtrlKey = 1 << 0;
+static const unsigned AltKey = 1 << 1;
+static const unsigned ShiftKey = 1 << 2;
+
+struct KeyDownEntry {
+ unsigned virtualKey;
+ unsigned modifiers;
+ const char* name;
+};
+
+struct KeyPressEntry {
+ unsigned charCode;
+ unsigned modifiers;
+ const char* name;
+};
+
+static const KeyDownEntry keyDownEntries[] = {
+ { VK_LEFT, 0, "MoveLeft" },
+ { VK_LEFT, ShiftKey, "MoveLeftAndModifySelection" },
+ { VK_LEFT, CtrlKey, "MoveWordLeft" },
+ { VK_LEFT, CtrlKey | ShiftKey, "MoveWordLeftAndModifySelection" },
+ { VK_RIGHT, 0, "MoveRight" },
+ { VK_RIGHT, ShiftKey, "MoveRightAndModifySelection" },
+ { VK_RIGHT, CtrlKey, "MoveWordRight" },
+ { VK_RIGHT, CtrlKey | ShiftKey, "MoveWordRightAndModifySelection" },
+ { VK_UP, 0, "MoveUp" },
+ { VK_UP, ShiftKey, "MoveUpAndModifySelection" },
+ { VK_PRIOR, ShiftKey, "MovePageUpAndModifySelection" },
+ { VK_DOWN, 0, "MoveDown" },
+ { VK_DOWN, ShiftKey, "MoveDownAndModifySelection" },
+ { VK_NEXT, ShiftKey, "MovePageDownAndModifySelection" },
+ { VK_PRIOR, 0, "MovePageUp" },
+ { VK_NEXT, 0, "MovePageDown" },
+ { VK_HOME, 0, "MoveToBeginningOfLine" },
+ { VK_HOME, ShiftKey, "MoveToBeginningOfLineAndModifySelection" },
+ { VK_HOME, CtrlKey, "MoveToBeginningOfDocument" },
+ { VK_HOME, CtrlKey | ShiftKey, "MoveToBeginningOfDocumentAndModifySelection" },
+
+ { VK_END, 0, "MoveToEndOfLine" },
+ { VK_END, ShiftKey, "MoveToEndOfLineAndModifySelection" },
+ { VK_END, CtrlKey, "MoveToEndOfDocument" },
+ { VK_END, CtrlKey | ShiftKey, "MoveToEndOfDocumentAndModifySelection" },
+
+ { VK_BACK, 0, "DeleteBackward" },
+ { VK_BACK, ShiftKey, "DeleteBackward" },
+ { VK_DELETE, 0, "DeleteForward" },
+ { VK_BACK, CtrlKey, "DeleteWordBackward" },
+ { VK_DELETE, CtrlKey, "DeleteWordForward" },
+
+ { 'B', CtrlKey, "ToggleBold" },
+ { 'I', CtrlKey, "ToggleItalic" },
+
+ { VK_ESCAPE, 0, "Cancel" },
+ //FIXME: this'll never happen. We can trash it or make it a normal period
+ { VK_OEM_PERIOD, CtrlKey, "Cancel" },
+ { VK_TAB, 0, "InsertTab" },
+ { VK_TAB, ShiftKey, "InsertBacktab" },
+ { VK_RETURN, 0, "InsertNewline" },
+ { VK_RETURN, CtrlKey, "InsertNewline" },
+ { VK_RETURN, AltKey, "InsertNewline" },
+ { VK_RETURN, AltKey | ShiftKey, "InsertNewline" },
+ { 'A', CtrlKey, "SelectAll" },
+ { 'Z', CtrlKey, "Undo" },
+ { 'Z', CtrlKey | ShiftKey, "Redo" },
+};
+
+static const KeyPressEntry keyPressEntries[] = {
+ { '\t', 0, "InsertTab" },
+ { '\t', ShiftKey, "InsertBacktab" },
+ { '\r', 0, "InsertNewline" },
+ { '\r', CtrlKey, "InsertNewline" },
+ { '\r', AltKey, "InsertNewline" },
+ { '\r', AltKey | ShiftKey, "InsertNewline" },
+};
+
EditorClientWx::~EditorClientWx()
{
m_page = NULL;
@@ -61,7 +136,7 @@ void EditorClientWx::setPage(Page* page)
void EditorClientWx::pageDestroyed()
{
- notImplemented();
+ delete this;
}
bool EditorClientWx::shouldDeleteRange(Range*)
@@ -286,6 +361,74 @@ void EditorClientWx::redo()
}
}
+bool EditorClientWx::handleEditingKeyboardEvent(KeyboardEvent* event)
+{
+ Node* node = event->target()->toNode();
+ ASSERT(node);
+ Frame* frame = node->document()->frame();
+ ASSERT(frame);
+
+ const PlatformKeyboardEvent* keyEvent = event->keyEvent();
+
+ //NB: this is what windows does, but they also have a keypress event for Alt+Enter which clearly won't get hit with this
+ if (!keyEvent || keyEvent->altKey()) // do not treat this as text input if Alt is down
+ return false;
+
+ Editor::Command command = frame->editor()->command(interpretKeyEvent(event));
+
+ if (keyEvent->type() == PlatformKeyboardEvent::RawKeyDown) {
+ // WebKit doesn't have enough information about mode to decide how commands that just insert text if executed via Editor should be treated,
+ // so we leave it upon WebCore to either handle them immediately (e.g. Tab that changes focus) or if not to let a CHAR event be generated
+ // (e.g. Tab that inserts a Tab character, or Enter).
+ return !command.isTextInsertion() && command.execute(event);
+ }
+
+ if (command.execute(event))
+ return true;
+
+ // Don't insert null or control characters as they can result in unexpected behaviour
+ if (event->charCode() < ' ')
+ return false;
+
+ return frame->editor()->insertText(event->keyEvent()->text(), event);
+}
+
+const char* EditorClientWx::interpretKeyEvent(const KeyboardEvent* evt)
+{
+ ASSERT(evt->keyEvent()->type() == PlatformKeyboardEvent::RawKeyDown || evt->keyEvent()->type() == PlatformKeyboardEvent::Char);
+
+ static HashMap<int, const char*>* keyDownCommandsMap = 0;
+ static HashMap<int, const char*>* keyPressCommandsMap = 0;
+
+ if (!keyDownCommandsMap) {
+ keyDownCommandsMap = new HashMap<int, const char*>;
+ keyPressCommandsMap = new HashMap<int, const char*>;
+
+ for (unsigned i = 0; i < WXSIZEOF(keyDownEntries); i++)
+ keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
+
+ for (unsigned i = 0; i < WXSIZEOF(keyPressEntries); i++)
+ keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
+ }
+
+ unsigned modifiers = 0;
+ if (evt->shiftKey())
+ modifiers |= ShiftKey;
+ if (evt->altKey())
+ modifiers |= AltKey;
+ if (evt->ctrlKey())
+ modifiers |= CtrlKey;
+
+ if (evt->keyEvent()->type() == PlatformKeyboardEvent::RawKeyDown) {
+ int mapKey = modifiers << 16 | evt->keyCode();
+ return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
+ }
+
+ int mapKey = modifiers << 16 | evt->charCode();
+ return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
+}
+
+
void EditorClientWx::handleInputMethodKeydown(KeyboardEvent* event)
{
// NOTE: we don't currently need to handle this. When key events occur,
@@ -295,63 +438,8 @@ void EditorClientWx::handleInputMethodKeydown(KeyboardEvent* event)
void EditorClientWx::handleKeyboardEvent(KeyboardEvent* event)
{
- Frame* frame = m_page->focusController()->focusedOrMainFrame();
- if (!frame)
- return;
-
- const PlatformKeyboardEvent* kevent = event->keyEvent();
- if (kevent->type() != PlatformKeyboardEvent::KeyUp) {
- Node* start = frame->selection()->start().node();
- if (!start || !start->isContentEditable())
- return;
-
- if (kevent->type() == PlatformKeyboardEvent::Char && !kevent->ctrlKey() && !kevent->altKey()) {
- switch (kevent->windowsVirtualKeyCode()) {
- // we handled these on key down, ignore them for char events
- case VK_BACK:
- case VK_DELETE:
- case VK_LEFT:
- case VK_RIGHT:
- case VK_UP:
- case VK_DOWN:
- case VK_RETURN:
- break;
- default:
- frame->editor()->insertText(kevent->text(), event);
- }
- event->setDefaultHandled();
- return;
- }
-
- switch (kevent->windowsVirtualKeyCode()) {
- case VK_BACK:
- frame->editor()->deleteWithDirection(SelectionController::BACKWARD,
- CharacterGranularity, false, true);
- break;
- case VK_DELETE:
- frame->editor()->deleteWithDirection(SelectionController::FORWARD,
- CharacterGranularity, false, true);
- break;
- case VK_LEFT:
- frame->editor()->command("MoveLeft").execute();
- break;
- case VK_RIGHT:
- frame->editor()->command("MoveRight").execute();
- break;
- case VK_UP:
- frame->editor()->command("MoveUp").execute();
- break;
- case VK_DOWN:
- frame->editor()->command("MoveDown").execute();
- break;
- case VK_RETURN:
- frame->editor()->command("InsertLineBreak").execute();
- default:
- break;
- }
-
+ if (handleEditingKeyboardEvent(event))
event->setDefaultHandled();
- }
}
void EditorClientWx::textFieldDidBeginEditing(Element*)
@@ -436,6 +524,12 @@ void EditorClientWx::getGuessesForWord(const String&, Vector<String>& guesses)
notImplemented();
}
+String EditorClientWx::getAutoCorrectSuggestionForMisspelledWord(const WebCore::String&)
+{
+ notImplemented();
+ return String();
+}
+
void EditorClientWx::setInputMethodState(bool enabled)
{
notImplemented();