Skip to content

Commit 5d167bd

Browse files
mfreed7moz-wptsync-bot
authored andcommitted
Bug 1931875 [wpt PR 49223] - Fix dialog.requestClose() in two ways, a=testonly
Automatic update from web-platform-tests Fix dialog.requestClose() in two ways 1. The prior implementation ignored the argument to requestClose. With this CL, requestClose(string) stores away string and then returns it from the CloseWatcher close event. 2. If the dialog's closedBy state is None (either explicitly or through the "Auto" state), requestClose throws an exception. I also added a more significant set of tests for requestClose() in all states. This goes along with recent discussion about throwing exceptions if requestClose() is called when the dialog isn't in the right state, relative to closedBy: whatwg/html#10164 (comment) The spec PR has been updated accordingly: whatwg/html#10737 Bug: 376516550 Change-Id: I023845844e6afb4da9a71637d517ac78d2861329 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6026242 Auto-Submit: Mason Freed <masonf@chromium.org> Reviewed-by: David Baron <dbaron@chromium.org> Commit-Queue: David Baron <dbaron@chromium.org> Cr-Commit-Position: refs/heads/main@{#1384345} -- wpt-commits: 6f4f09f92913154e70e9214636ee0e60c65f5d05 wpt-pr: 49223
1 parent 59c54db commit 5d167bd

File tree

1 file changed

+124
-23
lines changed

1 file changed

+124
-23
lines changed

testing/web-platform/tests/html/semantics/interactive-elements/the-dialog-element/dialog-requestclose.tentative.html

Lines changed: 124 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -41,31 +41,132 @@
4141
assert_false(dialog.open,'Without user activation, requestClose can\'t be cancelled');
4242
},`requestClose requires user activation in order to be cancelable`);
4343

