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

Rename & refactor invoker commands to reflect new spec decisions. #48581

Merged
merged 1 commit into from
Oct 11, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
promise_test(async function (t) {
t.add_cleanup(reset);
assert_false(interestee.matches(":popover-open"));
interestbutton.setAttribute("interestaction", "togglepopover");
interestbutton.setAttribute("interestaction", "toggle-popover");
await hoverOver(interestbutton);
assert_true(interestee.matches(":popover-open"));
}, "hover interest invoking (as togglepopover) closed popover opens");
Expand All @@ -80,15 +80,15 @@
t.add_cleanup(reset);
interestee.showPopover();
assert_true(interestee.matches(":popover-open"));
interestbutton.setAttribute("interestaction", "togglepopover");
interestbutton.setAttribute("interestaction", "toggle-popover");
await hoverOver(interestbutton);
assert_false(interestee.matches(":popover-open"));
}, "hover interest invoking (as togglepopover) open popover closes");

promise_test(async function (t) {
t.add_cleanup(reset);
assert_false(interestee.matches(":popover-open"));
interestbutton.setAttribute("interestaction", "togglepopover");
interestbutton.setAttribute("interestaction", "toggle-popover");
interestbutton.focus();
assert_true(interestee.matches(":popover-open"));
}, "focus interest invoking (as togglepopover) closed popover opens");
Expand All @@ -97,15 +97,15 @@
t.add_cleanup(reset);
interestee.showPopover();
assert_true(interestee.matches(":popover-open"));
interestbutton.setAttribute("interestaction", "togglepopover");
interestbutton.setAttribute("interestaction", "toggle-popover");
interestbutton.focus();
assert_false(interestee.matches(":popover-open"));
}, "focus interest invoking (as togglepopover) open popover closes");

promise_test(async function (t) {
t.add_cleanup(reset);
assert_false(interestee.matches(":popover-open"));
interestbutton.setAttribute("interestaction", "tOgGlEpOpOvEr");
interestbutton.setAttribute("interestaction", "tOgGlE-pOpOvEr");
interestbutton.focus();
assert_true(interestee.matches(":popover-open"));
}, "interest invoking (as togglepopover - case insensitive) closed popover opens");
Expand Down
30 changes: 15 additions & 15 deletions html/semantics/invokers/invokeevent-dispatch-shadow.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,16 @@
const slot = shadow.appendChild(document.createElement("slot"));
let childEvent = null;
let childEventTarget = null;
let childEventInvoker = null;
let childEventSource = null;
let hostEvent = null;
let hostEventTarget = null;
let hostEventInvoker = null;
let hostEventSource = null;
slot.addEventListener(
"command",
(e) => {
childEvent = e;
childEventTarget = e.target;
childEventInvoker = e.invoker;
childEventSource = e.source;
},
{ once: true },
);
Expand All @@ -38,13 +38,13 @@
(e) => {
hostEvent = e;
hostEventTarget = e.target;
hostEventInvoker = e.invoker;
hostEventSource = e.source;
},
{ once: true },
);
const event = new CommandEvent("command", {
bubbles: true,
invoker: slot,
source: slot,
composed: true,
});
slot.dispatchEvent(event);
Expand All @@ -55,9 +55,9 @@
"target is child inside shadow boundary",
);
assert_equals(
childEventInvoker,
childEventSource,
slot,
"invoker is child inside shadow boundary",
"source is child inside shadow boundary",
);
assert_equals(
hostEvent,
Expand All @@ -70,11 +70,11 @@
"target is retargeted to shadowroot host",
);
assert_equals(
hostEventInvoker,
hostEventSource,
host,
"invoker is retargeted to shadowroot host",
"source is retargeted to shadowroot host",
);
}, "CommandEvent propagates across shadow boundaries retargeting invoker");
}, "CommandEvent propagates across shadow boundaries retargeting source");

