[WK2] [OS X] Create API for switching RTL scrollbar policy
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Apr 2016 01:25:26 +0000 (01:25 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 27 Apr 2016 01:25:26 +0000 (01:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=156948
<rdar://problem/25707757>

Reviewed by Darin Adler.

Source/WebCore:

There are two schools of thought for where to put scrollbars in RTL environments.
The first is that we should obey the content's "dir" attribute, specified on each
element. The second is that we should be consistent with the platform (AppKit's)
behavior.

There are some situations where the placement should be done according to the
content. For example, this policy would be used in web browsers.

However, there are also places where web content is designed to fit seamlessly
amongst native content. In this situation, the placement of the scrollbars should
be done according to the view.

Because WebKit doesn't know which of these situations it is operating within, this
patch adds a new API property, userInterfaceDirectionPolicy, to
WKWebViewConfigurationPolicy. This allows clients to instruct us which policy to
abide by. It is plumbed to the web process inside the WebPreferencesStore and is
ultimately held inside the Page's Settings object.

This Setting is consulted by RenderLayerModelObject, which serves as a good
centralized place for this policy implementation. This is the class which decides
if we should be consulting its RenderStyle or the platform itself when we decide
where to put the scrollbars.

Putting this decision inside the renderer is important because ScrollableArea
often needs to know if scrollbars should be put on the left, but ScrollableArea
doesn't know anything about RenderStyles. Therefore, the renderer must be the
intermediary between ScrollableArea and the RenderStyle. (ScrollableArea also
doesn't directly know anything about renderers either; however, each of the
subclasses knows about an appropriate renderer.) Therefore, ScrollableArea gets
a new virtual method which is implemented by the RenderLayerModelObject.

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

* WebCore.xcodeproj/project.pbxproj: ScrollableAreaMac.mm is no longer necessary.
* page/FrameView.cpp:
(WebCore::FrameView::shouldPlaceBlockDirectionScrollbarOnLeft): Overridden
ScrollableArea function.
* page/FrameView.h:
* page/Settings.h:
* page/Settings.in:
* platform/ScrollView.cpp: Adding two new settings: One to know if we should
consult with the RenderStyle or the platform, and the other is whether or not
the platform considers itself to be RTL.
(WebCore::ScrollView::documentScrollPositionRelativeToViewOrigin): Update to
use new mechanism.
(WebCore::ScrollView::updateScrollbars): Ditto.
(WebCore::ScrollView::scrollCornerRect): Ditto.
(WebCore::ScrollView::locationOfContents): Ditto.
* platform/ScrollableArea.cpp:
(WebCore::ScrollableArea::verticalScrollbarIsOnLeft): Deleted. This was the old
mechanism.
(WebCore::ScrollableArea::systemLanguageIsRTL): Deleted. Ditto.
* platform/ScrollableArea.h:
* platform/mac/ScrollableAreaMac.mm: Removed.
(WebCore::ScrollableArea::verticalScrollbarIsOnLeft): Deleted.
(WebCore::ScrollableArea::systemLanguageIsRTL): Deleted.
* platform/mac/ScrollbarThemeMac.mm:
(WebCore::ScrollbarThemeMac::didCreateScrollerImp): Update to use new
mechanism.
* platform/text/WritingMode.h: These enums should match what's in WebKit2.
* rendering/RenderBlock.cpp:
(WebCore::RenderBlock::logicalLeftOffsetForContent): Update to use new mechanism.
(WebCore::RenderBlock::logicalRightOffsetForContent): Ditto.
* rendering/RenderBlockFlow.cpp:
(WebCore::RenderBlockFlow::determineLogicalLeftPositionForChild): Ditto.
* rendering/RenderBox.cpp: Ditto.
(WebCore::RenderBox::contentBoxRect):
(WebCore::RenderBox::overflowClipRect):
(WebCore::RenderBox::computePositionedLogicalWidth):
(WebCore::RenderBox::layoutOverflowRectForPropagation):
* rendering/RenderBoxModelObject.cpp: Ditto.
(WebCore::RenderBoxModelObject::constrainingRectForStickyPosition):
* rendering/RenderLayer.cpp:
(WebCore::RenderLayer::resize): Ditto.
(WebCore::cornerStart): Migrate to use references.
(WebCore::cornerRect): Ditto.
(WebCore::RenderLayer::scrollCornerRect): Ditto.
(WebCore::resizerCornerRect): Ditto.
(WebCore::RenderLayer::scrollCornerAndResizerRect): Ditto.
(WebCore::RenderLayer::verticalScrollbarStart): Update to use new mechanism.
(WebCore::RenderLayer::horizontalScrollbarStart): Ditto.
(WebCore::RenderLayer::offsetFromResizeCorner): Ditto.
(WebCore::RenderLayer::positionOverflowControls): Migrate to use references.
(WebCore::RenderLayer::computeScrollDimensions): Ditto.
(WebCore::RenderLayer::overflowControlsIntersectRect): Ditto.
(WebCore::RenderLayer::drawPlatformResizerImage): Update to use new mechanism.
(WebCore::RenderLayer::paintResizer): Migrate to use references.
(WebCore::RenderLayer::isPointInResizeControl): Ditto.
(WebCore::RenderLayer::hitTestOverflowControls): Ditto.
(WebCore::RenderLayer::hitTestResizerInFragments): Ditto.
* rendering/RenderLayer.h: ScrollableArea override
* rendering/RenderLayerCompositor.cpp:
(WebCore::RenderLayerCompositor::positionForClipLayer): Update to use new
mechanism.
* rendering/RenderLayerModelObject.cpp:
(WebCore::RenderLayerModelObject::shouldPlaceBlockDirectionScrollbarOnLeft):
This is the meat of this patch. This is where we decide if we should be
interrogating the RenderStyle or the underlying platform.
* rendering/RenderLayerModelObject.h:
* rendering/RenderListBox.cpp: Update to use new mechanism.
(WebCore::RenderListBox::itemBoundingBoxRect):
(WebCore::RenderListBox::paintScrollbar):
(WebCore::RenderListBox::isPointInOverflowControl):
(WebCore::RenderListBox::listIndexAtOffset):
(WebCore::RenderListBox::controlClipRect):
(WebCore::RenderListBox::invalidateScrollbarRect):
(WebCore::RenderListBox::convertFromScrollbarToContainingView):
(WebCore::RenderListBox::convertFromContainingViewToScrollbar):
* rendering/RenderListBox.h:
* rendering/RenderView.cpp: Ditto.
(WebCore::RenderView::repaintViewRectangle):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::shouldPlaceBlockDirectionScrollbarOnLeft): This
function is now much dumber. It just inspects its own style.
* testing/InternalSettings.cpp: Allow mocking.
(WebCore::InternalSettings::Backup::Backup):
(WebCore::InternalSettings::Backup::restoreTo):
(WebCore::InternalSettings::verticalScrollbarLocationPolicy):
(WebCore::InternalSettings::setVerticalScrollbarLocationPolicy):
(WebCore::InternalSettings::systemLayoutDirection):
(WebCore::InternalSettings::setSystemLayoutDirection):
* testing/InternalSettings.h:
* testing/InternalSettings.idl:

Source/WebKit2:

Add the new API.

* Shared/WebPreferencesDefinitions.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _initializeWithConfiguration:]):
* UIProcess/API/Cocoa/WKWebViewConfiguration.h:
* UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
(-[WKWebViewConfiguration init]):
(-[WKWebViewConfiguration encodeWithCoder:]):
(-[WKWebViewConfiguration initWithCoder:]):
(-[WKWebViewConfiguration copyWithZone:]):
* UIProcess/WebPageProxy.cpp:
* WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::updatePreferences):

LayoutTests:

Update tests to use new RTL scrollbar mechanism.

* fast/scrolling/rtl-scrollbars-animation-property.html:
* fast/scrolling/rtl-scrollbars-elementFromPoint-static.html:
* fast/scrolling/rtl-scrollbars-elementFromPoint.html:
* fast/scrolling/rtl-scrollbars-expected.html:
* fast/scrolling/rtl-scrollbars-iframe-offset-expected.html:
* fast/scrolling/rtl-scrollbars-iframe-offset.html:
* fast/scrolling/rtl-scrollbars-iframe-position-absolute.html:
* fast/scrolling/rtl-scrollbars-iframe-scrolled-expected.html:
* fast/scrolling/rtl-scrollbars-iframe-scrolled.html:
* fast/scrolling/rtl-scrollbars-iframe.html:
* fast/scrolling/rtl-scrollbars-listbox-expected.html:
* fast/scrolling/rtl-scrollbars-listbox-scroll-expected.html:
* fast/scrolling/rtl-scrollbars-listbox-scroll.html:
* fast/scrolling/rtl-scrollbars-listbox-select-left-expected.html:
* fast/scrolling/rtl-scrollbars-listbox-select-left.html:
* fast/scrolling/rtl-scrollbars-listbox-select-right-expected.html:
* fast/scrolling/rtl-scrollbars-listbox-select-right.html:
* fast/scrolling/rtl-scrollbars-listbox-simple-expected-mismatch.html:
* fast/scrolling/rtl-scrollbars-listbox-simple.html:
* fast/scrolling/rtl-scrollbars-listbox.html:
* fast/scrolling/rtl-scrollbars-overflow-contents-expected.html:
* fast/scrolling/rtl-scrollbars-overflow-contents.html:
* fast/scrolling/rtl-scrollbars-overflow-dir-rtl-expected.html:
* fast/scrolling/rtl-scrollbars-overflow-dir-rtl.html:
* fast/scrolling/rtl-scrollbars-overflow-elementFromPoint.html:
* fast/scrolling/rtl-scrollbars-overflow-expected.html:
* fast/scrolling/rtl-scrollbars-overflow-padding-expected.html:
* fast/scrolling/rtl-scrollbars-overflow-padding.html:
* fast/scrolling/rtl-scrollbars-overflow-position-absolute-expected.html:
* fast/scrolling/rtl-scrollbars-overflow-position-absolute.html:
* fast/scrolling/rtl-scrollbars-overflow-simple-expected-mismatch.html:
* fast/scrolling/rtl-scrollbars-overflow-simple.html:
* fast/scrolling/rtl-scrollbars-overflow-text-selection-scrolled-expected.html:
* fast/scrolling/rtl-scrollbars-overflow-text-selection-scrolled.html:
* fast/scrolling/rtl-scrollbars-overflow.html:
* fast/scrolling/rtl-scrollbars-overlay-no-push-contents-expected.html:
* fast/scrolling/rtl-scrollbars-overlay-no-push-contents.html:
* fast/scrolling/rtl-scrollbars-position-absolute-expected.html:
* fast/scrolling/rtl-scrollbars-position-absolute.html:
* fast/scrolling/rtl-scrollbars-position-fixed-expected.html:
* fast/scrolling/rtl-scrollbars-position-fixed.html:
* fast/scrolling/rtl-scrollbars-positioning-expected.html:
* fast/scrolling/rtl-scrollbars-positioning.html:
* fast/scrolling/rtl-scrollbars-simple-expected-mismatch.html:
* fast/scrolling/rtl-scrollbars-simple.html:
* fast/scrolling/rtl-scrollbars-sticky-document-2-expected.html:
* fast/scrolling/rtl-scrollbars-sticky-document-2.html:
* fast/scrolling/rtl-scrollbars-sticky-document-expected.html:
* fast/scrolling/rtl-scrollbars-sticky-document.html:
* fast/scrolling/rtl-scrollbars-sticky-iframe-2-expected.html:
* fast/scrolling/rtl-scrollbars-sticky-iframe-2.html:
* fast/scrolling/rtl-scrollbars-sticky-iframe-expected.html:
* fast/scrolling/rtl-scrollbars-sticky-iframe.html:
* fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-2-expected.html:
* fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-2.html:
* fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-expected.html:
* fast/scrolling/rtl-scrollbars-sticky-overflow-scroll.html:
* fast/scrolling/rtl-scrollbars-text-selection-expected.html:
* fast/scrolling/rtl-scrollbars-text-selection-scrolled-expected.html:
* fast/scrolling/rtl-scrollbars-text-selection-scrolled.html:
* fast/scrolling/rtl-scrollbars-text-selection.html:
* fast/scrolling/rtl-scrollbars.html:
* platform/mac/fast/scrolling/rtl-scrollbars-animation-property-expected.png: Added.

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

