Bug 91661 - [Chromium] Support scrolling and zooming to focused input elements
Summary: [Chromium] Support scrolling and zooming to focused input elements
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: HTML Editing (show other bugs)
Version: 528+ (Nightly build)
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Adam Barth
URL:
Keywords:
Depends on: 91801
Blocks: 91648
  Show dependency treegraph
 
Reported: 2012-07-18 13:08 PDT by Peter Beverloo
Modified: 2012-07-24 17:27 PDT (History)
10 users (show)

See Also:


Attachments
work in progress (4.26 KB, patch)
2012-07-20 15:04 PDT, Adam Barth
no flags Details | Formatted Diff | Diff
Patch (4.64 KB, patch)
2012-07-20 16:09 PDT, Adam Barth
no flags Details | Formatted Diff | Diff
Patch (4.59 KB, patch)
2012-07-20 16:37 PDT, Adam Barth
no flags Details | Formatted Diff | Diff
Patch (6.38 KB, patch)
2012-07-23 13:53 PDT, Adam Barth
no flags Details | Formatted Diff | Diff
Patch for landing (6.38 KB, patch)
2012-07-24 16:37 PDT, Adam Barth
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Beverloo 2012-07-18 13:08:14 PDT
When an input element gets focused, the element should be positioned in a convenient position and size on the user's screen for editing.

Downstream CL is:
https://gerrit-int.chromium.org/#change,15078
Comment 1 Adam Barth 2012-07-19 12:50:49 PDT
Assigned for investigation.
Comment 2 Adam Barth 2012-07-19 15:55:59 PDT
Looks like this covers these functions from WebView.h:

virtual void undoScrollFocusedNode() = 0;
virtual void zoomToFindInPageRect(const WebRect&) = 0;
Comment 3 Adam Barth 2012-07-19 15:59:06 PDT
This is going to require a bit of cleanup downstream first.
Comment 4 Adam Barth 2012-07-20 09:41:54 PDT
zoomToFindInPageRect is in Bug 91801.  Looking at undoScrollFocusedNode now.
Comment 5 Adam Barth 2012-07-20 09:45:21 PDT
undoScrollFocusedNode depends on 757bb01d84e3817ec56f1d2945744245d1a43962 to make any sense.
Comment 6 Adam Barth 2012-07-20 15:04:16 PDT
Created attachment 153608 [details]
work in progress
Comment 7 Adam Barth 2012-07-20 15:05:56 PDT
This patch as a simplified version of scrollFocusedNodeIntoRect.  We can upstream the full version in a future patch.

@aelias: Would you be willing to take a look at this patch?  In particular, I'm not super confident in my simplification of scrollFocusedNodeIntoRect.  Thanks!
Comment 8 Alexandre Elias 2012-07-20 15:27:26 PDT
Sorry, why do we want to upstream a simplified version?  Every line in there is there for a reason.  If it's blocked on some dependencies, we should upstream those dependencies first.
Comment 9 Adam Barth 2012-07-20 15:32:03 PDT
I'm just trying to break things down in to smaller pieces.  That way we can iterate towards success instead of having to do things in large chunks.

In this particular case, the milestone we're aiming for is API compatibility.  In some sense, we could upstream stub implementations of these functions, but this patch takes a slightly bigger chunk than that.  :)
Comment 10 Alexandre Elias 2012-07-20 15:36:31 PDT
I understand API compatibility is a useful goal.  In that case, I would actually prefer a pure stub implementation.  Then there is no expectation that it works at all, and it's not confusing during merges.
Comment 11 Adam Barth 2012-07-20 16:06:29 PDT
Ok.  Thanks!
Comment 12 Adam Barth 2012-07-20 16:09:18 PDT
Created attachment 153616 [details]
Patch
Comment 13 Adam Barth 2012-07-20 16:10:36 PDT
Note: The implementation of undoScrollFocusedNode in this patch is complete.  It just doesn't do much without the changes to scrollFocusedNodeIntoRect.
Comment 14 WebKit Review Bot 2012-07-20 16:11:39 PDT
Please wait for approval from abarth@webkit.org, dglazkov@chromium.org, fishd@chromium.org, jamesr@chromium.org or tkent@chromium.org before submitting, as this patch contains changes to the Chromium public API. See also https://trac.webkit.org/wiki/ChromiumWebKitAPI.
Comment 15 Alexandre Elias 2012-07-20 16:13:55 PDT
LGTM, thanks.
Comment 16 Darin Fisher (:fishd, Google) 2012-07-20 16:25:23 PDT
Comment on attachment 153616 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=153616&action=review

> Source/WebKit/chromium/src/WebViewImpl.cpp:201
> +static const int minReadableCaretHeight = 18;

