Title: [286873] trunk
Revision
286873
Author
[email protected]
Date
2021-12-10 13:28:43 -0800 (Fri, 10 Dec 2021)

Log Message

Extend the scope where the Window's current event is set
https://bugs.webkit.org/show_bug.cgi?id=233833

Reviewed by Ryosuke Niwa.

LayoutTests/imported/w3c:

Import WPT tests from https://github.com/web-platform-tests/wpt/pull/31894.

* web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result-expected.txt: Added.
* web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html: Added.
* web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any-expected.txt: Added.
* web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.html: Added.
* web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.js: Added.
* web-platform-tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html: Added.

Source/WebCore:

Inner invoke algorithm [1] sets window.event from step 8.2 until step 12 (inclusive).
That includes calling a callback interface [2], which performs "handleEvent" lookup
(step 10.1) and coerces return value of "beforeunload" handler (step 14).

Before this patch, window.event was not set during these user-observable operations.
Now WebKit is aligned with Blink and Gecko.

JSErrorHandler is correct: although reportException() may call userland "error" handler,
it will have window.event on its own.

[1] https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
[2] https://webidl.spec.whatwg.org/#call-a-user-objects-operation

Tests: imported/w3c/web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html
       imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.html

* bindings/js/JSEventListener.cpp:
(WebCore::JSEventListener::handleEvent):
ScopeExit is used since the method has so many exit points.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/imported/w3c/ChangeLog (286872 => 286873)


--- trunk/LayoutTests/imported/w3c/ChangeLog	2021-12-10 21:25:01 UTC (rev 286872)
+++ trunk/LayoutTests/imported/w3c/ChangeLog	2021-12-10 21:28:43 UTC (rev 286873)
@@ -1,5 +1,21 @@
 2021-12-10  Alexey Shvayka  <[email protected]>
 
+        Extend the scope where the Window's current event is set
+        https://bugs.webkit.org/show_bug.cgi?id=233833
+
+        Reviewed by Ryosuke Niwa.
+
+        Import WPT tests from https://github.com/web-platform-tests/wpt/pull/31894.
+
+        * web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result-expected.txt: Added.
+        * web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html: Added.
+        * web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any-expected.txt: Added.
+        * web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.html: Added.
+        * web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.js: Added.
+        * web-platform-tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html: Added.
+
+2021-12-10  Alexey Shvayka  <[email protected]>
+
         JSErrorHandler should not set window.event if invocation target is in shadow tree
         https://bugs.webkit.org/show_bug.cgi?id=233834
 

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result-expected.txt (0 => 286873)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result-expected.txt	2021-12-10 21:28:43 UTC (rev 286873)
@@ -0,0 +1,4 @@
+
+
+PASS window.event is still set when 'beforeunload' result is coerced to string
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html (0 => 286873)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html	2021-12-10 21:28:43 UTC (rev 286873)
@@ -0,0 +1,23 @@
+<!doctype html>
+<meta charset="utf-8">
+<title>window.event is still set when 'beforeunload' result is coerced to string</title>
+<link rel="help" href=""
+<link rel="help" href=""
+
+<script src=""
+<script src=""
+
+<iframe id="iframe" src=""
+<body>
+<script>
+window._onload_ = () => {
+  async_test(t => {
+    iframe._onload_ = t.step_func_done(() => {
+      assert_equals(typeof window.currentEventInToString, "object");
+      assert_equals(window.currentEventInToString.type, "beforeunload");
+    });
+
+    iframe.contentWindow.location.href = ""
+  });
+};
+</script>

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any-expected.txt (0 => 286873)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any-expected.txt	2021-12-10 21:28:43 UTC (rev 286873)
@@ -0,0 +1,3 @@
+
+PASS self.event is set before 'handleEvent' lookup
+

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.html (0 => 286873)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.html	2021-12-10 21:28:43 UTC (rev 286873)
@@ -0,0 +1 @@
+<!-- This file is required for WebKit test infrastructure to run the templated test -->
\ No newline at end of file

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.js (0 => 286873)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.js	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.js	2021-12-10 21:28:43 UTC (rev 286873)
@@ -0,0 +1,19 @@
+// https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke (steps 8.2 - 12)
+// https://webidl.spec.whatwg.org/#call-a-user-objects-operation (step 10.1)
+
+test(() => {
+  const eventTarget = new EventTarget;
+
+  let currentEvent;
+  eventTarget.addEventListener("foo", {
+    get handleEvent() {
+      currentEvent = self.event;
+      return () => {};
+    }
+  });
+
+  const event = new Event("foo");
+  eventTarget.dispatchEvent(event);
+
+  assert_equals(currentEvent, event);
+}, "self.event is set before 'handleEvent' lookup");

Added: trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html (0 => 286873)


--- trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html	                        (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/dom/events/resources/event-global-is-still-set-when-coercing-beforeunload-result-frame.html	2021-12-10 21:28:43 UTC (rev 286873)
@@ -0,0 +1,6 @@
+<!doctype html>
+<meta charset="utf-8">
+<body>
+<script>
+window._onbeforeunload_ = () => ({ toString: () => { parent.currentEventInToString = window.event; } });
+</script>

Modified: trunk/Source/WebCore/ChangeLog (286872 => 286873)


--- trunk/Source/WebCore/ChangeLog	2021-12-10 21:25:01 UTC (rev 286872)
+++ trunk/Source/WebCore/ChangeLog	2021-12-10 21:28:43 UTC (rev 286873)
@@ -1,5 +1,32 @@
 2021-12-10  Alexey Shvayka  <[email protected]>
 
+        Extend the scope where the Window's current event is set
+        https://bugs.webkit.org/show_bug.cgi?id=233833
+
+        Reviewed by Ryosuke Niwa.
+
+        Inner invoke algorithm [1] sets window.event from step 8.2 until step 12 (inclusive).
+        That includes calling a callback interface [2], which performs "handleEvent" lookup
+        (step 10.1) and coerces return value of "beforeunload" handler (step 14).
+
+        Before this patch, window.event was not set during these user-observable operations.
+        Now WebKit is aligned with Blink and Gecko.
+
+        JSErrorHandler is correct: although reportException() may call userland "error" handler,
+        it will have window.event on its own.
+
+        [1] https://dom.spec.whatwg.org/#concept-event-listener-inner-invoke
+        [2] https://webidl.spec.whatwg.org/#call-a-user-objects-operation
+
+        Tests: imported/w3c/web-platform-tests/dom/events/event-global-is-still-set-when-coercing-beforeunload-result.html
+               imported/w3c/web-platform-tests/dom/events/event-global-set-before-handleEvent-lookup.any.html
+
+        * bindings/js/JSEventListener.cpp:
+        (WebCore::JSEventListener::handleEvent):
+        ScopeExit is used since the method has so many exit points.
+
+2021-12-10  Alexey Shvayka  <[email protected]>
+
         JSErrorHandler should not set window.event if invocation target is in shadow tree
         https://bugs.webkit.org/show_bug.cgi?id=233834
 

Modified: trunk/Source/WebCore/bindings/js/JSEventListener.cpp (286872 => 286873)


--- trunk/Source/WebCore/bindings/js/JSEventListener.cpp	2021-12-10 21:25:01 UTC (rev 286872)
+++ trunk/Source/WebCore/bindings/js/JSEventListener.cpp	2021-12-10 21:28:43 UTC (rev 286873)
@@ -41,6 +41,7 @@
 #include <_javascript_Core/VMEntryScope.h>
 #include <_javascript_Core/Watchdog.h>
 #include <wtf/Ref.h>
+#include <wtf/Scope.h>
 
 namespace WebCore {
 using namespace JSC;
@@ -137,6 +138,21 @@
             return;
     }
 
+    RefPtr<Event> savedEvent;
+    auto* jsFunctionWindow = jsDynamicCast<JSDOMWindow*>(vm, jsFunction->globalObject(vm));
+    if (jsFunctionWindow) {
+        savedEvent = jsFunctionWindow->currentEvent();
+
+        // window.event should not be set when the target is inside a shadow tree, as per the DOM specification.
+        if (!event.currentTargetIsInShadowTree())
+            jsFunctionWindow->setCurrentEvent(&event);
+    }
+
+    auto restoreCurrentEventOnExit = makeScopeExit([&] {
+        if (jsFunctionWindow)
+            jsFunctionWindow->setCurrentEvent(savedEvent.get());
+    });
+
     JSGlobalObject* lexicalGlobalObject = jsFunction->globalObject();
 
     JSValue handleEventFunction = jsFunction;
@@ -170,16 +186,6 @@
     args.append(toJS(lexicalGlobalObject, globalObject, &event));
     ASSERT(!args.hasOverflowed());
 
-    RefPtr<Event> savedEvent;
-    auto* jsFunctionWindow = jsDynamicCast<JSDOMWindow*>(vm, jsFunction->globalObject());
-    if (jsFunctionWindow) {
-        savedEvent = jsFunctionWindow->currentEvent();
-
-        // window.event should not be set when the target is inside a shadow tree, as per the DOM specification.
-        if (!event.currentTargetIsInShadowTree())
-            jsFunctionWindow->setCurrentEvent(&event);
-    }
-
     VMEntryScope entryScope(vm, vm.entryScope ? vm.entryScope->globalObject() : lexicalGlobalObject);
 
     JSExecState::instrumentFunction(&scriptExecutionContext, callData);
@@ -190,9 +196,6 @@
 
     InspectorInstrumentation::didCallFunction(&scriptExecutionContext);
 
-    if (jsFunctionWindow)
-        jsFunctionWindow->setCurrentEvent(savedEvent.get());
-
     auto handleExceptionIfNeeded = [&] (JSC::Exception* exception) -> bool {
         if (is<WorkerGlobalScope>(scriptExecutionContext)) {
             auto* scriptController = downcast<WorkerGlobalScope>(scriptExecutionContext).script();
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to