104 files changed:
LayoutTests/ChangeLog
LayoutTests/fast/scrolling/rtl-scrollbars-animation-property.html
LayoutTests/fast/scrolling/rtl-scrollbars-elementFromPoint-static.html
LayoutTests/fast/scrolling/rtl-scrollbars-elementFromPoint.html
LayoutTests/fast/scrolling/rtl-scrollbars-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-iframe-offset-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-iframe-offset.html
LayoutTests/fast/scrolling/rtl-scrollbars-iframe-position-absolute.html
LayoutTests/fast/scrolling/rtl-scrollbars-iframe-scrolled-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-iframe-scrolled.html
LayoutTests/fast/scrolling/rtl-scrollbars-iframe.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-scroll-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-scroll.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-select-left-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-select-left.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-select-right-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-select-right.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-simple-expected-mismatch.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox-simple.html
LayoutTests/fast/scrolling/rtl-scrollbars-listbox.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-contents-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-contents.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-dir-rtl-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-dir-rtl.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-elementFromPoint.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-padding-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-padding.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-position-absolute-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-position-absolute.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-simple-expected-mismatch.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-simple.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-text-selection-scrolled-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow-text-selection-scrolled.html
LayoutTests/fast/scrolling/rtl-scrollbars-overflow.html
LayoutTests/fast/scrolling/rtl-scrollbars-overlay-no-push-contents-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-overlay-no-push-contents.html
LayoutTests/fast/scrolling/rtl-scrollbars-position-absolute-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-position-absolute.html
LayoutTests/fast/scrolling/rtl-scrollbars-position-fixed-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-position-fixed.html
LayoutTests/fast/scrolling/rtl-scrollbars-positioning-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-positioning.html
LayoutTests/fast/scrolling/rtl-scrollbars-simple-expected-mismatch.html
LayoutTests/fast/scrolling/rtl-scrollbars-simple.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-document-2-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-document-2.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-document-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-document.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-iframe-2-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-iframe-2.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-iframe-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-iframe.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-2-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-2.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-sticky-overflow-scroll.html
LayoutTests/fast/scrolling/rtl-scrollbars-text-selection-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-text-selection-scrolled-expected.html
LayoutTests/fast/scrolling/rtl-scrollbars-text-selection-scrolled.html
LayoutTests/fast/scrolling/rtl-scrollbars-text-selection.html
LayoutTests/fast/scrolling/rtl-scrollbars.html
LayoutTests/platform/mac/fast/scrolling/rtl-scrollbars-animation-property-expected.png [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/WebCore.xcodeproj/project.pbxproj
Source/WebCore/page/FrameView.cpp
Source/WebCore/page/FrameView.h
Source/WebCore/page/Settings.h
Source/WebCore/page/Settings.in
Source/WebCore/platform/ScrollView.cpp
Source/WebCore/platform/ScrollableArea.cpp
Source/WebCore/platform/ScrollableArea.h
Source/WebCore/platform/mac/ScrollableAreaMac.mm [deleted file]
Source/WebCore/platform/mac/ScrollbarThemeMac.mm
Source/WebCore/platform/win/PopupMenuWin.h
Source/WebCore/rendering/RenderBlock.cpp
Source/WebCore/rendering/RenderBlockFlow.cpp
Source/WebCore/rendering/RenderBox.cpp
Source/WebCore/rendering/RenderBoxModelObject.cpp
Source/WebCore/rendering/RenderLayer.cpp
Source/WebCore/rendering/RenderLayer.h
Source/WebCore/rendering/RenderLayerCompositor.cpp
Source/WebCore/rendering/RenderLayerModelObject.cpp
Source/WebCore/rendering/RenderLayerModelObject.h
Source/WebCore/rendering/RenderListBox.cpp
Source/WebCore/rendering/RenderListBox.h
Source/WebCore/rendering/RenderView.cpp
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/testing/InternalSettings.cpp
Source/WebCore/testing/InternalSettings.h
Source/WebCore/testing/InternalSettings.idl
Source/WebKit2/ChangeLog
Source/WebKit2/Shared/WebPreferencesDefinitions.h
Source/WebKit2/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfiguration.h
Source/WebKit2/UIProcess/API/Cocoa/WKWebViewConfiguration.mm
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h
Source/WebKit2/WebProcess/WebPage/WebPage.cpp
Tools/WebKitTestRunner/InjectedBundle/mac/InjectedBundleMac.mm
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestOptions.h
Tools/WebKitTestRunner/mac/PlatformWebViewMac.mm

index 4f4fd0a..9e32f89 100644 (file)
@@ -1,3 +1,77 @@
+2016-04-26  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [WK2] [OS X] Create API for switching RTL scrollbar policy
+        https://bugs.webkit.org/show_bug.cgi?id=156948
+        <rdar://problem/25707757>
+
+        Reviewed by Darin Adler.
+
+        Update tests to use new RTL scrollbar mechanism.
+
+        * fast/scrolling/rtl-scrollbars-animation-property.html:
+        * fast/scrolling/rtl-scrollbars-elementFromPoint-static.html:
+        * fast/scrolling/rtl-scrollbars-elementFromPoint.html:
+        * fast/scrolling/rtl-scrollbars-expected.html:
+        * fast/scrolling/rtl-scrollbars-iframe-offset-expected.html:
+        * fast/scrolling/rtl-scrollbars-iframe-offset.html:
+        * fast/scrolling/rtl-scrollbars-iframe-position-absolute.html:
+        * fast/scrolling/rtl-scrollbars-iframe-scrolled-expected.html:
+        * fast/scrolling/rtl-scrollbars-iframe-scrolled.html:
+        * fast/scrolling/rtl-scrollbars-iframe.html:
+        * fast/scrolling/rtl-scrollbars-listbox-expected.html:
+        * fast/scrolling/rtl-scrollbars-listbox-scroll-expected.html:
+        * fast/scrolling/rtl-scrollbars-listbox-scroll.html:
+        * fast/scrolling/rtl-scrollbars-listbox-select-left-expected.html:
+        * fast/scrolling/rtl-scrollbars-listbox-select-left.html:
+        * fast/scrolling/rtl-scrollbars-listbox-select-right-expected.html:
+        * fast/scrolling/rtl-scrollbars-listbox-select-right.html:
+        * fast/scrolling/rtl-scrollbars-listbox-simple-expected-mismatch.html:
+        * fast/scrolling/rtl-scrollbars-listbox-simple.html:
+        * fast/scrolling/rtl-scrollbars-listbox.html:
+        * fast/scrolling/rtl-scrollbars-overflow-contents-expected.html:
+        * fast/scrolling/rtl-scrollbars-overflow-contents.html:
+        * fast/scrolling/rtl-scrollbars-overflow-dir-rtl-expected.html:
+        * fast/scrolling/rtl-scrollbars-overflow-dir-rtl.html:
+        * fast/scrolling/rtl-scrollbars-overflow-elementFromPoint.html:
+        * fast/scrolling/rtl-scrollbars-overflow-expected.html:
+        * fast/scrolling/rtl-scrollbars-overflow-padding-expected.html:
+        * fast/scrolling/rtl-scrollbars-overflow-padding.html:
+        * fast/scrolling/rtl-scrollbars-overflow-position-absolute-expected.html:
+        * fast/scrolling/rtl-scrollbars-overflow-position-absolute.html:
+        * fast/scrolling/rtl-scrollbars-overflow-simple-expected-mismatch.html:
+        * fast/scrolling/rtl-scrollbars-overflow-simple.html:
+        * fast/scrolling/rtl-scrollbars-overflow-text-selection-scrolled-expected.html:
+        * fast/scrolling/rtl-scrollbars-overflow-text-selection-scrolled.html:
+        * fast/scrolling/rtl-scrollbars-overflow.html:
+        * fast/scrolling/rtl-scrollbars-overlay-no-push-contents-expected.html:
+        * fast/scrolling/rtl-scrollbars-overlay-no-push-contents.html:
+        * fast/scrolling/rtl-scrollbars-position-absolute-expected.html:
+        * fast/scrolling/rtl-scrollbars-position-absolute.html:
+        * fast/scrolling/rtl-scrollbars-position-fixed-expected.html:
+        * fast/scrolling/rtl-scrollbars-position-fixed.html:
+        * fast/scrolling/rtl-scrollbars-positioning-expected.html:
+        * fast/scrolling/rtl-scrollbars-positioning.html:
+        * fast/scrolling/rtl-scrollbars-simple-expected-mismatch.html:
+        * fast/scrolling/rtl-scrollbars-simple.html:
+        * fast/scrolling/rtl-scrollbars-sticky-document-2-expected.html:
+        * fast/scrolling/rtl-scrollbars-sticky-document-2.html:
+        * fast/scrolling/rtl-scrollbars-sticky-document-expected.html:
+        * fast/scrolling/rtl-scrollbars-sticky-document.html:
+        * fast/scrolling/rtl-scrollbars-sticky-iframe-2-expected.html:
+        * fast/scrolling/rtl-scrollbars-sticky-iframe-2.html:
+        * fast/scrolling/rtl-scrollbars-sticky-iframe-expected.html:
+        * fast/scrolling/rtl-scrollbars-sticky-iframe.html:
+        * fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-2-expected.html:
+        * fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-2.html:
+        * fast/scrolling/rtl-scrollbars-sticky-overflow-scroll-expected.html:
+        * fast/scrolling/rtl-scrollbars-sticky-overflow-scroll.html:
+        * fast/scrolling/rtl-scrollbars-text-selection-expected.html:
+        * fast/scrolling/rtl-scrollbars-text-selection-scrolled-expected.html:
+        * fast/scrolling/rtl-scrollbars-text-selection-scrolled.html:
+        * fast/scrolling/rtl-scrollbars-text-selection.html:
+        * fast/scrolling/rtl-scrollbars.html:
+        * platform/mac/fast/scrolling/rtl-scrollbars-animation-property-expected.png: Added.
+
 2016-04-26  Ryosuke Niwa  <rniwa@webkit.org>
 
         ASSERTION FAILED: m_templateInsertionModes.isEmpty() in WebCore::HTMLTreeBuilder::finished
index ee360b4..258acea 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true useMockScrollbars=false ] -->
+<!DOCTYPE html><!-- webkit-test-runner [ useMockScrollbars=false ] -->
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <div style="width: 200px; height: 200px; position: relative; overflow: scroll;">
index 354cdd9..29b3e32 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 <script src="../../resources/js-test-pre.js"></script>
 </head>
 <body>
@@ -14,4 +20,4 @@ shouldBeEqualToString("document.elementFromPoint(22, 7).id", "a");
 </script>
 <script src="../../resources/js-test-post.js"></script>
 </body>
-</html>
\ No newline at end of file
+</html>
index e3a8659..f911453 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 <script src="../../resources/js-test-pre.js"></script>
 </head>
 <body>
@@ -13,4 +19,4 @@ shouldBeEqualToString("document.elementFromPoint(7, 7).id", "a");
 </script>
 <script src="../../resources/js-test-post.js"></script>
 </body>
-</html>
\ No newline at end of file
+</html>
index e95f290..679fa22 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </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>
index 28d1766..8575108 100644 (file)
@@ -1,10 +1,16 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <div id="text" style='position: absolute; left: 0px; top: 0px;'>ABCD</div>
 <div style='position: absolute; left: 0px; top: 25px;'>DEFG</div>
 <div style="position: absolute; left: 8px; top: 100px;">This test makes sure that contents of iframes are not covered by an rtl scrollbar.</div>
 </body>
-</html>
\ No newline at end of file
+</html>
index c36ff86..13f7514 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <iframe id="iframe" style="position: absolute; width: 100px; height: 100px; left: -15px; top: 0px; margin: 0px; border: solid black 0px; padding: 0px;"
@@ -15,4 +21,4 @@ ABCD
 </html>"></iframe>
 <div style="position: absolute; left: 8px; top: 100px;">This test makes sure that contents of iframes are not covered by an rtl scrollbar.</div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 3279521..fe894b3 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 <script src='../../resources/js-test-pre.js'></script>
 </head>
 <body>