what is this line for?

> Source/WebKit/chromium/src/WebViewImpl.cpp:2464
> +void WebViewImpl::undoScrollFocusedNode()

I wish we had a term that embodied "scrolling and scaling" the viewport to
bring an element into view.  Maybe we could just refer to restoring the
viewport or something like that.  It might be easier to think about what
the transition into the scrolled and scaled state is called.

> Source/WebKit/chromium/src/WebViewImpl.h:815
> +    WebPoint m_undoScrollFocusedNodeScrollOffset;

how do these fields get set?
Comment 17 Adam Barth 2012-07-20 16:36:31 PDT
(In reply to comment #16)
> (From update of attachment 153616 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=153616&action=review
> 
> > Source/WebKit/chromium/src/WebViewImpl.cpp:201
> > +static const int minReadableCaretHeight = 18;
> 
> what is this line for?

A previous iteration of the patch.  Removed.

> > Source/WebKit/chromium/src/WebViewImpl.cpp:2464
> > +void WebViewImpl::undoScrollFocusedNode()
> 
> I wish we had a term that embodied "scrolling and scaling" the viewport to
> bring an element into view.  Maybe we could just refer to restoring the
> viewport or something like that.  It might be easier to think about what
> the transition into the scrolled and scaled state is called.

I'm open to naming suggestions.

> > Source/WebKit/chromium/src/WebViewImpl.h:815
> > +    WebPoint m_undoScrollFocusedNodeScrollOffset;
> 
> how do these fields get set?

They get set by the version of scrollFocusedNodeIntoRect on the chromium-android branch that zooms in on the focused node.  An earlier version of this patch contained a simplified version of this function that set these variables but aelias asked that we not upstream a simplified version of that function.

Another alternative is to upstream all the changes to scrollFocusedNodeIntoRect in this patch.  The changes are just a bit hairy.  :)
Comment 18 Adam Barth 2012-07-20 16:37:12 PDT
Created attachment 153618 [details]
Patch
Comment 19 Darin Fisher (:fishd, Google) 2012-07-20 16:54:12 PDT
(In reply to comment #17)
> They get set by the version of scrollFocusedNodeIntoRect on the chromium-android branch that zooms in on the focused node.  An earlier version of this patch contained a simplified version of this function that set these variables but aelias asked that we not upstream a simplified version of that function.

I see, so we could go with:

   scrollFocusedNodeIntoRect
   undoScrollFocusedNodeIntoRect

The two functions would then be very clearly paired.

Adding "scale":

   scrollAndScaleFocusedNodeIntoRect
   undoScrollAndScaleFocusedNodeIntoRect

More of a mouthful:

   scrollAndScaleViewportToBringFocusedNodeIntoRect
   undoScrollAndScaleShootMeNow

Other ideas:

   adjustViewportTo{Highlight,Feature}FocusedNode
   restoreViewport
Comment 20 Adam Barth 2012-07-20 16:58:12 PDT
> I see, so we could go with:
> 
>    scrollFocusedNodeIntoRect
>    undoScrollFocusedNodeIntoRect
> 
> The two functions would then be very clearly paired.

Yes.  It's a bit unclear from those names what happens if the user scrolls/zooms in between.  Perhaps we should make the embedder manage the state explicitly?

pushScrollAndScaleState();
scrollFocusedNodeIntoRect(...);
...
popScrollAndScaleState();

>    adjustViewportTo{Highlight,Feature}FocusedNode
>    restoreViewport

Highlight isn't the best term to use because there's another feature that draws a highlight around nodes (e.g., as in Bug 84936).
Comment 21 Adam Barth 2012-07-20 17:05:25 PDT
It occurs to me that push/pop could leak, maybe we should have a save/restore interface that only keeps one history entry:

saveScrollAndScaleState();
scrollFocusedNodeIntoRect(...);
...
restoreScrollAndScaleState();
Comment 22 Alexandre Elias 2012-07-20 17:15:56 PDT
The use case for the undo is for when a user accidentally taps a form field, then presses the hardware back button to dismiss the on-screen-keyboard, we wanted to also return to the previous page scale level.  I think save/restore makes a lot of sense as we don't require a stack.

The term that we used in the past in Android to refer to a page scale action is "magnify".  Essentially a synonym for "zoom" but not as overloaded :).  I don't know if it's clear enough in a codebase that doesn't commonly use the word, though.  "scrollAndScale" might be the best option.
Comment 23 Darin Fisher (:fishd, Google) 2012-07-22 21:59:36 PDT
save/restoreScrollAndScaleState SGTM
Comment 24 Darin Fisher (:fishd, Google) 2012-07-22 22:02:07 PDT
may as well also be verbose with: scrollAndScaleFocusedNodeIntoRect
Comment 25 Adam Barth 2012-07-23 09:00:45 PDT
Comment on attachment 153618 [details]
Patch

Will do.
Comment 26 Adam Barth 2012-07-23 13:53:45 PDT
Created attachment 153857 [details]
Patch
Comment 27 Adam Barth 2012-07-23 13:54:03 PDT
Any advice on writing a test is appreciated.
Comment 28 Alexandre Elias 2012-07-23 14:54:42 PDT
There's helpers for creating WebViewImpl inside the WebFrameTest.cpp, that should work well to test this.
Comment 29 Adam Barth 2012-07-23 14:55:47 PDT
(In reply to comment #28)
> There's helpers for creating WebViewImpl inside the WebFrameTest.cpp, that should work well to test this.

Creating the WebViewImpl isn't the issue.  It's the fact that startPageScaleAnimation is asynchronous.
Comment 30 Alexandre Elias 2012-07-23 15:37:18 PDT
In the downstream version of startPageScaleAnimation(), the method is synchronous   if durationSec == 0.  One option would be to upstream that and have animateScrollFocusedNodeSec parametrizable by test.  This approach could also be handy for adding more tests to double-tap zoom.
Comment 31 Adam Barth 2012-07-23 15:44:23 PDT
Ok.  I'm happy to up the priority of upstreaming that change and to write a test for this patch once that lands.
Comment 32 Alexandre Elias 2012-07-23 15:47:58 PDT
Yusuf is working on it in https://bugs.webkit.org/show_bug.cgi?id=90316 .  He told me he should be have time to restart work on it within a week or two.
Comment 33 Darin Fisher (:fishd, Google) 2012-07-23 22:12:52 PDT
Comment on attachment 153857 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=153857&action=review

> Source/WebKit/chromium/src/WebViewImpl.cpp:201
> +static const double scrollFocusedNodeAnimationDurationInSeconds = 0.2;

nit: since this is used with restoreScrollAndScaleState, it may be used in cases
that don't involve the focused node.  maybe call it scrollAndScaleAnimationDurationInSeconds?

> Source/WebKit/chromium/src/WebViewImpl.cpp:2730
> +#if ENABLE(GESTURE_EVENTS)

nit: not sure why this is protected by GESTURE_EVENTS feature guard, but that's ok.

> Source/WebKit/chromium/src/WebViewImpl.cpp:2743
> +    m_savedScrollOffset = WebSize();

... = IntSize();

> Source/WebKit/chromium/src/WebViewImpl.h:724
> +    WebSize m_savedScrollOffset;

nit: use IntSize instead.  better to use WebCore types in the implementation.
Comment 34 Adam Barth 2012-07-23 22:29:44 PDT
Comment on attachment 153857 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=153857&action=review

>> Source/WebKit/chromium/src/WebViewImpl.cpp:2730
>> +#if ENABLE(GESTURE_EVENTS)
> 
> nit: not sure why this is protected by GESTURE_EVENTS feature guard, but that's ok.

startPageScaleAnimation only exists when ENABLE(GESTURE_EVENTS) is true.  The #else block gives the non-animated implementation.
Comment 35 Adam Barth 2012-07-24 16:36:52 PDT
(In reply to comment #33)
> (From update of attachment 153857 [details])
> View in context: https://bugs.webkit.org/attachment.cgi?id=153857&action=review
> 
> > Source/WebKit/chromium/src/WebViewImpl.cpp:201
> > +static const double scrollFocusedNodeAnimationDurationInSeconds = 0.2;
> 
> nit: since this is used with restoreScrollAndScaleState, it may be used in cases
> that don't involve the focused node.  maybe call it scrollAndScaleAnimationDurationInSeconds?

Done.

> > Source/WebKit/chromium/src/WebViewImpl.cpp:2743
> > +    m_savedScrollOffset = WebSize();
> 
> ... = IntSize();

Fixed.

> > Source/WebKit/chromium/src/WebViewImpl.h:724
> > +    WebSize m_savedScrollOffset;
> 
> nit: use IntSize instead.  better to use WebCore types in the implementation.

Thanks.  I missed the implicit conversion from WebSize to IntSize.  Using IntSize makes all this code much prettier.
Comment 36 Adam Barth 2012-07-24 16:37:41 PDT
Created attachment 154172 [details]
Patch for landing
Comment 37 WebKit Review Bot 2012-07-24 17:27:39 PDT
Comment on attachment 154172 [details]
Patch for landing

Clearing flags on attachment: 154172

Committed r123554: <http://trac.webkit.org/changeset/123554>
Comment 38 WebKit Review Bot 2012-07-24 17:27:46 PDT
All reviewed patches have been landed.  Closing bug.