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

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: 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
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 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
192 // The following constants control parameters for automated scaling of webpages 192 // The following constants control parameters for automated scaling of webpages
193 // (such as due to a double tap gesture or find in page etc.). These are 193 // (such as due to a double tap gesture or find in page etc.). These are
194 // experimentally determined. 194 // experimentally determined.
195 static const int touchPointPadding = 32; 195 static const int touchPointPadding = 32;
196 static const int nonUserInitiatedPointPadding = 11; 196 static const int nonUserInitiatedPointPadding = 11;
197 static const float minScaleDifference = 0.01f; 197 static const float minScaleDifference = 0.01f;
198 static const float doubleTapZoomContentDefaultMargin = 5; 198 static const float doubleTapZoomContentDefaultMargin = 5;
199 static const float doubleTapZoomContentMinimumMargin = 2; 199 static const float doubleTapZoomContentMinimumMargin = 2;
200 static const double doubleTapZoomAnimationDurationInSeconds = 0.25; 200 static const double doubleTapZoomAnimationDurationInSeconds = 0.25;
201 static const float doubleTapZoomAlreadyLegibleRatio = 1.2f; 201 static const float doubleTapZoomAlreadyLegibleRatio = 1.2f;
202 static const float viewportAnchorRelativeEpsilon = 0.1f;
202 203
203 // Constants for zooming in on a focused text field. 204 // Constants for zooming in on a focused text field.
204 static const double scrollAndScaleAnimationDurationInSeconds = 0.2; 205 static const double scrollAndScaleAnimationDurationInSeconds = 0.2;
205 static const int minReadableCaretHeight = 18; 206 static const int minReadableCaretHeight = 18;
206 static const float minScaleChangeToTriggerZoom = 1.05f; 207 static const float minScaleChangeToTriggerZoom = 1.05f;
207 static const float leftBoxRatio = 0.3f; 208 static const float leftBoxRatio = 0.3f;
208 static const int caretPadding = 10; 209 static const int caretPadding = 10;
209 210
210 namespace WebKit { 211 namespace WebKit {
211 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 {
223 public:
224 ViewportAnchor(EventHandler* eventHandler)
225 : m_eventHandler(eventHandler)
226 {
227 ASSERT(m_eventHandler);
aelias_OOO_until_Jul13 2013/04/08 04:24:52 This type of assertion is not an idiom in WebKit,
jdduke (slow) 2013/04/10 16:58:19 Done.
228 }
229
230 void setAnchor(const IntRect& viewRect, const FloatSize& anchorInViewCoords)
231 {
232 m_viewRect = viewRect;
233 m_anchorNode.clear();
234 m_anchorNodeBounds = LayoutRect();
235 m_anchorInNodeCoords = FloatSize();
236 m_anchorInViewCoords = anchorInViewCoords;
237
238 if (viewRect.isEmpty())
239 return;
240
241 // Preserve origins at the absolute screen origin
242 if (viewRect.location() == IntPoint::zero())
243 return;
244
245 FloatSize anchorOffset = FloatSize(viewRect.size());
aelias_OOO_until_Jul13 2013/04/08 04:24:52 = viewRect.size()
jdduke (slow) 2013/04/10 16:58:19 Done.
246 anchorOffset.scale(anchorInViewCoords.width(), anchorInViewCoords.height ());
247 const FloatPoint anchorPoint = FloatPoint(viewRect.location()) + anchorO ffset;
248
249 Node* node = findNonEmptyAnchorNode(flooredIntPoint(anchorPoint), viewRe ct, m_eventHandler);
250 if (!node)
251 return;
252
253 m_anchorNode = node;
254 m_anchorNodeBounds = node->Node::boundingBox();
aelias_OOO_until_Jul13 2013/04/08 04:24:52 node->boundingBox(). The Node:: you copied from s
jdduke (slow) 2013/04/10 16:58:19 Done.
255
256 m_anchorInNodeCoords = anchorPoint - m_anchorNodeBounds.location();
257 m_anchorInNodeCoords.scale(1.f / m_anchorNodeBounds.width(), 1.f / m_anc horNodeBounds.height());
aelias_OOO_until_Jul13 2013/04/08 04:24:52 Delete .f
jdduke (slow) 2013/04/10 16:58:19 Without the .f, int / LayoutUnit performs integer
258 }
259
260 // Note: No guarantees are made on the validity of the returned point.
aelias_OOO_until_Jul13 2013/04/08 04:24:52 This comment is too scary and not very useful. Ca
jdduke (slow) 2013/04/10 16:58:19 Done.
261 // It is up to the caller to ensure the point is properly bounded for
262 // the relevant use-case.
263 IntPoint computeOrigin(const IntSize& currentViewSize) const
264 {
265 if (!m_anchorNode || !m_anchorNode->inDocument())
266 return m_viewRect.location();
267
268 const LayoutRect currentNodeBounds = m_anchorNode->Node::boundingBox();
aelias_OOO_until_Jul13 2013/04/08 04:24:52 m_anchorNode->boundingBox()
jdduke (slow) 2013/04/10 16:58:19 Done.
269 if (m_anchorNodeBounds == currentNodeBounds)
270 return m_viewRect.location();
271
272 // Compute the new anchor point relative to the node position
273 FloatSize anchorOffsetFromNode = currentNodeBounds.size();
274 anchorOffsetFromNode.scale(m_anchorInNodeCoords.width(), m_anchorInNodeC oords.height());
275 FloatPoint anchorPoint = currentNodeBounds.location() + anchorOffsetFrom Node;
276
277 // Compute the new origin point relative to the new anchor point
278 FloatSize anchorOffsetFromOrigin = FloatSize(currentViewSize);
aelias_OOO_until_Jul13 2013/04/08 04:24:52 = currentViewSize;
jdduke (slow) 2013/04/10 16:58:19 Done.
279 anchorOffsetFromOrigin.scale(m_anchorInViewCoords.width(), m_anchorInVie wCoords.height());
280 return flooredIntPoint(anchorPoint - anchorOffsetFromOrigin);
281 }
282
283 private:
284 ViewportAnchor();
285 ViewportAnchor& operator=(ViewportAnchor&);
aelias_OOO_until_Jul13 2013/04/08 04:24:52 Not a common idiom to have a private operator=, pl
jdduke (slow) 2013/04/10 16:58:19 Done.
286
287 static Node* findNonEmptyAnchorNode(const IntPoint& point, const IntRect& vi ewRect, EventHandler* eventHandler)
288 {
289 Node* node = eventHandler->hitTestResultAtPoint(point).innerNode();
290
291 // If the node bounding box contains the view, make a single attempt to
292 // find a smaller node; the larger the node bounds, the greater the
293 // variability under resize.
294 if (node && node->Node::pixelSnappedBoundingBox().contains(viewRect)) {
aelias_OOO_until_Jul13 2013/04/08 04:24:52 node->boundingBox() ?
jdduke (slow) 2013/04/10 16:58:19 Done.
295 IntSize pointOffset = viewRect.size();
296 pointOffset.scale(viewportAnchorRelativeEpsilon);
297 IntPoint shiftedPoint = point + pointOffset;
aelias_OOO_until_Jul13 2013/04/08 04:24:52 Please delete this local variable.
jdduke (slow) 2013/04/10 16:58:19 Done.
298 node = eventHandler->hitTestResultAtPoint(shiftedPoint).innerNode();
299 }
300
301 while (node && node->Node::boundingBox().isEmpty())
aelias_OOO_until_Jul13 2013/04/08 04:24:52 Switch to node->boundingBox().
jdduke (slow) 2013/04/10 16:58:19 Done.
302 node = node->parentNode();
303
304 return node;
305 }
306
307 EventHandler* m_eventHandler;
308
309 IntRect m_viewRect;
310
311 RefPtr<Node> m_anchorNode;
312 LayoutRect m_anchorNodeBounds;
313
314 FloatSize m_anchorInViewCoords;
315 FloatSize m_anchorInNodeCoords;
316 };
317 }
318 #endif // ENABLE(VIEWPORT)
319
212 // Change the text zoom level by kTextSizeMultiplierRatio each time the user 320 // Change the text zoom level by kTextSizeMultiplierRatio each time the user
213 // zooms text in or out (ie., change by 20%). The min and max values limit 321 // zooms text in or out (ie., change by 20%). The min and max values limit
214 // text zoom to half and 3x the original text size. These three values match 322 // text zoom to half and 3x the original text size. These three values match
215 // those in Apple's port in WebKit/WebKit/WebView/WebView.mm 323 // those in Apple's port in WebKit/WebKit/WebView/WebView.mm
216 const double WebView::textSizeMultiplierRatio = 1.2; 324 const double WebView::textSizeMultiplierRatio = 1.2;
217 const double WebView::minTextSizeMultiplier = 0.5; 325 const double WebView::minTextSizeMultiplier = 0.5;
218 const double WebView::maxTextSizeMultiplier = 3.0; 326 const double WebView::maxTextSizeMultiplier = 3.0;
219 const float WebView::minPageScaleFactor = 0.25f; 327 const float WebView::minPageScaleFactor = 0.25f;
220 const float WebView::maxPageScaleFactor = 4.0f; 328 const float WebView::maxPageScaleFactor = 4.0f;
221 329
(...skipping 1441 matching lines...) Expand 10 before | Expand all | Expand 10 after
1663 { 1771 {
1664 if (m_shouldAutoResize || m_size == newSize) 1772 if (m_shouldAutoResize || m_size == newSize)
1665 return; 1773 return;
1666 1774
1667 FrameView* view = mainFrameImpl()->frameView(); 1775 FrameView* view = mainFrameImpl()->frameView();
1668 if (!view) 1776 if (!view)
1669 return; 1777 return;
1670 1778
1671 WebSize oldSize = m_size; 1779 WebSize oldSize = m_size;
1672 float oldPageScaleFactor = pageScaleFactor(); 1780 float oldPageScaleFactor = pageScaleFactor();
1673 IntSize oldScrollOffset = view->scrollOffset(); 1781 float oldMinimumPageScaleFactor = m_minimumPageScaleFactor;
1782 int oldContentsWidth = contentsSize().width();
1674 int oldFixedLayoutWidth = fixedLayoutSize().width; 1783 int oldFixedLayoutWidth = fixedLayoutSize().width;
1675 1784
1676 m_size = newSize; 1785 m_size = newSize;
1677 1786
1678 #if ENABLE(VIEWPORT) 1787 #if ENABLE(VIEWPORT)
1788 ViewportAnchor viewportAnchor(mainFrameImpl()->frame()->eventHandler());
1789 if (settings()->viewportEnabled())
1790 viewportAnchor.setAnchor(view->visibleContentRect(), FloatSize(0.5f, 0)) ;
aelias_OOO_until_Jul13 2013/04/08 04:24:52 FloatSize(0.5f, 0) looks like a magic number, plea
jdduke (slow) 2013/04/10 16:58:19 Done.
jdduke (slow) 2013/04/10 16:58:19 Done.
1791
1679 ViewportArguments viewportArguments = mainFrameImpl()->frame()->document()-> viewportArguments(); 1792 ViewportArguments viewportArguments = mainFrameImpl()->frame()->document()-> viewportArguments();
1680 m_page->chrome()->client()->dispatchViewportPropertiesDidChange(viewportArgu ments); 1793 m_page->chrome()->client()->dispatchViewportPropertiesDidChange(viewportArgu ments);
1681 #endif 1794 #endif
1682 1795
1683 WebDevToolsAgentPrivate* agentPrivate = devToolsAgentPrivate(); 1796 WebDevToolsAgentPrivate* agentPrivate = devToolsAgentPrivate();
1684 if (agentPrivate) 1797 if (agentPrivate)
1685 agentPrivate->webViewResized(newSize); 1798 agentPrivate->webViewResized(newSize);
1686 if (!agentPrivate || !agentPrivate->metricsOverridden()) { 1799 if (!agentPrivate || !agentPrivate->metricsOverridden()) {
1687 WebFrameImpl* webFrame = mainFrameImpl(); 1800 WebFrameImpl* webFrame = mainFrameImpl();
1688 if (webFrame->frameView()) 1801 if (webFrame->frameView())
1689 webFrame->frameView()->resize(m_size); 1802 webFrame->frameView()->resize(m_size);
1690 } 1803 }
1691 1804
1692 #if ENABLE(VIEWPORT) 1805 #if ENABLE(VIEWPORT)
1693 if (settings()->viewportEnabled()) { 1806 if (settings()->viewportEnabled()) {
1694 // Relayout immediately to recalculate the minimum scale limit. 1807 // Relayout immediately to recalculate the minimum scale limit.
1695 if (view->needsLayout()) 1808 if (view->needsLayout())
1696 view->layout(); 1809 view->layout();
1697 1810
1698 // When the device rotates: 1811 // When the device rotates:
aelias_OOO_until_Jul13 2013/04/08 04:24:52 This comment is out of date, could you delete/upda
jdduke (slow) 2013/04/10 16:58:19 Done.
1699 // - If the page width is unchanged, then zoom by new width/old width 1812 // - If the page width is unchanged, then zoom by new width/old width
1700 // such as to keep the same content horizontally onscreen. 1813 // such as to keep the same content horizontally onscreen.
1701 // - If the page width stretches proportionally to the change in 1814 // - If the page width stretches proportionally to the change in
1702 // screen width, then don't zoom at all (assuming the content has 1815 // screen width, then don't zoom at all (assuming the content has
1703 // scaled uniformly, then the same content will be horizontally 1816 // scaled uniformly, then the same content will be horizontally
1704 // onscreen). 1817 // onscreen).
1705 // - If the page width partially stretches, then zoom partially to 1818 // - If the page width partially stretches, then zoom partially to
1706 // make up the difference. 1819 // make up the difference.
1820 // - If the resized content triggers a change in minimum scale limit,
1821 // zoom relative to the change in content width.
1707 // In all cases try to keep the same content at the top of the screen. 1822 // In all cases try to keep the same content at the top of the screen.
1823 IntSize viewportSize = view->visibleContentRect().size();
1708 float viewportWidthRatio = !oldSize.width ? 1 : newSize.width / (float) oldSize.width; 1824 float viewportWidthRatio = !oldSize.width ? 1 : newSize.width / (float) oldSize.width;
1709 float fixedLayoutWidthRatio = !oldFixedLayoutWidth ? 1 : fixedLayoutSize ().width / (float) oldFixedLayoutWidth; 1825 float fixedLayoutWidthRatio = !oldFixedLayoutWidth ? 1 : fixedLayoutSize ().width / (float) oldFixedLayoutWidth;
1710 float scaleMultiplier = viewportWidthRatio / fixedLayoutWidthRatio; 1826 float contentsWidthRatio = !oldContentsWidth ? 1 : contentsSize().width( ) / (float) oldContentsWidth;
1711 if (scaleMultiplier != 1) 1827 float scaleMultiplier = m_minimumPageScaleFactor == oldMinimumPageScaleF actor ?
aelias_OOO_until_Jul13 2013/04/08 04:24:52 Too much for ternary operator, please make into an
jdduke (slow) 2013/04/10 16:58:19 Done.
1712 setPageScaleFactor(oldPageScaleFactor * scaleMultiplier, WebPoint(ol dScrollOffset.width(), oldScrollOffset.height())); 1828 viewportWidthRatio / fixedLayoutWidthRatio : viewportWidthRatio / co ntentsWidthRatio;
1829 if (scaleMultiplier != 1) {
1830 float newPageScaleFactor = oldPageScaleFactor * scaleMultiplier;
1831 viewportSize.scale(pageScaleFactor() / newPageScaleFactor);
1832 IntPoint scrollOffsetAtNewScale = viewportAnchor.computeOrigin(viewp ortSize);
1833 setPageScaleFactor(newPageScaleFactor, scrollOffsetAtNewScale);
1834 } else {
1835 IntPoint scrollOffsetAtNewScale = clampOffsetAtScale(viewportAnchor. computeOrigin(viewportSize), pageScaleFactor());
1836 updateMainFrameScrollPosition(scrollOffsetAtNewScale, false);
1837 }
1713 } 1838 }
1714 #endif 1839 #endif
1715 1840
1716 sendResizeEventAndRepaint(); 1841 sendResizeEventAndRepaint();
1717 } 1842 }
1718 1843
1719 void WebViewImpl::willEndLiveResize() 1844 void WebViewImpl::willEndLiveResize()
1720 { 1845 {
1721 if (mainFrameImpl() && mainFrameImpl()->frameView()) 1846 if (mainFrameImpl() && mainFrameImpl()->frameView())
1722 mainFrameImpl()->frameView()->willEndLiveResize(); 1847 mainFrameImpl()->frameView()->willEndLiveResize();
(...skipping 2558 matching lines...) Expand 10 before | Expand all | Expand 10 after
4281 #endif 4406 #endif
4282 4407
4283 bool WebViewImpl::shouldDisableDesktopWorkarounds() 4408 bool WebViewImpl::shouldDisableDesktopWorkarounds()
4284 { 4409 {
4285 ViewportArguments arguments = mainFrameImpl()->frame()->document()->viewport Arguments(); 4410 ViewportArguments arguments = mainFrameImpl()->frame()->document()->viewport Arguments();
4286 return arguments.width == ViewportArguments::ValueDeviceWidth || !arguments. userZoom 4411 return arguments.width == ViewportArguments::ValueDeviceWidth || !arguments. userZoom
4287 || (arguments.minZoom == arguments.maxZoom && arguments.minZoom != Viewp ortArguments::ValueAuto); 4412 || (arguments.minZoom == arguments.maxZoom && arguments.minZoom != Viewp ortArguments::ValueAuto);
4288 } 4413 }
4289 4414
4290 } // namespace WebKit 4415 } // namespace WebKit
OLDNEW
« no previous file with comments | « no previous file | Source/WebKit/chromium/tests/WebFrameTest.cpp » ('j') | Source/WebKit/chromium/tests/WebFrameTest.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698