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

Side by Side Diff: Source/WebKit/chromium/src/WebViewImpl.cpp

Issue 13704012: Improve mobile device rotation behavior. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Rebase Created 7 years, 8 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 | « no previous file | Source/WebKit/chromium/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 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 // (such as due to a double tap gesture or find in page etc.). These are 190 // (such as due to a double tap gesture or find in page etc.). These are
191 // experimentally determined. 191 // experimentally determined.
192 static const int touchPointPadding = 32; 192 static const int touchPointPadding = 32;
193 static const int nonUserInitiatedPointPadding = 11; 193 static const int nonUserInitiatedPointPadding = 11;
194 static const float minScaleDifference = 0.01f; 194 static const float minScaleDifference = 0.01f;
195 static const float doubleTapZoomContentDefaultMargin = 5; 195 static const float doubleTapZoomContentDefaultMargin = 5;
196 static const float doubleTapZoomContentMinimumMargin = 2; 196 static const float doubleTapZoomContentMinimumMargin = 2;
197 static const double doubleTapZoomAnimationDurationInSeconds = 0.25; 197 static const double doubleTapZoomAnimationDurationInSeconds = 0.25;
198 static const float doubleTapZoomAlreadyLegibleRatio = 1.2f; 198 static const float doubleTapZoomAlreadyLegibleRatio = 1.2f;
199 199
200 static const float viewportAnchorRelativeEpsilon = 0.1f;
201 static const float viewportAnchorXCoord = 0.5f;
202 static const float viewportAnchorYCoord = 0;
203
200 // Constants for zooming in on a focused text field. 204 // Constants for zooming in on a focused text field.
201 static const double scrollAndScaleAnimationDurationInSeconds = 0.2; 205 static const double scrollAndScaleAnimationDurationInSeconds = 0.2;
202 static const int minReadableCaretHeight = 18; 206 static const int minReadableCaretHeight = 18;
203 static const float minScaleChangeToTriggerZoom = 1.05f; 207 static const float minScaleChangeToTriggerZoom = 1.05f;
204 static const float leftBoxRatio = 0.3f; 208 static const float leftBoxRatio = 0.3f;
205 static const int caretPadding = 10; 209 static const int caretPadding = 10;
206 210
207 namespace WebKit { 211 namespace WebKit {
208 212
213 #if ENABLE(VIEWPORT)
214 namespace {
215 // ViewportAnchor provides a way to anchor a viewport origin to a DOM node.
216 // In particular, the user supplies the current viewport (in CSS coordinates)
217 // and an anchor point (in view coordinates, e.g., (0, 0) == viewport origin,
218 // (0.5, 0) == viewport top center). The anchor point tracks the underlying DOM
219 // node; as the node moves or the view is resized, the viewport anchor maintains
220 // its orientation relative to the node, and the viewport origin maintains its
221 // orientation relative to the anchor.
222 class ViewportAnchor {
abarth-chromium 2013/04/12 17:33:30 This class should go in its own file. WebViewImpl
jdduke (slow) 2013/04/12 19:20:16 Done.
223 public:
224 ViewportAnchor(EventHandler* eventHandler)
abarth-chromium 2013/04/12 17:33:30 one-argument constructors should be marked explici
jdduke (slow) 2013/04/12 19:20:16 Done.
225 : m_eventHandler(eventHandler) { }
226
227 void setAnchor(const IntRect& viewRect, const FloatSize& anchorInViewCoords)
228 {
229 m_viewRect = viewRect;
230 m_anchorNode.clear();
231 m_anchorNodeBounds = LayoutRect();
232 m_anchorInNodeCoords = FloatSize();
233 m_anchorInViewCoords = anchorInViewCoords;
234
235 if (viewRect.isEmpty())
236 return;
237
238 // Preserve origins at the absolute screen origin
239 if (viewRect.location() == IntPoint::zero())
240 return;
241
242 FloatSize anchorOffset = viewRect.size();
243 anchorOffset.scale(anchorInViewCoords.width(), anchorInViewCoords.height ());
244 const FloatPoint anchorPoint = FloatPoint(viewRect.location()) + anchorO ffset;
245
246 Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPoint), viewRe ct, m_eventHandler);
247 if (!node)
248 return;
249
250 m_anchorNode = node;
251 m_anchorNodeBounds = node->boundingBox();
252 m_anchorInNodeCoords = anchorPoint - m_anchorNodeBounds.location();
253 m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anc horNodeBounds.height());
254 }
255
256 // Note: The returned point may not lie within the document bounds.
257 IntPoint computeOrigin(const IntSize& currentViewSize) const
258 {
259 if (!m_anchorNode || !m_anchorNode->inDocument())
260 return m_viewRect.location();
261
262 const LayoutRect currentNodeBounds = m_anchorNode->boundingBox();
263 if (m_anchorNodeBounds == currentNodeBounds)
264 return m_viewRect.location();
265
266 // Compute the new anchor point relative to the node position
267 FloatSize anchorOffsetFromNode = currentNodeBounds.size();
268 anchorOffsetFromNode.scale(m_anchorInNodeCoords.width(), m_anchorInNodeC oords.height());
269 FloatPoint anchorPoint = currentNodeBounds.location() + anchorOffsetFrom Node;
270
271 // Compute the new origin point relative to the new anchor point
272 FloatSize anchorOffsetFromOrigin = currentViewSize;
273 anchorOffsetFromOrigin.scale(m_anchorInViewCoords.width(), m_anchorInVie wCoords.height());
274 return flooredIntPoint(anchorPoint - anchorOffsetFromOrigin);
275 }
276
277 private:
278 ViewportAnchor();
279
280 static Node* findNonEmptyAnchorNode(const IntPoint& point, const IntRect& vi ewRect, EventHandler* eventHandler)
281 {
282 Node* node = eventHandler->hitTestResultAtPoint(point).innerNode();
283
284 // If the node bounding box contains the view, make a single attempt to
285 // find a smaller node; the larger the node bounds, the greater the
286 // variability under resize.
287 if (node && node->boundingBox().contains(viewRect)) {
288 IntSize pointOffset = viewRect.size();
289 pointOffset.scale(viewportAnchorRelativeEpsilon);
290 node = eventHandler->hitTestResultAtPoint(point + pointOffset).inner Node();
291 }
292
293 while (node && node->boundingBox().isEmpty())
294 node = node->parentNode();
295
296 return node;
297 }
298
299 EventHandler* m_eventHandler;
300
301 IntRect m_viewRect;
302
303 RefPtr<Node> m_anchorNode;
304 LayoutRect m_anchorNodeBounds;
305
306 FloatSize m_anchorInViewCoords;
307 FloatSize m_anchorInNodeCoords;
308 };
309 }
310 #endif // ENABLE(VIEWPORT)
311
209 // Change the text zoom level by kTextSizeMultiplierRatio each time the user 312 // Change the text zoom level by kTextSizeMultiplierRatio each time the user
210 // zooms text in or out (ie., change by 20%). The min and max values limit 313 // zooms text in or out (ie., change by 20%). The min and max values limit
211 // text zoom to half and 3x the original text size. These three values match 314 // text zoom to half and 3x the original text size. These three values match
212 // those in Apple's port in WebKit/WebKit/WebView/WebView.mm 315 // those in Apple's port in WebKit/WebKit/WebView/WebView.mm
213 const double WebView::textSizeMultiplierRatio = 1.2; 316 const double WebView::textSizeMultiplierRatio = 1.2;
214 const double WebView::minTextSizeMultiplier = 0.5; 317 const double WebView::minTextSizeMultiplier = 0.5;
215 const double WebView::maxTextSizeMultiplier = 3.0; 318 const double WebView::maxTextSizeMultiplier = 3.0;
216 const float WebView::minPageScaleFactor = 0.25f; 319 const float WebView::minPageScaleFactor = 0.25f;
217 const float WebView::maxPageScaleFactor = 4.0f; 320 const float WebView::maxPageScaleFactor = 4.0f;
218 321
(...skipping 1428 matching lines...) Expand 10 before | Expand all | Expand 10 after
1647 { 1750 {
1648 if (m_shouldAutoResize || m_size == newSize) 1751 if (m_shouldAutoResize || m_size == newSize)
1649 return; 1752 return;
1650 1753
1651 FrameView* view = mainFrameImpl()->frameView(); 1754 FrameView* view = mainFrameImpl()->frameView();
1652 if (!view) 1755 if (!view)
1653 return; 1756 return;
1654 1757
1655 WebSize oldSize = m_size; 1758 WebSize oldSize = m_size;
1656 float oldPageScaleFactor = pageScaleFactor(); 1759 float oldPageScaleFactor = pageScaleFactor();
1657 IntSize oldScrollOffset = view->scrollOffset(); 1760 float oldMinimumPageScaleFactor = m_minimumPageScaleFactor;
1658 int oldFixedLayoutWidth = fixedLayoutSize().width; 1761 int oldFixedLayoutWidth = fixedLayoutSize().width;
1762 int oldContentsWidth = contentsSize().width();
1659 1763
1660 m_size = newSize; 1764 m_size = newSize;
1661 1765
1662 #if ENABLE(VIEWPORT) 1766 #if ENABLE(VIEWPORT)
1767 ViewportAnchor viewportAnchor(mainFrameImpl()->frame()->eventHandler());
1768 if (settings()->viewportEnabled())
1769 viewportAnchor.setAnchor(view->visibleContentRect(),
1770 FloatSize(viewportAnchorXCoord, viewportAnchorY Coord));
1771
1663 ViewportArguments viewportArguments = mainFrameImpl()->frame()->document()-> viewportArguments(); 1772 ViewportArguments viewportArguments = mainFrameImpl()->frame()->document()-> viewportArguments();
1664 m_page->chrome()->client()->dispatchViewportPropertiesDidChange(viewportArgu ments); 1773 m_page->chrome()->client()->dispatchViewportPropertiesDidChange(viewportArgu ments);
1665 #endif 1774 #endif
1666 1775
1667 WebDevToolsAgentPrivate* agentPrivate = devToolsAgentPrivate(); 1776 WebDevToolsAgentPrivate* agentPrivate = devToolsAgentPrivate();
1668 if (agentPrivate) 1777 if (agentPrivate)
1669 agentPrivate->webViewResized(newSize); 1778 agentPrivate->webViewResized(newSize);
1670 if (!agentPrivate || !agentPrivate->metricsOverridden()) { 1779 if (!agentPrivate || !agentPrivate->metricsOverridden()) {
1671 WebFrameImpl* webFrame = mainFrameImpl(); 1780 WebFrameImpl* webFrame = mainFrameImpl();
1672 if (webFrame->frameView()) 1781 if (webFrame->frameView())
1673 webFrame->frameView()->resize(m_size); 1782 webFrame->frameView()->resize(m_size);
1674 } 1783 }
1675 1784
1676 #if ENABLE(VIEWPORT) 1785 #if ENABLE(VIEWPORT)
1677 if (settings()->viewportEnabled()) { 1786 if (settings()->viewportEnabled()) {
1678 // Relayout immediately to recalculate the minimum scale limit. 1787 // Relayout immediately to recalculate the minimum scale limit.
1679 if (view->needsLayout()) 1788 if (view->needsLayout())
1680 view->layout(); 1789 view->layout();
1681 1790
1682 // When the device rotates: 1791 // The minimum scale limit may change as a result of layout content
1683 // - If the page width is unchanged, then zoom by new width/old width 1792 // changes; in this case, scale relative to the change in content width.
1684 // such as to keep the same content horizontally onscreen. 1793 // Otherwise scale relative to the change in layout width.
1685 // - If the page width stretches proportionally to the change in 1794 // Don't do any scaling if the old width was zero (i.e., first resize).
1686 // screen width, then don't zoom at all (assuming the content has 1795 float scalingWidthRatio = 1;
1687 // scaled uniformly, then the same content will be horizontally 1796 if (oldSize.width && oldContentsWidth && m_minimumPageScaleFactor != old MinimumPageScaleFactor)
1688 // onscreen). 1797 scalingWidthRatio = contentsSize().width() / (float) oldContentsWidt h;
1689 // - If the page width partially stretches, then zoom partially to 1798 else if (oldFixedLayoutWidth)
1690 // make up the difference. 1799 scalingWidthRatio = fixedLayoutSize().width / (float) oldFixedLayout Width;
1691 // In all cases try to keep the same content at the top of the screen. 1800
1692 float viewportWidthRatio = !oldSize.width ? 1 : newSize.width / (float) oldSize.width; 1801 float viewportWidthRatio = !oldSize.width ? 1 : newSize.width / (float) oldSize.width;
1693 float fixedLayoutWidthRatio = !oldFixedLayoutWidth ? 1 : fixedLayoutSize ().width / (float) oldFixedLayoutWidth; 1802 float scaleMultiplier = viewportWidthRatio / scalingWidthRatio;
1694 float scaleMultiplier = viewportWidthRatio / fixedLayoutWidthRatio; 1803
1695 if (scaleMultiplier != 1) 1804 IntSize viewportSize = view->visibleContentRect().size();
1696 setPageScaleFactor(oldPageScaleFactor * scaleMultiplier, WebPoint(ol dScrollOffset.width(), oldScrollOffset.height())); 1805 if (scaleMultiplier != 1) {
1806 float newPageScaleFactor = oldPageScaleFactor * scaleMultiplier;
1807 viewportSize.scale(pageScaleFactor() / newPageScaleFactor);
1808 IntPoint scrollOffsetAtNewScale = viewportAnchor.computeOrigin(viewp ortSize);
1809 setPageScaleFactor(newPageScaleFactor, scrollOffsetAtNewScale);
1810 } else {
1811 IntPoint scrollOffsetAtNewScale = clampOffsetAtScale(viewportAnchor. computeOrigin(viewportSize), pageScaleFactor());
1812 updateMainFrameScrollPosition(scrollOffsetAtNewScale, false);
1813 }
1697 } 1814 }
1698 #endif 1815 #endif
1699 1816
1700 sendResizeEventAndRepaint(); 1817 sendResizeEventAndRepaint();
1701 } 1818 }
1702 1819
1703 void WebViewImpl::willEndLiveResize() 1820 void WebViewImpl::willEndLiveResize()
1704 { 1821 {
1705 if (mainFrameImpl() && mainFrameImpl()->frameView()) 1822 if (mainFrameImpl() && mainFrameImpl()->frameView())
1706 mainFrameImpl()->frameView()->willEndLiveResize(); 1823 mainFrameImpl()->frameView()->willEndLiveResize();
(...skipping 2485 matching lines...) Expand 10 before | Expand all | Expand 10 after
4192 } 4309 }
4193 4310
4194 bool WebViewImpl::shouldDisableDesktopWorkarounds() 4311 bool WebViewImpl::shouldDisableDesktopWorkarounds()
4195 { 4312 {
4196 ViewportArguments arguments = mainFrameImpl()->frame()->document()->viewport Arguments(); 4313 ViewportArguments arguments = mainFrameImpl()->frame()->document()->viewport Arguments();
4197 return arguments.width == ViewportArguments::ValueDeviceWidth || !arguments. userZoom 4314 return arguments.width == ViewportArguments::ValueDeviceWidth || !arguments. userZoom
4198 || (arguments.minZoom == arguments.maxZoom && arguments.minZoom != Viewp ortArguments::ValueAuto); 4315 || (arguments.minZoom == arguments.maxZoom && arguments.minZoom != Viewp ortArguments::ValueAuto);
4199 } 4316 }
4200 4317
4201 } // namespace WebKit 4318 } // namespace WebKit
OLDNEW
« no previous file with comments | « no previous file | Source/WebKit/chromium/tests/WebFrameTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698