Diff
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (285502 => 285503)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-11-09 17:49:37 UTC (rev 285503)
@@ -1,3 +1,31 @@
+2021-11-09 Chris Dumez <cdu...@apple.com>
+
+ Ignore BroadcastChannel::postMessage from detached iframe / closing worker contexts
+ https://bugs.webkit.org/show_bug.cgi?id=232693
+
+ Reviewed by Darin Adler.
+
+ Resync BroadcastChannel WPT tests from upstream to gain test coverage.
+
+ * web-platform-tests/webmessaging/broadcastchannel/basics.any.serviceworker.html: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/cross-origin-expected.txt: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/cross-origin.html: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/detached-iframe-expected.txt: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/detached-iframe.html: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/ordering-expected.txt: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/ordering.html: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/resources/cross-origin.html: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/resources/ordering.html: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/resources/service-worker.js: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/resources/w3c-import.log:
+ * web-platform-tests/webmessaging/broadcastchannel/resources/worker.js:
+ (handler):
+ * web-platform-tests/webmessaging/broadcastchannel/service-worker.https-expected.txt: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/service-worker.https.html: Added.
+ * web-platform-tests/webmessaging/broadcastchannel/w3c-import.log:
+ * web-platform-tests/webmessaging/broadcastchannel/workers-expected.txt:
+ * web-platform-tests/webmessaging/broadcastchannel/workers.html:
+
2021-11-09 Commit Queue <commit-qu...@webkit.org>
Unreviewed, reverting r285488.
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin-expected.txt (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin-expected.txt 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,4 @@
+
+
+PASS Messages aren't delivered across origins
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin.html (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin.html 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,38 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<script src=""
+<script src=""
+<script src=""
+<!-- Pull in the with_iframe helper function from the service worker tests -->
+<script src=""
+<body>
+<script>
+
+const events = [];
+
+function testCompletion(t) {
+ return new Promise((resolve) => {
+ window.addEventListener("message", t.step_func(e => {
+ if (e.data == 'done') {
+ assert_equals(events.length, 0);
+ resolve();
+ }
+ }));
+ });
+}
+
+promise_test(async t => {
+
+ const bc0 = new BroadcastChannel('no-cross-origin-messages');
+ bc0._onmessage_ = e => {window.events.push(e);};
+
+ const testResults = testCompletion(t);
+ const url = "" +
+ '/webmessaging/broadcastchannel/resources/cross-origin.html';
+ await with_iframe(url);
+
+ return testResults;
+}, "Messages aren't delivered across origins");
+
+</script>
+</body>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe-expected.txt (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe-expected.txt 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,8 @@
+
+PASS BroadcastChannel messages from detached iframe to parent should be ignored (BC created before detaching)
+PASS BroadcastChannel messages from detached iframe to parent should be ignored (BC created after detaching)
+PASS BroadcastChannel messages from parent to detached iframe should be ignored (BC created before detaching)
+PASS BroadcastChannel messages from parent to detached iframe should be ignored (BC created after detaching)
+PASS BroadcastChannel messages within detached iframe should be ignored (BCs created before detaching)
+PASS BroadcastChannel messages within detached iframe should be ignored (BCs created after detaching)
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe.html (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe.html 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,174 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<script src=""
+<script src=""
+<script src=""
+<!-- Pull in the with_iframe helper function from the service worker tests -->
+<script src=""
+<body>
+<script>
+const TEST_IFRAME_CLASS_NAME = 'test-iframe';
+const events = [];
+var bc1;
+const DONE_MSG = 'done';
+
+function DetachedIframeTestCheckForOneMessage(t) {
+ return new Promise((resolve) => {
+ bc1._onmessage_ = t.step_func(e => {
+ events.push(e);
+ if (e.data == DONE_MSG) {
+ assert_equals(events.length, 1);
+ resolve();
+ }
+ });
+ });
+}
+
+const IframeAction = {
+ REMOVE_BEFORE_CREATION: 'remove-before-creation',
+ REMOVE_AFTER_CREATION: 'remove-after-creation',
+};
+
+async function doMessageSentTest(t, channelName, action) {
+ await with_iframe('about:blank');
+ const iframe = document.getElementsByClassName(TEST_IFRAME_CLASS_NAME)[0];
+ const iframe_BroadcastChannel = iframe.contentWindow.BroadcastChannel;
+
+ if (action ="" IframeAction.REMOVE_BEFORE_CREATION) {
+ iframe.remove();
+ }
+
+ events.length = 0;
+
+ bc1 = new BroadcastChannel(channelName);
+ const bc2 = new BroadcastChannel(channelName);
+ const iframe_bc = new iframe_BroadcastChannel(channelName);
+
+ if (action ="" IframeAction.REMOVE_AFTER_CREATION) {
+ iframe.remove();
+ }
+
+ const testResultsPromise = DetachedIframeTestCheckForOneMessage(t);
+
+ iframe_bc.postMessage('test');
+ bc2.postMessage(DONE_MSG);
+
+ bc2.close();
+ iframe_bc.close();
+ t.add_cleanup(() => bc1.close());
+
+ return testResultsPromise;
+}
+
+promise_test(async t => {
+ return doMessageSentTest(
+ t, 'postMessage-from-detached-iframe-pre',
+ IframeAction.REMOVE_AFTER_CREATION);
+}, 'BroadcastChannel messages from detached iframe to parent should be ignored (BC created before detaching)');
+
+promise_test(async t => {
+ return doMessageSentTest(
+ t, 'postMessage-from-detached-iframe-post',
+ IframeAction.REMOVE_BEFORE_CREATION);
+}, 'BroadcastChannel messages from detached iframe to parent should be ignored (BC created after detaching)');
+
+
+async function doMessageReceivedTest(t, channelName, action) {
+ await with_iframe('about:blank');
+ const iframe = document.getElementsByClassName(TEST_IFRAME_CLASS_NAME)[0];
+ const iframe_BroadcastChannel = iframe.contentWindow.BroadcastChannel;
+
+ if (action ="" IframeAction.REMOVE_BEFORE_CREATION) {
+ iframe.remove();
+ }
+
+ events.length = 0;
+
+ // `iframe_bc` must be created first so that it receives messages before
+ // `bc1`. That way we can tell whether `iframe_bc` received a message by
+ // inspecting `events` in the `bc1` message handler.
+ const iframe_bc = new iframe_BroadcastChannel(channelName);
+ iframe_bc._onmessage_ = e => {
+ events.push(e)
+ };
+ bc1 = new BroadcastChannel(channelName);
+ const bc2 = new BroadcastChannel(channelName);
+
+ if (action ="" IframeAction.REMOVE_AFTER_CREATION) {
+ iframe.remove();
+ }
+
+ const testResultsPromise = DetachedIframeTestCheckForOneMessage(t);
+ bc2.postMessage(DONE_MSG);
+
+ bc2.close();
+ iframe_bc.close();
+ t.add_cleanup(() => bc1.close());
+}
+
+promise_test(async t => {
+ return doMessageReceivedTest(
+ t, 'postMessage-to-detached-iframe-pre',
+ IframeAction.REMOVE_AFTER_CREATION);
+}, 'BroadcastChannel messages from parent to detached iframe should be ignored (BC created before detaching)');
+
+promise_test(async t => {
+ return doMessageReceivedTest(
+ t, 'postMessage-to-detached-iframe-post',
+ IframeAction.REMOVE_BEFORE_CREATION);
+}, 'BroadcastChannel messages from parent to detached iframe should be ignored (BC created after detaching)');
+
+
+async function doMessageSendReceiveTest(t, channelName, action) {
+ await with_iframe('about:blank');
+ const iframe = document.getElementsByClassName(TEST_IFRAME_CLASS_NAME)[0];
+ const iframe_BroadcastChannel = iframe.contentWindow.BroadcastChannel;
+
+ if (action ="" IframeAction.REMOVE_BEFORE_CREATION) {
+ iframe.remove();
+ }
+
+ const iframe_bc1 = new iframe_BroadcastChannel(channelName);
+ const iframe_bc2 = new iframe_BroadcastChannel(channelName);
+ iframe_bc1._onmessage_ = t.unreached_func(
+ 'Detached iframe BroadcastChannel instance received message unexpectedly');
+
+ if (action ="" IframeAction.REMOVE_AFTER_CREATION) {
+ iframe.remove();
+ }
+
+ iframe_bc2.postMessage(DONE_MSG);
+
+ iframe_bc2.close();
+ t.add_cleanup(() => iframe_bc1.close());
+
+ // To avoid calling t.step_timeout here, instead just create two new
+ // BroadcastChannel instances and complete the test when a message is passed
+ // between them. Per the spec, all "BroadcastChannel objects whose relevant
+ // agents are the same" must have messages delivered to them in creation
+ // order, so if we get this message then it's safe to assume the earlier
+ // message would have been delivered if it was going to be.
+ const bc1 = new BroadcastChannel(channelName);
+ const bc2 = new BroadcastChannel(channelName);
+ return new Promise((resolve) => {
+ bc1._onmessage_ = t.step_func(e => {
+ resolve();
+ });
+ bc2.postMessage(DONE_MSG);
+ });
+}
+
+promise_test(async t => {
+ return doMessageSendReceiveTest(
+ t, 'postMessage-within-detached-iframe-pre',
+ IframeAction.REMOVE_AFTER_CREATION);
+}, 'BroadcastChannel messages within detached iframe should be ignored (BCs created before detaching)');
+
+promise_test(async t => {
+ return doMessageSendReceiveTest(
+ t, 'postMessage-within-detached-iframe-post',
+ IframeAction.REMOVE_BEFORE_CREATION);
+}, 'BroadcastChannel messages within detached iframe should be ignored (BCs created after detaching)');
+
+</script>
+</body>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering-expected.txt (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering-expected.txt 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,4 @@
+
+
+PASS Messages are delivered in port creation order across multiple frames
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering.html (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering.html 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<script src=""
+<script src=""
+<!-- Pull in the with_iframe helper function from the service worker tests -->
+<script src=""
+<body>
+<script>
+
+const BC0_FIRST_MSG = 'from BC0 - first';
+const BC1_FIRST_MSG = 'from BC1 - first';
+const BC2_FIRST_MSG = 'from BC2 - first';
+const BC3_FIRST_MSG = 'from BC3 - first';
+const BC0_SECOND_MSG = 'from BC0 - second';
+const BC1_SECOND_MSG = 'from BC1 - second';
+const BC2_SECOND_MSG = 'from BC2 - second';
+const BC3_SECOND_MSG = 'done';
+const BC0_TARGET_NAME = 'BC1';
+const BC1_TARGET_NAME = 'BC1';
+const BC2_TARGET_NAME = 'BC2';
+const BC3_TARGET_NAME = 'BC3';
+const MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME = 'multi-frame-order';
+
+const bc0 = new BroadcastChannel(MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME);
+const messages = [];
+
+function logReceivedMessage(targetname, e) {
+ messages.push({'target': targetname, 'data': e.data});
+}
+
+function postMessagesToChannel() {
+ return new Promise((resolve) => {
+ bc0.postMessage(BC0_FIRST_MSG);
+ bc0.postMessage(BC0_SECOND_MSG);
+ resolve();
+ });
+}
+
+// Expected flow of messages between the BroadcastChannel objects (based on
+// the requirement that messages get delivered to BroadcastChannel objects
+// "in creation order, oldest first") and comments describing the actions
+// taken in response to each event
+const EXPECTED_RESULTS = [
+ // -> BC0 sends two messages, BC1 and BC2 are connected to the channel
+
+ {'data': BC0_FIRST_MSG, 'target': BC1_TARGET_NAME},
+ // -> BC1 Creates BC3 and sends first message
+
+ {'data': BC0_FIRST_MSG, 'target': BC2_TARGET_NAME},
+ // -> BC2 sends two messages
+
+ // BC3 isn't expected to receive the messages sent before it was created, so
+ // no corresponding entries here for messages from BC0.
+
+ {'data': BC0_SECOND_MSG, 'target': BC1_TARGET_NAME},
+ // -> BC1 sends second message
+
+ {'data': BC0_SECOND_MSG, 'target': BC2_TARGET_NAME},
+ // -> BC2 closes
+
+ {'data': BC1_FIRST_MSG, 'target': BC0_TARGET_NAME},
+
+ {'data': BC1_FIRST_MSG, 'target': BC3_TARGET_NAME},
+ // -> BC3 sends first message
+
+ {'data': BC2_FIRST_MSG, 'target': BC0_TARGET_NAME},
+
+ {'data': BC2_FIRST_MSG, 'target': BC1_TARGET_NAME},
+ // -> BC1 closes
+
+ {'data': BC2_FIRST_MSG, 'target': BC3_TARGET_NAME},
+ // -> BC3 sends second message
+
+ {'data': BC2_SECOND_MSG, 'target': BC0_TARGET_NAME},
+
+ {'data': BC2_SECOND_MSG, 'target': BC3_TARGET_NAME},
+ // -> BC3 closes
+
+ {'data': BC1_SECOND_MSG, 'target': BC0_TARGET_NAME},
+
+ {'data': BC3_FIRST_MSG, 'target': BC0_TARGET_NAME},
+
+ {'data': BC3_SECOND_MSG, 'target': BC0_TARGET_NAME},
+];
+
+function testCompletion(t) {
+ return new Promise((resolve) => {
+ bc0._onmessage_ = t.step_func(e => {
+ logReceivedMessage(BC0_TARGET_NAME, e);
+ if (e.data == BC3_SECOND_MSG) {
+ assert_equals(messages.length, EXPECTED_RESULTS.length);
+ for(var i = 0; i < messages.length; i++) {
+ assert_equals(messages[i].target, EXPECTED_RESULTS[i].target, `Message ${i+1} has unexpected target`);
+ assert_equals(messages[i].data, EXPECTED_RESULTS[i].data, `Message ${i+1} has unexpected message contents`);
+ }
+ resolve();
+ }
+ });
+ });
+}
+
+promise_test(async t => {
+
+ const testResults = testCompletion(t);
+ // Await them sequentially because we need the BroadcastChannel object in
+ // iframe1 to be created first, we need the BroadcastChannel object in
+ // iframe2 to be created second, and then we only want to call
+ // postMessagesToChannel once both BroadcastChannels have been created.
+ await with_iframe('resources/ordering.html?id=iframe1');
+ await with_iframe('resources/ordering.html?id=iframe2');
+ await postMessagesToChannel();
+ return testResults;
+}, "Messages are delivered in port creation order across multiple frames");
+
+</script>
+</body>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/cross-origin.html (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/cross-origin.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/cross-origin.html 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,15 @@
+<body></body>
+<script>
+ window._onload_ = function() {
+ bc1 = new BroadcastChannel('no-cross-origin-messages');
+ bc2 = new BroadcastChannel('no-cross-origin-messages');
+ bc2._onmessage_ = e => {
+ parent.postMessage('done', "*");
+ };
+ // Post a message on bc1 and once we receive it in bc2, we know that the
+ // message should have been sent to bc0 if messages were being passed
+ // across origin (assuming compliance with the spec regarding message
+ // delivery in port creation order).
+ bc1.postMessage('ignition');
+ }
+</script>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/ordering.html (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/ordering.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/ordering.html 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,78 @@
+<body></body>
+<script>
+ const BC0_FIRST_MSG = 'from BC0 - first';
+ const BC1_FIRST_MSG = 'from BC1 - first';
+ const BC2_FIRST_MSG = 'from BC2 - first';
+ const BC3_FIRST_MSG = 'from BC3 - first';
+ const BC0_SECOND_MSG = 'from BC0 - second';
+ const BC1_SECOND_MSG = 'from BC1 - second';
+ const BC2_SECOND_MSG = 'from BC2 - second';
+ const BC3_SECOND_MSG = 'done';
+ const BC0_TARGET_NAME = 'BC1';
+ const BC1_TARGET_NAME = 'BC1';
+ const BC2_TARGET_NAME = 'BC2';
+ const BC3_TARGET_NAME = 'BC3';
+ const MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME = 'multi-frame-order';
+
+ var bc1, bc2, bc3;
+ var sentMessageCountForBc1 = 0;
+ var sentMessageCountForBc2 = 0;
+ var sentMessageCountForBc3 = 0;
+
+ var bc1_handler = e => {
+ window.top.logReceivedMessage(BC1_TARGET_NAME, e);
+ switch(sentMessageCountForBc1) {
+ case 0:
+ bc3 = new BroadcastChannel(MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME);
+ bc3._onmessage_ = bc3_handler;
+ bc1.postMessage(BC1_FIRST_MSG);
+ break;
+ case 1:
+ bc1.postMessage(BC1_SECOND_MSG);
+ break;
+ case 2:
+ bc1.close();
+ return;
+ }
+ sentMessageCountForBc1 += 1;
+ }
+ var bc2_handler = e => {
+ window.top.logReceivedMessage(BC2_TARGET_NAME, e);
+ switch(sentMessageCountForBc2) {
+ case 0:
+ bc2.postMessage(BC2_FIRST_MSG);
+ bc2.postMessage(BC2_SECOND_MSG);
+ sentMessageCountForBc2 += 2;
+ break;
+ case 2:
+ bc2.close();
+ return;
+ }
+ };
+ var bc3_handler = e => {
+ window.top.logReceivedMessage(BC3_TARGET_NAME, e);
+ switch(sentMessageCountForBc3) {
+ case 0:
+ bc3.postMessage(BC3_FIRST_MSG);
+ break;
+ case 1:
+ bc3.postMessage(BC3_SECOND_MSG);
+ break;
+ case 2:
+ bc3.close();
+ return;
+ }
+ sentMessageCountForBc3 += 1;
+ };
+
+ window._onload_ = function() {
+ const params = new URLSearchParams(window.location.search);
+ if (params.get('id') === 'iframe1') {
+ bc1 = new BroadcastChannel(MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME);
+ bc1._onmessage_ = bc1_handler;
+ } else if (params.get('id') === 'iframe2') {
+ bc2 = new BroadcastChannel(MULTI_FRAME_ORDERING_TEST_CHANNEL_NAME);
+ bc2._onmessage_ = bc2_handler;
+ }
+ }
+</script>
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/service-worker.js (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/service-worker.js (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/service-worker.js 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,15 @@
+let promise_func = null;
+let promise = new Promise(resolve => promise_func = resolve);
+
+const SERVICE_WORKER_TEST_CHANNEL_NAME = 'service worker';
+const bc3 = new BroadcastChannel(SERVICE_WORKER_TEST_CHANNEL_NAME);
+bc3._onmessage_ = e => {
+ bc3.postMessage('done');
+ promise_func();
+};
+bc3.postMessage('from worker');
+
+// Ensure that the worker stays alive for the duration of the test
+self.addEventListener('install', evt => {
+ evt.waitUntil(promise);
+});
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/w3c-import.log (285502 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/w3c-import.log 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/w3c-import.log 2021-11-09 17:49:37 UTC (rev 285503)
@@ -14,6 +14,9 @@
None
------------------------------------------------------------------------
List of files:
+/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/cross-origin.html
+/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/ordering.html
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/origin.html
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/sandboxed.html
+/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/service-worker.js
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/worker.js
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/worker.js (285502 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/worker.js 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/resources/worker.js 2021-11-09 17:49:37 UTC (rev 285503)
@@ -16,6 +16,12 @@
c = new BroadcastChannel(e.data.channel);
let messages = [];
c._onmessage_ = e => {
+ if (e.data ="" 'ready') {
+ // Ignore any 'ready' messages from the other thread since there could
+ // be some race conditions between this BroadcastChannel instance
+ // being created / ready to receive messages and the message being sent.
+ return;
+ }
messages.push(e.data);
if (e.data == 'done')
reply(messages);
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https-expected.txt (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https-expected.txt (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https-expected.txt 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,3 @@
+
+FAIL BroadcastChannel works in service workers promise_test: Unhandled rejection with value: object "TypeError: ReferenceError: Can't find variable: BroadcastChannel"
+
Added: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https.html (0 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https.html (rev 0)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https.html 2021-11-09 17:49:37 UTC (rev 285503)
@@ -0,0 +1,47 @@
+<!DOCTYPE html>
+<meta charset=utf-8>
+<script src=""
+<script src=""
+<script>
+
+const SERVICE_WORKER_TEST_CHANNEL_NAME = 'service worker';
+const events = [];
+const c1 = new BroadcastChannel(SERVICE_WORKER_TEST_CHANNEL_NAME);
+const c2 = new BroadcastChannel(SERVICE_WORKER_TEST_CHANNEL_NAME);
+c1._onmessage_ = e => events.push(e);
+c2._onmessage_ = e => events.push(e);
+
+function testCompletion(t) {
+ return new Promise((resolve) => {
+ c2.addEventListener("message", t.step_func(e => {
+ if (e.data == 'from worker') {
+ c2.postMessage('from c2');
+ } else if (e.data == 'done') {
+ assert_equals(events.length, 5);
+ assert_equals(events[0].data, 'from worker');
+ assert_equals(events[0].target, c1);
+ assert_equals(events[1].data, 'from worker');
+ assert_equals(events[1].target, c2);
+ assert_equals(events[2].data, 'from c2');
+ assert_equals(events[3].data, 'done');
+ assert_equals(events[3].target, c1);
+ assert_equals(events[4].data, 'done');
+ assert_equals(events[4].target, c2);
+ resolve();
+ }
+ }));
+ });
+}
+
+promise_test(async t => {
+
+ const testResults = testCompletion(t);
+ const SCRIPT = "resources/service-worker.js";
+ const SCOPE = "/webmessaging/broadcastchannel/resources/not-used/";
+
+ const reg = await navigator.serviceWorker.register(SCRIPT, {'scope': SCOPE});
+ t.add_cleanup(() => reg.unregister());
+
+ return testResults;
+ }, 'BroadcastChannel works in service workers');
+</script>
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/w3c-import.log (285502 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/w3c-import.log 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/w3c-import.log 2021-11-09 17:49:37 UTC (rev 285503)
@@ -16,7 +16,11 @@
List of files:
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/basics.any.js
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/blobs.html
+/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin.html
+/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe.html
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/interface.any.js
+/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering.html
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/origin.window.js
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/sandbox.html
+/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https.html
/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/workers.html
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/workers-expected.txt (285502 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/workers-expected.txt 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/workers-expected.txt 2021-11-09 17:49:37 UTC (rev 285503)
@@ -3,5 +3,10 @@
FAIL BroadcastChannel works in shared workers null is not an object (evaluating 'worker.port')
PASS Closing and re-opening a channel works.
PASS BroadcastChannel created after a worker self.close()
-PASS BroadcastChannel used after a worker self.close()
+PASS BroadcastChannel messages from closed worker to parent should be ignored (BC created before closing)
+PASS BroadcastChannel messages from closed worker to parent should be ignored (BC created after closing)
+PASS BroadcastChannel messages from parent to closed worker should be ignored (BC created before closing)
+PASS BroadcastChannel messages from parent to closed worker should be ignored (BC created after closing)
+PASS BroadcastChannel messages within closed worker should be ignored (BCs created before closing)
+PASS BroadcastChannel messages within closed worker should be ignored (BCs created after closing)
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/workers.html (285502 => 285503)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/workers.html 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/webmessaging/broadcastchannel/workers.html 2021-11-09 17:49:37 UTC (rev 285503)
@@ -80,11 +80,14 @@
let worker = new Worker('resources/worker.js');
worker._onmessage_ = t.step_func(e => {
- assert_array_equals(events, ['c1: from worker', 'c2: echo'],
+ assert_array_equals(events,
+ ['c1: from worker', 'c2: ready', 'c2: echo'],
'messages in document');
assert_array_equals(e.data, ['done'], 'messages in worker');
t.done();
});
+ worker._onmessagerror_ =
+ t.unreached_func('Worker\'s onmessageerror handler called');
c.addEventListener('message', e => {
if (e.data == 'from worker') {
@@ -94,14 +97,29 @@
let c2 = new BroadcastChannel('worker-close');
c2._onmessage_ = e => {
events.push('c2: ' + e.data);
- c2.postMessage('done');
+ if (e.data ="" 'ready') {
+ worker.postMessage({ping: 'echo'});
+ } else {
+ c2.postMessage('done');
+ c2.close();
+ }
};
- worker.postMessage({ping: 'echo'});
+ // For some implementations there may be a race condition between
+ // when the BroadcastChannel instance above is created / ready to
+ // receive messages and when the worker calls postMessage on it's
+ // BroadcastChannel instance. To avoid this, confirm that our
+ // instance can receive a message before indicating to the other
+ // thread that we are ready. For more details, see:
+ // https://github.com/whatwg/html/issues/7267
+ let c3 = new BroadcastChannel('worker-close');
+ c3.postMessage('ready');
+ c3.close();
}, 1);
}
});
worker.postMessage({channel: 'worker-close'});
+ t.add_cleanup(() => worker.terminate());
}, 'Closing and re-opening a channel works.');
@@ -108,34 +126,250 @@
async_test(t => {
function workerCode() {
close();
- var bc = new BroadcastChannel('worker-test');
+ try {
+ var bc = new BroadcastChannel('worker-create-after-close');
+ } catch (e) {
+ postMessage(e);
+ return;
+ }
postMessage(true);
}
- var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/_javascript_"});
+ var workerBlob = new Blob(
+ [workerCode.toString() + ';workerCode();'],
+ {type: 'application/_javascript_'});
var w = new Worker(URL.createObjectURL(workerBlob));
- w._onmessage_ = function(e) {
- assert_true(e.data, "BroadcastChannel created on worker shutdown.");
- t.done();
- }
+ w._onmessage_ = t.step_func_done(function(e) {
+ assert_equals(
+ e.data, true,
+ 'BroadcastChannel creation in closed worker triggered exception: ' +
+ e.data.message);
+ });
+ t.add_cleanup(() => w.terminate());
}, 'BroadcastChannel created after a worker self.close()');
-async_test(t => {
- function workerCode() {
+
+function postMessageFromWorkerWorkerCode(workerName, channelName) {
+ if (workerName === 'close-before-create-worker') {
close();
- var bc = new BroadcastChannel('worker-test-after-close');
- bc.postMessage(true);
}
+ let bc = new BroadcastChannel(channelName);
+ if (workerName === 'close-after-create-worker') {
+ close();
+ }
+ bc.postMessage(workerName + ' done');
+ postMessage(true);
+}
- var bc = new BroadcastChannel('worker-test-after-close');
- bc._onmessage_ = function(e) {
- assert_true(e.data, "BroadcastChannel created on worker shutdown.");
- t.done();
+function doPostMessageFromWorkerTest(t, workerName, channelName) {
+ var bc = new BroadcastChannel(channelName);
+ bc._onmessage_ = t.step_func_done(function(e) {
+ assert_equals(
+ e.data, 'done-worker done',
+ 'BroadcastChannel message should only be received from the second worker');
+ });
+ t.add_cleanup(() => bc.close());
+
+ var testMessageHandler = t.step_func(function(e) {
+ assert_equals(
+ e.data, true,
+ 'Worker sent postMessage indicating it sent a BroadcastChannel message');
+
+ var w = createWorker(
+ postMessageFromWorkerWorkerCode, 'done-worker', channelName);
+ t.add_cleanup(() => w.terminate());
+ });
+ createWorker(
+ postMessageFromWorkerWorkerCode, workerName, channelName,
+ testMessageHandler);
+
+ // To avoid calling t.step_timeout here, have the worker postMessage(true)
+ // once it is finished and then we'll instantiate another worker that
+ // performs the same test steps but doesn't close. By the time the
+ // BroadcastChannel message in that worker gets sent successfully it should
+ // be safe to assume that any BroadcastChannel messages from the previous
+ // worker would have been sent if they were going to be.
+}
+
+function createWorker(workerCode, workerName, channelName, handler = null) {
+ var workerCodeStr = workerCode.toString() +
+ `;${workerCode.name}("${workerName}", "${channelName}");`;
+ var workerBlob = new Blob([workerCodeStr], {type: 'application/_javascript_'});
+ var w = new Worker(URL.createObjectURL(workerBlob));
+ if (handler !== null) {
+ w._onmessage_ = handler;
}
+ return w;
+}
- var workerBlob = new Blob([workerCode.toString() + ";workerCode();"], {type:"application/_javascript_"});
- new Worker(URL.createObjectURL(workerBlob));
-}, 'BroadcastChannel used after a worker self.close()');
+async_test(t => {
+ const workerName = 'close-after-create-worker';
+ const channelName = workerName + '-postmessage-from-worker';
+ doPostMessageFromWorkerTest(t, workerName, channelName);
+}, 'BroadcastChannel messages from closed worker to parent should be ignored (BC created before closing)');
+async_test(t => {
+ const workerName = 'close-before-create-worker';
+ const channelName = workerName + '-postmessage-from-worker';
+ doPostMessageFromWorkerTest(t, workerName, channelName);
+}, 'BroadcastChannel messages from closed worker to parent should be ignored (BC created after closing)');
+
+
+function postMessageToWorkerWorkerCode(workerName, channelName) {
+ self.addEventListener('message', () => {
+ if (workerName === 'close-before-create-worker') {
+ close();
+ }
+ try {
+ let bc1 = new BroadcastChannel(channelName);
+ bc1._onmessage_ = e => {
+ if (e.data ="" 'ready') {
+ postMessage(e.data);
+ } else if (e.data ="" 'test') {
+ postMessage(workerName + ' done');
+ }
+ };
+ bc1._onmessageerror_ = () => {
+ postMessage('onmessageerror called from worker BroadcastChannel');
+ };
+ if (workerName === 'close-after-create-worker') {
+ close();
+ }
+ } catch (e) {
+ postMessage(e);
+ return;
+ }
+
+ if (workerName === 'done-worker') {
+ // For some implementations there may be a race condition between when
+ // the BroadcastChannel instance above is created / ready to receive
+ // messages and when the parent calls postMessage on it's
+ // BroadcastChannel instance. To avoid this, confirm that our instance
+ // can receive a message before indicating to the other thread that we
+ // are ready. For more details, see:
+ // https://github.com/whatwg/html/issues/7267
+ let bc2 = new BroadcastChannel(channelName);
+ bc2.postMessage('ready');
+ bc2.close();
+ } else {
+ // Since the worker has closed, it's not expected that the
+ // BroadcastChannel will receive messages (there's a separate test for
+ // that), so just indicate directly that it's ready to test receiving
+ // a message from the parent dispite the possibility of a race condition.
+ postMessage('ready');
+ }
+ });
+ self.addEventListener('messageerror', () => {
+ postMessage('onmessageerror called from worker');
+ });
+}
+
+function doPostMessageToWorkerTest(t, workerName, channelName) {
+ var bc = new BroadcastChannel(channelName);
+ t.add_cleanup(() => bc.close());
+
+ var doneMessageHandler = t.step_func(function(e) {
+ if (e.data ="" 'ready') {
+ bc.postMessage('test');
+ } else if (e.data ="" 'done-worker done') {
+ t.done();
+ } else {
+ assert_unreached(
+ 'BroadcastChannel.postMessage triggered exception within second worker: ' +
+ e.data.message);
+ }
+ });
+ var testMessageHandler = t.step_func(function(e) {
+ assert_equals(
+ e.data, 'ready',
+ 'Worker sent postMessage indicating its BroadcastChannel instance is ready');
+ bc.postMessage('test');
+
+ var doneWorker = createWorker(
+ postMessageToWorkerWorkerCode, 'done-worker', channelName,
+ doneMessageHandler);
+ t.add_cleanup(() => {
+ doneWorker.terminate();
+ });
+ doneWorker.postMessage('start');
+ });
+ var testWorker = createWorker(
+ postMessageToWorkerWorkerCode, workerName, channelName,
+ testMessageHandler);
+ testWorker.postMessage('start');
+}
+
+async_test(t => {
+ const workerName = 'close-after-create-worker';
+ const channelName = workerName + '-postmessage-to-worker';
+ doPostMessageToWorkerTest(t, workerName, channelName);
+}, 'BroadcastChannel messages from parent to closed worker should be ignored (BC created before closing)');
+
+async_test(t => {
+ const workerName = 'close-before-create-worker';
+ const channelName = workerName + '-postmessage-to-worker';
+ doPostMessageToWorkerTest(t, workerName, channelName);
+}, 'BroadcastChannel messages from parent to closed worker should be ignored (BC created after closing)');
+
+
+function postMessageWithinWorkerWorkerCode(workerName, channelName) {
+ if (workerName === 'close-before-create-worker') {
+ close();
+ }
+ try {
+ let bc1 = new BroadcastChannel(channelName);
+ let bc2 = new BroadcastChannel(channelName);
+ bc1._onmessage_ = e => {
+ postMessage(workerName + ' done')
+ };
+ if (workerName === 'close-after-create-worker') {
+ close();
+ }
+ bc2.postMessage(true);
+ postMessage(true);
+ } catch (e) {
+ postMessage(e);
+ }
+}
+
+function doPostMessageWithinWorkerTest(t, workerName, channelName) {
+ var doneMessageHandler = t.step_func(function(e) {
+ if (e.data ="" true) {
+ // Done worker has finished - no action needed
+ } else if (e.data ="" 'done-worker done') {
+ t.done();
+ } else {
+ assert_unreached(
+ 'BroadcastChannel.postMessage triggered exception within second worker: ' +
+ e.data.message);
+ }
+ });
+ var testMessageHandler = t.step_func(function(e) {
+ assert_equals(
+ e.data, true,
+ 'Worker indicated that the test procedures were executed successfully');
+
+ var w = createWorker(
+ postMessageWithinWorkerWorkerCode, 'done-worker', channelName,
+ doneMessageHandler);
+ t.add_cleanup(() => w.terminate());
+ });
+ createWorker(
+ postMessageWithinWorkerWorkerCode, workerName, channelName,
+ testMessageHandler);
+}
+
+async_test(t => {
+ const workerName = 'close-after-create-worker';
+ const channelName = workerName + '-postmessage-within-worker';
+ doPostMessageWithinWorkerTest(t, workerName, channelName);
+}, 'BroadcastChannel messages within closed worker should be ignored (BCs created before closing)');
+
+async_test(t => {
+ const workerName = 'close-before-create-worker';
+ const channelName = workerName + '-postmessage-within-worker';
+ doPostMessageWithinWorkerTest(t, workerName, channelName);
+}, 'BroadcastChannel messages within closed worker should be ignored (BCs created after closing)');
+
</script>
Modified: trunk/LayoutTests/platform/mac-wk1/TestExpectations (285502 => 285503)
--- trunk/LayoutTests/platform/mac-wk1/TestExpectations 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/LayoutTests/platform/mac-wk1/TestExpectations 2021-11-09 17:49:37 UTC (rev 285503)
@@ -387,6 +387,7 @@
imported/w3c/web-platform-tests/web-locks/secure-context.tentative.https.any.serviceworker.html [ Skip ]
imported/w3c/web-platform-tests/web-locks/signal.tentative.https.any.serviceworker.html [ Skip ]
imported/w3c/web-platform-tests/web-locks/steal.tentative.https.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https.html [ Skip ]
imported/w3c/web-platform-tests/worklets/animation-worklet-service-worker-interception.https.html [ Skip ]
imported/w3c/web-platform-tests/worklets/audio-worklet-service-worker-interception.https.html [ Skip ]
imported/w3c/web-platform-tests/worklets/layout-worklet-service-worker-interception.https.html [ Skip ]
Modified: trunk/LayoutTests/platform/win/TestExpectations (285502 => 285503)
--- trunk/LayoutTests/platform/win/TestExpectations 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/LayoutTests/platform/win/TestExpectations 2021-11-09 17:49:37 UTC (rev 285503)
@@ -3756,6 +3756,7 @@
imported/w3c/web-platform-tests/web-locks/secure-context.tentative.https.any.serviceworker.html [ Skip ]
imported/w3c/web-platform-tests/web-locks/signal.tentative.https.any.serviceworker.html [ Skip ]
imported/w3c/web-platform-tests/web-locks/steal.tentative.https.any.serviceworker.html [ Skip ]
+imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https.html [ Skip ]
imported/w3c/web-platform-tests/worklets/animation-worklet-service-worker-interception.https.html [ Skip ]
imported/w3c/web-platform-tests/worklets/audio-worklet-service-worker-interception.https.html [ Skip ]
imported/w3c/web-platform-tests/worklets/layout-worklet-service-worker-interception.https.html [ Skip ]
Modified: trunk/Source/WebCore/ChangeLog (285502 => 285503)
--- trunk/Source/WebCore/ChangeLog 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/Source/WebCore/ChangeLog 2021-11-09 17:49:37 UTC (rev 285503)
@@ -1,3 +1,25 @@
+2021-11-09 Chris Dumez <cdu...@apple.com>
+
+ Ignore BroadcastChannel::postMessage from detached iframe / closing worker contexts
+ https://bugs.webkit.org/show_bug.cgi?id=232693
+
+ Reviewed by Darin Adler.
+
+ Ignore BroadcastChannel::postMessage from detached iframe / closing worker contexts:
+ - https://html.spec.whatwg.org/#eligible-for-messaging
+
+ Tests: imported/w3c/web-platform-tests/webmessaging/broadcastchannel/basics.any.serviceworker.html
+ imported/w3c/web-platform-tests/webmessaging/broadcastchannel/cross-origin.html
+ imported/w3c/web-platform-tests/webmessaging/broadcastchannel/detached-iframe.html
+ imported/w3c/web-platform-tests/webmessaging/broadcastchannel/ordering.html
+ imported/w3c/web-platform-tests/webmessaging/broadcastchannel/service-worker.https.html
+
+ * dom/BroadcastChannel.cpp:
+ (WebCore::BroadcastChannel::postMessage):
+ (WebCore::BroadcastChannel::dispatchMessage):
+ (WebCore::BroadcastChannel::isEligibleForMessaging const):
+ * dom/BroadcastChannel.h:
+
2021-11-09 Ziran Sun <z...@igalia.com>
[css-grid] update the content-sized grid width before laying out a grid item with block constraints and aspect-ratio
Modified: trunk/Source/WebCore/dom/BroadcastChannel.cpp (285502 => 285503)
--- trunk/Source/WebCore/dom/BroadcastChannel.cpp 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/Source/WebCore/dom/BroadcastChannel.cpp 2021-11-09 17:49:37 UTC (rev 285503)
@@ -180,6 +180,9 @@
ExceptionOr<void> BroadcastChannel::postMessage(JSC::JSGlobalObject& globalObject, JSC::JSValue message)
{
+ if (!isEligibleForMessaging())
+ return { };
+
if (m_isClosed)
return Exception { InvalidStateError, "This BroadcastChannel is closed" };
@@ -225,6 +228,9 @@
void BroadcastChannel::dispatchMessage(Ref<SerializedScriptValue>&& message)
{
+ if (!isEligibleForMessaging())
+ return;
+
if (m_isClosed)
return;
@@ -249,4 +255,17 @@
return !m_isClosed && m_hasRelevantEventListener;
}
+// https://html.spec.whatwg.org/#eligible-for-messaging
+bool BroadcastChannel::isEligibleForMessaging() const
+{
+ auto* context = scriptExecutionContext();
+ if (!context)
+ return false;
+
+ if (is<Document>(*context))
+ return downcast<Document>(*context).isFullyActive();
+
+ return !downcast<WorkerGlobalScope>(*context).isClosing();
+}
+
} // namespace WebCore
Modified: trunk/Source/WebCore/dom/BroadcastChannel.h (285502 => 285503)
--- trunk/Source/WebCore/dom/BroadcastChannel.h 2021-11-09 16:58:33 UTC (rev 285502)
+++ trunk/Source/WebCore/dom/BroadcastChannel.h 2021-11-09 17:49:37 UTC (rev 285503)
@@ -70,6 +70,8 @@
void dispatchMessage(Ref<SerializedScriptValue>&&);
void ensureOnMainThread(Function<void(Document&)>&&);
+ bool isEligibleForMessaging() const;
+
// EventTarget
EventTargetInterface eventTargetInterface() const final { return BroadcastChannelEventTargetInterfaceType; }
ScriptExecutionContext* scriptExecutionContext() const final { return ActiveDOMObject::scriptExecutionContext(); }