summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WebKit/android/jni/WebViewCore.cpp79
-rw-r--r--WebKit/android/jni/WebViewCore.h17
-rw-r--r--WebKit/android/nav/WebView.cpp15
3 files changed, 108 insertions, 3 deletions
diff --git a/WebKit/android/jni/WebViewCore.cpp b/WebKit/android/jni/WebViewCore.cpp
index 9c3f0a1..f7f1058 100644
--- a/WebKit/android/jni/WebViewCore.cpp
+++ b/WebKit/android/jni/WebViewCore.cpp
@@ -2037,6 +2037,61 @@ String WebViewCore::modifySelection(const int direction, const int axis)
}
}
+String WebViewCore::moveSelection(WebCore::Frame* frame, WebCore::Node* node)
+{
+ if (!frame || !node)
+ return String();
+
+ if (!CacheBuilder::validNode(m_mainFrame, frame, node))
+ return String();
+
+ PassRefPtr<Range> rangeRef = 0;
+ ExceptionCode ec = 0;
+ DOMSelection* selection = frame->domWindow()->getSelection();
+ if (selection->rangeCount() > 0) {
+ rangeRef = selection->getRangeAt(0, ec);
+ if (ec)
+ return String();
+ selection->removeAllRanges();
+ } else {
+ rangeRef = frame->document()->createRange();
+ }
+
+ rangeRef->selectNode(node, ec);
+ if (ec)
+ return String();
+
+ selection->addRange(rangeRef.get());
+
+ scrollNodeIntoView(frame, node);
+
+ String markup = formatMarkup(selection).stripWhiteSpace();
+ LOGV("Selection markup: %s", markup.utf8().data());
+ return markup;
+}
+
+void WebViewCore::scrollNodeIntoView(Frame* frame, Node* node)
+{
+ if (!frame || !node)
+ return;
+
+ Element* elementNode = 0;
+
+ // If not an Element, find a visible predecessor
+ // Element to scroll into view.
+ if (!node->isElementNode()) {
+ HTMLElement* body = frame->document()->body();
+ do {
+ if (!node || node == body)
+ return;
+ node = node->parentNode();
+ } while (!node->isElementNode() && !isVisible(node));
+ }
+
+ elementNode = static_cast<Element*>(node);
+ elementNode->scrollIntoViewIfNeeded(true);
+}
+
String WebViewCore::modifySelectionTextNavigationAxis(DOMSelection* selection, int direction, int axis)
{
String directionString;
@@ -2166,10 +2221,14 @@ String WebViewCore::modifySelectionTextNavigationAxis(DOMSelection* selection, i
}
}
+ if (direction == DIRECTION_FORWARD)
+ scrollNodeIntoView(m_mainFrame, selection->focusNode());
+ else
+ scrollNodeIntoView(m_mainFrame, selection->anchorNode());
+
tryFocusInlineSelectionElement(selection);
- // TODO (svetoslavganov): Draw the selected text in the WebView - a-la-Android
String markup = formatMarkup(selection).stripWhiteSpace();
- LOGD("Selection markup: %s", markup.utf8().data());
+ LOGV("Selection markup: %s", markup.utf8().data());
return markup;
}
@@ -2284,10 +2343,11 @@ String WebViewCore::modifySelectionDomNavigationAxis(DOMSelection* selection, in
}
if (currentNode) {
m_currentNodeDomNavigationAxis = currentNode;
+ scrollNodeIntoView(m_mainFrame, currentNode);
focusIfFocusableAndNotTextInput(selection, currentNode);
// TODO (svetoslavganov): Draw the selected text in the WebView - a-la-Android
String selectionString = createMarkup(currentNode);
- LOGD("Selection markup: %s", selectionString.utf8().data());
+ LOGV("Selection markup: %s", selectionString.utf8().data());
return selectionString;
}
return String();
@@ -3523,6 +3583,17 @@ static jstring ModifySelection(JNIEnv *env, jobject obj, jint direction, jint gr
return wtfStringToJstring(env, selectionString);
}
+static jstring MoveSelection(JNIEnv *env, jobject obj, jint framePtr, jint nodePtr)
+{
+#ifdef ANDROID_INSTRUMENT
+ TimeCounterAuto counter(TimeCounter::WebViewCoreTimeCounter);
+#endif
+ WebViewCore* viewImpl = GET_NATIVE_VIEW(env, obj);
+ String selectionString = viewImpl->moveSelection((WebCore::Frame*) framePtr,
+ (WebCore::Node*) nodePtr);
+ return wtfStringToJstring(env, selectionString);
+}
+
static void ReplaceTextfieldText(JNIEnv *env, jobject obj,
jint oldStart, jint oldEnd, jstring replace, jint start, jint end,
jint textGeneration)
@@ -4107,6 +4178,8 @@ static JNINativeMethod gJavaWebViewCoreMethods[] = {
(void*) SetSelection } ,
{ "nativeModifySelection", "(II)Ljava/lang/String;",
(void*) ModifySelection },
+ { "nativeMoveSelection", "(II)Ljava/lang/String;",
+ (void*) MoveSelection },
{ "nativeDeleteSelection", "(III)V",
(void*) DeleteSelection } ,
{ "nativeReplaceTextfieldText", "(IILjava/lang/String;III)V",
diff --git a/WebKit/android/jni/WebViewCore.h b/WebKit/android/jni/WebViewCore.h
index b13e3a5..fa474ce 100644
--- a/WebKit/android/jni/WebViewCore.h
+++ b/WebKit/android/jni/WebViewCore.h
@@ -364,6 +364,8 @@ namespace android {
/**
* Modifies the current selection.
*
+ * Note: Accessibility support.
+ *
* direction - The direction in which to alter the selection.
* granularity - The granularity of the selection modification.
*
@@ -374,6 +376,20 @@ namespace android {
String modifySelection(const int direction, const int granularity);
/**
+ * Moves the selection to the given node in a given frame i.e. selects that node.
+ *
+ * Note: Accessibility support.
+ *
+ * frame - The frame in which to select is the node to be selected.
+ * node - The node to be selected.
+ *
+ * returns - The selected HTML as a string. This is not a well formed
+ * HTML, rather the selection annotated with the tags of all
+ * intermediary elements it crosses.
+ */
+ String moveSelection(WebCore::Frame* frame, WebCore::Node* node);
+
+ /**
* In the currently focused textfield, replace the characters from oldStart to oldEnd
* (if oldStart == oldEnd, this will be an insert at that position) with replace,
* and set the selection to (start, end).
@@ -632,6 +648,7 @@ namespace android {
bool setSelection(DOMSelection* selection, Text* textNode, int direction);
bool setSelection(DOMSelection* selection, Node* startNode, Node* endNode, int startOffset, int endOffset);
Node* m_currentNodeDomNavigationAxis;
+ void scrollNodeIntoView(Frame* frame, Node* node);
#if ENABLE(TOUCH_EVENTS)
bool m_forwardingTouchEvents;
#endif
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 4b0f21d..862b99b 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -113,6 +113,7 @@ struct JavaGlue {
jmethodID m_sendMoveFocus;
jmethodID m_sendMoveMouse;
jmethodID m_sendMoveMouseIfLatest;
+ jmethodID m_sendMoveSelection;
jmethodID m_sendMotionUp;
jmethodID m_domChangedFocus;
jmethodID m_getScaledMaxXScroll;
@@ -147,6 +148,7 @@ WebView(JNIEnv* env, jobject javaWebView, int viewImpl) :
m_javaGlue.m_sendMoveFocus = GetJMethod(env, clazz, "sendMoveFocus", "(II)V");
m_javaGlue.m_sendMoveMouse = GetJMethod(env, clazz, "sendMoveMouse", "(IIII)V");
m_javaGlue.m_sendMoveMouseIfLatest = GetJMethod(env, clazz, "sendMoveMouseIfLatest", "(Z)V");
+ m_javaGlue.m_sendMoveSelection = GetJMethod(env, clazz, "sendMoveSelection", "(II)V");
m_javaGlue.m_sendMotionUp = GetJMethod(env, clazz, "sendMotionUp", "(IIIII)V");
m_javaGlue.m_domChangedFocus = GetJMethod(env, clazz, "domChangedFocus", "()V");
m_javaGlue.m_getScaledMaxXScroll = GetJMethod(env, clazz, "getScaledMaxXScroll", "()I");
@@ -841,6 +843,8 @@ bool moveCursor(int keyCode, int count, bool ignoreScroll)
bool disableFocusController = cachedNode != root->currentFocus()
&& cachedNode->wantsKeyEvents();
sendMoveMouseIfLatest(disableFocusController);
+ sendMoveSelection((WebCore::Frame*) cachedFrame->framePointer(),
+ (WebCore::Node*) cachedNode->nodePointer());
} else {
int docHeight = root->documentHeight();
int docWidth = root->documentWidth();
@@ -917,6 +921,8 @@ void selectBestAt(const WebCore::IntRect& rect)
const_cast<CachedNode*>(node));
}
sendMoveMouseIfLatest(false);
+ sendMoveSelection((WebCore::Frame*) frame->framePointer(),
+ (WebCore::Node*) node->nodePointer());
}
const CachedNode* m_cacheHitNode;
@@ -1178,6 +1184,15 @@ void sendMoveMouseIfLatest(bool disableFocusController)
checkException(env);
}
+void sendMoveSelection(WebCore::Frame* frame, WebCore::Node* node)
+{
+ DBG_NAV_LOGD("framePtr=%p nodePtr=%p x=%d y=%d", frame, node);
+ JNIEnv* env = JSC::Bindings::getJNIEnv();
+ env->CallVoidMethod(m_javaGlue.object(env).get(),
+ m_javaGlue.m_sendMoveSelection, (jint) frame, (jint) node);
+ checkException(env);
+}
+
void sendMotionUp(
WebCore::Frame* framePtr, WebCore::Node* nodePtr, int x, int y)
{