Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(12)

Side by Side Diff: Source/web/WebViewImpl.cpp

Issue 1192433010: Use Android's "scroll focused node into view" path on all platforms (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Added test Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/web/WebViewImpl.h ('k') | Source/web/tests/WebFrameTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2011, 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 2838 matching lines...) Expand 10 before | Expand all | Expand 10 after
2849 } 2849 }
2850 2850
2851 bool WebViewImpl::scrollFocusedNodeIntoRect(const WebRect& rectInViewport) 2851 bool WebViewImpl::scrollFocusedNodeIntoRect(const WebRect& rectInViewport)
2852 { 2852 {
2853 LocalFrame* frame = page()->mainFrame() && page()->mainFrame()->isLocalFrame () 2853 LocalFrame* frame = page()->mainFrame() && page()->mainFrame()->isLocalFrame ()
2854 ? page()->deprecatedLocalMainFrame() : 0; 2854 ? page()->deprecatedLocalMainFrame() : 0;
2855 Element* element = focusedElement(); 2855 Element* element = focusedElement();
2856 if (!frame || !frame->view() || !element) 2856 if (!frame || !frame->view() || !element)
2857 return false; 2857 return false;
2858 2858
2859 if (!m_webSettings->autoZoomFocusedNodeToLegibleScale()) { 2859 bool zoomInToLegibleScale = m_webSettings->autoZoomFocusedNodeToLegibleScale () && !shouldDisableDesktopWorkarounds();
2860 frame->document()->updateLayoutIgnorePendingStylesheets();
2861
2862 PinchViewport& pinchViewport = page()->frameHost().pinchViewport();
2863 FloatRect targetRectInRootFrame = pinchViewport.viewportToRootFrame(rect InViewport);
2864
2865 FrameView* elementView = element->document().view();
2866 IntRect boundsInRootFrame = elementView->contentsToRootFrame(pixelSnappe dIntRect(element->boundingBox()));
2867 LayoutRect boundsInRootContent = LayoutRect(frame->view()->frameToConten ts(boundsInRootFrame));
2868
2869 frame->view()->scrollableArea()->scrollIntoRect(boundsInRootContent, tar getRectInRootFrame);
2870 return false;
2871 }
2872 2860
2873 float scale; 2861 float scale;
2874 IntPoint scroll; 2862 IntPoint scroll;
2875 bool needAnimation; 2863 bool needAnimation;
2876 computeScaleAndScrollForFocusedNode(element, scale, scroll, needAnimation); 2864 computeScaleAndScrollForFocusedNode(element, zoomInToLegibleScale, scale, sc roll, needAnimation);
2877 if (needAnimation) 2865 if (needAnimation)
2878 return startPageScaleAnimation(scroll, false, scale, scrollAndScaleAnima tionDurationInSeconds); 2866 return startPageScaleAnimation(scroll, false, scale, scrollAndScaleAnima tionDurationInSeconds);
2879 2867
2880 return false; 2868 return false;
2881 } 2869 }
2882 2870
2883 void WebViewImpl::computeScaleAndScrollForFocusedNode(Node* focusedNode, float& newScale, IntPoint& newScroll, bool& needAnimation) 2871 void WebViewImpl::computeScaleAndScrollForFocusedNode(Node* focusedNode, bool zo omInToLegibleScale, float& newScale, IntPoint& newScroll, bool& needAnimation)
2884 { 2872 {
2885 focusedNode->document().updateLayoutIgnorePendingStylesheets(); 2873 focusedNode->document().updateLayoutIgnorePendingStylesheets();
2886 2874
2887 // 'caret' is rect encompassing the blinking cursor. 2875 PinchViewport& pinchViewport = page()->frameHost().pinchViewport();
2888 IntRect textboxRectInRootFrame = focusedNode->document().view()->contentsToR ootFrame(pixelSnappedIntRect(focusedNode->Node::boundingBox()));
2889 WebRect caret, unusedEnd;
2890 selectionBounds(caret, unusedEnd);
2891 IntRect unscaledCaret = caret;
2892 unscaledCaret.scale(1 / pageScaleFactor());
2893 caret = unscaledCaret;
2894 2876
2895 if (shouldDisableDesktopWorkarounds()) { 2877 WebRect caretInViewport, unusedEnd;
2878 selectionBounds(caretInViewport, unusedEnd);
2879
2880 // 'caretInDocument' is rect encompassing the blinking cursor relative to th e root document.
2881 IntRect caretInDocument = mainFrameImpl()->frameView()->frameToContents(pinc hViewport.viewportToRootFrame(caretInViewport));
2882 IntRect textboxRectInDocument = mainFrameImpl()->frameView()->frameToContent s(
2883 focusedNode->document().view()->contentsToRootFrame(pixelSnappedIntRect( focusedNode->Node::boundingBox())));
2884
2885 if (!zoomInToLegibleScale) {
2896 newScale = pageScaleFactor(); 2886 newScale = pageScaleFactor();
2897 } else { 2887 } else {
2898 // Pick a scale which is reasonably readable. This is the scale at which 2888 // Pick a scale which is reasonably readable. This is the scale at which
2899 // the caret height will become minReadableCaretHeightForNode (adjusted 2889 // the caret height will become minReadableCaretHeightForNode (adjusted
2900 // for dpi and font scale factor). 2890 // for dpi and font scale factor).
2901 const int minReadableCaretHeightForNode = textboxRectInRootFrame.height( ) >= 2 * caret.height ? minReadableCaretHeightForTextArea : minReadableCaretHeig ht; 2891 const int minReadableCaretHeightForNode = textboxRectInDocument.height() >= 2 * caretInDocument.height() ? minReadableCaretHeightForTextArea : minReadab leCaretHeight;
2902 newScale = clampPageScaleFactorToLimits(maximumLegiblePageScale() * minR eadableCaretHeightForNode / caret.height); 2892 newScale = clampPageScaleFactorToLimits(maximumLegiblePageScale() * minR eadableCaretHeightForNode / caretInDocument.height());
2903 newScale = std::max(newScale, pageScaleFactor()); 2893 newScale = std::max(newScale, pageScaleFactor());
2904 } 2894 }
2905 const float deltaScale = newScale / pageScaleFactor(); 2895 const float deltaScale = newScale / pageScaleFactor();
2906 2896
2907 needAnimation = false; 2897 needAnimation = false;
2898
2908 // If we are at less than the target zoom level, zoom in. 2899 // If we are at less than the target zoom level, zoom in.
2909 if (deltaScale > minScaleChangeToTriggerZoom) 2900 if (deltaScale > minScaleChangeToTriggerZoom)
2910 needAnimation = true; 2901 needAnimation = true;
2911 else 2902 else
2912 newScale = pageScaleFactor(); 2903 newScale = pageScaleFactor();
2913 2904
2914 // Convert the rects to absolute space in the new scale.
2915 IntRect textboxRectInDocumentCoordinates = mainFrameImpl()->frameView()->fra meToContents(textboxRectInRootFrame);
2916 IntRect caretInDocumentCoordinates = caret;
2917 caretInDocumentCoordinates.move(mainFrame()->scrollOffset());
2918
2919 int viewWidth = m_size.width / newScale;
2920 int viewHeight = m_size.height / newScale;
2921
2922 // If the caret is offscreen, then animate. 2905 // If the caret is offscreen, then animate.
2923 IntRect sizeRect(0, 0, viewWidth, viewHeight); 2906 if (!pinchViewport.visibleRectInDocument().contains(caretInDocument))
2924 sizeRect.scale(newScale / pageScaleFactor());
2925 if (!sizeRect.contains(caret))
2926 needAnimation = true; 2907 needAnimation = true;
2927 2908
2928 // If the box is partially offscreen and it's possible to bring it fully 2909 // If the box is partially offscreen and it's possible to bring it fully
2929 // onscreen, then animate. 2910 // onscreen, then animate.
2930 if (sizeRect.contains(textboxRectInDocumentCoordinates.width(), textboxRectI nDocumentCoordinates.height()) && !sizeRect.contains(textboxRectInRootFrame)) 2911 if (pinchViewport.visibleRect().width() >= textboxRectInDocument.width()
2912 && pinchViewport.visibleRect().height() >= textboxRectInDocument.height( )
2913 && !pinchViewport.visibleRectInDocument().contains(textboxRectInDocument ))
2931 needAnimation = true; 2914 needAnimation = true;
2932 2915
2933 if (!needAnimation) 2916 if (!needAnimation)
2934 return; 2917 return;
2935 2918
2936 if (textboxRectInDocumentCoordinates.width() <= viewWidth) { 2919 FloatSize targetViewportSize = pinchViewport.size();
2920 targetViewportSize.scale(1 / newScale);
2921
2922 if (textboxRectInDocument.width() <= targetViewportSize.width()) {
2937 // Field is narrower than screen. Try to leave padding on left so field' s 2923 // Field is narrower than screen. Try to leave padding on left so field' s
2938 // label is visible, but it's more important to ensure entire field is 2924 // label is visible, but it's more important to ensure entire field is
2939 // onscreen. 2925 // onscreen.
2940 int idealLeftPadding = viewWidth * leftBoxRatio; 2926 int idealLeftPadding = targetViewportSize.width() * leftBoxRatio;
2941 int maxLeftPaddingKeepingBoxOnscreen = viewWidth - textboxRectInDocument Coordinates.width(); 2927 int maxLeftPaddingKeepingBoxOnscreen = targetViewportSize.width() - text boxRectInDocument.width();
2942 newScroll.setX(textboxRectInDocumentCoordinates.x() - std::min<int>(idea lLeftPadding, maxLeftPaddingKeepingBoxOnscreen)); 2928 newScroll.setX(textboxRectInDocument.x() - std::min<int>(idealLeftPaddin g, maxLeftPaddingKeepingBoxOnscreen));
2943 } else { 2929 } else {
2944 // Field is wider than screen. Try to left-align field, unless caret wou ld 2930 // Field is wider than screen. Try to left-align field, unless caret wou ld
2945 // be offscreen, in which case right-align the caret. 2931 // be offscreen, in which case right-align the caret.
2946 newScroll.setX(std::max<int>(textboxRectInDocumentCoordinates.x(), caret InDocumentCoordinates.x() + caretInDocumentCoordinates.width() + caretPadding - viewWidth)); 2932 newScroll.setX(std::max<int>(textboxRectInDocument.x(), caretInDocument. x() + caretInDocument.width() + caretPadding - targetViewportSize.width()));
2947 } 2933 }
2948 if (textboxRectInDocumentCoordinates.height() <= viewHeight) { 2934 if (textboxRectInDocument.height() <= targetViewportSize.height()) {
2949 // Field is shorter than screen. Vertically center it. 2935 // Field is shorter than screen. Vertically center it.
2950 newScroll.setY(textboxRectInDocumentCoordinates.y() - (viewHeight - text boxRectInDocumentCoordinates.height()) / 2); 2936 newScroll.setY(textboxRectInDocument.y() - (targetViewportSize.height() - textboxRectInDocument.height()) / 2);
2951 } else { 2937 } else {
2952 // Field is taller than screen. Try to top align field, unless caret wou ld 2938 // Field is taller than screen. Try to top align field, unless caret wou ld
2953 // be offscreen, in which case bottom-align the caret. 2939 // be offscreen, in which case bottom-align the caret.
2954 newScroll.setY(std::max<int>(textboxRectInDocumentCoordinates.y(), caret InDocumentCoordinates.y() + caretInDocumentCoordinates.height() + caretPadding - viewHeight)); 2940 newScroll.setY(std::max<int>(textboxRectInDocument.y(), caretInDocument. y() + caretInDocument.height() + caretPadding - targetViewportSize.height()));
2955 } 2941 }
2956 } 2942 }
2957 2943
2958 void WebViewImpl::advanceFocus(bool reverse) 2944 void WebViewImpl::advanceFocus(bool reverse)
2959 { 2945 {
2960 page()->focusController().advanceFocus(reverse ? WebFocusTypeBackward : WebF ocusTypeForward); 2946 page()->focusController().advanceFocus(reverse ? WebFocusTypeBackward : WebF ocusTypeForward);
2961 } 2947 }
2962 2948
2963 double WebViewImpl::zoomLevel() 2949 double WebViewImpl::zoomLevel()
2964 { 2950 {
(...skipping 1446 matching lines...) Expand 10 before | Expand all | Expand 10 after
4411 { 4397 {
4412 WebGLRenderingContext::forceNextWebGLContextCreationToFail(); 4398 WebGLRenderingContext::forceNextWebGLContextCreationToFail();
4413 } 4399 }
4414 4400
4415 void WebViewImpl::forceNextDrawingBufferCreationToFail() 4401 void WebViewImpl::forceNextDrawingBufferCreationToFail()
4416 { 4402 {
4417 DrawingBuffer::forceNextDrawingBufferCreationToFail(); 4403 DrawingBuffer::forceNextDrawingBufferCreationToFail();
4418 } 4404 }
4419 4405
4420 } // namespace blink 4406 } // namespace blink
OLDNEW
« no previous file with comments | « Source/web/WebViewImpl.h ('k') | Source/web/tests/WebFrameTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698