[iOS WebKit2] Implement CSS viewport units
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Apr 2014 20:16:50 +0000 (20:16 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 21 Apr 2014 20:16:50 +0000 (20:16 +0000)
https://bugs.webkit.org/show_bug.cgi?id=131863
<rdar://problem/16279088>

Reviewed by Darin Adler.

* UIProcess/API/Cocoa/WKWebView.mm:
(setMinimumLayoutSizeForMinimalUI):
(-[WKWebView _minimumLayoutSizeOverrideForMinimalUI]):
(-[WKWebView _setMinimumLayoutSizeOverrideForMinimalUI:]):
Add _setMinimumLayoutSizeOverrideForMinimalUI:, which pushes said size
down from the client to WebPageIOS, below.

* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::setMinimumLayoutSizeForMinimalUI):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::setMinimumLayoutSizeForMinimalUI):
(WebKit::WebPage::viewportConfigurationChanged):
Update FrameView's viewport size based on the minimum layout size for minimal UI (if we have it)
or the normal minimum layout size, scaled to the page's initial scale.

* WebCore.exp.in:
* page/FrameView.cpp:
(WebCore::FrameView::setViewportSize):
* page/FrameView.h:
(WebCore::FrameView::viewportSize):
Add setViewportSize() and viewportSize().
If the viewport size changes, we have to do style recalc.
If we have an overridden viewport size, use it.

* rendering/RenderView.cpp:
(WebCore::RenderView::viewportSize):
* rendering/RenderView.h:
Get the size from FrameView.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@167616 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/WebCore.exp.in
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/rendering/RenderView.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit2/UIProcess/WebPageProxy.h
Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit2/WebProcess/WebPage/WebPage.h
Source/WebKit2/WebProcess/WebPage/WebPage.messages.in
Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm

index 82b4887..5723bb0 100644 (file)
@@ -1,3 +1,25 @@
+2014-04-21  Tim Horton  <timothy_horton@apple.com>
+
+        [iOS WebKit2] Implement CSS viewport units
+        https://bugs.webkit.org/show_bug.cgi?id=131863
+        <rdar://problem/16279088>
+
+        Reviewed by Darin Adler.
+
+        * WebCore.exp.in:
+        * page/FrameView.cpp:
+        (WebCore::FrameView::setViewportSize):
+        * page/FrameView.h:
+        (WebCore::FrameView::viewportSize):
+        Add setViewportSize() and viewportSize().
+        If the viewport size changes, we have to do style recalc.
+        If we have an overridden viewport size, use it.
+
+        * rendering/RenderView.cpp:
+        (WebCore::RenderView::viewportSize):
+        * rendering/RenderView.h:
+        Get the size from FrameView.
+
 2014-04-21  Joseph Pecoraro  <pecoraro@apple.com>
 
         Remove unused WebKitSystemInterface functions
index f799929..ba385a5 100644 (file)
@@ -1343,6 +1343,7 @@ __ZN7WebCore9FrameView14setNeedsLayoutEv
 __ZN7WebCore9FrameView14setTransparentEb
 __ZN7WebCore9FrameView15setFooterHeightEi
 __ZN7WebCore9FrameView15setHeaderHeightEi
+__ZN7WebCore9FrameView15setViewportSizeENS_7IntSizeE
 __ZN7WebCore9FrameView16setPaintBehaviorEj
 __ZN7WebCore9FrameView17addScrollableAreaEPNS_14ScrollableAreaE
 __ZN7WebCore9FrameView17paintControlTintsEv
index 4ecba8a..a201341 100644 (file)
@@ -182,6 +182,7 @@ FrameView::FrameView(Frame& frame)
 #if PLATFORM(IOS)
     , m_useCustomFixedPositionLayoutRect(false)
 #endif
+    , m_hasOverrideViewportSize(false)
     , m_shouldAutoSize(false)
     , m_inAutoSize(false)
     , m_didRunAutosize(false)
@@ -4298,5 +4299,25 @@ void FrameView::setExposedRect(FloatRect exposedRect)
     if (auto* view = renderView())
         view->compositor().scheduleLayerFlush(false /* canThrottle */);
 }
-
+    
+void FrameView::setViewportSize(IntSize size)
+{
+    if (m_hasOverrideViewportSize && m_overrideViewportSize == size)
+        return;
+    
+    m_overrideViewportSize = size;
+    m_hasOverrideViewportSize = true;
+    
+    if (Document* document = m_frame->document())
+        document->styleResolverChanged(DeferRecalcStyle);
+}
+    
+IntSize FrameView::viewportSize() const
+{
+    if (m_hasOverrideViewportSize)
+        return m_overrideViewportSize;
+    
+    return visibleContentRectIncludingScrollbars(ScrollableArea::LegacyIOSDocumentVisibleRect).size();
+}
+    
 } // namespace WebCore
index e0a54e0..e54f286 100644 (file)
@@ -213,6 +213,9 @@ public:
 
     void adjustViewSize();
     
