diff options
author | George Mount <mount@google.com> | 2012-03-01 08:38:30 -0800 |
---|---|---|
committer | George Mount <mount@google.com> | 2012-03-09 15:06:39 -0800 |
commit | 730ac8198c5c9a59a2b11e54657155f3ea33d83f (patch) | |
tree | c529fe2e227312b5b51fb5f745e57d36e8d962f3 /Source | |
parent | ddacf299acbe17093f175cec8d86088ea3472793 (diff) | |
download | external_webkit-730ac8198c5c9a59a2b11e54657155f3ea33d83f.zip external_webkit-730ac8198c5c9a59a2b11e54657155f3ea33d83f.tar.gz external_webkit-730ac8198c5c9a59a2b11e54657155f3ea33d83f.tar.bz2 |
Add back auto-completion and auto-fill.
Bug 5993316
Framework Change: If00d42c0cb4f2c207f0d502e297741e1d6a68bf4
Change-Id: I9d09a924a579d2d4551bff0489670de71d04757e
Diffstat (limited to 'Source')
-rw-r--r-- | Source/WebKit/android/jni/WebCoreJni.cpp | 10 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebCoreJni.h | 1 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.cpp | 129 | ||||
-rw-r--r-- | Source/WebKit/android/jni/WebViewCore.h | 11 | ||||
-rw-r--r-- | Source/WebKit/android/nav/WebView.cpp | 21 |
5 files changed, 129 insertions, 43 deletions
diff --git a/Source/WebKit/android/jni/WebCoreJni.cpp b/Source/WebKit/android/jni/WebCoreJni.cpp index 5a142c8..6dfc9f1 100644 --- a/Source/WebKit/android/jni/WebCoreJni.cpp +++ b/Source/WebKit/android/jni/WebCoreJni.cpp @@ -112,6 +112,16 @@ jstring stdStringToJstring(JNIEnv* env, const std::string& str, bool validOnZero return !str.empty() || validOnZeroLength ? env->NewStringUTF(str.c_str()) : 0; } +jobject intRectToRect(JNIEnv* env, const WebCore::IntRect& rect) +{ + jclass rectClass = env->FindClass("android/graphics/Rect"); + ALOG_ASSERT(rectClass, "Could not find android/graphics/Rect"); + jmethodID rectInit = env->GetMethodID(rectClass, "<init>", "(IIII)V"); + ALOG_ASSERT(rectInit, "Could not find init method on Rect"); + return env->NewObject(rectClass, rectInit, rect.x(), rect.y(), + rect.maxX(), rect.maxY()); +} + jobjectArray intRectVectorToRectArray(JNIEnv* env, Vector<WebCore::IntRect>& rects) { jclass rectClass = env->FindClass("android/graphics/Rect"); diff --git a/Source/WebKit/android/jni/WebCoreJni.h b/Source/WebKit/android/jni/WebCoreJni.h index 25aa986..e8cc6ea 100644 --- a/Source/WebKit/android/jni/WebCoreJni.h +++ b/Source/WebKit/android/jni/WebCoreJni.h @@ -92,6 +92,7 @@ jstring stdStringToJstring(JNIEnv*, const std::string&, bool validOnZeroLength = jobjectArray intRectVectorToRectArray(JNIEnv*, Vector<WebCore::IntRect>&); +jobject intRectToRect(JNIEnv* env, const WebCore::IntRect& rect); } #endif diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp index af25b3b..879c007 100644 --- a/Source/WebKit/android/jni/WebViewCore.cpp +++ b/Source/WebKit/android/jni/WebViewCore.cpp @@ -122,6 +122,7 @@ #include "TypingCommand.h" #include "WebCache.h" #include "WebCoreFrameBridge.h" +#include "WebCoreJni.h" #include "WebFrameView.h" #include "WindowsKeyboardCodes.h" #include "android_graphics.h" @@ -462,7 +463,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m m_javaGlue->m_getDeviceOrientationService = GetJMethod(env, clazz, "getDeviceOrientationService", "()Landroid/webkit/DeviceOrientationService;"); m_javaGlue->m_addMessageToConsole = GetJMethod(env, clazz, "addMessageToConsole", "(Ljava/lang/String;ILjava/lang/String;I)V"); m_javaGlue->m_formDidBlur = GetJMethod(env, clazz, "formDidBlur", "(I)V"); - m_javaGlue->m_focusNodeChanged = GetJMethod(env, clazz, "focusNodeChanged", "(Landroid/webkit/WebViewCore$WebKitHitTest;)V"); + m_javaGlue->m_focusNodeChanged = GetJMethod(env, clazz, "focusNodeChanged", "(ILandroid/webkit/WebViewCore$WebKitHitTest;)V"); m_javaGlue->m_getPluginClass = GetJMethod(env, clazz, "getPluginClass", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Class;"); m_javaGlue->m_showFullScreenPlugin = GetJMethod(env, clazz, "showFullScreenPlugin", "(Landroid/webkit/ViewManager$ChildView;II)V"); m_javaGlue->m_hideFullScreenPlugin = GetJMethod(env, clazz, "hideFullScreenPlugin", "()V"); @@ -482,7 +483,7 @@ WebViewCore::WebViewCore(JNIEnv* env, jobject javaWebViewCore, WebCore::Frame* m #endif m_javaGlue->m_setWebTextViewAutoFillable = GetJMethod(env, clazz, "setWebTextViewAutoFillable", "(ILjava/lang/String;)V"); m_javaGlue->m_selectAt = GetJMethod(env, clazz, "selectAt", "(II)V"); - m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;IZZLjava/lang/String;IIII)V"); + m_javaGlue->m_initEditField = GetJMethod(env, clazz, "initEditField", "(ILjava/lang/String;IZZZLjava/lang/String;Ljava/lang/String;IIIILandroid/graphics/Rect;I)V"); m_javaGlue->m_updateMatchCount = GetJMethod(env, clazz, "updateMatchCount", "(IILjava/lang/String;)V"); m_javaGlue->m_chromeCanTakeFocus = GetJMethod(env, clazz, "chromeCanTakeFocus", "(I)Z"); m_javaGlue->m_chromeTakeFocus = GetJMethod(env, clazz, "chromeTakeFocus", "(I)V"); @@ -3213,41 +3214,8 @@ bool WebViewCore::handleMouseClick(WebCore::Frame* framePtr, WebCore::Node* node bool handled = framePtr->eventHandler()->handleMouseReleaseEvent(mouseUp); webFrame->setUserInitiatedAction(false); - // If the user clicked on a textfield, make the focusController active - // so we show the blinking cursor. WebCore::Node* focusNode = currentFocus(); - if (focusNode) { - WebCore::RenderTextControl* rtc = toRenderTextControl(focusNode); - if (rtc) { - bool ime = !shouldSuppressKeyboard(focusNode) - && !(static_cast<WebCore::HTMLInputElement*>(focusNode))->readOnly(); - if (ime) { -#if ENABLE(WEB_AUTOFILL) - if (rtc->isTextField()) { - EditorClientAndroid* editorC = static_cast<EditorClientAndroid*>(framePtr->page()->editorClient()); - WebAutofill* autoFill = editorC->getAutofill(); - autoFill->formFieldFocused(static_cast<HTMLFormControlElement*>(focusNode)); - } -#endif - if (!fake) - initEditField(focusNode); - } else if (!fake) { - requestKeyboard(false); - } - } else if (!fake){ - // If the selection is contentEditable, show the keyboard so the - // user can type. Otherwise hide the keyboard because no text - // input is needed. - if (isContentEditable(focusNode)) { - initEditField(focusNode); - } else if (!nodeIsPlugin(focusNode)) { - clearTextEntry(); - } - } - } else if (!fake) { - // There is no focusNode, so the keyboard is not needed. - clearTextEntry(); - } + initializeTextInput(focusNode, fake); return handled; } @@ -3291,6 +3259,16 @@ int WebViewCore::getMaxLength(Node* node) return maxLength; } +String WebViewCore::getFieldName(Node* node) +{ + String name; + if (node->hasTagName(WebCore::HTMLNames::inputTag)) { + HTMLInputElement* htmlInput = static_cast<HTMLInputElement*>(node); + name = htmlInput->name(); + } + return name; +} + bool WebViewCore::isSpellCheckEnabled(Node* node) { bool isEnabled = true; @@ -3301,6 +3279,34 @@ bool WebViewCore::isSpellCheckEnabled(Node* node) return isEnabled; } +bool WebViewCore::isAutoCompleteEnabled(Node* node) +{ + bool isEnabled = false; + if (node->hasTagName(WebCore::HTMLNames::inputTag)) { + HTMLInputElement* htmlInput = static_cast<HTMLInputElement*>(node); + isEnabled = htmlInput->autoComplete(); + } + return isEnabled; +} + +WebCore::IntRect WebViewCore::boundingRect(WebCore::Node* node, + LayerAndroid* layer) +{ + // Caret selection + IntRect boundingRect; + if (node) { + RenderObject* render = node->renderer(); + if (render && !render->isBody()) { + IntPoint offset = convertGlobalContentToFrameContent(IntPoint(), + node->document()->frame()); + WebViewCore::layerToAbsoluteOffset(layer, offset); + boundingRect = render->absoluteBoundingBoxRect(true); + boundingRect.move(-offset.x(), -offset.y()); + } + } + return boundingRect; +} + void WebViewCore::initEditField(Node* node) { String text = getInputText(node); @@ -3322,13 +3328,19 @@ void WebViewCore::initEditField(Node* node) bool spellCheckEnabled = isSpellCheckEnabled(node); int maxLength = getMaxLength(node); String label = requestLabel(document->frame(), node); + bool autoComplete = isAutoCompleteEnabled(node); + jstring name = wtfStringToJstring(env, getFieldName(node), false); jstring fieldText = wtfStringToJstring(env, text, true); jstring labelText = wtfStringToJstring(env, text, false); + LayerAndroid* layer = 0; + int layerId = platformLayerIdFromNode(node, &layer); + jobject nodeBounds = intRectToRect(env, boundingRect(node, layer)); SelectText* selectText = createSelectText(focusedFrame()->selection()->selection()); env->CallVoidMethod(javaObject.get(), m_javaGlue->m_initEditField, reinterpret_cast<int>(node), fieldText, inputType, - spellCheckEnabled, isNextText, labelText, start, end, - reinterpret_cast<int>(selectText), maxLength); + spellCheckEnabled, autoComplete, isNextText, name, labelText, + start, end, reinterpret_cast<int>(selectText), maxLength, + nodeBounds, layerId); checkException(env); } @@ -3378,13 +3390,49 @@ WebCore::Node* nextNodeWithinParent(WebCore::Node* parent, WebCore::Node* start) return 0; } +void WebViewCore::initializeTextInput(WebCore::Node* node, bool fake) +{ + if (node) { + if (isTextInput(node)) { + initEditField(node); + WebCore::RenderTextControl* rtc = toRenderTextControl(node); + if (rtc && node->hasTagName(HTMLNames::inputTag)) { + HTMLInputElement* inputElement = static_cast<HTMLInputElement*>(node); + bool ime = !shouldSuppressKeyboard(node) && !inputElement->readOnly(); + if (ime) { +#if ENABLE(WEB_AUTOFILL) + if (rtc->isTextField()) { + Page* page = node->document()->page(); + EditorClient* editorClient = page->editorClient(); + EditorClientAndroid* androidEditor = + static_cast<EditorClientAndroid*>(editorClient); + WebAutofill* autoFill = androidEditor->getAutofill(); + autoFill->formFieldFocused(inputElement); + } +#endif + } else if (!fake) { + requestKeyboard(false); + } + } + } else if (!fake && !nodeIsPlugin(node)) { + // not a text entry field, put away the keyboard. + clearTextEntry(); + } + } else if (!fake) { + // There is no focusNode, so the keyboard is not needed. + clearTextEntry(); + } +} + void WebViewCore::focusNodeChanged(WebCore::Node* newFocus) { JNIEnv* env = JSC::Bindings::getJNIEnv(); AutoJObject javaObject = m_javaGlue->object(env); if (!javaObject.get()) return; - if (!isTextInput(newFocus) && m_blurringNodePointer) { + if (isTextInput(newFocus)) + initializeTextInput(newFocus); + else if (m_blurringNodePointer) { env->CallVoidMethod(javaObject.get(), m_javaGlue->m_formDidBlur, m_blurringNodePointer); checkException(env); m_blurringNodePointer = 0; @@ -3416,7 +3464,8 @@ void WebViewCore::focusNodeChanged(WebCore::Node* newFocus) } AndroidHitTestResult androidHitTest(this, focusHitResult); jobject jHitTestObj = androidHitTest.createJavaObject(env); - env->CallVoidMethod(javaObject.get(), m_javaGlue->m_focusNodeChanged, jHitTestObj); + env->CallVoidMethod(javaObject.get(), m_javaGlue->m_focusNodeChanged, + reinterpret_cast<int>(newFocus), jHitTestObj); env->DeleteLocalRef(jHitTestObj); } diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h index c5704e0..ff55c00 100644 --- a/Source/WebKit/android/jni/WebViewCore.h +++ b/Source/WebKit/android/jni/WebViewCore.h @@ -670,6 +670,14 @@ namespace android { void initEditField(Node* node); /** + * If node is not a text input field or if it explicitly requests + * not to have keyboard input, then the soft keyboard is closed. If + * it is a text input field then initEditField is called and + * auto-fill information is requested for HTML form input fields. + */ + void initializeTextInput(Node* node, bool fake = false); + + /** * Gets the input type a Node. NONE is returned if it isn't an * input field. */ @@ -713,6 +721,9 @@ namespace android { void selectWordAroundPosition(Frame* frame, VisiblePosition pos); SelectText* createSelectText(const VisibleSelection&); static int getMaxLength(Node* node); + static String getFieldName(Node* node); + static bool isAutoCompleteEnabled(Node* node); + IntRect boundingRect(Node* node, LayerAndroid* layer); // called from constructor, to add this to a global list static void addInstance(WebViewCore*); diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp index 8b7acc5..c7f132f 100644 --- a/Source/WebKit/android/nav/WebView.cpp +++ b/Source/WebKit/android/nav/WebView.cpp @@ -617,7 +617,12 @@ int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) { if (!selectText || !m_baseLayer) return -1; int layerId = selectText->caretLayerId(handleId); - IntRect rect = selectText->caretRect(handleId); + cursorRect = selectText->caretRect(handleId); + mapLayerRect(layerId, cursorRect); + return layerId; +} + +void mapLayerRect(int layerId, SkIRect& rect) { if (layerId != -1) { // We need to make sure the drawTransform is up to date as this is // called before a draw() or drawGL() @@ -627,8 +632,6 @@ int getHandleLayerId(SelectText::HandleId handleId, SkIRect& cursorRect) { if (layer && layer->drawTransform()) rect = layer->drawTransform()->mapRect(rect); } - cursorRect.set(rect.x(), rect.y(), rect.maxX(), rect.maxY()); - return layerId; } bool m_isDrawingPaused; @@ -1184,6 +1187,16 @@ static jboolean nativeIsBaseFirst(JNIEnv *env, jobject obj, jint nativeView) return select ? select->isBaseFirst() : false; } +static void nativeMapLayerRect(JNIEnv *env, jobject obj, jint nativeView, + jint layerId, jobject rect) +{ + WebView* webview = reinterpret_cast<WebView*>(nativeView); + SkIRect nativeRect; + GraphicsJNI::jrect_to_irect(env, rect, &nativeRect); + webview->mapLayerRect(layerId, nativeRect); + GraphicsJNI::irect_to_jrect(nativeRect, env, rect); +} + /* * JNI registration */ @@ -1262,6 +1275,8 @@ static JNINativeMethod gJavaWebViewMethods[] = { (void*) nativeGetHandleLayerId }, { "nativeIsBaseFirst", "(I)Z", (void*) nativeIsBaseFirst }, + { "nativeMapLayerRect", "(IILandroid/graphics/Rect;)V", + (void*) nativeMapLayerRect }, }; int registerWebView(JNIEnv* env) |