<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[181488] trunk/Source</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/181488">181488</a></dd>
<dt>Author</dt> <dd>timothy_horton@apple.com</dd>
<dt>Date</dt> <dd>2015-03-13 14:07:06 -0700 (Fri, 13 Mar 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Sites that use a device-width viewport but don't have enough height to fill the view are scaled up
https://bugs.webkit.org/show_bug.cgi?id=142664
&lt;rdar://problem/18859470&gt;

Reviewed by Benjamin Poulain.

* page/ViewportConfiguration.cpp:
(WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints):
(WebCore::ViewportConfiguration::shouldIgnoreVerticalScalingConstraints):
(WebCore::ViewportConfiguration::shouldIgnoreScalingConstraints):
Split shouldIgnoreScalingConstraints into one for each dimension.

(WebCore::ViewportConfiguration::initialScale):
(WebCore::ViewportConfiguration::minimumScale):
Don't force the initial and minimum scales to cover the whole view if the
page claims to want to lay out to device width but then lays out too big.
This will allow pages that misbehave in this way to scale down further
than they previously could, but will result in a region of empty background
color being exposed at the initial/minimum scale.

(WebCore::ViewportConfiguration::description):
Update the logging to show each dimension separately.

* page/ViewportConfiguration.h:

* UIProcess/ios/WKScrollView.mm:
(-[WKScrollView _rubberBandOffsetForOffset:maxOffset:minOffset:range:outside:]):
Now that the WKContentView can (without pinching) be smaller than the unobscured
region of the WKWebView, we need to take that into account when deciding where
to retarget scrolling.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorepageViewportConfigurationcpp">trunk/Source/WebCore/page/ViewportConfiguration.cpp</a></li>
<li><a href="#trunkSourceWebCorepageViewportConfigurationh">trunk/Source/WebCore/page/ViewportConfiguration.h</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKScrollViewmm">trunk/Source/WebKit2/UIProcess/ios/WKScrollView.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (181487 => 181488)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-03-13 20:18:08 UTC (rev 181487)
+++ trunk/Source/WebCore/ChangeLog        2015-03-13 21:07:06 UTC (rev 181488)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2015-03-13  Timothy Horton  &lt;timothy_horton@apple.com&gt;
+
+        Sites that use a device-width viewport but don't have enough height to fill the view are scaled up
+        https://bugs.webkit.org/show_bug.cgi?id=142664
+        &lt;rdar://problem/18859470&gt;
+
+        Reviewed by Benjamin Poulain.
+
+        * page/ViewportConfiguration.cpp:
+        (WebCore::ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints):
+        (WebCore::ViewportConfiguration::shouldIgnoreVerticalScalingConstraints):
+        (WebCore::ViewportConfiguration::shouldIgnoreScalingConstraints):
+        Split shouldIgnoreScalingConstraints into one for each dimension.
+
+        (WebCore::ViewportConfiguration::initialScale):
+        (WebCore::ViewportConfiguration::minimumScale):
+        Don't force the initial and minimum scales to cover the whole view if the
+        page claims to want to lay out to device width but then lays out too big.
+        This will allow pages that misbehave in this way to scale down further
+        than they previously could, but will result in a region of empty background
+        color being exposed at the initial/minimum scale.
+
+        (WebCore::ViewportConfiguration::description):
+        Update the logging to show each dimension separately.
+
+        * page/ViewportConfiguration.h:
+
</ins><span class="cx"> 2015-03-13  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Replace TCSpinLock with a new WTF::SpinLock based on WTF::Atomic.
</span></span></pre></div>
<a id="trunkSourceWebCorepageViewportConfigurationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ViewportConfiguration.cpp (181487 => 181488)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ViewportConfiguration.cpp        2015-03-13 20:18:08 UTC (rev 181487)
+++ trunk/Source/WebCore/page/ViewportConfiguration.cpp        2015-03-13 21:07:06 UTC (rev 181488)
</span><span class="lines">@@ -97,7 +97,7 @@
</span><span class="cx">     return IntSize(layoutWidth(), layoutHeight());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-bool ViewportConfiguration::shouldIgnoreScalingConstraints() const
</del><ins>+bool ViewportConfiguration::shouldIgnoreHorizontalScalingConstraints() const
</ins><span class="cx"> {
</span><span class="cx">     if (!m_canIgnoreScalingConstraints)
</span><span class="cx">         return false;
</span><span class="lines">@@ -106,16 +106,29 @@
</span><span class="cx">     if (m_viewportArguments.width == ViewportArguments::ValueDeviceWidth)
</span><span class="cx">         return laidOutWiderThanViewport;
</span><span class="cx"> 
</span><ins>+    if (m_configuration.initialScaleIsSet &amp;&amp; m_configuration.initialScale == 1)
+        return laidOutWiderThanViewport;
+
+    return false;
+}
+
+bool ViewportConfiguration::shouldIgnoreVerticalScalingConstraints() const
+{
+    if (!m_canIgnoreScalingConstraints)
+        return false;
+
</ins><span class="cx">     bool laidOutTallerThanViewport = m_contentSize.height() &gt; layoutHeight();
</span><span class="cx">     if (m_viewportArguments.height == ViewportArguments::ValueDeviceHeight)
</span><span class="cx">         return laidOutTallerThanViewport;
</span><span class="cx"> 
</span><del>-    if (m_configuration.initialScaleIsSet &amp;&amp; m_configuration.initialScale == 1)
-        return laidOutWiderThanViewport;
-
</del><span class="cx">     return false;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool ViewportConfiguration::shouldIgnoreScalingConstraints() const
+{
+    return shouldIgnoreHorizontalScalingConstraints() || shouldIgnoreVerticalScalingConstraints();
+}
+
</ins><span class="cx"> double ViewportConfiguration::initialScale() const
</span><span class="cx"> {
</span><span class="cx">     ASSERT(!constraintsAreAllRelative(m_configuration));
</span><span class="lines">@@ -130,12 +143,12 @@
</span><span class="cx">     const FloatSize&amp; minimumLayoutSize = m_minimumLayoutSize;
</span><span class="cx">     double width = m_contentSize.width() &gt; 0 ? m_contentSize.width() : layoutWidth();
</span><span class="cx">     double initialScale = 0;
</span><del>-    if (width &gt; 0)
</del><ins>+    if (width &gt; 0 &amp;&amp; !shouldIgnoreVerticalScalingConstraints())
</ins><span class="cx">         initialScale = minimumLayoutSize.width() / width;
</span><span class="cx"> 
</span><del>-    // Prevent the intial scale from shrinking to a height smaller than our view's minimum height.
</del><ins>+    // Prevent the initial scale from shrinking to a height smaller than our view's minimum height.
</ins><span class="cx">     double height = m_contentSize.height() &gt; 0 ? m_contentSize.height() : layoutHeight();
</span><del>-    if (height &gt; 0 &amp;&amp; height * initialScale &lt; minimumLayoutSize.height())
</del><ins>+    if (height &gt; 0 &amp;&amp; height * initialScale &lt; minimumLayoutSize.height() &amp;&amp; !shouldIgnoreHorizontalScalingConstraints())
</ins><span class="cx">         initialScale = minimumLayoutSize.height() / height;
</span><span class="cx">     return std::min(std::max(initialScale, shouldIgnoreScalingConstraints() ? m_defaultConfiguration.minimumScale : m_configuration.minimumScale), m_configuration.maximumScale);
</span><span class="cx"> }
</span><span class="lines">@@ -151,11 +164,11 @@
</span><span class="cx"> 
</span><span class="cx">     const FloatSize&amp; minimumLayoutSize = m_minimumLayoutSize;
</span><span class="cx">     double contentWidth = m_contentSize.width();
</span><del>-    if (contentWidth &gt; 0 &amp;&amp; contentWidth * minimumScale &lt; minimumLayoutSize.width())
</del><ins>+    if (contentWidth &gt; 0 &amp;&amp; contentWidth * minimumScale &lt; minimumLayoutSize.width() &amp;&amp; !shouldIgnoreVerticalScalingConstraints())
</ins><span class="cx">         minimumScale = minimumLayoutSize.width() / contentWidth;
</span><span class="cx"> 
</span><span class="cx">     double contentHeight = m_contentSize.height();
</span><del>-    if (contentHeight &gt; 0 &amp;&amp; contentHeight * minimumScale &lt; minimumLayoutSize.height())
</del><ins>+    if (contentHeight &gt; 0 &amp;&amp; contentHeight * minimumScale &lt; minimumLayoutSize.height() &amp;&amp; !shouldIgnoreHorizontalScalingConstraints())
</ins><span class="cx">         minimumScale = minimumLayoutSize.height() / contentHeight;
</span><span class="cx"> 
</span><span class="cx">     minimumScale = std::min(std::max(minimumScale, m_configuration.minimumScale), m_configuration.maximumScale);
</span><span class="lines">@@ -490,7 +503,9 @@
</span><span class="cx">     ts.writeIndent();
</span><span class="cx">     ts &lt;&lt; &quot;(computed layout size &quot; &lt;&lt; layoutSize() &lt;&lt; &quot;)\n&quot;;
</span><span class="cx">     ts.writeIndent();
</span><del>-    ts &lt;&lt; &quot;(ignoring scaling constraints &quot; &lt;&lt; (shouldIgnoreScalingConstraints() ? &quot;true&quot; : &quot;false&quot;) &lt;&lt; &quot;)&quot;;
</del><ins>+    ts &lt;&lt; &quot;(ignoring horizontal scaling constraints &quot; &lt;&lt; (shouldIgnoreHorizontalScalingConstraints() ? &quot;true&quot; : &quot;false&quot;) &lt;&lt; &quot;)\n&quot;;
+    ts.writeIndent();
+    ts &lt;&lt; &quot;(ignoring vertical scaling constraints &quot; &lt;&lt; (shouldIgnoreVerticalScalingConstraints() ? &quot;true&quot; : &quot;false&quot;) &lt;&lt; &quot;)&quot;;
</ins><span class="cx">     ts.decreaseIndent();
</span><span class="cx"> 
</span><span class="cx">     ts &lt;&lt; &quot;)\n&quot;;
</span></span></pre></div>
<a id="trunkSourceWebCorepageViewportConfigurationh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/ViewportConfiguration.h (181487 => 181488)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/ViewportConfiguration.h        2015-03-13 20:18:08 UTC (rev 181487)
+++ trunk/Source/WebCore/page/ViewportConfiguration.h        2015-03-13 21:07:06 UTC (rev 181488)
</span><span class="lines">@@ -101,7 +101,10 @@
</span><span class="cx">     double viewportArgumentsLength(double length) const;
</span><span class="cx">     int layoutWidth() const;
</span><span class="cx">     int layoutHeight() const;
</span><ins>+
</ins><span class="cx">     bool shouldIgnoreScalingConstraints() const;
</span><ins>+    bool shouldIgnoreVerticalScalingConstraints() const;
+    bool shouldIgnoreHorizontalScalingConstraints() const;
</ins><span class="cx"> 
</span><span class="cx">     Parameters m_configuration;
</span><span class="cx">     Parameters m_defaultConfiguration;
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (181487 => 181488)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2015-03-13 20:18:08 UTC (rev 181487)
+++ trunk/Source/WebKit2/ChangeLog        2015-03-13 21:07:06 UTC (rev 181488)
</span><span class="lines">@@ -1,3 +1,17 @@
</span><ins>+2015-03-13  Timothy Horton  &lt;timothy_horton@apple.com&gt;
+
+        Sites that use a device-width viewport but don't have enough height to fill the view are scaled up
+        https://bugs.webkit.org/show_bug.cgi?id=142664
+        &lt;rdar://problem/18859470&gt;
+
+        Reviewed by Benjamin Poulain.
+
+        * UIProcess/ios/WKScrollView.mm:
+        (-[WKScrollView _rubberBandOffsetForOffset:maxOffset:minOffset:range:outside:]):
+        Now that the WKContentView can (without pinching) be smaller than the unobscured
+        region of the WKWebView, we need to take that into account when deciding where
+        to retarget scrolling.
+
</ins><span class="cx"> 2015-03-13  Mark Lam  &lt;mark.lam@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Replace TCSpinLock with a new WTF::SpinLock based on WTF::Atomic.
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKScrollViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKScrollView.mm (181487 => 181488)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKScrollView.mm        2015-03-13 20:18:08 UTC (rev 181487)
+++ trunk/Source/WebKit2/UIProcess/ios/WKScrollView.mm        2015-03-13 21:07:06 UTC (rev 181488)
</span><span class="lines">@@ -176,6 +176,11 @@
</span><span class="cx">     CGRect bounds = self.bounds;
</span><span class="cx"> 
</span><span class="cx">     CGFloat minimalHorizontalRange = bounds.size.width - contentInsets.left - contentInsets.right;
</span><ins>+    CGFloat contentWidthAtMinimumScale = contentSize.width * (self.minimumZoomScale / self.zoomScale);
+    if (contentWidthAtMinimumScale &lt; minimalHorizontalRange) {
+        CGFloat unobscuredEmptyHorizontalMarginAtMinimumScale = minimalHorizontalRange - contentWidthAtMinimumScale;
+        minimalHorizontalRange -= unobscuredEmptyHorizontalMarginAtMinimumScale;
+    }
</ins><span class="cx">     if (contentSize.width &lt; minimalHorizontalRange) {
</span><span class="cx">         if (valuesAreWithinOnePixel(minOffset, -contentInsets.left)
</span><span class="cx">             &amp;&amp; valuesAreWithinOnePixel(maxOffset, contentSize.width + contentInsets.right - bounds.size.width)
</span><span class="lines">@@ -188,6 +193,11 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     CGFloat minimalVerticalRange = bounds.size.height - contentInsets.top - contentInsets.bottom;
</span><ins>+    CGFloat contentHeightAtMinimumScale = contentSize.height * (self.minimumZoomScale / self.zoomScale);
+    if (contentHeightAtMinimumScale &lt; minimalVerticalRange) {
+        CGFloat unobscuredEmptyVerticalMarginAtMinimumScale = minimalVerticalRange - contentHeightAtMinimumScale;
+        minimalVerticalRange -= unobscuredEmptyVerticalMarginAtMinimumScale;
+    }
</ins><span class="cx">     if (contentSize.height &lt; minimalVerticalRange) {
</span><span class="cx">         if (valuesAreWithinOnePixel(minOffset, -contentInsets.top)
</span><span class="cx">             &amp;&amp; valuesAreWithinOnePixel(maxOffset, contentSize.height + contentInsets.bottom - bounds.size.height)
</span></span></pre>
</div>
</div>

</body>
</html>