Skip to content

Commit

Permalink
Add aftertoggle event for popover
Browse files Browse the repository at this point in the history
This CL adds an async `aftertoggle` event to both the show and hide
popover transitions, and renames the event class from BeforeToggle
to PopoverToggle, to be used by both events.

This was resolved by OpenUI here:
openui/open-ui#342 (comment)

Bug: 1307772
Change-Id: I996be74b90f43eee4bf859cecfed051fa6f633d5
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4160443
Auto-Submit: Mason Freed <masonf@chromium.org>
Commit-Queue: Joey Arhar <jarhar@chromium.org>
Commit-Queue: Mason Freed <masonf@chromium.org>
Reviewed-by: Joey Arhar <jarhar@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1092158}
  • Loading branch information
mfreed7 authored and chromium-wpt-export-bot committed Jan 13, 2023
1 parent 6a6832e commit e3246af
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 67 deletions.
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

1 comment on commit e3246af

@community-tc-integration
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Uh oh! Looks like an error! Details

RequestError: connect ECONNREFUSED 10.8.18.19:80

Please sign in to comment.