44+
async function setup(t,closedby) {
45+
t.add_cleanup(() => {
46+
dialog.close();
47+
dialog.removeAttribute('closedby');
48+
dialog.returnValue = '';
49+
});
50+
assert_false(dialog.hasAttribute('closedby'));
51+
if (closedby) {
52+
dialog.setAttribute('closedby',closedby);
53+
}
54+
// Be sure any pending close events get fired.
55+
await new Promise(resolve => requestAnimationFrame(resolve));
56+
return getSignal(t);
57+
}
58+
4459
[false,true].forEach(modal => {
45-
promise_test(async (t) => {
46-
t.add_cleanup(() => dialog.close());
47-
openDialog(modal);
48-
dialog.requestClose();
49-
assert_false(dialog.open);
50-
},`${modal ? "Modal:" : "Non-modal:"} requestClose closes the dialog`);
60+
[null,'any','closedrequest','none'].forEach(closedby => {
61+
const testDescription = `for ${modal ? "modal" : "modeless"} dialog with closedby=${closedby}`;
62+
promise_test(async (t) => {
63+
await setup(t,closedby);
64+
openDialog(modal);
65+
if (dialog.closedBy != "none") {
66+
dialog.requestClose();
67+
assert_false(dialog.open);
68+
} else {
69+
assert_throws_dom('InvalidStateError',() => dialog.requestClose());
70+
assert_true(dialog.open);
71+
}
72+
},`requestClose basic behavior ${testDescription}`);
73+
74+
promise_test(async (t) => {
75+
const signal = await setup(t,closedby);
76+
let events = [];
77+
dialog.addEventListener('cancel',() => events.push('cancel'),{signal});
78+
dialog.addEventListener('close',() => events.push('close'),{signal});
79+
openDialog(modal);
80+
assert_array_equals(events,[]);
81+
if (dialog.closedBy != "none") {
82+
dialog.requestClose();
83+
assert_false(dialog.open);
84+
assert_array_equals(events,['cancel'],'close is scheduled');
85+
await new Promise(resolve => requestAnimationFrame(resolve));
86+
assert_array_equals(events,['cancel','close']);
87+
} else {
88+
assert_throws_dom('InvalidStateError',() => dialog.requestClose());
89+
}
90+
},`requestClose fires both cancel and close ${testDescription}`);
5191

52-
promise_test(async (t) => {
53-
t.add_cleanup(() => dialog.close());
54-
const signal = getSignal(t);
55-
let shouldPreventDefault = true;
56-
dialog.addEventListener('cancel',(e) => {
57-
if (shouldPreventDefault) {
58-
e.preventDefault();
92+
promise_test(async (t) => {
93+
const signal = await setup(t,'none');
94+
let events = [];
95+
dialog.addEventListener('cancel',() => events.push('cancel'),{signal});
96+
dialog.addEventListener('close',() => events.push('close'),{signal});
97+
openDialog(modal);
98+
dialog.setAttribute('closedby',closedby);
99+
assert_array_equals(events,[]);
100+
if (dialog.closedBy != "none") {
101+
dialog.requestClose();
102+
assert_false(dialog.open);
103+
} else {
104+
assert_throws_dom('InvalidStateError',() => dialog.requestClose());
59105
}
60-
},{signal});
61-
openDialog(modal);
62-
await clickOn(dialog); // User activation
63-
dialog.requestClose();
64-
assert_true(dialog.open,'cancel event was cancelled - dialog shouldn\'t close');
65-
shouldPreventDefault = false;
66-
await clickOn(dialog); // User activation
67-
dialog.requestClose();
68-
assert_false(dialog.open,'cancel event was not cancelled - dialog should now close');
69-
},`${modal ? "Modal:" : "Non-modal:"} requestClose can be cancelled`);
106+
},`changing closedby from 'none' to '${closedby}' for ${modal ? "modal" : "modeless"} dialog`);
107+
108+
promise_test(async (t) => {
109+
const signal = await setup(t,closedby);
110+
let events = [];
111+
dialog.addEventListener('cancel',() => events.push('cancel'),{signal});
112+
dialog.addEventListener('close',() => events.push('close'),{signal});
113+
openDialog(modal);
114+
dialog.removeAttribute('closedby');
115+
assert_array_equals(events,[]);
116+
if (dialog.closedBy != "none") {
117+
dialog.requestClose();
118+
assert_false(dialog.open);
119+
} else {
120+
assert_throws_dom('InvalidStateError',() => dialog.requestClose());
121+
}
122+
},`Removing closedby when closedby='${closedby}' for ${modal ? "modal" : "modeless"} dialog`);
123+
124+
if (dialog.closedBy != "none") {
125+
promise_test(async (t) => {
126+
const signal = await setup(t,closedby);
127+
let shouldPreventDefault = true;
128+
dialog.addEventListener('cancel',(e) => {
129+
if (shouldPreventDefault) {
130+
e.preventDefault();
131+
}
132+
},{signal});
133+
openDialog(modal);
134+
await clickOn(dialog); // User activation
135+
dialog.requestClose();
136+
assert_true(dialog.open,'cancel event was cancelled - dialog shouldn\'t close');
137+
shouldPreventDefault = false;
138+
await clickOn(dialog); // User activation
139+
dialog.requestClose();
140+
assert_false(dialog.open,'cancel event was not cancelled - dialog should now close');
141+
},`requestClose can be cancelled ${testDescription}`);
142+
143+
promise_test(async (t) => {
144+
await setup(t,closedby);
145+
openDialog(modal);
146+
assert_equals(dialog.returnValue,'','Return value starts out empty');
147+
const returnValue = 'The return value';
148+
dialog.requestClose(returnValue);
149+
assert_false(dialog.open);
150+
assert_equals(dialog.returnValue,returnValue,'Return value should be set');
151+
dialog.show();
152+
dialog.close();
153+
assert_equals(dialog.returnValue,returnValue,'Return value should not be changed by close()');
154+
dialog.show();
155+
dialog.close('another');
156+
assert_equals(dialog.returnValue,'another','Return value changes via close(value)');
157+
},`requestClose(returnValue) passes along the return value ${testDescription}`);
158+
159+
promise_test(async (t) => {
160+
await setup(t,closedby);
161+
dialog.addEventListener('cancel',(e) => e.preventDefault(),{once:true});
162+
openDialog(modal);
163+
dialog.returnValue = 'foo';
164+
assert_equals(dialog.returnValue,'foo');
165+
dialog.requestClose('This should not get saved');
166+
assert_true(dialog.open,'cancelled');
167+
assert_equals(dialog.returnValue,'foo','Return value should not be changed');
168+
},`requestClose(returnValue) doesn't change returnvalue when cancelled ${testDescription}`);
169+
}
170+
});
70171
});
71172
</script>

0 commit comments

Comments
 (0)