Changeset 130545 in webkit
- Timestamp:
- Oct 5, 2012, 1:30:59 PM (13 years ago)
- Location:
- trunk/Source/WebKit/chromium
- Files:
-
- 1 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit/chromium/ChangeLog
r130539 r130545 1 2012-10-05 Yusuf Ozuysal <yusufo@google.com> 2 3 [chromium] Support zooming focused node for mobile devices 4 https://bugs.webkit.org/show_bug.cgi?id=97958 5 6 Reviewed by Adam Barth. 7 8 This unforks the Android version of scrollFocusedNodeIntoRect().A new setting 9 autoZoomFocusedNodeToLegibleScale was added to turn it on, since not all 10 platforms with ENABLE(GESTURE_EVENTS) want this. 11 12 Test: WebFrameTest.DivScrollIntoEditableTest 13 14 * public/WebSettings.h: 15 * src/WebSettingsImpl.cpp: 16 (WebKit::WebSettingsImpl::WebSettingsImpl): 17 (WebKit::WebSettingsImpl::setAutoZoomFocusedNodeToLegibleScale): 18 (WebKit): 19 * src/WebSettingsImpl.h: 20 (WebSettingsImpl): 21 (WebKit::WebSettingsImpl::autoZoomFocusedNodeToLegibleScale): 22 * src/WebViewImpl.cpp: 23 (WebKit::WebViewImpl::scrollFocusedNodeIntoRect): 24 * tests/WebFrameTest.cpp: 25 * tests/data/get_scale_for_zoom_into_editable_test.html: Added. 26 1 27 2012-10-05 W. James MacLean <wjmaclean@chromium.org> 2 28 -
trunk/Source/WebKit/chromium/public/WebSettings.h
r130321 r130545 75 75 virtual void setApplyPageScaleFactorInCompositor(bool) = 0; 76 76 virtual void setAsynchronousSpellCheckingEnabled(bool) = 0; 77 virtual void setAutoZoomFocusedNodeToLegibleScale(bool) = 0; 77 78 virtual void setAuthorAndUserStylesEnabled(bool) = 0; 78 79 virtual void setCaretBrowsingEnabled(bool) = 0; -
trunk/Source/WebKit/chromium/src/WebSettingsImpl.cpp
r130530 r130545 55 55 , m_applyDefaultDeviceScaleFactorInCompositor(false) 56 56 , m_gestureTapHighlightEnabled(true) 57 , m_autoZoomFocusedNodeToLegibleScale(false) 57 58 , m_defaultTileSize(WebSize(256, 256)) 58 59 , m_maxUntiledLayerSize(WebSize(512, 512)) … … 146 147 } 147 148 149 void WebSettingsImpl::setAutoZoomFocusedNodeToLegibleScale(bool autoZoomFocusedNodeToLegibleScale) 150 { 151 m_autoZoomFocusedNodeToLegibleScale = autoZoomFocusedNodeToLegibleScale; 152 } 153 148 154 void WebSettingsImpl::setTextAutosizingEnabled(bool enabled) 149 155 { -
trunk/Source/WebKit/chromium/src/WebSettingsImpl.h
r130321 r130545 68 68 virtual void setAsynchronousSpellCheckingEnabled(bool); 69 69 virtual void setAuthorAndUserStylesEnabled(bool); 70 virtual void setAutoZoomFocusedNodeToLegibleScale(bool); 70 71 virtual void setCaretBrowsingEnabled(bool); 71 72 virtual void setCookieEnabled(bool); … … 163 164 bool applyDefaultDeviceScaleFactorInCompositor() const { return m_applyDefaultDeviceScaleFactorInCompositor; } 164 165 bool applyPageScaleFactorInCompositor() const; 166 bool autoZoomFocusedNodeToLegibleScale() const { return m_autoZoomFocusedNodeToLegibleScale; } 165 167 bool gestureTapHighlightEnabled() { return m_gestureTapHighlightEnabled; } 166 168 WebSize defaultTileSize() const { return m_defaultTileSize; } … … 176 178 bool m_applyDefaultDeviceScaleFactorInCompositor; 177 179 bool m_gestureTapHighlightEnabled; 180 bool m_autoZoomFocusedNodeToLegibleScale; 178 181 WebSize m_defaultTileSize; 179 182 WebSize m_maxUntiledLayerSize; -
trunk/Source/WebKit/chromium/src/WebViewImpl.cpp
r130539 r130545 201 201 // Constants for zooming in on a focused text field. 202 202 static const double scrollAndScaleAnimationDurationInSeconds = 0.2; 203 static const int minReadableCaretHeight = 18; 204 static const float minScaleChangeToTriggerZoom = 1.05f; 205 static const float leftBoxRatio = 0.3f; 206 static const int caretPadding = 10; 203 207 204 208 namespace WebKit { … … 2639 2643 if (!frame || !frame->view() || !focusedNode || !focusedNode->isElementNode()) 2640 2644 return; 2641 Element* elementNode = static_cast<Element*>(focusedNode); 2642 frame->view()->scrollElementToRect(elementNode, IntRect(rect.x, rect.y, rect.width, rect.height)); 2645 2646 if (!m_webSettings->autoZoomFocusedNodeToLegibleScale()) { 2647 Element* elementNode = static_cast<Element*>(focusedNode); 2648 frame->view()->scrollElementToRect(elementNode, IntRect(rect.x, rect.y, rect.width, rect.height)); 2649 return; 2650 } 2651 2652 #if ENABLE(GESTURE_EVENTS) 2653 focusedNode->document()->updateLayoutIgnorePendingStylesheets(); 2654 2655 // 'caret' is rect encompassing the blinking cursor. 2656 IntRect textboxRect = focusedNode->document()->view()->contentsToWindow(pixelSnappedIntRect(focusedNode->Node::boundingBox())); 2657 WebRect caret, end; 2658 selectionBounds(caret, end); 2659 2660 // Pick a scale which is reasonably readable. This is the scale at which 2661 // the caret height will become minReadableCaretHeight (adjusted for dpi 2662 // and font scale factor). 2663 float targetScale = deviceScaleFactor(); 2664 #if ENABLE(TEXT_AUTOSIZING) 2665 if (page() && page()->settings()) 2666 targetScale *= page()->settings()->textAutosizingFontScaleFactor(); 2667 #endif 2668 const float newScale = clampPageScaleFactorToLimits(pageScaleFactor() * minReadableCaretHeight * targetScale / caret.height); 2669 const float deltaScale = newScale / pageScaleFactor(); 2670 2671 // Convert the rects to absolute space in the new scale. 2672 IntRect textboxRectInDocumentCoordinates = textboxRect; 2673 textboxRectInDocumentCoordinates.move(mainFrame()->scrollOffset()); 2674 textboxRectInDocumentCoordinates.scale(deltaScale); 2675 IntRect caretInDocumentCoordinates = caret; 2676 caretInDocumentCoordinates.move(mainFrame()->scrollOffset()); 2677 caretInDocumentCoordinates.scale(deltaScale); 2678 2679 IntPoint newOffset; 2680 if (textboxRectInDocumentCoordinates.width() <= m_size.width) { 2681 // Field is narrower than screen. Try to leave padding on left so field's 2682 // label is visible, but it's more important to ensure entire field is 2683 // onscreen. 2684 int idealLeftPadding = m_size.width * leftBoxRatio; 2685 int maxLeftPaddingKeepingBoxOnscreen = m_size.width - textboxRectInDocumentCoordinates.width(); 2686 newOffset.setX(textboxRectInDocumentCoordinates.x() - min<int>(idealLeftPadding, maxLeftPaddingKeepingBoxOnscreen)); 2687 } else { 2688 // Field is wider than screen. Try to left-align field, unless caret would 2689 // be offscreen, in which case right-align the caret. 2690 newOffset.setX(max<int>(textboxRectInDocumentCoordinates.x(), caretInDocumentCoordinates.x() + caretInDocumentCoordinates.width() + caretPadding - m_size.width)); 2691 } 2692 if (textboxRectInDocumentCoordinates.height() <= m_size.height) { 2693 // Field is shorter than screen. Vertically center it. 2694 newOffset.setY(textboxRectInDocumentCoordinates.y() - (m_size.height - textboxRectInDocumentCoordinates.height()) / 2); 2695 } else { 2696 // Field is taller than screen. Try to top align field, unless caret would 2697 // be offscreen, in which case bottom-align the caret. 2698 newOffset.setY(max<int>(textboxRectInDocumentCoordinates.y(), caretInDocumentCoordinates.y() + caretInDocumentCoordinates.height() + caretPadding - m_size.height)); 2699 } 2700 2701 bool needAnimation = false; 2702 // If we are at less than the target zoom level, zoom in. 2703 if (deltaScale > minScaleChangeToTriggerZoom) 2704 needAnimation = true; 2705 // If the caret is offscreen, then animate. 2706 IntRect sizeRect(0, 0, m_size.width, m_size.height); 2707 if (!sizeRect.contains(caret)) 2708 needAnimation = true; 2709 // If the box is partially offscreen and it's possible to bring it fully 2710 // onscreen, then animate. 2711 if (sizeRect.contains(textboxRectInDocumentCoordinates.width(), textboxRectInDocumentCoordinates.height()) && !sizeRect.contains(textboxRect)) 2712 needAnimation = true; 2713 2714 if (needAnimation) 2715 startPageScaleAnimation(newOffset, false, newScale, scrollAndScaleAnimationDurationInSeconds); 2716 #endif 2643 2717 } 2644 2718 -
trunk/Source/WebKit/chromium/tests/WebFrameTest.cpp
r130141 r130545 497 497 EXPECT_FLOAT_EQ(webViewImpl->minimumPageScaleFactor(), scale); 498 498 } 499 500 TEST_F(WebFrameTest, DivScrollIntoEditableTest) 501 { 502 registerMockedHttpURLLoad("get_scale_for_zoom_into_editable_test.html"); 503 504 DivAutoZoomTestWebViewClient client; 505 int viewportWidth = 640; 506 int viewportHeight = 480; 507 float LeftBoxRatio = 0.3; 508 int caretPadding = 10; 509 int minReadableCaretHeight = 18; 510 client.m_windowRect = WebRect(0, 0, viewportWidth, viewportHeight); 511 WebKit::WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "get_scale_for_zoom_into_editable_test.html", true, 0, &client); 512 webView->enableFixedLayoutMode(true); 513 webView->resize(WebSize(viewportWidth, viewportHeight)); 514 webView->setPageScaleFactorLimits(1, 10); 515 webView->layout(); 516 webView->setDeviceScaleFactor(1.5f); 517 webView->settings()->setAutoZoomFocusedNodeToLegibleScale(true); 518 519 WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView); 520 webViewImpl->shouldUseAnimateDoubleTapTimeZeroForTesting(true); 521 522 WebRect editBoxWithText(200, 200, 250, 20); 523 WebRect editBoxWithNoText(200, 250, 250, 20); 524 525 // Test scrolling the focused node 526 // The edit box is shorter and narrower than the viewport when legible. 527 setScaleAndScrollAndLayout(webView, WebPoint(0, 0), 1); 528 WebRect rect, caret; 529 webViewImpl->selectionBounds(caret, rect); 530 webView->scrollFocusedNodeIntoRect(rect); 531 // The edit box should be left aligned with a margin for possible label. 532 int hScroll = editBoxWithText.x * webView->pageScaleFactor() - LeftBoxRatio * viewportWidth; 533 EXPECT_EQ(hScroll, webView->mainFrame()->scrollOffset().width); 534 int vScroll = editBoxWithText.y * webView->pageScaleFactor() - (viewportHeight - editBoxWithText.height * webView->pageScaleFactor()) / 2; 535 EXPECT_EQ(vScroll, webView->mainFrame()->scrollOffset().height); 536 EXPECT_FLOAT_EQ(webView->deviceScaleFactor() * minReadableCaretHeight / caret.height, webView->pageScaleFactor()); 537 538 // The edit box is wider than the viewport when legible. 539 webView->setDeviceScaleFactor(4); 540 setScaleAndScrollAndLayout(webView, WebPoint(0, 0), 1); 541 webViewImpl->selectionBounds(caret, rect); 542 webView->scrollFocusedNodeIntoRect(rect); 543 // The caret should be right aligned since the caret would be offscreen when the edit box is left aligned. 544 hScroll = (caret.x + caret.width) * webView->pageScaleFactor() + caretPadding - viewportWidth; 545 EXPECT_EQ(hScroll, webView->mainFrame()->scrollOffset().width); 546 EXPECT_FLOAT_EQ(webView->deviceScaleFactor() * minReadableCaretHeight / caret.height, webView->pageScaleFactor()); 547 548 setScaleAndScrollAndLayout(webView, WebPoint(0, 0), 1); 549 // Move focus to edit box with text. 550 webView->advanceFocus(false); 551 webViewImpl->selectionBounds(caret, rect); 552 webView->scrollFocusedNodeIntoRect(rect); 553 // The edit box should be left aligned. 554 hScroll = editBoxWithNoText.x * webView->pageScaleFactor(); 555 EXPECT_EQ(hScroll, webView->mainFrame()->scrollOffset().width); 556 vScroll = editBoxWithNoText.y * webView->pageScaleFactor() - (viewportHeight - editBoxWithNoText.height * webView->pageScaleFactor()) / 2; 557 EXPECT_EQ(vScroll, webView->mainFrame()->scrollOffset().height); 558 EXPECT_FLOAT_EQ(webView->deviceScaleFactor() * minReadableCaretHeight / caret.height, webView->pageScaleFactor()); 559 560 // Move focus back to the first edit box. 561 webView->advanceFocus(true); 562 webViewImpl->selectionBounds(caret, rect); 563 // The position should have stayed the same since this box was already on screen with the right scale. 564 EXPECT_EQ(vScroll, webView->mainFrame()->scrollOffset().height); 565 EXPECT_EQ(hScroll, webView->mainFrame()->scrollOffset().width); 566 } 499 567 #endif 500 568
Note:
See TracChangeset
for help on using the changeset viewer.