Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add aftertoggle event for popover #37915

Merged
merged 1 commit into from
Jan 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions html/semantics/popovers/idlharness.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@
'document.getElementById("b3")',
],
BeforeToggleEvent: [
'new BeforeToggleEvent("beforetoggle")',
'new BeforeToggleEvent("beforetoggle", {currentState: "open"})',
'new BeforeToggleEvent("beforetoggle", {currentState: "open",newState: "open"})',
'new PopoverToggleEvent("beforetoggle")',
'new PopoverToggleEvent("beforetoggle", {currentState: "open"})',
'new PopoverToggleEvent("beforetoggle", {currentState: "open",newState: "open"})',
'new PopoverToggleEvent("aftertoggle")',
'new PopoverToggleEvent("aftertoggle", {currentState: "open"})',
'new PopoverToggleEvent("aftertoggle", {currentState: "open",newState: "open"})',
],
});
}
Expand Down
69 changes: 54 additions & 15 deletions html/semantics/popovers/popover-events.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -16,54 +16,93 @@
const popover = document.querySelector('[popover]');
assert_false(popover.matches(':open'));
let showCount = 0;
let afterShowCount = 0;
let hideCount = 0;
let afterHideCount = 0;
function listener(e) {
if (e.newState === "open") {
assert_equals(e.currentState,"closed",'Popover toggleevent states should be "open" and "closed"')
assert_true(e.target.matches(':closed'),'The popover should be in the :closed state when the opening event fires.');
assert_false(e.target.matches(':open'),'The popover should *not* be in the :open state when the opening event fires.');
++showCount;
if (e.type === "beforetoggle") {
if (e.newState === "open") {
assert_equals(e.currentState,"closed",'The "beforetoggle" event should be fired before the popover is open');
assert_true(e.target.matches(':closed'),'The popover should be in the :closed state when the opening event fires.');
assert_false(e.target.matches(':open'),'The popover should *not* be in the :open state when the opening event fires.');
++showCount;
} else {
assert_equals(e.newState,"closed",'Popover toggleevent states should be "open" and "closed"');
assert_equals(e.currentState,"open",'The "beforetoggle" event should be fired before the popover is closed')
assert_true(e.target.matches(':open'),'The popover should be in the :open state when the hiding event fires.');
assert_false(e.target.matches(':closed'),'The popover should *not* be in the :closed state when the hiding event fires.');
++hideCount;
}
} else {
assert_equals(e.currentState,"open",'Popover toggleevent states should be "open" and "closed"')
assert_equals(e.newState,"closed",'Popover toggleevent states should be "open" and "closed"')
assert_true(e.target.matches(':open'),'The popover should be in the :open state when the hiding event fires.');
assert_false(e.target.matches(':closed'),'The popover should *not* be in the :closed state when the hiding event fires.');
++hideCount;
assert_equals(e.type,"aftertoggle",'Popover events should be "beforetoggle" and "aftertoggle"')
if (e.newState === "open") {
assert_equals(e.currentState,"open",'Aftertoggle should be fired after the popover is open');
if (document.body.contains(e.target)) {
assert_true(e.target.matches(':open'),'The popover should be in the :open state when the after opening event fires.');
assert_false(e.target.matches(':closed'),'The popover should *not* be in the :closed state when the after opening event fires.');
}
++afterShowCount;
} else {
assert_equals(e.newState,"closed",'Popover toggleevent states should be "open" and "closed"');
assert_equals(e.currentState,"closed",'Aftertoggle should be fired after the popover is closed');
assert_true(e.target.matches(':closed'),'The popover should be in the :closed state when the after hiding event fires.');
assert_false(e.target.matches(':open'),'The popover should *not* be in the :open state when the after hiding event fires.');
++afterHideCount;
}
e.preventDefault(); // "aftertoggle" should not be cancelable.
}
};
switch (method) {
case "listener":
const controller = new AbortController();
const signal = controller.signal;
t.add_cleanup(() => controller.abort());
// The 'beforetoggle' event bubbles.
// These events bubble.
document.addEventListener('beforetoggle', listener, {signal});
document.addEventListener('aftertoggle', listener, {signal});
break;
case "attribute":
assert_false(popover.hasAttribute('onbeforetoggle'));
t.add_cleanup(() => popover.removeAttribute('onbeforetoggle'));
popover.onbeforetoggle = listener;
assert_false(popover.hasAttribute('onaftertoggle'));
t.add_cleanup(() => popover.removeAttribute('onaftertoggle'));
popover.onaftertoggle = listener;
break;
default: assert_unreached();
}
assert_equals(0,showCount);
assert_equals(0,hideCount);
assert_equals(0,afterShowCount);
assert_equals(0,afterHideCount);
popover.showPopover();
assert_true(popover.matches(':open'));
assert_equals(1,showCount);
assert_equals(0,hideCount);
assert_equals(0,afterShowCount);
assert_equals(0,afterHideCount);
await waitForRender();
assert_equals(1,afterShowCount,'aftertoggle show is fired asynchronously');
assert_equals(0,afterHideCount);
assert_true(popover.matches(':open'));
popover.hidePopover();
assert_false(popover.matches(':open'));
assert_equals(1,showCount);
assert_equals(1,hideCount);
assert_equals(1,afterShowCount);
assert_equals(0,afterHideCount);
await waitForRender();
assert_equals(1,afterShowCount);
assert_equals(1,afterHideCount,'aftertoggle hide is fired asynchronously');
// No additional events
await waitForRender();
await waitForRender();
// No additional events after animation frame
assert_false(popover.matches(':open'));
assert_equals(1,showCount);
assert_equals(1,hideCount);
}, `Beforetoggle event (${method}) get properly dispatched for popovers`);
assert_equals(1,afterShowCount);
assert_equals(1,afterHideCount);
}, `The "beforetoggle" event (${method}) get properly dispatched for popovers`);
}

