commit | ea3211f440adba72ec2b260721da115c3e9505ad | [log] [tgz] |
---|---|---|
author | wenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc> | Wed May 01 21:08:38 2019 +0000 |
committer | wenson_hsieh@apple.com <wenson_hsieh@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc> | Wed May 01 21:08:38 2019 +0000 |
tree | a151623a6587d63fde63a9c7d94b72fde4b17c84 | |
parent | bad0528e9004197d2f5d3802a7c697d5f03c2f56 [diff] |
[iOS] Add a version of viewport shrink-to-fit heuristics that preserves page layout https://bugs.webkit.org/show_bug.cgi?id=197342 <rdar://problem/50063091> Reviewed by Tim Horton. Source/WebCore: Adds support for a new shrink-to-fit heuristic that attempts to lay out the contents of the page at a larger width in order to shrink content to fit the viewport. See WebKit ChangeLog for more details. Tests: fast/viewport/ios/shrink-to-fit-content-constant-width.html fast/viewport/ios/shrink-to-fit-content-large-width-breakpoint.html fast/viewport/ios/shrink-to-fit-content-no-viewport.html fast/viewport/ios/shrink-to-fit-content-responsive-viewport-with-horizontal-overflow.html fast/viewport/ios/shrink-to-fit-content-temporary-overflow.html * page/ViewportConfiguration.cpp: (WebCore::ViewportConfiguration::setMinimumEffectiveDeviceWidth): (WebCore::ViewportConfiguration::setIsKnownToLayOutWiderThanViewport): (WebCore::ViewportConfiguration::description const): * page/ViewportConfiguration.h: (WebCore::ViewportConfiguration::canIgnoreScalingConstraints const): (WebCore::ViewportConfiguration::minimumEffectiveDeviceWidth const): Add several new getters and setters in ViewportConfiguration. (WebCore::ViewportConfiguration::isKnownToLayOutWiderThanViewport const): (WebCore::ViewportConfiguration::shouldIgnoreMinimumEffectiveDeviceWidth const): Importantly, only allow ignoring the minimum effective device width in webpages with responsive viewports, if they also have *not* laid out wider than the viewport. (WebCore::ViewportConfiguration::setForceAlwaysUserScalable): Source/WebKit: This patch introduces a new shrink-to-fit heuristic that attempts to lay out the contents of the page at a larger width in order to shrink content to fit the viewport. This is similar to existing shrink-to-fit behaviors used for viewport sizing in multitasking mode, except that it not only scales the view, but additionally expands the layout size, such that the overall layout of the page is preserved. In fact, the reason we ended up reverting the existing flavor of shrink-to-fit in all cases except for multitasking was that page layout was not preserved, which caused elements that poke out of the viewport to make the rest of the page look out of proportion — see <rdar://problem/23818102> and related radars. Covered by 5 new layout tests, and by adjusting a couple of existing layout tests. See comments below for more details. * Platform/Logging.h: Add a new ViewportSizing logging channel. This will only log on pages that overflow the viewport and shrink to fit as a result. * Shared/WebPreferences.yaml: Turn IgnoreViewportScalingConstraints off by default. This preference currently controls whether we allow shrink-to-fit behaviors, and is only used by Safari when it is in multitasking mode. The value of this preference is currenly *on* by default, and is turned off almost immediately during every page load after the first visible content rect update, wherein visibleContentRectUpdateInfo.allowShrinkToFit() is false. However, this sometimes causes a brief jitter during page load; to fix this, make the default value for IgnoreViewportScalingConstraints false, and change the logic in WebPage::updateVisibleContentRects to setCanIgnoreScalingConstraints to true if either the IgnoreViewportScalingConstraints preference (not only affected by an internal debug switch) is true, or WKWebView SPI is used to enable the behavior. * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp: (WebKit::WebFrameLoaderClient::dispatchDidFinishDocumentLoad): (WebKit::WebFrameLoaderClient::dispatchDidFinishLoad): Add a new hook for WebFrameLoaderClient to call into WebPage when document load finishes. Also, tweak dispatchDidFinishLoad to take a WebFrame& instead of a WebFrame* in a drive-by fix (the frame is assumed to be non-null anyways). * WebProcess/WebPage/WebPage.cpp: (WebKit::WebPage::didCommitLoad): (WebKit::WebPage::didFinishDocumentLoad): (WebKit::WebPage::didFinishLoad): When finishing document load or finishing the overall load, kick off the shrink-to-fit timer; when committing a load, cancel the timer. * WebProcess/WebPage/WebPage.h: * WebProcess/WebPage/ios/WebPageIOS.mm: (WebKit::WebPage::setViewportConfigurationViewLayoutSize): Don't allow the minimum effective device width from the client to stomp over any minimum effective device width set as a result of the new shrink-to-fit heuristic; on some pages that load quickly, this can result in a race where the minimum effective device width (i.e. a value that lower-bounds the minimum layout width) is first set by the shrink-to-fit heuristic, and then set to an incorrect value by the client. In the near future, web view SPI used to set the minimum effective device width should actually be removed altogether, since the new shrink-to-fit heuristic supersedes any need for the client to fiddle with the minimum effective device width. (WebKit::WebPage::dynamicViewportSizeUpdate): When performing a dynamic viewport size update, additionally re-run the shrink-to-fit heuristic. This allows the minimum layout size of the viewport to be updated, if necessary. An example of where this matters is when a web page is *below* a tablet/desktop layout breakpoint in portrait device orientation, but then exceeds this layout breakpoint in landscape orientation. In this scenario, rotating the device should swap between these two page layouts. (WebKit::WebPage::resetViewportDefaultConfiguration): (WebKit::WebPage::scheduleShrinkToFitContent): (WebKit::WebPage::shrinkToFitContentTimerFired): (WebKit::WebPage::immediatelyShrinkToFitContent): Leverage the existing capability for a viewport to have a "minimum effective device width" to grant the viewport a larger layout size than it would normally have, and then scale down to fit within the bounds of the view. One challenge with this overall approach is that laying out at a larger width may cause the page to lay out even wider in response, which may actually worsen horizontal scrolling. To mitigate this, we only attempt to lay out at the current content width once; if laying out at this width reduced the amount of horizontal scrolling by any amount, then proceed with this layout width; otherwise, revert to the previous layout width. (WebKit::WebPage::shouldIgnoreMetaViewport const): Pull some common logic out into a readonly getter. (WebKit::WebPage::updateVisibleContentRects): See the comment below WebPreferences.yaml, above. LayoutTests: Introduces new layout tests, and adjusts some existing tests. See comments below. * fast/viewport/ios/shrink-to-fit-content-constant-width-expected.txt: Added. * fast/viewport/ios/shrink-to-fit-content-constant-width.html: Added. Add a new layout test to exercise the scenario where a constant width viewport narrower than the view is used. * fast/viewport/ios/shrink-to-fit-content-large-width-breakpoint-expected.txt: Added. * fast/viewport/ios/shrink-to-fit-content-large-width-breakpoint.html: Added. Add a new layout test to exercise the scenario where a responsive website that lays out larger than the view width ends up with even more horizontal scrolling when laying out at the initial content width. In this scenario, we shouldn't try to expand the viewport to try and encompass the content width, since that would only induce even worse horizontal scrolling. * fast/viewport/ios/shrink-to-fit-content-no-viewport-expected.txt: Added. * fast/viewport/ios/shrink-to-fit-content-no-viewport.html: Added. Add a new layout test for the case where there is no viewport, but content lays out wider than the view. * fast/viewport/ios/shrink-to-fit-content-responsive-viewport-with-horizontal-overflow-expected.txt: Added. * fast/viewport/ios/shrink-to-fit-content-responsive-viewport-with-horizontal-overflow.html: Added. Add a new layout test for the case where the page has opted for a responsive viewport (device-width, initial scale 1), but has laid out wider than the viewport anyways. In this case, we want to shrink the contents down to fit inside the view. * fast/viewport/ios/shrink-to-fit-content-temporary-overflow-expected.txt: Added. * fast/viewport/ios/shrink-to-fit-content-temporary-overflow.html: Added. Add a new layout test to exercise the case where, during page load, content width temporarily increases, and then decreases such that it once again fits within the viewport. In this case, we don't want to expand the viewport to be as wide as the large temporary width of the page. * fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-expected.txt: * fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden.html: * fast/viewport/ios/width-is-device-width-overflowing-expected.txt: * fast/viewport/ios/width-is-device-width-overflowing.html: Tweak these 2 existing layout tests to include "shrink-to-fit=no", to prevent the new heuristics from shrinking the page to fit on device classes that use native viewports by default. * platform/ipad/fast/viewport/ios/width-is-device-width-overflowing-body-overflow-hidden-expected.txt: * platform/ipad/fast/viewport/ios/width-is-device-width-overflowing-expected.txt: git-svn-id: http://svn.webkit.org/repository/webkit/trunk@244849 268f45cc-cd09-0410-ab3c-d52691b4dbfc
WebKit is a cross-platform web browser engine. On iOS and macOS, it powers Safari, Mail, iBooks, and many other applications.
Visit WebKit Feature Status page to see which Web API has been implemented, in development, or under consideration.
On macOS, download Safari Technology Preview to test the latest version of WebKit. On Linux, download Epiphany Technology Preview. On Windows, you'll have to build it yourself.
Once your bug is filed, you will receive email when it is updated at each stage in the bug life cycle. After the bug is considered fixed, you may be asked to download the latest nightly and confirm that the fix works for you.
On Windows, follow the instructions on our website.
Run the following command to clone WebKit's Git SVN repository:
git clone git://git.webkit.org/WebKit.git WebKit
or
git clone https://git.webkit.org/git/WebKit.git WebKit
If you want to be able to commit changes to the repository, or just want to check out branches that aren’t contained in WebKit.git, you will need track WebKit's Subversion repository. You can run the following command to configure this and other options of the new Git clone for WebKit development.
Tools/Scripts/webkit-patch setup-git-clone
For information about this, and other aspects of using Git with WebKit, read the wiki page.
If you don‘t want to use Git, run the following command to check out WebKit’s Subversion repository:
svn checkout https://svn.webkit.org/repository/webkit/trunk WebKit
Install Xcode and its command line tools if you haven't done so already:
xcode-select --install
Run the following command to build a debug build with debugging symbols and assertions:
Tools/Scripts/build-webkit --debug
For performance testing, and other purposes, use --release
instead.
You can open WebKit.xcworkspace
to build and debug WebKit within Xcode.
If you don't use a custom build location in Xcode preferences, you have to update the workspace settings to use WebKitBuild
directory. In menu bar, choose File > Workspace Settings, then click the Advanced button, select “Custom”, “Relative to Workspace”, and enter WebKitBuild
for both Products and Intermediates.
The first time after you install a new Xcode, you will need to run the following command to enable Xcode to build command line tools for iOS Simulator:
sudo Tools/Scripts/configure-xcode-for-ios-development
Without this step, you will see the error message: “target specifies product type ‘com.apple.product-type.tool’, but there’s no such product type for the ‘iphonesimulator’ platform.
” when building target JSCLLIntOffsetsExtractor
of project JavaScriptCore
.
Run the following command to build a debug build with debugging symbols and assertions for iOS:
Tools/Scripts/build-webkit --debug --ios-simulator
For production builds:
cmake -DPORT=GTK -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja ninja sudo ninja install
For development builds:
Tools/gtk/install-dependencies Tools/Scripts/update-webkitgtk-libs Tools/Scripts/build-webkit --gtk --debug
For more information on building WebKitGTK+, see the wiki page.
For production builds:
cmake -DPORT=WPE -DCMAKE_BUILD_TYPE=RelWithDebInfo -GNinja ninja sudo ninja install
For development builds:
Tools/wpe/install-dependencies Tools/Scripts/update-webkitwpe-libs Tools/Scripts/build-webkit --wpe --debug
For building WebKit on Windows, see the wiki page.
Run the following command to launch Safari with your local build of WebKit:
Tools/Scripts/run-safari --debug
The run-safari
script sets the DYLD_FRAMEWORK_PATH
environment variable to point to your build products, and then launches /Applications/Safari.app
. DYLD_FRAMEWORK_PATH
tells the system loader to prefer your build products over the frameworks installed in /System/Library/Frameworks
.
To run other applications with your local build of WebKit, run the following command:
Tools/Scripts/run-webkit-app <application-path>
Run the following command to launch iOS simulator with your local build of WebKit:
run-safari --debug --ios-simulator
In both cases, if you have built release builds instead, use --release
instead of --debug
.
If you have a development build, you can use the run-minibrowser script, e.g.:
run-minibrowser --debug --wpe
Pass one of --gtk
, --jsc-only
, or --wpe
to indicate the port to use.
Congratulations! You’re up and running. Now you can begin coding in WebKit and contribute your fixes and new features to the project. For details on submitting your code to the project, read Contributing Code.