[OS X] Main frame scrollbars should appear on the left on RTL systems
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Mar 2016 22:05:30 +0000 (22:05 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 10 Mar 2016 22:05:30 +0000 (22:05 +0000)
https://bugs.webkit.org/show_bug.cgi?id=155149

Reviewed by Simon Fraser.

Source/WebCore:

A helper function, ScrollableArea::systemLanguageIsRTL() is used to determine
if we should be in this new mode. Once we have determined we should be in
this new mode, there are some scattered places where the geometry math
needed to be updated.

Tests: fast/scrolling/rtl-scrollbars-simple.html
       fast/scrolling/rtl-scrollbars.html

* page/scrolling/AsyncScrollingCoordinator.cpp:
(WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):
(WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
* page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
(WebCore::ScrollingTreeFrameScrollingNodeMac::setScrollLayerPosition):
* platform/mac/ScrollableAreaMac.mm:
(WebCore::ScrollableArea::systemLanguageIsRTL):
* platform/ScrollableArea.h:
* platform/ScrollView.cpp:
(WebCore::ScrollView::updateScrollbars):
(WebCore::ScrollView::scrollCornerRect):
* platform/mac/ScrollAnimatorMac.mm:
(WebCore::ScrollAnimator::scrollbarsAreRTL):
* platform/spi/mac/NSScrollerImpSPI.h:
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::positionForClipLayer):

Tools:

Setting the volatile default needs to be done early, so it is
plumbed through the injected bundle's initialization routine.

Control of RTL scrollbars is handled by putting the string
<!-- webkit-test-runner [ rtlScrollbars=true ] -->
on the first line of a test.

* WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm:
(WTR::shouldUseRTLScrollbars):
(WTR::InjectedBundle::platformInitialize):
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::generatePageConfiguration):
(WTR::updateTestOptionsFromTestHeader):
(WTR::TestController::getInjectedBundleInitializationUserData):
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestOptions.h:
* WebKitTestRunner/mac/PlatformWebViewMac.mm:
(WTR::PlatformWebView::viewSupportsOptions):

LayoutTests:

* fast/scrolling/rtl-scrollbars-expected.html: Added.
* fast/scrolling/rtl-scrollbars-simple-expected-mismatch.html: Added.
* fast/scrolling/rtl-scrollbars-simple.html: Added.
* fast/scrolling/rtl-scrollbars.html: Added.
* platform/mac-wk1/TestExpectations:
* platform/mac/TestExpectations:
* platform/efl/TestExpectations:
* platform/gtk/TestExpectations:
* platform/ios-simulator/TestExpectations:
* platform/win/TestExpectations:

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

27 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/scrolling/rtl-scrollbars-expected.html [new file with mode: 0644]
LayoutTests/fast/scrolling/rtl-scrollbars-simple-expected-mismatch.html [new file with mode: 0644]
LayoutTests/fast/scrolling/rtl-scrollbars-simple.html [new file with mode: 0644]
LayoutTests/fast/scrolling/rtl-scrollbars.html [new file with mode: 0644]
LayoutTests/platform/efl/TestExpectations
LayoutTests/platform/gtk/TestExpectations
LayoutTests/platform/ios-simulator/TestExpectations
LayoutTests/platform/mac-wk1/TestExpectations
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/scrolling/AsyncScrollingCoordinator.cpp
Source/WebCore/page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm
Source/WebCore/platform/ScrollView.cpp
Source/WebCore/platform/ScrollableArea.cpp
Source/WebCore/platform/ScrollableArea.h
Source/WebCore/platform/mac/ScrollableAreaMac.mm [new file with mode: 0644]
Source/WebCore/platform/spi/mac/NSScrollerImpSPI.h
Source/WebCore/rendering/RenderLayerCompositor.cpp
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestController.h
Tools/WebKitTestRunner/TestOptions.h
Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm

