summaryrefslogtreecommitdiffstats
path: root/WebKit
diff options
context:
space:
mode:
authorLeon Scroggins <scroggo@google.com>2009-07-30 16:29:30 -0400
committerLeon Scroggins <scroggo@google.com>2009-07-31 11:33:01 -0400
commite3635bdd4530eeff44657cb1423a0572482381ce (patch)
tree10560cd9ed79aaa8d4faac770518e7cf3982f938 /WebKit
parent7ed73b9c2878d611c2c6954665d21aa6f162d5cc (diff)
downloadexternal_webkit-e3635bdd4530eeff44657cb1423a0572482381ce.zip
external_webkit-e3635bdd4530eeff44657cb1423a0572482381ce.tar.gz
external_webkit-e3635bdd4530eeff44657cb1423a0572482381ce.tar.bz2
Allow user to jump to the next textfield.
In CachedFrame, add methods to find the next textfield and to determine which ImeAction should be associated with a given textfield. In WebView, uses these apis to determine the ImeAction and jump to the next textfield and scroll it on screen. Requires a change to frameworks/base.
Diffstat (limited to 'WebKit')
-rw-r--r--WebKit/android/nav/CachedFrame.cpp28
-rw-r--r--WebKit/android/nav/CachedFrame.h12
-rw-r--r--WebKit/android/nav/CachedRoot.cpp26
-rw-r--r--WebKit/android/nav/CachedRoot.h10
-rw-r--r--WebKit/android/nav/WebView.cpp84
5 files changed, 139 insertions, 21 deletions
diff --git a/WebKit/android/nav/CachedFrame.cpp b/WebKit/android/nav/CachedFrame.cpp
index 4bf9805..416e880 100644
--- a/WebKit/android/nav/CachedFrame.cpp
+++ b/WebKit/android/nav/CachedFrame.cpp
@@ -891,6 +891,34 @@ int CachedFrame::maxWorkingVertical() const
return history()->maxWorkingVertical();
}
+const CachedNode* CachedFrame::nextTextField(const CachedNode* start,
+ const CachedFrame** framePtr, bool includeTextAreas) const
+{
+ CachedNode* test;
+ if (start) {
+ test = const_cast<CachedNode*>(start);
+ test++;
+ } else {
+ test = const_cast<CachedNode*>(mCachedNodes.begin());
+ }
+ while (test != mCachedNodes.end()) {
+ CachedFrame* frame = const_cast<CachedFrame*>(hasFrame(test));
+ if (frame) {
+ const CachedNode* node
+ = frame->nextTextField(0, framePtr, includeTextAreas);
+ if (node)
+ return node;
+ } else if (test->isTextField()
+ || (includeTextAreas && test->isTextArea())) {
+ if (framePtr)
+ *framePtr = this;
+ return test;
+ }
+ test++;
+ }
+ return 0;
+}
+
bool CachedFrame::moveInFrame(MoveInDirection moveInDirection,
const CachedNode* test, BestData* bestData,
const CachedNode* cursor) const
diff --git a/WebKit/android/nav/CachedFrame.h b/WebKit/android/nav/CachedFrame.h
index 0df5489..fcfddb8 100644
--- a/WebKit/android/nav/CachedFrame.h
+++ b/WebKit/android/nav/CachedFrame.h
@@ -97,6 +97,18 @@ public:
const CachedFrame* lastChild() const { return &mCachedFrames.last(); }
CachedNode* lastNode() { return &mCachedNodes.last(); }
CachedFrame* lastChild() { return &mCachedFrames.last(); }
+ /**
+ * Find the next textfield/textarea
+ * @param start Must be a CachedNode in this CachedFrame's tree, or
+ * null, in which case we start from the beginning.
+ * @param framePtr If not null, and a textfield/textarea is found, its
+ * CachedFrame will be pointed to by this pointer.
+ * @param includeTextAreas If true, will return the next textfield or area.
+ * Otherwise it only considers textfields.
+ * @return CachedNode* Next textfield (or area)
+ */
+ const CachedNode* nextTextField(const CachedNode* start,
+ const CachedFrame** framePtr, bool includeTextAreas) const;
const CachedFrame* parent() const { return mParent; }
CachedFrame* parent() { return mParent; }
bool sameFrame(const CachedFrame* ) const;
diff --git a/WebKit/android/nav/CachedRoot.cpp b/WebKit/android/nav/CachedRoot.cpp
index 93b4179..cf029c2 100644
--- a/WebKit/android/nav/CachedRoot.cpp
+++ b/WebKit/android/nav/CachedRoot.cpp
@@ -738,6 +738,32 @@ bool CachedRoot::checkRings(const WTF::Vector<WebCore::IntRect>& rings,
return ringCheck.success();
}
+CachedRoot::ImeAction CachedRoot::cursorTextFieldAction() const
+{
+ const CachedFrame* cursorFrame;
+ const CachedNode* cursor = currentCursor(&cursorFrame);
+ if (!cursor) {
+ // Error case. The cursor has no action, because there is no node under
+ // the cursor
+ return FAILURE;
+ }
+ const CachedNode* firstTextfield = nextTextField(0, 0, false);
+ if (!firstTextfield) {
+ // Error case. There are no textfields in this tree.
+ return FAILURE;
+ }
+ // Now find the next textfield/area starting with the cursor
+ if (nextTextField(cursor, 0, true)) {
+ // There is a textfield/area after the cursor, so the textfield under
+ // the cursor should have the NEXT action
+ return NEXT;
+ }
+ // If this line is reached, we know that the textfield under the cursor is
+ // the last one. If it is also the first, then it is the only one, so make
+ // the action GO. Otherwise, the action is DONE.
+ return (firstTextfield == cursor) ? GO : DONE;
+}
+
const CachedNode* CachedRoot::findAt(const WebCore::IntRect& rect,
const CachedFrame** framePtr, int* x, int* y, bool checkForHidden) const
{
diff --git a/WebKit/android/nav/CachedRoot.h b/WebKit/android/nav/CachedRoot.h
index a64fa22..23cc126 100644
--- a/WebKit/android/nav/CachedRoot.h
+++ b/WebKit/android/nav/CachedRoot.h
@@ -40,6 +40,12 @@ class CachedNode;
class CachedRoot : public CachedFrame {
public:
+ enum ImeAction {
+ FAILURE = -1,
+ NEXT = 0,
+ GO = 1,
+ DONE = 2
+ };
bool adjustForScroll(BestData* , Direction , WebCore::IntPoint* scrollPtr,
bool findClosest);
int checkForCenter(int x, int y) const;
@@ -47,6 +53,10 @@ public:
bool checkRings(const WTF::Vector<WebCore::IntRect>& rings,
const WebCore::IntRect& bounds) const;
WebCore::IntPoint cursorLocation() const;
+ // This method returns the desired ImeAction for the textfield where the
+ // mouse cursor currently is. If the mouse cursor is not on a textfield,
+ // it will return FAILURE
+ ImeAction cursorTextFieldAction() const;
int documentHeight() { return mContents.height(); }
int documentWidth() { return mContents.width(); }
const CachedNode* findAt(const WebCore::IntRect& , const CachedFrame** ,
diff --git a/WebKit/android/nav/WebView.cpp b/WebKit/android/nav/WebView.cpp
index 37e4608..cbc91ae 100644
--- a/WebKit/android/nav/WebView.cpp
+++ b/WebKit/android/nav/WebView.cpp
@@ -339,29 +339,10 @@ void drawMatch(const SkRegion& region, SkCanvas* canvas, bool focused)
canvas->drawPath(matchPath, m_findPaint);
}
-// Put a cap on the number of matches to draw. If the current page has more
-// matches than this, only draw the focused match.
-#define MAX_NUMBER_OF_MATCHES_TO_DRAW 101
-
-void drawMatches(SkCanvas* canvas)
+bool scrollRectOnScreen(int left, int top, int right, int bottom)
{
- if (!m_matches || !m_matches->size()) {
- return;
- }
- if (m_findIndex >= m_matches->size()) {
- m_findIndex = 0;
- }
- const MatchInfo& matchInfo = (*m_matches)[m_findIndex];
- const SkRegion& currentMatchRegion = matchInfo.getLocation();
- const SkIRect& currentMatchBounds = currentMatchRegion.getBounds();
- int left = currentMatchBounds.fLeft;
- int top = currentMatchBounds.fTop;
- int right = currentMatchBounds.fRight;
- int bottom = currentMatchBounds.fBottom;
WebCore::IntRect visible;
getVisibleRect(&visible);
- // Check to make sure that the highlighted match is on screen. If not,
- // scroll it onscreen and return.
int dx = 0;
if (left < visible.x()) {
dx = left - visible.x();
@@ -379,8 +360,28 @@ void drawMatches(SkCanvas* canvas)
if ((dx|dy)) {
scrollBy(dx, dy);
viewInvalidate();
- return;
+ return true;
}
+ return false;
+}
+
+// Put a cap on the number of matches to draw. If the current page has more
+// matches than this, only draw the focused match.
+#define MAX_NUMBER_OF_MATCHES_TO_DRAW 101
+
+void drawMatches(SkCanvas* canvas)
+{
+ if (!m_matches || !m_matches->size())
+ return;
+ if (m_findIndex >= m_matches->size())
+ m_findIndex = 0;
+ const MatchInfo& matchInfo = (*m_matches)[m_findIndex];
+ const SkRegion& currentMatchRegion = matchInfo.getLocation();
+ const SkIRect& currentMatchBounds = currentMatchRegion.getBounds();
+ if (scrollRectOnScreen(currentMatchBounds.fLeft, currentMatchBounds.fTop,
+ currentMatchBounds.fRight, currentMatchBounds.fBottom))
+ return;
+
// Set up the paints used for drawing the matches
if (!m_isFindPaintSetUp)
setUpFindPaint();
@@ -394,6 +395,8 @@ void drawMatches(SkCanvas* canvas)
unsigned numberOfMatches = m_matches->size();
if (numberOfMatches > 1
&& numberOfMatches < MAX_NUMBER_OF_MATCHES_TO_DRAW) {
+ WebCore::IntRect visible;
+ getVisibleRect(&visible);
SkIRect visibleIRect(visible);
for(unsigned i = 0; i < numberOfMatches; i++) {
// The current match has already been drawn
@@ -1871,6 +1874,41 @@ static void nativeDestroy(JNIEnv *env, jobject obj)
delete view;
}
+static void nativeMoveCursorToNextTextInput(JNIEnv *env, jobject obj)
+{
+ WebView* view = GET_NATIVE_VIEW(env, obj);
+ CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
+ if (!root)
+ return;
+ const CachedNode* cursor = root->currentCursor();
+ if (!cursor)
+ return;
+ const CachedFrame* frame;
+ const CachedNode* next = root->nextTextField(cursor, &frame, true);
+ if (!next)
+ return;
+ const WebCore::IntRect& bounds = next->bounds();
+ root->rootHistory()->setMouseBounds(bounds);
+ view->updateCursorBounds(root, frame, next);
+ root->setCursor(const_cast<CachedFrame*>(frame),
+ const_cast<CachedNode*>(next));
+ WebCore::IntPoint pos;
+ root->getSimulatedMousePosition(&pos);
+ view->sendMoveMouse(static_cast<WebCore::Frame*>(frame->framePointer()),
+ static_cast<WebCore::Node*>(next->nodePointer()), pos.x(), pos.y());
+ view->scrollRectOnScreen(bounds.x(), bounds.y(), bounds.right(),
+ bounds.bottom());
+}
+
+static jint nativeTextFieldAction(JNIEnv *env, jobject obj)
+{
+ WebView* view = GET_NATIVE_VIEW(env, obj);
+ CachedRoot* root = view->getFrameCache(WebView::DontAllowNewer);
+ if (!root)
+ return static_cast<jint>(CachedRoot::FAILURE);
+ return static_cast<jint>(root->cursorTextFieldAction());
+}
+
static int nativeMoveGeneration(JNIEnv *env, jobject obj)
{
WebView* view = GET_NATIVE_VIEW(env, obj);
@@ -2023,6 +2061,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeMotionUp },
{ "nativeMoveCursor", "(IIZ)Z",
(void*) nativeMoveCursor },
+ { "nativeMoveCursorToNextTextInput", "()V",
+ (void*) nativeMoveCursorToNextTextInput },
{ "nativeMoveGeneration", "()I",
(void*) nativeMoveGeneration },
{ "nativeMoveSelection", "(IIZ)V",
@@ -2039,6 +2079,8 @@ static JNINativeMethod gJavaWebViewMethods[] = {
(void*) nativeSetFollowedLink },
{ "nativeSetHeightCanMeasure", "(Z)V",
(void*) nativeSetHeightCanMeasure },
+ { "nativeTextFieldAction", "()I",
+ (void*) nativeTextFieldAction },
{ "nativeTextGeneration", "()I",
(void*) nativeTextGeneration },
{ "nativeUpdateCachedTextfield", "(Ljava/lang/String;I)V",