Initial upstreaming of EditorClientBlackBerry
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Feb 2012 02:58:17 +0000 (02:58 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 16 Feb 2012 02:58:17 +0000 (02:58 +0000)
https://bugs.webkit.org/show_bug.cgi?id=78730

Patch by Mike Fenton <mifenton@rim.com> on 2012-02-15
Reviewed by Rob Buis.

Initial upstreaming, no new tests.

* blackberry/WebCoreSupport/EditorClientBlackBerry.cpp: Added.
(WebCore):
(WebCore::EditorClientBlackBerry::EditorClientBlackBerry):
(WebCore::EditorClientBlackBerry::pageDestroyed):
(WebCore::EditorClientBlackBerry::shouldDeleteRange):
(WebCore::EditorClientBlackBerry::shouldShowDeleteInterface):
(WebCore::EditorClientBlackBerry::smartInsertDeleteEnabled):
(WebCore::EditorClientBlackBerry::isSelectTrailingWhitespaceEnabled):
(WebCore::EditorClientBlackBerry::enableSpellChecking):
(WebCore::EditorClientBlackBerry::shouldSpellCheckFocusedField):
(WebCore::EditorClientBlackBerry::isContinuousSpellCheckingEnabled):
(WebCore::EditorClientBlackBerry::toggleContinuousSpellChecking):
(WebCore::EditorClientBlackBerry::isGrammarCheckingEnabled):
(WebCore::EditorClientBlackBerry::toggleGrammarChecking):
(WebCore::EditorClientBlackBerry::spellCheckerDocumentTag):
(WebCore::EditorClientBlackBerry::shouldBeginEditing):
(WebCore::EditorClientBlackBerry::shouldEndEditing):
(WebCore::EditorClientBlackBerry::shouldInsertNode):
(WebCore::EditorClientBlackBerry::shouldInsertText):
(WebCore::EditorClientBlackBerry::shouldChangeSelectedRange):
(WebCore::EditorClientBlackBerry::shouldApplyStyle):
(WebCore::EditorClientBlackBerry::shouldMoveRangeAfterDelete):
(WebCore::EditorClientBlackBerry::didBeginEditing):
(WebCore::EditorClientBlackBerry::respondToChangedContents):
(WebCore::EditorClientBlackBerry::respondToChangedSelection):
(WebCore::EditorClientBlackBerry::didEndEditing):
(WebCore::EditorClientBlackBerry::respondToSelectionAppearanceChange):
(WebCore::EditorClientBlackBerry::didWriteSelectionToPasteboard):
(WebCore::EditorClientBlackBerry::didSetSelectionTypesForPasteboard):
(WebCore::EditorClientBlackBerry::registerCommandForUndo):
(WebCore::EditorClientBlackBerry::registerCommandForRedo):
(WebCore::EditorClientBlackBerry::clearUndoRedoOperations):
(WebCore::EditorClientBlackBerry::canUndo):
(WebCore::EditorClientBlackBerry::canRedo):
(WebCore::EditorClientBlackBerry::canCopyCut):
(WebCore::EditorClientBlackBerry::canPaste):
(WebCore::EditorClientBlackBerry::undo):
(WebCore::EditorClientBlackBerry::redo):
(KeyDownEntry):
(KeyPressEntry):
(WebCore::EditorClientBlackBerry::interpretKeyEvent):
(WebCore::EditorClientBlackBerry::handleKeyboardEvent):
(WebCore::EditorClientBlackBerry::handleInputMethodKeydown):
(WebCore::EditorClientBlackBerry::textFieldDidBeginEditing):
(WebCore::EditorClientBlackBerry::textFieldDidEndEditing):
(WebCore::EditorClientBlackBerry::textDidChangeInTextField):
(WebCore::EditorClientBlackBerry::doTextFieldCommandFromEvent):
(WebCore::EditorClientBlackBerry::textWillBeDeletedInTextField):
(WebCore::EditorClientBlackBerry::textDidChangeInTextArea):
(WebCore::EditorClientBlackBerry::ignoreWordInSpellDocument):
(WebCore::EditorClientBlackBerry::learnWord):
(WebCore::EditorClientBlackBerry::checkSpellingOfString):
(WebCore::EditorClientBlackBerry::getAutoCorrectSuggestionForMisspelledWord):
(WebCore::EditorClientBlackBerry::checkGrammarOfString):
(WebCore::EditorClientBlackBerry::requestCheckingOfString):
(WebCore::EditorClientBlackBerry::textChecker):
(WebCore::EditorClientBlackBerry::updateSpellingUIWithGrammarString):
(WebCore::EditorClientBlackBerry::updateSpellingUIWithMisspelledWord):
(WebCore::EditorClientBlackBerry::showSpellingUI):
(WebCore::EditorClientBlackBerry::spellingUIIsShowing):
(WebCore::EditorClientBlackBerry::getGuessesForWord):
(WebCore::EditorClientBlackBerry::willSetInputMethodState):
(WebCore::EditorClientBlackBerry::setInputMethodState):
* blackberry/WebCoreSupport/EditorClientBlackBerry.h: Added.
(WebKit):
(WebCore):
(EditorClientBlackBerry):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@107870 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp [new file with mode: 0644]
Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.h [new file with mode: 0644]

index f4d34a5..c177f6a 100644 (file)
@@ -1,3 +1,80 @@
+2012-02-15  Mike Fenton  <mifenton@rim.com>
+
+        Initial upstreaming of EditorClientBlackBerry
+        https://bugs.webkit.org/show_bug.cgi?id=78730
+
+        Reviewed by Rob Buis.
+
+        Initial upstreaming, no new tests.
+
+        * blackberry/WebCoreSupport/EditorClientBlackBerry.cpp: Added.
+        (WebCore):
+        (WebCore::EditorClientBlackBerry::EditorClientBlackBerry):
+        (WebCore::EditorClientBlackBerry::pageDestroyed):
+        (WebCore::EditorClientBlackBerry::shouldDeleteRange):
+        (WebCore::EditorClientBlackBerry::shouldShowDeleteInterface):
+        (WebCore::EditorClientBlackBerry::smartInsertDeleteEnabled):
+        (WebCore::EditorClientBlackBerry::isSelectTrailingWhitespaceEnabled):
+        (WebCore::EditorClientBlackBerry::enableSpellChecking):
+        (WebCore::EditorClientBlackBerry::shouldSpellCheckFocusedField):
+        (WebCore::EditorClientBlackBerry::isContinuousSpellCheckingEnabled):
+        (WebCore::EditorClientBlackBerry::toggleContinuousSpellChecking):
+        (WebCore::EditorClientBlackBerry::isGrammarCheckingEnabled):
+        (WebCore::EditorClientBlackBerry::toggleGrammarChecking):
+        (WebCore::EditorClientBlackBerry::spellCheckerDocumentTag):
+        (WebCore::EditorClientBlackBerry::shouldBeginEditing):
+        (WebCore::EditorClientBlackBerry::shouldEndEditing):
+        (WebCore::EditorClientBlackBerry::shouldInsertNode):
+        (WebCore::EditorClientBlackBerry::shouldInsertText):
+        (WebCore::EditorClientBlackBerry::shouldChangeSelectedRange):
+        (WebCore::EditorClientBlackBerry::shouldApplyStyle):
+        (WebCore::EditorClientBlackBerry::shouldMoveRangeAfterDelete):
+        (WebCore::EditorClientBlackBerry::didBeginEditing):
+        (WebCore::EditorClientBlackBerry::respondToChangedContents):
+        (WebCore::EditorClientBlackBerry::respondToChangedSelection):
+        (WebCore::EditorClientBlackBerry::didEndEditing):
+        (WebCore::EditorClientBlackBerry::respondToSelectionAppearanceChange):
+        (WebCore::EditorClientBlackBerry::didWriteSelectionToPasteboard):
+        (WebCore::EditorClientBlackBerry::didSetSelectionTypesForPasteboard):
+        (WebCore::EditorClientBlackBerry::registerCommandForUndo):
+        (WebCore::EditorClientBlackBerry::registerCommandForRedo):
+        (WebCore::EditorClientBlackBerry::clearUndoRedoOperations):
+        (WebCore::EditorClientBlackBerry::canUndo):
+        (WebCore::EditorClientBlackBerry::canRedo):
+        (WebCore::EditorClientBlackBerry::canCopyCut):
+        (WebCore::EditorClientBlackBerry::canPaste):
+        (WebCore::EditorClientBlackBerry::undo):
+        (WebCore::EditorClientBlackBerry::redo):
+        (KeyDownEntry):
+        (KeyPressEntry):
+        (WebCore::EditorClientBlackBerry::interpretKeyEvent):
+        (WebCore::EditorClientBlackBerry::handleKeyboardEvent):
+        (WebCore::EditorClientBlackBerry::handleInputMethodKeydown):
+        (WebCore::EditorClientBlackBerry::textFieldDidBeginEditing):
+        (WebCore::EditorClientBlackBerry::textFieldDidEndEditing):
+        (WebCore::EditorClientBlackBerry::textDidChangeInTextField):
+        (WebCore::EditorClientBlackBerry::doTextFieldCommandFromEvent):
+        (WebCore::EditorClientBlackBerry::textWillBeDeletedInTextField):
+        (WebCore::EditorClientBlackBerry::textDidChangeInTextArea):
+        (WebCore::EditorClientBlackBerry::ignoreWordInSpellDocument):
+        (WebCore::EditorClientBlackBerry::learnWord):
+        (WebCore::EditorClientBlackBerry::checkSpellingOfString):
+        (WebCore::EditorClientBlackBerry::getAutoCorrectSuggestionForMisspelledWord):
+        (WebCore::EditorClientBlackBerry::checkGrammarOfString):
+        (WebCore::EditorClientBlackBerry::requestCheckingOfString):
+        (WebCore::EditorClientBlackBerry::textChecker):
+        (WebCore::EditorClientBlackBerry::updateSpellingUIWithGrammarString):
+        (WebCore::EditorClientBlackBerry::updateSpellingUIWithMisspelledWord):
+        (WebCore::EditorClientBlackBerry::showSpellingUI):
+        (WebCore::EditorClientBlackBerry::spellingUIIsShowing):
+        (WebCore::EditorClientBlackBerry::getGuessesForWord):
+        (WebCore::EditorClientBlackBerry::willSetInputMethodState):
+        (WebCore::EditorClientBlackBerry::setInputMethodState):
+        * blackberry/WebCoreSupport/EditorClientBlackBerry.h: Added.
+        (WebKit):
+        (WebCore):
+        (EditorClientBlackBerry):
+
 2012-02-15  Leo Yang  <leo.yang@torchmobile.com.cn>
 
         [BlackBerry] Upstream WebPageClient.h
diff --git a/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp b/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.cpp
new file mode 100644 (file)
index 0000000..7c0404b
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
+ * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+#include "EditorClientBlackBerry.h"
+
+#include "DOMSupport.h"
+#include "DumpRenderTreeClient.h"
+#include "EditCommand.h"
+#include "Frame.h"
+#include "HTMLInputElement.h"
+#include "HTMLNames.h"
+#include "InputHandler.h"
+#include "KeyboardEvent.h"
+#include "NotImplemented.h"
+#include "Page.h"
+#include "PlatformKeyboardEvent.h"
+#include "SelectionHandler.h"
+#include "WebPage_p.h"
+#include "WindowsKeyboardCodes.h"
+
+using namespace BlackBerry::WebKit;
+
+namespace WebCore {
+
+// Arbitrary depth limit for the undo stack, to keep it from using
+// unbounded memory. This is the maximum number of distinct undoable
+// actions -- unbroken stretches of typed characters are coalesced
+// into a single action only when not interrupted by string replacements
+// triggered by replaceText calls.
+static const size_t maximumUndoStackDepth = 1000;
+
+EditorClientBlackBerry::EditorClientBlackBerry(WebPagePrivate* webPagePrivate)
+    : m_webPagePrivate(webPagePrivate)
+    , m_waitingForCursorFocus(false)
+    , m_spellCheckState(SpellCheckDefault)
+    , m_inRedo(false)
+{
+}
+
+void EditorClientBlackBerry::pageDestroyed()
+{
+    delete this;
+}
+
+bool EditorClientBlackBerry::shouldDeleteRange(Range* range)
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        return m_webPagePrivate->m_dumpRenderTree->shouldDeleteDOMRange(range);
+    return true;
+}
+
+bool EditorClientBlackBerry::shouldShowDeleteInterface(HTMLElement*)
+{
+    notImplemented();
+    return false;
+}
+
+bool EditorClientBlackBerry::smartInsertDeleteEnabled()
+{
+    notImplemented();
+    return false;
+}
+
+bool EditorClientBlackBerry::isSelectTrailingWhitespaceEnabled()
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        return m_webPagePrivate->m_dumpRenderTree->isSelectTrailingWhitespaceEnabled();
+    return false;
+}
+
+void EditorClientBlackBerry::enableSpellChecking(bool enable)
+{
+    m_spellCheckState = enable ? SpellCheckDefault : SpellCheckOff;
+}
+
+bool EditorClientBlackBerry::shouldSpellCheckFocusedField()
+{
+    const Frame* frame = m_webPagePrivate->focusedOrMainFrame();
+    if (!frame || !frame->document() || !frame->editor())
+        return false;
+
+    const Node* node = frame->document()->focusedNode();
+    // NOTE: This logic is taken from EditorClientImpl::shouldSpellcheckByDefault
+    // If |node| is null, we default to allowing spellchecking. This is done in
+    // order to mitigate the issue when the user clicks outside the textbox, as a
+    // result of which |node| becomes null, resulting in all the spell check
+    // markers being deleted. Also, the Frame will decide not to do spellchecking
+    // if the user can't edit - so returning true here will not cause any problems
+    // to the Frame's behavior.
+    if (!node)
+        return true;
+
+    // If the field does not support autocomplete, do not do spellchecking.
+    if (node->isElementNode()) {
+        const Element* element = static_cast<const Element*>(node);
+        if (element->hasTagName(HTMLNames::inputTag) && !DOMSupport::elementSupportsAutocomplete(element))
+            return false;
+    }
+
+    // Check if the node disables spell checking directly.
+    return frame->editor()->isSpellCheckingEnabledInFocusedNode();
+}
+
+bool EditorClientBlackBerry::isContinuousSpellCheckingEnabled()
+{
+    if (m_spellCheckState == SpellCheckOff)
+        return false;
+    if (m_spellCheckState == SpellCheckOn)
+        return true;
+    return shouldSpellCheckFocusedField();
+}
+
+void EditorClientBlackBerry::toggleContinuousSpellChecking()
+{
+    // Use the current state to determine how to toggle, if it hasn't
+    // been explicitly set, it will toggle based on the field type.
+    if (isContinuousSpellCheckingEnabled())
+        m_spellCheckState = SpellCheckOff;
+    else
+        m_spellCheckState = SpellCheckOn;
+}
+
+bool EditorClientBlackBerry::isGrammarCheckingEnabled()
+{
+    notImplemented();
+    return false;
+}
+
+void EditorClientBlackBerry::toggleGrammarChecking()
+{
+    notImplemented();
+}
+
+int EditorClientBlackBerry::spellCheckerDocumentTag()
+{
+    notImplemented();
+    return 0;
+}
+
+bool EditorClientBlackBerry::shouldBeginEditing(Range* range)
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        return m_webPagePrivate->m_dumpRenderTree->shouldBeginEditingInDOMRange(range);
+
+    return m_webPagePrivate->m_inputHandler->shouldAcceptInputFocus();
+}
+
+bool EditorClientBlackBerry::shouldEndEditing(Range* range)
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        return m_webPagePrivate->m_dumpRenderTree->shouldEndEditingInDOMRange(range);
+    return true;
+}
+
+bool EditorClientBlackBerry::shouldInsertNode(Node* node, Range* range, EditorInsertAction insertAction)
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        return m_webPagePrivate->m_dumpRenderTree->shouldInsertNode(node, range, static_cast<int>(insertAction));
+    return true;
+}
+
+bool EditorClientBlackBerry::shouldInsertText(const WTF::String& text, Range* range, EditorInsertAction insertAction)
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        return m_webPagePrivate->m_dumpRenderTree->shouldInsertText(text, range, static_cast<int>(insertAction));
+    return true;
+}
+
+bool EditorClientBlackBerry::shouldChangeSelectedRange(Range* fromRange, Range* toRange, EAffinity affinity, bool stillSelecting)
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        return m_webPagePrivate->m_dumpRenderTree->shouldChangeSelectedDOMRangeToDOMRangeAffinityStillSelecting(fromRange, toRange, static_cast<int>(affinity), stillSelecting);
+
+    Frame* frame = m_webPagePrivate->focusedOrMainFrame();
+    if (frame && frame->document()) {
+        if (frame->document()->focusedNode() && frame->document()->focusedNode()->hasTagName(HTMLNames::selectTag))
+            return false;
+
+        // Update the focus state to re-show the keyboard if needed.
+        // FIXME, this should be removed and strictly be a show keyboard call if
+        // focus is active.
+        if (m_webPagePrivate->m_inputHandler->isInputMode())
+            m_webPagePrivate->m_inputHandler->nodeFocused(frame->document()->focusedNode());
+    }
+
+    return true;
+}
+
+bool EditorClientBlackBerry::shouldApplyStyle(CSSStyleDeclaration*, Range*)
+{
+    notImplemented();
+    return true;
+}
+
+bool EditorClientBlackBerry::shouldMoveRangeAfterDelete(Range*, Range*)
+{
+    notImplemented();
+    return true;
+}
+
+void EditorClientBlackBerry::didBeginEditing()
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        m_webPagePrivate->m_dumpRenderTree->didBeginEditing();
+}
+
+void EditorClientBlackBerry::respondToChangedContents()
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        m_webPagePrivate->m_dumpRenderTree->didChange();
+}
+
+void EditorClientBlackBerry::respondToChangedSelection(Frame* frame)
+{
+    if (m_waitingForCursorFocus)
+        m_waitingForCursorFocus = false;
+    else
+        m_webPagePrivate->selectionChanged(frame);
+
+    if (m_webPagePrivate->m_dumpRenderTree)
+        m_webPagePrivate->m_dumpRenderTree->didChangeSelection();
+}
+
+void EditorClientBlackBerry::didEndEditing()
+{
+    if (m_webPagePrivate->m_dumpRenderTree)
+        m_webPagePrivate->m_dumpRenderTree->didEndEditing();
+}
+
+void EditorClientBlackBerry::respondToSelectionAppearanceChange()
+{
+    m_webPagePrivate->m_selectionHandler->selectionPositionChanged();
+}
+
+void EditorClientBlackBerry::didWriteSelectionToPasteboard()
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::didSetSelectionTypesForPasteboard()
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::registerCommandForUndo(PassRefPtr<EditCommand> command)
+{
+    // Remove the oldest item if we've reached the maximum capacity for the stack.
+    if (m_undoStack.size() == maximumUndoStackDepth)
+        m_undoStack.removeFirst();
+
+    if (!m_inRedo)
+        m_redoStack.clear();
+
+    m_undoStack.append(command);
+}
+
+void EditorClientBlackBerry::registerCommandForRedo(PassRefPtr<EditCommand> command)
+{
+    m_redoStack.append(command);
+}
+
+void EditorClientBlackBerry::clearUndoRedoOperations()
+{
+    m_undoStack.clear();
+    m_redoStack.clear();
+}
+
+bool EditorClientBlackBerry::canUndo() const
+{
+    return !m_undoStack.isEmpty();
+}
+
+bool EditorClientBlackBerry::canRedo() const
+{
+    return !m_redoStack.isEmpty();
+}
+
+bool EditorClientBlackBerry::canCopyCut(Frame*, bool defaultValue) const
+{
+    return defaultValue;
+}
+
+bool EditorClientBlackBerry::canPaste(Frame*, bool defaultValue) const
+{
+    return defaultValue;
+}
+
+void EditorClientBlackBerry::undo()
+{
+    if (canUndo()) {
+        EditCommandStack::iterator back = --m_undoStack.end();
+        RefPtr<EditCommand> command(*back);
+        m_undoStack.remove(back);
+
+        // Unapply will call us back to push this command onto the redo stack.
+        command->unapply();
+    }
+}
+
+void EditorClientBlackBerry::redo()
+{
+    if (canRedo()) {
+        EditCommandStack::iterator back = --m_redoStack.end();
+        RefPtr<EditCommand> command(*back);
+        m_redoStack.remove(back);
+
+        ASSERT(!m_inRedo);
+        m_inRedo = true;
+
+        // Reapply will call us back to push this command onto the undo stack.
+        command->reapply();
+        m_inRedo = false;
+    }
+}
+
+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_DOWN,   0,                  "MoveDown"                                    },
+    { VK_DOWN,   ShiftKey,           "MoveDownAndModifySelection"                  },
+    { VK_PRIOR,  0,                  "MovePageUp"                                  },
+    { VK_PRIOR,  ShiftKey,           "MovePageUpAndModifySelection"                },
+    { VK_NEXT,   0,                  "MovePageDown"                                },
+    { VK_NEXT,   ShiftKey,           "MovePageDownAndModifySelection"              },
+    { 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"       },
+
+    { 'B',       CtrlKey,            "ToggleBold"                                  },
+    { 'I',       CtrlKey,            "ToggleItalic"                                },
+    { 'U',       CtrlKey,            "ToggleUnderline"                             },
+
+    { VK_BACK,   0,                  "DeleteBackward"                              },
+    { VK_BACK,   ShiftKey,           "DeleteBackward"                              },
+    { VK_DELETE, 0,                  "DeleteForward"                               },
+    { VK_BACK,   CtrlKey,            "DeleteWordBackward"                          },
+    { VK_DELETE, CtrlKey,            "DeleteWordForward"                           },
+
+    { 'C',       CtrlKey,            "Copy"                                        },
+    { 'V',       CtrlKey,            "Paste"                                       },
+    { 'V',       CtrlKey | ShiftKey, "PasteAndMatchStyle"                          },
+    { 'X',       CtrlKey,            "Cut"                                         },
+    { VK_INSERT, CtrlKey,            "Copy"                                        },
+    { VK_DELETE, ShiftKey,           "Cut"                                         },
+    { VK_INSERT, ShiftKey,           "Paste"                                       },
+
+    { 'A',       CtrlKey,            "SelectAll"                                   },
+    { 'Z',       CtrlKey,            "Undo"                                        },
+    { 'Z',       CtrlKey | ShiftKey, "Redo"                                        },
+    { 'Y',       CtrlKey,            "Redo"                                        },
+
+    { VK_TAB,    0,                  "InsertTab"                                   },
+    { VK_TAB,    ShiftKey,           "InsertBacktab"                               },
+    { VK_RETURN, 0,                  "InsertNewline"                               },
+    { VK_RETURN, CtrlKey,            "InsertNewline"                               },
+    { VK_RETURN, AltKey,             "InsertNewline"                               },
+    { VK_RETURN, ShiftKey,           "InsertLineBreak"                             },
+    { VK_RETURN, AltKey | ShiftKey,  "InsertNewline"                               },
+
+};
+
+static const KeyPressEntry keyPressEntries[] = {
+    { '\t',   0,                  "InsertTab"                                   },
+    { '\t',   ShiftKey,           "InsertBacktab"                               },
+    { '\r',   0,                  "InsertNewline"                               },
+    { '\r',   CtrlKey,            "InsertNewline"                               },
+    { '\r',   AltKey,             "InsertNewline"                               },
+    { '\r',   ShiftKey,           "InsertLineBreak"                             },
+    { '\r',   AltKey | ShiftKey,  "InsertNewline"                               },
+};
+
+
+const char* EditorClientBlackBerry::interpretKeyEvent(const KeyboardEvent* event)
+{
+    ASSERT(event->type() == eventNames().keydownEvent || event->type() == eventNames().keypressEvent);
+
+    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 (size_t i = 0; i < WTF_ARRAY_LENGTH(keyDownEntries); ++i)
+            keyDownCommandsMap->set(keyDownEntries[i].modifiers << 16 | keyDownEntries[i].virtualKey, keyDownEntries[i].name);
+
+        for (size_t i = 0; i < WTF_ARRAY_LENGTH(keyPressEntries); ++i)
+            keyPressCommandsMap->set(keyPressEntries[i].modifiers << 16 | keyPressEntries[i].charCode, keyPressEntries[i].name);
+    }
+
+    unsigned modifiers = 0;
+    if (event->shiftKey())
+        modifiers |= ShiftKey;
+    if (event->altKey())
+        modifiers |= AltKey;
+    if (event->ctrlKey())
+        modifiers |= CtrlKey;
+
+    if (event->type() == eventNames().keydownEvent) {
+        int mapKey = modifiers << 16 | event->keyCode();
+        return mapKey ? keyDownCommandsMap->get(mapKey) : 0;
+    }
+
+    int mapKey = modifiers << 16 | event->charCode();
+    return mapKey ? keyPressCommandsMap->get(mapKey) : 0;
+}
+
+void EditorClientBlackBerry::handleKeyboardEvent(KeyboardEvent* event)
+{
+    ASSERT(event);
+
+    const PlatformKeyboardEvent* platformEvent = event->keyEvent();
+    if (!platformEvent)
+        return;
+
+    ASSERT(event->target()->toNode());
+    Frame* frame = event->target()->toNode()->document()->frame();
+    ASSERT(frame);
+
+    String commandName = interpretKeyEvent(event);
+
+    if (!commandName.isEmpty()) {
+        if (frame->editor()->command(commandName).execute())
+            event->setDefaultHandled();
+        return;
+    }
+
+    if (!frame->editor()->canEdit())
+        return;
+
+    // Text insertion commands should only be triggered from keypressEvent.
+    // There is an assert guaranteeing this in
+    // EventHandler::handleTextInputEvent. Note that windowsVirtualKeyCode
+    // is not set for keypressEvent: special keys should have been already
+    // handled in keydownEvent, which is called first.
+    if (event->type() != eventNames().keypressEvent)
+        return;
+
+    // Don't insert null or control characters as they can result in unexpected behaviour.
+    if (event->charCode() < ' ')
+        return;
+
+    // Don't insert anything if a modifier is pressed.
+    if (event->ctrlKey() || event->altKey())
+        return;
+
+    if (!platformEvent->text().isEmpty()) {
+        if (frame->editor()->insertText(platformEvent->text(), event))
+            event->setDefaultHandled();
+    }
+}
+
+void EditorClientBlackBerry::handleInputMethodKeydown(KeyboardEvent*)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::textFieldDidBeginEditing(Element*)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::textFieldDidEndEditing(Element*)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::textDidChangeInTextField(Element*)
+{
+    notImplemented();
+}
+
+bool EditorClientBlackBerry::doTextFieldCommandFromEvent(Element*, KeyboardEvent*)
+{
+    notImplemented();
+    return false;
+}
+
+void EditorClientBlackBerry::textWillBeDeletedInTextField(Element*)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::textDidChangeInTextArea(Element*)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::ignoreWordInSpellDocument(const WTF::String&)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::learnWord(const WTF::String&)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::checkSpellingOfString(const UChar* text, int textLength, int* misspellLocation, int* misspellLength)
+{
+    m_webPagePrivate->m_client->checkSpellingOfString(text, textLength, *misspellLocation, *misspellLength);
+}
+
+WTF::String EditorClientBlackBerry::getAutoCorrectSuggestionForMisspelledWord(const WTF::String& misspelledWord)
+{
+    notImplemented();
+    return WTF::String();
+}
+
+void EditorClientBlackBerry::checkGrammarOfString(const UChar*, int, WTF::Vector<GrammarDetail, 0u>&, int*, int*)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::requestCheckingOfString(SpellChecker*, int, TextCheckingTypeMask, const String&)
+{
+    notImplemented();
+}
+
+TextCheckerClient* EditorClientBlackBerry::textChecker()
+{
+    return this;
+}
+
+void EditorClientBlackBerry::updateSpellingUIWithGrammarString(const WTF::String&, const GrammarDetail&)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::updateSpellingUIWithMisspelledWord(const WTF::String&)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::showSpellingUI(bool)
+{
+    notImplemented();
+}
+
+bool EditorClientBlackBerry::spellingUIIsShowing()
+{
+    notImplemented();
+    return false;
+}
+
+void EditorClientBlackBerry::getGuessesForWord(const WTF::String&, WTF::Vector<WTF::String, 0u>&)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::getGuessesForWord(const String&, const String&, Vector<String>&)
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::willSetInputMethodState()
+{
+    notImplemented();
+}
+
+void EditorClientBlackBerry::setInputMethodState(bool active)
+{
+    Frame* frame = m_webPagePrivate->focusedOrMainFrame();
+    // Determines whether or not to provide input assistance. Password fields
+    // do not have this flag active, so it needs to be overridden.
+    if (frame && frame->document()) {
+        if (Node* focusNode = frame->document()->focusedNode()) {
+            if (!active && focusNode->hasTagName(HTMLNames::inputTag)
+                && static_cast<HTMLInputElement*>(focusNode)->isPasswordField())
+                    active = true;
+
+            if (active) {
+                m_webPagePrivate->m_inputHandler->nodeFocused(focusNode);
+                return;
+            }
+        }
+    }
+    // No frame or document or a node that doesn't support IME.
+    m_webPagePrivate->m_inputHandler->nodeFocused(0);
+}
+
+} // namespace WebCore
diff --git a/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.h b/Source/WebKit/blackberry/WebCoreSupport/EditorClientBlackBerry.h
new file mode 100644 (file)
index 0000000..9466d0c
--- /dev/null
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2009 Torch Mobile Inc. http://www.torchmobile.com/
+ * Copyright (C) 2009, 2010, 2011, 2012 Research In Motion Limited. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifndef EditorClientBlackBerry_h
+#define EditorClientBlackBerry_h
+
+#include "EditorClient.h"
+#include "TextCheckerClient.h"
+
+#include <wtf/Deque.h>
+
+namespace BlackBerry {
+namespace WebKit {
+class WebPagePrivate;
+}
+}
+
+namespace WebCore {
+
+class EditorClientBlackBerry : public EditorClient, public TextCheckerClient {
+public:
+    EditorClientBlackBerry(BlackBerry::WebKit::WebPagePrivate*);
+    virtual void pageDestroyed();
+    virtual bool shouldDeleteRange(Range*);
+    virtual bool shouldShowDeleteInterface(HTMLElement*);
+    virtual bool smartInsertDeleteEnabled();
+    virtual bool isSelectTrailingWhitespaceEnabled();
+    virtual bool isContinuousSpellCheckingEnabled();
+    virtual void toggleContinuousSpellChecking();
+    virtual bool isGrammarCheckingEnabled();
+    virtual void toggleGrammarChecking();
+    virtual int spellCheckerDocumentTag();
+    virtual bool shouldBeginEditing(Range*);
+    virtual bool shouldEndEditing(Range*);
+    virtual bool shouldInsertNode(Node*, Range*, EditorInsertAction);
+    virtual bool shouldInsertText(const String&, Range*, EditorInsertAction);
+    virtual bool shouldChangeSelectedRange(Range*, Range*, EAffinity, bool);
+    virtual bool shouldApplyStyle(CSSStyleDeclaration*, Range*);
+    virtual bool shouldMoveRangeAfterDelete(Range*, Range*);
+    virtual void didBeginEditing();
+    virtual void respondToChangedContents();
+    virtual void respondToChangedSelection(Frame*);
+    virtual void respondToSelectionAppearanceChange();
+    virtual void didEndEditing();
+    virtual void didWriteSelectionToPasteboard();
+    virtual void didSetSelectionTypesForPasteboard();
+    virtual void registerCommandForUndo(PassRefPtr<EditCommand>);
+    virtual void registerCommandForRedo(PassRefPtr<EditCommand>);
+    virtual void clearUndoRedoOperations();
+    virtual bool canCopyCut(Frame*, bool) const;
+    virtual bool canPaste(Frame*, bool) const;
+    virtual bool canUndo() const;
+    virtual bool canRedo() const;
+    virtual void undo();
+    virtual void redo();
+    virtual const char* interpretKeyEvent(const KeyboardEvent*);
+    virtual void handleKeyboardEvent(KeyboardEvent*);
+    virtual void handleInputMethodKeydown(KeyboardEvent*);
+    virtual void textFieldDidBeginEditing(Element*);
+    virtual void textFieldDidEndEditing(Element*);
+    virtual void textDidChangeInTextField(Element*);
+    virtual bool doTextFieldCommandFromEvent(Element*, KeyboardEvent*);
+    virtual void textWillBeDeletedInTextField(Element*);
+    virtual void textDidChangeInTextArea(Element*);
+    virtual void ignoreWordInSpellDocument(const String&);
+    virtual void learnWord(const String&);
+    virtual void checkSpellingOfString(const UChar*, int, int*, int*);
+    virtual String getAutoCorrectSuggestionForMisspelledWord(const String& misspelledWord);
+    virtual void checkGrammarOfString(const UChar*, int, Vector<GrammarDetail, 0u>&, int*, int*);
+    virtual void getGuessesForWord(const String&, const String&, Vector<String>&);
+    virtual void requestCheckingOfString(SpellChecker*, int, TextCheckingTypeMask, const String&);
+
+    virtual TextCheckerClient* textChecker();
+    virtual void updateSpellingUIWithGrammarString(const String&, const GrammarDetail&);
+    virtual void updateSpellingUIWithMisspelledWord(const String&);
+    virtual void showSpellingUI(bool);
+    virtual bool spellingUIIsShowing();
+    virtual void getGuessesForWord(const String&, Vector<String, 0u>&);
+    virtual void willSetInputMethodState();
+    virtual void setInputMethodState(bool);
+
+    void enableSpellChecking(bool);
+
+private:
+    bool shouldSpellCheckFocusedField();
+
+    BlackBerry::WebKit::WebPagePrivate* m_webPagePrivate;
+    bool m_waitingForCursorFocus;
+
+    enum SpellCheckState { SpellCheckDefault, SpellCheckOn, SpellCheckOff };
+    SpellCheckState m_spellCheckState;
+
+    bool m_inRedo;
+
+    typedef Deque<RefPtr<WebCore::EditCommand> > EditCommandStack;
+    EditCommandStack m_undoStack;
+    EditCommandStack m_redoStack;
+};
+
+} // WebCore
+
+#endif // EditorClientBlackBerry_h