index 9387e79..be4f78b 100644 (file)
@@ -1,3 +1,21 @@
+2016-03-10  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [OS X] Main frame scrollbars should appear on the left on RTL systems
+        https://bugs.webkit.org/show_bug.cgi?id=155149
+
+        Reviewed by Simon Fraser.
+
+        * fast/scrolling/rtl-scrollbars-expected.html: Added.
+        * fast/scrolling/rtl-scrollbars-simple-expected-mismatch.html: Added.
+        * fast/scrolling/rtl-scrollbars-simple.html: Added.
+        * fast/scrolling/rtl-scrollbars.html: Added.
+        * platform/mac-wk1/TestExpectations:
+        * platform/mac/TestExpectations:
+        * platform/efl/TestExpectations:
+        * platform/gtk/TestExpectations:
+        * platform/ios-simulator/TestExpectations:
+        * platform/win/TestExpectations:
+
 2016-03-07  Jer Noble  <jer.noble@apple.com>
 
         Add separate WK and WK2 preferences for requiring user gestures for video media, distinct from user gestures for media generally
diff --git a/LayoutTests/fast/scrolling/rtl-scrollbars-expected.html b/LayoutTests/fast/scrolling/rtl-scrollbars-expected.html
new file mode 100644 (file)
index 0000000..e95f290
--- /dev/null
@@ -0,0 +1,11 @@
+<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<html>
+<head>
+</head>
+<body style="height: 1000px; position: relative;">
+<div style="position: absolute; left: 0px; bottom: 0px;">This test makes sure that rtl scrollbars are on the left of the main frame.</div>
+<script>
+window.scrollTo(0, 1000);
+</script>
+</body>
+</html>
diff --git a/LayoutTests/fast/scrolling/rtl-scrollbars-simple-expected-mismatch.html b/LayoutTests/fast/scrolling/rtl-scrollbars-simple-expected-mismatch.html
new file mode 100644 (file)
index 0000000..c6fc882
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html>
+<html>
+<head>
+</head>
+<body style="height: 1000px;">
+This test makes sure that rtl scrollbars are on the left of the main frame.
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/fast/scrolling/rtl-scrollbars-simple.html b/LayoutTests/fast/scrolling/rtl-scrollbars-simple.html
new file mode 100644 (file)
index 0000000..78bd050
--- /dev/null
@@ -0,0 +1,8 @@
+<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<html>
+<head>
+</head>
+<body style="height: 1000px;">
+This test makes sure that rtl scrollbars are on the left of the main frame.
+</body>
+</html>
\ No newline at end of file
diff --git a/LayoutTests/fast/scrolling/rtl-scrollbars.html b/LayoutTests/fast/scrolling/rtl-scrollbars.html
new file mode 100644 (file)
index 0000000..06e7d25
--- /dev/null
@@ -0,0 +1,16 @@
+<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<html>
+<head>
+</head>
+<body style="height: 1000px; position: relative;">
+<div style="position: absolute; left: 0px; bottom: 0px;">This test makes sure that rtl scrollbars are on the left of the main frame.</div>
+<script>
+if (window.eventSender) {
+    eventSender.mouseMoveTo(4, 20);
+    eventSender.mouseDown();
+    eventSender.mouseMoveTo(4, window.innerHeight - 20);
+    eventSender.mouseUp();
+}
+</script>
+</body>
+</html>
\ No newline at end of file
index 961c348..c2bfd61 100644 (file)
@@ -2957,3 +2957,7 @@ webkit.org/b/152602 loader/navigation-policy/should-open-external-urls/user-gest
 webkit.org/b/152602 loader/navigation-policy/should-open-external-urls/user-gesture-window-open-without-flag.html [ Crash ]
 
 webkit.org/b/153772 fast/shadow-dom/slot-removal-crash-2.html [ Timeout ]
+
+# RTL Scrollbars are only implemented on OS X
+fast/scrolling/rtl-scrollbars.html [ ImageOnlyFailure ]
+fast/scrolling/rtl-scrollbars-simple.html [ ImageOnlyFailure ]
index 4bd3e2e..6a66e8f 100644 (file)
@@ -2703,3 +2703,7 @@ fast/multicol/multicol-with-child-renderLayer-for-input.html [ Pass ]
 
 # This test relies on iOS-specific font fallback.
 fast/text/arabic-blacklisted-expected.html [ Pass ImageOnlyFailure ]
