<!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>[168820] branches/safari-538.34-branch/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/168820">168820</a></dd>
<dt>Author</dt> <dd>lforschler@apple.com</dd>
<dt>Date</dt> <dd>2014-05-14 01:53:28 -0700 (Wed, 14 May 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Merged <a href="http://trac.webkit.org/projects/webkit/changeset/168744">r168744</a>.  </pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#branchessafari53834branchSourceWebCoreChangeLog">branches/safari-538.34-branch/Source/WebCore/ChangeLog</a></li>
<li><a href="#branchessafari53834branchSourceWebCoreWebCoreexpin">branches/safari-538.34-branch/Source/WebCore/WebCore.exp.in</a></li>
<li><a href="#branchessafari53834branchSourceWebCoreplatformScrollViewcpp">branches/safari-538.34-branch/Source/WebCore/platform/ScrollView.cpp</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2ChangeLog">branches/safari-538.34-branch/Source/WebKit2/ChangeLog</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2SharedAssistedNodeInformationcpp">branches/safari-538.34-branch/Source/WebKit2/Shared/AssistedNodeInformation.cpp</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2SharedAssistedNodeInformationh">branches/safari-538.34-branch/Source/WebKit2/Shared/AssistedNodeInformation.h</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2UIProcessAPICocoaWKWebViewmm">branches/safari-538.34-branch/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2UIProcessAPICocoaWKWebViewInternalh">branches/safari-538.34-branch/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2UIProcessiosWKContentViewh">branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentView.h</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2UIProcessiosWKContentViewmm">branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentView.mm</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2UIProcessiosWKContentViewInteractionmm">branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm</a></li>
<li><a href="#branchessafari53834branchSourceWebKit2WebProcessWebPageiosWebPageIOSmm">branches/safari-538.34-branch/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="branchessafari53834branchSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebCore/ChangeLog (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebCore/ChangeLog        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebCore/ChangeLog        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -1,5 +1,24 @@
</span><span class="cx"> 2014-05-14  Lucas Forschler  &lt;lforschler@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r168744
+
+    2014-05-13  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+            REGRESSION (WebKit2): Zooming to text field leaves it partially hidden by the form assistant.
+            https://bugs.webkit.org/show_bug.cgi?id=132879
+            &lt;rdar://problem/16318049&gt;
+
+            Reviewed by Benjamin Poulain.
+
+            Adding some exports. The fix to setScrollPosition is to avoid clamping the scroll
+            position when using delegate scrolling.
+
+            * WebCore.exp.in:
+            * platform/ScrollView.cpp:
+            (WebCore::ScrollView::setScrollPosition):
+
+2014-05-14  Lucas Forschler  &lt;lforschler@apple.com&gt;
+
</ins><span class="cx">         Merge r168670
</span><span class="cx"> 
</span><span class="cx">     2014-05-12  Simon Fraser  &lt;simon.fraser@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebCoreWebCoreexpin"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebCore/WebCore.exp.in (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebCore/WebCore.exp.in        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebCore/WebCore.exp.in        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -1545,6 +1545,7 @@
</span><span class="cx"> __ZNK7WebCore11RenderLayer19absoluteBoundingBoxEv
</span><span class="cx"> __ZNK7WebCore11RenderLayer24needsCompositedScrollingEv
</span><span class="cx"> __ZNK7WebCore11RenderStyle11fontMetricsEv
</span><ins>+__ZNK7WebCore11RenderStyle15fontDescriptionEv
</ins><span class="cx"> __ZNK7WebCore11RenderStyle21visitedDependentColorEi
</span><span class="cx"> __ZNK7WebCore11RenderStyle4fontEv
</span><span class="cx"> __ZNK7WebCore12RenderObject14enclosingLayerEv
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebCoreplatformScrollViewcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebCore/platform/ScrollView.cpp (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebCore/platform/ScrollView.cpp        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebCore/platform/ScrollView.cpp        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -504,7 +504,7 @@
</span><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    IntPoint newScrollPosition = adjustScrollPositionWithinRange(scrollPoint);
</del><ins>+    IntPoint newScrollPosition = !delegatesScrolling() ? adjustScrollPositionWithinRange(scrollPoint) : scrollPoint;
</ins><span class="cx"> 
</span><span class="cx">     if ((!delegatesScrolling() || !inProgrammaticScroll()) &amp;&amp; newScrollPosition == scrollPosition())
</span><span class="cx">         return;
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2ChangeLog"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/ChangeLog (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/ChangeLog        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/ChangeLog        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -1,5 +1,38 @@
</span><span class="cx"> 2014-05-14  Lucas Forschler  &lt;lforschler@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Merge r168744
+
+    2014-05-13  Enrica Casucci  &lt;enrica@apple.com&gt;
+
+            REGRESSION (WebKit2): Zooming to text field leaves it partially hidden by the form assistant.
+            https://bugs.webkit.org/show_bug.cgi?id=132879
+            &lt;rdar://problem/16318049&gt;
+
+            Reviewed by Benjamin Poulain.
+
+            Adds the heuristics to zoom and scroll to ensure the element being focused
+            is fully visible and its text readable.
+
+            * Shared/AssistedNodeInformation.cpp:
+            (WebKit::AssistedNodeInformation::encode):
+            (WebKit::AssistedNodeInformation::decode):
+            * Shared/AssistedNodeInformation.h:
+            (WebKit::AssistedNodeInformation::AssistedNodeInformation):
+            * UIProcess/API/Cocoa/WKWebView.mm:
+            (-[WKWebView _zoomToFocusRect:WebCore::selectionRect:WebCore::fontSize:minimumScale:maximumScale:allowUserScaling:forceScroll:]):
+            (-[WKWebView _keyboardChangedWithInfo:adjustScrollView:]):
+            * UIProcess/API/Cocoa/WKWebViewInternal.h:
+            * UIProcess/ios/WKContentView.h:
+            * UIProcess/ios/WKContentView.mm:
+            (-[WKContentView _zoomToFocusRect:selectionRect:fontSize:minimumScale:maximumScale:allowUserScaling:forceScroll:]):
+            * UIProcess/ios/WKContentViewInteraction.mm:
+            (-[WKContentView _displayFormNodeInputView]):
+            (-[WKContentView _startAssistingNode:userIsInteracting:userObject:]):
+            * WebProcess/WebPage/ios/WebPageIOS.mm:
+            (WebKit::WebPage::getAssistedNodeInformation):
+
+2014-05-14  Lucas Forschler  &lt;lforschler@apple.com&gt;
+
</ins><span class="cx">         Merge r168768
</span><span class="cx"> 
</span><span class="cx">     2014-05-13  Anders Carlsson  &lt;andersca@apple.com&gt;
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2SharedAssistedNodeInformationcpp"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/Shared/AssistedNodeInformation.cpp (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/Shared/AssistedNodeInformation.cpp        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/Shared/AssistedNodeInformation.cpp        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -64,8 +64,10 @@
</span><span class="cx"> void AssistedNodeInformation::encode(IPC::ArgumentEncoder&amp; encoder) const
</span><span class="cx"> {
</span><span class="cx">     encoder &lt;&lt; elementRect;
</span><ins>+    encoder &lt;&lt; selectionRect;
</ins><span class="cx">     encoder &lt;&lt; minimumScaleFactor;
</span><span class="cx">     encoder &lt;&lt; maximumScaleFactor;
</span><ins>+    encoder &lt;&lt; nodeFontSize;
</ins><span class="cx">     encoder &lt;&lt; hasNextNode;
</span><span class="cx">     encoder &lt;&lt; hasPreviousNode;
</span><span class="cx">     encoder &lt;&lt; isAutocorrect;
</span><span class="lines">@@ -76,6 +78,7 @@
</span><span class="cx">     encoder &lt;&lt; selectedIndex;
</span><span class="cx">     encoder &lt;&lt; isMultiSelect;
</span><span class="cx">     encoder &lt;&lt; isReadOnly;
</span><ins>+    encoder &lt;&lt; allowsUserScaling;
</ins><span class="cx">     encoder &lt;&lt; value;
</span><span class="cx">     encoder &lt;&lt; valueAsNumber;
</span><span class="cx">     encoder &lt;&lt; title;
</span><span class="lines">@@ -86,12 +89,18 @@
</span><span class="cx">     if (!decoder.decode(result.elementRect))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.selectionRect))
+        return false;
+
</ins><span class="cx">     if (!decoder.decode(result.minimumScaleFactor))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="cx">     if (!decoder.decode(result.maximumScaleFactor))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.nodeFontSize))
+        return false;
+
</ins><span class="cx">     if (!decoder.decode(result.hasNextNode))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><span class="lines">@@ -122,6 +131,9 @@
</span><span class="cx">     if (!decoder.decode(result.isReadOnly))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span><ins>+    if (!decoder.decode(result.allowsUserScaling))
+        return false;
+
</ins><span class="cx">     if (!decoder.decode(result.value))
</span><span class="cx">         return false;
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2SharedAssistedNodeInformationh"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/Shared/AssistedNodeInformation.h (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/Shared/AssistedNodeInformation.h        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/Shared/AssistedNodeInformation.h        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -95,11 +95,13 @@
</span><span class="cx">     AssistedNodeInformation()
</span><span class="cx">         : minimumScaleFactor(-INFINITY)
</span><span class="cx">         , maximumScaleFactor(INFINITY)
</span><ins>+        , nodeFontSize(0)
</ins><span class="cx">         , hasNextNode(false)
</span><span class="cx">         , hasPreviousNode(false)
</span><span class="cx">         , isAutocorrect(false)
</span><span class="cx">         , isMultiSelect(false)
</span><span class="cx">         , isReadOnly(false)
</span><ins>+        , allowsUserScaling(false)
</ins><span class="cx">         , autocapitalizeType(WebAutocapitalizeTypeDefault)
</span><span class="cx">         , elementType(WKTypeNone)
</span><span class="cx">         , selectedIndex(-1)
</span><span class="lines">@@ -108,13 +110,16 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     WebCore::IntRect elementRect;
</span><ins>+    WebCore::IntRect selectionRect;
</ins><span class="cx">     double minimumScaleFactor;
</span><span class="cx">     double maximumScaleFactor;
</span><ins>+    double nodeFontSize;
</ins><span class="cx">     bool hasNextNode;
</span><span class="cx">     bool hasPreviousNode;
</span><span class="cx">     bool isAutocorrect;
</span><span class="cx">     bool isMultiSelect;
</span><span class="cx">     bool isReadOnly;
</span><ins>+    bool allowsUserScaling;
</ins><span class="cx">     WebAutocapitalizeType autocapitalizeType;
</span><span class="cx">     WKInputType elementType;
</span><span class="cx">     String formAction;
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2UIProcessAPICocoaWKWebViewmm"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -83,6 +83,19 @@
</span><span class="cx"> @interface UIPeripheralHost(UIKitInternal)
</span><span class="cx"> - (CGFloat)getVerticalOverlapForView:(UIView *)view usingKeyboardInfo:(NSDictionary *)info;
</span><span class="cx"> @end
</span><ins>+
+@interface UIView (UIViewInternal)
+- (UIViewController *)_viewControllerForAncestor;
+@end
+
+@interface UIWindow (UIWindowInternal)
+- (BOOL)_isHostedInAnotherProcess;
+@end
+
+@interface UIViewController (UIViewControllerInternal)
+- (UIViewController *)_rootAncestorViewController;
+- (UIViewController *)_viewControllerForSupportedInterfaceOrientations;
+@end
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="lines">@@ -105,6 +118,7 @@
</span><span class="cx">     BOOL _hasStaticMinimumLayoutSize;
</span><span class="cx">     CGSize _minimumLayoutSizeOverride;
</span><span class="cx">     CGSize _minimumLayoutSizeOverrideForMinimalUI;
</span><ins>+    CGRect _inputViewBounds;
</ins><span class="cx"> 
</span><span class="cx">     UIEdgeInsets _obscuredInsets;
</span><span class="cx">     bool _isChangingObscuredInsetsInteractively;
</span><span class="lines">@@ -119,7 +133,6 @@
</span><span class="cx">     CATransform3D _resizeAnimationTransformAdjustments;
</span><span class="cx">     RetainPtr&lt;UIView&gt; _resizeAnimationView;
</span><span class="cx">     CGFloat _lastAdjustmentForScroller;
</span><del>-    CGFloat _keyboardVerticalOverlap;
</del><span class="cx"> 
</span><span class="cx">     std::unique_ptr&lt;WebKit::ViewGestureController&gt; _gestureController;
</span><span class="cx">     BOOL _allowsBackForwardNavigationGestures;
</span><span class="lines">@@ -610,6 +623,122 @@
</span><span class="cx">     [self _zoomToPoint:origin atScale:[_scrollView minimumZoomScale]];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// focusedElementRect and selectionRect are both in document coordinates.
+- (void)_zoomToFocusRect:(WebCore::FloatRect)focusedElementRectInDocumentCoordinates selectionRect:(WebCore::FloatRect)selectionRectInDocumentCoordinates fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll
+{
+    const double WKWebViewStandardFontSize = 16;
+    const double kMinimumHeightToShowContentAboveKeyboard = 106;
+    const CFTimeInterval UIWebFormAnimationDuration = 0.25;
+    const double CaretOffsetFromWindowEdge = 20;
+
+    // Zoom around the element's bounding frame. We use a &quot;standard&quot; size to determine the proper frame.
+    double scale = allowScaling ? std::min(std::max(WKWebViewStandardFontSize / fontSize, minimumScale), maximumScale) : contentZoomScale(self);
+    CGFloat documentWidth = [_contentView bounds].size.width;
+    scale = CGRound(documentWidth * scale) / documentWidth;
+
+    UIWindow *window = [_scrollView window];
+
+    WebCore::FloatRect focusedElementRectInNewScale = focusedElementRectInDocumentCoordinates;
+    focusedElementRectInNewScale.scale(scale);
+    focusedElementRectInNewScale.moveBy([_contentView frame].origin);
+
+    // Find the portion of the view that is visible on the screen.
+    UIViewController *topViewController = [[[_scrollView _viewControllerForAncestor] _rootAncestorViewController] _viewControllerForSupportedInterfaceOrientations];
+    UIView *fullScreenView = topViewController.view;
+    if (!fullScreenView)
+        fullScreenView = window;
+
+    CGRect unobscuredScrollViewRectInWebViewCoordinates = UIEdgeInsetsInsetRect([self bounds], _obscuredInsets);
+    CGRect visibleScrollViewBoundsInWebViewCoordinates = CGRectIntersection(unobscuredScrollViewRectInWebViewCoordinates, [fullScreenView convertRect:[fullScreenView bounds] toView:self]);
+    CGRect formAssistantFrameInWebViewCoordinates = [window convertRect:_inputViewBounds toView:self];
+    CGRect intersectionBetweenScrollViewAndFormAssistant = CGRectIntersection(visibleScrollViewBoundsInWebViewCoordinates, formAssistantFrameInWebViewCoordinates);
+    CGSize visibleSize = visibleScrollViewBoundsInWebViewCoordinates.size;
+
+    CGFloat visibleOffsetFromTop = 0;
+    if (!CGRectIsEmpty(intersectionBetweenScrollViewAndFormAssistant)) {
+        CGFloat heightVisibleAboveFormAssistant = CGRectGetMinY(intersectionBetweenScrollViewAndFormAssistant) - CGRectGetMinY(visibleScrollViewBoundsInWebViewCoordinates);
+        CGFloat heightVisibleBelowFormAssistant = CGRectGetMaxY(visibleScrollViewBoundsInWebViewCoordinates) - CGRectGetMaxY(intersectionBetweenScrollViewAndFormAssistant);
+
+        if (heightVisibleAboveFormAssistant &gt;= kMinimumHeightToShowContentAboveKeyboard || heightVisibleBelowFormAssistant &lt; heightVisibleAboveFormAssistant)
+            visibleSize.height = heightVisibleAboveFormAssistant;
+        else {
+            visibleSize.height = heightVisibleBelowFormAssistant;
+            visibleOffsetFromTop = CGRectGetMaxY(intersectionBetweenScrollViewAndFormAssistant) - CGRectGetMinY(visibleScrollViewBoundsInWebViewCoordinates);
+        }
+    }
+
+    BOOL selectionRectIsNotNull = !selectionRectInDocumentCoordinates.isZero();
+    if (!forceScroll) {
+        CGRect currentlyVisibleRegionInWebViewCoordinates;
+        currentlyVisibleRegionInWebViewCoordinates.origin = unobscuredScrollViewRectInWebViewCoordinates.origin;
+        currentlyVisibleRegionInWebViewCoordinates.origin.y += visibleOffsetFromTop;
+        currentlyVisibleRegionInWebViewCoordinates.size = visibleSize;
+
+        // Don't bother scrolling if the entire node is already visible, whether or not we got a selectionRect.
+        if (CGRectContainsRect(currentlyVisibleRegionInWebViewCoordinates, [self convertRect:focusedElementRectInDocumentCoordinates fromView:_contentView.get()]))
+            return;
+
+        // Don't bother scrolling if we have a valid selectionRect and it is already visible.
+        if (selectionRectIsNotNull &amp;&amp; CGRectContainsRect(currentlyVisibleRegionInWebViewCoordinates, [self convertRect:selectionRectInDocumentCoordinates fromView:_contentView.get()]))
+            return;
+    }
+
+    // We want to zoom to the left/top corner of the DOM node, with as much spacing on all sides as we
+    // can get based on the visible area after zooming (workingFrame).  The spacing in either dimension is half the
+    // difference between the size of the DOM node and the size of the visible frame.
+    CGFloat horizontalSpaceInWebViewCoordinates = std::max((visibleSize.width - focusedElementRectInNewScale.width()) / 2.0, 0.0);
+    CGFloat verticalSpaceInWebViewCoordinates = std::max((visibleSize.height - focusedElementRectInNewScale.height()) / 2.0, 0.0);
+
+    CGPoint topLeft;
+    topLeft.x = focusedElementRectInNewScale.x() - horizontalSpaceInWebViewCoordinates;
+    topLeft.y = focusedElementRectInNewScale.y() - verticalSpaceInWebViewCoordinates - visibleOffsetFromTop;
+
+    CGFloat minimumAllowableHorizontalOffsetInWebViewCoordinates = -INFINITY;
+    CGFloat minimumAllowableVerticalOffsetInWebViewCoordinates = -INFINITY;
+    if (selectionRectIsNotNull) {
+        WebCore::FloatRect selectionRectInNewScale = selectionRectInDocumentCoordinates;
+        selectionRectInNewScale.scale(scale);
+        selectionRectInNewScale.moveBy([_contentView frame].origin);
+        minimumAllowableHorizontalOffsetInWebViewCoordinates = CGRectGetMaxX(selectionRectInNewScale) + CaretOffsetFromWindowEdge - visibleSize.width;
+        minimumAllowableVerticalOffsetInWebViewCoordinates = CGRectGetMaxY(selectionRectInNewScale) + CaretOffsetFromWindowEdge - visibleSize.height - visibleOffsetFromTop;
+    }
+
+    WebCore::FloatRect documentBoundsInNewScale = [_contentView bounds];
+    documentBoundsInNewScale.scale(scale);
+    documentBoundsInNewScale.moveBy([_contentView frame].origin);
+
+    // Constrain the left edge in document coordinates so that:
+    //  - it isn't so small that the scrollVisibleRect isn't visible on the screen
+    //  - it isn't so great that the document's right edge is less than the right edge of the screen
+    if (selectionRectIsNotNull &amp;&amp; topLeft.x &lt; minimumAllowableHorizontalOffsetInWebViewCoordinates)
+        topLeft.x = minimumAllowableHorizontalOffsetInWebViewCoordinates;
+    else {
+        CGFloat maximumAllowableHorizontalOffset = CGRectGetMaxX(documentBoundsInNewScale) - visibleSize.width;
+        if (topLeft.x &gt; maximumAllowableHorizontalOffset)
+            topLeft.x = maximumAllowableHorizontalOffset;
+    }
+
+    // Constrain the top edge in document coordinates so that:
+    //  - it isn't so small that the scrollVisibleRect isn't visible on the screen
+    //  - it isn't so great that the document's bottom edge is higher than the top of the form assistant
+    if (selectionRectIsNotNull &amp;&amp; topLeft.y &lt; minimumAllowableVerticalOffsetInWebViewCoordinates)
+        topLeft.y = minimumAllowableVerticalOffsetInWebViewCoordinates;
+    else {
+        CGFloat maximumAllowableVerticalOffset = CGRectGetMaxY(documentBoundsInNewScale) - visibleSize.height;
+        if (topLeft.y &gt; maximumAllowableVerticalOffset)
+            topLeft.y = maximumAllowableVerticalOffset;
+    }
+
+    WebCore::FloatPoint newCenter = CGPointMake(topLeft.x + unobscuredScrollViewRectInWebViewCoordinates.size.width / 2.0, topLeft.y + unobscuredScrollViewRectInWebViewCoordinates.size.height / 2.0);
+
+    // The newCenter has been computed in the new scale, but _zoomToCenter expected the center to be in the original scale.
+    newCenter.scale(1 / scale, 1 / scale);
+    [_scrollView _zoomToCenter:newCenter
+                        scale:scale
+                     duration:UIWebFormAnimationDuration
+                        force:YES];
+}
+
</ins><span class="cx"> - (BOOL)_zoomToRect:(WebCore::FloatRect)targetRect withOrigin:(WebCore::FloatPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(float)minimumScrollDistance
</span><span class="cx"> {
</span><span class="cx">     const float maximumScaleFactorDeltaForPanScroll = 0.02;
</span><span class="lines">@@ -753,7 +882,7 @@
</span><span class="cx"> {
</span><span class="cx">     // FIXME: handle split keyboard.
</span><span class="cx">     UIEdgeInsets obscuredInsets = _obscuredInsets;
</span><del>-    obscuredInsets.bottom = std::max(_obscuredInsets.bottom, _keyboardVerticalOverlap);
</del><ins>+    obscuredInsets.bottom = std::max(_obscuredInsets.bottom, _inputViewBounds.size.height);
</ins><span class="cx">     CGRect unobscuredRect = UIEdgeInsetsInsetRect(self.bounds, obscuredInsets);
</span><span class="cx">     return [self convertRect:unobscuredRect toView:_contentView.get()];
</span><span class="cx"> }
</span><span class="lines">@@ -780,7 +909,18 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_keyboardChangedWithInfo:(NSDictionary *)keyboardInfo adjustScrollView:(BOOL)adjustScrollView
</span><span class="cx"> {
</span><del>-    _keyboardVerticalOverlap = [[UIPeripheralHost sharedInstance] getVerticalOverlapForView:self usingKeyboardInfo:keyboardInfo];
</del><ins>+    NSValue *endFrameValue = [keyboardInfo objectForKey:UIKeyboardFrameEndUserInfoKey];
+    if (!endFrameValue)
+        return;
+
+    // The keyboard rect is always in screen coordinates. In the view services case the window does not
+    // have the interface orientation rotation transformation; its host does. So, it makes no sense to
+    // clip the keyboard rect against its screen.
+    if ([[self window] _isHostedInAnotherProcess])
+        _inputViewBounds = [self.window convertRect:[endFrameValue CGRectValue] fromWindow:nil];
+    else
+        _inputViewBounds = [self.window convertRect:CGRectIntersection([endFrameValue CGRectValue], self.window.screen.bounds) fromWindow:nil];
+
</ins><span class="cx">     [self _updateVisibleContentRects];
</span><span class="cx"> 
</span><span class="cx">     if (adjustScrollView)
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2UIProcessAPICocoaWKWebViewInternalh"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/UIProcess/API/Cocoa/WKWebViewInternal.h        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -67,6 +67,7 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_scrollToContentOffset:(WebCore::FloatPoint)contentOffset;
</span><span class="cx"> - (BOOL)_scrollToRect:(WebCore::FloatRect)targetRect origin:(WebCore::FloatPoint)origin minimumScrollDistance:(float)minimumScrollDistance;
</span><ins>+- (void)_zoomToFocusRect:(WebCore::FloatRect)focusedElementRect selectionRect:(WebCore::FloatRect)selectionRectInDocumentCoordinates fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll;
</ins><span class="cx"> - (BOOL)_zoomToRect:(WebCore::FloatRect)targetRect withOrigin:(WebCore::FloatPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(float)minimumScrollDistance;
</span><span class="cx"> - (void)_zoomOutWithOrigin:(WebCore::FloatPoint)origin;
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2UIProcessiosWKContentViewh"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentView.h (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentView.h        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentView.h        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -81,6 +81,7 @@
</span><span class="cx"> - (void)_setAccessibilityWebProcessToken:(NSData *)data;
</span><span class="cx"> 
</span><span class="cx"> - (BOOL)_scrollToRect:(CGRect)targetRect withOrigin:(CGPoint)origin minimumScrollDistance:(CGFloat)minimumScrollDistance;
</span><ins>+- (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll;
</ins><span class="cx"> - (BOOL)_zoomToRect:(CGRect)targetRect withOrigin:(CGPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(CGFloat)minimumScrollDistance;
</span><span class="cx"> - (void)_zoomOutWithOrigin:(CGPoint)origin;
</span><span class="cx"> 
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2UIProcessiosWKContentViewmm"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentView.mm (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentView.mm        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentView.mm        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -446,6 +446,17 @@
</span><span class="cx">     return [_webView _scrollToRect:targetRect origin:origin minimumScrollDistance:minimumScrollDistance];
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+- (void)_zoomToFocusRect:(CGRect)rectToFocus selectionRect:(CGRect)selectionRect fontSize:(float)fontSize minimumScale:(double)minimumScale maximumScale:(double)maximumScale allowScaling:(BOOL)allowScaling forceScroll:(BOOL)forceScroll
+{
+    [_webView _zoomToFocusRect:rectToFocus
+                 selectionRect:selectionRect
+                      fontSize:fontSize
+                  minimumScale:minimumScale
+                  maximumScale:maximumScale
+              allowScaling:allowScaling
+                   forceScroll:forceScroll];
+}
+
</ins><span class="cx"> - (BOOL)_zoomToRect:(CGRect)targetRect withOrigin:(CGPoint)origin fitEntireRect:(BOOL)fitEntireRect minimumScale:(double)minimumScale maximumScale:(double)maximumScale minimumScrollDistance:(CGFloat)minimumScrollDistance
</span><span class="cx"> {
</span><span class="cx">     return [_webView _zoomToRect:targetRect withOrigin:origin fitEntireRect:fitEntireRect minimumScale:minimumScale maximumScale:maximumScale minimumScrollDistance:minimumScrollDistance];
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2UIProcessiosWKContentViewInteractionmm"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/UIProcess/ios/WKContentViewInteraction.mm        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -495,15 +495,13 @@
</span><span class="cx"> 
</span><span class="cx"> - (void)_displayFormNodeInputView
</span><span class="cx"> {
</span><del>-    if (UICurrentUserInterfaceIdiomIsPad())
-        [self _scrollToRect:_assistedNodeInformation.elementRect withOrigin:_page-&gt;editorState().caretRectAtStart.location() minimumScrollDistance:0];
-    else
-        [self _zoomToRect:_assistedNodeInformation.elementRect
-               withOrigin:_page-&gt;editorState().caretRectAtStart.location()
-            fitEntireRect:YES minimumScale:_assistedNodeInformation.minimumScaleFactor
-             maximumScale:_assistedNodeInformation.maximumScaleFactor
-    minimumScrollDistance:0];
-
</del><ins>+    [self _zoomToFocusRect:_assistedNodeInformation.elementRect
+             selectionRect:_assistedNodeInformation.selectionRect
+                  fontSize:_assistedNodeInformation.nodeFontSize
+              minimumScale:_assistedNodeInformation.minimumScaleFactor
+              maximumScale:_assistedNodeInformation.maximumScaleFactor
+              allowScaling:(_assistedNodeInformation.allowsUserScaling &amp;&amp; !UICurrentUserInterfaceIdiomIsPad())
+               forceScroll:[self requiresAccessoryView]];
</ins><span class="cx">     [self _updateAccessory];
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -2126,6 +2124,11 @@
</span><span class="cx">     if (!userIsInteracting &amp;&amp; !_textSelectionAssistant)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><ins>+    // FIXME: We should remove this check when we manage to send StartAssistingNode from the WebProcess
+    // only when it is truly time to show the keyboard.
+    if (_assistedNodeInformation.elementType == information.elementType &amp;&amp; _assistedNodeInformation.elementRect == information.elementRect)
+        return;
+
</ins><span class="cx">     _isEditable = YES;
</span><span class="cx">     _assistedNodeInformation = information;
</span><span class="cx">     _inputPeripheral = nil;
</span></span></pre></div>
<a id="branchessafari53834branchSourceWebKit2WebProcessWebPageiosWebPageIOSmm"></a>
<div class="modfile"><h4>Modified: branches/safari-538.34-branch/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (168819 => 168820)</h4>
<pre class="diff"><span>
<span class="info">--- branches/safari-538.34-branch/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-05-14 08:44:09 UTC (rev 168819)
+++ branches/safari-538.34-branch/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm        2014-05-14 08:53:28 UTC (rev 168820)
</span><span class="lines">@@ -1776,12 +1776,17 @@
</span><span class="cx"> {
</span><span class="cx">     layoutIfNeeded();
</span><span class="cx"> 
</span><del>-    if (RenderObject* renderer = m_assistedNode-&gt;renderer())
</del><ins>+    if (RenderObject* renderer = m_assistedNode-&gt;renderer()) {
</ins><span class="cx">         information.elementRect = m_page-&gt;focusController().focusedOrMainFrame().view()-&gt;contentsToRootView(renderer-&gt;absoluteBoundingBoxRect());
</span><del>-    else
</del><ins>+        information.nodeFontSize = renderer-&gt;style().fontDescription().computedSize();
+    } else
</ins><span class="cx">         information.elementRect = IntRect();
</span><ins>+    // FIXME: This should return the selection rect, but when this is called at focus time
+    // we don't have a selection yet. Using the last interaction location is a reasonable approximation for now.
+    information.selectionRect = IntRect(m_lastInteractionLocation, IntSize(1, 1));
</ins><span class="cx">     information.minimumScaleFactor = m_viewportConfiguration.minimumScale();
</span><span class="cx">     information.maximumScaleFactor = m_viewportConfiguration.maximumScale();
</span><ins>+    information.allowsUserScaling = m_viewportConfiguration.allowsUserScaling();
</ins><span class="cx">     information.hasNextNode = hasFocusableElement(m_assistedNode.get(), m_page.get(), true);
</span><span class="cx">     information.hasPreviousNode = hasFocusableElement(m_assistedNode.get(), m_page.get(), false);
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>