WebKit Bugzilla
Attachment 346790 Details for
Bug 188416
: Import WPTs for IntersectionObserver
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-188416-20180808165328.patch (text/plain), 119.42 KB, created by
Ali Juma
on 2018-08-08 13:53:30 PDT
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Ali Juma
Created:
2018-08-08 13:53:30 PDT
Size:
119.42 KB
patch
obsolete
>Subversion Revision: 234702 >diff --git a/Source/WebKit/ChangeLog b/Source/WebKit/ChangeLog >index a8463f581e6dc46dbaeef030ce65bea97cc066d4..cabb7dde066d71cf8e3158f4c9108e57c2db53b3 100644 >--- a/Source/WebKit/ChangeLog >+++ b/Source/WebKit/ChangeLog >@@ -1,3 +1,15 @@ >+2018-08-08 Ali Juma <ajuma@chromium.org> >+ >+ Import WPTs for IntersectionObserver >+ https://bugs.webkit.org/show_bug.cgi?id=188416 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Make IntersectionObserver an experimental feature, so that it is enabled in >+ WebKitTestRunner. >+ >+ * Shared/WebPreferences.yaml: >+ > 2018-08-05 Darin Adler <darin@apple.com> > > [Cocoa] More tweaks and refactoring to prepare for ARC >diff --git a/Source/WebKitLegacy/mac/ChangeLog b/Source/WebKitLegacy/mac/ChangeLog >index 7ba849e8d610b84c22d72efa9f4066ae38d41f27..78764aeb98faa2893a13990af62070a31f6fc7de 100644 >--- a/Source/WebKitLegacy/mac/ChangeLog >+++ b/Source/WebKitLegacy/mac/ChangeLog >@@ -1,3 +1,12 @@ >+2018-08-08 Ali Juma <ajuma@chromium.org> >+ >+ Import WPTs for IntersectionObserver >+ https://bugs.webkit.org/show_bug.cgi?id=188416 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * WebView/WebPreferencesPrivate.h: >+ > 2018-08-08 Jonathan Bedard <jbedard@apple.com> > > Follow-up build fix for r234685 >diff --git a/Source/WebKit/Shared/WebPreferences.yaml b/Source/WebKit/Shared/WebPreferences.yaml >index dc4f68c05fa578c86ced91d47157a3baa9f1c8e7..cd2bfd5e1b5c6dd936ecb37acf55841b49b849cd 100644 >--- a/Source/WebKit/Shared/WebPreferences.yaml >+++ b/Source/WebKit/Shared/WebPreferences.yaml >@@ -655,14 +655,6 @@ MediaPreloadingEnabled: > defaultValue: false > webcoreBinding: RuntimeEnabledFeatures > >-IntersectionObserverEnabled: >- type: bool >- defaultValue: false >- humanReadableName: "Intersection Observer" >- humanReadableDescription: "Enable Intersection Observer support" >- webcoreBinding: RuntimeEnabledFeatures >- condition: ENABLE(INTERSECTION_OBSERVER) >- > InteractiveFormValidationEnabled: > type: bool > defaultValue: true >@@ -1146,6 +1138,15 @@ ImageBitmapOffscreenCanvasEnabled: > category: experimental > webcoreBinding: RuntimeEnabledFeatures > >+IntersectionObserverEnabled: >+ type: bool >+ defaultValue: false >+ humanReadableName: "Intersection Observer" >+ humanReadableDescription: "Enable Intersection Observer support" >+ webcoreBinding: RuntimeEnabledFeatures >+ category: experimental >+ condition: ENABLE(INTERSECTION_OBSERVER) >+ > WebRTCLegacyAPIEnabled: > type: bool > defaultValue: false >diff --git a/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h b/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h >index 05a121dbc31e784d1369d431fb35cb644755f749..6bf0d480425aa9f216c6a1f0a8ef2aa06b47e777 100644 >--- a/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h >+++ b/Source/WebKitLegacy/mac/WebView/WebPreferencesPrivate.h >@@ -576,6 +576,9 @@ extern NSString *WebPreferencesCacheModelChangedInternalNotification WEBKIT_DEPR > - (void)setWebAuthenticationEnabled:(BOOL)flag; > - (BOOL)webAuthenticationEnabled; > >+- (void)setIntersectionObserverEnabled:(BOOL)flag; >+- (BOOL)intersectionObserverEnabled; >+ > - (void)setIsSecureContextAttributeEnabled:(BOOL)flag; > - (BOOL)isSecureContextAttributeEnabled; > >diff --git a/Tools/ChangeLog b/Tools/ChangeLog >index 5beae2a31bd37f2cfddf518eb8684bae1b306128..0f727e895a993955f70c3c83603ef28ace3bdb02 100644 >--- a/Tools/ChangeLog >+++ b/Tools/ChangeLog >@@ -1,3 +1,18 @@ >+2018-08-08 Ali Juma <ajuma@chromium.org> >+ >+ Import WPTs for IntersectionObserver >+ https://bugs.webkit.org/show_bug.cgi?id=188416 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ Enable IntersectionObserver in DumpRenderTree. >+ >+ * DumpRenderTree/mac/DumpRenderTree.mm: >+ (enableExperimentalFeatures): >+ (setWebPreferencesForTestOptions): >+ * WebKitTestRunner/TestController.cpp: >+ (WTR::TestController::resetPreferencesToConsistentValues): >+ > 2018-08-08 Wenson Hsieh <wenson_hsieh@apple.com> > > [iOS] fast/events/ios/contenteditable-autocapitalize.html is a flaky failure >diff --git a/Tools/DumpRenderTree/mac/DumpRenderTree.mm b/Tools/DumpRenderTree/mac/DumpRenderTree.mm >index d9b84fc2009f2c976bae3dace8118e97241e2e60..5d52905736a36bb9b4b6b50a8f458c528a352a41 100644 >--- a/Tools/DumpRenderTree/mac/DumpRenderTree.mm >+++ b/Tools/DumpRenderTree/mac/DumpRenderTree.mm >@@ -867,6 +867,7 @@ static void enableExperimentalFeatures(WebPreferences* preferences) > [preferences setColorFilterEnabled:YES]; > [preferences setCrossOriginWindowPolicySupportEnabled:YES]; > [preferences setServerTimingEnabled:YES]; >+ [preferences setIntersectionObserverEnabled:YES]; > } > > // Called before each test. >@@ -996,7 +997,6 @@ static void setWebPreferencesForTestOptions(const TestOptions& options) > > preferences.attachmentElementEnabled = options.enableAttachmentElement; > preferences.acceleratedDrawingEnabled = options.useAcceleratedDrawing; >- preferences.intersectionObserverEnabled = options.enableIntersectionObserver; > preferences.menuItemElementEnabled = options.enableMenuItemElement; > preferences.modernMediaControlsEnabled = options.enableModernMediaControls; > preferences.webAuthenticationEnabled = options.enableWebAuthentication; >diff --git a/Tools/WebKitTestRunner/TestController.cpp b/Tools/WebKitTestRunner/TestController.cpp >index 0e7d8e6a48f3dac164914854bb6031ff0cd9df01..01203ce19db46cf22073b45c0ed3399baa035084 100644 >--- a/Tools/WebKitTestRunner/TestController.cpp >+++ b/Tools/WebKitTestRunner/TestController.cpp >@@ -711,7 +711,6 @@ void TestController::resetPreferencesToConsistentValues(const TestOptions& optio > WKPreferencesSetMockScrollbarsEnabled(preferences, options.useMockScrollbars); > WKPreferencesSetNeedsSiteSpecificQuirks(preferences, options.needsSiteSpecificQuirks); > WKPreferencesSetAttachmentElementEnabled(preferences, options.enableAttachmentElement); >- WKPreferencesSetIntersectionObserverEnabled(preferences, options.enableIntersectionObserver); > WKPreferencesSetMenuItemElementEnabled(preferences, options.enableMenuItemElement); > WKPreferencesSetModernMediaControlsEnabled(preferences, options.enableModernMediaControls); > WKPreferencesSetWebAuthenticationEnabled(preferences, options.enableWebAuthentication); >diff --git a/LayoutTests/imported/w3c/ChangeLog b/LayoutTests/imported/w3c/ChangeLog >index 094a3226b48ecc4c0295d5fa8296391d3737eb40..d81798650ca2c4daa27a285168652333ae665b25 100644 >--- a/LayoutTests/imported/w3c/ChangeLog >+++ b/LayoutTests/imported/w3c/ChangeLog >@@ -1,3 +1,87 @@ >+2018-08-08 Ali Juma <ajuma@chromium.org> >+ >+ Import WPTs for IntersectionObserver >+ https://bugs.webkit.org/show_bug.cgi?id=188416 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ * resources/import-expectations.json: >+ * web-platform-tests/intersection-observer/META.yml: Added. >+ * web-platform-tests/intersection-observer/bounding-box-expected.txt: Added. >+ * web-platform-tests/intersection-observer/bounding-box.html: Added. >+ * web-platform-tests/intersection-observer/client-rect-expected.txt: Added. >+ * web-platform-tests/intersection-observer/client-rect.html: Added. >+ * web-platform-tests/intersection-observer/containing-block-expected.txt: Added. >+ * web-platform-tests/intersection-observer/containing-block.html: Added. >+ * web-platform-tests/intersection-observer/cross-origin-iframe-expected.txt: Added. >+ * web-platform-tests/intersection-observer/cross-origin-iframe.html: Added. >+ * web-platform-tests/intersection-observer/disconnect-expected.txt: Added. >+ * web-platform-tests/intersection-observer/disconnect.html: Added. >+ * web-platform-tests/intersection-observer/display-none-expected.txt: Added. >+ * web-platform-tests/intersection-observer/display-none.html: Added. >+ * web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt: Added. >+ * web-platform-tests/intersection-observer/edge-inclusive-intersection.html: Added. >+ * web-platform-tests/intersection-observer/idlharness.window-expected.txt: Added. >+ * web-platform-tests/intersection-observer/idlharness.window.html: Added. >+ * web-platform-tests/intersection-observer/idlharness.window.js: Added. >+ (idl_array.self.observer.new.IntersectionObserver): >+ * web-platform-tests/intersection-observer/iframe-no-root-expected.txt: Added. >+ * web-platform-tests/intersection-observer/iframe-no-root.html: Added. >+ * web-platform-tests/intersection-observer/inline-client-rect-expected.txt: Added. >+ * web-platform-tests/intersection-observer/inline-client-rect.html: Added. >+ * web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt: Added. >+ * web-platform-tests/intersection-observer/isIntersecting-change-events.html: Added. >+ * web-platform-tests/intersection-observer/multiple-targets-expected.txt: Added. >+ * web-platform-tests/intersection-observer/multiple-targets.html: Added. >+ * web-platform-tests/intersection-observer/multiple-thresholds-expected.txt: Added. >+ * web-platform-tests/intersection-observer/multiple-thresholds.html: Added. >+ * web-platform-tests/intersection-observer/observer-attributes-expected.txt: Added. >+ * web-platform-tests/intersection-observer/observer-attributes.html: Added. >+ * web-platform-tests/intersection-observer/observer-exceptions-expected.txt: Added. >+ * web-platform-tests/intersection-observer/observer-exceptions.html: Added. >+ * web-platform-tests/intersection-observer/observer-in-iframe.html: Added. >+ * web-platform-tests/intersection-observer/observer-without-js-reference-expected.txt: Added. >+ * web-platform-tests/intersection-observer/observer-without-js-reference.html: Added. >+ * web-platform-tests/intersection-observer/remove-element-expected.txt: Added. >+ * web-platform-tests/intersection-observer/remove-element.html: Added. >+ * web-platform-tests/intersection-observer/resources/cross-origin-subframe.html: Added. >+ * web-platform-tests/intersection-observer/resources/iframe-no-root-subframe.html: Added. >+ * web-platform-tests/intersection-observer/resources/intersection-observer-test-utils.js: Added. >+ (waitForNotification): >+ (runTestCycle): >+ (contentBounds): >+ (borderBoxBounds): >+ (clientBounds): >+ (rectArea): >+ (checkRect): >+ (checkLastEntry): >+ (checkJsonEntry): >+ (checkJsonEntries): >+ * web-platform-tests/intersection-observer/resources/observer-in-iframe-subframe.html: Added. >+ * web-platform-tests/intersection-observer/resources/timestamp-subframe.html: Added. >+ * web-platform-tests/intersection-observer/resources/w3c-import.log: Added. >+ * web-platform-tests/intersection-observer/root-margin-expected.txt: Added. >+ * web-platform-tests/intersection-observer/root-margin.html: Added. >+ * web-platform-tests/intersection-observer/same-document-no-root-expected.txt: Added. >+ * web-platform-tests/intersection-observer/same-document-no-root.html: Added. >+ * web-platform-tests/intersection-observer/same-document-root-expected.txt: Added. >+ * web-platform-tests/intersection-observer/same-document-root.html: Added. >+ * web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt: Added. >+ * web-platform-tests/intersection-observer/same-document-zero-size-target.html: Added. >+ * web-platform-tests/intersection-observer/shadow-content-expected.txt: Added. >+ * web-platform-tests/intersection-observer/shadow-content.html: Added. >+ * web-platform-tests/intersection-observer/text-target-expected.txt: Added. >+ * web-platform-tests/intersection-observer/text-target.html: Added. >+ * web-platform-tests/intersection-observer/timestamp-expected.txt: Added. >+ * web-platform-tests/intersection-observer/timestamp.html: Added. >+ * web-platform-tests/intersection-observer/unclipped-root-expected.txt: Added. >+ * web-platform-tests/intersection-observer/unclipped-root.html: Added. >+ * web-platform-tests/intersection-observer/w3c-import.log: Added. >+ * web-platform-tests/intersection-observer/zero-area-element-hidden-expected.txt: Added. >+ * web-platform-tests/intersection-observer/zero-area-element-hidden.html: Added. >+ * web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt: Added. >+ * web-platform-tests/intersection-observer/zero-area-element-visible.html: Added. >+ > 2018-08-08 Charlie Turner <cturner@igalia.com> > > Add CENC sanitization >diff --git a/LayoutTests/imported/w3c/resources/import-expectations.json b/LayoutTests/imported/w3c/resources/import-expectations.json >index feb825aac07b7bde69c9671b7fffec8fd561ccf5..137b29c1b5fd6232289f1d6d5187c5717ce49481 100644 >--- a/LayoutTests/imported/w3c/resources/import-expectations.json >+++ b/LayoutTests/imported/w3c/resources/import-expectations.json >@@ -246,7 +246,7 @@ > "web-platform-tests/innerText": "import", > "web-platform-tests/input-events": "skip", > "web-platform-tests/interfaces": "skip", >- "web-platform-tests/intersection-observer": "skip", >+ "web-platform-tests/intersection-observer": "import", > "web-platform-tests/js": "skip", > "web-platform-tests/keyboard-lock": "skip", > "web-platform-tests/longtask-timing": "skip", >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/META.yml b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/META.yml >new file mode 100644 >index 0000000000000000000000000000000000000000..31dddab561edd292a18e5b2cd4fb313a96af65b9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/META.yml >@@ -0,0 +1,3 @@ >+spec: https://w3c.github.io/IntersectionObserver/ >+suggested_reviewers: >+ - szager-chromium >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..50762b64c80febecffaae98d9c467d7d3f61ef62 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box-expected.txt >@@ -0,0 +1,5 @@ >+ >+PASS Test that the target's border bounding box is used to calculate intersection. >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL target.style.transform = 'translateY(195px)' assert_equals: entries.length expected 2 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box.html >new file mode 100644 >index 0000000000000000000000000000000000000000..69052b11ce6c40c6a56fe2b723c70c49ddc36dd9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box.html >@@ -0,0 +1,61 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#root { >+ overflow: visible; >+ height: 200px; >+ width: 160px; >+ border: 7px solid black; >+} >+#target { >+ margin: 10px; >+ width: 100px; >+ height: 100px; >+ padding: 10px; >+ background-color: green; >+} >+</style> >+ >+<div id="root"> >+ <div id="target" style="transform: translateY(300px)"></div> >+</div> >+ >+<script> >+var entries = []; >+var target; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ assert_true(!!target, "target exists"); >+ var root = document.getElementById("root"); >+ assert_true(!!root, "root exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }, {root: root}); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "Test that the target's border bounding box is used to calculate intersection."); >+ >+function step0() { >+ var targetBounds = clientBounds(target); >+ target.style.transform = "translateY(195px)"; >+ runTestCycle(step1, "target.style.transform = 'translateY(195px)'"); >+ checkLastEntry(entries, 0, targetBounds.concat(0, 0, 0, 0, 8, 182, 8, 222, false)); >+} >+ >+function step1() { >+ var targetBounds = clientBounds(target); >+ target.style.transform = ""; >+ checkLastEntry(entries, 1, targetBounds.concat(25, 145, 220, 222, 8, 182, 8, 222, true)); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/client-rect-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/client-rect-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..08fc2c4b449f4d5d0dcdc3f707a41a956a0d229b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/client-rect-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS IntersectionObserverEntry.boundingClientRect should match target.boundingClientRect() >+FAIL First rAF should generate notification. assert_equals: One notification. expected 1 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/client-rect.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/client-rect.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6c50fdb14ac4e094ca8e42a4bfafb83f36e15a59 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/client-rect.html >@@ -0,0 +1,45 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+iframe { >+ width: 180px; >+ height: 100px; >+} >+</style> >+ >+<iframe id="iframe" srcdoc="<div id='target' style='margin:0.5px;width:1000px;height:1000px;'></div>"></iframe> >+ >+<script> >+var target; >+var entries = []; >+var observer; >+var iframe = document.getElementById("iframe"); >+ >+iframe.onload = function() { >+ runTestCycle(function() { >+ target = iframe.contentDocument.getElementById("target"); >+ assert_true(!!target, "Target element exists."); >+ observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes); >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(test0, "First rAF should generate notification."); >+ }, "IntersectionObserverEntry.boundingClientRect should match target.boundingClientRect()"); >+}; >+ >+function test0() { >+ assert_equals(entries.length, 1, "One notification."); >+ var bcr = target.getBoundingClientRect(); >+ checkLastEntry(entries, 0, [bcr.left, bcr.right, bcr.top, bcr.bottom]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9eeb18e5977332c4fc9d3ca358624fe67fc00d5a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block-expected.txt >@@ -0,0 +1,7 @@ >+ >+PASS IntersectionObserver should only report intersections if root is a containing block ancestor of target. >+FAIL In containing block and intersecting. assert_equals: entries.length expected 1 but got 0 >+FAIL In containing block and not intersecting. assert_equals: entries.length expected 2 but got 0 >+FAIL Not in containing block and intersecting. assert_equals: entries.length expected 2 but got 0 >+FAIL Not in containing block and not intersecting. assert_equals: entries.length expected 2 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d4f46b0fa77d8ed930f5bac19c3f5854d4950ed0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block.html >@@ -0,0 +1,73 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#root { >+ width: 170px; >+ height: 200px; >+ overflow-y: scroll; >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+ position: absolute; >+} >+</style> >+ >+<div id="root" style="position: absolute"> >+ <div id="target" style="left: 50px; top: 250px"></div> >+</div> >+ >+<script> >+var entries = []; >+var root, target; >+ >+runTestCycle(function() { >+ root = document.getElementById("root"); >+ assert_true(!!root, "root element exists."); >+ target = document.getElementById("target"); >+ assert_true(!!target, "target element exists."); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes); >+ }, { root: root }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ target.style.top = "10px"; >+ runTestCycle(test1, "In containing block and intersecting."); >+}, "IntersectionObserver should only report intersections if root is a containing block ancestor of target."); >+ >+function test1() { >+ runTestCycle(test2, "In containing block and not intersecting."); >+ var rootBounds = contentBounds(root); >+ checkLastEntry(entries, 0, [58, 158, 18, 118, 58, 158, 18, 118].concat(rootBounds)); >+ target.style.top = "250px"; >+} >+ >+function test2() { >+ runTestCycle(test3, "Not in containing block and intersecting."); >+ var rootBounds = contentBounds(root); >+ checkLastEntry(entries, 1, [58, 158, 258, 358, 0, 0, 0, 0].concat(rootBounds)); >+ root.style.position = "static"; >+ target.style.top = "10px"; >+} >+ >+function test3() { >+ runTestCycle(test4, "Not in containing block and not intersecting."); >+ checkLastEntry(entries, 1); >+ target.style.top = "250px"; >+} >+ >+function test4() { >+ checkLastEntry(entries, 1); >+ target.style.top = "0"; >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/cross-origin-iframe-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/cross-origin-iframe-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f26709bc5cf3bdc7301c085bb53ff65063d71a44 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/cross-origin-iframe-expected.txt >@@ -0,0 +1,8 @@ >+ >+ >+PASS Intersection observer test with no explicit root and target in a cross-origin iframe. >+FAIL First rAF assert_equals: expected 1 but got 0 >+PASS topDocument.scrollingElement.scrollTop = 200 >+FAIL iframeDocument.scrollingElement.scrollTop = 250 assert_equals: expected 1 but got 0 >+FAIL topDocument.scrollingElement.scrollTop = 100 assert_equals: expected 1 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/cross-origin-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/cross-origin-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2c9c4bcec69666f0e37509618e05a6b741f5533d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/cross-origin-iframe.html >@@ -0,0 +1,52 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+iframe { >+ width: 160px; >+ height: 100px; >+ overflow-y: scroll; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+</style> >+ >+<div class="spacer"></div> >+<iframe src="resources/cross-origin-subframe.html" sandbox="allow-scripts"></iframe> >+<div class="spacer"></div> >+ >+<script> >+async_test(function(t) { >+ var iframe = document.querySelector("iframe"); >+ >+ function handleMessage(event) { >+ if (event.data.hasOwnProperty('scrollTo')) { >+ document.scrollingElement.scrollTop = event.data.scrollTo; >+ waitForNotification(t, function() { iframe.contentWindow.postMessage("", "*"); }, >+ "document.scrollingElement.scrollTop = " + event.data.scrollTo); >+ } else if (event.data.hasOwnProperty('actual')) { >+ checkJsonEntries(event.data.actual, event.data.expected, event.data.description); >+ } else if (event.data.hasOwnProperty('DONE')) { >+ document.scrollingElement.scrollTop = 0; >+ t.done(); >+ } else { >+ var description = event.data.description; >+ waitForNotification(t, function() { iframe.contentWindow.postMessage("", "*"); }, description); >+ } >+ } >+ >+ window.addEventListener("message", t.step_func(handleMessage)); >+ >+ iframe.onload = t.step_func(function() { >+ waitForNotification(t, function() { iframe.contentWindow.postMessage("", "*") }, "setup"); >+ }); >+}, "Intersection observer test with no explicit root and target in a cross-origin iframe."); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/disconnect-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/disconnect-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..41df6e7a70bb1a50cc1773f24ae80fe0d9e6eeeb >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/disconnect-expected.txt >@@ -0,0 +1,5 @@ >+ >+PASS IntersectionObserver should not deliver pending notifications after disconnect(). >+FAIL First rAF. assert_equals: Initial notification. expected 1 but got 0 >+FAIL observer.disconnect() assert_equals: No new notifications. expected 1 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/disconnect.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/disconnect.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0abfbc4e8aafa3e5f073f8899188f409af21e566 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/disconnect.html >@@ -0,0 +1,53 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+</style> >+ >+<div class="spacer"></div> >+<div id="target"></div> >+<div class="spacer"></div> >+ >+<script> >+var entries = []; >+var observer; >+var target; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ assert_true(!!target, "target exists"); >+ observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "IntersectionObserver should not deliver pending notifications after disconnect()."); >+ >+function step0() { >+ runTestCycle(step1, "observer.disconnect()"); >+ document.scrollingElement.scrollTop = 300; >+ observer.disconnect(); >+ assert_equals(entries.length, 1, "Initial notification."); >+} >+ >+function step1() { >+ assert_equals(entries.length, 1, "No new notifications."); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/display-none-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/display-none-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..372a41fd75e1464241ce6c1babc83cbbcfcd386d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/display-none-expected.txt >@@ -0,0 +1,6 @@ >+ >+PASS IntersectionObserver should send a not-intersecting notification for a target that gets display:none. >+FAIL Intersecting notification after first rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL Not-intersecting notification after setting display:none on target. assert_equals: entries.length expected 2 but got 0 >+FAIL Intersecting notification after removing display:none on target. assert_equals: entries.length expected 3 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/display-none.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/display-none.html >new file mode 100644 >index 0000000000000000000000000000000000000000..7cebc5633ef91228129d2a1c0478262615ad3ba1 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/display-none.html >@@ -0,0 +1,54 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#target { >+ background-color: green; >+ width: 100px; >+ height: 100px; >+} >+</style> >+ >+<div id="target"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+ >+runTestCycle(function() { >+ var target = document.getElementById("target"); >+ var root = document.getElementById("root"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "Intersecting notification after first rAF."); >+}, "IntersectionObserver should send a not-intersecting notification for a target that gets display:none."); >+ >+function step0() { >+ runTestCycle(step1, "Not-intersecting notification after setting display:none on target."); >+ checkLastEntry(entries, 0, [8, 108, 8, 108, 8, 108, 8, 108, 0, vw, 0, vh, true]); >+ target.style.display = "none"; >+} >+ >+function step1() { >+ runTestCycle(step2, "Intersecting notification after removing display:none on target."); >+ checkLastEntry(entries, 1, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false]); >+ target.style.display = ""; >+} >+ >+function step2() { >+ checkLastEntry(entries, 2, [8, 108, 8, 108, 8, 108, 8, 108, 0, vw, 0, vh, true]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6fd199f7d53f050299d4f8fe08eb294a50167a5a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection-expected.txt >@@ -0,0 +1,7 @@ >+ >+PASS IntersectionObserver should detect and report edge-adjacent and zero-area intersections. >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL Set transform=translateY(200px) on target. assert_equals: entries.length expected 2 but got 0 >+FAIL Set transform=translateY(201px) on target. assert_equals: entries.length expected 3 but got 0 >+FAIL Set transform=translateY(185px) on target. assert_equals: entries.length expected 4 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection.html >new file mode 100644 >index 0000000000000000000000000000000000000000..b9fa24b87808abc158307e8c69afeeb5ce3c1907 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection.html >@@ -0,0 +1,66 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#root { >+ width: 200px; >+ height: 200px; >+ overflow: visible; >+} >+#target { >+ background-color: green; >+} >+</style> >+ >+<div id="root"> >+ <div id="target" style="width: 100px; height: 100px; transform: translateY(250px)"></div> >+</div> >+ >+<script> >+var entries = []; >+ >+runTestCycle(function() { >+ var root = document.getElementById('root'); >+ assert_true(!!root, "root element exists."); >+ var target = document.getElementById('target'); >+ assert_true(!!target, "target element exists."); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes); >+ }, { root: root }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "IntersectionObserver should detect and report edge-adjacent and zero-area intersections."); >+ >+function step0() { >+ runTestCycle(step1, "Set transform=translateY(200px) on target."); >+ checkLastEntry(entries, 0, [8, 108, 258, 358, 0, 0, 0, 0, 8, 208, 8, 208, false]); >+ target.style.transform = "translateY(200px)"; >+} >+ >+function step1() { >+ runTestCycle(step2, "Set transform=translateY(201px) on target."); >+ checkLastEntry(entries, 1, [8, 108, 208, 308, 8, 108, 208, 208, 8, 208, 8, 208, true]); >+ target.style.transform = "translateY(201px)"; >+} >+ >+function step2() { >+ runTestCycle(step3, "Set transform=translateY(185px) on target."); >+ checkLastEntry(entries, 2); >+ target.style.height = "0px"; >+ target.style.width = "300px"; >+ target.style.transform = "translateY(185px)"; >+} >+ >+function step3() { >+ checkLastEntry(entries, 3, [8, 308, 193, 193, 8, 208, 193, 193, 8, 208, 8, 208, true]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..0b7fee05acb0bd1e2990450bf1b8ee2d72e3b1ee >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window-expected.txt >@@ -0,0 +1,4 @@ >+CONSOLE MESSAGE: line 8: ReferenceError: Can't find variable: idl_test >+ >+FAIL Untitled ReferenceError: Can't find variable: idl_test >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window.html >new file mode 100644 >index 0000000000000000000000000000000000000000..2382913528e693b3a5d56c660a45060980b548c3 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window.html >@@ -0,0 +1 @@ >+<!-- This file is required for WebKit test infrastructure to run the templated test --> >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window.js b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window.js >new file mode 100644 >index 0000000000000000000000000000000000000000..2059e1ce638b5f2cac4e4f013c567a56894599a0 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window.js >@@ -0,0 +1,22 @@ >+// META: script=/resources/WebIDLParser.js >+// META: script=/resources/idlharness.js >+ >+'use strict'; >+ >+// https://w3c.github.io/IntersectionObserver/ >+ >+idl_test( >+ ['intersection-observer'], >+ ['dom'], >+ idl_array => { >+ idl_array.add_objects({ >+ IntersectionObserver: ['observer'], >+ }); >+ var options = { >+ root: document.body, >+ rootMargin: '0px', >+ threshold: 1.0 >+ } >+ self.observer = new IntersectionObserver(() => {}, options); >+ } >+); >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/iframe-no-root-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/iframe-no-root-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..9137bee6b5d4e8de631354876333fbe9b04b624c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/iframe-no-root-expected.txt >@@ -0,0 +1,8 @@ >+ >+ >+PASS Observer with the implicit root; target in a same-origin iframe. >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL document.scrollingElement.scrollTop = 200 assert_equals: entries.length == 1 expected 1 but got 0 >+FAIL iframe.contentDocument.scrollingElement.scrollTop = 250 assert_equals: entries.length expected 2 but got 0 >+FAIL document.scrollingElement.scrollTop = 100 assert_equals: entries.length expected 3 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/iframe-no-root.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/iframe-no-root.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e37aeac5530f348328274f9f8a2eeae9f08609ff >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/iframe-no-root.html >@@ -0,0 +1,71 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+iframe { >+ height: 100px; >+ width: 150px; >+} >+</style> >+ >+<div class="spacer"></div> >+<iframe id="target-iframe" src="resources/iframe-no-root-subframe.html"></iframe> >+<div class="spacer"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var iframe = document.getElementById("target-iframe"); >+var target; >+var entries = []; >+ >+iframe.onload = function() { >+ runTestCycle(function() { >+ assert_true(!!iframe, "iframe exists"); >+ >+ target = iframe.contentDocument.getElementById("target"); >+ assert_true(!!target, "Target element exists."); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+ }, "Observer with the implicit root; target in a same-origin iframe."); >+}; >+ >+function step0() { >+ document.scrollingElement.scrollTop = 200; >+ runTestCycle(step1, "document.scrollingElement.scrollTop = 200"); >+ checkLastEntry(entries, 0, [8, 108, 208, 308, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+ >+function step1() { >+ iframe.contentDocument.scrollingElement.scrollTop = 250; >+ runTestCycle(step2, "iframe.contentDocument.scrollingElement.scrollTop = 250"); >+ assert_equals(entries.length, 1, "entries.length == 1"); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = 100; >+ runTestCycle(step3, "document.scrollingElement.scrollTop = 100"); >+ checkLastEntry(entries, 1, [8, 108, -42, 58, 8, 108, 0, 58, 0, vw, 0, vh, true]); >+} >+ >+function step3() { >+ checkLastEntry(entries, 2, [8, 108, -42, 58, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+ document.scrollingElement.scrollTop = 0; >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/inline-client-rect-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/inline-client-rect-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..1ccadf05989d0299c05cd80d1f04bcccd1b0908c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/inline-client-rect-expected.txt >@@ -0,0 +1,6 @@ >+1 2 3 4 5 >+ >+PASS Inline target >+FAIL First rAF assert_equals: entries.length expected 1 but got 0 >+FAIL scroller.scrollLeft = 90 assert_equals: entries.length expected 2 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/inline-client-rect.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/inline-client-rect.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0bdfc8de24458e0fb490de4f00537197c0662e53 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/inline-client-rect.html >@@ -0,0 +1,92 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 120px; >+ left: 0; >+} >+#scroller { >+ width: 250px; >+ overflow: auto; >+} >+#overflow { >+ width: 1000px; >+} >+.content { >+ width: 100px; >+ height: 20px; >+ padding: 40px 0; >+ text-align: center; >+ background-color: grey; >+ display: inline-block; >+} >+</style> >+ >+<div id="scroller"> >+ <div id="overflow"> >+ <span><div class="content">1</div></span> >+ <span><div class="content">2</div></span> >+ <span><div class="content">3</div></span> >+ <span id="target"><div class="content">4</div></span> >+ <span><div class="content">5</div></span> >+ </div> >+</div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+var scroller, target, spaceWidth, targetOffsetLeft, targetOffsetTop; >+ >+runTestCycle(function() { >+ scroller = document.getElementById("scroller"); >+ assert_true(!!scroller, "scroller exists"); >+ target = document.getElementById("target"); >+ assert_true(!!target, "target exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF"); >+}, "Inline target"); >+ >+function step0() { >+ // Measure space width between two adjacent inlines. >+ let nextEl = target.nextElementSibling; >+ spaceWidth = nextEl.offsetLeft - target.offsetLeft - target.offsetWidth; >+ // 8px body margin + 3 preceding siblings @ (100px width + spaceWidth) each >+ targetOffsetLeft = 8 + 300 + (spaceWidth * 3); >+ // 8px body margin + 40px top padding >+ targetOffsetTop = 48; >+ let left = targetOffsetLeft; >+ let right = left + 100; >+ let top = targetOffsetTop; >+ let bottom = top + target.offsetHeight; >+ >+ scroller.scrollLeft = 90; >+ runTestCycle(step1, "scroller.scrollLeft = 90"); >+ >+ checkLastEntry(entries, 0, [left, right, top, bottom, >+ 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+ >+function step1() { >+ // -90px for scroll offset >+ let left = targetOffsetLeft - 90; >+ let right = left + 100; >+ let top = targetOffsetTop; >+ let bottom = top + target.offsetHeight; >+ // 8px body margin + 250px client width of scroller >+ let scrollerRight = 258; >+ checkLastEntry(entries, 1, [left, right, top, bottom, >+ left, scrollerRight, top, bottom, >+ 0, vw, 0, vh, true]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..07d48f20195ec7acbbb54800c160092a91850b6b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS isIntersecting changes should trigger notifications. >+FAIL Rects in initial notifications should report initial positions. assert_equals: Has 3 initial notifications. expected 3 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f9362c3024c2003ac03c1e789c54486830710c92 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events.html >@@ -0,0 +1,112 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#root { >+ position: absolute; >+ top: 0; >+ left: 0; >+ width: 150px; >+ height: 200px; >+ overflow-y: scroll; >+} >+#target1, #target2, #target3, #target4 { >+ width: 100px; >+ height: 100px; >+} >+#target1 { >+ background-color: green; >+} >+#target2 { >+ background-color: red; >+} >+#target3 { >+ background-color: blue; >+} >+#target4 { >+ background-color: yellow; >+} >+</style> >+ >+<div id="root"> >+ <div id="target1"></div> >+ <div id="target2"></div> >+ <div id="target3"></div> >+</div> >+ >+<script> >+var entries = []; >+var observer; >+ >+runTestCycle(function() { >+ var root = document.getElementById('root'); >+ var target1 = document.getElementById('target1'); >+ var target2 = document.getElementById('target2'); >+ var target3 = document.getElementById('target3'); >+ assert_true(!!root, "root element exists."); >+ assert_true(!!target1, "target1 element exists."); >+ assert_true(!!target2, "target2 element exists."); >+ assert_true(!!target3, "target3 element exists."); >+ observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes); >+ }, { root: root }); >+ observer.observe(target1); >+ observer.observe(target2); >+ observer.observe(target3); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "Rects in initial notifications should report initial positions."); >+}, "isIntersecting changes should trigger notifications."); >+ >+function step0() { >+ assert_equals(entries.length, 3, "Has 3 initial notifications."); >+ checkRect(entries[0].boundingClientRect, [0, 100, 0, 100], "Check 1st entry rect"); >+ assert_equals(entries[0].target.id, 'target1', "Check 1st entry target id."); >+ checkIsIntersecting(entries, 0, true); >+ checkRect(entries[1].boundingClientRect, [0, 100, 100, 200], "Check 2nd entry rect"); >+ assert_equals(entries[1].target.id, 'target2', "Check 2nd entry target id."); >+ checkIsIntersecting(entries, 1, true); >+ checkRect(entries[2].boundingClientRect, [0, 100, 200, 300], "Check 3rd entry rect"); >+ assert_equals(entries[2].target.id, 'target3', "Check 3rd entry target id."); >+ checkIsIntersecting(entries, 2, true); >+ runTestCycle(step1, "Set scrollTop=100 and check for no new notifications."); >+ root.scrollTop = 100; >+} >+ >+function step1() { >+ assert_equals(entries.length, 3, "Has 3 total notifications because isIntersecting did not change."); >+ runTestCycle(step2, "Add 4th target."); >+ root.scrollTop = 0; >+ var target4 = document.createElement('div'); >+ target4.setAttribute('id', 'target4'); >+ root.appendChild(target4); >+ observer.observe(target4); >+} >+ >+function step2() { >+ assert_equals(entries.length, 4, "Has 3 total notifications because 4th element was added."); >+ checkRect(entries[3].boundingClientRect, [0, 100, 300, 400], "Check 4th entry rect"); >+ assert_equals(entries[3].target.id, 'target4', "Check 4th entry target id."); >+ checkIsIntersecting(entries, 3, false); >+ assert_equals(entries[3].intersectionRatio, 0, 'target4 initially has intersectionRatio of 0.'); >+ runTestCycle(step3, "Set scrollTop=100 and check for one new notification."); >+ root.scrollTop = 100; >+} >+ >+function step3() { >+ assert_equals(entries.length, 5, "Has 5 total notifications."); >+ checkRect(entries[4].boundingClientRect, [0, 100, 200, 300], "Check 5th entry rect"); >+ assert_equals(entries[4].target.id, 'target4', "Check 5th entry target id."); >+ checkIsIntersecting(entries, 4, true); >+ assert_equals(entries[4].intersectionRatio, 0, 'target4 still has intersectionRatio of 0.'); >+ root.scrollTop = 0; // reset to make it easier to refresh and run the test >+} >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-targets-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-targets-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4d1482ccb46a3dc4e686dff5e8a7bfac5f7bf20f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-targets-expected.txt >@@ -0,0 +1,7 @@ >+ >+PASS One observer with multiple targets. >+FAIL First rAF. assert_equals: Three initial notifications. expected 3 but got 0 >+FAIL document.scrollingElement.scrollTop = 150 assert_equals: Four notifications. expected 4 but got 0 >+FAIL document.scrollingElement.scrollTop = 10000 assert_equals: Six notifications. expected 6 but got 0 >+FAIL document.scrollingElement.scrollTop = 0 assert_equals: Nine notifications. expected 9 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-targets.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-targets.html >new file mode 100644 >index 0000000000000000000000000000000000000000..525c5a699d1cc51080bebc650ae377b26c2fe7eb >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-targets.html >@@ -0,0 +1,80 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+.target { >+ width: 100px; >+ height: 100px; >+ margin: 10px; >+ background-color: green; >+} >+</style> >+ >+<div class="spacer"></div> >+<div id="target1" class="target"></div> >+<div id="target2" class="target"></div> >+<div id="target3" class="target"></div> >+ >+<script> >+var entries = []; >+var target1, target2, target3; >+ >+runTestCycle(function() { >+ target1 = document.getElementById("target1"); >+ assert_true(!!target1, "target1 exists."); >+ target2 = document.getElementById("target2"); >+ assert_true(!!target2, "target2 exists."); >+ target3 = document.getElementById("target3"); >+ assert_true(!!target3, "target3 exists."); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target1); >+ observer.observe(target2); >+ observer.observe(target3); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "One observer with multiple targets."); >+ >+function step0() { >+ document.scrollingElement.scrollTop = 150; >+ runTestCycle(step1, "document.scrollingElement.scrollTop = 150"); >+ assert_equals(entries.length, 3, "Three initial notifications."); >+ assert_equals(entries[0].target, target1, "entries[0].target === target1"); >+ assert_equals(entries[1].target, target2, "entries[1].target === target2"); >+ assert_equals(entries[2].target, target3, "entries[2].target === target3"); >+} >+ >+function step1() { >+ document.scrollingElement.scrollTop = 10000; >+ runTestCycle(step2, "document.scrollingElement.scrollTop = 10000"); >+ assert_equals(entries.length, 4, "Four notifications."); >+ assert_equals(entries[3].target, target1, "entries[3].target === target1"); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = 0; >+ runTestCycle(step3, "document.scrollingElement.scrollTop = 0"); >+ assert_equals(entries.length, 6, "Six notifications."); >+ assert_equals(entries[4].target, target2, "entries[4].target === target2"); >+ assert_equals(entries[5].target, target3, "entries[5].target === target3"); >+} >+ >+function step3() { >+ assert_equals(entries.length, 9, "Nine notifications."); >+ assert_equals(entries[6].target, target1, "entries[6].target === target1"); >+ assert_equals(entries[7].target, target2, "entries[7].target === target2"); >+ assert_equals(entries[8].target, target3, "entries[8].target === target3"); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-thresholds-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-thresholds-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..f4a66f808e5edb8949d7da8dc1778557b66f71e6 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-thresholds-expected.txt >@@ -0,0 +1,11 @@ >+ >+PASS Observer with multiple thresholds. >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL document.scrollingElement.scrollTop = 120 assert_equals: entries.length expected 2 but got 0 >+FAIL document.scrollingElement.scrollTop = 160 assert_equals: entries.length expected 3 but got 0 >+FAIL document.scrollingElement.scrollTop = 200 assert_equals: entries.length expected 4 but got 0 >+FAIL document.scrollingElement.scrollTop = 240 assert_equals: entries.length expected 5 but got 0 >+FAIL document.scrollingElement.scrollTop = window.innerHeight + 140 assert_equals: entries.length expected 6 but got 0 >+FAIL document.scrollingElement.scrollTop = window.innerHeight + 160 assert_equals: entries.length expected 7 but got 0 >+FAIL document.scrollingElement.scrollTop = window.innerHeight + 200 assert_equals: entries.length expected 8 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-thresholds.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-thresholds.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6450068941ce1d132e3bba6970b366a25a7dbc4a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-thresholds.html >@@ -0,0 +1,96 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+</style> >+ >+<div class="spacer"></div> >+<div id="target"></div> >+<div class="spacer"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+var target; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }, { threshold: [0, 0.25, 0.5, 0.75, 1] }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "Observer with multiple thresholds."); >+ >+function step0() { >+ document.scrollingElement.scrollTop = 120; >+ runTestCycle(step1, "document.scrollingElement.scrollTop = 120"); >+ checkLastEntry(entries, 0, [8, 108, vh + 108, vh + 208, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+ >+function step1() { >+ document.scrollingElement.scrollTop = 160; >+ runTestCycle(step2, "document.scrollingElement.scrollTop = 160"); >+ checkLastEntry(entries, 1, [8, 108, vh - 12, vh + 88, 8, 108, vh - 12, vh, 0, vw, 0, vh, true]); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = 200; >+ runTestCycle(step3, "document.scrollingElement.scrollTop = 200"); >+ checkLastEntry(entries, 2, [8, 108, vh - 52, vh + 48, 8, 108, vh - 52, vh, 0, vw, 0, vh, true]); >+} >+ >+function step3() { >+ document.scrollingElement.scrollTop = 240; >+ runTestCycle(step4, "document.scrollingElement.scrollTop = 240"); >+ checkLastEntry(entries, 3, [8, 108, vh - 92, vh + 8, 8, 108, vh - 92, vh, 0, vw, 0, vh, true]); >+} >+ >+function step4() { >+ document.scrollingElement.scrollTop = vh + 140; >+ runTestCycle(step5, "document.scrollingElement.scrollTop = window.innerHeight + 140"); >+ checkLastEntry(entries, 4, [8, 108, vh - 132, vh - 32, 8, 108, vh - 132, vh - 32, 0, vw, 0, vh, true]); >+} >+ >+function step5() { >+ document.scrollingElement.scrollTop = vh + 160; >+ runTestCycle(step6, "document.scrollingElement.scrollTop = window.innerHeight + 160"); >+ checkLastEntry(entries, 5, [8, 108, -32, 68, 8, 108, 0, 68, 0, vw, 0, vh, true]); >+} >+ >+function step6() { >+ document.scrollingElement.scrollTop = vh + 200; >+ runTestCycle(step7, "document.scrollingElement.scrollTop = window.innerHeight + 200"); >+ checkLastEntry(entries, 6, [8, 108, -52, 48, 8, 108, 0, 48, 0, vw, 0, vh, true]); >+} >+ >+function step7() { >+ checkLastEntry(entries, 7, [8, 108, -92, 8, 8, 108, 0, 8, 0, vw, 0, vh, true]); >+ document.scrollingElement.scrollTop = vh + 220; >+ runTestCycle(step8, "document.scrollingElement.scrollTop = window.innerHeight + 220"); >+} >+ >+function step8() { >+ checkLastEntry(entries, 8, [8, 108, -112, -12, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+ document.scrollingElement.scrollTop = 0; >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2efd44b4eee0f77504a8cce8bd0b2479108bfd44 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes-expected.txt >@@ -0,0 +1,9 @@ >+ >+PASS Observer attribute getters. >+PASS observer.root >+PASS observer.thresholds >+FAIL observer.rootMargin assert_equals: expected "0px 0px 0px 0px" but got "0px" >+PASS set observer.root >+PASS set observer.thresholds >+FAIL set observer.rootMargin assert_equals: expected "10% 20px 10% 20px" but got "10% 20px" >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ffca95ded3160b887adc6bbfada2e5b366efac24 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes.html >@@ -0,0 +1,31 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<div id="root"></div> >+ >+<script> >+test(function() { >+ var observer = new IntersectionObserver(function(e) {}, {}); >+ test(function() { assert_equals(observer.root, null) }, >+ "observer.root"); >+ test(function() { assert_array_equals(observer.thresholds, [0]) }, >+ "observer.thresholds"); >+ test(function() { assert_equals(observer.rootMargin, "0px 0px 0px 0px") }, >+ "observer.rootMargin"); >+ >+ var rootDiv = document.getElementById("root"); >+ observer = new IntersectionObserver(function(e) {}, { >+ root: rootDiv, >+ threshold: [0, 0.25, 0.5, 1.0], >+ rootMargin: "10% 20px" >+ }); >+ test(function() { assert_equals(observer.root, rootDiv) }, >+ "set observer.root"); >+ test(function() { assert_array_equals(observer.thresholds, [0, 0.25, 0.5, 1.0]) }, >+ "set observer.thresholds"); >+ test(function() { assert_equals(observer.rootMargin, "10% 20px 10% 20px") }, >+ "set observer.rootMargin"); >+}, "Observer attribute getters."); >+ >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..be3d45748031fea3f889081f61aa1f1023bdf304 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions-expected.txt >@@ -0,0 +1,25 @@ >+ >+FAIL IntersectionObserver constructor with { threshold: [1.1] } assert_throws: function "function () { >+ new IntersectionObserver(e => {}, {threshold: [1.1]}) >+ }" did not throw >+PASS IntersectionObserver constructor with { threshold: ["foo"] } >+FAIL IntersectionObserver constructor witth { rootMargin: "1" } assert_throws: function "function () { >+ new IntersectionObserver(e => {}, {rootMargin: "1"}) >+ }" did not throw >+FAIL IntersectionObserver constructor with { rootMargin: "2em" } assert_throws: function "function () { >+ new IntersectionObserver(e => {}, {rootMargin: "2em"}) >+ }" did not throw >+FAIL IntersectionObserver constructor with { rootMargin: "auto" } assert_throws: function "function () { >+ new IntersectionObserver(e => {}, {rootMargin: "auto"}) >+ }" did not throw >+FAIL IntersectionObserver constructor with { rootMargin: "calc(1px + 2px)" } assert_throws: function "function () { >+ new IntersectionObserver(e => {}, {rootMargin: "calc(1px + 2px)"}) >+ }" did not throw >+FAIL IntersectionObserver constructor with { rootMargin: "1px !important" } assert_throws: function "function () { >+ new IntersectionObserver(e => {}, {rootMargin: "1px !important"}) >+ }" did not throw >+FAIL IntersectionObserver constructor with { rootMargin: "1px 1px 1px 1px 1px" } assert_throws: function "function () { >+ new IntersectionObserver(e => {}, {rootMargin: "1px 1px 1px 1px 1px"}) >+ }" did not throw >+PASS IntersectionObserver.observe("foo") >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d4f178be51c394ba98225f359eb02cd78f45259e >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions.html >@@ -0,0 +1,60 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+ >+<script> >+test(function () { >+ assert_throws(RangeError(), function() { >+ new IntersectionObserver(e => {}, {threshold: [1.1]}) >+ }) >+}, "IntersectionObserver constructor with { threshold: [1.1] }"); >+ >+test(function () { >+ assert_throws(TypeError(), function() { >+ new IntersectionObserver(e => {}, {threshold: ["foo"]}) >+ }) >+}, 'IntersectionObserver constructor with { threshold: ["foo"] }'); >+ >+test(function () { >+ assert_throws("SYNTAX_ERR", function() { >+ new IntersectionObserver(e => {}, {rootMargin: "1"}) >+ }) >+}, 'IntersectionObserver constructor witth { rootMargin: "1" }'); >+ >+test(function () { >+ assert_throws("SYNTAX_ERR", function() { >+ new IntersectionObserver(e => {}, {rootMargin: "2em"}) >+ }) >+}, 'IntersectionObserver constructor with { rootMargin: "2em" }'); >+ >+test(function () { >+ assert_throws("SYNTAX_ERR", function() { >+ new IntersectionObserver(e => {}, {rootMargin: "auto"}) >+ }) >+}, 'IntersectionObserver constructor with { rootMargin: "auto" }'); >+ >+test(function () { >+ assert_throws("SYNTAX_ERR", function() { >+ new IntersectionObserver(e => {}, {rootMargin: "calc(1px + 2px)"}) >+ }) >+}, 'IntersectionObserver constructor with { rootMargin: "calc(1px + 2px)" }'); >+ >+test(function () { >+ assert_throws("SYNTAX_ERR", function() { >+ new IntersectionObserver(e => {}, {rootMargin: "1px !important"}) >+ }) >+}, 'IntersectionObserver constructor with { rootMargin: "1px !important" }'); >+ >+test(function () { >+ assert_throws("SYNTAX_ERR", function() { >+ new IntersectionObserver(e => {}, {rootMargin: "1px 1px 1px 1px 1px"}) >+ }) >+}, 'IntersectionObserver constructor with { rootMargin: "1px 1px 1px 1px 1px" }'); >+ >+test(function () { >+ assert_throws(TypeError(), function() { >+ let observer = new IntersectionObserver(c => {}, {}); >+ observer.observe("foo"); >+ }) >+}, 'IntersectionObserver.observe("foo")'); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-in-iframe.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-in-iframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..f4aa387de2a80eb7309b3d457eb605d87eae6046 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-in-iframe.html >@@ -0,0 +1,9 @@ >+<!DOCTYPE html> >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+</style> >+<iframe id="target-iframe" src="resources/observer-in-iframe-subframe.html" width="150px" height="150px"></iframe> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-without-js-reference-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-without-js-reference-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..4935ea6151cb330dcd9153acbc5d27a61405a6d2 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-without-js-reference-expected.txt >@@ -0,0 +1,5 @@ >+ >+PASS IntersectionObserver that is unreachable in js should still generate notifications. >+FAIL First rAF assert_equals: One notification. expected 1 but got 0 >+FAIL document.scrollingElement.scrollTop = 300 assert_equals: Two notifications. expected 2 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-without-js-reference.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-without-js-reference.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3214345b61052cfc0ab3720f688416faf23a5585 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-without-js-reference.html >@@ -0,0 +1,50 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+</style> >+<div class="spacer"></div> >+<div id="target"></div> >+<div class="spacer"></div> >+ >+<script> >+var entries = []; >+ >+runTestCycle(function() { >+ var target = document.getElementById("target"); >+ assert_true(!!target, "Target exists"); >+ function createObserver() { >+ new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }).observe(target); >+ } >+ createObserver(); >+ runTestCycle(step0, "First rAF"); >+}, "IntersectionObserver that is unreachable in js should still generate notifications."); >+ >+function step0() { >+ document.scrollingElement.scrollTop = 300; >+ runTestCycle(step1, "document.scrollingElement.scrollTop = 300"); >+ assert_equals(entries.length, 1, "One notification."); >+} >+ >+function step1() { >+ document.scrollingElement.scrollTop = 0; >+ assert_equals(entries.length, 2, "Two notifications."); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..dd4186c082586cc61f2b778d19940b4ad41647ef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element-expected.txt >@@ -0,0 +1,8 @@ >+ >+PASS Verify that not-intersecting notifications are sent when a target is removed from the DOM tree. >+FAIL First rAF assert_equals: entries.length expected 1 but got 0 >+FAIL root.scrollTop = 150 assert_equals: entries.length expected 2 but got 0 >+FAIL root.removeChild(target). assert_equals: entries.length expected 3 but got 0 >+FAIL root.insertBefore(target, trailingSpace). assert_equals: entries.length expected 3 but got 0 >+FAIL root.scrollTop = 150 after reinserting target. assert_equals: entries.length expected 4 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element.html >new file mode 100644 >index 0000000000000000000000000000000000000000..3b6a65e2d0e42513aefd4568409b1a2f510b2db9 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element.html >@@ -0,0 +1,82 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#root { >+ display: inline-block; >+ overflow-y: scroll; >+ height: 200px; >+ border: 3px solid black; >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+.spacer { >+ height: 300px; >+} >+</style> >+ >+<div id="root"> >+ <div id="leading-space" class="spacer"></div> >+ <div id="target"></div> >+ <div id="trailing-space" class="spacer"</div> >+</div> >+ >+<script> >+var entries = []; >+var root, target, trailingSpace; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ assert_true(!!target, "Target exists"); >+ trailingSpace = document.getElementById("trailing-space"); >+ assert_true(!!trailingSpace, "TrailingSpace exists"); >+ root = document.getElementById("root"); >+ assert_true(!!root, "Root exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }, {root: root}); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF"); >+}, "Verify that not-intersecting notifications are sent when a target is removed from the DOM tree."); >+ >+function step0() { >+ root.scrollTop = 150; >+ runTestCycle(step1, "root.scrollTop = 150"); >+ checkLastEntry(entries, 0, [11, 111, 311, 411, 0, 0, 0, 0, 11, 111, 11, 211, false]); >+} >+ >+function step1() { >+ root.removeChild(target); >+ runTestCycle(step2, "root.removeChild(target)."); >+ checkLastEntry(entries, 1, [11, 111, 161, 261, 11, 111, 161, 211, 11, 111, 11, 211, true]); >+} >+ >+function step2() { >+ root.scrollTop = 0; >+ root.insertBefore(target, trailingSpace); >+ runTestCycle(step3, "root.insertBefore(target, trailingSpace)."); >+ checkLastEntry(entries, 2, [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, false]); >+} >+ >+function step3() { >+ root.scrollTop = 150; >+ runTestCycle(step4, "root.scrollTop = 150 after reinserting target."); >+ checkLastEntry(entries, 2); >+} >+ >+function step4() { >+ checkLastEntry(entries, 3, [11, 111, 161, 261, 11, 111, 161, 211, 11, 111, 11, 211, true]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/cross-origin-subframe.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/cross-origin-subframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..0cc117cb3a69d0f2ed19505f7d14f824cbad6d71 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/cross-origin-subframe.html >@@ -0,0 +1,125 @@ >+<!DOCTYPE html> >+<div style="height: 200px; width: 100px;"></div> >+<div id="target" style="background-color: green; width:100px; height:100px"></div> >+<div style="height: 200px; width: 100px;"></div> >+ >+<script> >+var port; >+var entries = []; >+var target = document.getElementById('target'); >+var scroller = document.scrollingElement; >+var nextStep; >+ >+function clientRectToJson(rect) { >+ if (!rect) >+ return "null"; >+ return { >+ top: rect.top, >+ right: rect.right, >+ bottom: rect.bottom, >+ left: rect.left >+ }; >+} >+ >+function entryToJson(entry) { >+ return { >+ boundingClientRect: clientRectToJson(entry.boundingClientRect), >+ intersectionRect: clientRectToJson(entry.intersectionRect), >+ rootBounds: clientRectToJson(entry.rootBounds), >+ target: entry.target.id >+ }; >+} >+ >+function coordinatesToClientRectJson(top, right, bottom, left) { >+ return { >+ top: top, >+ right: right, >+ bottom: bottom, >+ left: left >+ }; >+} >+ >+// Note that we never use RAF in this code, because this frame might get render-throttled. >+// Instead of RAF-ing, we just post an empty message to the parent window, which will >+// RAF when it is received, and then send us a message to cause the next step to run. >+ >+// Use a rootMargin here, and verify it does NOT get applied for the cross-origin case. >+var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+}, { rootMargin: "7px" }); >+observer.observe(target); >+ >+function step0() { >+ entries = entries.concat(observer.takeRecords()); >+ nextStep = step1; >+ var expected = [{ >+ boundingClientRect: coordinatesToClientRectJson(8, 208, 108, 308), >+ intersectionRect: coordinatesToClientRectJson(0, 0, 0, 0), >+ rootBounds: "null", >+ target: target.id >+ }]; >+ port.postMessage({ >+ actual: entries.map(entryToJson), >+ expected: expected, >+ description: "First rAF" >+ }, "*"); >+ entries = []; >+ port.postMessage({scrollTo: 200}, "*"); >+} >+ >+function step1() { >+ entries = entries.concat(observer.takeRecords()); >+ port.postMessage({ >+ actual: entries.map(entryToJson), >+ expected: [], >+ description: "topDocument.scrollingElement.scrollTop = 200" >+ }, "*"); >+ entries = []; >+ scroller.scrollTop = 250; >+ nextStep = step2; >+ port.postMessage({}, "*"); >+} >+ >+function step2() { >+ entries = entries.concat(observer.takeRecords()); >+ var expected = [{ >+ boundingClientRect: coordinatesToClientRectJson(-42, 108, 58, 8), >+ intersectionRect: coordinatesToClientRectJson(0, 108, 58, 8), >+ rootBounds: "null", >+ target: target.id >+ }]; >+ port.postMessage({ >+ actual: entries.map(entryToJson), >+ expected: expected, >+ description: "iframeDocument.scrollingElement.scrollTop = 250" >+ }, "*"); >+ entries = []; >+ nextStep = step3; >+ port.postMessage({scrollTo: 100}, "*"); >+} >+ >+function step3() { >+ entries = entries.concat(observer.takeRecords()); >+ var expected = [{ >+ boundingClientRect: coordinatesToClientRectJson(-42, 108, 58, 8), >+ intersectionRect: coordinatesToClientRectJson(0, 0, 0, 0), >+ rootBounds: "null", >+ target: target.id >+ }]; >+ port.postMessage({ >+ actual: entries.map(entryToJson), >+ expected: expected, >+ description: "topDocument.scrollingElement.scrollTop = 100" >+ }, "*"); >+ port.postMessage({DONE: 1}, "*"); >+} >+ >+function handleMessage(event) >+{ >+ port = event.source; >+ nextStep(); >+} >+ >+nextStep = step0; >+window.addEventListener("message", handleMessage); >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/iframe-no-root-subframe.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/iframe-no-root-subframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..ee63a06ca0ff30eb6bc82d28350cf8d85313251b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/iframe-no-root-subframe.html >@@ -0,0 +1,4 @@ >+<!DOCTYPE html> >+<div style="height: 200px; width: 100px;"></div> >+<div id="target" style="background-color: green; width:100px; height:100px"></div> >+<div style="height: 200px; width: 100px;"></div> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/intersection-observer-test-utils.js b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/intersection-observer-test-utils.js >new file mode 100644 >index 0000000000000000000000000000000000000000..5ad811932f06c34f1bb3bfd70094a0cd5c046c56 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/intersection-observer-test-utils.js >@@ -0,0 +1,127 @@ >+// Here's how waitForNotification works: >+// >+// - myTestFunction0() >+// - waitForNotification(myTestFunction1) >+// - requestAnimationFrame() >+// - Modify DOM in a way that should trigger an IntersectionObserver callback. >+// - BeginFrame >+// - requestAnimationFrame handler runs >+// - First step_timeout() >+// - Style, layout, paint >+// - IntersectionObserver generates new notifications >+// - Posts a task to deliver notifications >+// - First step_timeout handler runs >+// - Second step_timeout() >+// - Task to deliver IntersectionObserver notifications runs >+// - IntersectionObserver callbacks run >+// - Second step_timeout handler runs >+// - myTestFunction1() >+// - [optional] waitForNotification(myTestFunction2) >+// - requestAnimationFrame() >+// - Verify newly-arrived IntersectionObserver notifications >+// - [optional] Modify DOM to trigger new notifications >+function waitForNotification(t, f) { >+ requestAnimationFrame(function() { >+ t.step_timeout(function() { t.step_timeout(f); }); >+ }); >+} >+ >+// The timing of when runTestCycle is called is important. It should be >+// called: >+// >+// - Before or during the window load event, or >+// - Inside of a prior runTestCycle callback, *before* any assert_* methods >+// are called. >+// >+// Following these rules will ensure that the test suite will not abort before >+// all test steps have run. >+function runTestCycle(f, description) { >+ async_test(function(t) { >+ waitForNotification(t, t.step_func_done(f)); >+ }, description); >+} >+ >+// Root bounds for a root with an overflow clip as defined by: >+// http://wicg.github.io/IntersectionObserver/#intersectionobserver-root-intersection-rectangle >+function contentBounds(root) { >+ var left = root.offsetLeft + root.clientLeft; >+ var right = left + root.clientWidth; >+ var top = root.offsetTop + root.clientTop; >+ var bottom = top + root.clientHeight; >+ return [left, right, top, bottom]; >+} >+ >+// Root bounds for a root without an overflow clip as defined by: >+// http://wicg.github.io/IntersectionObserver/#intersectionobserver-root-intersection-rectangle >+function borderBoxBounds(root) { >+ var left = root.offsetLeft; >+ var right = left + root.offsetWidth; >+ var top = root.offsetTop; >+ var bottom = top + root.offsetHeight; >+ return [left, right, top, bottom]; >+} >+ >+function clientBounds(element) { >+ var rect = element.getBoundingClientRect(); >+ return [rect.left, rect.right, rect.top, rect.bottom]; >+} >+ >+function rectArea(rect) { >+ return (rect.left - rect.right) * (rect.bottom - rect.top); >+} >+ >+function checkRect(actual, expected, description, all) { >+ if (!expected.length) >+ return; >+ assert_equals(actual.left | 0, expected[0] | 0, description + '.left'); >+ assert_equals(actual.right | 0, expected[1] | 0, description + '.right'); >+ assert_equals(actual.top | 0, expected[2] | 0, description + '.top'); >+ assert_equals(actual.bottom | 0, expected[3] | 0, description + '.bottom'); >+} >+ >+function checkLastEntry(entries, i, expected) { >+ assert_equals(entries.length, i + 1, 'entries.length'); >+ if (expected) { >+ checkRect( >+ entries[i].boundingClientRect, expected.slice(0, 4), >+ 'entries[' + i + '].boundingClientRect', entries[i]); >+ checkRect( >+ entries[i].intersectionRect, expected.slice(4, 8), >+ 'entries[' + i + '].intersectionRect', entries[i]); >+ checkRect( >+ entries[i].rootBounds, expected.slice(8, 12), >+ 'entries[' + i + '].rootBounds', entries[i]); >+ if (expected.length > 12) { >+ assert_equals( >+ entries[i].isIntersecting, expected[12], >+ 'entries[' + i + '].isIntersecting'); >+ } >+ } >+} >+ >+function checkJsonEntry(actual, expected) { >+ checkRect( >+ actual.boundingClientRect, expected.boundingClientRect, >+ 'entry.boundingClientRect'); >+ checkRect( >+ actual.intersectionRect, expected.intersectionRect, >+ 'entry.intersectionRect'); >+ if (actual.rootBounds == 'null') >+ assert_equals(expected.rootBounds, 'null', 'rootBounds is null'); >+ else >+ checkRect(actual.rootBounds, expected.rootBounds, 'entry.rootBounds'); >+ assert_equals(actual.target, expected.target); >+} >+ >+function checkJsonEntries(actual, expected, description) { >+ test(function() { >+ assert_equals(actual.length, expected.length); >+ for (var i = 0; i < actual.length; i++) >+ checkJsonEntry(actual[i], expected[i]); >+ }, description); >+} >+ >+function checkIsIntersecting(entries, i, expected) { >+ assert_equals(entries[i].isIntersecting, expected, >+ 'entries[' + i + '].target.isIntersecting equals ' + expected); >+} >\ No newline at end of file >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/observer-in-iframe-subframe.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/observer-in-iframe-subframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..9d0769ae44a1bb4a6195c006999b0959f706330c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/observer-in-iframe-subframe.html >@@ -0,0 +1,65 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./intersection-observer-test-utils.js"></script> >+ >+<style> >+#root { >+ width: 200px; >+ height: 200px; >+} >+#scroller { >+ width: 160px; >+ height: 200px; >+ overflow-y: scroll; >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+.spacer { >+ height: 300px; >+} >+</style> >+ >+<div id="root"> >+ <div id="scroller"> >+ <div class="spacer"></div> >+ <div id="target"></div> >+ <div class="spacer"></div> >+ </div> >+</div> >+ >+<script> >+setup({message_events: [], output_document: window.parent.document}); >+ >+var entries = []; >+var root, scroller, target; >+ >+runTestCycle(function() { >+ root = document.getElementById("root"); >+ assert_true(!!root, "Root element exists."); >+ scroller = document.getElementById("scroller"); >+ assert_true(!!scroller, "Scroller element exists."); >+ target = document.getElementById("target"); >+ assert_true(!!target, "Target element exists."); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }, {root: root}); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications.") >+ runTestCycle(step1, "First rAF."); >+}, "IntersectionObserver in iframe with explicit root."); >+ >+function step1() { >+ scroller.scrollTop = 250; >+ runTestCycle(step2, "scroller.scrollTop = 250"); >+ checkLastEntry(entries, 0, [8, 108, 308, 408, 0, 0, 0, 0, 8, 208, 8, 208, false]); >+} >+ >+function step2() { >+ checkLastEntry(entries, 1, [8, 108, 58, 158, 8, 108, 58, 158, 8, 208, 8, 208, true]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/timestamp-subframe.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/timestamp-subframe.html >new file mode 100644 >index 0000000000000000000000000000000000000000..143e4f6e23a7688949420a07ccd20e3c211a6f6b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/timestamp-subframe.html >@@ -0,0 +1,28 @@ >+<!DOCTYPE html> >+<style> >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+.spacer { >+ width: height: 100px >+} >+</style> >+ >+<div class="spacer"></div> >+<div id="target"></div> >+<div class="spacer"></div> >+ >+<script> >+document.createObserverCallback = function(entries) { >+ return function(newEntries) { >+ for (var i in newEntries) { >+ entries.push(newEntries[i]); >+ } >+ }; >+} >+document.createObserver = function(callback) { >+ return new IntersectionObserver(callback, {}); >+}; >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..aa1e851e351d4be8830c412cfea0f07947558f60 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/w3c-import.log >@@ -0,0 +1,21 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/web-platform-tests/wpt >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/cross-origin-subframe.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/iframe-no-root-subframe.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/intersection-observer-test-utils.js >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/observer-in-iframe-subframe.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/resources/timestamp-subframe.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/root-margin-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/root-margin-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..5d1e48f94ed374cfc4b44cadfc69138d104e1482 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/root-margin-expected.txt >@@ -0,0 +1,8 @@ >+ >+ >+PASS Root margin tests >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL document.scrollingElement.scrollLeft = 100 assert_equals: entries.length expected 2 but got 0 >+FAIL document.scrollingElement.scrollTop = document.documentElement.clientHeight + 200 assert_equals: entries.length expected 2 but got 0 >+FAIL document.scrollingElement.scrollTop = document.documentElement.clientHeight + 300 assert_equals: entries.length expected 3 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/root-margin.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/root-margin.html >new file mode 100644 >index 0000000000000000000000000000000000000000..c1fffec02becc50ccaad1f8fdaa9ffd16afef11c >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/root-margin.html >@@ -0,0 +1,86 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#target { >+ display: inline-block; >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+.vertical-spacer { >+ height: calc(100vh + 100px); >+} >+.horizontal-spacer { >+ display: inline-block; >+ width: 120vw; >+} >+</style> >+ >+<div class="vertical-spacer"></div> >+<div style="white-space:nowrap;"> >+ <div class="horizontal-spacer"></div> >+ <div id="target"></div> >+ <div class="horizontal-spacer"></div> >+</div> >+<div class="vertical-spacer"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+var target; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ assert_true(!!target, "Target exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }, { rootMargin: "10px 20% 40% 30px" }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "Root margin tests"); >+ >+function step0() { >+ var targetBounds = clientBounds(target); >+ document.scrollingElement.scrollLeft = 100; >+ runTestCycle(step1, "document.scrollingElement.scrollLeft = 100"); >+ checkLastEntry(entries, 0, targetBounds.concat(0, 0, 0, 0, -30, vw * 1.2, -10, vh * 1.4, false)); >+} >+ >+function step1() { >+ var targetBounds = clientBounds(target); >+ var sw = window.innerWidth - document.documentElement.clientWidth; >+ var sh = window.innerHeight - document.documentElement.clientHeight; >+ document.scrollingElement.scrollTop = vh + 200; >+ runTestCycle(step2, "document.scrollingElement.scrollTop = document.documentElement.clientHeight + 200"); >+ checkLastEntry(entries, 1, targetBounds.concat( >+ targetBounds[0], Math.min(targetBounds[1], vw * 1.2), vh + 108 + sh, Math.min(vh + 208 + sw, vh * 1.4), >+ -30, vw * 1.2, -10, vh * 1.4, >+ true >+ )); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = vh + 300; >+ runTestCycle(step3, "document.scrollingElement.scrollTop = document.documentElement.clientHeight + 300"); >+ checkLastEntry(entries, 1); >+} >+ >+function step3() { >+ var targetBounds = clientBounds(target); >+ document.scrollingElement.scrollLeft = 0; >+ document.scrollingElement.scrollTop = 0; >+ checkLastEntry(entries, 2, targetBounds.concat(0, 0, 0, 0, -30, vw * 1.2, -10, vh * 1.4, false)); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-no-root-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-no-root-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..30c7a88cd81649ae47b792a005e53893402d4532 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-no-root-expected.txt >@@ -0,0 +1,6 @@ >+ >+PASS IntersectionObserver in a single document using the implicit root. >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL document.scrollingElement.scrollTop = 300 assert_equals: entries.length expected 2 but got 0 >+FAIL document.scrollingElement.scrollTop = 100 assert_equals: entries.length expected 3 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-no-root.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-no-root.html >new file mode 100644 >index 0000000000000000000000000000000000000000..783880888abdcdd870e2edb2358f619d434ad51f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-no-root.html >@@ -0,0 +1,61 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+</style> >+ >+<div class="spacer"></div> >+<div id="target"></div> >+<div class="spacer"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+var target; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ assert_true(!!target, "target exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "IntersectionObserver in a single document using the implicit root."); >+ >+function step0() { >+ document.scrollingElement.scrollTop = 300; >+ runTestCycle(step1, "document.scrollingElement.scrollTop = 300"); >+ checkLastEntry(entries, 0, [8, 108, vh + 108, vh + 208, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+ >+function step1() { >+ document.scrollingElement.scrollTop = 100; >+ runTestCycle(step2, "document.scrollingElement.scrollTop = 100"); >+ checkLastEntry(entries, 1, [8, 108, vh - 192, vh - 92, 8, 108, vh - 192, vh - 92, 0, vw, 0, vh, true]); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = 0; >+ checkLastEntry(entries, 2, [8, 108, vh + 8, vh + 108, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..6a18d4d560fa6a385eb8b4dc7ba59be252e5202a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root-expected.txt >@@ -0,0 +1,9 @@ >+ >+PASS IntersectionObserver in a single document with explicit root. >+FAIL First rAF assert_equals: entries.length expected 1 but got 0 >+FAIL document.scrollingElement.scrollTop = window.innerHeight. assert_equals: No notifications after scrolling frame. expected 1 but got 0 >+FAIL root.scrollTop = 150 with root scrolled into view. assert_equals: entries.length expected 2 but got 0 >+FAIL document.scrollingElement.scrollTop = 0. assert_equals: entries.length expected 2 but got 0 >+FAIL root.scrollTop = 0 assert_equals: entries.length expected 3 but got 0 >+FAIL root.scrollTop = 150 with root scrolled out of view. assert_equals: entries.length expected 4 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root.html >new file mode 100644 >index 0000000000000000000000000000000000000000..40467be72b4f298bb9d8704cbb938391e395a3ef >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root.html >@@ -0,0 +1,90 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+#root { >+ display: inline-block; >+ overflow-y: scroll; >+ height: 200px; >+ border: 3px solid black; >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+</style> >+ >+<div class="spacer"></div> >+<div id="root"> >+ <div style="height: 300px;"></div> >+ <div id="target"></div> >+</div> >+<div class="spacer"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+var root, target; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ assert_true(!!target, "target exists"); >+ root = document.getElementById("root"); >+ assert_true(!!root, "root exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }, { root: root }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF"); >+}, "IntersectionObserver in a single document with explicit root."); >+ >+function step0() { >+ document.scrollingElement.scrollTop = vh; >+ runTestCycle(step1, "document.scrollingElement.scrollTop = window.innerHeight."); >+ checkLastEntry(entries, 0, [ 11, 111, vh + 411, vh + 511, 0, 0, 0, 0, 11, 111, vh + 111, vh + 311, false]); >+} >+ >+function step1() { >+ root.scrollTop = 150; >+ runTestCycle(step2, "root.scrollTop = 150 with root scrolled into view."); >+ assert_equals(entries.length, 1, "No notifications after scrolling frame."); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = 0; >+ runTestCycle(step3, "document.scrollingElement.scrollTop = 0."); >+ checkLastEntry(entries, 1, [11, 111, 261, 361, 11, 111, 261, 311, 11, 111, 111, 311, true]); >+} >+ >+function step3() { >+ root.scrollTop = 0; >+ runTestCycle(step4, "root.scrollTop = 0"); >+ checkLastEntry(entries, 1); >+} >+ >+function step4() { >+ root.scrollTop = 150; >+ runTestCycle(step5, "root.scrollTop = 150 with root scrolled out of view."); >+ checkLastEntry(entries, 2, [11, 111, vh + 411, vh + 511, 0, 0, 0, 0, 11, 111, vh + 111, vh + 311, false]); >+} >+ >+// This tests that notifications are generated even when the root element is off screen. >+function step5() { >+ checkLastEntry(entries, 3, [11, 111, vh + 261, vh + 361, 11, 111, vh + 261, vh + 311, 11, 111, vh + 111, vh + 311, true]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..40b11a681301511df142629b7f6f01d72645c99f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target-expected.txt >@@ -0,0 +1,6 @@ >+ >+PASS Observing a zero-area target. >+FAIL First rAF assert_equals: entries.length expected 1 but got 0 >+FAIL document.scrollingElement.scrollTop = 300 assert_equals: entries.length expected 2 but got 0 >+FAIL document.scrollingElement.scrollTop = 100 assert_equals: entries.length expected 3 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d835b40634d33d0c7dd912ea81d4ef6d42af7c1b >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target.html >@@ -0,0 +1,61 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+#target { >+ width: 0px; >+ height: 0px; >+ background-color: green; >+} >+</style> >+ >+<div class="spacer"></div> >+<div id="target"></div> >+<div class="spacer"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+var target; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ assert_true(!!target, "Target exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF"); >+}, "Observing a zero-area target."); >+ >+function step0() { >+ document.scrollingElement.scrollTop = 300; >+ runTestCycle(step1, "document.scrollingElement.scrollTop = 300"); >+ checkLastEntry(entries, 0, [8, 8, vh + 108, vh + 108, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+ >+function step1() { >+ document.scrollingElement.scrollTop = 100; >+ runTestCycle(step2, "document.scrollingElement.scrollTop = 100"); >+ checkLastEntry(entries, 1, [8, 8, vh - 192, vh - 192, 8, 8, vh - 192, vh - 192, 0, vw, 0, vh, true]); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = 0; >+ checkLastEntry(entries, 2, [8, 8, vh + 8, vh + 8, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/shadow-content-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/shadow-content-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..bd0179886430c5287a3f8d1499f22d6640446e4f >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/shadow-content-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS Observing a target inside shadow DOM. >+FAIL First rAF after creating shadow DOM. assert_equals: entries.length expected 1 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/shadow-content.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/shadow-content.html >new file mode 100644 >index 0000000000000000000000000000000000000000..d049c70919e129fa6c335e8601f6ce6a6cd73a9d >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/shadow-content.html >@@ -0,0 +1,44 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+</style> >+ >+<div id="host"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+var target; >+ >+runTestCycle(function() { >+ var shadowHost = document.getElementById("host"); >+ assert_true(!!shadowHost, "Host exists"); >+ var shadowRoot = shadowHost.attachShadow({ mode: "open" }); >+ assert_true(!!shadowRoot, "Shadow root exists"); >+ shadowRoot.innerHTML = "<div id='target' style='width: 100px; height: 100px; background-color: green;'></div>"; >+ target = shadowRoot.getElementById("target"); >+ assert_true(!!target, "target exists"); >+ >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF after creating shadow DOM."); >+}, "Observing a target inside shadow DOM."); >+ >+function step0() { >+ checkLastEntry(entries, 0, [8, 108, 8, 108, 8, 108, 8, 108, 0, vw, 0, vh, true]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..a713ec2acf269c98d1140abfe444e87f446b6a86 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target-expected.txt >@@ -0,0 +1,7 @@ >+ >+ >+PASS IntersectionObserver observing a br element. >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL document.scrollingElement.scrollTop = 300 assert_equals: entries.length expected 2 but got 0 >+FAIL document.scrollingElement.scrollTop = 100 assert_equals: entries.length expected 3 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target.html >new file mode 100644 >index 0000000000000000000000000000000000000000..13dc3abea2d8b0438ac76e9da974718778bcbb12 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target.html >@@ -0,0 +1,62 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+</style> >+ >+<div class="spacer"></div> >+<br id="target"> >+<div class="spacer"></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+var target; >+var tw, th; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ let target_rect = target.getBoundingClientRect(); >+ tw = target_rect.width; >+ th = target_rect.height; >+ assert_true(!!target, "target exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "IntersectionObserver observing a br element."); >+ >+function step0() { >+ document.scrollingElement.scrollTop = 300; >+ runTestCycle(step1, "document.scrollingElement.scrollTop = 300"); >+ // The numbers in brackets are target client rect; intersection rect; >+ // and root bounds. >+ checkLastEntry(entries, 0, [8, 8 + tw, vh + 108, vh + 108 + th, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+ >+function step1() { >+ document.scrollingElement.scrollTop = 100; >+ runTestCycle(step2, "document.scrollingElement.scrollTop = 100"); >+ checkLastEntry(entries, 1, [8, 8 + tw, vh - 192, vh - 192 + th, 8, 8 + tw, vh - 192, vh - 192 + th, 0, vw, 0, vh, true]); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = 0; >+ checkLastEntry(entries, 2, [8, 8 + tw, vh + 8, vh + 8 + th, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/timestamp-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/timestamp-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..c8e113505b187ab19d006507aec96bfa8b56a692 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/timestamp-expected.txt >@@ -0,0 +1,6 @@ >+ >+ >+PASS Check that timestamps correspond to the to execution context that created the observer. >+FAIL First rAF after iframe is loaded. assert_equals: One notification to top window observer. expected 1 but got 0 >+FAIL Generate notifications. undefined is not an object (evaluating 'topWindowEntries[1].time') >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/timestamp.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/timestamp.html >new file mode 100644 >index 0000000000000000000000000000000000000000..be1980040d298b4d6d0055976ed42c202dec9888 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/timestamp.html >@@ -0,0 +1,99 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+.spacer { >+ height: calc(100vh + 100px); >+} >+ >+</style> >+<div id="leading-space" class="spacer"></div> >+<div id="trailing-space" class="spacer"></div> >+ >+<script> >+// Pick this number to be comfortably greater than the length of two frames at 60Hz. >+var timeSkew = 40; >+ >+var topWindowEntries = []; >+var iframeWindowEntries = []; >+var targetIframe; >+var topWindowTimeBeforeNotification; >+var iframeWindowTimeBeforeNotification; >+ >+async_test(function(t) { >+ t.step_timeout(function() { >+ targetIframe = document.createElement("iframe"); >+ assert_true(!!targetIframe, "iframe exists"); >+ targetIframe.src = "resources/timestamp-subframe.html"; >+ var trailingSpace = document.getElementById("trailing-space"); >+ assert_true(!!trailingSpace, "trailing-space exists"); >+ trailingSpace.parentNode.insertBefore(targetIframe, trailingSpace); >+ targetIframe.onload = function() { >+ var target = targetIframe.contentDocument.getElementById("target"); >+ var iframeScroller = targetIframe.contentDocument.scrollingElement; >+ >+ // Observer created here, callback created in iframe context. Timestamps should be >+ // from this window. >+ var observer = new IntersectionObserver( >+ targetIframe.contentDocument.createObserverCallback(topWindowEntries), {}); >+ assert_true(!!observer, "Observer exists"); >+ observer.observe(target); >+ >+ // Callback created here, observer created in iframe. Timestamps should be >+ // from iframe window. >+ observer = targetIframe.contentDocument.createObserver(function(newEntries) { >+ iframeWindowEntries = iframeWindowEntries.concat(newEntries); >+ }); >+ observer.observe(target); >+ runTestCycle(step1, "First rAF after iframe is loaded."); >+ t.done(); >+ }; >+ }, timeSkew); >+}, "Check that timestamps correspond to the to execution context that created the observer."); >+ >+function step1() { >+ document.scrollingElement.scrollTop = 200; >+ targetIframe.contentDocument.scrollingElement.scrollTop = 250; >+ topWindowTimeBeforeNotification = performance.now(); >+ iframeWindowTimeBeforeNotification = targetIframe.contentWindow.performance.now(); >+ runTestCycle(step2, "Generate notifications."); >+ assert_equals(topWindowEntries.length, 1, "One notification to top window observer."); >+ assert_equals(iframeWindowEntries.length, 1, "One notification to iframe observer."); >+} >+ >+function step2() { >+ document.scrollingElement.scrollTop = 0; >+ var topWindowTimeAfterNotification = performance.now(); >+ var iframeWindowTimeAfterNotification = targetIframe.contentWindow.performance.now(); >+ >+ assert_approx_equals( >+ topWindowEntries[1].time - topWindowTimeBeforeNotification, >+ iframeWindowEntries[1].time - iframeWindowTimeBeforeNotification, >+ // Since all intersections are computed in a tight loop between 2 frames, >+ // an epsilon of 16ms (the length of one frame at 60Hz) turned out to be >+ // reliable, even at slow frame rates. >+ 16, >+ "Notification times are relative to the expected time origins"); >+ >+ assert_equals(topWindowEntries.length, 2, "Top window observer has two notifications."); >+ assert_between_inclusive( >+ topWindowEntries[1].time, >+ topWindowTimeBeforeNotification, >+ topWindowTimeAfterNotification, >+ "Notification to top window observer is within the expected range."); >+ >+ assert_equals(iframeWindowEntries.length, 2, "Iframe observer has two notifications."); >+ assert_between_inclusive( >+ iframeWindowEntries[1].time, >+ iframeWindowTimeBeforeNotification, >+ iframeWindowTimeAfterNotification, >+ "Notification to iframe observer is within the expected range."); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..eabc5778c39717e2fe5ef82f3960213759eebb79 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root-expected.txt >@@ -0,0 +1,5 @@ >+ >+PASS Test that border bounding box is used to calculate intersection with a non-scrolling root. >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+FAIL target.style.transform = 'translateY(195px)' assert_equals: entries.length expected 2 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root.html >new file mode 100644 >index 0000000000000000000000000000000000000000..24ae01cedc2ef95f6dd04a722d47aefa30e8b777 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root.html >@@ -0,0 +1,57 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#root { >+ overflow: visible; >+ height: 200px; >+ width: 160px; >+ border: 7px solid black; >+} >+#target { >+ width: 100px; >+ height: 100px; >+ background-color: green; >+} >+</style> >+ >+<div id="root"> >+ <div id="target" style="transform: translateY(300px)"></div> >+</div> >+ >+<script> >+var entries = []; >+var target; >+ >+runTestCycle(function() { >+ target = document.getElementById("target"); >+ assert_true(!!target, "target exists"); >+ var root = document.getElementById("root"); >+ assert_true(!!root, "root exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }, {root: root}); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "Test that border bounding box is used to calculate intersection with a non-scrolling root."); >+ >+function step0() { >+ target.style.transform = "translateY(195px)"; >+ runTestCycle(step1, "target.style.transform = 'translateY(195px)'"); >+ checkLastEntry(entries, 0, [15, 115, 315, 415, 0, 0, 0, 0, 8, 182, 8, 222, false]); >+} >+ >+function step1() { >+ target.style.transform = ""; >+ checkLastEntry(entries, 1, [15, 115, 210, 310, 15, 115, 210, 222, 8, 182, 8, 222, true]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/w3c-import.log b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/w3c-import.log >new file mode 100644 >index 0000000000000000000000000000000000000000..ac05011f80e2ea2cff4da6ba63cc4a8a3429ba5a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/w3c-import.log >@@ -0,0 +1,45 @@ >+The tests in this directory were imported from the W3C repository. >+Do NOT modify these tests directly in WebKit. >+Instead, create a pull request on the WPT github: >+ https://github.com/web-platform-tests/wpt >+ >+Then run the Tools/Scripts/import-w3c-tests in WebKit to reimport >+ >+Do NOT modify or remove this file. >+ >+------------------------------------------------------------------------ >+Properties requiring vendor prefixes: >+None >+Property values requiring vendor prefixes: >+None >+------------------------------------------------------------------------ >+List of files: >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/META.yml >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/bounding-box.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/client-rect.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/containing-block.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/cross-origin-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/disconnect.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/display-none.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/edge-inclusive-intersection.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/idlharness.window.js >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/iframe-no-root.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/inline-client-rect.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/isIntersecting-change-events.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-targets.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/multiple-thresholds.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-attributes.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-exceptions.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-in-iframe.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/observer-without-js-reference.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/remove-element.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/root-margin.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-no-root.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-root.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/same-document-zero-size-target.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/shadow-content.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/text-target.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/timestamp.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/unclipped-root.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-hidden.html >+/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible.html >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-hidden-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-hidden-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..2507ee2bf3746e5898b1df36db3f85214b5d4551 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-hidden-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS A zero-area hidden target should not be intersecting. >+FAIL First rAF. assert_equals: entries.length expected 1 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-hidden.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-hidden.html >new file mode 100644 >index 0000000000000000000000000000000000000000..e007040c8fe2e25bfca8fbe450b06a26934ad186 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-hidden.html >@@ -0,0 +1,43 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#target { >+ width: 0px; >+ height: 0px; >+ position: fixed; >+ top: -1000px; >+} >+</style> >+ >+<div id='target'></div> >+ >+<script> >+var vw = document.documentElement.clientWidth; >+var vh = document.documentElement.clientHeight; >+ >+var entries = []; >+ >+runTestCycle(function() { >+ var target = document.getElementById('target'); >+ assert_true(!!target, "target exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF."); >+}, "A zero-area hidden target should not be intersecting."); >+ >+function step0() { >+ checkLastEntry(entries, 0, [8, 8, -1000, -1000, 0, 0, 0, 0, 0, vw, 0, vh, false]); >+} >+</script> >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt >new file mode 100644 >index 0000000000000000000000000000000000000000..d4ba44456f76740b7e16d11667efebaad8ce358a >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible-expected.txt >@@ -0,0 +1,4 @@ >+ >+PASS Ensure that a zero-area target intersecting root generates a notification with intersectionRatio == 1 >+FAIL First rAF should generate a notification. assert_equals: One notification. expected 1 but got 0 >+ >diff --git a/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible.html b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible.html >new file mode 100644 >index 0000000000000000000000000000000000000000..6bf1297fe453dce1d748d047f54ec427289d8df4 >--- /dev/null >+++ b/LayoutTests/imported/w3c/web-platform-tests/intersection-observer/zero-area-element-visible.html >@@ -0,0 +1,39 @@ >+<!DOCTYPE html> >+<script src="/resources/testharness.js"></script> >+<script src="/resources/testharnessreport.js"></script> >+<script src="./resources/intersection-observer-test-utils.js"></script> >+ >+<style> >+pre, #log { >+ position: absolute; >+ top: 0; >+ left: 200px; >+} >+#target { >+ width: 0px; >+ height: 0px; >+} >+</style> >+ >+<div id='target'></div> >+ >+<script> >+var entries = []; >+ >+runTestCycle(function() { >+ var target = document.getElementById('target'); >+ assert_true(!!target, "target exists"); >+ var observer = new IntersectionObserver(function(changes) { >+ entries = entries.concat(changes) >+ }); >+ observer.observe(target); >+ entries = entries.concat(observer.takeRecords()); >+ assert_equals(entries.length, 0, "No initial notifications."); >+ runTestCycle(step0, "First rAF should generate a notification."); >+}, "Ensure that a zero-area target intersecting root generates a notification with intersectionRatio == 1"); >+ >+function step0() { >+ assert_equals(entries.length, 1, "One notification."); >+ assert_equals(entries[0].intersectionRatio, 1, "intersectionRatio == 1"); >+} >+</script>
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 188416
: 346790