+
+# RTL Scrollbars are only implemented on OS X
+fast/scrolling/rtl-scrollbars.html [ ImageOnlyFailure ]
+fast/scrolling/rtl-scrollbars-simple.html [ ImageOnlyFailure ]
index 802d343..2730aa7 100644 (file)
@@ -2989,3 +2989,7 @@ svg/text/tspan-multiple-outline.svg [ ImageOnlyFailure ]
 webkit.org/b/155174 svg/animations/animate-marker-orient-from-angle-to-autostartreverse.html [ Skip ]
 
 webkit.org/b/155271 [ Debug ] js/regress/getter-richards-try-catch.html [ Skip ]
+
+# RTL Scrollbars are only implemented on OS X.
+fast/scrolling/rtl-scrollbars.html [ ImageOnlyFailure ]
+fast/scrolling/rtl-scrollbars-simple.html [ ImageOnlyFailure ]
index e5fdea1..f1d1f81 100644 (file)
@@ -195,3 +195,7 @@ inspector/heap/getRemoteObject.html [ Skip ]
 
 # This test checks ScrollAnimator events only for main frame scrollbars that use native widgets in WK1.
 fast/scrolling/scroll-animator-overlay-scrollbars-hovered.html [ Skip ]
+
+# RTL Scrollbars are only implemented in WK2
+fast/scrolling/rtl-scrollbars.html [ ImageOnlyFailure ]
+fast/scrolling/rtl-scrollbars-simple.html [ ImageOnlyFailure ]
index fd15116..aa01589 100644 (file)
@@ -1335,3 +1335,7 @@ webkit.org/b/154709 [ ElCapitan+ ] fast/text/crash-complex-text-surrogate.html [
 webkit.org/b/155092 js/arraybuffer-wrappers.html [ Pass Timeout ]
 
 webkit.org/b/155140 js/promises-tests/promises-tests-2-3-3.html [ Pass Failure ]
+
+# RTL Scrollbars are only implemented on certain OSes.
+[ Yosemite ElCapitan ] fast/scrolling/rtl-scrollbars.html [ ImageOnlyFailure ]
+[ Yosemite ElCapitan ] fast/scrolling/rtl-scrollbars-simple.html [ ImageOnlyFailure ]
index a91750f..b046aee 100644 (file)
@@ -3360,3 +3360,7 @@ webkit.org/b/137093 svg/custom/glyph-selection-lang-attribute.svg [ Failure ]
 
 # This test relies on iOS-specific font fallback.
 fast/text/arabic-blacklisted-expected.html [ Pass ImageOnlyFailure ]
+
+# RTL Scrollbars are only implemented on OS X
+fast/scrolling/rtl-scrollbars.html [ ImageOnlyFailure ]
+fast/scrolling/rtl-scrollbars-simple.html [ ImageOnlyFailure ]
index f9a9c92..5e54540 100644 (file)
@@ -1,3 +1,35 @@
+2016-03-10  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [OS X] Main frame scrollbars should appear on the left on RTL systems
+        https://bugs.webkit.org/show_bug.cgi?id=155149
+
+        Reviewed by Simon Fraser.
+
+        A helper function, ScrollableArea::systemLanguageIsRTL() is used to determine
+        if we should be in this new mode. Once we have determined we should be in
+        this new mode, there are some scattered places where the geometry math
+        needed to be updated.
+
+        Tests: fast/scrolling/rtl-scrollbars-simple.html
+               fast/scrolling/rtl-scrollbars.html
+
+        * page/scrolling/AsyncScrollingCoordinator.cpp:
+        (WebCore::AsyncScrollingCoordinator::requestScrollPositionUpdate):
+        (WebCore::AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll):
+        * page/scrolling/mac/ScrollingTreeFrameScrollingNodeMac.mm:
+        (WebCore::ScrollingTreeFrameScrollingNodeMac::setScrollLayerPosition):
+        * platform/mac/ScrollableAreaMac.mm:
+        (WebCore::ScrollableArea::systemLanguageIsRTL):
+        * platform/ScrollableArea.h:
+        * platform/ScrollView.cpp:
+        (WebCore::ScrollView::updateScrollbars):
+        (WebCore::ScrollView::scrollCornerRect):
+        * platform/mac/ScrollAnimatorMac.mm:
+        (WebCore::ScrollAnimator::scrollbarsAreRTL):
+        * platform/spi/mac/NSScrollerImpSPI.h:
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::positionForClipLayer):
+
 2016-03-07  Jer Noble  <jer.noble@apple.com>
 
         Add separate WK and WK2 preferences for requiring user gestures for video media, distinct from user gestures for media generally
index 85e9590..0307ba3 100644 (file)
                1C81B95A0E97330800266E07 /* InspectorController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C81B9560E97330800266E07 /* InspectorController.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1C81B95B0E97330800266E07 /* InspectorController.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 1C81B9570E97330800266E07 /* InspectorController.cpp */; };
                1C81B95C0E97330800266E07 /* InspectorClient.h in Headers */ = {isa = PBXBuildFile; fileRef = 1C81B9580E97330800266E07 /* InspectorClient.h */; settings = {ATTRIBUTES = (Private, ); }; };
+               1C99542E1C92105200DBD226 /* ScrollableAreaMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1C99542D1C92105200DBD226 /* ScrollableAreaMac.mm */; };
                1CA19E050DC255950065A994 /* EventLoopMac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 1CA19E030DC255950065A994 /* EventLoopMac.mm */; };
                1CA19E160DC255CA0065A994 /* EventLoop.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CA19E150DC255CA0065A994 /* EventLoop.h */; };
                1CAF34810A6C405200ABE06E /* WebScriptObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 1CAF347E0A6C405200ABE06E /* WebScriptObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
                1C81B9570E97330800266E07 /* InspectorController.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InspectorController.cpp; sourceTree = "<group>"; };
                1C81B9580E97330800266E07 /* InspectorClient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InspectorClient.h; sourceTree = "<group>"; };
                1C904DF90BA9D2C80081E9D0 /* Version.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Version.xcconfig; sourceTree = "<group>"; };
+               1C99542D1C92105200DBD226 /* ScrollableAreaMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ScrollableAreaMac.mm; sourceTree = "<group>"; };
                1CA19E030DC255950065A994 /* EventLoopMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = EventLoopMac.mm; sourceTree = "<group>"; };
                1CA19E150DC255CA0065A994 /* EventLoop.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EventLoop.h; sourceTree = "<group>"; };
                1CAF347E0A6C405200ABE06E /* WebScriptObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebScriptObject.h; sourceTree = "<group>"; };
                                41F54F7D1C50C4F600338488 /* FetchBody.cpp */,
                                41F54F7E1C50C4F600338488 /* FetchBody.h */,
                                41F54F7F1C50C4F600338488 /* FetchBody.idl */,
-                               4147E2B21C88337F00A7E715 /* FetchBodyOwner.h */,
+                               4147E2B21C88337F00A7E715 /* FetchBodyOwner.h */,
                                41F54F821C50C4F600338488 /* FetchHeaders.cpp */,
                                41F54F831C50C4F600338488 /* FetchHeaders.h */,
                                41F54F841C50C4F600338488 /* FetchHeaders.idl */,
                                CD82030E1395ACE700F956C6 /* WebWindowAnimation.h */,
                                CD82030F1395ACE700F956C6 /* WebWindowAnimation.mm */,
                                9380F47709A11ACC001FDB34 /* WidgetMac.mm */,
+                               1C99542D1C92105200DBD226 /* ScrollableAreaMac.mm */,
                        );
                        path = mac;
                        sourceTree = "<group>";
                                F55B3DCB1251F12D003EF269 /* RadioInputType.cpp in Sources */,
                                B658FFA51522EFAA00DD5595 /* RadioNodeList.cpp in Sources */,
                                93F19AB908245E59001E9ABC /* Range.cpp in Sources */,
+                               1C99542E1C92105200DBD226 /* ScrollableAreaMac.mm in Sources */,
                                F55B3DCD1251F12D003EF269 /* RangeInputType.cpp in Sources */,
                                6E84E9E017668BEE00815B68 /* RasterShape.cpp in Sources */,
                                FD31603B12B0267600C1A359 /* RealtimeAnalyser.cpp in Sources */,
index 0291a4f..b25a471 100644 (file)
@@ -322,7 +322,7 @@ void AsyncScrollingCoordinator::updateScrollPositionAfterAsyncScroll(ScrollingNo
             LayoutPoint scrollPositionForFixed = frameView.scrollPositionForFixedPosition();
 
             float topContentInset = frameView.topContentInset();
-            FloatPoint positionForInsetClipLayer = FloatPoint(0, FrameView::yPositionForInsetClipLayer(scrollPosition, topContentInset));
+            FloatPoint positionForInsetClipLayer = FloatPoint(insetClipLayer ? insetClipLayer->position().x() : 0, FrameView::yPositionForInsetClipLayer(scrollPosition, topContentInset));
             FloatPoint positionForContentsLayer = frameView.positionForRootContentLayer();
             FloatPoint positionForHeaderLayer = FloatPoint(scrollPositionForFixed.x(), FrameView::yPositionForHeaderLayer(scrollPosition, topContentInset));
             FloatPoint positionForFooterLayer = FloatPoint(scrollPositionForFixed.x(),
index 13a57e8..9feee03 100644 (file)
@@ -419,7 +419,7 @@ void ScrollingTreeFrameScrollingNodeMac::setScrollLayerPosition(const FloatPoint
 
     float topContentInset = this->topContentInset();
     if (m_insetClipLayer && m_scrolledContentsLayer && topContentInset) {
-        m_insetClipLayer.get().position = FloatPoint(0, FrameView::yPositionForInsetClipLayer(position, topContentInset));
+        m_insetClipLayer.get().position = FloatPoint(m_insetClipLayer.get().position.x, FrameView::yPositionForInsetClipLayer(position, topContentInset));
         m_scrolledContentsLayer.get().position = FrameView::positionForRootContentLayer(position, scrollOrigin(), topContentInset, headerHeight());
         if (m_contentShadowLayer)
             m_contentShadowLayer.get().position = m_scrolledContentsLayer.get().position;
index 93118c2..22251b5 100644 (file)
@@ -709,7 +709,7 @@ void ScrollView::updateScrollbars(const ScrollPosition& desiredPosition)
         int clientWidth = visibleWidth();
         int pageStep = Scrollbar::pageStep(clientWidth);
         IntRect oldRect(m_horizontalScrollbar->frameRect());
-        IntRect hBarRect(0,
+        IntRect hBarRect(ScrollableArea::systemLanguageIsRTL() && m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0,
             height() - m_horizontalScrollbar->height(),
             width() - (m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0),
             m_horizontalScrollbar->height());
@@ -730,7 +730,7 @@ void ScrollView::updateScrollbars(const ScrollPosition& desiredPosition)
         int clientHeight = visibleHeight();
         int pageStep = Scrollbar::pageStep(clientHeight);
         IntRect oldRect(m_verticalScrollbar->frameRect());
-        IntRect vBarRect(width() - m_verticalScrollbar->width(), 
+        IntRect vBarRect(ScrollableArea::systemLanguageIsRTL() ? 0 : width() - m_verticalScrollbar->width(),
             topContentInset(),
             m_verticalScrollbar->width(),
             height() - topContentInset() - (m_horizontalScrollbar ? m_horizontalScrollbar->occupiedHeight() : 0));
@@ -1124,14 +1124,14 @@ IntRect ScrollView::scrollCornerRect() const
     int heightTrackedByScrollbar = height() - topContentInset();
 
     if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
-        cornerRect.unite(IntRect(m_horizontalScrollbar->width(),
+        cornerRect.unite(IntRect(ScrollableArea::systemLanguageIsRTL() ? 0 : m_horizontalScrollbar->width(),
             height() - m_horizontalScrollbar->height(),
             width() - m_horizontalScrollbar->width(),
             m_horizontalScrollbar->height()));
     }
 
     if (m_verticalScrollbar && heightTrackedByScrollbar - m_verticalScrollbar->height() > 0) {
-        cornerRect.unite(IntRect(width() - m_verticalScrollbar->width(),
+        cornerRect.unite(IntRect(ScrollableArea::systemLanguageIsRTL() ? 0 : width() - m_verticalScrollbar->width(),
             m_verticalScrollbar->height() + topContentInset(),
             m_verticalScrollbar->width(),
             heightTrackedByScrollbar - m_verticalScrollbar->height()));
index 8dfc940..4e08f64 100644 (file)
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 2010, Google Inc. All rights reserved.
- * Copyright (C) 2008, 2011, 2014-2015 Apple Inc. All Rights Reserved.
+ * Copyright (C) 2008, 2011, 2014-2016 Apple Inc. All Rights Reserved.
  * 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -527,12 +527,19 @@ bool ScrollableArea::isPinnedVerticallyInDirection(int verticalScrollDelta) cons
 }
 #endif // PLATFORM(IOS)
 
+int ScrollableArea::horizontalScrollbarIntrusion() const
+{
+    return verticalScrollbar() ? verticalScrollbar()->occupiedWidth() : 0;
+}
+
+int ScrollableArea::verticalScrollbarIntrusion() const
+{
+    return horizontalScrollbar() ? horizontalScrollbar()->occupiedHeight() : 0;
+}
+
 IntSize ScrollableArea::scrollbarIntrusion() const
 {
-    return {
-        verticalScrollbar() ? verticalScrollbar()->occupiedWidth() : 0,
-        horizontalScrollbar() ? horizontalScrollbar()->occupiedHeight() : 0
-    };
+    return { horizontalScrollbarIntrusion(), verticalScrollbarIntrusion() };
 }
 
 ScrollPosition ScrollableArea::scrollPosition() const
@@ -682,4 +689,11 @@ void ScrollableArea::computeScrollbarValueAndOverhang(float currentPosition, flo
     }
 }
 
+#if !PLATFORM(COCOA)
+bool ScrollableArea::systemLanguageIsRTL()
+{
+    return false;
+}
+#endif
+
 } // namespace WebCore
index 2bf13a1..f35cb8d 100644 (file)
@@ -175,7 +175,9 @@ public:
     {
         return scrollbar->Widget::convertFromContainingView(parentPoint);
     }
-    
+
+    int horizontalScrollbarIntrusion() const;
+    int verticalScrollbarIntrusion() const;
     WEBCORE_EXPORT IntSize scrollbarIntrusion() const;
 
     virtual Scrollbar* horizontalScrollbar() const { return 0; }
@@ -310,6 +312,8 @@ public:
     virtual bool usesMockScrollAnimator() const { return false; }
     virtual void logMockScrollAnimatorMessage(const String&) const { };
 
+    static bool systemLanguageIsRTL();
+
 protected:
     WEBCORE_EXPORT ScrollableArea();
     WEBCORE_EXPORT virtual ~ScrollableArea();
diff --git a/Source/WebCore/platform/mac/ScrollableAreaMac.mm b/Source/WebCore/platform/mac/ScrollableAreaMac.mm
new file mode 100644 (file)
index 0000000..0e7ae8d
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Apple Inc. All Rights Reserved.
+ * 
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ * 
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ * 
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "ScrollableArea.h"
+
+#if PLATFORM(MAC)
+#include "NSScrollerImpSPI.h"
+#endif
+
+namespace WebCore {
+
+bool ScrollableArea::systemLanguageIsRTL()
+{
+#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
+    static bool result = [NSScrollerImpPair scrollerLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft;
+    return result;
+#else
+    return false;
+#endif
+}
+
+}
index b8e1178..03b3278 100644 (file)
@@ -110,6 +110,7 @@ typedef NSUInteger NSOverlayScrollerState;
 @property(retain) NSScrollerImp *verticalScrollerImp;
 @property(retain) NSScrollerImp *horizontalScrollerImp;
 @property NSScrollerStyle scrollerStyle;
++ (NSUserInterfaceLayoutDirection)scrollerLayoutDirection;
 - (void)flashScrollers;
 - (void)hideOverlayScrollers;
 - (void)lockOverlayScrollerState:(NSOverlayScrollerState)state;
index d6a772a..dad6d9e 100644 (file)
@@ -1759,7 +1759,9 @@ void RenderLayerCompositor::updateScrollLayerPosition()
 
 FloatPoint RenderLayerCompositor::positionForClipLayer() const
 {
-    return FloatPoint(0, FrameView::yPositionForInsetClipLayer(m_renderView.frameView().scrollPosition(), m_renderView.frameView().topContentInset()));
+    return FloatPoint(
+        ScrollableArea::systemLanguageIsRTL() ? m_renderView.frameView().horizontalScrollbarIntrusion() : 0,
+        FrameView::yPositionForInsetClipLayer(m_renderView.frameView().scrollPosition(), m_renderView.frameView().topContentInset()));
 }
 
 void RenderLayerCompositor::frameViewDidScroll()
index 4d7b743..2233420 100644 (file)
@@ -1,3 +1,29 @@
+2016-03-10  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [OS X] Main frame scrollbars should appear on the left on RTL systems
+        https://bugs.webkit.org/show_bug.cgi?id=155149
+
+        Reviewed by Simon Fraser.
+
+        Setting the volatile default needs to be done early, so it is
+        plumbed through the injected bundle's initialization routine.
+
+        Control of RTL scrollbars is handled by putting the string
+        <!-- webkit-test-runner [ rtlScrollbars=true ] -->
+        on the first line of a test.
+
+        * WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm:
+        (WTR::shouldUseRTLScrollbars):
+        (WTR::InjectedBundle::platformInitialize):
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::generatePageConfiguration):
+        (WTR::updateTestOptionsFromTestHeader):
+        (WTR::TestController::getInjectedBundleInitializationUserData):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestOptions.h:
+        * WebKitTestRunner/mac/PlatformWebViewMac.mm:
+        (WTR::PlatformWebView::viewSupportsOptions):
+
 2016-03-08  Jer Noble  <jer.noble@apple.com>
 
         Add separate WK and WK2 preferences for requiring user gestures for video media, distinct from user gestures for media generally
index 568acfe..b5692e8 100644 (file)
 
 namespace WTR {
 
-void InjectedBundle::platformInitialize(WKTypeRef)
+static bool shouldUseRTLScrollbars(WKTypeRef initializationUserData)
+{
+    if (!initializationUserData || WKGetTypeID(initializationUserData) != WKDictionaryGetTypeID())
+        return false;
+
+    WKTypeRef item = WKDictionaryGetItemForKey(static_cast<WKDictionaryRef>(initializationUserData), adoptWK(WKStringCreateWithUTF8CString("UseRTLScrollbars")).get());
+    if (!item || WKGetTypeID(item) != WKBooleanGetTypeID())
+        return false;
+
+    return WKBooleanGetValue(static_cast<WKBooleanRef>(item));
+}
+
+void InjectedBundle::platformInitialize(WKTypeRef initializationUserData)
 {
     static const int NoFontSmoothing = 0;
     static const int BlueTintedAppearance = 1;
@@ -82,6 +94,13 @@ void InjectedBundle::platformInitialize(WKTypeRef)
         @"com.apple.swipescrolldirection": @1,
     };
 
+    if (shouldUseRTLScrollbars(initializationUserData)) {
+        NSMutableDictionary *newDictionary = [dict mutableCopy];
+        [newDictionary setValue:@YES forKey:@"AppleTextDirection"];
+        [newDictionary setValue:@YES forKey:@"NSForceRightToLeftWritingDirection"];
+        dict = [newDictionary autorelease];
+    }
+
     [[NSUserDefaults standardUserDefaults] setVolatileDomain:dict forName:NSArgumentDomain];
 
     // Make NSFont use the new defaults.
index 3761d0c..dd75412 100644 (file)
@@ -435,7 +435,7 @@ WKRetainPtr<WKPageConfigurationRef> TestController::generatePageConfiguration(WK
         { 1, this },
         didReceiveMessageFromInjectedBundle,
         didReceiveSynchronousMessageFromInjectedBundle,
-        0 // getInjectedBundleInitializationUserData
+        getInjectedBundleInitializationUserData,
     };
     WKContextSetInjectedBundleClient(m_context.get(), &injectedBundleClient.base);
 
@@ -937,6 +937,8 @@ static void updateTestOptionsFromTestHeader(TestOptions& testOptions, const std:
             testOptions.useFlexibleViewport = parseBooleanTestHeaderValue(value);
         if (key == "useDataDetection")
             testOptions.useDataDetection = parseBooleanTestHeaderValue(value);
+        if (key == "rtlScrollbars")
+            testOptions.useRTLScrollbars = parseBooleanTestHeaderValue(value);
         pairStart = pairEnd + 1;
     }
 }
@@ -1137,6 +1139,11 @@ void TestController::didReceiveSynchronousMessageFromInjectedBundle(WKContextRef
     *returnData = static_cast<TestController*>(const_cast<void*>(clientInfo))->didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody).leakRef();
 }
 
+WKTypeRef TestController::getInjectedBundleInitializationUserData(WKContextRef, const void* clientInfo)
+{
+    return static_cast<TestController*>(const_cast<void*>(clientInfo))->getInjectedBundleInitializationUserData().leakRef();
+}
+
 // WKPageInjectedBundleClient
 
 void TestController::didReceivePageMessageFromInjectedBundle(WKPageRef page, WKStringRef messageName, WKTypeRef messageBody, const void* clientInfo)
@@ -1453,6 +1460,18 @@ WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedB
     return m_currentInvocation->didReceiveSynchronousMessageFromInjectedBundle(messageName, messageBody);
 }
 
+WKRetainPtr<WKTypeRef> TestController::getInjectedBundleInitializationUserData()
+{
+    if (m_currentInvocation->options().useRTLScrollbars) {
+        WKRetainPtr<WKStringRef> key = adoptWK(WKStringCreateWithUTF8CString("UseRTLScrollbars"));
+        WKRetainPtr<WKBooleanRef> value = adoptWK(WKBooleanCreate(true));
+        const WKStringRef keyArray[] = { key.get() };
+        const WKTypeRef valueArray[] = { value.get() };
+        return adoptWK(WKDictionaryCreate(keyArray, valueArray, WTF_ARRAY_LENGTH(keyArray)));
+    }
+    return nullptr;
+}
+
 // WKContextClient
 
 void TestController::networkProcessDidCrash()
index d51caf7..303fda1 100644 (file)
@@ -179,12 +179,14 @@ private:
     // WKContextInjectedBundleClient
     static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, const void*);
     static void didReceiveSynchronousMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void*);
+    static WKTypeRef getInjectedBundleInitializationUserData(WKContextRef, const void *clientInfo);
 
     // WKPageInjectedBundleClient
     static void didReceivePageMessageFromInjectedBundle(WKPageRef, WKStringRef messageName, WKTypeRef messageBody, const void*);
     static void didReceiveSynchronousPageMessageFromInjectedBundle(WKPageRef, WKStringRef messageName, WKTypeRef messageBody, WKTypeRef* returnData, const void*);
     void didReceiveMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);
     WKRetainPtr<WKTypeRef> didReceiveSynchronousMessageFromInjectedBundle(WKStringRef messageName, WKTypeRef messageBody);
+    WKRetainPtr<WKTypeRef> getInjectedBundleInitializationUserData();
 
     void didReceiveKeyDownMessageFromInjectedBundle(WKDictionaryRef messageBodyDictionary, bool synchronous);
 
index c26742f..7e45acf 100644 (file)
@@ -40,6 +40,7 @@ struct TestOptions {
     bool isSVGTest { false };
     bool isHiDPITest { false };
     bool useDataDetection { false };
+    bool useRTLScrollbars { false };
 
     Vector<String> overrideLanguages;
     
index 37da023..b35b7d4 100644 (file)
@@ -233,7 +233,7 @@ WKRetainPtr<WKImageRef> PlatformWebView::windowSnapshotImage()
 
 bool PlatformWebView::viewSupportsOptions(const TestOptions& options) const
 {
-    if (m_options.useThreadedScrolling != options.useThreadedScrolling || m_options.overrideLanguages != options.overrideLanguages)
+    if (m_options.useThreadedScrolling != options.useThreadedScrolling || m_options.overrideLanguages != options.overrideLanguages || m_options.useRTLScrollbars != options.useRTLScrollbars)
         return false;
 
     return true;