test(function (t) {
const host = document.createElement("div");
Expand All @@ -84,22 +84,22 @@
const button = shadow.appendChild(document.createElement("button"));
const invokee = host.appendChild(document.createElement("div"));
button.commandForElement = invokee;
button.command = 'test-command';
button.command = '--test-command';
let event = null;
let eventTarget = null;
let eventInvoker = null;
let eventSource = null;
invokee.addEventListener(
"command",
(e) => {
event = e;
eventTarget = e.target;
eventInvoker = e.invoker;
eventSource = e.source;
},
{ once: true },
);
button.click();
assert_true(event instanceof CommandEvent);
assert_equals(eventTarget, invokee, "target is invokee");
assert_equals(eventInvoker, host, "invoker is host");
}, "cross shadow CommandEvent retargets invoker to host element");
assert_equals(eventSource, host, "source is host");
}, "cross shadow CommandEvent retargets source to host element");
</script>
54 changes: 27 additions & 27 deletions html/semantics/invokers/invokeevent-interface.tentative.html
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

test(function () {
const event = new CommandEvent("test");
assert_equals(event.invoker, null);
assert_readonly(event, "invoker", "readonly attribute value");
}, "invoker is readonly defaulting to null");
assert_equals(event.source, null);
assert_readonly(event, "source", "readonly attribute value");
}, "source is readonly defaulting to null");

test(function () {
const event = new CommandEvent("test", { command: "sAmPle" });
Expand Down Expand Up @@ -87,80 +87,80 @@
}, "command set to an object with a toString function");

test(function () {
const eventInit = { command: "sample", invoker: document.body };
const eventInit = { command: "sample", source: document.body };
const event = new CommandEvent("test", eventInit);
assert_equals(event.command, "sample");
assert_equals(event.invoker, document.body);
assert_equals(event.source, document.body);
}, "CommandEventInit properties set value");

test(function () {
const eventInit = {
command: "open",
invoker: document.getElementById("div"),
source: document.getElementById("div"),
};
const event = new CommandEvent("beforetoggle", eventInit);
assert_equals(event.command, "open");
assert_equals(event.invoker, document.getElementById("div"));
assert_equals(event.source, document.getElementById("div"));
}, "CommandEventInit properties set value 2");

test(function () {
const eventInit = {
command: "closed",
invoker: document.getElementById("button"),
source: document.getElementById("button"),
};
const event = new CommandEvent("toggle", eventInit);
assert_equals(event.command, "closed");
assert_equals(event.invoker, document.getElementById("button"));
assert_equals(event.source, document.getElementById("button"));
}, "CommandEventInit properties set value 3");

test(function () {
const event = new CommandEvent("test", { invoker: undefined });
assert_equals(event.invoker, null);
}, "invoker set to undefined");
const event = new CommandEvent("test", { source: undefined });
assert_equals(event.source, null);
}, "source set to undefined");

test(function () {
const event = new CommandEvent("test", { invoker: null });
assert_equals(event.invoker, null);
}, "invoker set to null");
const event = new CommandEvent("test", { source: null });
assert_equals(event.source, null);
}, "source set to null");

test(function () {
assert_throws_js(
TypeError,
function () {
new CommandEvent("test", { invoker: false });
new CommandEvent("test", { source: false });
},
"invoker is not an object",
"source is not an object",
);
}, "invoker set to false");
}, "source set to false");

test(function () {
assert_throws_js(
TypeError,
function () {
const event = new CommandEvent("test", { invoker: true });
const event = new CommandEvent("test", { source: true });
},
"invoker is not an object",
"source is not an object",
);
}, "invoker set to true");
}, "source set to true");

test(function () {
assert_throws_js(
TypeError,
function () {
const event = new CommandEvent("test", { invoker: {} });
const event = new CommandEvent("test", { source: {} });
},
"invoker is not an object",
"source is not an object",
);
}, "invoker set to {}");
}, "source set to {}");

test(function () {
assert_throws_js(
TypeError,
function () {
const eventInit = { command: "closed", invoker: new XMLHttpRequest() };
const eventInit = { command: "closed", source: new XMLHttpRequest() };
const event = new CommandEvent("toggle", eventInit);
},
"invoker is not an Element",
"source is not an Element",
);
}, "invoker set to non-Element EventTarget");
}, "source set to non-Element EventTarget");
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
<script src="resources/invoker-utils.js"></script>

