diff options
author | Leon Scroggins <scroggo@google.com> | 2010-05-03 14:21:02 +0100 |
---|---|---|
committer | Leon Scroggins <scroggo@google.com> | 2010-05-05 14:56:43 -0400 |
commit | 1cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8 (patch) | |
tree | 6b54bab07b61f358f3fd0edc52bc135946a299d3 /WebKit | |
parent | 7e3fdd33ac8153016019ccdc7b5bb9ec788776fa (diff) | |
download | external_webkit-1cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8.zip external_webkit-1cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8.tar.gz external_webkit-1cc2f5523913bd14a01c0c85710dcd6f0d7b5bb8.tar.bz2 |
Enable contentEditable.
WebViewCore.cpp:
Open the keyboard when a contentEditable element is put
into focus by a click.
In key(), return whether the selection changed if a contentEditable
element is in focus.
CacheBuilder.cpp:
Add root contentEditable elements to the navigation tree.
CachedNode.h:
Include contentEditable elements as elements that want key events.
CachedNodeType.h
Add a type for contentEditable.
WebView.cpp:
Do not call setFollowedLink for contentEditable, so that the orange
selection ring stays around the field.
Add a check to determine whether the page should handle shift and
arrow keys.
Bug 1788820
Caveats:
Does not ensure that the caret remains on screen. Frame::revealSelection
is called, but we ignore it for other reasons. Need to investigate that.
The cursor will blink if the contentEditable node has focus, even if the
user has not clicked on it or has moved to a different input field. Further,
while in this state, the user can input text.
Requires a change to frameworks/base
Change-Id: Ife39254f46dcc1046a075eee2fda6cf4879b4ee8
Diffstat (limited to 'WebKit')
-rw-r--r-- | WebKit/android/jni/WebViewCore.cpp | 22 | ||||
-rw-r--r-- | WebKit/android/nav/CacheBuilder.cpp | 7 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNode.h | 3 | ||||
-rw-r--r-- | WebKit/android/nav/CachedNodeType.h | 3 | ||||
-rw-r--r-- | WebKit/android/nav/WebView.cpp | 19 |
5 files changed, 47 insertions, 7 deletions
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp index 14fd44e..56b0601 100644 --- a/WebKit/android/jni/WebViewCore.cpp +++ b/WebKit/android/jni/WebViewCore.cpp @@ -1985,12 +1985,25 @@ void WebViewCore::listBoxRequest(WebCoreReply* reply, const uint16_t** labels, s bool WebViewCore::key(const PlatformKeyboardEvent& event) { - WebCore::EventHandler* eventHandler = m_mainFrame->eventHandler(); + WebCore::EventHandler* eventHandler; WebCore::Node* focusNode = currentFocus(); - if (focusNode) - eventHandler = focusNode->document()->frame()->eventHandler(); DBG_NAV_LOGD("keyCode=%s unichar=%d focusNode=%p", event.keyIdentifier().utf8().data(), event.unichar(), focusNode); + if (focusNode) { + WebCore::Frame* frame = focusNode->document()->frame(); + eventHandler = frame->eventHandler(); + if (focusNode->isContentEditable()) { + // keyEvent will return true even if the contentEditable did not + // change its selection. In the case that it does not, we want to + // return false so that the key will be sent back to our navigation + // system. + VisibleSelection old = frame->selection()->selection(); + eventHandler->keyEvent(event); + return frame->selection()->selection() != old; + } + } else { + eventHandler = m_mainFrame->eventHandler(); + } return eventHandler->keyEvent(event); } @@ -2195,6 +2208,9 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node } else { requestKeyboard(false); } + } else if (focusNode->isContentEditable()) { + setFocusControllerActive(framePtr, true); + requestKeyboard(true); } } return handled; diff --git a/WebKit/android/nav/CacheBuilder.cpp b/WebKit/android/nav/CacheBuilder.cpp index b98b31f..c5f7b12 100644 --- a/WebKit/android/nav/CacheBuilder.cpp +++ b/WebKit/android/nav/CacheBuilder.cpp @@ -1112,6 +1112,13 @@ void CacheBuilder::BuildFrame(Frame* root, Frame* frame, type = PLUGIN_CACHEDNODETYPE; goto keepNode; } + // Only use the root contentEditable element + if (node->isContentEditable() && !node->parent()->isContentEditable()) { + bounds = absBounds; + takesFocus = true; + type = CONTENT_EDITABLE_CACHEDNODETYPE; + goto keepNode; + } if (nodeRenderer->isRenderBlock()) { RenderBlock* renderBlock = (RenderBlock*) nodeRenderer; if (renderBlock->hasColumns()) { diff --git a/WebKit/android/nav/CachedNode.h b/WebKit/android/nav/CachedNode.h index b707ac1..09f53c3 100644 --- a/WebKit/android/nav/CachedNode.h +++ b/WebKit/android/nav/CachedNode.h @@ -108,6 +108,7 @@ public: int index() const { return mIndex; } void init(WebCore::Node* node); bool isAnchor() const { return mType == ANCHOR_CACHEDNODETYPE; } + bool isContentEditable() const { return mType == CONTENT_EDITABLE_CACHEDNODETYPE; } bool isCursor() const { return mIsCursor; } bool isArea() const { return mType == AREA_CACHEDNODETYPE; } bool isFocus() const { return mIsFocus; } @@ -174,7 +175,7 @@ public: const CachedNode* traverseNextNode() const { return mLast ? NULL : &this[1]; } bool useBounds() const { return mUseBounds; } bool useHitBounds() const { return mUseHitBounds; } - bool wantsKeyEvents() const { return isTextInput() || isPlugin(); } + bool wantsKeyEvents() const { return isTextInput() || isPlugin() || isContentEditable(); } private: friend class CacheBuilder; WebCore::String mExport; diff --git a/WebKit/android/nav/CachedNodeType.h b/WebKit/android/nav/CachedNodeType.h index 8334b2f..8bc9328 100644 --- a/WebKit/android/nav/CachedNodeType.h +++ b/WebKit/android/nav/CachedNodeType.h @@ -38,7 +38,8 @@ enum CachedNodeType { FRAME_CACHEDNODETYPE, PLUGIN_CACHEDNODETYPE, TEXT_INPUT_CACHEDNODETYPE, - SELECT_CACHEDNODETYPE + SELECT_CACHEDNODETYPE, + CONTENT_EDITABLE_CACHEDNODETYPE }; enum CachedNodeBits { diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp index d5c0758..fff0ea3 100644 --- a/WebKit/android/nav/WebView.cpp +++ b/WebKit/android/nav/WebView.cpp @@ -882,7 +882,7 @@ bool motionUp(int x, int y, int slop) viewInvalidate(); if (!result->isTextInput()) { clearTextEntry(); - if (!result->isSelect()) + if (!result->isSelect() && !result->isContentEditable()) setFollowedLink(true); if (syntheticLink) overrideUrlLoading(result->getExport()); @@ -1263,6 +1263,19 @@ static const CachedInput* getInputCandidate(JNIEnv *env, jobject obj) return cursor ? frame->textInput(cursor) : 0; } +static jboolean nativePageShouldHandleShiftAndArrows(JNIEnv *env, jobject obj) +{ + const CachedNode* focus = getFocusNode(env, obj); + if (!focus) return false; + // Plugins handle shift and arrows whether or not they have focus. + if (focus->isPlugin()) return true; + const CachedNode* cursor = getCursorNode(env, obj); + // ContentEditable nodes should only receive shift and arrows if they have + // both the cursor and the focus. + return cursor && cursor->nodePointer() == focus->nodePointer() + && cursor->isContentEditable(); +} + static jboolean nativeCursorMatchesFocus(JNIEnv *env, jobject obj) { const CachedNode* cursor = getCursorNode(env, obj); @@ -1636,7 +1649,7 @@ static void nativeSetFindIsEmpty(JNIEnv *env, jobject obj) static void nativeSetFollowedLink(JNIEnv *env, jobject obj, bool followed) { const CachedNode* cursor = getCursorNode(env, obj); - if (cursor && !cursor->isSelect()) { + if (cursor && !cursor->isSelect() && ! cursor->isContentEditable()) { WebView* view = GET_NATIVE_VIEW(env, obj); LOG_ASSERT(view, "view not set in %s", __FUNCTION__); view->setFollowedLink(followed); @@ -1901,6 +1914,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeCreate }, { "nativeCursorFramePointer", "()I", (void*) nativeCursorFramePointer }, + { "nativePageShouldHandleShiftAndArrows", "()Z", + (void*) nativePageShouldHandleShiftAndArrows }, { "nativeCursorMatchesFocus", "()Z", (void*) nativeCursorMatchesFocus }, { "nativeCursorNodeBounds", "()Landroid/graphics/Rect;", |