+    void setViewportSize(IntSize);
+    IntSize viewportSize() const;
+    
     virtual IntRect windowClipRect(bool clipToContents = true) const override;
     IntRect windowClipRectForFrameOwner(const HTMLFrameOwnerElement*, bool clipToLayerContents) const;
 
@@ -683,6 +686,9 @@ private:
     IntRect m_customFixedPositionLayoutRect;
 #endif
 
+    IntSize m_overrideViewportSize;
+    bool m_hasOverrideViewportSize;
+
     // If true, automatically resize the frame view around its content.
     bool m_shouldAutoSize;
     bool m_inAutoSize;
index 2ea86a1..985870a 100644 (file)
@@ -1045,9 +1045,7 @@ bool RenderView::shouldDisableLayoutStateForSubtree(RenderObject* renderer) cons
 
 IntSize RenderView::viewportSize() const
 {
-    // FIXME: viewportSize() is used to layout content from viewport units. On iOS, it should use the last stable
-    // unobscured rect. See <rdar://problem/16279088>.
-    return frameView().visibleContentRectIncludingScrollbars(ScrollableArea::LegacyIOSDocumentVisibleRect).size();
+    return frameView().viewportSize();
 }
 
 void RenderView::updateHitTestResult(HitTestResult& result, const LayoutPoint& point)
index b2c325d..d24deec 100644 (file)
@@ -1,3 +1,30 @@
+2014-04-21  Tim Horton  <timothy_horton@apple.com>
+
+        [iOS WebKit2] Implement CSS viewport units
+        https://bugs.webkit.org/show_bug.cgi?id=131863
+        <rdar://problem/16279088>
+
+        Reviewed by Darin Adler.
+
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (setMinimumLayoutSizeForMinimalUI):
+        (-[WKWebView _minimumLayoutSizeOverrideForMinimalUI]):
+        (-[WKWebView _setMinimumLayoutSizeOverrideForMinimalUI:]):
+        Add _setMinimumLayoutSizeOverrideForMinimalUI:, which pushes said size
+        down from the client to WebPageIOS, below.
+
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::setMinimumLayoutSizeForMinimalUI):
+        * WebProcess/WebPage/WebPage.h:
+        * WebProcess/WebPage/WebPage.messages.in:
+        * WebProcess/WebPage/ios/WebPageIOS.mm:
+        (WebKit::WebPage::setMinimumLayoutSizeForMinimalUI):
+        (WebKit::WebPage::viewportConfigurationChanged):
+        Update FrameView's viewport size based on the minimum layout size for minimal UI (if we have it)
+        or the normal minimum layout size, scaled to the page's initial scale.
+
 2014-04-21  Benjamin Poulain  <bpoulain@apple.com>
 
         [iOS][WK2] Fix the dynamic viewport update when the viewport's max-scale conflict with the transition
index e500e7c..18a3ee9 100644 (file)
     BOOL _isWaitingForNewLayerTreeAfterDidCommitLoad;
     BOOL _hasStaticMinimumLayoutSize;
     CGSize _minimumLayoutSizeOverride;
+    CGSize _minimumLayoutSizeOverrideForMinimalUI;
 
     UIEdgeInsets _obscuredInsets;
     bool _isChangingObscuredInsetsInteractively;
@@ -1269,6 +1270,18 @@ static inline WebKit::FindOptions toFindOptions(_WKFindOptions wkFindOptions)
         setViewportConfigurationMinimumLayoutSize(*_page, minimumLayoutSizeOverride);
 }
 
+- (CGSize)_minimumLayoutSizeOverrideForMinimalUI
+{
+    return _minimumLayoutSizeOverrideForMinimalUI;
+}
+
+- (void)_setMinimumLayoutSizeOverrideForMinimalUI:(CGSize)size
+{
+    _minimumLayoutSizeOverrideForMinimalUI = size;
+    if (!_isAnimatingResize)
+        _page->setMinimumLayoutSizeForMinimalUI(WebCore::IntSize(CGCeiling(size.width), CGCeiling(size.height)));
+}
+
 - (UIEdgeInsets)_obscuredInsets
 {
     return _obscuredInsets;
index 2179c4f..638c6ef 100644 (file)
@@ -94,6 +94,7 @@ typedef NS_OPTIONS(NSUInteger, _WKFindOptions) {
 
 #if TARGET_OS_IPHONE
 @property (nonatomic, setter=_setMinimumLayoutSizeOverride:) CGSize _minimumLayoutSizeOverride;
+@property (nonatomic, setter=_setMinimumLayoutSizeOverrideForMinimalUI:) CGSize _minimumLayoutSizeOverrideForMinimalUI;
 
 // Define the inset of the scrollview unusable by the web page.
 @property (nonatomic, setter=_setObscuredInsets:) UIEdgeInsets _obscuredInsets;
index 99eb98a..4a0bbd7 100644 (file)
@@ -579,6 +579,7 @@ public:
     void dynamicViewportSizeUpdate(const WebCore::IntSize& minimumLayoutSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, double targetScale);
     
     void setViewportConfigurationMinimumLayoutSize(const WebCore::IntSize&);
+    void setMinimumLayoutSizeForMinimalUI(const WebCore::IntSize&);
     void didCommitLayerTree(const WebKit::RemoteLayerTreeTransaction&);
 
     void selectWithGesture(const WebCore::IntPoint, WebCore::TextGranularity, uint32_t gestureType, uint32_t gestureState, PassRefPtr<GestureCallback>);
index 7692d1d..2e482c5 100644 (file)
@@ -198,6 +198,11 @@ void WebPageProxy::setViewportConfigurationMinimumLayoutSize(const WebCore::IntS
     m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size), m_pageID);
 }
 