promise_test(async t => {
Expand All @@ -86,7 +125,7 @@
assert_true(popover.matches(':open'));
popover.hidePopover();
assert_false(popover.matches(':open'));
}, 'Beforetoggle event is cancelable for the "opening" transition');
}, 'The "beforetoggle" event is cancelable for the "opening" transition');

promise_test(async t => {
const popover = document.querySelector('[popover]');
Expand All @@ -104,6 +143,6 @@
await waitForRender(); // Check for async events also
await waitForRender(); // Check for async events also
assert_false(popover.matches(':open'));
}, 'Beforetoggle event is not fired for element removal');
}, 'The "beforetoggle" event is not fired for element removal');
};
</script>
92 changes: 46 additions & 46 deletions html/semantics/popovers/toggleevent-interface.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,200 +7,200 @@

<script>
test(function() {
var event = new BeforeToggleEvent("");
assert_true(event instanceof window.BeforeToggleEvent);
}, "the event is an instance of BeforeToggleEvent");
var event = new PopoverToggleEvent("");
assert_true(event instanceof window.PopoverToggleEvent);
}, "the event is an instance of PopoverToggleEvent");

test(function() {
var event = new BeforeToggleEvent("");
var event = new PopoverToggleEvent("");
assert_true(event instanceof window.Event);
}, "the event inherts from Event");

test(function() {
assert_throws_js(TypeError, function() {
new BeforeToggleEvent();
new PopoverToggleEvent();
}, 'First argument (type) is required, so was expecting a TypeError.');
}, 'Missing type argument');

test(function() {
var event = new BeforeToggleEvent("test");
var event = new PopoverToggleEvent("test");
assert_equals(event.type, "test");
}, "type argument is string");

test(function() {
var event = new BeforeToggleEvent(null);
var event = new PopoverToggleEvent(null);
assert_equals(event.type, "null");
}, "type argument is null");

test(function() {
var event = new BeforeToggleEvent(undefined);
var event = new PopoverToggleEvent(undefined);
assert_equals(event.type, "undefined");
}, "event type set to undefined");

test(function() {
var event = new BeforeToggleEvent("test");
var event = new PopoverToggleEvent("test");
assert_equals(event.currentState, "");
}, "currentState has default value of empty string");

test(function() {
var event = new BeforeToggleEvent("test");
var event = new PopoverToggleEvent("test");
assert_readonly(event, "currentState", "readonly attribute value");
}, "currentState is readonly");

test(function() {
var event = new BeforeToggleEvent("test");
var event = new PopoverToggleEvent("test");
assert_equals(event.newState, "");
}, "newState has default value of empty string");

test(function() {
var event = new BeforeToggleEvent("test");
var event = new PopoverToggleEvent("test");
assert_readonly(event, "newState", "readonly attribute value");
}, "newState is readonly");

test(function() {
var event = new BeforeToggleEvent("test", null);
var event = new PopoverToggleEvent("test", null);
assert_equals(event.currentState, "");
assert_equals(event.newState, "");
}, "BeforeToggleEventInit argument is null");
}, "PopoverToggleEventInit argument is null");

test(function() {
var event = new BeforeToggleEvent("test", undefined);
var event = new PopoverToggleEvent("test", undefined);
assert_equals(event.currentState, "");
assert_equals(event.newState, "");
}, "BeforeToggleEventInit argument is undefined");
}, "PopoverToggleEventInit argument is undefined");

test(function() {
var event = new BeforeToggleEvent("test", {});
var event = new PopoverToggleEvent("test", {});
assert_equals(event.currentState, "");
assert_equals(event.newState, "");
}, "BeforeToggleEventInit argument is empty dictionary");
}, "PopoverToggleEventInit argument is empty dictionary");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: "sample"});
var event = new PopoverToggleEvent("test", {currentState: "sample"});
assert_equals(event.currentState, "sample");
}, "currentState set to 'sample'");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: undefined});
var event = new PopoverToggleEvent("test", {currentState: undefined});
assert_equals(event.currentState, "");
}, "currentState set to undefined");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: null});
var event = new PopoverToggleEvent("test", {currentState: null});
assert_equals(event.currentState, "null");
}, "currentState set to null");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: false});
var event = new PopoverToggleEvent("test", {currentState: false});
assert_equals(event.currentState, "false");
}, "currentState set to false");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: true});
var event = new PopoverToggleEvent("test", {currentState: true});
assert_equals(event.currentState, "true");
}, "currentState set to true");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: 0.5});
var event = new PopoverToggleEvent("test", {currentState: 0.5});
assert_equals(event.currentState, "0.5");
}, "currentState set to a number");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: []});
var event = new PopoverToggleEvent("test", {currentState: []});
assert_equals(event.currentState, "");
}, "currentState set to []");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: [1, 2, 3]});
var event = new PopoverToggleEvent("test", {currentState: [1, 2, 3]});
assert_equals(event.currentState, "1,2,3");
}, "currentState set to [1, 2, 3]");

