From 7fd8f7b18836929349333c31306feb9526cc54a0 Mon Sep 17 00:00:00 2001 From: "L. David Baron" Date: Sat, 20 May 2017 10:15:26 -0700 Subject: [PATCH 01/12] Bug 1365449 - Reflow absolutely positioned children when they need to be repaginated. r=mats This fixes the failure of layout/reftests/pagination/dynamic-abspos-overflow-01-cols.xhtml with the primary patch in bug 1308876. Since it is an independently testable failure, I'm posting it as a separate bug. Without the patch, both reftests fail to rewrap in response to the dynamic change, and the inner dark blue absolutely positioned element remains wrapped at the wrong position when the inner light blue relatively positioned element rewraps. (I tested this only outside of the reftest harness, but that should be sufficient.) I verified manually that the height conditions were correct by modifying both reftests to add some padding and border to #relpos and margin to #abspos, changing the height of #abspos so that it was either exactly at or just above the threshold where reflow was needed, and using GECKO_DISPLAY_REFLOW_RULES_FILE debugging to verify that the reflow of the absolutely positioned element did or didn't happen as expected. MozReview-Commit-ID: 6ISgSEYyMiN --HG-- extra : transplant_source : %93%86%8Csr_L%83%F2OJ%DC%7F%3D%7D%BC%9C%A6%1F0 --- layout/generic/nsAbsoluteContainingBlock.cpp | 32 ++++++++++-- .../abspos-breaking-dynamic-001-ref.html | 41 ++++++++++++++++ .../abspos-breaking-dynamic-001.html | 44 +++++++++++++++++ .../abspos-breaking-dynamic-002-ref.html | 39 +++++++++++++++ .../abspos-breaking-dynamic-002.html | 44 +++++++++++++++++ .../abspos-breaking-dynamic-003-ref.html | 49 +++++++++++++++++++ .../abspos-breaking-dynamic-003.html | 49 +++++++++++++++++++ layout/reftests/pagination/reftest.list | 3 ++ 8 files changed, 298 insertions(+), 3 deletions(-) create mode 100644 layout/reftests/pagination/abspos-breaking-dynamic-001-ref.html create mode 100644 layout/reftests/pagination/abspos-breaking-dynamic-001.html create mode 100644 layout/reftests/pagination/abspos-breaking-dynamic-002-ref.html create mode 100644 layout/reftests/pagination/abspos-breaking-dynamic-002.html create mode 100644 layout/reftests/pagination/abspos-breaking-dynamic-003-ref.html create mode 100644 layout/reftests/pagination/abspos-breaking-dynamic-003.html diff --git a/layout/generic/nsAbsoluteContainingBlock.cpp b/layout/generic/nsAbsoluteContainingBlock.cpp index 09747e39929e..007369ca0a81 100644 --- a/layout/generic/nsAbsoluteContainingBlock.cpp +++ b/layout/generic/nsAbsoluteContainingBlock.cpp @@ -113,7 +113,7 @@ nsAbsoluteContainingBlock::RemoveFrame(nsIFrame* aDelegatingFrame, void nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, nsPresContext* aPresContext, - const ReflowInput& aReflowInput, + const ReflowInput& aReflowInput, nsReflowStatus& aReflowStatus, const nsRect& aContainingBlock, AbsPosReflowFlags aFlags, @@ -130,11 +130,37 @@ nsAbsoluteContainingBlock::Reflow(nsContainerFrame* aDelegatingFrame, FrameDependsOnContainer(kidFrame, !!(aFlags & AbsPosReflowFlags::eCBWidthChanged), !!(aFlags & AbsPosReflowFlags::eCBHeightChanged)); + nscoord availBSize = aReflowInput.AvailableBSize(); + const nsRect& cb = isGrid ? nsGridContainerFrame::GridItemCB(kidFrame) + : aContainingBlock; + WritingMode containerWM = aReflowInput.GetWritingMode(); + if (!kidNeedsReflow && availBSize != NS_UNCONSTRAINEDSIZE) { + // If we need to redo pagination on the kid, we need to reflow it. + // This can happen either if the available height shrunk and the + // kid (or its overflow that creates overflow containers) is now + // too large to fit in the available height, or if the available + // height has increased and the kid has a next-in-flow that we + // might need to pull from. + WritingMode kidWM = kidFrame->GetWritingMode(); + if (containerWM.GetBlockDir() != kidWM.GetBlockDir()) { + // Not sure what the right test would be here. + kidNeedsReflow = true; + } else { + nscoord kidBEnd = kidFrame->GetLogicalRect(cb.Size()).BEnd(kidWM); + nscoord kidOverflowBEnd = + LogicalRect(containerWM, + kidFrame->GetScrollableOverflowRectRelativeToParent(), + aContainingBlock.Size()).BEnd(containerWM); + MOZ_ASSERT(kidOverflowBEnd >= kidBEnd); + if (kidOverflowBEnd > availBSize || + (kidBEnd < availBSize && kidFrame->GetNextInFlow())) { + kidNeedsReflow = true; + } + } + } if (kidNeedsReflow && !aPresContext->HasPendingInterrupt()) { // Reflow the frame nsReflowStatus kidStatus; - const nsRect& cb = isGrid ? nsGridContainerFrame::GridItemCB(kidFrame) - : aContainingBlock; ReflowAbsoluteFrame(aDelegatingFrame, aPresContext, aReflowInput, cb, aFlags, kidFrame, kidStatus, aOverflowAreas); nsIFrame* nextFrame = kidFrame->GetNextInFlow(); diff --git a/layout/reftests/pagination/abspos-breaking-dynamic-001-ref.html b/layout/reftests/pagination/abspos-breaking-dynamic-001-ref.html new file mode 100644 index 000000000000..e94b3eb94aa0 --- /dev/null +++ b/layout/reftests/pagination/abspos-breaking-dynamic-001-ref.html @@ -0,0 +1,41 @@ + +Test for dynamic re-pagination of absolutely positioned elements + + + +
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/pagination/abspos-breaking-dynamic-001.html b/layout/reftests/pagination/abspos-breaking-dynamic-001.html new file mode 100644 index 000000000000..375273018277 --- /dev/null +++ b/layout/reftests/pagination/abspos-breaking-dynamic-001.html @@ -0,0 +1,44 @@ + +Test for dynamic re-pagination of absolutely positioned elements + + + +
+
+
+
+
+ + diff --git a/layout/reftests/pagination/abspos-breaking-dynamic-002-ref.html b/layout/reftests/pagination/abspos-breaking-dynamic-002-ref.html new file mode 100644 index 000000000000..1399f3c52731 --- /dev/null +++ b/layout/reftests/pagination/abspos-breaking-dynamic-002-ref.html @@ -0,0 +1,39 @@ + +Test for dynamic re-pagination of absolutely positioned elements + + + +
+
+
+
+
+
+
+
diff --git a/layout/reftests/pagination/abspos-breaking-dynamic-002.html b/layout/reftests/pagination/abspos-breaking-dynamic-002.html new file mode 100644 index 000000000000..52c50786cc59 --- /dev/null +++ b/layout/reftests/pagination/abspos-breaking-dynamic-002.html @@ -0,0 +1,44 @@ + +Test for dynamic re-pagination of absolutely positioned elements + + + +
+
+
+
+
+ + diff --git a/layout/reftests/pagination/abspos-breaking-dynamic-003-ref.html b/layout/reftests/pagination/abspos-breaking-dynamic-003-ref.html new file mode 100644 index 000000000000..bccffbb2ecd0 --- /dev/null +++ b/layout/reftests/pagination/abspos-breaking-dynamic-003-ref.html @@ -0,0 +1,49 @@ + +Test for dynamic re-pagination of absolutely positioned elements + + + +
+
+
+
+
+
+
+
+
+
+
+
diff --git a/layout/reftests/pagination/abspos-breaking-dynamic-003.html b/layout/reftests/pagination/abspos-breaking-dynamic-003.html new file mode 100644 index 000000000000..d5005f407fa5 --- /dev/null +++ b/layout/reftests/pagination/abspos-breaking-dynamic-003.html @@ -0,0 +1,49 @@ + +Test for dynamic re-pagination of absolutely positioned elements + + + +
+
+
+
+
+ + diff --git a/layout/reftests/pagination/reftest.list b/layout/reftests/pagination/reftest.list index 1579ceec74f8..cef819182b6f 100644 --- a/layout/reftests/pagination/reftest.list +++ b/layout/reftests/pagination/reftest.list @@ -13,6 +13,9 @@ pref(layout.css.box-decoration-break.enabled,true) == abspos-breaking-008.html a pref(layout.css.box-decoration-break.enabled,true) == abspos-breaking-009.html abspos-breaking-009-ref.html pref(layout.css.box-decoration-break.enabled,true) == abspos-breaking-010.html abspos-breaking-010-ref.html == abspos-breaking-011.html abspos-breaking-011-ref.html +== abspos-breaking-dynamic-001.html abspos-breaking-dynamic-001-ref.html +== abspos-breaking-dynamic-002.html abspos-breaking-dynamic-002-ref.html +== abspos-breaking-dynamic-003.html abspos-breaking-dynamic-003-ref.html == abspos-overflow-01.xhtml abspos-overflow-01.ref.xhtml == abspos-overflow-01-cols.xhtml abspos-overflow-01-cols.ref.xhtml == border-breaking-000-cols.xhtml border-breaking-000-cols.ref.xhtml From c745ceee904f70eb72ffa107b14faf9b76edff4e Mon Sep 17 00:00:00 2001 From: Tobias Schneider Date: Tue, 16 May 2017 21:23:20 -0700 Subject: [PATCH 02/12] Bug 1358666 - (intersection-observer) Import web-platform tests. r=jet --- testing/web-platform/meta/MANIFEST.json | 274 ++++++++++++++++++ .../meta/intersection-observer/__dir__.ini | 1 + .../client-rect.html.ini | 2 + .../containing-block.html.ini | 3 + .../cross-origin-iframe.html.ini | 3 + .../intersection-observer/disconnect.html.ini | 3 + .../display-none.html.ini | 3 + .../edge-inclusive-intersection.html.ini | 5 + .../iframe-no-root.html.ini | 5 + .../multiple-targets.html.ini | 5 + .../multiple-thresholds.html.ini | 3 + .../observer-attributes.html.ini | 2 + .../observer-exceptions.html.ini | 2 + .../observer-in-iframe.html.ini | 2 + .../observer-without-js-reference.html.ini | 3 + .../remove-element.html.ini | 5 + .../root-margin.html.ini | 3 + .../same-document-no-root.html.ini | 3 + .../same-document-root.html.ini | 5 + .../same-document-zero-size-target.html.ini | 3 + .../shadow-content.html.ini | 4 + .../intersection-observer/timestamp.html.ini | 3 + .../unclipped-root.html.ini | 5 + .../zero-area-element-hidden.html.ini | 3 + .../zero-area-element-visible.html.ini | 5 + .../intersection-observer/client-rect.html | 45 +++ .../containing-block.html | 73 +++++ .../cross-origin-iframe.html | 52 ++++ .../intersection-observer/disconnect.html | 53 ++++ .../intersection-observer/display-none.html | 54 ++++ .../edge-inclusive-intersection.html | 66 +++++ .../intersection-observer/iframe-no-root.html | 71 +++++ .../multiple-targets.html | 80 +++++ .../multiple-thresholds.html | 96 ++++++ .../observer-attributes.html | 31 ++ .../observer-exceptions.html | 48 +++ .../observer-in-iframe.html | 9 + .../observer-without-js-reference.html | 50 ++++ .../intersection-observer/remove-element.html | 82 ++++++ .../resources/cross-origin-subframe.html | 125 ++++++++ .../resources/iframe-no-root-subframe.html | 4 + .../intersection-observer-test-utils.js | 122 ++++++++ .../observer-in-iframe-subframe.html | 65 +++++ .../resources/timestamp-subframe.html | 28 ++ .../intersection-observer/root-margin.html | 86 ++++++ .../same-document-no-root.html | 61 ++++ .../same-document-root.html | 90 ++++++ .../same-document-zero-size-target.html | 61 ++++ .../intersection-observer/shadow-content.html | 44 +++ .../intersection-observer/timestamp.html | 98 +++++++ .../intersection-observer/unclipped-root.html | 57 ++++ .../zero-area-element-hidden.html | 43 +++ .../zero-area-element-visible.html | 39 +++ 53 files changed, 2088 insertions(+) create mode 100644 testing/web-platform/meta/intersection-observer/__dir__.ini create mode 100644 testing/web-platform/meta/intersection-observer/client-rect.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/containing-block.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/cross-origin-iframe.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/disconnect.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/display-none.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/edge-inclusive-intersection.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/iframe-no-root.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/multiple-targets.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/multiple-thresholds.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/observer-attributes.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/observer-exceptions.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/observer-in-iframe.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/observer-without-js-reference.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/remove-element.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/root-margin.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/same-document-no-root.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/same-document-root.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/same-document-zero-size-target.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/shadow-content.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/timestamp.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/unclipped-root.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/zero-area-element-hidden.html.ini create mode 100644 testing/web-platform/meta/intersection-observer/zero-area-element-visible.html.ini create mode 100644 testing/web-platform/tests/intersection-observer/client-rect.html create mode 100644 testing/web-platform/tests/intersection-observer/containing-block.html create mode 100644 testing/web-platform/tests/intersection-observer/cross-origin-iframe.html create mode 100644 testing/web-platform/tests/intersection-observer/disconnect.html create mode 100644 testing/web-platform/tests/intersection-observer/display-none.html create mode 100644 testing/web-platform/tests/intersection-observer/edge-inclusive-intersection.html create mode 100644 testing/web-platform/tests/intersection-observer/iframe-no-root.html create mode 100644 testing/web-platform/tests/intersection-observer/multiple-targets.html create mode 100644 testing/web-platform/tests/intersection-observer/multiple-thresholds.html create mode 100644 testing/web-platform/tests/intersection-observer/observer-attributes.html create mode 100644 testing/web-platform/tests/intersection-observer/observer-exceptions.html create mode 100644 testing/web-platform/tests/intersection-observer/observer-in-iframe.html create mode 100644 testing/web-platform/tests/intersection-observer/observer-without-js-reference.html create mode 100644 testing/web-platform/tests/intersection-observer/remove-element.html create mode 100644 testing/web-platform/tests/intersection-observer/resources/cross-origin-subframe.html create mode 100644 testing/web-platform/tests/intersection-observer/resources/iframe-no-root-subframe.html create mode 100644 testing/web-platform/tests/intersection-observer/resources/intersection-observer-test-utils.js create mode 100644 testing/web-platform/tests/intersection-observer/resources/observer-in-iframe-subframe.html create mode 100644 testing/web-platform/tests/intersection-observer/resources/timestamp-subframe.html create mode 100644 testing/web-platform/tests/intersection-observer/root-margin.html create mode 100644 testing/web-platform/tests/intersection-observer/same-document-no-root.html create mode 100644 testing/web-platform/tests/intersection-observer/same-document-root.html create mode 100644 testing/web-platform/tests/intersection-observer/same-document-zero-size-target.html create mode 100644 testing/web-platform/tests/intersection-observer/shadow-content.html create mode 100644 testing/web-platform/tests/intersection-observer/timestamp.html create mode 100644 testing/web-platform/tests/intersection-observer/unclipped-root.html create mode 100644 testing/web-platform/tests/intersection-observer/zero-area-element-hidden.html create mode 100644 testing/web-platform/tests/intersection-observer/zero-area-element-visible.html diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json index eacbecc88c80..af30b6e7cdcd 100644 --- a/testing/web-platform/meta/MANIFEST.json +++ b/testing/web-platform/meta/MANIFEST.json @@ -58563,6 +58563,36 @@ {} ] ], + "intersection-observer/observer-in-iframe.html": [ + [ + {} + ] + ], + "intersection-observer/resources/cross-origin-subframe.html": [ + [ + {} + ] + ], + "intersection-observer/resources/iframe-no-root-subframe.html": [ + [ + {} + ] + ], + "intersection-observer/resources/intersection-observer-test-utils.js": [ + [ + {} + ] + ], + "intersection-observer/resources/observer-in-iframe-subframe.html": [ + [ + {} + ] + ], + "intersection-observer/resources/timestamp-subframe.html": [ + [ + {} + ] + ], "js/builtins/Math.maxmin.js": [ [ {} @@ -104111,6 +104141,138 @@ {} ] ], + "intersection-observer/client-rect.html": [ + [ + "/intersection-observer/client-rect.html", + {} + ] + ], + "intersection-observer/containing-block.html": [ + [ + "/intersection-observer/containing-block.html", + {} + ] + ], + "intersection-observer/cross-origin-iframe.html": [ + [ + "/intersection-observer/cross-origin-iframe.html", + {} + ] + ], + "intersection-observer/disconnect.html": [ + [ + "/intersection-observer/disconnect.html", + {} + ] + ], + "intersection-observer/display-none.html": [ + [ + "/intersection-observer/display-none.html", + {} + ] + ], + "intersection-observer/edge-inclusive-intersection.html": [ + [ + "/intersection-observer/edge-inclusive-intersection.html", + {} + ] + ], + "intersection-observer/iframe-no-root.html": [ + [ + "/intersection-observer/iframe-no-root.html", + {} + ] + ], + "intersection-observer/multiple-targets.html": [ + [ + "/intersection-observer/multiple-targets.html", + {} + ] + ], + "intersection-observer/multiple-thresholds.html": [ + [ + "/intersection-observer/multiple-thresholds.html", + {} + ] + ], + "intersection-observer/observer-attributes.html": [ + [ + "/intersection-observer/observer-attributes.html", + {} + ] + ], + "intersection-observer/observer-exceptions.html": [ + [ + "/intersection-observer/observer-exceptions.html", + {} + ] + ], + "intersection-observer/observer-without-js-reference.html": [ + [ + "/intersection-observer/observer-without-js-reference.html", + {} + ] + ], + "intersection-observer/remove-element.html": [ + [ + "/intersection-observer/remove-element.html", + {} + ] + ], + "intersection-observer/root-margin.html": [ + [ + "/intersection-observer/root-margin.html", + {} + ] + ], + "intersection-observer/same-document-no-root.html": [ + [ + "/intersection-observer/same-document-no-root.html", + {} + ] + ], + "intersection-observer/same-document-root.html": [ + [ + "/intersection-observer/same-document-root.html", + {} + ] + ], + "intersection-observer/same-document-zero-size-target.html": [ + [ + "/intersection-observer/same-document-zero-size-target.html", + {} + ] + ], + "intersection-observer/shadow-content.html": [ + [ + "/intersection-observer/shadow-content.html", + {} + ] + ], + "intersection-observer/timestamp.html": [ + [ + "/intersection-observer/timestamp.html", + {} + ] + ], + "intersection-observer/unclipped-root.html": [ + [ + "/intersection-observer/unclipped-root.html", + {} + ] + ], + "intersection-observer/zero-area-element-hidden.html": [ + [ + "/intersection-observer/zero-area-element-hidden.html", + {} + ] + ], + "intersection-observer/zero-area-element-visible.html": [ + [ + "/intersection-observer/zero-area-element-visible.html", + {} + ] + ], "js/behaviours/SetPrototypeOf-window.html": [ [ "/js/behaviours/SetPrototypeOf-window.html", @@ -191666,6 +191828,118 @@ "4f94c4236168ed722f71d81bd957e0da72b29c71", "support" ], + "intersection-observer/client-rect.html": [ + "acec9a4f59ebee1840950cf766a45676490eef84", + "testharness" + ], + "intersection-observer/containing-block.html": [ + "8bdf6fa6a3ee09130981bf83728aa9f61a6ebc54", + "testharness" + ], + "intersection-observer/cross-origin-iframe.html": [ + "98ac8bd3447bc16e86c4b15708dcd86aa4b5ed92", + "testharness" + ], + "intersection-observer/disconnect.html": [ + "d8206b91756a367394ea9d444deefc0f37589427", + "testharness" + ], + "intersection-observer/display-none.html": [ + "3dc956e76b23ae44f2694f4b24579f896a1086b5", + "testharness" + ], + "intersection-observer/edge-inclusive-intersection.html": [ + "97921caeabdafb402de1a6f64fc28176eda3e6db", + "testharness" + ], + "intersection-observer/iframe-no-root.html": [ + "6cbea44f209e59ea0b901b0fe1cec7ac1aee0b64", + "testharness" + ], + "intersection-observer/multiple-targets.html": [ + "83173248b825b97063c61dd31c64d8fe7ba10aac", + "testharness" + ], + "intersection-observer/multiple-thresholds.html": [ + "dcfa7d005d1f94186b173b20d4f9c367abc5a77b", + "testharness" + ], + "intersection-observer/observer-attributes.html": [ + "69c802af77a38c450ce81c4c010588b0e4f240db", + "testharness" + ], + "intersection-observer/observer-exceptions.html": [ + "28ccc6905713894b43033e30949170439215bf2e", + "testharness" + ], + "intersection-observer/observer-in-iframe.html": [ + "3e6dcbc7aac43899186395f50649195b2ecc4c74", + "support" + ], + "intersection-observer/observer-without-js-reference.html": [ + "4211529e1fdd3bfb9b3b64c29b7d000b3c706408", + "testharness" + ], + "intersection-observer/remove-element.html": [ + "f2b3688fd8e069a41e16086baad74bda0fe2f180", + "testharness" + ], + "intersection-observer/resources/cross-origin-subframe.html": [ + "91073aed8b250177d69ee36e9be95c30c9cf1c95", + "support" + ], + "intersection-observer/resources/iframe-no-root-subframe.html": [ + "a9ea444d6bb15cda784871e2d495dc204b0e3d50", + "support" + ], + "intersection-observer/resources/intersection-observer-test-utils.js": [ + "889d403e334e3c0fc4ae7a6af06ef9504145fa2b", + "support" + ], + "intersection-observer/resources/observer-in-iframe-subframe.html": [ + "5f390b2e969132bce9ab486cbf2292765d5c62f2", + "support" + ], + "intersection-observer/resources/timestamp-subframe.html": [ + "7b590da7cf426cc7d2e3f25fac30f4533e36153c", + "support" + ], + "intersection-observer/root-margin.html": [ + "be98d804610d2c08ee516a4aecbe59ffc58c22bd", + "testharness" + ], + "intersection-observer/same-document-no-root.html": [ + "0f29996e4542db243c3fcd9c108463ba7260cb8e", + "testharness" + ], + "intersection-observer/same-document-root.html": [ + "71876c5290184f77223843c7d3c0bed670e2ee3f", + "testharness" + ], + "intersection-observer/same-document-zero-size-target.html": [ + "c1d1054447e116becb50aaf96aad00a25f0a6752", + "testharness" + ], + "intersection-observer/shadow-content.html": [ + "11681640d5c8b2c62229ed5a717172f917d75ba4", + "testharness" + ], + "intersection-observer/timestamp.html": [ + "cf4e91716ed1d02935c3c73ee639e566cf5b60a4", + "testharness" + ], + "intersection-observer/unclipped-root.html": [ + "67dab96304c745f1b5462bb1074753b09d77fbd1", + "testharness" + ], + "intersection-observer/zero-area-element-hidden.html": [ + "59d854e89ca0d7b035a87376566775ca2f3420e5", + "testharness" + ], + "intersection-observer/zero-area-element-visible.html": [ + "f3e1fbeb1a912be412724cec47a6aa981664ff7d", + "testharness" + ], "js/behaviours/SetPrototypeOf-window.html": [ "92efe1a4f3910a32097fb3cbeef0019d82a0e78a", "testharness" diff --git a/testing/web-platform/meta/intersection-observer/__dir__.ini b/testing/web-platform/meta/intersection-observer/__dir__.ini new file mode 100644 index 000000000000..6c2e6355aa34 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/__dir__.ini @@ -0,0 +1 @@ +prefs: [dom.IntersectionObserver.enabled:true] diff --git a/testing/web-platform/meta/intersection-observer/client-rect.html.ini b/testing/web-platform/meta/intersection-observer/client-rect.html.ini new file mode 100644 index 000000000000..781359f8ee4a --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/client-rect.html.ini @@ -0,0 +1,2 @@ +[client-rect.html] + type: testharness diff --git a/testing/web-platform/meta/intersection-observer/containing-block.html.ini b/testing/web-platform/meta/intersection-observer/containing-block.html.ini new file mode 100644 index 000000000000..8a43c8f9c51f --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/containing-block.html.ini @@ -0,0 +1,3 @@ +[containing-block.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1363650 diff --git a/testing/web-platform/meta/intersection-observer/cross-origin-iframe.html.ini b/testing/web-platform/meta/intersection-observer/cross-origin-iframe.html.ini new file mode 100644 index 000000000000..e2bf5de1aeed --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/cross-origin-iframe.html.ini @@ -0,0 +1,3 @@ +[cross-origin-iframe.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/disconnect.html.ini b/testing/web-platform/meta/intersection-observer/disconnect.html.ini new file mode 100644 index 000000000000..45a4815aa706 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/disconnect.html.ini @@ -0,0 +1,3 @@ +[disconnect.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/display-none.html.ini b/testing/web-platform/meta/intersection-observer/display-none.html.ini new file mode 100644 index 000000000000..3c93628f0380 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/display-none.html.ini @@ -0,0 +1,3 @@ +[display-none.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1358668 diff --git a/testing/web-platform/meta/intersection-observer/edge-inclusive-intersection.html.ini b/testing/web-platform/meta/intersection-observer/edge-inclusive-intersection.html.ini new file mode 100644 index 000000000000..1ac064926b96 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/edge-inclusive-intersection.html.ini @@ -0,0 +1,5 @@ +[edge-inclusive-intersection.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359317 + [First rAF.] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/iframe-no-root.html.ini b/testing/web-platform/meta/intersection-observer/iframe-no-root.html.ini new file mode 100644 index 000000000000..78005b3de4b9 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/iframe-no-root.html.ini @@ -0,0 +1,5 @@ +[iframe-no-root.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359318 + [First rAF.] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/multiple-targets.html.ini b/testing/web-platform/meta/intersection-observer/multiple-targets.html.ini new file mode 100644 index 000000000000..c9690a576278 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/multiple-targets.html.ini @@ -0,0 +1,5 @@ +[multiple-targets.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359311 + [First rAF.] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/multiple-thresholds.html.ini b/testing/web-platform/meta/intersection-observer/multiple-thresholds.html.ini new file mode 100644 index 000000000000..b9023815d7bf --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/multiple-thresholds.html.ini @@ -0,0 +1,3 @@ +[multiple-thresholds.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/observer-attributes.html.ini b/testing/web-platform/meta/intersection-observer/observer-attributes.html.ini new file mode 100644 index 000000000000..1acec48c3878 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/observer-attributes.html.ini @@ -0,0 +1,2 @@ +[observer-attributes.html] + type: testharness diff --git a/testing/web-platform/meta/intersection-observer/observer-exceptions.html.ini b/testing/web-platform/meta/intersection-observer/observer-exceptions.html.ini new file mode 100644 index 000000000000..16e2da5f3e33 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/observer-exceptions.html.ini @@ -0,0 +1,2 @@ +[observer-exceptions.html] + type: testharness diff --git a/testing/web-platform/meta/intersection-observer/observer-in-iframe.html.ini b/testing/web-platform/meta/intersection-observer/observer-in-iframe.html.ini new file mode 100644 index 000000000000..b93e4d6bafb1 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/observer-in-iframe.html.ini @@ -0,0 +1,2 @@ +[observer-in-iframe.html] + type: testharness diff --git a/testing/web-platform/meta/intersection-observer/observer-without-js-reference.html.ini b/testing/web-platform/meta/intersection-observer/observer-without-js-reference.html.ini new file mode 100644 index 000000000000..6b65a00e2677 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/observer-without-js-reference.html.ini @@ -0,0 +1,3 @@ +[observer-without-js-reference.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/remove-element.html.ini b/testing/web-platform/meta/intersection-observer/remove-element.html.ini new file mode 100644 index 000000000000..2d5000ba7a2f --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/remove-element.html.ini @@ -0,0 +1,5 @@ +[remove-element.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1363650 + [First rAF.] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/root-margin.html.ini b/testing/web-platform/meta/intersection-observer/root-margin.html.ini new file mode 100644 index 000000000000..6e5eab584983 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/root-margin.html.ini @@ -0,0 +1,3 @@ +[root-margin.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/same-document-no-root.html.ini b/testing/web-platform/meta/intersection-observer/same-document-no-root.html.ini new file mode 100644 index 000000000000..4d4f0a809ccf --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/same-document-no-root.html.ini @@ -0,0 +1,3 @@ +[same-document-no-root.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/same-document-root.html.ini b/testing/web-platform/meta/intersection-observer/same-document-root.html.ini new file mode 100644 index 000000000000..4734a925a1dc --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/same-document-root.html.ini @@ -0,0 +1,5 @@ +[same-document-root.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1363650 + [First rAF.] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/same-document-zero-size-target.html.ini b/testing/web-platform/meta/intersection-observer/same-document-zero-size-target.html.ini new file mode 100644 index 000000000000..06245a792a63 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/same-document-zero-size-target.html.ini @@ -0,0 +1,3 @@ +[same-document-zero-size-target.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/shadow-content.html.ini b/testing/web-platform/meta/intersection-observer/shadow-content.html.ini new file mode 100644 index 000000000000..99facb40f111 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/shadow-content.html.ini @@ -0,0 +1,4 @@ +[shadow-content.html] + type: testharness + prefs: [dom.webcomponents.enabled:true] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359318 diff --git a/testing/web-platform/meta/intersection-observer/timestamp.html.ini b/testing/web-platform/meta/intersection-observer/timestamp.html.ini new file mode 100644 index 000000000000..1715bc15a56f --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/timestamp.html.ini @@ -0,0 +1,3 @@ +[timestamp.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/unclipped-root.html.ini b/testing/web-platform/meta/intersection-observer/unclipped-root.html.ini new file mode 100644 index 000000000000..38f608219a0b --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/unclipped-root.html.ini @@ -0,0 +1,5 @@ +[unclipped-root.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359317 + [First rAF.] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/zero-area-element-hidden.html.ini b/testing/web-platform/meta/intersection-observer/zero-area-element-hidden.html.ini new file mode 100644 index 000000000000..c896b25c449f --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/zero-area-element-hidden.html.ini @@ -0,0 +1,3 @@ +[zero-area-element-hidden.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/meta/intersection-observer/zero-area-element-visible.html.ini b/testing/web-platform/meta/intersection-observer/zero-area-element-visible.html.ini new file mode 100644 index 000000000000..798836957bf4 --- /dev/null +++ b/testing/web-platform/meta/intersection-observer/zero-area-element-visible.html.ini @@ -0,0 +1,5 @@ +[zero-area-element-visible.html] + type: testharness + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1359316 + [First rAF should generate a notification.] + disabled: https://bugzilla.mozilla.org/show_bug.cgi?id=1335644 diff --git a/testing/web-platform/tests/intersection-observer/client-rect.html b/testing/web-platform/tests/intersection-observer/client-rect.html new file mode 100644 index 000000000000..913e0d9f12c9 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/client-rect.html @@ -0,0 +1,45 @@ + + + + + + + + + + diff --git a/testing/web-platform/tests/intersection-observer/containing-block.html b/testing/web-platform/tests/intersection-observer/containing-block.html new file mode 100644 index 000000000000..d4f46b0fa77d --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/containing-block.html @@ -0,0 +1,73 @@ + + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/cross-origin-iframe.html b/testing/web-platform/tests/intersection-observer/cross-origin-iframe.html new file mode 100644 index 000000000000..2c9c4bcec696 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/cross-origin-iframe.html @@ -0,0 +1,52 @@ + + + + + + + +
+ +
+ + diff --git a/testing/web-platform/tests/intersection-observer/disconnect.html b/testing/web-platform/tests/intersection-observer/disconnect.html new file mode 100644 index 000000000000..0abfbc4e8aaf --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/disconnect.html @@ -0,0 +1,53 @@ + + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/display-none.html b/testing/web-platform/tests/intersection-observer/display-none.html new file mode 100644 index 000000000000..7cebc5633ef9 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/display-none.html @@ -0,0 +1,54 @@ + + + + + + + +
+ + diff --git a/testing/web-platform/tests/intersection-observer/edge-inclusive-intersection.html b/testing/web-platform/tests/intersection-observer/edge-inclusive-intersection.html new file mode 100644 index 000000000000..b9fa24b87808 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/edge-inclusive-intersection.html @@ -0,0 +1,66 @@ + + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/iframe-no-root.html b/testing/web-platform/tests/intersection-observer/iframe-no-root.html new file mode 100644 index 000000000000..e37aeac5530f --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/iframe-no-root.html @@ -0,0 +1,71 @@ + + + + + + + +
+ +
+ + diff --git a/testing/web-platform/tests/intersection-observer/multiple-targets.html b/testing/web-platform/tests/intersection-observer/multiple-targets.html new file mode 100644 index 000000000000..525c5a699d1c --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/multiple-targets.html @@ -0,0 +1,80 @@ + + + + + + + +
+
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/multiple-thresholds.html b/testing/web-platform/tests/intersection-observer/multiple-thresholds.html new file mode 100644 index 000000000000..6450068941ce --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/multiple-thresholds.html @@ -0,0 +1,96 @@ + + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/observer-attributes.html b/testing/web-platform/tests/intersection-observer/observer-attributes.html new file mode 100644 index 000000000000..ffca95ded316 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/observer-attributes.html @@ -0,0 +1,31 @@ + + + + +
+ + diff --git a/testing/web-platform/tests/intersection-observer/observer-exceptions.html b/testing/web-platform/tests/intersection-observer/observer-exceptions.html new file mode 100644 index 000000000000..b44b7bd0cc13 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/observer-exceptions.html @@ -0,0 +1,48 @@ + + + + + diff --git a/testing/web-platform/tests/intersection-observer/observer-in-iframe.html b/testing/web-platform/tests/intersection-observer/observer-in-iframe.html new file mode 100644 index 000000000000..f4aa387de2a8 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/observer-in-iframe.html @@ -0,0 +1,9 @@ + + + diff --git a/testing/web-platform/tests/intersection-observer/observer-without-js-reference.html b/testing/web-platform/tests/intersection-observer/observer-without-js-reference.html new file mode 100644 index 000000000000..3214345b6105 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/observer-without-js-reference.html @@ -0,0 +1,50 @@ + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/remove-element.html b/testing/web-platform/tests/intersection-observer/remove-element.html new file mode 100644 index 000000000000..3b6a65e2d0e4 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/remove-element.html @@ -0,0 +1,82 @@ + + + + + + + +
+
+
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/resources/cross-origin-subframe.html b/testing/web-platform/tests/intersection-observer/resources/cross-origin-subframe.html new file mode 100644 index 000000000000..0cc117cb3a69 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/resources/cross-origin-subframe.html @@ -0,0 +1,125 @@ + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/resources/iframe-no-root-subframe.html b/testing/web-platform/tests/intersection-observer/resources/iframe-no-root-subframe.html new file mode 100644 index 000000000000..ee63a06ca0ff --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/resources/iframe-no-root-subframe.html @@ -0,0 +1,4 @@ + +
+
+
diff --git a/testing/web-platform/tests/intersection-observer/resources/intersection-observer-test-utils.js b/testing/web-platform/tests/intersection-observer/resources/intersection-observer-test-utils.js new file mode 100644 index 000000000000..48ccbb1991b7 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/resources/intersection-observer-test-utils.js @@ -0,0 +1,122 @@ +// 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); +} diff --git a/testing/web-platform/tests/intersection-observer/resources/observer-in-iframe-subframe.html b/testing/web-platform/tests/intersection-observer/resources/observer-in-iframe-subframe.html new file mode 100644 index 000000000000..9d0769ae44a1 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/resources/observer-in-iframe-subframe.html @@ -0,0 +1,65 @@ + + + + + + + +
+
+
+
+
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/resources/timestamp-subframe.html b/testing/web-platform/tests/intersection-observer/resources/timestamp-subframe.html new file mode 100644 index 000000000000..143e4f6e23a7 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/resources/timestamp-subframe.html @@ -0,0 +1,28 @@ + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/root-margin.html b/testing/web-platform/tests/intersection-observer/root-margin.html new file mode 100644 index 000000000000..c1fffec02bec --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/root-margin.html @@ -0,0 +1,86 @@ + + + + + + + +
+
+
+
+
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/same-document-no-root.html b/testing/web-platform/tests/intersection-observer/same-document-no-root.html new file mode 100644 index 000000000000..783880888abd --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/same-document-no-root.html @@ -0,0 +1,61 @@ + + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/same-document-root.html b/testing/web-platform/tests/intersection-observer/same-document-root.html new file mode 100644 index 000000000000..40467be72b4f --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/same-document-root.html @@ -0,0 +1,90 @@ + + + + + + + +
+
+
+
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/same-document-zero-size-target.html b/testing/web-platform/tests/intersection-observer/same-document-zero-size-target.html new file mode 100644 index 000000000000..d835b40634d3 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/same-document-zero-size-target.html @@ -0,0 +1,61 @@ + + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/shadow-content.html b/testing/web-platform/tests/intersection-observer/shadow-content.html new file mode 100644 index 000000000000..a0a6242050e7 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/shadow-content.html @@ -0,0 +1,44 @@ + + + + + + + +
+ + diff --git a/testing/web-platform/tests/intersection-observer/timestamp.html b/testing/web-platform/tests/intersection-observer/timestamp.html new file mode 100644 index 000000000000..00d787d295f5 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/timestamp.html @@ -0,0 +1,98 @@ + + + + + + +
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/unclipped-root.html b/testing/web-platform/tests/intersection-observer/unclipped-root.html new file mode 100644 index 000000000000..24ae01cedc2e --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/unclipped-root.html @@ -0,0 +1,57 @@ + + + + + + + +
+
+
+ + diff --git a/testing/web-platform/tests/intersection-observer/zero-area-element-hidden.html b/testing/web-platform/tests/intersection-observer/zero-area-element-hidden.html new file mode 100644 index 000000000000..e007040c8fe2 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/zero-area-element-hidden.html @@ -0,0 +1,43 @@ + + + + + + + +
+ + diff --git a/testing/web-platform/tests/intersection-observer/zero-area-element-visible.html b/testing/web-platform/tests/intersection-observer/zero-area-element-visible.html new file mode 100644 index 000000000000..6bf1297fe453 --- /dev/null +++ b/testing/web-platform/tests/intersection-observer/zero-area-element-visible.html @@ -0,0 +1,39 @@ + + + + + + + +
+ + From 6523b5834f7b0c42deb43cb481ef1f392ccfe037 Mon Sep 17 00:00:00 2001 From: Will Wang Date: Wed, 10 May 2017 09:50:17 +0800 Subject: [PATCH 03/12] Bug 1356605 - Part 1: Add an enumerator for getting session cookies only. r=valentin --- netwerk/cookie/nsCookieService.cpp | 25 +++++++++++++++++++++++++ netwerk/cookie/nsICookieManager.idl | 6 ++++++ 2 files changed, 31 insertions(+) diff --git a/netwerk/cookie/nsCookieService.cpp b/netwerk/cookie/nsCookieService.cpp index 0cd86ec1337d..0765b1a55c1a 100644 --- a/netwerk/cookie/nsCookieService.cpp +++ b/netwerk/cookie/nsCookieService.cpp @@ -2361,6 +2361,31 @@ nsCookieService::GetEnumerator(nsISimpleEnumerator **aEnumerator) return NS_NewArrayEnumerator(aEnumerator, cookieList); } +NS_IMETHODIMP +nsCookieService::GetSessionEnumerator(nsISimpleEnumerator **aEnumerator) +{ + if (!mDBState) { + NS_WARNING("No DBState! Profile already closed?"); + return NS_ERROR_NOT_AVAILABLE; + } + + EnsureReadComplete(); + + nsCOMArray cookieList(mDBState->cookieCount); + for (auto iter = mDBState->hostTable.Iter(); !iter.Done(); iter.Next()) { + const nsCookieEntry::ArrayType& cookies = iter.Get()->GetCookies(); + for (nsCookieEntry::IndexType i = 0; i < cookies.Length(); ++i) { + nsCookie* cookie = cookies[i]; + // Filter out non-session cookies. + if (cookie->IsSession()) { + cookieList.AppendObject(cookie); + } + } + } + + return NS_NewArrayEnumerator(aEnumerator, cookieList); +} + static nsresult InitializeOriginAttributes(OriginAttributes* aAttrs, JS::HandleValue aOriginAttributes, diff --git a/netwerk/cookie/nsICookieManager.idl b/netwerk/cookie/nsICookieManager.idl index 374b73d37de7..e7c019afd5ae 100644 --- a/netwerk/cookie/nsICookieManager.idl +++ b/netwerk/cookie/nsICookieManager.idl @@ -41,6 +41,12 @@ interface nsICookieManager : nsISupports */ readonly attribute nsISimpleEnumerator enumerator; + /** + * Called to enumerate through each session cookie in the cookie list. + * The objects enumerated over are of type nsICookie + */ + readonly attribute nsISimpleEnumerator sessionEnumerator; + /** * Called to remove an individual cookie from the cookie list, specified * by host, name, and path. If the cookie cannot be found, no exception From 15fb67470c53d0b41f3e80ab0c2478708978d241 Mon Sep 17 00:00:00 2001 From: Will Wang Date: Wed, 10 May 2017 12:14:31 +0800 Subject: [PATCH 04/12] Bug 1356605 - Part 2: Use the new `sessionEnumerator` to iterate only the cookies we need. r=mikedeboer --- .../sessionstore/SessionCookies.jsm | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/browser/components/sessionstore/SessionCookies.jsm b/browser/components/sessionstore/SessionCookies.jsm index e0f1b0db0c73..d727131fae09 100644 --- a/browser/components/sessionstore/SessionCookies.jsm +++ b/browser/components/sessionstore/SessionCookies.jsm @@ -102,16 +102,17 @@ var SessionCookiesInternal = { * cookies service and puts them into the store if they're session cookies. */ _ensureInitialized() { - if (!this._initialized) { - this._reloadCookies(); - this._initialized = true; - Services.obs.addObserver(this, "cookie-changed"); - - // Listen for privacy level changes to reload cookies when needed. - Services.prefs.addObserver("browser.sessionstore.privacy_level", () => { - this._reloadCookies(); - }); + if (this._initialized) { + return; } + this._reloadCookies(); + this._initialized = true; + Services.obs.addObserver(this, "cookie-changed"); + + // Listen for privacy level changes to reload cookies when needed. + Services.prefs.addObserver("browser.sessionstore.privacy_level", () => { + this._reloadCookies(); + }); }, /** @@ -172,7 +173,7 @@ var SessionCookiesInternal = { return; } - let iter = Services.cookies.enumerator; + let iter = Services.cookies.sessionEnumerator; while (iter.hasMoreElements()) { this._addCookie(iter.getNext()); } From 27787d394f33a029f61745f732a4c118647394f4 Mon Sep 17 00:00:00 2001 From: Geoff Lankow Date: Sat, 20 May 2017 14:06:16 +1200 Subject: [PATCH 05/12] Bug 1361899 - Allow extensions to specify provider when calling topSites.get. r=mixedpuppy --- toolkit/components/extensions/ext-topSites.js | 34 +++++-- .../extensions/schemas/top_sites.json | 13 +++ .../test/xpcshell/test_ext_topSites.js | 98 +++++++++++++------ toolkit/modules/NewTabUtils.jsm | 8 ++ 4 files changed, 112 insertions(+), 41 deletions(-) diff --git a/toolkit/components/extensions/ext-topSites.js b/toolkit/components/extensions/ext-topSites.js index 5f8235b5e4ab..dfa0cc677413 100644 --- a/toolkit/components/extensions/ext-topSites.js +++ b/toolkit/components/extensions/ext-topSites.js @@ -9,16 +9,30 @@ this.topSites = class extends ExtensionAPI { getAPI(context) { return { topSites: { - get: function() { - let urls = NewTabUtils.links.getLinks() - .filter(link => !!link) - .map(link => { - return { - url: link.url, - title: link.title, - }; - }); - return Promise.resolve(urls); + get: function(options) { + return new Promise(function(resolve) { + NewTabUtils.links.populateCache(function() { + let urls; + + if (options && options.providers && options.providers.length > 0) { + let urlLists = options.providers.map(function(p) { + let provider = NewTabUtils[`${p}Provider`]; + return provider ? NewTabUtils.getProviderLinks(provider).slice() : []; + }); + urls = NewTabUtils.links.mergeLinkLists(urlLists); + } else { + urls = NewTabUtils.links.getLinks(); + } + + resolve(urls.filter(link => !!link) + .map(link => { + return { + url: link.url, + title: link.title, + }; + })); + }, false); + }); }, }, }; diff --git a/toolkit/components/extensions/schemas/top_sites.json b/toolkit/components/extensions/schemas/top_sites.json index bcf60aa5bf73..1a42e1d0ad17 100644 --- a/toolkit/components/extensions/schemas/top_sites.json +++ b/toolkit/components/extensions/schemas/top_sites.json @@ -46,6 +46,19 @@ "description": "Gets a list of top sites.", "async": "callback", "parameters": [ + { + "type": "object", + "name": "options", + "properties": { + "providers": { + "type": "array", + "items": { "type": "string" }, + "description": "Which providers to get top sites from. Possible values are \"places\" and \"activityStream\".", + "optional": true + } + }, + "optional": true + }, { "name": "callback", "type": "function", diff --git a/toolkit/components/extensions/test/xpcshell/test_ext_topSites.js b/toolkit/components/extensions/test/xpcshell/test_ext_topSites.js index b9cb0df68029..b31c22d36324 100644 --- a/toolkit/components/extensions/test/xpcshell/test_ext_topSites.js +++ b/toolkit/components/extensions/test/xpcshell/test_ext_topSites.js @@ -28,30 +28,29 @@ TestProvider.prototype = { }, }; -function makeLinks(links) { +add_task(async function test_topSites() { // Important: To avoid test failures due to clock jitter on Windows XP, call // Date.now() once here, not each time through the loop. - let frecency = 0; let now = Date.now() * 1000; - let places = []; - links.map((link, i) => { - places.push({ - url: link.url, - title: link.title, - lastVisitDate: now - i, - frecency: frecency++, - }); + let provider1 = new TestProvider(done => { + let data = [{url: "http://example.com/", title: "site#-1", frecency: 9, lastVisitDate: now}, + {url: "http://example0.com/", title: "site#0", frecency: 8, lastVisitDate: now}, + {url: "http://example3.com/", title: "site#3", frecency: 5, lastVisitDate: now}]; + done(data); + }); + let provider2 = new TestProvider(done => { + let data = [{url: "http://example1.com/", title: "site#1", frecency: 7, lastVisitDate: now}, + {url: "http://example2.com/", title: "site#2", frecency: 6, lastVisitDate: now}]; + done(data); }); - return places; -} -add_task(async function test_topSites() { - let expect = [{url: "http://example.com/", title: "site#-1"}, - {url: "http://example0.com/", title: "site#0"}, - {url: "http://example1.com/", title: "site#1"}, - {url: "http://example2.com/", title: "site#2"}, - {url: "http://example3.com/", title: "site#3"}]; + NewTabUtils.initWithoutProviders(); + NewTabUtils.links.addProvider(provider1); + NewTabUtils.links.addProvider(provider2); + NewTabUtils.test1Provider = provider1; + NewTabUtils.test2Provider = provider2; + // Test that results from all providers are returned by default. let extension = ExtensionTestUtils.loadExtension({ manifest: { "permissions": [ @@ -59,27 +58,64 @@ add_task(async function test_topSites() { ], }, background() { + // Tests consistent behaviour when no providers are specified. browser.topSites.get(result => { - browser.test.sendMessage("done", result); + browser.test.sendMessage("done1", result); + }); + browser.topSites.get({}, result => { + browser.test.sendMessage("done2", result); + }); + browser.topSites.get({providers: []}, result => { + browser.test.sendMessage("done3", result); + }); + // Tests that results are merged correctly. + browser.topSites.get({providers: ["test2", "test1"]}, result => { + browser.test.sendMessage("done4", result); + }); + // Tests that only the specified provider is used. + browser.topSites.get({providers: ["test2"]}, result => { + browser.test.sendMessage("done5", result); + }); + // Tests that specifying a non-existent provider returns an empty array. + browser.topSites.get({providers: ["fake"]}, result => { + browser.test.sendMessage("done6", result); }); }, }); - - let expectedLinks = makeLinks(expect); - let provider = new TestProvider(done => done(expectedLinks)); - - NewTabUtils.initWithoutProviders(); - NewTabUtils.links.addProvider(provider); - - await NewTabUtils.links.populateCache(); - await extension.startup(); - let result = await extension.awaitMessage("done"); - Assert.deepEqual(expect, result, "got topSites"); + let expected1 = [{url: "http://example.com/", title: "site#-1"}, + {url: "http://example0.com/", title: "site#0"}, + {url: "http://example1.com/", title: "site#1"}, + {url: "http://example2.com/", title: "site#2"}, + {url: "http://example3.com/", title: "site#3"}]; + + let actual1 = await extension.awaitMessage("done1"); + Assert.deepEqual(expected1, actual1, "got topSites"); + + let actual2 = await extension.awaitMessage("done2"); + Assert.deepEqual(expected1, actual2, "got topSites"); + + let actual3 = await extension.awaitMessage("done3"); + Assert.deepEqual(expected1, actual3, "got topSites"); + + let actual4 = await extension.awaitMessage("done4"); + Assert.deepEqual(expected1, actual4, "got topSites"); + + let expected5 = [{url: "http://example1.com/", title: "site#1"}, + {url: "http://example2.com/", title: "site#2"}]; + + let actual5 = await extension.awaitMessage("done5"); + Assert.deepEqual(expected5, actual5, "got topSites"); + + let actual6 = await extension.awaitMessage("done6"); + Assert.deepEqual([], actual6, "got topSites"); await extension.unload(); - NewTabUtils.links.removeProvider(provider); + NewTabUtils.links.removeProvider(provider1); + NewTabUtils.links.removeProvider(provider2); + delete NewTabUtils.test1Provider; + delete NewTabUtils.test2Provider; }); diff --git a/toolkit/modules/NewTabUtils.jsm b/toolkit/modules/NewTabUtils.jsm index ffd10ae4e7da..048ecbf79e4b 100644 --- a/toolkit/modules/NewTabUtils.jsm +++ b/toolkit/modules/NewTabUtils.jsm @@ -1453,6 +1453,14 @@ var Links = { } } + return this.mergeLinkLists(linkLists); + }, + + mergeLinkLists: function Links_mergeLinkLists(linkLists) { + if (linkLists.length == 1) { + return linkLists[0]; + } + function getNextLink() { let minLinks = null; for (let links of linkLists) { From df79943fc1279a59880f15977f21e8d1b2b31a1e Mon Sep 17 00:00:00 2001 From: Andreas Farre Date: Thu, 4 May 2017 05:44:00 -0400 Subject: [PATCH 06/12] Bug 1355311 - Set default values for throttling background timeouts. r=ehsan --- modules/libpref/init/all.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index ef9951e6d503..a9831a838197 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -1221,6 +1221,14 @@ pref("dom.send_after_paint_to_content", false); pref("dom.min_timeout_value", 4); // And for background windows pref("dom.min_background_timeout_value", 1000); +// Timeout clamp in ms for tracking timeouts we clamp +// Note that this requires the privacy.trackingprotection.annotate_channels pref to be on in order to have any effect. +pref("dom.min_tracking_timeout_value", 4); +// And for background windows +// Note that this requires the privacy.trackingprotection.annotate_channels pref to be on in order to have any effect. +pref("dom.min_tracking_background_timeout_value", 10000); +// Delay in ms from document load until we start throttling tracking timeouts. +pref("dom.timeout.tracking_throttling_delay", 30000); // Don't use new input types pref("dom.experimental_forms", false); From 673dfaa56ae3c0d2d2265d3e163eafe485ad0a20 Mon Sep 17 00:00:00 2001 From: Steve Fink Date: Sat, 20 May 2017 14:27:58 -0700 Subject: [PATCH 07/12] Bug 1366522 - Drop SM(tsan) back to tier 3, r=philor --HG-- extra : rebase_source : a9a1932dd8174bde02d2eb880f21fb2b744f0785 --- taskcluster/ci/spidermonkey/kind.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/taskcluster/ci/spidermonkey/kind.yml b/taskcluster/ci/spidermonkey/kind.yml index 899a7e28b0a0..135bbb4f5840 100644 --- a/taskcluster/ci/spidermonkey/kind.yml +++ b/taskcluster/ci/spidermonkey/kind.yml @@ -156,7 +156,6 @@ jobs: treeherder: symbol: SM-tc(tsan) tier: 3 - run-on-projects: [] run: spidermonkey-variant: tsan tooltool-manifest: browser/config/tooltool-manifests/linux64/tsan.manifest From f085a0060e16b840d7272b044078d5c261e00257 Mon Sep 17 00:00:00 2001 From: Xidorn Quan Date: Sun, 21 May 2017 10:22:26 +1000 Subject: [PATCH 08/12] Bug 1337655 - Turn on moz-prefixed gradient functions again. MozReview-Commit-ID: AUDeFVbQsT3 --- layout/style/test/stylo-failures.md | 4 ++++ modules/libpref/init/all.js | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/layout/style/test/stylo-failures.md b/layout/style/test/stylo-failures.md index 56c8f985b49f..878ecaca093f 100644 --- a/layout/style/test/stylo-failures.md +++ b/layout/style/test/stylo-failures.md @@ -103,6 +103,10 @@ to mochitest command. * test_value_storage.html `font-variant` [167] * test_specified_value_serialization.html `bug-721136` [1] * Unsupported prefixed values + * moz-prefixed gradient functions bug 1337655 + * test_value_storage.html `-moz-linear-gradient` [322] + * ... `-moz-radial-gradient` [309] + * ... `-moz-repeating-` [298] * serialization of prefixed gradient functions bug 1358710 * test_specified_value_serialization.html `-webkit-radial-gradient` [1] * moz-prefixed intrinsic width values bug 1355402 diff --git a/modules/libpref/init/all.js b/modules/libpref/init/all.js index a9831a838197..4f55f971db1a 100644 --- a/modules/libpref/init/all.js +++ b/modules/libpref/init/all.js @@ -2801,11 +2801,7 @@ pref("layout.css.prefixes.box-sizing", true); pref("layout.css.prefixes.font-features", true); // Is -moz-prefixed gradient functions enabled? -#ifdef NIGHTLY_BUILD -pref("layout.css.prefixes.gradients", false); -#else pref("layout.css.prefixes.gradients", true); -#endif // Are webkit-prefixed properties & property-values supported? pref("layout.css.prefixes.webkit", true); From 6960f047b8c5381223e335d9c58e57283e186b04 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 20 May 2017 11:54:51 -0700 Subject: [PATCH 09/12] Bug 1354733: Part 1 - Allow creating DeadObjectProxies directly. r=till MozReview-Commit-ID: HnFgiRcA7l5 --HG-- extra : rebase_source : 0337ac2451f3a72ef3feae1d05fbf426fec21d4f --- js/src/jsfriendapi.cpp | 6 +++++ js/src/jsfriendapi.h | 10 +++++++ js/src/proxy/DeadObjectProxy.cpp | 34 ++++++++++++++++++++++++ js/src/proxy/DeadObjectProxy.h | 8 ++++++ js/src/vm/ProxyObject.cpp | 19 +++---------- js/xpconnect/wrappers/WrapperFactory.cpp | 6 +---- 6 files changed, 63 insertions(+), 20 deletions(-) diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index ade062ad6f2f..8c77d850cde7 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -597,6 +597,12 @@ JS_IsDeadWrapper(JSObject* obj) return IsDeadProxyObject(obj); } +JS_FRIEND_API(JSObject*) +JS_NewDeadWrapper(JSContext* cx, JSObject* origObj) +{ + return NewDeadProxyObject(cx, origObj); +} + void js::TraceWeakMaps(WeakMapTracer* trc) { diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 3e9b8ceabf02..e8a41af624d5 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -96,6 +96,16 @@ JS_PCToLineNumber(JSScript* script, jsbytecode* pc, unsigned* columnp = nullptr) extern JS_FRIEND_API(bool) JS_IsDeadWrapper(JSObject* obj); +/** + * Creates a new dead wrapper object in the given scope. To be used when + * attempting to wrap objects from scopes which are already dead. + * + * If origObject is passed, it must be an proxy object, and will be + * used to determine the characteristics of the new dead wrapper. + */ +extern JS_FRIEND_API(JSObject*) +JS_NewDeadWrapper(JSContext* cx, JSObject* origObject = nullptr); + /* * Used by the cycle collector to trace through a shape or object group and * all cycle-participating data it reaches, using bounded stack space. diff --git a/js/src/proxy/DeadObjectProxy.cpp b/js/src/proxy/DeadObjectProxy.cpp index f5fc1982d4c0..b2ed273fecb3 100644 --- a/js/src/proxy/DeadObjectProxy.cpp +++ b/js/src/proxy/DeadObjectProxy.cpp @@ -185,3 +185,37 @@ js::IsDeadProxyObject(JSObject* obj) IsDerivedProxyObject(obj, DeadObjectProxy::singleton()) || IsDerivedProxyObject(obj, DeadObjectProxy::singleton()); } + + +const BaseProxyHandler* +js::SelectDeadProxyHandler(ProxyObject* obj) +{ + // When nuking scripted proxies, isCallable and isConstructor values for + // the proxy needs to be preserved. + uint32_t callable = obj->handler()->isCallable(obj); + uint32_t constructor = obj->handler()->isConstructor(obj); + + if (callable) { + if (constructor) + return DeadObjectProxy::singleton(); + return DeadObjectProxy::singleton(); + } + + if (constructor) + return DeadObjectProxy::singleton(); + return DeadObjectProxy::singleton(); +} + +JSObject* +js::NewDeadProxyObject(JSContext* cx, JSObject* origObj) +{ + MOZ_ASSERT_IF(origObj, origObj->is()); + + const BaseProxyHandler* handler; + if (origObj && origObj->is()) + handler = SelectDeadProxyHandler(&origObj->as()); + else + handler = DeadObjectProxy::singleton(); + + return NewProxyObject(cx, handler, NullHandleValue, nullptr, ProxyOptions()); +} diff --git a/js/src/proxy/DeadObjectProxy.h b/js/src/proxy/DeadObjectProxy.h index f42b9978e74a..fab8b9736518 100644 --- a/js/src/proxy/DeadObjectProxy.h +++ b/js/src/proxy/DeadObjectProxy.h @@ -11,6 +11,8 @@ namespace js { +class ProxyObject; + enum DeadProxyIsCallableIsConstructorOption { DeadProxyNotCallableNotConstructor, @@ -79,6 +81,12 @@ class DeadObjectProxy : public BaseProxyHandler bool IsDeadProxyObject(JSObject* obj); +const BaseProxyHandler* +SelectDeadProxyHandler(ProxyObject* obj); + +JSObject* +NewDeadProxyObject(JSContext* cx, JSObject* origObj = nullptr); + } /* namespace js */ #endif /* proxy_DeadObjectProxy_h */ diff --git a/js/src/vm/ProxyObject.cpp b/js/src/vm/ProxyObject.cpp index 4cb5505e73ec..296faa2eab8d 100644 --- a/js/src/vm/ProxyObject.cpp +++ b/js/src/vm/ProxyObject.cpp @@ -125,26 +125,15 @@ ProxyObject::setSameCompartmentPrivate(const Value& priv) void ProxyObject::nuke() { - // When nuking scripted proxies, isCallable and isConstructor values for - // the proxy needs to be preserved. Do this before clearing the target. - uint32_t callable = handler()->isCallable(this); - uint32_t constructor = handler()->isConstructor(this); + // Select a dead proxy handler based on the properties of this wrapper. + // Do this before clearing the target. + const BaseProxyHandler* handler = SelectDeadProxyHandler(this); // Clear the target reference. setSameCompartmentPrivate(NullValue()); // Update the handler to make this a DeadObjectProxy. - if (callable) { - if (constructor) - setHandler(DeadObjectProxy::singleton()); - else - setHandler(DeadObjectProxy::singleton()); - } else { - if (constructor) - setHandler(DeadObjectProxy::singleton()); - else - setHandler(DeadObjectProxy::singleton()); - } + setHandler(handler); // The proxy's reserved slots are not cleared and will continue to be // traced. This avoids the possibility of triggering write barriers while diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index 72ef062c7c85..ae8787cb29c1 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -190,11 +190,7 @@ WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope, CompartmentPrivate::Get(target)->wasNuked) { NS_WARNING("Trying to create a wrapper into or out of a nuked compartment"); - RootedObject ccw(cx, Wrapper::New(cx, obj, &CrossCompartmentWrapper::singleton)); - - NukeCrossCompartmentWrapper(cx, ccw); - - retObj.set(ccw); + retObj.set(JS_NewDeadWrapper(cx)); return; } From d82e509e370953c0385987922a061371ad7c33f7 Mon Sep 17 00:00:00 2001 From: Kris Maglione Date: Sat, 20 May 2017 11:51:05 -0700 Subject: [PATCH 10/12] Bug 1354733: Part 2 - Never rewrap dead wrappers. r=bholley MozReview-Commit-ID: 2oSGtKe9pkI --HG-- extra : rebase_source : 48fb1050ebfdf6e3c6f16cda13842b3e1eb4eb06 --- js/xpconnect/src/XPCComponents.cpp | 9 ++--- .../tests/unit/test_rewrap_dead_wrapper.js | 33 +++++++++++++++++++ js/xpconnect/tests/unit/xpcshell.ini | 1 + js/xpconnect/wrappers/WrapperFactory.cpp | 7 ++++ 4 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 js/xpconnect/tests/unit/test_rewrap_dead_wrapper.js diff --git a/js/xpconnect/src/XPCComponents.cpp b/js/xpconnect/src/XPCComponents.cpp index ff63133193d6..d876567ba78a 100644 --- a/js/xpconnect/src/XPCComponents.cpp +++ b/js/xpconnect/src/XPCComponents.cpp @@ -2841,10 +2841,11 @@ nsXPCComponents_Utils::IsDeadWrapper(HandleValue obj, bool* out) if (obj.isPrimitive()) return NS_ERROR_INVALID_ARG; - // Make sure to unwrap first. Once a proxy is nuked, it ceases to be a - // wrapper, meaning that, if passed to another compartment, we'll generate - // a CCW for it. Make sure that IsDeadWrapper sees through the confusion. - *out = JS_IsDeadWrapper(js::CheckedUnwrap(&obj.toObject())); + // We should never have cross-compartment wrappers for dead wrappers. + MOZ_ASSERT_IF(js::IsCrossCompartmentWrapper(&obj.toObject()), + !JS_IsDeadWrapper(js::UncheckedUnwrap(&obj.toObject()))); + + *out = JS_IsDeadWrapper(&obj.toObject()); return NS_OK; } diff --git a/js/xpconnect/tests/unit/test_rewrap_dead_wrapper.js b/js/xpconnect/tests/unit/test_rewrap_dead_wrapper.js new file mode 100644 index 000000000000..849c68e051da --- /dev/null +++ b/js/xpconnect/tests/unit/test_rewrap_dead_wrapper.js @@ -0,0 +1,33 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* See https://bugzilla.mozilla.org/show_bug.cgi?id=1354733 */ + +const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components; + +const global = this; + +function run_test() +{ + var sb = Cu.Sandbox(global); + let obj = new sb.Object(); + Cu.nukeSandbox(sb); + + ok(Cu.isDeadWrapper(obj), "object should be a dead wrapper"); + + // Create a new sandbox to wrap objects for. + + var sb = Cu.Sandbox(global); + Cu.evalInSandbox(function echo(val) { return val; }, + sb); + + let echoed = sb.echo(obj); + ok(Cu.isDeadWrapper(echoed), "Rewrapped object should be a dead wrapper"); + ok(echoed !== obj, "Rewrapped object should be a new dead wrapper"); + + ok(obj === obj, "Dead wrapper object should be equal to itself"); + + let liveObj = {}; + ok(liveObj === sb.echo(liveObj), "Rewrapped live object should be equal to itself"); +} diff --git a/js/xpconnect/tests/unit/xpcshell.ini b/js/xpconnect/tests/unit/xpcshell.ini index 346e83c1911e..44d48defebe2 100644 --- a/js/xpconnect/tests/unit/xpcshell.ini +++ b/js/xpconnect/tests/unit/xpcshell.ini @@ -99,6 +99,7 @@ skip-if = toolkit == "android" # bug 1347431 [test_nuke_sandbox.js] [test_nuke_sandbox_event_listeners.js] [test_nuke_webextension_wrappers.js] +[test_rewrap_dead_wrapper.js] [test_sandbox_metadata.js] [test_exportFunction.js] [test_promise.js] diff --git a/js/xpconnect/wrappers/WrapperFactory.cpp b/js/xpconnect/wrappers/WrapperFactory.cpp index ae8787cb29c1..96c918a61cc2 100644 --- a/js/xpconnect/wrappers/WrapperFactory.cpp +++ b/js/xpconnect/wrappers/WrapperFactory.cpp @@ -181,6 +181,13 @@ WrapperFactory::PrepareForWrapping(JSContext* cx, HandleObject scope, ExposeObjectToActiveJS(obj); } + // If the object is a dead wrapper, return a new dead wrapper rather than + // trying to wrap it for a different compartment. + if (JS_IsDeadWrapper(obj)) { + retObj.set(JS_NewDeadWrapper(cx, obj)); + return; + } + // If we've somehow gotten to this point after either the source or target // compartment has been nuked, return a DeadObjectProxy to prevent further // access. From 4ff181c16738213156dc9ad82afceef88f39c8be Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Sat, 20 May 2017 19:07:39 -0700 Subject: [PATCH 11/12] Bug 1366547 - set browser.storageManager.enabled in storage/storagemanager-persist.https.html so it won't be permaorange on beta, and set dom.storageManager.prompt.testing so it will actually work on both trunk and beta --- .../meta/storage/storagemanager-persist.https.html.ini | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/testing/web-platform/meta/storage/storagemanager-persist.https.html.ini b/testing/web-platform/meta/storage/storagemanager-persist.https.html.ini index 7ec60ea85889..7367cbb57303 100644 --- a/testing/web-platform/meta/storage/storagemanager-persist.https.html.ini +++ b/testing/web-platform/meta/storage/storagemanager-persist.https.html.ini @@ -1,6 +1,5 @@ [storagemanager-persist.https.html] type: testharness - expected: TIMEOUT - [navigator.storage.persist() returns a promise that resolves.] - expected: TIMEOUT + prefs: [browser.storageManager.enabled:true, + dom.storageManager.prompt.testing:true] From 2ef9628ee64e098161095ac9718c6c0900d099ba Mon Sep 17 00:00:00 2001 From: Phil Ringnalda Date: Sat, 20 May 2017 18:08:56 -0700 Subject: [PATCH 12/12] Bug 1366548 - Set dom.enable_performance_observer in server-timing/test_server_timing.html by copying the __dir__.ini from the directory where it should live, so it doesn't fail when we merge to beta --HG-- rename : testing/web-platform/meta/performance-timeline/__dir__.ini => testing/web-platform/meta/server-timing/__dir__.ini --- testing/web-platform/meta/server-timing/__dir__.ini | 1 + 1 file changed, 1 insertion(+) create mode 100644 testing/web-platform/meta/server-timing/__dir__.ini diff --git a/testing/web-platform/meta/server-timing/__dir__.ini b/testing/web-platform/meta/server-timing/__dir__.ini new file mode 100644 index 000000000000..92d8e2bd0140 --- /dev/null +++ b/testing/web-platform/meta/server-timing/__dir__.ini @@ -0,0 +1 @@ +prefs: [dom.enable_performance_observer:true]