+void WebPageProxy::setMinimumLayoutSizeForMinimalUI(const WebCore::IntSize& size)
+{
+    m_process->send(Messages::WebPage::SetMinimumLayoutSizeForMinimalUI(size), m_pageID);
+}
+
 void WebPageProxy::didCommitLayerTree(const WebKit::RemoteLayerTreeTransaction& layerTreeTransaction)
 {
     m_pageExtendedBackgroundColor = layerTreeTransaction.pageExtendedBackgroundColor();
index ba35ee2..d68d2c7 100644 (file)
@@ -695,6 +695,7 @@ public:
 
 #if PLATFORM(IOS)
     void setViewportConfigurationMinimumLayoutSize(const WebCore::IntSize&);
+    void setMinimumLayoutSizeForMinimalUI(const WebCore::IntSize&);
     void dynamicViewportSizeUpdate(const WebCore::IntSize& minimumLayoutSize, const WebCore::FloatRect& targetExposedContentRect, const WebCore::FloatRect& targetUnobscuredRect, double scale);
     void viewportConfigurationChanged();
     void updateVisibleContentRects(const VisibleContentRectUpdateInfo&);
@@ -1160,6 +1161,7 @@ private:
     WebCore::FloatSize m_screenSize;
     WebCore::FloatSize m_availableScreenSize;
     WebCore::IntSize m_blockSelectionDesiredSize;
+    WebCore::IntSize m_minimumLayoutSizeForMinimalUI;
     bool m_inDynamicSizeUpdate;
     HashMap<std::pair<WebCore::IntSize, double>, WebCore::IntPoint> m_dynamicSizeUpdateHistory;
 #endif
index f9b8209..3b0ae77 100644 (file)
@@ -44,6 +44,7 @@ messages -> WebPage LegacyReceiver {
     WheelEventSyncForTesting(WebKit::WebWheelEvent event) -> (bool handled)
 #if PLATFORM(IOS)
     SetViewportConfigurationMinimumLayoutSize(WebCore::IntSize size)
+    SetMinimumLayoutSizeForMinimalUI(WebCore::IntSize size)
     DynamicViewportSizeUpdate(WebCore::IntSize minimumLayoutSize, WebCore::FloatRect targetExposedContentRect, WebCore::FloatRect targetUnobscuredRect, double scale)
 
     HandleTap(WebCore::IntPoint point)
index afc8535..f6f8cee 100644 (file)
@@ -1764,6 +1764,12 @@ void WebPage::setViewportConfigurationMinimumLayoutSize(const IntSize& size)
     viewportConfigurationChanged();
 }
 
+void WebPage::setMinimumLayoutSizeForMinimalUI(const IntSize& size)
+{
+    m_minimumLayoutSizeForMinimalUI = size;
+    viewportConfigurationChanged();
+}
+
 void WebPage::dynamicViewportSizeUpdate(const IntSize& minimumLayoutSize, const FloatRect& targetExposedContentRect, const FloatRect& targetUnobscuredRect, double targetScale)
 {
     TemporaryChange<bool> dynamicSizeUpdateGuard(m_inDynamicSizeUpdate, true);
@@ -1924,8 +1930,12 @@ void WebPage::viewportConfigurationChanged()
         scale = initialScale;
 
     m_page->setZoomedOutPageScaleFactor(initialScale);
-
-    FrameView& frameView = *m_page->mainFrame().view();
+    
+    FrameView& frameView = *mainFrameView();
+    IntSize viewportSize = !m_minimumLayoutSizeForMinimalUI.isEmpty() ? m_minimumLayoutSizeForMinimalUI : m_viewportConfiguration.minimumLayoutSize();
+    viewportSize.scale(1 / initialScale);
+    frameView.setViewportSize(viewportSize);
+    
     IntPoint scrollPosition = frameView.scrollPosition();
     if (!m_hasReceivedVisibleContentRectsAfterDidCommitLoad) {
         IntSize minimumLayoutSizeInDocumentCoordinate = m_viewportConfiguration.minimumLayoutSize();