test(function() {
var event = new BeforeToggleEvent("test", {currentState: {sample: 0.5}});
var event = new PopoverToggleEvent("test", {currentState: {sample: 0.5}});
assert_equals(event.currentState, "[object Object]");
}, "currentState set to an object");

test(function() {
var event = new BeforeToggleEvent("test",
var event = new PopoverToggleEvent("test",
{currentState: {valueOf: function () { return 'sample'; }}});
assert_equals(event.currentState, "[object Object]");
}, "currentState set to an object with a valueOf function");

test(function() {
var eventInit = {currentState: "sample",newState: "sample2"};
var event = new BeforeToggleEvent("test", eventInit);
var event = new PopoverToggleEvent("test", eventInit);
assert_equals(event.currentState, "sample");
assert_equals(event.newState, "sample2");
}, "BeforeToggleEventInit properties set value");
}, "PopoverToggleEventInit properties set value");

test(function() {
var eventInit = {currentState: "open",newState: "closed"};
var event = new BeforeToggleEvent("beforetoggle", eventInit);
var event = new PopoverToggleEvent("beforetoggle", eventInit);
assert_equals(event.currentState, "open");
assert_equals(event.newState, "closed");
}, "BeforeToggleEventInit properties set value 2");
}, "PopoverToggleEventInit properties set value 2");

test(function() {
var eventInit = {currentState: "closed",newState: "open"};
var event = new BeforeToggleEvent("beforetoggle", eventInit);
var event = new PopoverToggleEvent("aftertoggle", eventInit);
assert_equals(event.currentState, "closed");
assert_equals(event.newState, "open");
}, "BeforeToggleEventInit properties set value 3");
}, "PopoverToggleEventInit properties set value 3");

test(function() {
var eventInit = {currentState: "open",newState: "open"};
var event = new BeforeToggleEvent("beforetoggle", eventInit);
var event = new PopoverToggleEvent("beforetoggle", eventInit);
assert_equals(event.currentState, "open");
assert_equals(event.newState, "open");
}, "BeforeToggleEventInit properties set value 4");
}, "PopoverToggleEventInit properties set value 4");

test(function() {
var event = new BeforeToggleEvent("test", {newState: "sample"});
var event = new PopoverToggleEvent("test", {newState: "sample"});
assert_equals(event.newState, "sample");
}, "newState set to 'sample'");

test(function() {
var event = new BeforeToggleEvent("test", {newState: undefined});
var event = new PopoverToggleEvent("test", {newState: undefined});
assert_equals(event.newState, "");
}, "newState set to undefined");

test(function() {
var event = new BeforeToggleEvent("test", {newState: null});
var event = new PopoverToggleEvent("test", {newState: null});
assert_equals(event.newState, "null");
}, "newState set to null");

test(function() {
var event = new BeforeToggleEvent("test", {newState: false});
var event = new PopoverToggleEvent("test", {newState: false});
assert_equals(event.newState, "false");
}, "newState set to false");

test(function() {
var event = new BeforeToggleEvent("test", {newState: true});
var event = new PopoverToggleEvent("test", {newState: true});
assert_equals(event.newState, "true");
}, "newState set to true");

test(function() {
var event = new BeforeToggleEvent("test", {newState: 0.5});
var event = new PopoverToggleEvent("test", {newState: 0.5});
assert_equals(event.newState, "0.5");
}, "newState set to a number");

test(function() {
var event = new BeforeToggleEvent("test", {newState: []});
var event = new PopoverToggleEvent("test", {newState: []});
assert_equals(event.newState, "");
}, "newState set to []");

test(function() {
var event = new BeforeToggleEvent("test", {newState: [1, 2, 3]});
var event = new PopoverToggleEvent("test", {newState: [1, 2, 3]});
assert_equals(event.newState, "1,2,3");
}, "newState set to [1, 2, 3]");

test(function() {
var event = new BeforeToggleEvent("test", {newState: {sample: 0.5}});
var event = new PopoverToggleEvent("test", {newState: {sample: 0.5}});
assert_equals(event.newState, "[object Object]");
}, "newState set to an object");

test(function() {
var event = new BeforeToggleEvent("test",
var event = new PopoverToggleEvent("test",
{newState: {valueOf: function () { return 'sample'; }}});
assert_equals(event.newState, "[object Object]");
}, "newState set to an object with a valueOf function");
Expand Down
Loading