зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1774491 [wpt PR 34454] - Fix popup animation bug, and add more testing of animations, a=testonly
Automatic update from web-platform-tests Fix popup animation bug, and add more testing of animations Primarily, this CL adds a test of popup animations for these two cases: 1. descendant elements have an animation: make sure "hide" waits for it 2. there are already-running animations: make sure "hide" doesn't wait These were follow-up action items from [1]. While writing this test, I found and fixed a corner case bug: if there are *only* pre-existing animations, a popup would never be hidden. [1] https://chromium-review.googlesource.com/c/chromium/src/+/3688871 Bug: 1307772 Change-Id: I133f4d682bb8081b137fb23675137b06e6a15565 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3708115 Reviewed-by: Robert Flack <flackr@chromium.org> Auto-Submit: Mason Freed <masonf@chromium.org> Commit-Queue: Robert Flack <flackr@chromium.org> Cr-Commit-Position: refs/heads/main@{#1015056} -- wpt-commits: 93a98d6ac4785d3c78b57845d91c78e2bf12c6eb wpt-pr: 34454
This commit is contained in:
Родитель
d1939b2c9d
Коммит
a36765a3a4
|
@ -0,0 +1,90 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<meta charset="utf-8">
|
||||
<link rel=author href="mailto:masonf@chromium.org">
|
||||
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/popup-utils.js"></script>
|
||||
|
||||
<body>
|
||||
<style>
|
||||
.animation { opacity: 0; }
|
||||
.animation:top-layer { opacity: 1; }
|
||||
.animation:not(:top-layer) { animation: fade-out 1000s; }
|
||||
@keyframes fade-out {
|
||||
from { opacity: 1; }
|
||||
to { opacity: 0; }
|
||||
}
|
||||
|
||||
.animation>div>div { left: 0; }
|
||||
.animation:not(:top-layer)>div>div { animation: rotate 1000s; color:red;}
|
||||
@keyframes rotate {
|
||||
from { transform: rotate(0); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
[popup] { top: 200px; }
|
||||
[popup]::backdrop { background-color: rgba(255,0,0,0.2); }
|
||||
</style>
|
||||
|
||||
<script>
|
||||
function createPopup(t,type) {
|
||||
const popup = document.createElement('div');
|
||||
popup.popup = 'auto';
|
||||
popup.classList = type;
|
||||
const div = document.createElement('div');
|
||||
const descendent = div.appendChild(document.createElement('div'));
|
||||
descendent.appendChild(document.createTextNode("Descendent element"));
|
||||
popup.append("This is a popup",div);
|
||||
document.body.appendChild(popup);
|
||||
t.add_cleanup(() => popup.remove());
|
||||
return {popup, descendent};
|
||||
}
|
||||
promise_test(async (t) => {
|
||||
const {popup, descendent} = createPopup(t,'animation');
|
||||
assert_false(isElementVisible(popup));
|
||||
assert_equals(descendent.parentElement.parentElement,popup);
|
||||
popup.showPopup();
|
||||
assert_true(popup.matches(':top-layer'));
|
||||
assert_true(isElementVisible(popup));
|
||||
assert_equals(popup.getAnimations({subtree: true}).length,0);
|
||||
popup.hidePopup();
|
||||
const animations = popup.getAnimations({subtree: true});
|
||||
assert_equals(animations.length,2,'There should be two animations running');
|
||||
assert_false(popup.matches(':top-layer'),'popup should not match :top-layer as soon as hidden');
|
||||
assert_true(isElementVisible(popup),'but animations should keep the popup visible');
|
||||
assert_true(isElementVisible(descendent),'The descendent should also be visible');
|
||||
await waitForRender();
|
||||
await waitForRender();
|
||||
assert_equals(popup.getAnimations({subtree: true}).length,2,'The animations should still be running');
|
||||
assert_true(isElementVisible(popup),'Popup should still be visible due to animation');
|
||||
animations.forEach(animation => animation.finish()); // Force the animations to finish
|
||||
await waitForRender(); // Wait one frame
|
||||
assert_false(popup.matches(':top-layer'),'The popup still shouldn\'t match :top-layer');
|
||||
assert_false(isElementVisible(popup),'The popup should now be invisible');
|
||||
assert_false(isElementVisible(descendent),'The descendent should also be invisible');
|
||||
assert_equals(popup.getAnimations({subtree: true}).length,0);
|
||||
},'Descendent animations should keep the popup visible until the animation ends');
|
||||
|
||||
promise_test(async (t) => {
|
||||
const {popup, descendent} = createPopup(t,'');
|
||||
assert_equals(popup.classList.length, 0);
|
||||
assert_false(isElementVisible(popup));
|
||||
popup.showPopup();
|
||||
assert_true(popup.matches(':top-layer'));
|
||||
assert_true(isElementVisible(popup));
|
||||
assert_equals(popup.getAnimations({subtree: true}).length,0);
|
||||
// Start an animation on the popup and its descendent.
|
||||
popup.animate([{opacity: 1},{opacity: 0}],{duration: 1000000,iterations: 1});
|
||||
descendent.animate([{transform: 'rotate(0)'},{transform: 'rotate(360deg)'}],{duration: 1000000,iterations: 1});
|
||||
assert_equals(popup.getAnimations({subtree: true}).length,2);
|
||||
// Then hide the popup.
|
||||
popup.hidePopup();
|
||||
assert_false(popup.matches(':top-layer'),'popup should not match :top-layer as soon as hidden');
|
||||
assert_equals(popup.getAnimations({subtree: true}).length,2,'animations should still be running');
|
||||
await waitForRender();
|
||||
assert_equals(popup.getAnimations({subtree: true}).length,2,'animations should still be running');
|
||||
assert_false(isElementVisible(popup),'Pre-existing animations should not keep the popup visible');
|
||||
},'Pre-existing animations should *not* keep the popup visible until the animation ends');
|
||||
</script>
|
|
@ -4,6 +4,7 @@
|
|||
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/popup-utils.js"></script>
|
||||
|
||||
<div id=popups>
|
||||
<div popup id=boolean>Popup</div>
|
||||
|
@ -21,7 +22,7 @@
|
|||
|
||||
<script>
|
||||
function popupVisible(popup, isPopup) {
|
||||
const isVisible = !!(popup.offsetWidth || popup.offsetHeight || popup.getClientRects().length);
|
||||
const isVisible = isElementVisible(popup);
|
||||
if (isVisible) {
|
||||
assert_not_equals(window.getComputedStyle(popup).display,'none');
|
||||
assert_equals(isPopup,popup.matches(':top-layer'));
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
<link rel=help href="https://open-ui.org/components/popup.research.explainer">
|
||||
<script src="/resources/testharness.js"></script>
|
||||
<script src="/resources/testharnessreport.js"></script>
|
||||
<script src="resources/popup-utils.js"></script>
|
||||
|
||||
<script>
|
||||
function ensureShadowDom(host) {
|
||||
|
@ -35,9 +36,6 @@
|
|||
ensureShadowDom(testRoot);
|
||||
return findPopups(testRoot);
|
||||
}
|
||||
function popupVisible(popup) {
|
||||
return !!(popup.offsetWidth || popup.offsetHeight || popup.getClientRects().length);
|
||||
}
|
||||
function showPopup(testId,popupNum) {
|
||||
getPopupReferences(testId)[popupNum].showPopup();
|
||||
}
|
||||
|
@ -59,7 +57,7 @@
|
|||
const popup = getPopupReferences('test1')[0];
|
||||
popup.showPopup();
|
||||
assert_true(popup.matches(':top-layer'));
|
||||
assert_true(popupVisible(popup));
|
||||
assert_true(isElementVisible(popup));
|
||||
}, "Popups located inside shadow DOM can still be shown");
|
||||
</script>
|
||||
|
||||
|
@ -85,12 +83,12 @@
|
|||
const [popup1,popup2] = getPopupReferences('test2');
|
||||
popup1.showPopup();
|
||||
assert_true(popup1.matches(':top-layer'));
|
||||
assert_true(popupVisible(popup1));
|
||||
assert_true(isElementVisible(popup1));
|
||||
popup2.showPopup();
|
||||
assert_false(popup1.matches(':top-layer'), 'popup1 open'); // P1 was closed by P2
|
||||
assert_false(popupVisible(popup1), 'popup1 visible');
|
||||
assert_false(isElementVisible(popup1), 'popup1 visible');
|
||||
assert_true(popup2.matches(':top-layer'), 'popup2 open'); // P2 is open
|
||||
assert_true(popupVisible(popup2), 'popup2 visible');
|
||||
assert_true(isElementVisible(popup2), 'popup2 visible');
|
||||
}, "anchor references do not cross shadow boundaries");
|
||||
</script>
|
||||
|
||||
|
@ -114,14 +112,14 @@
|
|||
const [popup1,popup2] = getPopupReferences('test3');
|
||||
popup1.showPopup();
|
||||
assert_true(popup1.matches(':top-layer'));
|
||||
assert_true(popupVisible(popup1));
|
||||
assert_true(isElementVisible(popup1));
|
||||
// Showing popup2 should not close popup1, since it is a flat
|
||||
// tree ancestor of popup2's anchor button.
|
||||
popup2.showPopup();
|
||||
assert_true(popup2.matches(':top-layer'));
|
||||
assert_true(popupVisible(popup2));
|
||||
assert_true(isElementVisible(popup2));
|
||||
assert_true(popup1.matches(':top-layer'));
|
||||
assert_true(popupVisible(popup1));
|
||||
assert_true(isElementVisible(popup1));
|
||||
popup1.hidePopup();
|
||||
assert_false(popup2.matches(':top-layer'));
|
||||
assert_false(popup1.matches(':top-layer'));
|
||||
|
@ -151,12 +149,12 @@
|
|||
popup2.showPopup();
|
||||
// Both 1 and 2 should be open at this point.
|
||||
assert_true(popup1.matches(':top-layer'), 'popup1 not open');
|
||||
assert_true(popupVisible(popup1));
|
||||
assert_true(isElementVisible(popup1));
|
||||
assert_true(popup2.matches(':top-layer'), 'popup2 not open');
|
||||
assert_true(popupVisible(popup2));
|
||||
assert_true(isElementVisible(popup2));
|
||||
// This should hide both of them.
|
||||
popup1.hidePopup();
|
||||
assert_false(popup2.matches(':top-layer'));
|
||||
assert_false(popupVisible(popup2));
|
||||
assert_false(isElementVisible(popup2));
|
||||
}, "The popup stack is preserved across shadow-inclusive ancestors");
|
||||
</script>
|
||||
|
|
|
@ -20,3 +20,6 @@ async function sendEscape() {
|
|||
await new test_driver.send_keys(document.body,'\uE00C'); // Escape
|
||||
await waitForRender();
|
||||
}
|
||||
function isElementVisible(el) {
|
||||
return !!(el.offsetWidth || el.offsetHeight || el.getClientRects().length);
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче