<!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>[170325] 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/170325">170325</a></dd>
<dt>Author</dt> <dd>benjamin@webkit.org</dd>
<dt>Date</dt> <dd>2014-06-23 15:05:47 -0700 (Mon, 23 Jun 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>[iOS][WK2] Make the state restore from HistoryItem more precise and reliable
https://bugs.webkit.org/show_bug.cgi?id=134150

Patch by Benjamin Poulain &lt;bpoulain@apple.com&gt; on 2014-06-23
Reviewed by Tim Horton.


Source/WebCore: 
The two biggest changes for WebCore are:
-Store everything we need to handle changes of ViewportConfiguration on HistoryItem.
-Store the exposedRect with floating point coordinates.

* WebCore.exp.in:
* history/CachedPage.cpp:
(WebCore::CachedPage::restore):
We cannot determine a good scroll position from the WebProcess because the obscured insets can change
arbitrarily in the UIProcess. When we scroll here from the WebProcess, we would force an invalid position
to the UIProcess with the next layer tree update.

To avoid any problem, we prohibit scrolling when restoring the focus appearance.

* history/HistoryItem.cpp:
(WebCore::encodeRect):
(WebCore::encodeSize):
(WebCore::HistoryItem::encodeBackForwardTreeNode):
(WebCore::decodeRect):
(WebCore::decodeSize):
(WebCore::HistoryItem::decodeBackForwardTree):
* history/HistoryItem.h:
(WebCore::HistoryItem::exposedContentRect):
(WebCore::HistoryItem::setExposedContentRect):
(WebCore::HistoryItem::unobscuredContentRect):
(WebCore::HistoryItem::setUnobscuredContentRect):
(WebCore::HistoryItem::minimumLayoutSizeInScrollViewCoordinates):
(WebCore::HistoryItem::setMinimumLayoutSizeInScrollViewCoordinates):
(WebCore::HistoryItem::contentSize):
(WebCore::HistoryItem::setContentSize):
(WebCore::HistoryItem::exposedContentPosition): Deleted.
(WebCore::HistoryItem::setExposedContentPosition): Deleted.
* loader/HistoryController.cpp:
(WebCore::HistoryController::saveScrollPositionAndViewStateToItem):
* page/FrameView.h:
* platform/ScrollView.h:
* platform/ios/ScrollViewIOS.mm:
(WebCore::ScrollView::exposedContentRect):
(WebCore::ScrollView::setExposedContentRect):
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::didChangeVisibleRect):

Source/WebKit2: 
This patch make several little improvements to improve how we restore the visible content rect and scale
from the HistoryItem.

The biggest architectural change is that the exposed rect is now restored on the UIProcess instead of the WebProcess,
this ensure we restore the same position regardless of any modification of obscured areas.

* Shared/VisibleContentRectUpdateInfo.cpp:
(WebKit::VisibleContentRectUpdateInfo::encode):
(WebKit::VisibleContentRectUpdateInfo::decode):
* Shared/VisibleContentRectUpdateInfo.h:
(WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo):
(WebKit::VisibleContentRectUpdateInfo::lastLayerTreeTransactionId):
(WebKit::WebPage::updateVisibleContentRects):
* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
A race between the UIProcess and the WebProcess could cause the viewport of the next page to be influenced by updates
of the previous page. To avoid that, VisibleContentRectUpdateInfo keeps track of the last transaction seen at the time
of the update.

The WebProcess updates the size and scale of the content through layer tree updates. If an update was generated for a layer tree
update of the old page, none of the information is valid for the current content. Since the UIProcess drives the state in case of conflicts,
the WebProcess was updating the scale of the current page based on incorrect information.

To avoid the problems, we save the layer tree transaction ID when we commit a new page. Only updates after that transaction are useful
for the current page.

* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _processDidExit]):
(withinEpsilon):
(changeContentOffsetBoundedInValidRange):
(-[WKWebView _didCommitLayerTree:WebKit::]):
(-[WKWebView _restorePageStateToExposedRect:WebCore::scale:]):
(-[WKWebView _restorePageStateToUnobscuredCenter:WebCore::scale:]):
* UIProcess/API/Cocoa/WKWebViewInternal.h:
* UIProcess/PageClient.h:
* UIProcess/WebPageProxy.h:
* UIProcess/WebPageProxy.messages.in:
* UIProcess/ios/PageClientImplIOS.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::restorePageState):
(WebKit::PageClientImpl::restorePageCenterAndScale):
Restoring the state is now done by WKWebView. The state is only updated on the next layer tree commit,
this is done to avoid any jumping if the page has scrolled since we tried to restore its state.

Both update path end up calling _updateVisibleContentRects. This is because the update on the WebProcess
never sets the ScrollPosition (because it does not know the current state of the obscured insets). Pushing
a new VisibleContentRect will nicely udpates the exposed rect, scroll position, fixed elements, etc.

* UIProcess/ios/WKContentView.mm:
(-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::restorePageState):
(WebKit::WebPageProxy::restorePageCenterAndScale):
* UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h:
(WebKit::RemoteLayerTreeDrawingAreaProxy::lastCommittedLayerTreeTransactionID):
* UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
(WebKit::RemoteLayerTreeDrawingAreaProxy::RemoteLayerTreeDrawingAreaProxy):
* WebProcess/WebCoreSupport/ios/WebFrameLoaderClientIOS.mm:
(WebKit::WebFrameLoaderClient::saveViewStateToItem):
(WebKit::WebFrameLoaderClient::restoreViewState):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::WebPage):
(WebKit::WebPage::didCommitLoad):
* WebProcess/WebPage/WebPage.h:
Get rid of m_obscuredTopInset. It was a bad idea. The UIProcess updates the obscured insets a lot during
page load, the value we used to restore the scroll position was frequently stale.

(WebKit::WebPage::userHasChangedPageScaleFactor): Deleted.
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::savePageState):
(WebKit::scaleAfterViewportWidthChange):
(WebKit::relativeCenterAfterContentSizeChange):
(WebKit::adjustExposedRectForNewScale):
Extract this out of dynamicViewportSizeUpdate(). It is useful to adjust the exposed rect when restoring a HistoryItem
to a ViewportConfiguration that is different from when it was saved.

(WebKit::WebPage::restorePageState):
There are two variations of restorePage:
1) If the viewport configuration is compatible, restore the exact scale and position of the page.
2) Otherwise, restore the scale and position similarily to dynamicViewportSizeUpdate().

(WebKit::WebPage::dynamicViewportSizeUpdate):
(WebKit::WebPage::viewportConfigurationChanged):
(WebKit::adjustExposedRectForBoundedScale):
(WebKit::RemoteLayerTreeDrawingArea::currentTransactionID):
Expose the transactionID for the race issue on VisibleRectUpdate.

* WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
(WebKit::RemoteLayerTreeDrawingArea::setExposedContentRect):
Store the exposed rect in floating point coordinates. This makes it possible to restore that exact
position when needed.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreWebCoreexpin">trunk/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#trunkSourceWebCorehistoryCachedPagecpp">trunk/Source/WebCore/history/CachedPage.cpp</a></li>
<li><a href="#trunkSourceWebCorehistoryHistoryItemcpp">trunk/Source/WebCore/history/HistoryItem.cpp</a></li>
<li><a href="#trunkSourceWebCorehistoryHistoryItemh">trunk/Source/WebCore/history/HistoryItem.h</a></li>
<li><a href="#trunkSourceWebCoreloaderHistoryControllercpp">trunk/Source/WebCore/loader/HistoryController.cpp</a></li>
<li><a href="#trunkSourceWebCorepageFrameViewh">trunk/Source/WebCore/page/FrameView.h</a></li>
<li><a href="#trunkSourceWebCoreplatformScrollViewh">trunk/Source/WebCore/platform/ScrollView.h</a></li>
<li><a href="#trunkSourceWebCoreplatformiosScrollViewIOSmm">trunk/Source/WebCore/platform/ios/ScrollViewIOS.mm</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderLayerCompositorcpp">trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp</a></li>
<li><a href="#trunkSourceWebKit2ChangeLog">trunk/Source/WebKit2/ChangeLog</a></li>
<li><a href="#trunkSourceWebKit2SharedVisibleContentRectUpdateInfocpp">trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.cpp</a></li>
<li><a href="#trunkSourceWebKit2SharedVisibleContentRectUpdateInfoh">trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessAPICocoaWKWebViewInternalh">trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessPageClienth">trunk/Source/WebKit2/UIProcess/PageClient.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxyh">trunk/Source/WebKit2/UIProcess/WebPageProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessWebPageProxymessagesin">trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosPageClientImplIOSh">trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosPageClientImplIOSmm">trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWKContentViewmm">trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm">trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxyh">trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h</a></li>
<li><a href="#trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxymm">trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebCoreSupportiosWebFrameLoaderClientIOSmm">trunk/Source/WebKit2/WebProcess/WebCoreSupport/ios/WebFrameLoaderClientIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPagecpp">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageWebPageh">trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm">trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacRemoteLayerTreeDrawingAreah">trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h</a></li>
<li><a href="#trunkSourceWebKit2WebProcessWebPagemacRemoteLayerTreeDrawingAreamm">trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/ChangeLog        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -1,3 +1,51 @@
</span><ins>+2014-06-23  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
+
+        [iOS][WK2] Make the state restore from HistoryItem more precise and reliable
+        https://bugs.webkit.org/show_bug.cgi?id=134150
+
+        Reviewed by Tim Horton.
+
+        The two biggest changes for WebCore are:
+        -Store everything we need to handle changes of ViewportConfiguration on HistoryItem.
+        -Store the exposedRect with floating point coordinates.
+
+        * WebCore.exp.in:
+        * history/CachedPage.cpp:
+        (WebCore::CachedPage::restore):
+        We cannot determine a good scroll position from the WebProcess because the obscured insets can change
+        arbitrarily in the UIProcess. When we scroll here from the WebProcess, we would force an invalid position
+        to the UIProcess with the next layer tree update.
+
+        To avoid any problem, we prohibit scrolling when restoring the focus appearance.
+
+        * history/HistoryItem.cpp:
+        (WebCore::encodeRect):
+        (WebCore::encodeSize):
+        (WebCore::HistoryItem::encodeBackForwardTreeNode):
+        (WebCore::decodeRect):
+        (WebCore::decodeSize):
+        (WebCore::HistoryItem::decodeBackForwardTree):
+        * history/HistoryItem.h:
+        (WebCore::HistoryItem::exposedContentRect):
+        (WebCore::HistoryItem::setExposedContentRect):
+        (WebCore::HistoryItem::unobscuredContentRect):
+        (WebCore::HistoryItem::setUnobscuredContentRect):
+        (WebCore::HistoryItem::minimumLayoutSizeInScrollViewCoordinates):
+        (WebCore::HistoryItem::setMinimumLayoutSizeInScrollViewCoordinates):
+        (WebCore::HistoryItem::contentSize):
+        (WebCore::HistoryItem::setContentSize):
+        (WebCore::HistoryItem::exposedContentPosition): Deleted.
+        (WebCore::HistoryItem::setExposedContentPosition): Deleted.
+        * loader/HistoryController.cpp:
+        (WebCore::HistoryController::saveScrollPositionAndViewStateToItem):
+        * page/FrameView.h:
+        * platform/ScrollView.h:
+        * platform/ios/ScrollViewIOS.mm:
+        (WebCore::ScrollView::exposedContentRect):
+        (WebCore::ScrollView::setExposedContentRect):
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::didChangeVisibleRect):
+
</ins><span class="cx"> 2014-06-23  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [Mac] process raw VTT in-band captions
</span></span></pre></div>
<a id="trunkSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/WebCore.exp.in (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/WebCore.exp.in        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/WebCore.exp.in        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -2502,7 +2502,7 @@
</span><span class="cx"> __ZN7WebCore10CredentialC1EP13__SecIdentityPK9__CFArrayNS_21CredentialPersistenceE
</span><span class="cx"> __ZN7WebCore10RenderView35resumePausedImageAnimationsIfNeededEv
</span><span class="cx"> __ZN7WebCore10ScrollView15setScrollOffsetERKNS_8IntPointE
</span><del>-__ZN7WebCore10ScrollView21setExposedContentRectERKNS_7IntRectE
</del><ins>+__ZN7WebCore10ScrollView21setExposedContentRectERKNS_9FloatRectE
</ins><span class="cx"> __ZN7WebCore10ScrollView24setUnobscuredContentSizeERKNS_7IntSizeE
</span><span class="cx"> __ZN7WebCore10XLinkNames4initEv
</span><span class="cx"> __ZN7WebCore10inSameLineERKNS_15VisiblePositionES2_
</span><span class="lines">@@ -2779,6 +2779,7 @@
</span><span class="cx"> __ZNK7WebCore9FrameView17wasScrolledByUserEv
</span><span class="cx"> __ZNK7WebCore9FrameView30viewportConstrainedObjectsRectEv
</span><span class="cx"> __ZNK7WebCore9RenderBox11borderRadiiEv
</span><ins>+__ZNK7WebCore10ScrollView18exposedContentRectEv
</ins><span class="cx"> _webThreadShouldYield
</span><span class="cx"> _wkExecutableWasLinkedOnOrAfterIOSVersion
</span><span class="cx"> _wkGetAvailableScreenSize
</span></span></pre></div>
<a id="trunkSourceWebCorehistoryCachedPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/history/CachedPage.cpp (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/history/CachedPage.cpp        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/history/CachedPage.cpp        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2006, 2007, 2008, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -89,9 +89,18 @@
</span><span class="cx">         // We don't want focused nodes changing scroll position when restoring from the cache
</span><span class="cx">         // as it can cause ugly jumps before we manage to restore the cached position.
</span><span class="cx">         page.mainFrame().selection().suppressScrolling();
</span><ins>+
+        bool hadProhibitsScrolling = false;
+        FrameView* frameView = page.mainFrame().view();
+        if (frameView) {
+            hadProhibitsScrolling = frameView-&gt;prohibitsScrolling();
+            frameView-&gt;setProhibitsScrolling(true);
+        }
</ins><span class="cx"> #endif
</span><span class="cx">         element-&gt;updateFocusAppearance(true);
</span><span class="cx"> #if PLATFORM(IOS)
</span><ins>+        if (frameView)
+            frameView-&gt;setProhibitsScrolling(hadProhibitsScrolling);
</ins><span class="cx">         page.mainFrame().selection().restoreScrolling();
</span><span class="cx"> #endif
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebCorehistoryHistoryItemcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/history/HistoryItem.cpp (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/history/HistoryItem.cpp        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/history/HistoryItem.cpp        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2005, 2006, 2008, 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2005, 2006, 2008, 2011, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -592,6 +592,36 @@
</span><span class="cx">     });
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+static void encodeRect(Encoder&amp; encoder, const FloatRect&amp; floatRect)
+{
+    encoder.encodeFloat(floatRect.x());
+    encoder.encodeFloat(floatRect.y());
+    encoder.encodeFloat(floatRect.width());
+    encoder.encodeFloat(floatRect.height());
+}
+
+static void encodeRect(Encoder&amp; encoder, const IntRect&amp; intRect)
+{
+    encoder.encodeInt32(intRect.x());
+    encoder.encodeInt32(intRect.y());
+    encoder.encodeInt32(intRect.width());
+    encoder.encodeInt32(intRect.height());
+}
+
+static void encodeSize(Encoder&amp; encoder, const FloatSize&amp; floatSize)
+{
+    encoder.encodeFloat(floatSize.width());
+    encoder.encodeFloat(floatSize.height());
+}
+
+static void encodeSize(Encoder&amp; encoder, const IntSize&amp; intSize)
+{
+    encoder.encodeInt32(intSize.width());
+    encoder.encodeInt32(intSize.height());
+}
+#endif
+
</ins><span class="cx"> void HistoryItem::encodeBackForwardTreeNode(Encoder&amp; encoder) const
</span><span class="cx"> {
</span><span class="cx">     size_t size = m_children.size();
</span><span class="lines">@@ -633,6 +663,14 @@
</span><span class="cx">         encoder.encodeBytes(m_stateObject-&gt;data().data(), m_stateObject-&gt;data().size());
</span><span class="cx"> 
</span><span class="cx">     encoder.encodeString(m_target);
</span><ins>+
+#if PLATFORM(IOS)
+    encodeRect(encoder, m_exposedContentRect);
+    encodeRect(encoder, m_unobscuredContentRect);
+    encodeSize(encoder, m_minimumLayoutSizeInScrollViewCoordinates);
+    encodeSize(encoder, m_contentSize);
+    encoder.encodeBool(m_scaleIsInitial);
+#endif
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void HistoryItem::encodeBackForwardTreeNode(KeyedEncoder&amp; encoder) const
</span><span class="lines">@@ -687,6 +725,68 @@
</span><span class="cx">     }
</span><span class="cx"> };
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+static bool decodeRect(Decoder&amp; decoder, FloatRect&amp; floatRect)
+{
+    float x;
+    if (!decoder.decodeFloat(x))
+        return false;
+    float y;
+    if (!decoder.decodeFloat(y))
+        return false;
+    float width;
+    if (!decoder.decodeFloat(width))
+        return false;
+    float height;
+    if (!decoder.decodeFloat(height))
+        return false;
+    floatRect = FloatRect(x, y, width, height);
+    return true;
+}
+
+static bool decodeRect(Decoder&amp; decoder, IntRect&amp; intRect)
+{
+    int x;
+    if (!decoder.decodeInt32(x))
+        return false;
+    int y;
+    if (!decoder.decodeInt32(y))
+        return false;
+    int width;
+    if (!decoder.decodeInt32(width))
+        return false;
+    int height;
+    if (!decoder.decodeInt32(height))
+        return false;
+    intRect = IntRect(x, y, width, height);
+    return true;
+}
+
+static bool decodeSize(Decoder&amp; decoder, FloatSize&amp; floatSize)
+{
+    float width;
+    if (!decoder.decodeFloat(width))
+        return false;
+    float height;
+    if (!decoder.decodeFloat(height))
+        return false;
+    floatSize = FloatSize(width, height);
+    return true;
+}
+
+static bool decodeSize(Decoder&amp; decoder, IntSize&amp; intSize)
+{
+    int width;
+    if (!decoder.decodeInt32(width))
+        return false;
+    int height;
+    if (!decoder.decodeInt32(height))
+        return false;
+    intSize = IntSize(width, height);
+    return true;
+}
+#endif
+
</ins><span class="cx"> PassRefPtr&lt;HistoryItem&gt; HistoryItem::decodeBackForwardTree(const String&amp; topURLString, const String&amp; topTitle, const String&amp; topOriginalURLString, Decoder&amp; decoder)
</span><span class="cx"> {
</span><span class="cx">     // Since the data stream is not trusted, the decode has to be non-recursive.
</span><span class="lines">@@ -784,6 +884,19 @@
</span><span class="cx">     if (!decoder.decodeString(node-&gt;m_target))
</span><span class="cx">         return 0;
</span><span class="cx"> 
</span><ins>+#if PLATFORM(IOS)
+    if (!decodeRect(decoder, node-&gt;m_exposedContentRect))
+        return nullptr;
+    if (!decodeRect(decoder, node-&gt;m_unobscuredContentRect))
+        return nullptr;
+    if (!decodeSize(decoder, node-&gt;m_minimumLayoutSizeInScrollViewCoordinates))
+        return nullptr;
+    if (!decodeSize(decoder, node-&gt;m_contentSize))
+        return nullptr;
+    if (!decoder.decodeBool(node-&gt;m_scaleIsInitial))
+        return nullptr;
+#endif
+
</ins><span class="cx">     // Simulate recursion with our own stack.
</span><span class="cx">     if (!recursionStack.isEmpty()) {
</span><span class="cx">         DecodeRecursionStackElement&amp; element = recursionStack.last();
</span></span></pre></div>
<a id="trunkSourceWebCorehistoryHistoryItemh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/history/HistoryItem.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/history/HistoryItem.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/history/HistoryItem.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2006, 2008, 2011 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2006, 2008, 2011, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2012 Research In Motion Limited. All rights reserved.
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -27,7 +27,9 @@
</span><span class="cx"> #ifndef HistoryItem_h
</span><span class="cx"> #define HistoryItem_h
</span><span class="cx"> 
</span><ins>+#include &quot;FloatRect.h&quot;
</ins><span class="cx"> #include &quot;IntPoint.h&quot;
</span><ins>+#include &quot;IntRect.h&quot;
</ins><span class="cx"> #include &quot;SerializedScriptValue.h&quot;
</span><span class="cx"> #include &lt;memory&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="lines">@@ -180,9 +182,18 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    IntPoint exposedContentPosition() const { return m_exposedContentPosition; }
-    void setExposedContentPosition(IntPoint exposedContentPosition) { m_exposedContentPosition = exposedContentPosition; }
</del><ins>+    FloatRect exposedContentRect() const { return m_exposedContentRect; }
+    void setExposedContentRect(FloatRect exposedContentRect) { m_exposedContentRect = exposedContentRect; }
</ins><span class="cx"> 
</span><ins>+    IntRect unobscuredContentRect() const { return m_unobscuredContentRect; }
+    void setUnobscuredContentRect(IntRect unobscuredContentRect) { m_unobscuredContentRect = unobscuredContentRect; }
+
+    FloatSize minimumLayoutSizeInScrollViewCoordinates() const { return m_minimumLayoutSizeInScrollViewCoordinates; }
+    void setMinimumLayoutSizeInScrollViewCoordinates(FloatSize minimumLayoutSizeInScrollViewCoordinates) { m_minimumLayoutSizeInScrollViewCoordinates = minimumLayoutSizeInScrollViewCoordinates; }
+
+    IntSize contentSize() const { return m_contentSize; }
+    void setContentSize(IntSize contentSize) { m_contentSize = contentSize; }
+
</ins><span class="cx">     float scale() const { return m_scale; }
</span><span class="cx">     bool scaleIsInitial() const { return m_scaleIsInitial; }
</span><span class="cx">     void setScaleIsInitial(bool scaleIsInitial) { m_scaleIsInitial = scaleIsInitial; }
</span><span class="lines">@@ -259,7 +270,10 @@
</span><span class="cx">     std::unique_ptr&lt;CachedPage&gt; m_cachedPage;
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    IntPoint m_exposedContentPosition;
</del><ins>+    FloatRect m_exposedContentRect;
+    IntRect m_unobscuredContentRect;
+    FloatSize m_minimumLayoutSizeInScrollViewCoordinates;
+    IntSize m_contentSize;
</ins><span class="cx">     float m_scale;
</span><span class="cx">     bool m_scaleIsInitial;
</span><span class="cx">     ViewportArguments m_viewportArguments;
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderHistoryControllercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/HistoryController.cpp (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/HistoryController.cpp        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/loader/HistoryController.cpp        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -71,15 +71,17 @@
</span><span class="cx"> 
</span><span class="cx"> void HistoryController::saveScrollPositionAndViewStateToItem(HistoryItem* item)
</span><span class="cx"> {
</span><del>-    if (!item || !m_frame.view())
</del><ins>+    FrameView* frameView = m_frame.view();
+    if (!item || !frameView)
</ins><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     if (m_frame.document()-&gt;inPageCache())
</span><del>-        item-&gt;setScrollPoint(m_frame.view()-&gt;cachedScrollPosition());
</del><ins>+        item-&gt;setScrollPoint(frameView-&gt;cachedScrollPosition());
</ins><span class="cx">     else
</span><del>-        item-&gt;setScrollPoint(m_frame.view()-&gt;scrollPosition());
</del><ins>+        item-&gt;setScrollPoint(frameView-&gt;scrollPosition());
</ins><span class="cx"> #if PLATFORM(IOS)
</span><del>-    item-&gt;setExposedContentPosition(m_frame.view()-&gt;exposedContentRect().location());
</del><ins>+    item-&gt;setExposedContentRect(frameView-&gt;exposedContentRect());
+    item-&gt;setUnobscuredContentRect(frameView-&gt;unobscuredContentRect());
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx">     Page* page = m_frame.page();
</span></span></pre></div>
<a id="trunkSourceWebCorepageFrameViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/page/FrameView.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/page/FrameView.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/page/FrameView.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -129,6 +129,7 @@
</span><span class="cx">     void setCustomFixedPositionLayoutRect(const IntRect&amp;);
</span><span class="cx">     bool updateFixedPositionLayoutRect();
</span><span class="cx"> 
</span><ins>+    IntSize customSizeForResizeEvent() const { return m_customSizeForResizeEvent; }
</ins><span class="cx">     void setCustomSizeForResizeEvent(IntSize);
</span><span class="cx"> 
</span><span class="cx">     void setScrollVelocity(double horizontalVelocity, double verticalVelocity, double scaleChangeRate, double timestamp);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformScrollViewh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ScrollView.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ScrollView.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/platform/ScrollView.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2004, 2006, 2007, 2008 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2004, 2006, 2007, 2008, 2013, 2014 Apple Inc. All rights reserved.
</ins><span class="cx">  * Copyright (C) 2009 Holger Hans Peter Freyther
</span><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="lines">@@ -27,6 +27,7 @@
</span><span class="cx"> #ifndef ScrollView_h
</span><span class="cx"> #define ScrollView_h
</span><span class="cx"> 
</span><ins>+#include &quot;FloatRect.h&quot;
</ins><span class="cx"> #include &quot;IntRect.h&quot;
</span><span class="cx"> #include &quot;Scrollbar.h&quot;
</span><span class="cx"> #include &quot;ScrollableArea.h&quot;
</span><span class="lines">@@ -182,10 +183,10 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     // This is the area that is partially or fully exposed, and may extend under overlapping UI elements.
</span><del>-    IntRect exposedContentRect() const;
</del><ins>+    FloatRect exposedContentRect() const;
</ins><span class="cx"> 
</span><span class="cx">     // The given rects are only used if there is no platform widget.
</span><del>-    void setExposedContentRect(const IntRect&amp;);
</del><ins>+    void setExposedContentRect(const FloatRect&amp;);
</ins><span class="cx">     void setUnobscuredContentSize(const IntSize&amp;);
</span><span class="cx"> 
</span><span class="cx">     void setActualScrollPosition(const IntPoint&amp;);
</span><span class="lines">@@ -429,7 +430,7 @@
</span><span class="cx">     // FIXME: exposedContentRect is a very similar concept to fixedVisibleContentRect except it does not differentiate
</span><span class="cx">     // between exposed and unobscured areas. The two attributes should eventually be merged.
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    IntRect m_exposedContentRect;
</del><ins>+    FloatRect m_exposedContentRect;
</ins><span class="cx">     IntSize m_unobscuredContentSize;
</span><span class="cx"> #else
</span><span class="cx">     IntRect m_fixedVisibleContentRect;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformiosScrollViewIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/ios/ScrollViewIOS.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/ios/ScrollViewIOS.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/platform/ios/ScrollViewIOS.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -119,7 +119,7 @@
</span><span class="cx">     m_unobscuredContentSize = size;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-IntRect ScrollView::exposedContentRect() const
</del><ins>+FloatRect ScrollView::exposedContentRect() const
</ins><span class="cx"> {
</span><span class="cx">     if (NSScrollView *view = static_cast&lt;NSScrollView *&gt;(platformWidget())) {
</span><span class="cx">         CGRect r = CGRectZero;
</span><span class="lines">@@ -132,20 +132,20 @@
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="cx">         END_BLOCK_OBJC_EXCEPTIONS;
</span><del>-        return enclosingIntRect(r);
</del><ins>+        return r;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     const ScrollView* parent = this-&gt;parent();
</span><span class="cx">     if (!parent)
</span><span class="cx">         return m_exposedContentRect;
</span><span class="cx"> 
</span><del>-    IntRect parentViewExtentContentRect = parent-&gt;exposedContentRect();
</del><ins>+    IntRect parentViewExtentContentRect = enclosingIntRect(parent-&gt;exposedContentRect());
</ins><span class="cx">     IntRect selfExtentContentRect = rootViewToContents(parentViewExtentContentRect);
</span><span class="cx">     selfExtentContentRect.intersect(boundsRect());
</span><span class="cx">     return selfExtentContentRect;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void ScrollView::setExposedContentRect(const IntRect&amp; rect)
</del><ins>+void ScrollView::setExposedContentRect(const FloatRect&amp; rect)
</ins><span class="cx"> {
</span><span class="cx">     ASSERT(!platformWidget());
</span><span class="cx">     m_exposedContentRect = rect;
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderLayerCompositorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebCore/rendering/RenderLayerCompositor.cpp        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -558,7 +558,7 @@
</span><span class="cx">     const FrameView&amp; frameView = m_renderView.frameView();
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    IntRect visibleRect = frameView.exposedContentRect();
</del><ins>+    IntRect visibleRect = enclosingIntRect(frameView.exposedContentRect());
</ins><span class="cx"> #else
</span><span class="cx">     IntRect visibleRect = m_clipLayer ? IntRect(IntPoint(), frameView.contentsSize()) : frameView.visibleContentRect();
</span><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/ChangeLog (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/ChangeLog        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/ChangeLog        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -1,3 +1,101 @@
</span><ins>+2014-06-23  Benjamin Poulain  &lt;bpoulain@apple.com&gt;
+
+        [iOS][WK2] Make the state restore from HistoryItem more precise and reliable
+        https://bugs.webkit.org/show_bug.cgi?id=134150
+
+        Reviewed by Tim Horton.
+
+        This patch make several little improvements to improve how we restore the visible content rect and scale
+        from the HistoryItem.
+
+        The biggest architectural change is that the exposed rect is now restored on the UIProcess instead of the WebProcess,
+        this ensure we restore the same position regardless of any modification of obscured areas.
+
+        * Shared/VisibleContentRectUpdateInfo.cpp:
+        (WebKit::VisibleContentRectUpdateInfo::encode):
+        (WebKit::VisibleContentRectUpdateInfo::decode):
+        * Shared/VisibleContentRectUpdateInfo.h:
+        (WebKit::VisibleContentRectUpdateInfo::VisibleContentRectUpdateInfo):
+        (WebKit::VisibleContentRectUpdateInfo::lastLayerTreeTransactionId):
+        (WebKit::WebPage::updateVisibleContentRects):
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h:
+        A race between the UIProcess and the WebProcess could cause the viewport of the next page to be influenced by updates
+        of the previous page. To avoid that, VisibleContentRectUpdateInfo keeps track of the last transaction seen at the time
+        of the update.
+
+        The WebProcess updates the size and scale of the content through layer tree updates. If an update was generated for a layer tree
+        update of the old page, none of the information is valid for the current content. Since the UIProcess drives the state in case of conflicts,
+        the WebProcess was updating the scale of the current page based on incorrect information.
+
+        To avoid the problems, we save the layer tree transaction ID when we commit a new page. Only updates after that transaction are useful
+        for the current page.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _processDidExit]):
+        (withinEpsilon):
+        (changeContentOffsetBoundedInValidRange):
+        (-[WKWebView _didCommitLayerTree:WebKit::]):
+        (-[WKWebView _restorePageStateToExposedRect:WebCore::scale:]):
+        (-[WKWebView _restorePageStateToUnobscuredCenter:WebCore::scale:]):
+        * UIProcess/API/Cocoa/WKWebViewInternal.h:
+        * UIProcess/PageClient.h:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/WebPageProxy.messages.in:
+        * UIProcess/ios/PageClientImplIOS.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::restorePageState):
+        (WebKit::PageClientImpl::restorePageCenterAndScale):
+        Restoring the state is now done by WKWebView. The state is only updated on the next layer tree commit,
+        this is done to avoid any jumping if the page has scrolled since we tried to restore its state.
+
+        Both update path end up calling _updateVisibleContentRects. This is because the update on the WebProcess
+        never sets the ScrollPosition (because it does not know the current state of the obscured insets). Pushing
+        a new VisibleContentRect will nicely udpates the exposed rect, scroll position, fixed elements, etc.
+
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView didUpdateVisibleRect:unobscuredRect:unobscuredRectInScrollViewCoordinates:scale:minimumScale:inStableState:isChangingObscuredInsetsInteractively:]):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::restorePageState):
+        (WebKit::WebPageProxy::restorePageCenterAndScale):
+        * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h:
+        (WebKit::RemoteLayerTreeDrawingAreaProxy::lastCommittedLayerTreeTransactionID):
+        * UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm:
+        (WebKit::RemoteLayerTreeDrawingAreaProxy::RemoteLayerTreeDrawingAreaProxy):
+        * WebProcess/WebCoreSupport/ios/WebFrameLoaderClientIOS.mm:
+        (WebKit::WebFrameLoaderClient::saveViewStateToItem):
+        (WebKit::WebFrameLoaderClient::restoreViewState):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::WebPage):
+        (WebKit::WebPage::didCommitLoad):
+        * WebProcess/WebPage/WebPage.h:
+        Get rid of m_obscuredTopInset. It was a bad idea. The UIProcess updates the obscured insets a lot during
+        page load, the value we used to restore the scroll position was frequently stale.
+
+        (WebKit::WebPage::userHasChangedPageScaleFactor): Deleted.
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::savePageState):
+        (WebKit::scaleAfterViewportWidthChange):
+        (WebKit::relativeCenterAfterContentSizeChange):
+        (WebKit::adjustExposedRectForNewScale):
+        Extract this out of dynamicViewportSizeUpdate(). It is useful to adjust the exposed rect when restoring a HistoryItem
+        to a ViewportConfiguration that is different from when it was saved.
+
+        (WebKit::WebPage::restorePageState):
+        There are two variations of restorePage:
+        1) If the viewport configuration is compatible, restore the exact scale and position of the page.
+        2) Otherwise, restore the scale and position similarily to dynamicViewportSizeUpdate().
+
+        (WebKit::WebPage::dynamicViewportSizeUpdate):
+        (WebKit::WebPage::viewportConfigurationChanged):
+        (WebKit::adjustExposedRectForBoundedScale):
+        (WebKit::RemoteLayerTreeDrawingArea::currentTransactionID):
+        Expose the transactionID for the race issue on VisibleRectUpdate.
+
+        * WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm:
+        (WebKit::RemoteLayerTreeDrawingArea::setExposedContentRect):
+        Store the exposed rect in floating point coordinates. This makes it possible to restore that exact
+        position when needed.
+
</ins><span class="cx"> 2014-06-23  Eric Carlson  &lt;eric.carlson@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, revert an unintentional change committed with r170323.
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedVisibleContentRectUpdateInfocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.cpp (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.cpp        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.cpp        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -43,6 +43,7 @@
</span><span class="cx">     encoder &lt;&lt; m_horizontalVelocity;
</span><span class="cx">     encoder &lt;&lt; m_verticalVelocity;
</span><span class="cx">     encoder &lt;&lt; m_scaleChangeRate;
</span><ins>+    encoder &lt;&lt; m_lastLayerTreeTransactionID;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool VisibleContentRectUpdateInfo::decode(IPC::ArgumentDecoder&amp; decoder, VisibleContentRectUpdateInfo&amp; result)
</span><span class="lines">@@ -69,6 +70,8 @@
</span><span class="cx">         return false;
</span><span class="cx">     if (!decoder.decode(result.m_scaleChangeRate))
</span><span class="cx">         return false;
</span><ins>+    if (!decoder.decode(result.m_lastLayerTreeTransactionID))
+        return false;
</ins><span class="cx"> 
</span><span class="cx">     return true;
</span><span class="cx"> }
</span></span></pre></div>
<a id="trunkSourceWebKit2SharedVisibleContentRectUpdateInfoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/Shared/VisibleContentRectUpdateInfo.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -41,10 +41,11 @@
</span><span class="cx">         : m_scale(-1)
</span><span class="cx">         , m_inStableState(false)
</span><span class="cx">         , m_isChangingObscuredInsetsInteractively(false)
</span><ins>+        , m_lastLayerTreeTransactionID(0)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    VisibleContentRectUpdateInfo(const WebCore::FloatRect&amp; exposedRect, const WebCore::FloatRect&amp; unobscuredRect, const WebCore::FloatRect&amp; unobscuredRectInScrollViewCoordinates, const WebCore::FloatRect&amp; customFixedPositionRect, double scale, bool inStableState, bool isChangingObscuredInsetsInteractively, double timestamp, double horizontalVelocity, double verticalVelocity, double scaleChangeRate)
</del><ins>+    VisibleContentRectUpdateInfo(const WebCore::FloatRect&amp; exposedRect, const WebCore::FloatRect&amp; unobscuredRect, const WebCore::FloatRect&amp; unobscuredRectInScrollViewCoordinates, const WebCore::FloatRect&amp; customFixedPositionRect, double scale, bool inStableState, bool isChangingObscuredInsetsInteractively, double timestamp, double horizontalVelocity, double verticalVelocity, double scaleChangeRate, uint64_t lastLayerTreeTranscationId)
</ins><span class="cx">         : m_exposedRect(exposedRect)
</span><span class="cx">         , m_unobscuredRect(unobscuredRect)
</span><span class="cx">         , m_unobscuredRectInScrollViewCoordinates(unobscuredRectInScrollViewCoordinates)
</span><span class="lines">@@ -56,6 +57,7 @@
</span><span class="cx">         , m_horizontalVelocity(horizontalVelocity)
</span><span class="cx">         , m_verticalVelocity(verticalVelocity)
</span><span class="cx">         , m_scaleChangeRate(scaleChangeRate)
</span><ins>+        , m_lastLayerTreeTransactionID(lastLayerTreeTranscationId)
</ins><span class="cx">     {
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="lines">@@ -72,6 +74,8 @@
</span><span class="cx">     double verticalVelocity() const { return m_verticalVelocity; }
</span><span class="cx">     double scaleChangeRate() const { return m_scaleChangeRate; }
</span><span class="cx"> 
</span><ins>+    uint64_t lastLayerTreeTransactionID() const { return m_lastLayerTreeTransactionID; }
+
</ins><span class="cx">     void encode(IPC::ArgumentEncoder&amp;) const;
</span><span class="cx">     static bool decode(IPC::ArgumentDecoder&amp;, VisibleContentRectUpdateInfo&amp;);
</span><span class="cx"> 
</span><span class="lines">@@ -87,6 +91,7 @@
</span><span class="cx">     double m_horizontalVelocity;
</span><span class="cx">     double m_verticalVelocity;
</span><span class="cx">     double m_scaleChangeRate;
</span><ins>+    uint64_t m_lastLayerTreeTransactionID;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline bool operator==(const VisibleContentRectUpdateInfo&amp; a, const VisibleContentRectUpdateInfo&amp; b)
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -169,6 +169,13 @@
</span><span class="cx">     RetainPtr&lt;UIView&gt; _resizeAnimationView;
</span><span class="cx">     CGFloat _lastAdjustmentForScroller;
</span><span class="cx"> 
</span><ins>+    BOOL _needsToRestoreExposedRect;
+    WebCore::FloatRect _exposedRectToRestore;
+    BOOL _needsToRestoreUnobscuredCenter;
+    WebCore::FloatPoint _unobscuredCenterToRestore;
+    uint64_t _firstTransactionIDAfterPageRestore;
+    double _scaleToRestore;
+
</ins><span class="cx">     std::unique_ptr&lt;WebKit::ViewGestureController&gt; _gestureController;
</span><span class="cx">     BOOL _allowsBackForwardNavigationGestures;
</span><span class="cx"> 
</span><span class="lines">@@ -700,6 +707,8 @@
</span><span class="cx"> 
</span><span class="cx">     _viewportMetaTagWidth = -1;
</span><span class="cx">     _needsResetViewStateAfterCommitLoadForMainFrame = NO;
</span><ins>+    _needsToRestoreExposedRect = NO;
+    _needsToRestoreUnobscuredCenter = NO;
</ins><span class="cx">     _scrollViewBackgroundColor = WebCore::Color();
</span><span class="cx">     _delayUpdateVisibleContentRects = NO;
</span><span class="cx">     _hadDelayedUpdateVisibleContentRects = NO;
</span><span class="lines">@@ -713,6 +722,30 @@
</span><span class="cx">     _usesMinimalUI = NO;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline bool withinEpsilon(float a, float b)
+{
+    return fabs(a - b) &lt; std::numeric_limits&lt;float&gt;::epsilon();
+}
+
+static void changeContentOffsetBoundedInValidRange(UIScrollView *scrollView, WebCore::FloatPoint contentOffset)
+{
+    UIEdgeInsets contentInsets = scrollView.contentInset;
+    CGSize contentSize = scrollView.contentSize;
+    CGSize scrollViewSize = scrollView.bounds.size;
+
+    float maxHorizontalOffset = contentSize.width + contentInsets.right - scrollViewSize.width;
+    if (contentOffset.x() &gt; maxHorizontalOffset)
+        contentOffset.setX(maxHorizontalOffset);
+    float maxVerticalOffset = contentSize.height + contentInsets.bottom - scrollViewSize.height;
+    if (contentOffset.y() &gt; maxVerticalOffset)
+        contentOffset.setY(maxVerticalOffset);
+    if (contentOffset.x() &lt; -contentInsets.left)
+        contentOffset.setX(-contentInsets.left);
+    if (contentOffset.y() &lt; -contentInsets.top)
+        contentOffset.setY(-contentInsets.top);
+    scrollView.contentOffset = contentOffset;
+}
+
</ins><span class="cx"> - (void)_didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&amp;)layerTreeTransaction
</span><span class="cx"> {
</span><span class="cx">     if (_customContentView)
</span><span class="lines">@@ -748,6 +781,34 @@
</span><span class="cx">         [_scrollView setContentOffset:CGPointMake(-_obscuredInsets.left, -_obscuredInsets.top)];
</span><span class="cx">         [self _updateVisibleContentRects];
</span><span class="cx">     }
</span><ins>+
+    if (_needsToRestoreExposedRect &amp;&amp; layerTreeTransaction.transactionID() &gt;= _firstTransactionIDAfterPageRestore) {
+        _needsToRestoreExposedRect = NO;
+
+        if (withinEpsilon(contentZoomScale(self), _scaleToRestore)) {
+            WebCore::FloatPoint exposedPosition = _exposedRectToRestore.location();
+            exposedPosition.scale(_scaleToRestore, _scaleToRestore);
+
+            changeContentOffsetBoundedInValidRange(_scrollView.get(), exposedPosition);
+        }
+        [self _updateVisibleContentRects];
+    }
+
+    if (_needsToRestoreUnobscuredCenter &amp;&amp; layerTreeTransaction.transactionID() &gt;= _firstTransactionIDAfterPageRestore) {
+        _needsToRestoreUnobscuredCenter = NO;
+
+        if (withinEpsilon(contentZoomScale(self), _scaleToRestore)) {
+            CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, _obscuredInsets);
+            WebCore::FloatSize unobscuredContentSizeAtNewScale(unobscuredRect.size.width / _scaleToRestore, unobscuredRect.size.height / _scaleToRestore);
+            WebCore::FloatPoint topLeftInDocumentCoordinate(_unobscuredCenterToRestore.x() - unobscuredContentSizeAtNewScale.width() / 2, _unobscuredCenterToRestore.y() - unobscuredContentSizeAtNewScale.height() / 2);
+
+            topLeftInDocumentCoordinate.scale(_scaleToRestore, _scaleToRestore);
+            topLeftInDocumentCoordinate.moveBy(WebCore::FloatPoint(-_obscuredInsets.left, -_obscuredInsets.top));
+
+            changeContentOffsetBoundedInValidRange(_scrollView.get(), topLeftInDocumentCoordinate);
+        }
+        [self _updateVisibleContentRects];
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> - (void)_dynamicViewportUpdateChangedTargetToScale:(double)newScale position:(CGPoint)newScrollPosition
</span><span class="lines">@@ -768,6 +829,36 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_restorePageStateToExposedRect:(WebCore::FloatRect)exposedRect scale:(double)scale
+{
+    if (_isAnimatingResize)
+        return;
+
+    if (_customContentView)
+        return;
+
+    _needsToRestoreUnobscuredCenter = NO;
+    _needsToRestoreExposedRect = YES;
+    _firstTransactionIDAfterPageRestore = toRemoteLayerTreeDrawingAreaProxy(_page-&gt;drawingArea())-&gt;nextLayerTreeTransactionID();
+    _exposedRectToRestore = exposedRect;
+    _scaleToRestore = scale;
+}
+
+- (void)_restorePageStateToUnobscuredCenter:(WebCore::FloatPoint)center scale:(double)scale
+{
+    if (_isAnimatingResize)
+        return;
+
+    if (_customContentView)
+        return;
+
+    _needsToRestoreExposedRect = NO;
+    _needsToRestoreUnobscuredCenter = YES;
+    _firstTransactionIDAfterPageRestore = toRemoteLayerTreeDrawingAreaProxy(_page-&gt;drawingArea())-&gt;nextLayerTreeTransactionID();
+    _unobscuredCenterToRestore = center;
+    _scaleToRestore = scale;
+}
+
</ins><span class="cx"> - (WebKit::ViewSnapshot)_takeViewSnapshot
</span><span class="cx"> {
</span><span class="cx">     float deviceScale = WKGetScreenScaleFactor();
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessAPICocoaWKWebViewInternalh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -71,6 +71,8 @@
</span><span class="cx"> - (void)_didCommitLayerTree:(const WebKit::RemoteLayerTreeTransaction&amp;)layerTreeTransaction;
</span><span class="cx"> 
</span><span class="cx"> - (void)_dynamicViewportUpdateChangedTargetToScale:(double)newScale position:(CGPoint)newScrollPosition;
</span><ins>+- (void)_restorePageStateToExposedRect:(WebCore::FloatRect)exposedRect scale:(double)scale;
+- (void)_restorePageStateToUnobscuredCenter:(WebCore::FloatPoint)center scale:(double)scale;
</ins><span class="cx"> 
</span><span class="cx"> - (WebKit::ViewSnapshot)_takeViewSnapshot;
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessPageClienth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/PageClient.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/PageClient.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/PageClient.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -250,6 +250,8 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&amp;) = 0;
</span><span class="cx">     virtual void dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint&amp; newScrollPosition) = 0;
</span><ins>+    virtual void restorePageState(const WebCore::FloatRect&amp;, double) = 0;
+    virtual void restorePageCenterAndScale(const WebCore::FloatPoint&amp;, double) = 0;
</ins><span class="cx"> 
</span><span class="cx">     virtual void startAssistingNode(const AssistedNodeInformation&amp;, bool userIsInteracting, bool blurPreviousNode, API::Object* userData) = 0;
</span><span class="cx">     virtual void stopAssistingNode() = 0;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -1198,6 +1198,9 @@
</span><span class="cx">     float textAutosizingWidth();
</span><span class="cx"> 
</span><span class="cx">     void dynamicViewportUpdateChangedTarget(double newTargetScale, const WebCore::FloatPoint&amp; newScrollPosition);
</span><ins>+    void restorePageState(const WebCore::FloatRect&amp;, double scale);
+    void restorePageCenterAndScale(const WebCore::FloatPoint&amp;, double scale);
+
</ins><span class="cx">     void didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color&amp; color, const Vector&lt;WebCore::FloatQuad&gt;&amp; geometries, const WebCore::IntSize&amp; topLeftRadius, const WebCore::IntSize&amp; topRightRadius, const WebCore::IntSize&amp; bottomLeftRadius, const WebCore::IntSize&amp; bottomRightRadius);
</span><span class="cx"> 
</span><span class="cx">     void startAssistingNode(const AssistedNodeInformation&amp;, bool userIsInteracting, bool blurPreviousNode, IPC::MessageDecoder&amp;);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessWebPageProxymessagesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.messages.in        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -332,6 +332,8 @@
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     DynamicViewportUpdateChangedTarget(double newTargetScale, WebCore::FloatPoint newScrollPosition)
</span><ins>+    RestorePageState(WebCore::FloatRect exposedRect, double scale)
+    RestorePageCenterAndScale(WebCore::FloatPoint unobscuredCenter, double scale)
</ins><span class="cx">     DidGetTapHighlightGeometries(uint64_t requestID, WebCore::Color color, Vector&lt;WebCore::FloatQuad&gt; geometries, WebCore::IntSize topLeftRadius, WebCore::IntSize topRightRadius, WebCore::IntSize bottomLeftRadius, WebCore::IntSize bottomRightRadius)
</span><span class="cx"> 
</span><span class="cx">     StartAssistingNode(WebKit::AssistedNodeInformation information, bool userIsInteracting, bool blurPreviousNode, WebKit::InjectedBundleUserMessageEncoder userData) Variadic
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosPageClientImplIOSh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -113,6 +113,8 @@
</span><span class="cx"> 
</span><span class="cx">     virtual void didCommitLayerTree(const RemoteLayerTreeTransaction&amp;) override;
</span><span class="cx">     virtual void dynamicViewportUpdateChangedTarget(double newScale, const WebCore::FloatPoint&amp; newScrollPosition) override;
</span><ins>+    virtual void restorePageState(const WebCore::FloatRect&amp;, double) override;
+    virtual void restorePageCenterAndScale(const WebCore::FloatPoint&amp;, double) override;
</ins><span class="cx"> 
</span><span class="cx">     virtual void startAssistingNode(const AssistedNodeInformation&amp;, bool userIsInteracting, bool blurPreviousNode, API::Object* userData) override;
</span><span class="cx">     virtual void stopAssistingNode() override;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosPageClientImplIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/ios/PageClientImplIOS.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -433,6 +433,16 @@
</span><span class="cx">     [m_webView _dynamicViewportUpdateChangedTargetToScale:newScale position:newScrollPosition];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void PageClientImpl::restorePageState(const WebCore::FloatRect&amp; exposedRect, double scale)
+{
+    [m_webView _restorePageStateToExposedRect:exposedRect scale:scale];
+}
+
+void PageClientImpl::restorePageCenterAndScale(const WebCore::FloatPoint&amp; center, double scale)
+{
+    [m_webView _restorePageStateToUnobscuredCenter:center scale:scale];
+}
+
</ins><span class="cx"> void PageClientImpl::startAssistingNode(const AssistedNodeInformation&amp; nodeInformation, bool userIsInteracting, bool blurPreviousNode, API::Object* userData)
</span><span class="cx"> {
</span><span class="cx">     MESSAGE_CHECK(!userData || userData-&gt;type() == API::Object::Type::Data);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWKContentViewmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -303,7 +303,7 @@
</span><span class="cx"> 
</span><span class="cx">     FloatRect fixedPositionRectForLayout = _page-&gt;computeCustomFixedPositionRect(unobscuredRect, zoomScale, WebPageProxy::UnobscuredRectConstraint::ConstrainedToDocumentRect);
</span><span class="cx">     _page-&gt;updateVisibleContentRects(VisibleContentRectUpdateInfo(visibleRect, unobscuredRect, unobscuredRectInScrollViewCoordinates, fixedPositionRectForLayout,
</span><del>-        zoomScale, isStableState, isChangingObscuredInsetsInteractively, timestamp, velocityData.horizontalVelocity, velocityData.verticalVelocity, velocityData.scaleChangeRate));
</del><ins>+        zoomScale, isStableState, isChangingObscuredInsetsInteractively, timestamp, velocityData.horizontalVelocity, velocityData.verticalVelocity, velocityData.scaleChangeRate, toRemoteLayerTreeDrawingAreaProxy(_page-&gt;drawingArea())-&gt;lastCommittedLayerTreeTransactionID()));
</ins><span class="cx"> 
</span><span class="cx">     RemoteScrollingCoordinatorProxy* scrollingCoordinator = _page-&gt;scrollingCoordinatorProxy();
</span><span class="cx">     scrollingCoordinator-&gt;viewportChangedViaDelegatedScrolling(scrollingCoordinator-&gt;rootScrollingNodeID(), _page-&gt;computeCustomFixedPositionRect(_page-&gt;unobscuredContentRect(), zoomScale), zoomScale);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessiosWebPageProxyIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -615,6 +615,16 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+void WebPageProxy::restorePageState(const WebCore::FloatRect&amp; exposedRect, double scale)
+{
+    m_pageClient.restorePageState(exposedRect, scale);
+}
+
+void WebPageProxy::restorePageCenterAndScale(const WebCore::FloatPoint&amp; center, double scale)
+{
+    m_pageClient.restorePageCenterAndScale(center, scale);
+}
+
</ins><span class="cx"> void WebPageProxy::didGetTapHighlightGeometries(uint64_t requestID, const WebCore::Color&amp; color, const Vector&lt;WebCore::FloatQuad&gt;&amp; highlightedQuads, const WebCore::IntSize&amp; topLeftRadius, const WebCore::IntSize&amp; topRightRadius, const WebCore::IntSize&amp; bottomLeftRadius, const WebCore::IntSize&amp; bottomRightRadius)
</span><span class="cx"> {
</span><span class="cx">     m_pageClient.didGetTapHighlightGeometries(requestID, color, highlightedQuads, topLeftRadius, topRightRadius, bottomLeftRadius, bottomRightRadius);
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxyh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">     void coreAnimationDidCommitLayers();
</span><span class="cx"> 
</span><span class="cx">     uint64_t nextLayerTreeTransactionID() const { return m_pendingLayerTreeTransactionID + 1; }
</span><ins>+    uint64_t lastCommittedLayerTreeTransactionID() const { return m_transactionIDForPendingCACommit; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     virtual void sizeDidChange() override;
</span></span></pre></div>
<a id="trunkSourceWebKit2UIProcessmacRemoteLayerTreeDrawingAreaProxymm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/UIProcess/mac/RemoteLayerTreeDrawingAreaProxy.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -50,6 +50,7 @@
</span><span class="cx">     , m_isWaitingForDidUpdateGeometry(false)
</span><span class="cx">     , m_pendingLayerTreeTransactionID(0)
</span><span class="cx">     , m_lastVisibleTransactionID(0)
</span><ins>+    , m_transactionIDForPendingCACommit(0)
</ins><span class="cx"> {
</span><span class="cx"> #if USE(IOSURFACE)
</span><span class="cx">     // We don't want to pool surfaces in the UI process.
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebCoreSupportiosWebFrameLoaderClientIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebCoreSupport/ios/WebFrameLoaderClientIOS.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebCoreSupport/ios/WebFrameLoaderClientIOS.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/WebProcess/WebCoreSupport/ios/WebFrameLoaderClientIOS.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -82,7 +82,7 @@
</span><span class="cx"> void WebFrameLoaderClient::saveViewStateToItem(HistoryItem* historyItem)
</span><span class="cx"> {
</span><span class="cx">     if (m_frame-&gt;isMainFrame())
</span><del>-        historyItem-&gt;setScaleIsInitial(m_frame-&gt;page()-&gt;userHasChangedPageScaleFactor());
</del><ins>+        m_frame-&gt;page()-&gt;savePageState(*historyItem);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> void WebFrameLoaderClient::restoreViewState()
</span><span class="lines">@@ -90,8 +90,8 @@
</span><span class="cx">     Frame&amp; frame = *m_frame-&gt;coreFrame();
</span><span class="cx">     HistoryItem* currentItem = frame.loader().history().currentItem();
</span><span class="cx">     if (FrameView* view = frame.view()) {
</span><del>-        if (m_frame-&gt;isMainFrame() &amp;&amp; currentItem-&gt;pageScaleFactor())
-            m_frame-&gt;page()-&gt;restorePageState(currentItem-&gt;pageScaleFactor(), currentItem-&gt;scaleIsInitial(), currentItem-&gt;exposedContentPosition());
</del><ins>+        if (m_frame-&gt;isMainFrame())
+            m_frame-&gt;page()-&gt;restorePageState(*currentItem);
</ins><span class="cx">         else if (!view-&gt;wasScrolledByUser())
</span><span class="cx">             view-&gt;setScrollPosition(currentItem-&gt;scrollPoint());
</span><span class="cx">     }
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPagecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.cpp        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -187,6 +187,7 @@
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span><ins>+#include &quot;RemoteLayerTreeDrawingArea.h&quot;
</ins><span class="cx"> #include &quot;WebVideoFullscreenManager.h&quot;
</span><span class="cx"> #include &lt;CoreGraphics/CoreGraphics.h&gt;
</span><span class="cx"> #include &lt;WebCore/Icon.h&gt;
</span><span class="lines">@@ -291,7 +292,7 @@
</span><span class="cx">     , m_isShowingContextMenu(false)
</span><span class="cx"> #endif
</span><span class="cx"> #if PLATFORM(IOS)
</span><del>-    , m_obscuredTopInset(0)
</del><ins>+    , m_lastLayerTreeTransactionIDBeforeDidCommitLoad(0)
</ins><span class="cx">     , m_hasReceivedVisibleContentRectsAfterDidCommitLoad(false)
</span><span class="cx">     , m_scaleWasSetByUIProcess(false)
</span><span class="cx">     , m_userHasChangedPageScaleFactor(false)
</span><span class="lines">@@ -4344,6 +4345,8 @@
</span><span class="cx">     }
</span><span class="cx"> #if PLATFORM(IOS)
</span><span class="cx">     m_hasReceivedVisibleContentRectsAfterDidCommitLoad = false;
</span><ins>+    m_scaleWasSetByUIProcess = false;
+    m_lastLayerTreeTransactionIDBeforeDidCommitLoad = toRemoteLayerTreeDrawingArea(*m_drawingArea).currentTransactionID();
</ins><span class="cx">     m_userHasChangedPageScaleFactor = false;
</span><span class="cx"> 
</span><span class="cx">     WebProcess::shared().eventDispatcher().clearQueuedTouchEventsForPage(*this);
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageWebPageh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -457,7 +457,8 @@
</span><span class="cx">     int32_t deviceOrientation() const { return m_deviceOrientation; }
</span><span class="cx">     void viewportPropertiesDidChange(const WebCore::ViewportArguments&amp;);
</span><span class="cx">     void didReceiveMobileDocType(bool);
</span><del>-    void restorePageState(double scale, bool userHasChangedPageScaleFactor, const WebCore::IntPoint&amp; exposedOrigin);
</del><ins>+    void savePageState(WebCore::HistoryItem&amp;);
+    void restorePageState(const WebCore::HistoryItem&amp;);
</ins><span class="cx"> 
</span><span class="cx">     void setUseTestingViewportConfiguration(bool useTestingViewport) { m_useTestingViewportConfiguration = useTestingViewport; }
</span><span class="cx">     bool isUsingTestingViewportConfiguration() const { return m_useTestingViewportConfiguration; }
</span><span class="lines">@@ -465,7 +466,6 @@
</span><span class="cx">     double minimumPageScaleFactor() const;
</span><span class="cx">     double maximumPageScaleFactor() const;
</span><span class="cx">     bool allowsUserScaling() const;
</span><del>-    bool userHasChangedPageScaleFactor() const { return m_userHasChangedPageScaleFactor; }
</del><span class="cx"> 
</span><span class="cx">     void handleTap(const WebCore::IntPoint&amp;);
</span><span class="cx">     void potentialTapAtPosition(uint64_t requestID, const WebCore::FloatPoint&amp;);
</span><span class="lines">@@ -1215,7 +1215,7 @@
</span><span class="cx">     WebCore::FloatPoint m_potentialTapLocation;
</span><span class="cx"> 
</span><span class="cx">     WebCore::ViewportConfiguration m_viewportConfiguration;
</span><del>-    float m_obscuredTopInset;
</del><ins>+    uint64_t m_lastLayerTreeTransactionIDBeforeDidCommitLoad;
</ins><span class="cx">     bool m_hasReceivedVisibleContentRectsAfterDidCommitLoad;
</span><span class="cx">     bool m_scaleWasSetByUIProcess;
</span><span class="cx">     bool m_userHasChangedPageScaleFactor;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -64,6 +64,7 @@
</span><span class="cx"> #import &lt;WebCore/HTMLParserIdioms.h&gt;
</span><span class="cx"> #import &lt;WebCore/HTMLSelectElement.h&gt;
</span><span class="cx"> #import &lt;WebCore/HTMLTextAreaElement.h&gt;
</span><ins>+#import &lt;WebCore/HistoryItem.h&gt;
</ins><span class="cx"> #import &lt;WebCore/HitTestResult.h&gt;
</span><span class="cx"> #import &lt;WebCore/KeyboardEvent.h&gt;
</span><span class="cx"> #import &lt;WebCore/MainFrame.h&gt;
</span><span class="lines">@@ -151,19 +152,101 @@
</span><span class="cx">         resetViewportDefaultConfiguration(m_mainFrame.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebPage::restorePageState(double scale, bool userHasChangedPageScaleFactor, const IntPoint&amp; exposedOrigin)
</del><ins>+void WebPage::savePageState(HistoryItem&amp; historyItem)
</ins><span class="cx"> {
</span><del>-    // FIXME: ideally, we should sync this with the UIProcess. We should not try to change the position if the user is interacting
-    // with the page, and we should send the new scroll position as soon as possible to the UIProcess.
</del><ins>+    historyItem.setScaleIsInitial(!m_userHasChangedPageScaleFactor);
+    historyItem.setMinimumLayoutSizeInScrollViewCoordinates(m_viewportConfiguration.activeMinimumLayoutSizeInScrollViewCoordinates());
+    historyItem.setContentSize(m_viewportConfiguration.contentsSize());
+}
</ins><span class="cx"> 
</span><del>-    float boundedScale = std::min&lt;float&gt;(m_viewportConfiguration.maximumScale(), std::max&lt;float&gt;(m_viewportConfiguration.minimumScale(), scale));
-    float topInsetInPageCoordinates = m_obscuredTopInset / boundedScale;
-    IntPoint scrollPosition(exposedOrigin.x(), exposedOrigin.y() + topInsetInPageCoordinates);
-    scalePage(boundedScale, scrollPosition);
-    m_page-&gt;mainFrame().view()-&gt;setScrollPosition(scrollPosition);
-    m_userHasChangedPageScaleFactor = userHasChangedPageScaleFactor;
</del><ins>+static double scaleAfterViewportWidthChange(double currentScale, bool userHasChangedPageScaleFactor, const ViewportConfiguration&amp; viewportConfiguration, float unobscuredWidthInScrollViewCoordinates, const IntSize&amp; newContentSize, const IntSize&amp; oldContentSize, float visibleHorizontalFraction)
+{
+    double scale;
+    if (!userHasChangedPageScaleFactor)
+        scale = viewportConfiguration.initialScale();
+    else
+        scale = std::max(std::min(currentScale, viewportConfiguration.maximumScale()), viewportConfiguration.minimumScale());
+
+    if (userHasChangedPageScaleFactor) {
+        // When the content size changes, we keep the same relative horizontal content width in view, otherwise we would
+        // end up zoomed too far in landscape-&gt;portrait, and too close in portrait-&gt;landscape.
+        float widthToKeepInView = visibleHorizontalFraction * newContentSize.width();
+        double newScale = unobscuredWidthInScrollViewCoordinates / widthToKeepInView;
+        scale = std::max(std::min(newScale, viewportConfiguration.maximumScale()), viewportConfiguration.minimumScale());
+    }
+    return scale;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static FloatPoint relativeCenterAfterContentSizeChange(const FloatRect&amp; originalContentRect, IntSize oldContentSize, IntSize newContentSize)
+{
+    // If the content size has changed, keep the same relative position.
+    FloatPoint oldContentCenter = originalContentRect.center();
+    float relativeHorizontalPosition = oldContentCenter.x() / oldContentSize.width();
+    float relativeVerticalPosition =  oldContentCenter.y() / oldContentSize.height();
+    return FloatPoint(relativeHorizontalPosition * newContentSize.width(), relativeVerticalPosition * newContentSize.height());
+}
+
+static inline FloatRect adjustExposedRectForNewScale(const FloatRect&amp; exposedRect, double exposedRectScale, double newScale)
+{
+    double overscaledWidth = exposedRect.width();
+    double missingHorizonalMargin = exposedRect.width() * exposedRectScale / newScale - overscaledWidth;
+
+    double overscaledHeight = exposedRect.height();
+    double missingVerticalMargin = exposedRect.height() * exposedRectScale / newScale - overscaledHeight;
+
+    return FloatRect(exposedRect.x() - missingHorizonalMargin / 2, exposedRect.y() - missingVerticalMargin / 2, exposedRect.width() + missingHorizonalMargin, exposedRect.height() + missingVerticalMargin);
+}
+
+void WebPage::restorePageState(const HistoryItem&amp; historyItem)
+{
+    // When a HistoryItem is cleared, its scale factor and scroll point are set to zero. We should not try to restore the other
+    // parameters in those conditions.
+    if (!historyItem.pageScaleFactor())
+        return;
+
+    // We can restore the exposed rect and scale, but we cannot touch the scroll position since the obscured insets
+    // may be changing in the UIProcess. The UIProcess can update the position from the information we send and will then
+    // scroll to the correct position through a regular VisibleContentRectUpdate.
+
+    m_userHasChangedPageScaleFactor = !historyItem.scaleIsInitial();
+
+    FloatSize currentMinimumLayoutSizeInScrollViewCoordinates = m_viewportConfiguration.activeMinimumLayoutSizeInScrollViewCoordinates();
+    if (historyItem.minimumLayoutSizeInScrollViewCoordinates() == currentMinimumLayoutSizeInScrollViewCoordinates) {
+        float boundedScale = std::min&lt;float&gt;(m_viewportConfiguration.maximumScale(), std::max&lt;float&gt;(m_viewportConfiguration.minimumScale(), historyItem.pageScaleFactor()));
+        scalePage(boundedScale, IntPoint());
+
+        m_drawingArea-&gt;setExposedContentRect(historyItem.exposedContentRect());
+
+        send(Messages::WebPageProxy::RestorePageState(historyItem.exposedContentRect(), boundedScale));
+    } else {
+        IntSize oldContentSize = historyItem.contentSize();
+        FrameView&amp; frameView = *m_page-&gt;mainFrame().view();
+        IntSize newContentSize = frameView.contentsSize();
+        double visibleHorizontalFraction = static_cast&lt;float&gt;(historyItem.unobscuredContentRect().width()) / oldContentSize.width();
+
+        double newScale = scaleAfterViewportWidthChange(historyItem.pageScaleFactor(), !historyItem.scaleIsInitial(), m_viewportConfiguration, currentMinimumLayoutSizeInScrollViewCoordinates.width(), newContentSize, oldContentSize, visibleHorizontalFraction);
+
+        FloatPoint newCenter;
+        if (!oldContentSize.isEmpty() &amp;&amp; !newContentSize.isEmpty() &amp;&amp; newContentSize != oldContentSize)
+            newCenter = relativeCenterAfterContentSizeChange(historyItem.unobscuredContentRect(), oldContentSize, newContentSize);
+        else
+            newCenter = FloatRect(historyItem.unobscuredContentRect()).center();
+
+        FloatSize unobscuredRectAtNewScale = frameView.customSizeForResizeEvent();
+        unobscuredRectAtNewScale.scale(1 / newScale, 1 / newScale);
+
+        FloatRect oldExposedRect = frameView.exposedContentRect();
+        FloatRect adjustedExposedRect = adjustExposedRectForNewScale(oldExposedRect, m_page-&gt;pageScaleFactor(), newScale);
+
+        FloatPoint oldCenter = adjustedExposedRect.center();
+        adjustedExposedRect.move(newCenter - oldCenter);
+
+        scalePage(newScale, IntPoint());
+
+        send(Messages::WebPageProxy::RestorePageCenterAndScale(newCenter, newScale));
+    }
+}
+
</ins><span class="cx"> double WebPage::minimumPageScaleFactor() const
</span><span class="cx"> {
</span><span class="cx">     return m_viewportConfiguration.minimumScale();
</span><span class="lines">@@ -2046,20 +2129,7 @@
</span><span class="cx"> 
</span><span class="cx">     IntSize newContentSize = frameView.contentsSize();
</span><span class="cx"> 
</span><del>-    double scale;
-    if (!m_userHasChangedPageScaleFactor)
-        scale = m_viewportConfiguration.initialScale();
-    else
-        scale = std::max(std::min(targetScale, m_viewportConfiguration.maximumScale()), m_viewportConfiguration.minimumScale());
-
-    if (m_userHasChangedPageScaleFactor &amp;&amp; newContentSize.width() != oldContentSize.width()) {
-        // When the content size change, we keep the same relative horizontal content width in view, otherwise we would
-        // end up zoom to far in landscape-&gt;portrait, and too close in portrait-&gt;landscape.
-        float widthToKeepInView = visibleHorizontalFraction * newContentSize.width();
-        double newScale = targetUnobscuredRectInScrollViewCoordinates.width() / widthToKeepInView;
-        scale = std::max(std::min(newScale, m_viewportConfiguration.maximumScale()), m_viewportConfiguration.minimumScale());
-    }
-
</del><ins>+    double scale = scaleAfterViewportWidthChange(targetScale, m_userHasChangedPageScaleFactor, m_viewportConfiguration, targetUnobscuredRectInScrollViewCoordinates.width(), newContentSize, oldContentSize, visibleHorizontalFraction);
</ins><span class="cx">     FloatRect newUnobscuredContentRect = targetUnobscuredRect;
</span><span class="cx">     FloatRect newExposedContentRect = targetExposedContentRect;
</span><span class="cx"> 
</span><span class="lines">@@ -2106,13 +2176,8 @@
</span><span class="cx">                 FrameView&amp; containingView = *oldNodeAtCenter-&gt;document().frame()-&gt;view();
</span><span class="cx">                 FloatRect newBoundingBox = containingView.contentsToRootView(renderer-&gt;absoluteBoundingBoxRect(true));
</span><span class="cx">                 newRelativeContentCenter = FloatPoint(newBoundingBox.x() + relativeHorizontalPositionInNodeAtCenter * newBoundingBox.width(), newBoundingBox.y() + relativeVerticalPositionInNodeAtCenter * newBoundingBox.height());
</span><del>-            } else {
-                // If the content size has changed, keep the same relative position.
-                FloatPoint oldContentCenter = targetUnobscuredRect.center();
-                float relativeHorizontalPosition = oldContentCenter.x() / oldContentSize.width();
-                float relativeVerticalPosition =  oldContentCenter.y() / oldContentSize.height();
-                newRelativeContentCenter = FloatPoint(relativeHorizontalPosition * newContentSize.width(), relativeVerticalPosition * newContentSize.height());
-            }
</del><ins>+            } else
+                newRelativeContentCenter = relativeCenterAfterContentSizeChange(targetUnobscuredRect, oldContentSize, newContentSize);
</ins><span class="cx"> 
</span><span class="cx">             FloatPoint newUnobscuredContentRectCenter = newUnobscuredContentRect.center();
</span><span class="cx">             FloatPoint positionDelta(newRelativeContentCenter.x() - newUnobscuredContentRectCenter.x(), newRelativeContentCenter.y() - newUnobscuredContentRectCenter.y());
</span><span class="lines">@@ -2234,7 +2299,7 @@
</span><span class="cx"> 
</span><span class="cx">         // FIXME: We could send down the obscured margins to find a better exposed rect and unobscured rect.
</span><span class="cx">         // It is not a big deal at the moment because the tile coverage will always extend past the obscured bottom inset.
</span><del>-        m_drawingArea-&gt;setExposedContentRect(IntRect(scrollPosition, minimumLayoutSizeInDocumentCoordinates));
</del><ins>+        m_drawingArea-&gt;setExposedContentRect(FloatRect(scrollPosition, minimumLayoutSizeInDocumentCoordinates));
</ins><span class="cx">     }
</span><span class="cx">     scalePage(scale, scrollPosition);
</span><span class="cx">     
</span><span class="lines">@@ -2272,20 +2337,6 @@
</span><span class="cx">     [[NSNotificationCenter defaultCenter] postNotificationName:WebUIApplicationDidBecomeActiveNotification object:nil];
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static inline FloatRect adjustExposedRectForBoundedScale(const FloatRect&amp; exposedRect, double exposedRectScale, double boundedScale)
-{
-    if (exposedRectScale &lt; boundedScale)
-        return exposedRect;
-
-    double overscaledWidth = exposedRect.width();
-    double missingHorizonalMargin = exposedRect.width() * exposedRectScale / boundedScale - overscaledWidth;
-
-    double overscaledHeight = exposedRect.height();
-    double missingVerticalMargin = exposedRect.height() * exposedRectScale / boundedScale - overscaledHeight;
-
-    return FloatRect(exposedRect.x() - missingHorizonalMargin / 2, exposedRect.y() - missingVerticalMargin / 2, exposedRect.width() + missingHorizonalMargin, exposedRect.height() + missingVerticalMargin);
-}
-
</del><span class="cx"> static inline void adjustVelocityDataForBoundedScale(double&amp; horizontalVelocity, double&amp; verticalVelocity, double&amp; scaleChangeRate, double exposedRectScale, double boundedScale)
</span><span class="cx"> {
</span><span class="cx">     if (scaleChangeRate) {
</span><span class="lines">@@ -2297,10 +2348,21 @@
</span><span class="cx">         scaleChangeRate = 0;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline FloatRect adjustExposedRectForBoundedScale(const FloatRect&amp; exposedRect, double exposedRectScale, double newScale)
+{
+    if (exposedRectScale &lt; newScale)
+        return exposedRect;
+
+    return adjustExposedRectForNewScale(exposedRect, exposedRectScale, newScale);
+}
+
</ins><span class="cx"> void WebPage::updateVisibleContentRects(const VisibleContentRectUpdateInfo&amp; visibleContentRectUpdateInfo)
</span><span class="cx"> {
</span><ins>+    // Skip any VisibleContentRectUpdate that have been queued before DidCommitLoad suppresses the updates in the UIProcess.
+    if (visibleContentRectUpdateInfo.lastLayerTreeTransactionID() &lt;= m_lastLayerTreeTransactionIDBeforeDidCommitLoad)
+        return;
+
</ins><span class="cx">     m_hasReceivedVisibleContentRectsAfterDidCommitLoad = true;
</span><del>-    m_obscuredTopInset = (visibleContentRectUpdateInfo.unobscuredRect().y() - visibleContentRectUpdateInfo.exposedRect().y()) * visibleContentRectUpdateInfo.scale();
</del><span class="cx"> 
</span><span class="cx">     double scaleNoiseThreshold = 0.005;
</span><span class="cx">     double filteredScale = visibleContentRectUpdateInfo.scale();
</span><span class="lines">@@ -2315,7 +2377,7 @@
</span><span class="cx"> 
</span><span class="cx">     FloatRect exposedRect = visibleContentRectUpdateInfo.exposedRect();
</span><span class="cx">     FloatRect adjustedExposedRect = adjustExposedRectForBoundedScale(exposedRect, visibleContentRectUpdateInfo.scale(), boundedScale);
</span><del>-    m_drawingArea-&gt;setExposedContentRect(enclosingIntRect(adjustedExposedRect));
</del><ins>+    m_drawingArea-&gt;setExposedContentRect(adjustedExposedRect);
</ins><span class="cx"> 
</span><span class="cx">     IntRect roundedUnobscuredRect = roundedIntRect(visibleContentRectUpdateInfo.unobscuredRect());
</span><span class="cx">     IntPoint scrollPosition = roundedUnobscuredRect.location();
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacRemoteLayerTreeDrawingAreah"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.h        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2012 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2012-2014 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -53,6 +53,8 @@
</span><span class="cx">     RemoteLayerTreeDrawingArea(WebPage&amp;, const WebPageCreationParameters&amp;);
</span><span class="cx">     virtual ~RemoteLayerTreeDrawingArea();
</span><span class="cx"> 
</span><ins>+    uint64_t currentTransactionID() const { return m_currentTransactionID; }
+
</ins><span class="cx"> private:
</span><span class="cx">     // DrawingArea
</span><span class="cx">     virtual void setNeedsDisplay() override;
</span></span></pre></div>
<a id="trunkSourceWebKit2WebProcessWebPagemacRemoteLayerTreeDrawingAreamm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm (170324 => 170325)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm        2014-06-23 22:04:02 UTC (rev 170324)
+++ trunk/Source/WebKit2/WebProcess/WebPage/mac/RemoteLayerTreeDrawingArea.mm        2014-06-23 22:05:47 UTC (rev 170325)
</span><span class="lines">@@ -203,7 +203,7 @@
</span><span class="cx">     if (!frameView)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><del>-    frameView-&gt;setExposedContentRect(enclosingIntRect(exposedContentRect));
</del><ins>+    frameView-&gt;setExposedContentRect(exposedContentRect);
</ins><span class="cx">     scheduleCompositingLayerFlush();
</span><span class="cx"> }
</span><span class="cx"> #endif
</span></span></pre>
</div>
</div>

</body>
</html>