<div id="invokee"></div>
<button id="invokerbutton" commandfor="invokee" command="custom-command"></button>
<button id="invokerbutton" commandfor="invokee" command="--custom-command"></button>
<input type="button" id="invalidbutton" commandfor="invokee" command="--custom-command">
<form id="aform"></form>

<script>
aform.addEventListener('submit', (e) => (e.preventDefault()));

function resetState() {
invokerbutton.setAttribute("commandfor", "invokee");
invokerbutton.setAttribute("command", "custom-command");
invokerbutton.setAttribute("command", "--custom-command");
invokerbutton.removeAttribute("disabled");
invokerbutton.removeAttribute("form");
invokerbutton.removeAttribute("type");
Expand All @@ -34,13 +35,13 @@
assert_equals(event.bubbles, false, "bubbles");
assert_equals(event.composed, true, "composed");
assert_equals(event.isTrusted, true, "isTrusted");
assert_equals(event.command, "custom-command", "command");
assert_equals(event.command, "--custom-command", "command");
assert_equals(event.target, invokee, "target");
assert_equals(event.invoker, invokerbutton, "invoker");
assert_equals(event.source, invokerbutton, "invoker");
}, "event dispatches on click");

// valid custom invokeactions
["-foo", "foo-", "cAsE-cArRiEs", "-", "-a-", "a-b", "---", "show-picker"].forEach(
["--foo", "--foo-", "--cAsE-cArRiEs", "--", "--a-", "--a-b", "---", "--show-picker"].forEach(
(command) => {
promise_test(async function (t) {
t.add_cleanup(resetState);
Expand All @@ -55,7 +56,7 @@
assert_equals(event.isTrusted, true, "isTrusted");
assert_equals(event.command, command, "command");
assert_equals(event.target, invokee, "target");
assert_equals(event.invoker, invokerbutton, "invoker");
assert_equals(event.source, invokerbutton, "invoker");
}, `setting custom command property to ${command} (must include dash) sets event command`);

promise_test(async function (t) {
Expand All @@ -71,13 +72,13 @@
assert_equals(event.isTrusted, true, "isTrusted");
assert_equals(event.command, command, "command");
assert_equals(event.target, invokee, "target");
assert_equals(event.invoker, invokerbutton, "invoker");
assert_equals(event.source, invokerbutton, "invoker");
}, `setting custom command attribute to ${command} (must include dash) sets event command`);
},
);

// invalid custom invokeactions
["foo", "foobar", "foo bar", "em—dash", "hidedocument"].forEach((command) => {
["-foo", "-foo-", "foo-bar", "-foo bar", "—-emdash", "hidedocument"].forEach((command) => {
promise_test(async function (t) {
t.add_cleanup(resetState);
let event = null;
Expand Down Expand Up @@ -117,6 +118,13 @@
assert_false(called, "event was not called");
}, "event does not dispatch if click:preventDefault is called");

promise_test(async function (t) {
let event = null;
invokee.addEventListener("command", (e) => (event = e), { once: true });
await clickOn(invalidbutton);
assert_equals(event, null, "command should not have fired");
}, "event does not dispatch on input[type=button]");

promise_test(async function (t) {
t.add_cleanup(resetState);
let called = false;
Expand Down Expand Up @@ -155,12 +163,12 @@
let event = null;
svgInvokee.addEventListener("command", (e) => (event = e), { once: true });
invokerbutton.setAttribute("commandfor", "svg-invokee");
invokerbutton.setAttribute("command", "custom-command");
invokerbutton.setAttribute("command", "--custom-command");
assert_equals(invokerbutton.commandForElement, svgInvokee);
await clickOn(invokerbutton);
assert_not_equals(event, null, "event was called");
assert_true(event instanceof CommandEvent, "event is CommandEvent");
assert_equals(event.invoker, invokerbutton, "event.invoker is set to right element");
assert_equals(event.source, invokerbutton, "event.invoker is set to right element");
assert_equals(event.target, svgInvokee, "event.target is set to right element");
}, "event dispatches if invokee is non-HTML Element");
</script>
Loading