diff --git a/testing/web-platform/meta/MANIFEST.json b/testing/web-platform/meta/MANIFEST.json
index cd03caf41546..2024d71bdf21 100644
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -287318,6 +287318,11 @@
{}
]
],
+ "html/webappapis/scripting/events/resources/event-handler-body.js": [
+ [
+ {}
+ ]
+ ],
"html/webappapis/scripting/events/resources/open-window.html": [
[
{}
@@ -361544,12 +361549,6 @@
{}
]
],
- "html/webappapis/scripting/events/body-exposed-window-event-handlers.html": [
- [
- "/html/webappapis/scripting/events/body-exposed-window-event-handlers.html",
- {}
- ]
- ],
"html/webappapis/scripting/events/body-onload.html": [
[
"/html/webappapis/scripting/events/body-onload.html",
@@ -361580,6 +361579,12 @@
{}
]
],
+ "html/webappapis/scripting/events/event-handler-attributes-windowless-body.html": [
+ [
+ "/html/webappapis/scripting/events/event-handler-attributes-windowless-body.html",
+ {}
+ ]
+ ],
"html/webappapis/scripting/events/event-handler-javascript.html": [
[
"/html/webappapis/scripting/events/event-handler-javascript.html",
@@ -361670,9 +361675,15 @@
{}
]
],
- "html/webappapis/scripting/events/event-handler-spec-example.html": [
+ "html/webappapis/scripting/events/event-handler-removal.window.js": [
[
- "/html/webappapis/scripting/events/event-handler-spec-example.html",
+ "/html/webappapis/scripting/events/event-handler-removal.window.html",
+ {}
+ ]
+ ],
+ "html/webappapis/scripting/events/event-handler-spec-example.window.js": [
+ [
+ "/html/webappapis/scripting/events/event-handler-spec-example.window.html",
{}
]
],
@@ -361688,15 +361699,21 @@
{}
]
],
- "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.html": [
+ "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.window.js": [
[
- "/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.html",
+ "/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.window.html",
{}
]
],
- "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.html": [
+ "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.window.js": [
[
- "/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.html",
+ "/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.window.html",
+ {}
+ ]
+ ],
+ "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-keeps-position.window.js": [
+ [
+ "/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-keeps-position.window.html",
{}
]
],
@@ -600647,10 +600664,6 @@
"c14a043b6ab10ab5e9e08d5bae1088f8dbf5e9c3",
"testharness"
],
- "html/webappapis/scripting/events/body-exposed-window-event-handlers.html": [
- "e4f00b866dba9849c8aabb4b1e2ef9b8d1d58e5d",
- "testharness"
- ],
"html/webappapis/scripting/events/body-onload.html": [
"1e43d1ccd476a530738cfdc7846adad807ca1edc",
"testharness"
@@ -600672,11 +600685,15 @@
"testharness"
],
"html/webappapis/scripting/events/event-handler-attributes-body-window.html": [
- "1c87892cba7fa30533c2c28f8c0244dd90ff8548",
+ "4a6bee61bef240cd0947d796f7b3c2c4166b2670",
"testharness"
],
"html/webappapis/scripting/events/event-handler-attributes-window-body.html": [
- "29c4c133b9ef3847146182a5fb24a4e0fd96bbfe",
+ "1ceed5278de7d17c4ef655a2a79e3ecc97339dbf",
+ "testharness"
+ ],
+ "html/webappapis/scripting/events/event-handler-attributes-windowless-body.html": [
+ "9b81d42ff729399d57e182abc8b8950cef503e12",
"testharness"
],
"html/webappapis/scripting/events/event-handler-javascript.html": [
@@ -600751,8 +600768,12 @@
"f5423d7ed448fbceb4d43ef7352b708b48ce2364",
"testharness"
],
- "html/webappapis/scripting/events/event-handler-spec-example.html": [
- "1f3cff426523ea5799d12b90e45f2f50eb6f8181",
+ "html/webappapis/scripting/events/event-handler-removal.window.js": [
+ "d0f75c511dd3d04e1e9334753bb0d030f0eb805e",
+ "testharness"
+ ],
+ "html/webappapis/scripting/events/event-handler-spec-example.window.js": [
+ "7bfbe58bce55aad177adb18f408852d7aed08a96",
"testharness"
],
"html/webappapis/scripting/events/eventhandler-cancellation.html": [
@@ -600763,12 +600784,16 @@
"aae0f1abf8bf3ced9e69e83996f76ef700c11866",
"testharness"
],
- "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.html": [
- "83ee25032c5877ed830e0070d3fff963746e290e",
+ "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.window.js": [
+ "2892a4c3ab98740dc2fa8240b91217ff6dd49e17",
"testharness"
],
- "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.html": [
- "a67f66ead4ffce7b6692f01dbe6449e28f062f08",
+ "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.window.js": [
+ "b39b54b0e9cea49e4628b72ddd84e236cb57e77a",
+ "testharness"
+ ],
+ "html/webappapis/scripting/events/invalid-uncompiled-raw-handler-keeps-position.window.js": [
+ "f9443bf99a0a9dfd937d8d1cf3bd618a3734aa1c",
"testharness"
],
"html/webappapis/scripting/events/messageevent-constructor.https.html": [
@@ -600787,6 +600812,10 @@
"d40c0b9cce8a7b9a369a30679560b0d1ab22aca0",
"support"
],
+ "html/webappapis/scripting/events/resources/event-handler-body.js": [
+ "656903cf99e6e36b491bec30d902466a83b9504f",
+ "support"
+ ],
"html/webappapis/scripting/events/resources/open-window.html": [
"1d23263570e6db17d36e6bf611f4f31d231327b6",
"support"
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/body-exposed-window-event-handlers.html b/testing/web-platform/tests/html/webappapis/scripting/events/body-exposed-window-event-handlers.html
deleted file mode 100644
index e4f00b866dba..000000000000
--- a/testing/web-platform/tests/html/webappapis/scripting/events/body-exposed-window-event-handlers.html
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
-
-
-
-
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-body-window.html b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-body-window.html
index 1c87892cba7f..4a6bee61bef2 100644
--- a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-body-window.html
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-body-window.html
@@ -3,32 +3,49 @@
+
+
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-window-body.html b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-window-body.html
index 29c4c133b9ef..1ceed5278de7 100644
--- a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-window-body.html
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-window-body.html
@@ -3,32 +3,47 @@
+
+
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-windowless-body.html b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-windowless-body.html
new file mode 100644
index 000000000000..9b81d42ff729
--- /dev/null
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-attributes-windowless-body.html
@@ -0,0 +1,71 @@
+
+
+
+
+
+
+
+
+
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-removal.window.js b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-removal.window.js
new file mode 100644
index 000000000000..d0f75c511dd3
--- /dev/null
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-removal.window.js
@@ -0,0 +1,70 @@
+test(() => {
+ var i = 0;
+ var uncalled = "assert_unreached('First event handler.');"
+ var button = document.createElement('button');
+ button.addEventListener('click', () => { assert_equals(++i, 1); }, false);
+ button.setAttribute('onclick', uncalled); // event handler is activated here
+ button.addEventListener('click', () => { assert_equals(++i, 2); }, false);
+ button.onclick = null; // but de-activated here
+ button.addEventListener('click', () => { assert_equals(++i, 3); }, false);
+ button.onclick = () => { assert_equals(++i, 4); }; // and re-activated here
+ button.addEventListener('click', () => { assert_equals(++i, 5); }, false);
+ button.click()
+ assert_equals(button.getAttribute("onclick"), uncalled)
+ assert_equals(i, 5);
+}, "Event handler set through content attribute should be removed when they are set to null.");
+
+let happened = 0;
+test(() => {
+ var script = "happened++;";
+ var button = document.createElement('button');
+ button.setAttribute('onclick', script); // event handler is activated here
+ button.onclick = null; // but de-activated here
+ assert_equals(button.getAttribute("onclick"), script)
+ button.setAttribute('onclick', script); // and re-activated here
+ button.click()
+ assert_equals(happened, 1);
+}, "Event handler set through content attribute should be re-activated even if content is the same.");
+
+test(() => {
+ var i = 0;
+ var uncalled = "assert_unreached('First event handler.');"
+ var button = document.createElement('button');
+ button.addEventListener('click', () => { assert_equals(++i, 1); }, false);
+ button.setAttribute('onclick', uncalled); // event handler is activated here
+ button.addEventListener('click', () => { assert_equals(++i, 2); }, false);
+ button.removeAttribute('onclick'); // but de-activated here
+ button.addEventListener('click', () => { assert_equals(++i, 3); }, false);
+ button.onclick = () => { assert_equals(++i, 4); }; // and re-activated here
+ button.addEventListener('click', () => { assert_equals(++i, 5); }, false);
+ button.click()
+ assert_equals(i, 5);
+}, "Event handler set through content attribute should be deactivated when the content attribute is removed.");
+test(t => {
+ var i = 0;
+ var uncalled = "assert_unreached('First event handler.');"
+ var button = document.createElement('button');
+ button.addEventListener('click', () => { assert_equals(++i, 1); }, false);
+ button.onclick = t.unreached_func('First event handler.'); // event handler is activated here
+ button.addEventListener('click', () => { assert_equals(++i, 2); }, false);
+ button.onclick = null; // but de-activated here
+ button.addEventListener('click', () => { assert_equals(++i, 3); }, false);
+ button.onclick = () => { assert_equals(++i, 4); }; // and re-activated here
+ button.addEventListener('click', () => { assert_equals(++i, 5); }, false);
+ button.click()
+ assert_equals(i, 5);
+}, "Event handler set through IDL should be deactivated when the IDL attribute is set to null.");
+test(t => {
+ var i = 0;
+ var uncalled = "assert_unreached('First event handler.');"
+ var button = document.createElement('button');
+ button.addEventListener('click', () => { assert_equals(++i, 1) }, false);
+ button.onclick = t.unreached_func('First event handler.'); // event handler is activated here
+ button.addEventListener('click', () => { assert_equals(++i, 3) }, false);
+ button.removeAttribute('onclick'); // but de-activated here
+ button.addEventListener('click', () => { assert_equals(++i, 4) }, false);
+ button.onclick = () => { assert_equals(++i, 2); }; // and re-activated here
+ button.addEventListener('click', () => { assert_equals(++i, 5) }, false);
+ button.click()
+ assert_equals(i, 5);
+}, "Event handler set through IDL should NOT be deactivated when the content attribute is removed.");
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-spec-example.html b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-spec-example.html
deleted file mode 100644
index 1f3cff426523..000000000000
--- a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-spec-example.html
+++ /dev/null
@@ -1,67 +0,0 @@
-
-Event handler invocation order
-
-
-
-
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-spec-example.window.js b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-spec-example.window.js
new file mode 100644
index 000000000000..7bfbe58bce55
--- /dev/null
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/event-handler-spec-example.window.js
@@ -0,0 +1,51 @@
+var objects = [{}, function() {}, new Number(42), new String()];
+var primitives = [42, null, undefined, ""];
+objects.forEach(function(object) {
+ test(function() {
+ var i = 0;
+ var uncalled = "assert_unreached('First event handler.');"
+ var button = document.createElement('button');
+ button.onclick = object; // event handler listener is registered here
+ assert_equals(button.onclick, object);
+ button.addEventListener('click', function () { assert_equals(++i, 2) }, false);
+ button.setAttribute('onclick', uncalled);
+ button.addEventListener('click', function () { assert_equals(++i, 3) }, false);
+ button.onclick = function () { assert_equals(++i, 1); };
+ button.addEventListener('click', function () { assert_equals(++i, 4) }, false);
+ button.click()
+ assert_equals(button.getAttribute("onclick"), uncalled)
+ assert_equals(i, 4);
+ }, "Event handler listeners should be registered when they are first set to an object value " +
+ "(" + format_value(object) + ").");
+});
+primitives.forEach(function(primitive) {
+ test(function() {
+ var i = 0;
+ var uncalled = "assert_unreached('First event handler.');"
+ var button = document.createElement('button');
+ button.onclick = primitive;
+ assert_equals(button.onclick, null);
+ button.addEventListener('click', function () { assert_equals(++i, 1) }, false);
+ button.setAttribute('onclick', uncalled); // event handler listener is registered here
+ button.addEventListener('click', function () { assert_equals(++i, 3) }, false);
+ button.onclick = function () { assert_equals(++i, 2); };
+ button.addEventListener('click', function () { assert_equals(++i, 4) }, false);
+ button.click()
+ assert_equals(button.getAttribute("onclick"), uncalled)
+ assert_equals(i, 4);
+ }, "Event handler listeners should be registered when they are first set to an object value " +
+ "(" + format_value(primitive) + ").");
+});
+test(function() {
+ var i = 0;
+ var uncalled = "assert_unreached('First event handler.');"
+ var button = document.createElement('button');
+ button.addEventListener('click', function () { assert_equals(++i, 1) }, false);
+ button.setAttribute('onclick', uncalled); // event handler listener is registered here
+ button.addEventListener('click', function () { assert_equals(++i, 3) }, false);
+ button.onclick = function () { assert_equals(++i, 2); };
+ button.addEventListener('click', function () { assert_equals(++i, 4) }, false);
+ button.click()
+ assert_equals(button.getAttribute("onclick"), uncalled)
+ assert_equals(i, 4);
+}, "Event handler listeners should be registered when they are first set to an object value.");
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.html b/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.window.js
similarity index 64%
rename from testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.html
rename to testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.window.js
index 83ee25032c58..2892a4c3ab98 100644
--- a/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.html
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-late.window.js
@@ -1,10 +1,3 @@
-
-
-Invalid uncompiled raw handlers should only be compiled when about to call them.
-
-
-
-
-
+}, "Invalid uncompiled raw handlers should only be compiled when about to call them");
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.html b/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.window.js
similarity index 52%
rename from testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.html
rename to testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.window.js
index a67f66ead4ff..b39b54b0e9ce 100644
--- a/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.html
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-compiled-once.window.js
@@ -1,10 +1,3 @@
-
-
-Invalid uncompiled raw handlers should only be compiled once.
-
-
-
-
-
+}, "Invalid uncompiled raw handlers should only be compiled once");
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-keeps-position.window.js b/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-keeps-position.window.js
new file mode 100644
index 000000000000..f9443bf99a0a
--- /dev/null
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/invalid-uncompiled-raw-handler-keeps-position.window.js
@@ -0,0 +1,20 @@
+setup({ allow_uncaught_exception: true });
+
+test(function() {
+ var events = [];
+ window.onerror = function() {
+ events.push("error");
+ };
+
+ var div = document.createElement("div");
+ div.addEventListener("click", function (e) { events.push("click 1"); });
+ div.setAttribute("onclick", "}");
+ div.addEventListener("click", function (e) { events.push("click 3"); });
+ assert_equals(div.onclick, null);
+ assert_array_equals(events, ["error"]);
+
+ events = [];
+ div.onclick = function (e) { events.push("click 2"); };
+ div.dispatchEvent(new Event("click"));
+ assert_array_equals(events, ["click 1", "click 2", "click 3"]);
+}, "Compiling invalid uncompiled raw handlers should keep the position in event listener list");
diff --git a/testing/web-platform/tests/html/webappapis/scripting/events/resources/event-handler-body.js b/testing/web-platform/tests/html/webappapis/scripting/events/resources/event-handler-body.js
new file mode 100644
index 000000000000..656903cf99e6
--- /dev/null
+++ b/testing/web-platform/tests/html/webappapis/scripting/events/resources/event-handler-body.js
@@ -0,0 +1,26 @@
+const windowReflectingBodyElementEventHandlerSet =
+ new Set(['blur', 'error', 'focus', 'load', 'resize', 'scroll']);
+
+function handlersInInterface(mainIDL, name) {
+ return mainIDL.find(idl => idl.name === name).members.map(member => member.name.slice(2));
+}
+
+const handlersListPromise = fetch("/interfaces/html.idl").then(res => res.text()).then(htmlIDL => {
+ const parsedHTMLIDL = WebIDL2.parse(htmlIDL);
+ const windowEventHandlers = handlersInInterface(parsedHTMLIDL, "WindowEventHandlers");
+ const globalEventHandlers = handlersInInterface(parsedHTMLIDL, "GlobalEventHandlers");
+ const documentAndElementEventHandlers = handlersInInterface(parsedHTMLIDL, "DocumentAndElementEventHandlers");
+
+ const shadowedHandlers = [
+ ...windowReflectingBodyElementEventHandlerSet,
+ ...windowEventHandlers
+ ];
+ const notShadowedHandlers = [
+ ...globalEventHandlers.filter(name => !windowReflectingBodyElementEventHandlerSet.has(name)),
+ ...documentAndElementEventHandlers
+ ];
+ return {
+ shadowedHandlers,
+ notShadowedHandlers
+ };
+});