summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Source/WebKit/android/jni/WebViewCore.cpp161
-rw-r--r--Source/WebKit/android/jni/WebViewCore.h18
-rw-r--r--Source/WebKit/android/nav/WebView.cpp21
3 files changed, 200 insertions, 0 deletions
diff --git a/Source/WebKit/android/jni/WebViewCore.cpp b/Source/WebKit/android/jni/WebViewCore.cpp
index 703f177..e429ae8 100644
--- a/Source/WebKit/android/jni/WebViewCore.cpp
+++ b/Source/WebKit/android/jni/WebViewCore.cpp
@@ -114,6 +114,7 @@
#include "SkPicture.h"
#include "SkUtils.h"
#include "Text.h"
+#include "TextIterator.h"
#include "TypingCommand.h"
#include "WebCache.h"
#include "WebCoreFrameBridge.h"
@@ -3997,6 +3998,137 @@ void WebViewCore::scrollRenderLayer(int layer, const SkRect& rect)
#endif
}
+Vector<VisibleSelection> WebViewCore::getTextRanges(
+ int startX, int startY, int endX, int endY)
+{
+ // These are the positions of the selection handles,
+ // which reside below the line that they are selecting.
+ // Use the vertical position higher, which will include
+ // the selected text.
+ startY--;
+ endY--;
+ VisiblePosition startSelect = visiblePositionForWindowPoint(
+ startX - m_scrollOffsetX, startY - m_scrollOffsetY);
+ VisiblePosition endSelect = visiblePositionForWindowPoint(
+ endX - m_scrollOffsetX, endY - m_scrollOffsetY);
+ Position start = startSelect.deepEquivalent();
+ Position end = endSelect.deepEquivalent();
+ Vector<VisibleSelection> ranges;
+ if (!start.isNull() && !end.isNull()) {
+ if (comparePositions(start, end) > 0) {
+ swap(start, end); // RTL start/end positions may be swapped
+ }
+ Position nextRangeStart = start;
+ Position previousRangeEnd;
+ int i = 0;
+ do {
+ VisibleSelection selection(nextRangeStart, end);
+ ranges.append(selection);
+ previousRangeEnd = selection.end();
+ nextRangeStart = nextCandidate(previousRangeEnd);
+ } while (comparePositions(previousRangeEnd, end) < 0);
+ }
+ return ranges;
+}
+
+void WebViewCore::deleteText(int startX, int startY, int endX, int endY)
+{
+ Vector<VisibleSelection> ranges =
+ getTextRanges(startX, startY, endX, endY);
+
+ EditorClientAndroid* client = static_cast<EditorClientAndroid*>(
+ m_mainFrame->editor()->client());
+ client->setUiGeneratedSelectionChange(true);
+
+ SelectionController* selector = m_mainFrame->selection();
+ for (size_t i = 0; i < ranges.size(); i++) {
+ const VisibleSelection& selection = ranges[i];
+ if (selection.isContentEditable()) {
+ selector->setSelection(selection, CharacterGranularity);
+ Document* document = selection.start().anchorNode()->document();
+ WebCore::TypingCommand::deleteSelection(document, 0);
+ }
+ }
+ client->setUiGeneratedSelectionChange(false);
+}
+
+void WebViewCore::insertText(const WTF::String &text)
+{
+ WebCore::Node* focus = currentFocus();
+ if (!focus || !isTextInput(focus))
+ return;
+
+ Document* document = focus->document();
+ Frame* frame = document->frame();
+
+ EditorClientAndroid* client = static_cast<EditorClientAndroid*>(
+ m_mainFrame->editor()->client());
+ if (!client)
+ return;
+ client->setUiGeneratedSelectionChange(true);
+ WebCore::TypingCommand::insertText(document, text,
+ TypingCommand::PreventSpellChecking);
+ client->setUiGeneratedSelectionChange(false);
+}
+
+String WebViewCore::getText(int startX, int startY, int endX, int endY)
+{
+ String text;
+
+ Vector<VisibleSelection> ranges =
+ getTextRanges(startX, startY, endX, endY);
+
+ for (size_t i = 0; i < ranges.size(); i++) {
+ const VisibleSelection& selection = ranges[i];
+ PassRefPtr<Range> range = selection.firstRange();
+ String textInRange = range->text();
+ if (textInRange.length() > 0) {
+ if (text.length() > 0)
+ text.append('\n');
+ text.append(textInRange);
+ }
+ }
+
+ return text;
+}
+
+VisiblePosition WebViewCore::visiblePositionForWindowPoint(int x, int y)
+{
+ HitTestRequest::HitTestRequestType hitType = HitTestRequest::MouseMove;
+ hitType |= HitTestRequest::ReadOnly;
+ hitType |= HitTestRequest::Active;
+ HitTestRequest request(hitType);
+ FrameView* view = m_mainFrame->view();
+ IntPoint point(view->windowToContents(
+ view->convertFromContainingWindow(IntPoint(x, y))));
+
+ // Look for the inner-most frame containing the hit. Its document
+ // contains the document with the selected text.
+ Frame* frame = m_mainFrame;
+ Frame* hitFrame = m_mainFrame;
+ Node* node = 0;
+ IntPoint localPoint = point;
+ do {
+ HitTestResult result(localPoint);
+ frame = hitFrame;
+ frame->document()->renderView()->layer()->hitTest(request, result);
+ node = result.innerNode();
+ if (!node)
+ return VisiblePosition();
+
+ if (node->isFrameOwnerElement())
+ hitFrame = static_cast<HTMLFrameOwnerElement*>(node)->contentFrame();
+ localPoint = result.localPoint();
+ } while (hitFrame && hitFrame != frame);
+
+ Element* element = node->parentElement();
+ if (!node->inDocument() && element && element->inDocument())
+ node = element;
+
+ RenderObject* renderer = node->renderer();
+ return renderer->positionForPoint(localPoint);
+}
+
//----------------------------------------------------------------------
// Native JNI methods
//----------------------------------------------------------------------
@@ -4634,6 +4766,29 @@ static void ScrollRenderLayer(JNIEnv* env, jobject obj, jint nativeClass,
reinterpret_cast<WebViewCore*>(nativeClass)->scrollRenderLayer(layer, rect);
}
+static void DeleteText(JNIEnv* env, jobject obj, jint nativeClass,
+ jint startX, jint startY, jint endX, jint endY)
+{
+ WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
+ viewImpl->deleteText(startX, startY, endX, endY);
+}
+
+static void InsertText(JNIEnv* env, jobject obj, jint nativeClass,
+ jstring text)
+{
+ WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
+ WTF::String wtfText = jstringToWtfString(env, text);
+ viewImpl->insertText(wtfText);
+}
+
+static jobject GetText(JNIEnv* env, jobject obj, jint nativeClass,
+ jint startX, jint startY, jint endX, jint endY)
+{
+ WebViewCore* viewImpl = reinterpret_cast<WebViewCore*>(nativeClass);
+ WTF::String text = viewImpl->getText(startX, startY, endX, endY);
+ return text.isEmpty() ? 0 : wtfStringToJstring(env, text);
+}
+
// ----------------------------------------------------------------------------
/*
@@ -4752,6 +4907,12 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) ScrollRenderLayer },
{ "nativeCloseIdleConnections", "(I)V",
(void*) CloseIdleConnections },
+ { "nativeDeleteText", "(IIIII)V",
+ (void*) DeleteText },
+ { "nativeInsertText", "(ILjava/lang/String;)V",
+ (void*) InsertText },
+ { "nativeGetText", "(IIIII)Ljava/lang/String;",
+ (void*) GetText },
};
int registerWebViewCore(JNIEnv* env)
diff --git a/Source/WebKit/android/jni/WebViewCore.h b/Source/WebKit/android/jni/WebViewCore.h
index 06f6b97..d753b6d 100644
--- a/Source/WebKit/android/jni/WebViewCore.h
+++ b/Source/WebKit/android/jni/WebViewCore.h
@@ -43,6 +43,7 @@
#include "WebCoreJni.h"
#include "WebRequestContext.h"
#include "android_npapi.h"
+#include "VisiblePosition.h"
#include <jni.h>
#include <ui/KeycodeLabels.h>
@@ -560,6 +561,10 @@ namespace android {
void notifyWebAppCanBeInstalled();
+ void deleteText(int startX, int startY, int endX, int endY);
+ WTF::String getText(int startX, int startY, int endX, int endY);
+ void insertText(const WTF::String &text);
+
#if ENABLE(VIDEO)
void enterFullscreenForVideoLayer(int layerId, const WTF::String& url);
void exitFullscreenVideo();
@@ -597,6 +602,19 @@ namespace android {
// Check whether a media mimeType is supported in Android media framework.
static bool isSupportedMediaMimeType(const WTF::String& mimeType);
+ /**
+ * Returns all text ranges consumed by the cursor points referred
+ * to by startX, startY, endX, and endY. The vector will be empty
+ * if no text is in the given area or if the positions are invalid.
+ */
+ Vector<WebCore::VisibleSelection> getTextRanges(
+ int startX, int startY, int endX, int endY);
+
+ /**
+ * Returns a text position at a given coordinate.
+ */
+ WebCore::VisiblePosition visiblePositionForWindowPoint(int x, int y);
+
// these members are shared with webview.cpp
static Mutex gFrameCacheMutex;
CachedRoot* m_frameCacheKit; // nav data being built by webcore
diff --git a/Source/WebKit/android/nav/WebView.cpp b/Source/WebKit/android/nav/WebView.cpp
index 2a7a97a..1501a12 100644
--- a/Source/WebKit/android/nav/WebView.cpp
+++ b/Source/WebKit/android/nav/WebView.cpp
@@ -1983,6 +1983,25 @@ static jint nativeFocusCandidateFramePointer(JNIEnv *env, jobject obj)
return reinterpret_cast<int>(frame ? frame->framePointer() : 0);
}
+static bool nativeFocusCandidateIsEditableText(JNIEnv* env, jobject obj,
+ jint nativeClass)
+{
+ WebView* view = reinterpret_cast<WebView*>(nativeClass);
+ CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
+ bool isEditable = false;
+ if (root) {
+ const CachedFrame* frame = NULL;
+ const CachedNode* cursor = root->currentCursor(&frame);
+ const CachedNode* focus = cursor;
+ if (!cursor || !cursor->wantsKeyEvents())
+ focus = root->currentFocus(&frame);
+ if (focus) {
+ isEditable = (focus->isTextInput() || focus->isContentEditable());
+ }
+ }
+ return isEditable;
+}
+
static bool nativeFocusCandidateIsPassword(JNIEnv *env, jobject obj)
{
const CachedInput* input = getInputCandidate(env, obj);
@@ -2948,6 +2967,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeSetPauseDrawing },
{ "nativeDisableNavcache", "()Z",
(void*) nativeDisableNavcache },
+ { "nativeFocusCandidateIsEditableText", "(I)Z",
+ (void*) nativeFocusCandidateIsEditableText },
};
int registerWebView(JNIEnv* env)