@@ -28,4 +34,4 @@ iframe.addEventListener("load", function() {
 </script>
 <script src='../../resources/js-test-post.js'></script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 27ef87e..52b3f7a 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <iframe id="iframe" style="position: absolute; width: 100px; height: 100px; left: 0px; top: 0px; margin: 0px; border: solid black 0px; padding: 0px;"
@@ -27,4 +33,4 @@ document.getElementById("iframe").focus();
 </script>
 <div style="position: absolute; left: 8px; top: 100px;">This test makes sure that hit testing in iframes works correctly.</div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 61ffcdf..645de45 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <iframe id="iframe" style="position: absolute; width: 100px; height: 100px; left: 0px; top: 0px; margin: 0px; border: solid black 0px; padding: 0px;"
@@ -23,4 +29,4 @@ if (window.eventSender) {
 </html>"></iframe>
 <div style="position: absolute; left: 8px; top: 100px;">This test makes sure that hit testing in iframes works correctly.</div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 384b0bd..4d2a251 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 <script src='../../resources/js-test-pre.js'></script>
 </head>
 <body>
@@ -28,4 +34,4 @@ iframe.addEventListener("load", function() {
 </script>
 <script src='../../resources/js-test-post.js'></script>
 </body>
-</html>
\ No newline at end of file
+</html>
index abcd492..72dcdcd 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="position: absolute; left: 8px; top: 200px;">This test makes sure that list boxes obey RTL scrollbars.</div>
@@ -23,4 +29,4 @@ var container = document.getElementById("container");
 container.scrollTop = container.scrollHeight - container.clientHeight;
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 864ca7c..2ec041e 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="position: absolute; left: 8px; top: 200px;">This test makes sure that list boxes obey RTL scrollbars.</div>
@@ -26,4 +32,4 @@ if (window.eventSender) {
 }
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 361e4f6..3a763ba 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="position: absolute; left: 8px; top: 200px;">This test makes sure that cliking on an LTR scrollbar doesn't select an item in a list box.</div>
@@ -23,4 +29,4 @@ var container = document.getElementById("container");
 container.focus();
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 231cd71..fa7f9f0 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="position: absolute; left: 8px; top: 200px;">This test makes sure that cliking on an LTR scrollbar doesn't select an item in a list box.</div>
@@ -26,4 +32,4 @@ if (window.eventSender) {
 }
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index d701efa..462e5b3 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="position: absolute; left: 8px; top: 200px;">This test makes sure that cliking on the rightmost part of an item causes it to be selected.</div>
@@ -25,4 +31,4 @@ var january = document.getElementById("january");
 january.selected = true;
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index cb735c9..3ac9cf9 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="position: absolute; left: 8px; top: 200px;">This test makes sure that cliking on the rightmost part of an item causes it to be selected.</div>
@@ -26,4 +32,4 @@ if (window.eventSender) {
 }
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index e974b68..03a0578 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <p>This test makes sure that list boxes obey RTL scrollbars.</p>
@@ -19,4 +25,4 @@
 <option>December</option>
 </select>
 </body>
-</html>
\ No newline at end of file
+</html>
index ce26936..1348c11 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="position: absolute; left: 8px; top: 200px;">This test makes sure that list boxes obey RTL scrollbars.</div>
@@ -21,4 +27,4 @@
 </select>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 2ab8289..2d776da 100644 (file)
@@ -17,4 +17,4 @@
 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse a risus nisi. Maecenas ut metus gravida, tincidunt arcu nec, ultrices dui. Vivamus at pretium purus, in feugiat odio. Phasellus facilisis mi id condimentum congue. Aenean sollicitudin risus a accumsan facilisis. Sed ac fringilla felis. Morbi malesuada vehicula sapien.</p>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index ff0a786..d78b5b8 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <div style="overflow: hidden; width: 700px; height: 500px; position: relative;">
@@ -19,4 +25,4 @@
 </div>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 35615ad..932c8be 100644 (file)
@@ -24,4 +24,4 @@ range.selectNode(document.getElementById("element"));
 selection.addRange(range);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 1959332..d05fc4c 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <div style="overflow: hidden; width: 100%; height: 539px; position: relative;">
@@ -26,4 +32,4 @@ range.selectNode(document.getElementById("element"));
 selection.addRange(range);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index d29e275..0588832 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 <script src="../../resources/js-test-pre.js"></script>
 </head>
 <body>
@@ -15,4 +21,4 @@ shouldBeEqualToString("document.elementFromPoint(22, 7).id", "a");
 </script>
 <script src="../../resources/js-test-post.js"></script>
 </body>
-</html>
\ No newline at end of file
+</html>
index c7f2e5c..ae4d379 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <div id="element" style="overflow: scroll; width: 700px; height: 500px;">
@@ -21,4 +27,4 @@ var element = document.getElementById("element");
 element.scrollTop = 1000;
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index fd68a39..a43e55e 100644 (file)
@@ -24,4 +24,4 @@ range.selectNode(document.getElementById("element"));
 selection.addRange(range);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 51d880b..34fd81b 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <div style="overflow: hidden; width: 100%; height: 539px; position: relative;">
@@ -26,4 +32,4 @@ range.selectNode(document.getElementById("element"));
 selection.addRange(range);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 0cc7360..c7f870b 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 This test makes sure that position: absolute elements do not overlap the vertical scrollbar on RTL machines. The test passes if you see a green square and a red square below.
@@ -10,4 +16,4 @@ This test makes sure that position: absolute elements do not overlap the vertica
 <div style="width: 1px; height: 3000px; position: absolute; left: 0px; top: 0px;"></div>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index e58617a..408fad7 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 This test makes sure that position: absolute elements do not overlap the vertical scrollbar on RTL machines. The test passes if you see a green square and a red square below.
@@ -12,4 +18,4 @@ This test makes sure that position: absolute elements do not overlap the vertica
 </div>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 2c3cf27..0b5d79c 100644 (file)
@@ -17,4 +17,4 @@
 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse a risus nisi. Maecenas ut metus gravida, tincidunt arcu nec, ultrices dui. Vivamus at pretium purus, in feugiat odio. Phasellus facilisis mi id condimentum congue. Aenean sollicitudin risus a accumsan facilisis. Sed ac fringilla felis. Morbi malesuada vehicula sapien.</p>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 40d61af..6c973c6 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <div id="element" style="overflow: scroll; width: 700px; height: 500px;">
@@ -17,4 +23,4 @@
 <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse a risus nisi. Maecenas ut metus gravida, tincidunt arcu nec, ultrices dui. Vivamus at pretium purus, in feugiat odio. Phasellus facilisis mi id condimentum congue. Aenean sollicitudin risus a accumsan facilisis. Sed ac fringilla felis. Morbi malesuada vehicula sapien.</p>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 599bb8b..db6c89b 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="overflow: hidden; width: 100%; height: 485px; position: absolute; left: -15px;">
@@ -21,4 +27,4 @@ if (window.eventSender) {
 }
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 21cf683..e6144f5 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body>
 <div id="element" style="overflow: scroll; width: 700px; height: 500px;">
@@ -26,4 +32,4 @@ if (window.eventSender) {
 }
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 376fe06..2b8d739 100644 (file)
@@ -1,7 +1,13 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
 <script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
+<script>
 if (window.internals)
     internals.setUsesOverlayScrollbars(true);
 </script>
index d70b821..2349e8f 100644 (file)
@@ -1,7 +1,13 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
 <script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
+<script>
 if (window.internals)
     internals.setUsesOverlayScrollbars(true);
 </script>
index 4f26609..e36e6f8 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div id="text" style="font: 20px Ahem; position: absolute; left: 100px;">pppppppppppppp</div>
index 96c1679..128c49f 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div id="text" style="font: 20px Ahem; position: absolute; left: 100px;">pppppppppppppp</div>
index 41017ad..956ba77 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div id="text" style="font: 20px Ahem; position: fixed; left: 100px;">pppppppppppppp</div>
index e7f01b3..d019f71 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div id="text" style="font: 20px Ahem; position: fixed; left: 100px;">pppppppppppppp</div>
index 7d9b226..cdf5ca3 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 <style>
 div {
     font: 20px Ahem;
@@ -19,4 +25,4 @@ div {
 <div style="position: absolute; left: 0px; top: 210px;">m</div>
 <div style="position: absolute; left: 0px; top: 0px; width: 1px; height: 2000px;"></div>
 </body>
-</html>
\ No newline at end of file
+</html>
index a065c9b..d95f57f 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 <style>
 div {
     font: 20px Ahem;
@@ -35,4 +41,4 @@ div {
 </html>"></iframe>
 <div style="position: absolute; left: 0px; top: 0px; width: 1px; height: 2000px;"></div>
 </body>
-</html>
\ No newline at end of file
+</html>
index c6fc882..d8f112b 100644 (file)
@@ -5,4 +5,4 @@
 <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
+</html>
index 78bd050..6235bde 100644 (file)
@@ -1,8 +1,14 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </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
+</html>
index 3e02081..92d1802 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -12,4 +18,4 @@ This test makes sure that position-sticky obeys RTL scrollbars when positioning.
 window.scroll(850, 0);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 0f2ecbe..21506ba 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -11,4 +17,4 @@ This test makes sure that position-sticky obeys RTL scrollbars when positioning.
 window.scroll(850, 0);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 528e830..b79304a 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -9,4 +15,4 @@ This test makes sure that position-sticky obeys RTL scrollbars when positioning.
     <div style="position: absolute; left: 685px; top: 0px; width: 100px; height: 100px; background: green;"></div>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index c7675df..d394dfb 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -8,4 +14,4 @@ This test makes sure that position-sticky obeys RTL scrollbars when positioning.
     <div style="display: inline-block; position: static; width: 800px; height: 100px; background: blue;"></div><div style="display: inline-block; position: -webkit-sticky; left: 0px; right: 0px; width: 100px; height: 100px; background: green;"></div><div style="display: inline-block; position: static; width: 800px; height: 100px; background: blue;"></div>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 639556e..a73c74c 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -18,4 +24,4 @@ window.scroll(850, 0);
 </body>
 </html">
 </body>
-</html>
\ No newline at end of file
+</html>
index fd41afc..941575e 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -17,4 +23,4 @@ window.scroll(850, 0);
 </body>
 </html">
 </body>
-</html>
\ No newline at end of file
+</html>
index 4861296..adb78eb 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -15,4 +21,4 @@ This test makes sure that position-sticky obeys RTL scrollbars when positioning.
 </body>
 </html">
 </body>
-</html>
\ No newline at end of file
+</html>
index 4901462..ab76c37 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -14,4 +20,4 @@ This test makes sure that position-sticky obeys RTL scrollbars when positioning.
 </body>
 </html">
 </body>
-</html>
\ No newline at end of file
+</html>
index b5363e5..cb05f38 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -15,4 +21,4 @@ var scrollingElement = document.getElementById("scrolling");
 scrollingElement.scrollLeft = 1000;
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index ae375d5..63dea39 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -14,4 +20,4 @@ var scrollingElement = document.getElementById("scrolling");
 scrollingElement.scrollLeft = 1000;
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index fde1540..c9b6c04 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -11,4 +17,4 @@ This test makes sure that position-sticky obeys RTL scrollbars when positioning.
 </div>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 10988e2..40bd842 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 This test makes sure that position-sticky obeys RTL scrollbars when positioning.
@@ -10,4 +16,4 @@ This test makes sure that position-sticky obeys RTL scrollbars when positioning.
 </div>
 </div>
 </body>
-</html>
\ No newline at end of file
+</html>
index 7ef5e3e..f19be9a 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div id="text" style="font: 20px Ahem;">pppppppppppppp</div>
index ed6b3d4..8ffff21 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div id="text" style="font: 20px Ahem;"><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>pppppppppppppp</div>
@@ -17,4 +23,4 @@ range.setEnd(text, 1);
 selection.addRange(range);
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 557b23b..f116804 100644 (file)
@@ -1,5 +1,11 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 <head>
 </head>
 <body style="margin: 0px;">
@@ -16,4 +22,4 @@ if (window.eventSender) {
 }
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
index 4dbc88a..bedf214 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </head>
 <body style="margin: 0px;">
 <div style="font: 20px Ahem;">pppppppppppppp</div>
index 06e7d25..86ad8c8 100644 (file)
@@ -1,6 +1,12 @@
-<!DOCTYPE html><!-- webkit-test-runner [ rtlScrollbars=true ] -->
+<!DOCTYPE html>
 <html>
 <head>
+<script>
+if (window.internals) {
+    internals.settings.setUserInterfaceDirectionPolicy("View");
+    internals.settings.setSystemLayoutDirection("RTL");
+}
+</script>
 </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>
@@ -13,4 +19,4 @@ if (window.eventSender) {
 }
 </script>
 </body>
-</html>
\ No newline at end of file
+</html>
diff --git a/LayoutTests/platform/mac/fast/scrolling/rtl-scrollbars-animation-property-expected.png b/LayoutTests/platform/mac/fast/scrolling/rtl-scrollbars-animation-property-expected.png
new file mode 100644 (file)
index 0000000..ff16d84
Binary files /dev/null and b/LayoutTests/platform/mac/fast/scrolling/rtl-scrollbars-animation-property-expected.png differ
index 5331b3d..868916e 100644 (file)
@@ -1,3 +1,135 @@
+2016-04-26  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [WK2] [OS X] Create API for switching RTL scrollbar policy
+        https://bugs.webkit.org/show_bug.cgi?id=156948
+        <rdar://problem/25707757>
+
+        Reviewed by Darin Adler.
+
+        There are two schools of thought for where to put scrollbars in RTL environments.
+        The first is that we should obey the content's "dir" attribute, specified on each
+        element. The second is that we should be consistent with the platform (AppKit's)
+        behavior.
+
+        There are some situations where the placement should be done according to the
+        content. For example, this policy would be used in web browsers.
+
+        However, there are also places where web content is designed to fit seamlessly
+        amongst native content. In this situation, the placement of the scrollbars should
+        be done according to the view.
+
+        Because WebKit doesn't know which of these situations it is operating within, this
+        patch adds a new API property, userInterfaceDirectionPolicy, to
+        WKWebViewConfigurationPolicy. This allows clients to instruct us which policy to
+        abide by. It is plumbed to the web process inside the WebPreferencesStore and is
+        ultimately held inside the Page's Settings object.
+
+        This Setting is consulted by RenderLayerModelObject, which serves as a good
+        centralized place for this policy implementation. This is the class which decides
+        if we should be consulting its RenderStyle or the platform itself when we decide
+        where to put the scrollbars.
+
+        Putting this decision inside the renderer is important because ScrollableArea
+        often needs to know if scrollbars should be put on the left, but ScrollableArea
+        doesn't know anything about RenderStyles. Therefore, the renderer must be the
+        intermediary between ScrollableArea and the RenderStyle. (ScrollableArea also
+        doesn't directly know anything about renderers either; however, each of the
+        subclasses knows about an appropriate renderer.) Therefore, ScrollableArea gets
+        a new virtual method which is implemented by the RenderLayerModelObject.
+
+        Tests: fast/scrolling/rtl-scrollbars*.html
+
+        * WebCore.xcodeproj/project.pbxproj: ScrollableAreaMac.mm is no longer necessary.
+        * page/FrameView.cpp:
+        (WebCore::FrameView::shouldPlaceBlockDirectionScrollbarOnLeft): Overridden
+        ScrollableArea function.
+        * page/FrameView.h:
+        * page/Settings.h:
+        * page/Settings.in:
+        * platform/ScrollView.cpp: Adding two new settings: One to know if we should
+        consult with the RenderStyle or the platform, and the other is whether or not
+        the platform considers itself to be RTL.
+        (WebCore::ScrollView::documentScrollPositionRelativeToViewOrigin): Update to
+        use new mechanism.
+        (WebCore::ScrollView::updateScrollbars): Ditto.
+        (WebCore::ScrollView::scrollCornerRect): Ditto.
+        (WebCore::ScrollView::locationOfContents): Ditto.
+        * platform/ScrollableArea.cpp:
+        (WebCore::ScrollableArea::verticalScrollbarIsOnLeft): Deleted. This was the old
+        mechanism.
+        (WebCore::ScrollableArea::systemLanguageIsRTL): Deleted. Ditto.
+        * platform/ScrollableArea.h:
+        * platform/mac/ScrollableAreaMac.mm: Removed.
+        (WebCore::ScrollableArea::verticalScrollbarIsOnLeft): Deleted.
+        (WebCore::ScrollableArea::systemLanguageIsRTL): Deleted.
+        * platform/mac/ScrollbarThemeMac.mm:
+        (WebCore::ScrollbarThemeMac::didCreateScrollerImp): Update to use new
+        mechanism.
+        * platform/text/WritingMode.h: These enums should match what's in WebKit2.
+        * rendering/RenderBlock.cpp:
+        (WebCore::RenderBlock::logicalLeftOffsetForContent): Update to use new mechanism.
+        (WebCore::RenderBlock::logicalRightOffsetForContent): Ditto.
+        * rendering/RenderBlockFlow.cpp:
+        (WebCore::RenderBlockFlow::determineLogicalLeftPositionForChild): Ditto.
+        * rendering/RenderBox.cpp: Ditto.
+        (WebCore::RenderBox::contentBoxRect):
+        (WebCore::RenderBox::overflowClipRect):
+        (WebCore::RenderBox::computePositionedLogicalWidth):
+        (WebCore::RenderBox::layoutOverflowRectForPropagation):
+        * rendering/RenderBoxModelObject.cpp: Ditto.
+        (WebCore::RenderBoxModelObject::constrainingRectForStickyPosition):
+        * rendering/RenderLayer.cpp:
+        (WebCore::RenderLayer::resize): Ditto.
+        (WebCore::cornerStart): Migrate to use references.
+        (WebCore::cornerRect): Ditto.
+        (WebCore::RenderLayer::scrollCornerRect): Ditto.
+        (WebCore::resizerCornerRect): Ditto.
+        (WebCore::RenderLayer::scrollCornerAndResizerRect): Ditto.
+        (WebCore::RenderLayer::verticalScrollbarStart): Update to use new mechanism.
+        (WebCore::RenderLayer::horizontalScrollbarStart): Ditto.
+        (WebCore::RenderLayer::offsetFromResizeCorner): Ditto.
+        (WebCore::RenderLayer::positionOverflowControls): Migrate to use references.
+        (WebCore::RenderLayer::computeScrollDimensions): Ditto.
+        (WebCore::RenderLayer::overflowControlsIntersectRect): Ditto.
+        (WebCore::RenderLayer::drawPlatformResizerImage): Update to use new mechanism.
+        (WebCore::RenderLayer::paintResizer): Migrate to use references.
+        (WebCore::RenderLayer::isPointInResizeControl): Ditto.
+        (WebCore::RenderLayer::hitTestOverflowControls): Ditto.
+        (WebCore::RenderLayer::hitTestResizerInFragments): Ditto.
+        * rendering/RenderLayer.h: ScrollableArea override
+        * rendering/RenderLayerCompositor.cpp:
+        (WebCore::RenderLayerCompositor::positionForClipLayer): Update to use new
+        mechanism.
+        * rendering/RenderLayerModelObject.cpp:
+        (WebCore::RenderLayerModelObject::shouldPlaceBlockDirectionScrollbarOnLeft):
+        This is the meat of this patch. This is where we decide if we should be
+        interrogating the RenderStyle or the underlying platform.
+        * rendering/RenderLayerModelObject.h:
+        * rendering/RenderListBox.cpp: Update to use new mechanism.
+        (WebCore::RenderListBox::itemBoundingBoxRect):
+        (WebCore::RenderListBox::paintScrollbar):
+        (WebCore::RenderListBox::isPointInOverflowControl):
+        (WebCore::RenderListBox::listIndexAtOffset):
+        (WebCore::RenderListBox::controlClipRect):
+        (WebCore::RenderListBox::invalidateScrollbarRect):
+        (WebCore::RenderListBox::convertFromScrollbarToContainingView):
+        (WebCore::RenderListBox::convertFromContainingViewToScrollbar):
+        * rendering/RenderListBox.h:
+        * rendering/RenderView.cpp: Ditto.
+        (WebCore::RenderView::repaintViewRectangle):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::shouldPlaceBlockDirectionScrollbarOnLeft): This
+        function is now much dumber. It just inspects its own style.
+        * testing/InternalSettings.cpp: Allow mocking.
+        (WebCore::InternalSettings::Backup::Backup):
+        (WebCore::InternalSettings::Backup::restoreTo):
+        (WebCore::InternalSettings::verticalScrollbarLocationPolicy):
+        (WebCore::InternalSettings::setVerticalScrollbarLocationPolicy):
+        (WebCore::InternalSettings::systemLayoutDirection):
+        (WebCore::InternalSettings::setSystemLayoutDirection):
+        * testing/InternalSettings.h:
+        * testing/InternalSettings.idl:
+
 2016-04-26  Chris Dumez  <cdumez@apple.com>
 
         [Web IDL] Specify default values for optional parameters of type 'unsigned long'
index 96bed15..11c0228 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>"; };
                                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 7a9c3ca..0a6cf04 100644 (file)
@@ -4968,5 +4968,10 @@ IntSize FrameView::viewportSizeForCSSViewportUnits() const
     // property on the root element.
     return visibleContentRectIncludingScrollbars().size();
 }
+
+bool FrameView::shouldPlaceBlockDirectionScrollbarOnLeft() const
+{
+    return renderView() && renderView()->shouldPlaceBlockDirectionScrollbarOnLeft();
+}
     
 } // namespace WebCore
index 97753dc..ac373b1 100644 (file)
@@ -557,6 +557,8 @@ public:
 
     void show() override;
 
+    bool shouldPlaceBlockDirectionScrollbarOnLeft() const final;
+
 protected:
     bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect) override;
     void scrollContentsSlowPath(const IntRect& updateRect) override;
index d2600f5..6ce9ac7 100644 (file)
@@ -35,6 +35,7 @@
 #include "TextFlags.h"
 #include "Timer.h"
 #include "URL.h"
+#include "WritingMode.h"
 #include <chrono>
 #include <runtime/RuntimeFlags.h>
 #include <unicode/uscript.h>
@@ -71,6 +72,11 @@ enum DebugOverlayRegionFlags {
     WheelEventHandlerRegion = 1 << 1,
 };
 
+enum class UserInterfaceDirectionPolicy {
+    Content,
+    System
+};
+
 typedef unsigned DebugOverlayRegions;
 
 class Settings : public RefCounted<Settings> {
index 04f1387..21e7c52 100644 (file)
@@ -251,3 +251,6 @@ httpEquivEnabled initial=true
 # enforces all frame sandbox flags (see enum SandboxFlag in SecurityContext.h), and also disables <meta http-equiv>
 # processing and subframe loading.
 contentDispositionAttachmentSandboxEnabled initial=false
+
+userInterfaceDirectionPolicy type=UserInterfaceDirectionPolicy, initial=UserInterfaceDirectionPolicy::Content
+systemLayoutDirection type=TextDirection, initial=LTR
index f79d775..f22d6bf 100644 (file)
@@ -405,7 +405,7 @@ ScrollPosition ScrollView::adjustScrollPositionWithinRange(const ScrollPosition&
 ScrollPosition ScrollView::documentScrollPositionRelativeToViewOrigin() const
 {
     return scrollPosition() - IntSize(
-        verticalScrollbarIsOnLeft() && m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0,
+        shouldPlaceBlockDirectionScrollbarOnLeft() && m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0,
         headerHeight() + topContentInset(TopContentInsetType::WebCoreOrPlatformContentInset));
 }
 
@@ -719,7 +719,7 @@ void ScrollView::updateScrollbars(const ScrollPosition& desiredPosition)
         int clientWidth = visibleWidth();
         int pageStep = Scrollbar::pageStep(clientWidth);
         IntRect oldRect(m_horizontalScrollbar->frameRect());
-        IntRect hBarRect(verticalScrollbarIsOnLeft() && m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0,
+        IntRect hBarRect(shouldPlaceBlockDirectionScrollbarOnLeft() && m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0,
             height() - m_horizontalScrollbar->height(),
             width() - (m_verticalScrollbar ? m_verticalScrollbar->occupiedWidth() : 0),
             m_horizontalScrollbar->height());
@@ -740,7 +740,7 @@ void ScrollView::updateScrollbars(const ScrollPosition& desiredPosition)
         int clientHeight = visibleHeight();
         int pageStep = Scrollbar::pageStep(clientHeight);
         IntRect oldRect(m_verticalScrollbar->frameRect());
-        IntRect vBarRect(verticalScrollbarIsOnLeft() ? 0 : width() - m_verticalScrollbar->width(),
+        IntRect vBarRect(shouldPlaceBlockDirectionScrollbarOnLeft() ? 0 : width() - m_verticalScrollbar->width(),
             topContentInset(),
             m_verticalScrollbar->width(),
             height() - topContentInset() - (m_horizontalScrollbar ? m_horizontalScrollbar->occupiedHeight() : 0));
@@ -1134,14 +1134,14 @@ IntRect ScrollView::scrollCornerRect() const
     int heightTrackedByScrollbar = height() - topContentInset();
 
     if (m_horizontalScrollbar && width() - m_horizontalScrollbar->width() > 0) {
-        cornerRect.unite(IntRect(verticalScrollbarIsOnLeft() ? 0 : m_horizontalScrollbar->width(),
+        cornerRect.unite(IntRect(shouldPlaceBlockDirectionScrollbarOnLeft() ? 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(verticalScrollbarIsOnLeft() ? 0 : width() - m_verticalScrollbar->width(),
+        cornerRect.unite(IntRect(shouldPlaceBlockDirectionScrollbarOnLeft() ? 0 : width() - m_verticalScrollbar->width(),
             m_verticalScrollbar->height() + topContentInset(),
             m_verticalScrollbar->width(),
             heightTrackedByScrollbar - m_verticalScrollbar->height()));
@@ -1502,7 +1502,7 @@ void ScrollView::styleDidChange()
 IntPoint ScrollView::locationOfContents() const
 {
     IntPoint result = location();
-    if (verticalScrollbarIsOnLeft() && m_verticalScrollbar)
+    if (shouldPlaceBlockDirectionScrollbarOnLeft() && m_verticalScrollbar)
         result.move(m_verticalScrollbar->occupiedWidth(), 0);
     return result;
 }
index d3a35e2..60fe93d 100644 (file)
@@ -689,16 +689,4 @@ void ScrollableArea::computeScrollbarValueAndOverhang(float currentPosition, flo
     }
 }
 
-#if !PLATFORM(COCOA)
-bool ScrollableArea::verticalScrollbarIsOnLeft() const
-{
-    return false;
-}
-
-bool ScrollableArea::systemLanguageIsRTL()
-{
-    return false;
-}
-#endif
-
 } // namespace WebCore
index 3fdaab4..099a351 100644 (file)
@@ -315,8 +315,7 @@ public:
     virtual bool usesMockScrollAnimator() const { return false; }
     virtual void logMockScrollAnimatorMessage(const String&) const { };
 
-    bool verticalScrollbarIsOnLeft() const;
-    static bool systemLanguageIsRTL();
+    virtual bool shouldPlaceBlockDirectionScrollbarOnLeft() const = 0;
 
 protected:
     WEBCORE_EXPORT ScrollableArea();
diff --git a/Source/WebCore/platform/mac/ScrollableAreaMac.mm b/Source/WebCore/platform/mac/ScrollableAreaMac.mm
deleted file mode 100644 (file)
index 27e55ae..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * 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 {
-
-// It's conceivable that in the future, we may want some scrollbars to be on the right while other scrollbars in the same document are on the left.
-// This non-static function on the ScrollableArea makes that possible.
-bool ScrollableArea::verticalScrollbarIsOnLeft() const
-{
-    return systemLanguageIsRTL();
-}
-
-bool ScrollableArea::systemLanguageIsRTL()
-{
-#if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
-    static bool result = [[NSScrollerImpPair class] respondsToSelector:@selector(scrollerLayoutDirection)] && [NSScrollerImpPair scrollerLayoutDirection] == NSUserInterfaceLayoutDirectionRightToLeft;
-    return result;
-#else
-    return false;
-#endif
-}
-
-}
index f239661..99e02ae 100644 (file)
@@ -158,7 +158,7 @@ void ScrollbarThemeMac::didCreateScrollerImp(Scrollbar& scrollbar)
 #if PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
     NSScrollerImp *scrollerImp = painterForScrollbar(scrollbar);
     ASSERT(scrollerImp);
-    scrollerImp.userInterfaceLayoutDirection = scrollbar.scrollableArea().verticalScrollbarIsOnLeft() ? NSUserInterfaceLayoutDirectionRightToLeft : NSUserInterfaceLayoutDirectionLeftToRight;
+    scrollerImp.userInterfaceLayoutDirection = scrollbar.scrollableArea().shouldPlaceBlockDirectionScrollbarOnLeft() ? NSUserInterfaceLayoutDirectionRightToLeft : NSUserInterfaceLayoutDirectionLeftToRight;
 #else
     UNUSED_PARAM(scrollbar);
 #endif
index 31061b6..b0fd6c3 100644 (file)
@@ -108,6 +108,7 @@ private:
     IntRect scrollableAreaBoundingBox(bool* = nullptr) const override;
     bool updatesScrollLayerPositionOnMainThread() const override { return true; }
     bool forceUpdateScrollbarsOnMainThreadForPerformanceTesting() const override { return false; }
+    bool shouldPlaceBlockDirectionScrollbarOnLeft() const final { return false; }
 
     // NOTE: This should only be called by the overriden setScrollOffset from ScrollableArea.
     void scrollTo(int offset);
index 1a8e5d0..96fa9e4 100644 (file)
@@ -2280,7 +2280,7 @@ LayoutUnit RenderBlock::textIndentOffset() const
 LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region) const
 {
     LayoutUnit logicalLeftOffset = style().isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
-    if (style().shouldPlaceBlockDirectionScrollbarOnLeft())
+    if (shouldPlaceBlockDirectionScrollbarOnLeft())
         logicalLeftOffset += verticalScrollbarWidth();
     if (!region)
         return logicalLeftOffset;
@@ -2291,7 +2291,7 @@ LayoutUnit RenderBlock::logicalLeftOffsetForContent(RenderRegion* region) const
 LayoutUnit RenderBlock::logicalRightOffsetForContent(RenderRegion* region) const
 {
     LayoutUnit logicalRightOffset = style().isHorizontalWritingMode() ? borderLeft() + paddingLeft() : borderTop() + paddingTop();
-    if (style().shouldPlaceBlockDirectionScrollbarOnLeft())
+    if (shouldPlaceBlockDirectionScrollbarOnLeft())
         logicalRightOffset += verticalScrollbarWidth();
     logicalRightOffset += availableLogicalWidth();
     if (!region)
index 82b886f..3a7f0a7 100644 (file)
@@ -828,7 +828,7 @@ LayoutUnit RenderBlockFlow::marginOffsetForSelfCollapsingBlock()
 void RenderBlockFlow::determineLogicalLeftPositionForChild(RenderBox& child, ApplyLayoutDeltaMode applyDelta)
 {
     LayoutUnit startPosition = borderStart() + paddingStart();
-    if (style().shouldPlaceBlockDirectionScrollbarOnLeft())
+    if (shouldPlaceBlockDirectionScrollbarOnLeft())
         startPosition += (style().isLeftToRightDirection() ? 1 : -1) * verticalScrollbarWidth();
     LayoutUnit totalAvailableLogicalWidth = borderAndPaddingLogicalWidth() + availableLogicalWidth();
 
index 030d0bc..b680661 100644 (file)
@@ -693,7 +693,7 @@ RoundedRect::Radii RenderBox::borderRadii() const
 LayoutRect RenderBox::contentBoxRect() const
 {
     LayoutUnit x = borderLeft() + paddingLeft();
-    if (layer() && layer()->verticalScrollbarIsOnLeft())
+    if (shouldPlaceBlockDirectionScrollbarOnLeft())
         x += verticalScrollbarWidth();
     LayoutUnit y = borderTop() + paddingTop();
     return LayoutRect(x, y, contentWidth(), contentHeight());
@@ -1827,7 +1827,7 @@ LayoutRect RenderBox::overflowClipRect(const LayoutPoint& location, RenderRegion
 
     // Subtract out scrollbars if we have them.
     if (layer()) {
-        if (style().shouldPlaceBlockDirectionScrollbarOnLeft())
+        if (shouldPlaceBlockDirectionScrollbarOnLeft())
             clipRect.move(layer()->verticalScrollbarWidth(relevancy), 0);
         clipRect.contract(layer()->verticalScrollbarWidth(relevancy), layer()->horizontalScrollbarHeight(relevancy));
     }
@@ -3534,7 +3534,7 @@ void RenderBox::computePositionedLogicalWidth(LogicalExtentComputedValues& compu
     computedValues.m_extent += bordersPlusPadding;
     if (is<RenderBox>(containerBlock)) {
         auto& containingBox = downcast<RenderBox>(containerBlock);
-        if (containingBox.layer() && containingBox.layer()->verticalScrollbarIsOnLeft())
+        if (containingBox.shouldPlaceBlockDirectionScrollbarOnLeft())
             computedValues.m_position += containingBox.verticalScrollbarWidth();
     }
     
@@ -4907,7 +4907,7 @@ LayoutRect RenderBox::flippedClientBoxRect() const
     flipForWritingMode(rect);
     // Subtract space occupied by scrollbars. They are at their physical edge in this coordinate
     // system, so order is important here: first flip, then subtract scrollbars.
-    if (style().shouldPlaceBlockDirectionScrollbarOnLeft() && style().isLeftToRightDirection())
+    if (shouldPlaceBlockDirectionScrollbarOnLeft() && style().isLeftToRightDirection())
         rect.move(verticalScrollbarWidth(), 0);
     rect.contract(verticalScrollbarWidth(), horizontalScrollbarHeight());
     return rect;
index 0295aab..dfb962c 100644 (file)
@@ -452,7 +452,7 @@ FloatRect RenderBoxModelObject::constrainingRectForStickyPosition() const
         FloatPoint scrollOffset = FloatPoint() + enclosingClippingLayer->scrollOffset();
 
         float scrollbarOffset = 0;
-        if (enclosingClippingBox.hasLayer() && enclosingClippingBox.style().shouldPlaceBlockDirectionScrollbarOnLeft())
+        if (enclosingClippingBox.hasLayer() && enclosingClippingBox.shouldPlaceBlockDirectionScrollbarOnLeft())
             scrollbarOffset = enclosingClippingBox.layer()->verticalScrollbarWidth(IgnoreOverlayScrollbarSize);
 
         constrainingRect.setLocation(FloatPoint(scrollOffset.x() + scrollbarOffset, scrollOffset.y()));
index a17210b..c92cc43 100644 (file)
@@ -2689,7 +2689,7 @@ void RenderLayer::resize(const PlatformMouseEvent& evt, const LayoutSize& oldOff
     element->setMinimumSizeForResizing(minimumSize);
     
     LayoutSize adjustedOldOffset = LayoutSize(oldOffset.width() / zoomFactor, oldOffset.height() / zoomFactor);
-    if (renderer->style().shouldPlaceBlockDirectionScrollbarOnLeft()) {
+    if (shouldPlaceBlockDirectionScrollbarOnLeft()) {
         newOffset.setWidth(-newOffset.width());
         adjustedOldOffset.setWidth(-adjustedOldOffset.width());
     }
@@ -2791,34 +2791,34 @@ bool RenderLayer::isActive() const
     return page && page->focusController().isActive();
 }
 
-static int cornerStart(const RenderLayer* layer, int minX, int maxX, int thickness)
+static int cornerStart(const RenderLayer& layer, int minX, int maxX, int thickness)
 {
-    if (layer->renderer().style().shouldPlaceBlockDirectionScrollbarOnLeft())
-        return minX + layer->renderer().style().borderLeftWidth();
-    return maxX - thickness - layer->renderer().style().borderRightWidth();
+    if (layer.shouldPlaceBlockDirectionScrollbarOnLeft())
+        return minX + layer.renderer().style().borderLeftWidth();
+    return maxX - thickness - layer.renderer().style().borderRightWidth();
 }
 
-static LayoutRect cornerRect(const RenderLayer* layer, const LayoutRect& bounds)
+static LayoutRect cornerRect(const RenderLayer& layer, const LayoutRect& bounds)
 {
     int horizontalThickness;
     int verticalThickness;
-    if (!layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
+    if (!layer.verticalScrollbar() && !layer.horizontalScrollbar()) {
         // FIXME: This isn't right.  We need to know the thickness of custom scrollbars
         // even when they don't exist in order to set the resizer square size properly.
         horizontalThickness = ScrollbarTheme::theme().scrollbarThickness();
         verticalThickness = horizontalThickness;
-    } else if (layer->verticalScrollbar() && !layer->horizontalScrollbar()) {
-        horizontalThickness = layer->verticalScrollbar()->width();
+    } else if (layer.verticalScrollbar() && !layer.horizontalScrollbar()) {
+        horizontalThickness = layer.verticalScrollbar()->width();
         verticalThickness = horizontalThickness;
-    } else if (layer->horizontalScrollbar() && !layer->verticalScrollbar()) {
-        verticalThickness = layer->horizontalScrollbar()->height();
+    } else if (layer.horizontalScrollbar() && !layer.verticalScrollbar()) {
+        verticalThickness = layer.horizontalScrollbar()->height();
         horizontalThickness = verticalThickness;
     } else {
-        horizontalThickness = layer->verticalScrollbar()->width();
-        verticalThickness = layer->horizontalScrollbar()->height();
+        horizontalThickness = layer.verticalScrollbar()->width();
+        verticalThickness = layer.horizontalScrollbar()->height();
     }
     return LayoutRect(cornerStart(layer, bounds.x(), bounds.maxX(), horizontalThickness),
-        bounds.maxY() - verticalThickness - layer->renderer().style().borderBottomWidth(),
+        bounds.maxY() - verticalThickness - layer.renderer().style().borderBottomWidth(),
         horizontalThickness, verticalThickness);
 }
 
@@ -2833,14 +2833,14 @@ IntRect RenderLayer::scrollCornerRect() const
     bool hasVerticalBar = m_vBar && !m_vBar->isOverlayScrollbar();
     bool hasResizer = renderer().style().resize() != RESIZE_NONE;
     if ((hasHorizontalBar && hasVerticalBar) || (hasResizer && (hasHorizontalBar || hasVerticalBar)))
-        return snappedIntRect(cornerRect(this, renderBox()->borderBoxRect()));
+        return snappedIntRect(cornerRect(*this, renderBox()->borderBoxRect()));
     return IntRect();
 }
 
-static LayoutRect resizerCornerRect(const RenderLayer* layer, const LayoutRect& bounds)
+static LayoutRect resizerCornerRect(const RenderLayer& layer, const LayoutRect& bounds)
 {
-    ASSERT(layer->renderer().isBox());
-    if (layer->renderer().style().resize() == RESIZE_NONE)
+    ASSERT(layer.renderer().isBox());
+    if (layer.renderer().style().resize() == RESIZE_NONE)
         return LayoutRect();
     return cornerRect(layer, bounds);
 }
@@ -2852,7 +2852,7 @@ LayoutRect RenderLayer::scrollCornerAndResizerRect() const
         return LayoutRect();
     LayoutRect scrollCornerAndResizer = scrollCornerRect();
     if (scrollCornerAndResizer.isEmpty())
-        scrollCornerAndResizer = resizerCornerRect(this, box->borderBoxRect());
+        scrollCornerAndResizer = resizerCornerRect(*this, box->borderBoxRect());
     return scrollCornerAndResizer;
 }
 
@@ -2996,7 +2996,7 @@ IntRect RenderLayer::rectForVerticalScrollbar(const IntRect& borderBoxRect) cons
 LayoutUnit RenderLayer::verticalScrollbarStart(int minX, int maxX) const
 {
     const RenderBox* box = renderBox();
-    if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLeft())
+    if (shouldPlaceBlockDirectionScrollbarOnLeft())
         return minX + box->borderLeft();
     return maxX - box->borderRight() - m_vBar->width();
 }
@@ -3005,8 +3005,8 @@ LayoutUnit RenderLayer::horizontalScrollbarStart(int minX) const
 {
     const RenderBox* box = renderBox();
     int x = minX + box->borderLeft();
-    if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLeft())
-        x += m_vBar ? m_vBar->width() : roundToInt(resizerCornerRect(this, box->borderBoxRect()).width());
+    if (shouldPlaceBlockDirectionScrollbarOnLeft())
+        x += m_vBar ? m_vBar->width() : roundToInt(resizerCornerRect(*this, box->borderBoxRect()).width());
     return x;
 }
 
@@ -3270,7 +3270,7 @@ IntSize RenderLayer::offsetFromResizeCorner(const IntPoint& absolutePoint) const
     // Currently the resize corner is either the bottom right corner or the bottom left corner.
     // FIXME: This assumes the location is 0, 0. Is this guaranteed to always be the case?
     IntSize elementSize = size();
-    if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLeft())
+    if (shouldPlaceBlockDirectionScrollbarOnLeft())
         elementSize.setWidth(0);
     IntPoint resizerPoint = IntPoint(elementSize);
     IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
@@ -3309,7 +3309,7 @@ void RenderLayer::positionOverflowControls(const IntSize& offsetFromRoot)
     if (m_scrollCorner)
         m_scrollCorner->setFrameRect(scrollCorner);
     if (m_resizer)
-        m_resizer->setFrameRect(resizerCornerRect(this, borderBox));
+        m_resizer->setFrameRect(resizerCornerRect(*this, borderBox));
 
     if (isComposited())
         backing()->positionOverflowControlsLayers();
@@ -3376,7 +3376,7 @@ void RenderLayer::computeScrollDimensions()
     m_scrollSize.setHeight(overflowBottom() - overflowTop());
 
     int scrollableLeftOverflow = overflowLeft() - box->borderLeft();
-    if (box->style().isLeftToRightDirection() && box->style().shouldPlaceBlockDirectionScrollbarOnLeft() && m_vBar)
+    if (box->style().isLeftToRightDirection() && box->shouldPlaceBlockDirectionScrollbarOnLeft() && m_vBar)
         scrollableLeftOverflow -= m_vBar->occupiedWidth();
     int scrollableTopOverflow = overflowTop() - box->borderTop();
     setScrollOrigin(IntPoint(-scrollableLeftOverflow, -scrollableTopOverflow));
@@ -3551,7 +3551,7 @@ bool RenderLayer::overflowControlsIntersectRect(const IntRect& localRect) const
     if (scrollCornerRect().intersects(localRect))
         return true;
     
-    if (resizerCornerRect(this, borderBox).intersects(localRect))
+    if (resizerCornerRect(*this, borderBox).intersects(localRect))
         return true;
 
     return false;
@@ -3670,7 +3670,7 @@ void RenderLayer::drawPlatformResizerImage(GraphicsContext& context, const Layou
         cornerResizerSize = resizeCornerImage->size();
     }
 
-    if (renderer().style().shouldPlaceBlockDirectionScrollbarOnLeft()) {
+    if (shouldPlaceBlockDirectionScrollbarOnLeft()) {
         context.save();
         context.translate(resizerCornerRect.x() + cornerResizerSize.width(), resizerCornerRect.y() + resizerCornerRect.height() - cornerResizerSize.height());
         context.scale(FloatSize(-1.0, 1.0));
@@ -3694,7 +3694,7 @@ void RenderLayer::paintResizer(GraphicsContext& context, const LayoutPoint& pain
     RenderBox* box = renderBox();
     ASSERT(box);
 
-    LayoutRect absRect = resizerCornerRect(this, box->borderBoxRect());
+    LayoutRect absRect = resizerCornerRect(*this, box->borderBoxRect());
     absRect.moveBy(paintOffset);
     if (!absRect.intersects(damageRect))
         return;
@@ -3736,7 +3736,7 @@ bool RenderLayer::isPointInResizeControl(const IntPoint& absolutePoint) const
     IntPoint localPoint = roundedIntPoint(absoluteToContents(absolutePoint));
 
     IntRect localBounds(IntPoint(), snappedIntRect(box->frameRect()).size());
-    return resizerCornerRect(this, localBounds).contains(localPoint);
+    return resizerCornerRect(*this, localBounds).contains(localPoint);
 }
 
 bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const IntPoint& localPoint)
@@ -3749,7 +3749,7 @@ bool RenderLayer::hitTestOverflowControls(HitTestResult& result, const IntPoint&
     
     IntRect resizeControlRect;
     if (renderer().style().resize() != RESIZE_NONE) {
-        resizeControlRect = snappedIntRect(resizerCornerRect(this, box->borderBoxRect()));
+        resizeControlRect = snappedIntRect(resizerCornerRect(*this, box->borderBoxRect()));
         if (resizeControlRect.contains(localPoint))
             return true;
     }
@@ -5228,7 +5228,7 @@ bool RenderLayer::hitTestResizerInFragments(const LayerFragments& layerFragments
 
     for (int i = layerFragments.size() - 1; i >= 0; --i) {
         const LayerFragment& fragment = layerFragments.at(i);
-        if (fragment.backgroundRect.intersects(hitTestLocation) && resizerCornerRect(this, snappedIntRect(fragment.layerBounds)).contains(hitTestLocation.roundedPoint()))
+        if (fragment.backgroundRect.intersects(hitTestLocation) && resizerCornerRect(*this, snappedIntRect(fragment.layerBounds)).contains(hitTestLocation.roundedPoint()))
             return true;
     }
     
index 13396bd..ae22c56 100644 (file)
@@ -671,6 +671,8 @@ public:
 
     RenderLayer* enclosingFlowThreadAncestor() const;
 
+    bool shouldPlaceBlockDirectionScrollbarOnLeft() const final { return renderer().shouldPlaceBlockDirectionScrollbarOnLeft(); }
+
 private:
     enum CollectLayersBehavior { StopAtStackingContexts, StopAtStackingContainers };
 
@@ -997,7 +999,6 @@ private:
 
     RenderNamedFlowFragment* currentRenderNamedFlowFragment() const;
 
-private:
     // The bitfields are up here so they will fall into the padding from ScrollableArea on 64-bit.
 
     const bool m_isRootLayer : 1;
index aa07202..c19bb2f 100644 (file)
@@ -1763,7 +1763,7 @@ FloatPoint RenderLayerCompositor::positionForClipLayer() const
     FrameView& frameView = m_renderView.frameView();
 
     return FloatPoint(
-        frameView.verticalScrollbarIsOnLeft() ? frameView.horizontalScrollbarIntrusion() : 0,
+        frameView.shouldPlaceBlockDirectionScrollbarOnLeft() ? frameView.horizontalScrollbarIntrusion() : 0,
         FrameView::yPositionForInsetClipLayer(frameView.scrollPosition(), frameView.topContentInset()));
 }
 
index bd9e65b..59eead4 100644 (file)
@@ -28,6 +28,7 @@
 #include "RenderLayer.h"
 #include "RenderLayerCompositor.h"
 #include "RenderView.h"
+#include "Settings.h"
 
 namespace WebCore {
 
@@ -212,5 +213,22 @@ void RenderLayerModelObject::styleDidChange(StyleDifference diff, const RenderSt
 #endif
 }
 
+bool RenderLayerModelObject::shouldPlaceBlockDirectionScrollbarOnLeft() const
+{
+// RTL Scrollbars require some system support, and this system support does not exist on certain versions of OS X. iOS uses a separate mechanism.
+#if PLATFORM(IOS) || (PLATFORM(MAC) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101200)
+    return false;
+#else
+    switch (frame().settings().userInterfaceDirectionPolicy()) {
+    case UserInterfaceDirectionPolicy::Content:
+        return style().shouldPlaceBlockDirectionScrollbarOnLeft();
+    case UserInterfaceDirectionPolicy::System:
+        return frame().settings().systemLayoutDirection() == RTL;
+    }
+    ASSERT_NOT_REACHED();
+    return style().shouldPlaceBlockDirectionScrollbarOnLeft();
+#endif
+}
+
 } // namespace WebCore
 
index 67ebc72..7f0a9be 100644 (file)
@@ -51,6 +51,8 @@ public:
 
     virtual bool isScrollableOrRubberbandableBox() const { return false; }
 
+    bool shouldPlaceBlockDirectionScrollbarOnLeft() const;
+
 protected:
     RenderLayerModelObject(Element&, RenderStyle&&, BaseTypeFlags);
     RenderLayerModelObject(Document&, RenderStyle&&, BaseTypeFlags);
index 8825773..5bb2fe6 100644 (file)
@@ -266,7 +266,7 @@ int RenderListBox::baselinePosition(FontBaseline baselineType, bool firstLine, L
 LayoutRect RenderListBox::itemBoundingBoxRect(const LayoutPoint& additionalOffset, int index)
 {
     LayoutUnit x = additionalOffset.x() + borderLeft() + paddingLeft();
-    if (verticalScrollbarIsOnLeft() && m_vBar)
+    if (shouldPlaceBlockDirectionScrollbarOnLeft() && m_vBar)
         x += m_vBar->occupiedWidth();
     LayoutUnit y = additionalOffset.y() + borderTop() + paddingTop() + itemHeight() * (index - m_indexOffset);
     return LayoutRect(x, y, contentWidth(), itemHeight());
@@ -345,7 +345,7 @@ void RenderListBox::paintScrollbar(PaintInfo& paintInfo, const LayoutPoint& pain
     if (!m_vBar)
         return;
 
-    LayoutUnit left = paintOffset.x() + (verticalScrollbarIsOnLeft() ? borderLeft() : width() - borderRight() - m_vBar->width());
+    LayoutUnit left = paintOffset.x() + (shouldPlaceBlockDirectionScrollbarOnLeft() ? borderLeft() : width() - borderRight() - m_vBar->width());
     LayoutUnit top = paintOffset.y() + borderTop();
     LayoutUnit width = m_vBar->width();
     LayoutUnit height = this->height() - (borderTop() + borderBottom());
@@ -448,7 +448,7 @@ bool RenderListBox::isPointInOverflowControl(HitTestResult& result, const Layout
     if (!m_vBar || !m_vBar->shouldParticipateInHitTesting())
         return false;
 
-    LayoutUnit x = accumulatedOffset.x() + (verticalScrollbarIsOnLeft() ? borderLeft() : width() - borderRight() - m_vBar->width());
+    LayoutUnit x = accumulatedOffset.x() + (shouldPlaceBlockDirectionScrollbarOnLeft() ? borderLeft() : width() - borderRight() - m_vBar->width());
     LayoutUnit y = accumulatedOffset.y() + borderTop();
     LayoutUnit width = m_vBar->width();
     LayoutUnit height = this->height() - borderTop() - borderBottom();
@@ -470,9 +470,9 @@ int RenderListBox::listIndexAtOffset(const LayoutSize& offset)
         return -1;
 
     int scrollbarWidth = m_vBar ? m_vBar->width() : 0;
-    if (verticalScrollbarIsOnLeft() && (offset.width() < borderLeft() + paddingLeft() + scrollbarWidth || offset.width() > width() - borderRight() - paddingRight()))
+    if (shouldPlaceBlockDirectionScrollbarOnLeft() && (offset.width() < borderLeft() + paddingLeft() + scrollbarWidth || offset.width() > width() - borderRight() - paddingRight()))
         return -1;
-    if (!verticalScrollbarIsOnLeft() && (offset.width() < borderLeft() + paddingLeft() || offset.width() > width() - borderRight() - paddingRight() - scrollbarWidth))
+    if (!shouldPlaceBlockDirectionScrollbarOnLeft() && (offset.width() < borderLeft() + paddingLeft() || offset.width() > width() - borderRight() - paddingRight() - scrollbarWidth))
         return -1;
 
     int newOffset = (offset.height() - borderTop() - paddingTop()) / itemHeight() + m_indexOffset;
@@ -729,7 +729,7 @@ LayoutRect RenderListBox::controlClipRect(const LayoutPoint& additionalOffset) c
     // Clip against the padding box, to give <option>s and overlay scrollbar some extra space
     // to get painted.
     LayoutRect clipRect = paddingBoxRect();
-    if (verticalScrollbarIsOnLeft() && (!layer() || !layer()->verticalScrollbarIsOnLeft()))
+    if (shouldPlaceBlockDirectionScrollbarOnLeft())
         clipRect.move(m_vBar->occupiedWidth(), 0);
     clipRect.moveBy(additionalOffset);
     return clipRect;
@@ -744,14 +744,14 @@ bool RenderListBox::isActive() const
 void RenderListBox::invalidateScrollbarRect(Scrollbar& scrollbar, const IntRect& rect)
 {
     IntRect scrollRect = rect;
-    scrollRect.move(verticalScrollbarIsOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width(), borderTop());
+    scrollRect.move(shouldPlaceBlockDirectionScrollbarOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width(), borderTop());
     repaintRectangle(scrollRect);
 }
 
 IntRect RenderListBox::convertFromScrollbarToContainingView(const Scrollbar& scrollbar, const IntRect& scrollbarRect) const
 {
     IntRect rect = scrollbarRect;
-    int scrollbarLeft = verticalScrollbarIsOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width();
+    int scrollbarLeft = shouldPlaceBlockDirectionScrollbarOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width();
     int scrollbarTop = borderTop();
     rect.move(scrollbarLeft, scrollbarTop);
     return view().frameView().convertFromRendererToContainingView(this, rect);
@@ -760,7 +760,7 @@ IntRect RenderListBox::convertFromScrollbarToContainingView(const Scrollbar& scr
 IntRect RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar& scrollbar, const IntRect& parentRect) const
 {
     IntRect rect = view().frameView().convertFromContainingViewToRenderer(this, parentRect);
-    int scrollbarLeft = verticalScrollbarIsOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width();
+    int scrollbarLeft = shouldPlaceBlockDirectionScrollbarOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width();
     int scrollbarTop = borderTop();
     rect.move(-scrollbarLeft, -scrollbarTop);
     return rect;
@@ -769,7 +769,7 @@ IntRect RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar& scr
 IntPoint RenderListBox::convertFromScrollbarToContainingView(const Scrollbar& scrollbar, const IntPoint& scrollbarPoint) const
 {
     IntPoint point = scrollbarPoint;
-    int scrollbarLeft = verticalScrollbarIsOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width();
+    int scrollbarLeft = shouldPlaceBlockDirectionScrollbarOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width();
     int scrollbarTop = borderTop();
     point.move(scrollbarLeft, scrollbarTop);
     return view().frameView().convertFromRendererToContainingView(this, point);
@@ -778,7 +778,7 @@ IntPoint RenderListBox::convertFromScrollbarToContainingView(const Scrollbar& sc
 IntPoint RenderListBox::convertFromContainingViewToScrollbar(const Scrollbar& scrollbar, const IntPoint& parentPoint) const
 {
     IntPoint point = view().frameView().convertFromContainingViewToRenderer(this, parentPoint);
-    int scrollbarLeft = verticalScrollbarIsOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width();
+    int scrollbarLeft = shouldPlaceBlockDirectionScrollbarOnLeft() ? borderLeft() : width() - borderRight() - scrollbar.width();
     int scrollbarTop = borderTop();
     point.move(-scrollbarLeft, -scrollbarTop);
     return point;
index 9daa8d6..ec767f3 100644 (file)
@@ -156,6 +156,8 @@ private:
     void paintItemBackground(PaintInfo&, const LayoutPoint&, int listIndex);
     void scrollToRevealSelection();
 
+    bool shouldPlaceBlockDirectionScrollbarOnLeft() const final { return RenderBlockFlow::shouldPlaceBlockDirectionScrollbarOnLeft(); }
+
     bool m_optionsChanged;
     bool m_scrollToRevealSelectionAfterLayout;
     bool m_inAutoscroll;
index 021e310..490e63a 100644 (file)
@@ -642,7 +642,7 @@ void RenderView::repaintViewRectangle(const LayoutRect& repaintRect) const
         // and the Renderer that contains the iframe. This transformation must account for a
         // left scrollbar (if one exists).
         FrameView& frameView = this->frameView();
-        if (frameView.verticalScrollbarIsOnLeft() && frameView.verticalScrollbar())
+        if (frameView.shouldPlaceBlockDirectionScrollbarOnLeft() && frameView.verticalScrollbar())
             adjustedRect.move(LayoutSize(frameView.verticalScrollbar()->occupiedWidth(), 0));
 
         ownerBox->repaintRectangle(adjustedRect);
index 03d2152..c406dba 100644 (file)
@@ -2077,13 +2077,7 @@ float RenderStyle::outlineOffset() const
 
 bool RenderStyle::shouldPlaceBlockDirectionScrollbarOnLeft() const
 {
-#if PLATFORM(MAC)
-    return ScrollableArea::systemLanguageIsRTL();
-#elif USE(RTL_SCROLLBAR)
     return !isLeftToRightDirection() && isHorizontalWritingMode();
-#else
-    return false;
-#endif
 }
 
 } // namespace WebCore
index fc435a7..5124fe7 100644 (file)
@@ -106,6 +106,8 @@ InternalSettings::Backup::Backup(Settings& settings)
 #if ENABLE(INDEXED_DATABASE_IN_WORKERS)
     , m_indexedDBWorkersEnabled(RuntimeEnabledFeatures::sharedFeatures().indexedDBWorkersEnabled())
 #endif
+    , m_userInterfaceDirectionPolicy(settings.userInterfaceDirectionPolicy())
+    , m_systemLayoutDirection(settings.systemLayoutDirection())
 {
 }
 
@@ -176,6 +178,8 @@ void InternalSettings::Backup::restoreTo(Settings& settings)
 #if ENABLE(INDEXED_DATABASE_IN_WORKERS)
     RuntimeEnabledFeatures::sharedFeatures().setIndexedDBWorkersEnabled(m_indexedDBWorkersEnabled);
 #endif
+    settings.setUserInterfaceDirectionPolicy(m_userInterfaceDirectionPolicy);
+    settings.setSystemLayoutDirection(m_systemLayoutDirection);
 }
 
 class InternalSettingsWrapper : public Supplement<Page> {
@@ -555,6 +559,59 @@ void InternalSettings::setIndexedDBWorkersEnabled(bool enabled, ExceptionCode&)
 #endif
 }
 
+String InternalSettings::userInterfaceDirectionPolicy(ExceptionCode& ec)
+{
+    InternalSettingsGuardForSettingsReturn("");
+    switch (settings()->userInterfaceDirectionPolicy()) {
+    case UserInterfaceDirectionPolicy::Content:
+        return ASCIILiteral("Content");
+    case UserInterfaceDirectionPolicy::System:
+        return ASCIILiteral("View");
+    }
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+void InternalSettings::setUserInterfaceDirectionPolicy(const String& policy, ExceptionCode& ec)
+{
+    InternalSettingsGuardForSettings();
+    if (equalLettersIgnoringASCIICase(policy, "content")) {
+        settings()->setUserInterfaceDirectionPolicy(UserInterfaceDirectionPolicy::Content);
+        return;
+    }
+    if (equalLettersIgnoringASCIICase(policy, "view")) {
+        settings()->setUserInterfaceDirectionPolicy(UserInterfaceDirectionPolicy::System);
+        return;
+    }
+    ec = INVALID_ACCESS_ERR;
+}
+
+String InternalSettings::systemLayoutDirection(ExceptionCode& ec)
+{
+    InternalSettingsGuardForSettingsReturn("");
+    switch (settings()->systemLayoutDirection()) {
+    case LTR:
+        return ASCIILiteral("LTR");
+    case RTL:
+        return ASCIILiteral("RTL");
+    }
+    ASSERT_NOT_REACHED();
+    return String();
+}
+
+void InternalSettings::setSystemLayoutDirection(const String& direction, ExceptionCode& ec)
+{
+    InternalSettingsGuardForSettings();
+    if (equalLettersIgnoringASCIICase(direction, "ltr")) {
+        settings()->setSystemLayoutDirection(LTR);
+        return;
+    }
+    if (equalLettersIgnoringASCIICase(direction, "rtl")) {
+        settings()->setSystemLayoutDirection(RTL);
+        return;
+    }
+    ec = INVALID_ACCESS_ERR;
+}
 
 // If you add to this list, make sure that you update the Backup class for test reproducability!
 
index b0f08f2..a59e6c8 100644 (file)
@@ -34,6 +34,8 @@
 #include "IntSize.h"
 #include "InternalSettingsGenerated.h"
 #include "SecurityOrigin.h"
+#include "Settings.h"
+#include "WritingMode.h"
 
 namespace WebCore {
 
@@ -102,6 +104,8 @@ public:
 #if ENABLE(INDEXED_DATABASE_IN_WORKERS)
         bool m_indexedDBWorkersEnabled;
 #endif
+        UserInterfaceDirectionPolicy m_userInterfaceDirectionPolicy;
+        TextDirection m_systemLayoutDirection;
     };
 
     static Ref<InternalSettings> create(Page* page)
@@ -150,6 +154,10 @@ public:
     void setAllowsInlineMediaPlayback(bool, ExceptionCode&);
     void setInlineMediaPlaybackRequiresPlaysInlineAttribute(bool, ExceptionCode&);
     void setIndexedDBWorkersEnabled(bool, ExceptionCode&);
+    String userInterfaceDirectionPolicy(ExceptionCode&);
+    void setUserInterfaceDirectionPolicy(const String& policy, ExceptionCode&);
+    String systemLayoutDirection(ExceptionCode&);
+    void setSystemLayoutDirection(const String& direction, ExceptionCode&);
 
 private:
     explicit InternalSettings(Page*);
index e39e741..86b4140 100644 (file)
     [RaisesException] void setInlineMediaPlaybackRequiresPlaysInlineAttribute(boolean requires);
 
     [RaisesException] void setIndexedDBWorkersEnabled(boolean requires);
+
+    [RaisesException] DOMString userInterfaceDirectionPolicy();
+    [RaisesException] void setUserInterfaceDirectionPolicy(DOMString policy);
+    [RaisesException] DOMString systemLayoutDirection();
+    [RaisesException] void setSystemLayoutDirection(DOMString direction);
 };
 
index f960f46..683bfba 100644 (file)
@@ -1,3 +1,27 @@
+2016-04-26  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        [WK2] [OS X] Create API for switching RTL scrollbar policy
+        https://bugs.webkit.org/show_bug.cgi?id=156948
+        <rdar://problem/25707757>
+
+        Reviewed by Darin Adler.
+
+        Add the new API.
+
+        * Shared/WebPreferencesDefinitions.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _initializeWithConfiguration:]):
+        * UIProcess/API/Cocoa/WKWebViewConfiguration.h:
+        * UIProcess/API/Cocoa/WKWebViewConfiguration.mm:
+        (-[WKWebViewConfiguration init]):
+        (-[WKWebViewConfiguration encodeWithCoder:]):
+        (-[WKWebViewConfiguration initWithCoder:]):
+        (-[WKWebViewConfiguration copyWithZone:]):
+        * UIProcess/WebPageProxy.cpp:
+        * WebProcess/Plugins/PDF/DeprecatedPDFPlugin.h:
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::updatePreferences):
+
 2016-04-26  Beth Dakin  <bdakin@apple.com>
 
         Check to make sure shouldRequestCandidates() before requesting candidates
index e480c1e..2a5986e 100644 (file)
     macro(StorageBlockingPolicy, storageBlockingPolicy, UInt32, uint32_t, WebCore::SecurityOrigin::BlockThirdPartyStorage, "", "") \
     macro(JavaScriptRuntimeFlags, javaScriptRuntimeFlags, UInt32, uint32_t, 0, "", "") \
     macro(DataDetectorTypes, dataDetectorTypes, UInt32, uint32_t, 0, "", "") \
+    macro(UserInterfaceDirection, userInterfaceDirection, UInt32, uint32_t, 0, "", "") \
+    macro(SystemLayoutDirection, systemLayoutDirection, UInt32, uint32_t, 0, "", "") \
     \
 
 #define FOR_EACH_WEBKIT_DEBUG_BOOL_PREFERENCE(macro) \
index 0ed753e..f2c2535 100644 (file)
@@ -87,6 +87,8 @@
 #import <WebCore/NSTextFinderSPI.h>
 #import <WebCore/PlatformScreen.h>
 #import <WebCore/RuntimeApplicationChecks.h>
+#import <WebCore/Settings.h>
+#import <WebCore/WritingMode.h>
 #import <wtf/HashMap.h>
 #import <wtf/MathExtras.h>
 #import <wtf/NeverDestroyed.h>
@@ -359,6 +361,30 @@ static WebCore::DataDetectorTypes fromWKDataDetectorTypes(uint64_t types)
 }
 #endif
 
+static uint32_t convertUserInterfaceDirectionPolicy(WKUserInterfaceDirectionPolicy policy)
+{
+    switch (policy) {
+    case WKUserInterfaceDirectionPolicyContent:
+        return static_cast<uint32_t>(WebCore::UserInterfaceDirectionPolicy::Content);
+    case WKUserInterfaceDirectionPolicySystem:
+        return static_cast<uint32_t>(WebCore::UserInterfaceDirectionPolicy::System);
+    }
+    return static_cast<uint32_t>(WebCore::UserInterfaceDirectionPolicy::Content);
+}
+
+#if PLATFORM(MAC)
+static uint32_t convertSystemLayoutDirection(NSUserInterfaceLayoutDirection direction)
+{
+    switch (direction) {
+    case NSUserInterfaceLayoutDirectionLeftToRight:
+        return static_cast<uint32_t>(WebCore::LTR);
+    case NSUserInterfaceLayoutDirectionRightToLeft:
+        return static_cast<uint32_t>(WebCore::RTL);
+    }
+    return static_cast<uint32_t>(WebCore::LTR);
+}
+#endif
+
 - (void)_initializeWithConfiguration:(WKWebViewConfiguration *)configuration
 {
     if (!configuration)
@@ -408,11 +434,17 @@ static WebCore::DataDetectorTypes fromWKDataDetectorTypes(uint64_t types)
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::shouldConvertPositionStyleOnCopyKey(), WebKit::WebPreferencesStore::Value(!![_configuration _convertsPositionStyleOnCopy]));
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::httpEquivEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowsMetaRefresh]));
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowUniversalAccessFromFileURLsKey(), WebKit::WebPreferencesStore::Value(!![_configuration _allowUniversalAccessFromFileURLs]));
+
+    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::userInterfaceDirectionKey(), WebKit::WebPreferencesStore::Value(convertUserInterfaceDirectionPolicy([_configuration userInterfaceDirectionPolicy])));
     
 #if PLATFORM(MAC)
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::showsURLsInToolTipsEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _showsURLsInToolTips]));
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::serviceControlsEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _serviceControlsEnabled]));
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::imageControlsEnabledKey(), WebKit::WebPreferencesStore::Value(!![_configuration _imageControlsEnabled]));
+    // We are in the View's initialization routine, so our client hasn't had time to set our user interface direction.
+    // Therefore, according to the docs[1], "this property contains the value reported by the app’s userInterfaceLayoutDirection property."
+    // [1] http://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Classes/NSView_Class/index.html#//apple_ref/doc/uid/20000014-SW222
+    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::systemLayoutDirectionKey(), WebKit::WebPreferencesStore::Value(convertSystemLayoutDirection(self.userInterfaceLayoutDirection)));
 #endif
 
 #if PLATFORM(IOS)
@@ -422,6 +454,7 @@ static WebCore::DataDetectorTypes fromWKDataDetectorTypes(uint64_t types)
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::inlineMediaPlaybackRequiresPlaysInlineAttributeKey(), WebKit::WebPreferencesStore::Value(!![_configuration _inlineMediaPlaybackRequiresPlaysInlineAttribute]));
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::allowsPictureInPictureMediaPlaybackKey(), WebKit::WebPreferencesStore::Value(!![_configuration allowsPictureInPictureMediaPlayback] && shouldAllowPictureInPictureMediaPlayback()));
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::requiresUserGestureForMediaPlaybackKey(), WebKit::WebPreferencesStore::Value(!![_configuration requiresUserActionForMediaPlayback]));
+    pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::systemLayoutDirectionKey(), WebKit::WebPreferencesStore::Value(static_cast<uint32_t>(WebCore::LTR)));
 #endif
 
     pageConfiguration->preferenceValues().set(WebKit::WebPreferencesKey::requiresUserGestureForVideoPlaybackKey(), WebKit::WebPreferencesStore::Value(!![_configuration _requiresUserActionForVideoPlayback]));
index 66d653f..25f414d 100644 (file)
@@ -73,6 +73,20 @@ typedef NS_OPTIONS(NSUInteger, WKDataDetectorTypes) {
     WKDataDetectorTypeAll = NSUIntegerMax
 } WK_ENUM_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
 
+
+/*! @enum WKUserInterfaceDirectionPolicy
+ @abstract The mechanism by which vertical scrollbars obey an RTL environment
+ @constant WKUserInterfaceDirectionPolicyContent Scrollbar placement obeys CSS / HTML / XHTML specifications.
+ @constant WKUserInterfaceDirectionPolicySystem Scrollbar placement obeys system platform specifications.
+ @discussion When WKUserInterfaceDirectionPolicyContent is specified, the placement of vertical scrollbars is
+ affected by the "dir" element or the "direction" CSS property. When WKUserInterfaceDirectionPolicySystem is
+ specified, the placement of vertical scrollbars is affected by the direction of the view.
+*/
+typedef NS_ENUM(NSInteger, WKUserInterfaceDirectionPolicy) {
+    WKUserInterfaceDirectionPolicyContent = 0,
+    WKUserInterfaceDirectionPolicySystem = 1,
+} WK_ENUM_AVAILABLE(WK_MAC_TBA, NA);
+
 /*! A WKWebViewConfiguration object is a collection of properties with
  which to initialize a web view.
  @helps Contains properties used to configure a @link WKWebView @/link.
@@ -124,6 +138,12 @@ WK_CLASS_AVAILABLE(10_10, 8_0)
  */
 @property (nonatomic) WKDataDetectorTypes dataDetectorTypes WK_AVAILABLE(WK_MAC_TBA, WK_IOS_TBA);
 
+/*! @abstract The placement behavior of vertical scrollbars.
+ @discussion Possible values are described in WKUserInterfaceDirectionPolicy.
+ The default value is WKUserInterfaceDirectionPolicyContent.
+ */
+@property (nonatomic) WKUserInterfaceDirectionPolicy userInterfaceDirectionPolicy WK_AVAILABLE(WK_MAC_TBA, NA);
+
 #if TARGET_OS_IPHONE
 /*! @abstract A Boolean value indicating whether HTML5 videos play inline
  (YES) or use the native full-screen controller (NO).
index 7b281d9..2b1fe1b 100644 (file)
@@ -140,6 +140,7 @@ private:
     _mediaDataLoadsAutomatically = NO;
 #else
     _mediaDataLoadsAutomatically = YES;
+    _userInterfaceDirectionPolicy = WKUserInterfaceDirectionPolicyContent;
 #endif
     _requiresUserActionForVideoPlayback = NO;
     _requiresUserActionForAudioPlayback = NO;
@@ -198,6 +199,7 @@ private:
     [coder encodeObject:self.applicationNameForUserAgent forKey:@"applicationNameForUserAgent"];
     [coder encodeBool:self.allowsAirPlayForMediaPlayback forKey:@"allowsAirPlayForMediaPlayback"];
     [coder encodeInteger:self.dataDetectorTypes forKey:@"dataDetectorTypes"];
+    [coder encodeInteger:self.userInterfaceDirectionPolicy forKey:@"userInterfaceDirectionPolicy"];
 
 #if PLATFORM(IOS)
     [coder encodeBool:self.allowsInlineMediaPlayback forKey:@"allowsInlineMediaPlayback"];
@@ -221,6 +223,9 @@ private:
     self.applicationNameForUserAgent = [coder decodeObjectForKey:@"applicationNameForUserAgent"];
     self.allowsAirPlayForMediaPlayback = [coder decodeBoolForKey:@"allowsAirPlayForMediaPlayback"];
     self.dataDetectorTypes = [coder decodeIntegerForKey:@"dataDetectorTypes"];
+    auto userInterfaceDirectionPolicyCandidate = static_cast<WKUserInterfaceDirectionPolicy>([coder decodeIntegerForKey:@"userInterfaceDirectionPolicy"]);
+    if (userInterfaceDirectionPolicyCandidate == WKUserInterfaceDirectionPolicyContent || userInterfaceDirectionPolicyCandidate == WKUserInterfaceDirectionPolicySystem)
+        self.userInterfaceDirectionPolicy = userInterfaceDirectionPolicyCandidate;
 
 #if PLATFORM(IOS)
     self.allowsInlineMediaPlayback = [coder decodeBoolForKey:@"allowsInlineMediaPlayback"];
@@ -266,6 +271,8 @@ private:
     configuration->_requiresUserActionForAudioPlayback = self->_requiresUserActionForAudioPlayback;
     configuration->_mainContentUserGestureOverrideEnabled = self->_mainContentUserGestureOverrideEnabled;
 
+    configuration->_userInterfaceDirectionPolicy = self->_userInterfaceDirectionPolicy;
+
 #if PLATFORM(IOS)
     configuration->_allowsInlineMediaPlayback = self->_allowsInlineMediaPlayback;
     configuration->_inlineMediaPlaybackRequiresPlaysInlineAttribute = self->_inlineMediaPlaybackRequiresPlaysInlineAttribute;
index 7fbc173..c297306 100644 (file)
 #include "WebPopupItem.h"
 #include "WebPopupMenuProxy.h"
 #include "WebPreferences.h"
+#include "WebPreferencesKeys.h"
 #include "WebProcessMessages.h"
 #include "WebProcessPool.h"
 #include "WebProcessProxy.h"
index 78eee9d..1bf1bfb 100644 (file)
@@ -111,6 +111,8 @@ public:
 
     CGFloat scaleFactor() const;
 
+    bool shouldPlaceBlockDirectionScrollbarOnLeft() const override { return false; }
+
 private:
     explicit PDFPlugin(WebFrame*);
 
index c7e00ab..fecb54c 100644 (file)
@@ -3072,6 +3072,13 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
 
     settings.setShouldDispatchJavaScriptWindowOnErrorEvents(true);
 
+    auto userInterfaceDirectionCandidate = static_cast<WebCore::UserInterfaceDirectionPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::userInterfaceDirectionKey()));
+    if (userInterfaceDirectionCandidate == WebCore::UserInterfaceDirectionPolicy::Content || userInterfaceDirectionCandidate == WebCore::UserInterfaceDirectionPolicy::System)
+        settings.setUserInterfaceDirectionPolicy(!store.getUInt32ValueForKey(WebPreferencesKey::userInterfaceDirectionKey()) ? UserInterfaceDirectionPolicy::Content : UserInterfaceDirectionPolicy::System);
+    TextDirection systemLayoutDirectionCandidate = static_cast<TextDirection>(store.getUInt32ValueForKey(WebPreferencesKey::systemLayoutDirectionKey()));
+    if (systemLayoutDirectionCandidate == WebCore::LTR || systemLayoutDirectionCandidate == WebCore::RTL)
+        settings.setSystemLayoutDirection(systemLayoutDirectionCandidate);
+
 #if USE(APPLE_INTERNAL_SDK)
 #include <WebKitAdditions/WebPagePreferences.cpp>
 #endif
index d8dd2e6..9ba581a 100644 (file)
 
 namespace WTR {
 
-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;
@@ -95,13 +83,6 @@ void InjectedBundle::platformInitialize(WKTypeRef initializationUserData)
         @"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 fcad8cd..3a432b3 100644 (file)
@@ -953,8 +953,6 @@ 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);
         if (key == "useMockScrollbars")
             testOptions.useMockScrollbars = parseBooleanTestHeaderValue(value);
         pairStart = pairEnd + 1;
@@ -1480,13 +1478,6 @@ WKRetainPtr<WKTypeRef> TestController::didReceiveSynchronousMessageFromInjectedB
 
 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;
 }
 
index 28aa9e0..5258e28 100644 (file)
@@ -40,7 +40,6 @@ struct TestOptions {
     bool isSVGTest { false };
     bool isHiDPITest { false };
     bool useDataDetection { false };
-    bool useRTLScrollbars { false };
     bool useMockScrollbars { true };
 
     Vector<String> overrideLanguages;
index 99df24b..f6e8d4c 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 || m_options.useRTLScrollbars != options.useRTLScrollbars || m_options.useMockScrollbars != options.useMockScrollbars)
+    if (m_options.useThreadedScrolling != options.useThreadedScrolling || m_options.overrideLanguages != options.overrideLanguages || m_options.useMockScrollbars != options.useMockScrollbars)
         return false;
 
     return true;