Diff
Modified: branches/safari-608-branch/Source/WebCore/ChangeLog (248556 => 248557)
--- branches/safari-608-branch/Source/WebCore/ChangeLog 2019-08-12 23:41:37 UTC (rev 248556)
+++ branches/safari-608-branch/Source/WebCore/ChangeLog 2019-08-12 23:41:41 UTC (rev 248557)
@@ -1,5 +1,109 @@
2019-08-12 Alan Coon <[email protected]>
+ Cherry-pick r248095. rdar://problem/53820658
+
+ REGRESSION (r240942): first visually non-empty layout milestone is not reached in media documents until after the video finishes loading
+ https://bugs.webkit.org/show_bug.cgi?id=200293
+ <rdar://problem/52937749>
+
+ Reviewed by Alex Christensen.
+
+ Source/WebCore:
+
+ r240942 changed FrameView::qualifiesAsVisuallyNonEmpty() to consider only documents in the
+ Interactive or Complete ready states as "finished parsing". Documents considered finished
+ parsing can qualify as visually non-empty even without exceeding the visual character or
+ pixel thresholds, but documents considered not finished must first exceed one of these
+ thresholds in order to qualify as visually non-empty.
+
+ HTMLDocuments are placed in the Interactive ready state by their HTMLDocumentParsers.
+ However, HTMLDocument subclasses like ImageDocument and MediaDocument use their own custom
+ parsers that never set the Interactive ready state on their documents; these documents go
+ from Loading directly to Complete.
+
+ In order for these HTMLDocument subclasses to be considered visually non-empty before they
+ finish loading they must render something that exceeds the visual character or pixel
+ thresholds. For image documents, rendering the image is usually enough to cross the
+ threshold, but for media documents the visual pixel threshold was never crossed because
+ videos did not contribute to the visually non-empty pixel count.
+
+ As a result, media documents are not considered visually non-empty until the main resource
+ finishes loading. On iOS this means that the layer tree remains frozen until this point,
+ even though the media might have started autoplaying with audio long before it finished
+ loading.
+
+ Fix this by teaching RenderVideo to contribute the video player's size to FrameView's
+ visually non-empty pixel count once the video player has loaded enough data to determine its
+ intrinsic size. Videos that render more than 1024 pixels will qualify a media document as
+ visually non-empty even when it is still loading its main resource.
+
+ Added a new API test.
+
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::imageChanged):
+ (WebCore::RenderImage::incrementVisuallyNonEmptyPixelCountIfNeeded):
+ * rendering/RenderImage.h:
+ * rendering/RenderVideo.cpp:
+ (WebCore::RenderVideo::updateIntrinsicSize):
+
+ Tools:
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm: Renamed from Tools/TestWebKitAPI/Tests/WebKit/FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm.
+ (-[FirstPaintMessageHandler userContentController:didReceiveScriptMessage:]):
+ (-[RenderingProgressNavigationDelegate _webView:renderingProgressDidChange:]):
+ (-[RenderingProgressNavigationDelegate webView:didFinishNavigation:]):
+ (TEST):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248095 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2019-07-31 Andy Estes <[email protected]>
+
+ REGRESSION (r240942): first visually non-empty layout milestone is not reached in media documents until after the video finishes loading
+ https://bugs.webkit.org/show_bug.cgi?id=200293
+ <rdar://problem/52937749>
+
+ Reviewed by Alex Christensen.
+
+ r240942 changed FrameView::qualifiesAsVisuallyNonEmpty() to consider only documents in the
+ Interactive or Complete ready states as "finished parsing". Documents considered finished
+ parsing can qualify as visually non-empty even without exceeding the visual character or
+ pixel thresholds, but documents considered not finished must first exceed one of these
+ thresholds in order to qualify as visually non-empty.
+
+ HTMLDocuments are placed in the Interactive ready state by their HTMLDocumentParsers.
+ However, HTMLDocument subclasses like ImageDocument and MediaDocument use their own custom
+ parsers that never set the Interactive ready state on their documents; these documents go
+ from Loading directly to Complete.
+
+ In order for these HTMLDocument subclasses to be considered visually non-empty before they
+ finish loading they must render something that exceeds the visual character or pixel
+ thresholds. For image documents, rendering the image is usually enough to cross the
+ threshold, but for media documents the visual pixel threshold was never crossed because
+ videos did not contribute to the visually non-empty pixel count.
+
+ As a result, media documents are not considered visually non-empty until the main resource
+ finishes loading. On iOS this means that the layer tree remains frozen until this point,
+ even though the media might have started autoplaying with audio long before it finished
+ loading.
+
+ Fix this by teaching RenderVideo to contribute the video player's size to FrameView's
+ visually non-empty pixel count once the video player has loaded enough data to determine its
+ intrinsic size. Videos that render more than 1024 pixels will qualify a media document as
+ visually non-empty even when it is still loading its main resource.
+
+ Added a new API test.
+
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::imageChanged):
+ (WebCore::RenderImage::incrementVisuallyNonEmptyPixelCountIfNeeded):
+ * rendering/RenderImage.h:
+ * rendering/RenderVideo.cpp:
+ (WebCore::RenderVideo::updateIntrinsicSize):
+
+2019-08-12 Alan Coon <[email protected]>
+
Cherry-pick r248447. rdar://problem/54218162
Add to InteractionInformationAtPosition information about whether the element is in a subscrollable region
Modified: branches/safari-608-branch/Source/WebCore/rendering/RenderImage.cpp (248556 => 248557)
--- branches/safari-608-branch/Source/WebCore/rendering/RenderImage.cpp 2019-08-12 23:41:37 UTC (rev 248556)
+++ branches/safari-608-branch/Source/WebCore/rendering/RenderImage.cpp 2019-08-12 23:41:41 UTC (rev 248557)
@@ -269,13 +269,10 @@
if (newImage != imageResource().imagePtr() || !newImage)
return;
-
- if (!m_didIncrementVisuallyNonEmptyPixelCount) {
- // At a zoom level of 1 the image is guaranteed to have an integer size.
- view().frameView().incrementVisuallyNonEmptyPixelCount(flooredIntSize(imageResource().imageSize(1.0f)));
- m_didIncrementVisuallyNonEmptyPixelCount = true;
- }
+ // At a zoom level of 1 the image is guaranteed to have an integer size.
+ incrementVisuallyNonEmptyPixelCountIfNeeded(flooredIntSize(imageResource().imageSize(1.0f)));
+
ImageSizeChangeType imageSizeChange = ImageSizeChangeNone;
// Set image dimensions, taking into account the size of the alt text.
@@ -850,4 +847,13 @@
return nullptr;
}
+void RenderImage::incrementVisuallyNonEmptyPixelCountIfNeeded(const IntSize& size)
+{
+ if (m_didIncrementVisuallyNonEmptyPixelCount)
+ return;
+
+ view().frameView().incrementVisuallyNonEmptyPixelCount(size);
+ m_didIncrementVisuallyNonEmptyPixelCount = true;
+}
+
} // namespace WebCore
Modified: branches/safari-608-branch/Source/WebCore/rendering/RenderImage.h (248556 => 248557)
--- branches/safari-608-branch/Source/WebCore/rendering/RenderImage.h 2019-08-12 23:41:37 UTC (rev 248556)
+++ branches/safari-608-branch/Source/WebCore/rendering/RenderImage.h 2019-08-12 23:41:41 UTC (rev 248557)
@@ -100,6 +100,8 @@
imageChanged(imageResource().imagePtr());
}
+ void incrementVisuallyNonEmptyPixelCountIfNeeded(const IntSize&);
+
private:
const char* renderName() const override { return "RenderImage"; }
Modified: branches/safari-608-branch/Source/WebCore/rendering/RenderVideo.cpp (248556 => 248557)
--- branches/safari-608-branch/Source/WebCore/rendering/RenderVideo.cpp 2019-08-12 23:41:37 UTC (rev 248556)
+++ branches/safari-608-branch/Source/WebCore/rendering/RenderVideo.cpp 2019-08-12 23:41:41 UTC (rev 248557)
@@ -101,6 +101,10 @@
if (size.isEmpty() && document().isMediaDocument())
return false;
+ // Treat the media player's natural size as visually non-empty.
+ if (videoElement().readyState() >= HTMLMediaElementEnums::HAVE_METADATA)
+ incrementVisuallyNonEmptyPixelCountIfNeeded(roundedIntSize(size));
+
if (size == intrinsicSize())
return false;
@@ -109,7 +113,7 @@
setNeedsLayout();
return true;
}
-
+
LayoutSize RenderVideo::calculateIntrinsicSize()
{
// Spec text from 4.8.6
Modified: branches/safari-608-branch/Tools/ChangeLog (248556 => 248557)
--- branches/safari-608-branch/Tools/ChangeLog 2019-08-12 23:41:37 UTC (rev 248556)
+++ branches/safari-608-branch/Tools/ChangeLog 2019-08-12 23:41:41 UTC (rev 248557)
@@ -1,3 +1,78 @@
+2019-08-12 Alan Coon <[email protected]>
+
+ Cherry-pick r248095. rdar://problem/53820658
+
+ REGRESSION (r240942): first visually non-empty layout milestone is not reached in media documents until after the video finishes loading
+ https://bugs.webkit.org/show_bug.cgi?id=200293
+ <rdar://problem/52937749>
+
+ Reviewed by Alex Christensen.
+
+ Source/WebCore:
+
+ r240942 changed FrameView::qualifiesAsVisuallyNonEmpty() to consider only documents in the
+ Interactive or Complete ready states as "finished parsing". Documents considered finished
+ parsing can qualify as visually non-empty even without exceeding the visual character or
+ pixel thresholds, but documents considered not finished must first exceed one of these
+ thresholds in order to qualify as visually non-empty.
+
+ HTMLDocuments are placed in the Interactive ready state by their HTMLDocumentParsers.
+ However, HTMLDocument subclasses like ImageDocument and MediaDocument use their own custom
+ parsers that never set the Interactive ready state on their documents; these documents go
+ from Loading directly to Complete.
+
+ In order for these HTMLDocument subclasses to be considered visually non-empty before they
+ finish loading they must render something that exceeds the visual character or pixel
+ thresholds. For image documents, rendering the image is usually enough to cross the
+ threshold, but for media documents the visual pixel threshold was never crossed because
+ videos did not contribute to the visually non-empty pixel count.
+
+ As a result, media documents are not considered visually non-empty until the main resource
+ finishes loading. On iOS this means that the layer tree remains frozen until this point,
+ even though the media might have started autoplaying with audio long before it finished
+ loading.
+
+ Fix this by teaching RenderVideo to contribute the video player's size to FrameView's
+ visually non-empty pixel count once the video player has loaded enough data to determine its
+ intrinsic size. Videos that render more than 1024 pixels will qualify a media document as
+ visually non-empty even when it is still loading its main resource.
+
+ Added a new API test.
+
+ * rendering/RenderImage.cpp:
+ (WebCore::RenderImage::imageChanged):
+ (WebCore::RenderImage::incrementVisuallyNonEmptyPixelCountIfNeeded):
+ * rendering/RenderImage.h:
+ * rendering/RenderVideo.cpp:
+ (WebCore::RenderVideo::updateIntrinsicSize):
+
+ Tools:
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm: Renamed from Tools/TestWebKitAPI/Tests/WebKit/FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm.
+ (-[FirstPaintMessageHandler userContentController:didReceiveScriptMessage:]):
+ (-[RenderingProgressNavigationDelegate _webView:renderingProgressDidChange:]):
+ (-[RenderingProgressNavigationDelegate webView:didFinishNavigation:]):
+ (TEST):
+
+
+ git-svn-id: https://svn.webkit.org/repository/webkit/trunk@248095 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+ 2019-07-31 Andy Estes <[email protected]>
+
+ REGRESSION (r240942): first visually non-empty layout milestone is not reached in media documents until after the video finishes loading
+ https://bugs.webkit.org/show_bug.cgi?id=200293
+ <rdar://problem/52937749>
+
+ Reviewed by Alex Christensen.
+
+ * TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj:
+ * TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm: Renamed from Tools/TestWebKitAPI/Tests/WebKit/FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm.
+ (-[FirstPaintMessageHandler userContentController:didReceiveScriptMessage:]):
+ (-[RenderingProgressNavigationDelegate _webView:renderingProgressDidChange:]):
+ (-[RenderingProgressNavigationDelegate webView:didFinishNavigation:]):
+ (TEST):
+
2019-08-06 Alan Coon <[email protected]>
Apply patch. rdar://problem/53992160
Modified: branches/safari-608-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj (248556 => 248557)
--- branches/safari-608-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2019-08-12 23:41:37 UTC (rev 248556)
+++ branches/safari-608-branch/Tools/TestWebKitAPI/TestWebKitAPI.xcodeproj/project.pbxproj 2019-08-12 23:41:41 UTC (rev 248557)
@@ -65,7 +65,7 @@
1171B24F219F49CD00CB897D /* FirstMeaningfulPaintMilestone_Bundle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11B7FD21219F46DD0069B27F /* FirstMeaningfulPaintMilestone_Bundle.cpp */; };
118153442208B7AC00B2CCD2 /* deferred-script-load.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 118153432208B7AC00B2CCD2 /* deferred-script-load.html */; };
118153462208B7E500B2CCD2 /* deferred-script.js in Copy Resources */ = {isa = PBXBuildFile; fileRef = 118153452208B7E500B2CCD2 /* deferred-script.js */; };
- 118153482208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm in Sources */ = {isa = PBXBuildFile; fileRef = 118153472208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm */; };
+ 118153482208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestone.mm in Sources */ = {isa = PBXBuildFile; fileRef = 118153472208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestone.mm */; };
11B7FD28219F47110069B27F /* FirstMeaningfulPaintMilestone.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 11B7FD22219F46DD0069B27F /* FirstMeaningfulPaintMilestone.cpp */; };
11C2598D21FA6324004C9E23 /* async-script-load.html in Copy Resources */ = {isa = PBXBuildFile; fileRef = 11C2598C21FA618D004C9E23 /* async-script-load.html */; };
143DDE9820C9018B007F76FA /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 574F55D0204D471C002948C6 /* Security.framework */; };
@@ -1440,7 +1440,7 @@
115EB3421EE0B720003C2C0A /* ViewportSizeForViewportUnits.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ViewportSizeForViewportUnits.mm; sourceTree = "<group>"; };
118153432208B7AC00B2CCD2 /* deferred-script-load.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "deferred-script-load.html"; sourceTree = "<group>"; };
118153452208B7E500B2CCD2 /* deferred-script.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode._javascript_; path = "deferred-script.js"; sourceTree = "<group>"; };
- 118153472208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm; sourceTree = "<group>"; };
+ 118153472208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestone.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = FirstVisuallyNonEmptyMilestone.mm; sourceTree = "<group>"; };
11B7FD21219F46DD0069B27F /* FirstMeaningfulPaintMilestone_Bundle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FirstMeaningfulPaintMilestone_Bundle.cpp; sourceTree = "<group>"; };
11B7FD22219F46DD0069B27F /* FirstMeaningfulPaintMilestone.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FirstMeaningfulPaintMilestone.cpp; sourceTree = "<group>"; };
11C2598C21FA618D004C9E23 /* async-script-load.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "async-script-load.html"; sourceTree = "<group>"; };
@@ -2700,6 +2700,7 @@
F44D06461F395C4D001A0E29 /* EditorStateTests.mm */,
CDA29B2820FD2A9900F15CED /* ExitFullscreenOnEnterPiP.mm */,
2D8104CB1BEC13E70020DA46 /* FindInPage.mm */,
+ 118153472208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestone.mm */,
2D1FE0AF1AD465C1006CD9E6 /* FixedLayoutSize.mm */,
2E92B8F8216490EA005B64F0 /* FontAttributes.mm */,
5CB5B3BD1FFC517E00C27BB0 /* FrameHandleSerialization.mm */,
@@ -3391,7 +3392,6 @@
C51AFB98169F49FF009CCF66 /* FindMatches.mm */,
11B7FD22219F46DD0069B27F /* FirstMeaningfulPaintMilestone.cpp */,
11B7FD21219F46DD0069B27F /* FirstMeaningfulPaintMilestone_Bundle.cpp */,
- 118153472208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm */,
1ADBEFAD130C689C00D61D19 /* ForceRepaint.cpp */,
376C8C041D6E197C007D2BB9 /* FrameHandle.cpp */,
BCBD370F125AA2EB00D2C29F /* FrameMIMETypeHTML.cpp */,
@@ -4367,7 +4367,7 @@
11B7FD28219F47110069B27F /* FirstMeaningfulPaintMilestone.cpp in Sources */,
7C83E0401D0A63E300FEBCF3 /* FirstResponderScrollingPosition.mm in Sources */,
C9E6DD351EA97D0800DD78AA /* FirstResponderSuppression.mm in Sources */,
- 118153482208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm in Sources */,
+ 118153482208BADF00B2CCD2 /* FirstVisuallyNonEmptyMilestone.mm in Sources */,
7C83E0BC1D0A650700FEBCF3 /* FixedLayoutSize.mm in Sources */,
7A909A7E1D877480007E10F8 /* FloatPoint.cpp in Sources */,
7A909A7F1D877480007E10F8 /* FloatRect.cpp in Sources */,
Deleted: branches/safari-608-branch/Tools/TestWebKitAPI/Tests/WebKit/FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm (248556 => 248557)
--- branches/safari-608-branch/Tools/TestWebKitAPI/Tests/WebKit/FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm 2019-08-12 23:41:37 UTC (rev 248556)
+++ branches/safari-608-branch/Tools/TestWebKitAPI/Tests/WebKit/FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm 2019-08-12 23:41:41 UTC (rev 248557)
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2019 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:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. 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.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
- */
-#import "config.h"
-
-#import "PlatformUtilities.h"
-#import "TestNavigationDelegate.h"
-#import <wtf/RetainPtr.h>
-
-static bool didFirstVisuallyNonEmptyLayout;
-static bool receivedMessage;
-
-@interface FirstPaintMessageHandler : NSObject <WKScriptMessageHandler>
-@end
-
-@implementation FirstPaintMessageHandler
-- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
-{
- receivedMessage = true;
-}
-@end
-
-@interface RenderingProgressNavigationDelegate : NSObject <WKNavigationDelegate>
-@end
-
-@implementation RenderingProgressNavigationDelegate
-- (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents
-{
- if (progressEvents & _WKRenderingProgressEventFirstVisuallyNonEmptyLayout)
- didFirstVisuallyNonEmptyLayout = true;
-}
-@end
-
-TEST(WebKit, FirstVisuallyNonEmptyMilestoneWithDeferredScript)
-{
- auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
- auto messageHandler = adoptNS([[FirstPaintMessageHandler alloc] init]);
- [[webViewConfiguration userContentController] addScriptMessageHandler:messageHandler.get() name:@"firstpaint"];
-
- auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
-
- RetainPtr<RenderingProgressNavigationDelegate> delegate = adoptNS([[RenderingProgressNavigationDelegate alloc] init]);
- [webView setNavigationDelegate:delegate.get()];
-
- receivedMessage = false;
- didFirstVisuallyNonEmptyLayout = false;
-
- [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"deferred-script-load" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
-
- TestWebKitAPI::Util::run(&receivedMessage);
- EXPECT_TRUE(didFirstVisuallyNonEmptyLayout);
-}
Copied: branches/safari-608-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm (from rev 248556, branches/safari-608-branch/Tools/TestWebKitAPI/Tests/WebKit/FirstVisuallyNonEmptyMilestoneWithDeferredScript.mm) (0 => 248557)
--- branches/safari-608-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm (rev 0)
+++ branches/safari-608-branch/Tools/TestWebKitAPI/Tests/WebKitCocoa/FirstVisuallyNonEmptyMilestone.mm 2019-08-12 23:41:41 UTC (rev 248557)
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2019 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:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+#import "config.h"
+
+#import "PlatformUtilities.h"
+#import "TestNavigationDelegate.h"
+#import "TestWKWebView.h"
+#import <WebKit/WKWebViewConfigurationPrivate.h>
+#import <wtf/RetainPtr.h>
+
+#if PLATFORM(IOS_FAMILY)
+#include <MobileCoreServices/MobileCoreServices.h>
+#endif
+
+static bool didFirstVisuallyNonEmptyLayout;
+static bool receivedMessage;
+
+@interface FirstPaintMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation FirstPaintMessageHandler
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+ receivedMessage = true;
+}
+@end
+
+@interface RenderingProgressNavigationDelegate : NSObject <WKNavigationDelegate>
+@end
+
+@implementation RenderingProgressNavigationDelegate
+- (void)_webView:(WKWebView *)webView renderingProgressDidChange:(_WKRenderingProgressEvents)progressEvents
+{
+ if (progressEvents & _WKRenderingProgressEventFirstVisuallyNonEmptyLayout)
+ didFirstVisuallyNonEmptyLayout = true;
+}
+@end
+
+TEST(WebKit, FirstVisuallyNonEmptyMilestoneWithDeferredScript)
+{
+ auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ auto messageHandler = adoptNS([[FirstPaintMessageHandler alloc] init]);
+ [[webViewConfiguration userContentController] addScriptMessageHandler:messageHandler.get() name:@"firstpaint"];
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+
+ RetainPtr<RenderingProgressNavigationDelegate> delegate = adoptNS([[RenderingProgressNavigationDelegate alloc] init]);
+ [webView setNavigationDelegate:delegate.get()];
+
+ receivedMessage = false;
+ didFirstVisuallyNonEmptyLayout = false;
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[[NSBundle mainBundle] URLForResource:@"deferred-script-load" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"]]];
+
+ TestWebKitAPI::Util::run(&receivedMessage);
+ EXPECT_TRUE(didFirstVisuallyNonEmptyLayout);
+}
+
+@interface NeverFinishLoadingSchemeHandler : NSObject <WKURLSchemeHandler>
+@property (nonatomic, readonly, class) NSString *URLScheme;
+@end
+
+@implementation NeverFinishLoadingSchemeHandler
+
++ (NSString *)URLScheme
+{
+ return @"never-finish-loading";
+}
+
+static NSString *contentTypeForFileExtension(NSString *fileExtension)
+{
+ auto identifier = adoptCF(UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, nullptr));
+ auto mimeType = adoptCF(UTTypeCopyPreferredTagWithClass(identifier.get(), kUTTagClassMIMEType));
+ return (__bridge NSString *)mimeType.autorelease();
+}
+
+- (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task
+{
+ NSURL *requestURL = task.request.URL;
+ NSString *fileName = requestURL.lastPathComponent;
+ NSString *fileExtension = fileName.pathExtension;
+ NSURL *bundleURL = [NSBundle.mainBundle URLForResource:fileName.stringByDeletingPathExtension withExtension:fileExtension subdirectory:@"TestWebKitAPI.resources"];
+
+ NSData *responseData = [NSData dataWithContentsOfURL:bundleURL];
+ NSUInteger responseLength = responseData.length;
+
+ auto response = adoptNS([[NSURLResponse alloc] initWithURL:requestURL MIMEType:contentTypeForFileExtension(fileExtension) expectedContentLength:responseLength textEncodingName:nil]);
+ [task didReceiveResponse:response.get()];
+
+ [task didReceiveData:[responseData subdataWithRange:NSMakeRange(0, responseLength - 1024)]];
+}
+
+- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)task
+{
+}
+
+@end
+
+TEST(WebKit, FirstVisuallyNonEmptyMilestoneWithMediaDocument)
+{
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+#if PLATFORM(IOS_FAMILY)
+ [configuration setAllowsInlineMediaPlayback:YES];
+ [configuration _setInlineMediaPlaybackRequiresPlaysInlineAttribute:NO];
+#endif
+
+ auto schemeHandler = adoptNS([[NeverFinishLoadingSchemeHandler alloc] init]);
+ [configuration setURLSchemeHandler:schemeHandler.get() forURLScheme:NeverFinishLoadingSchemeHandler.URLScheme];
+
+ auto navigationDelegate = adoptNS([[RenderingProgressNavigationDelegate alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 800, 600) configuration:configuration.get() addToWindow:YES]);
+ [webView setNavigationDelegate:navigationDelegate.get()];
+ [webView _setAllowsMediaDocumentInlinePlayback:YES];
+
+ [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"never-finish-loading:///large-video-with-audio.mp4"]]];
+
+ didFirstVisuallyNonEmptyLayout = false;
+ TestWebKitAPI::Util::run(&didFirstVisuallyNonEmptyLayout);
+}