| <!DOCTYPE html> |
| <html> |
| <body> |
| <script src="../../resources/js-test.js"></script> |
| <script> |
| description("Tests that MessagePort.postMessage() works from inside an iframe's unload event handler."); |
| jsTestIsAsync = true; |
| |
| let eventsReceivedByFrameWindow = 0; |
| let eventsReceivedByTopWindow = 0; |
| let eventsReceivedByTopWindowMessagePort = 0; |
| |
| function finishIfNecessary() |
| { |
| if (eventsReceivedByTopWindow < 3 || eventsReceivedByTopWindowMessagePort < 3) |
| return; |
| |
| setTimeout(() => { |
| shouldBe("eventsReceivedByFrameWindow", "3"); |
| shouldBe("eventsReceivedByTopWindow", "3"); |
| shouldBe("eventsReceivedByTopWindowMessagePort", "3"); |
| finishJSTest(); |
| }, 0); |
| } |
| |
| onload = () => { |
| const testFrame = document.getElementById("testFrame"); |
| testFrame.contentWindow.addEventListener("message", (e) => { |
| const framePort = e.data.port; |
| for (let event of ["unload", "pagehide", "visibilitychange"]) { |
| testFrame.contentWindow.addEventListener(event, () => { |
| eventsReceivedByFrameWindow++; |
| window.parent.testPassed(`iframe received "${event}" event`); |
| framePort.postMessage({ trigger: event }); |
| window.parent.postMessage({ trigger: event }); |
| }); |
| } |
| }); |
| |
| const channel = new MessageChannel(); |
| testFrame.contentWindow.postMessage({ |
| port: channel.port1, |
| }, testFrame.contentWindow.origin, [channel.port1]); |
| channel.port2.onmessage = (e) => { |
| eventsReceivedByTopWindowMessagePort++; |
| testPassed("MessagePort in parent frame received message", e.data); |
| finishIfNecessary(); |
| }; |
| |
| addEventListener("message", (e) => { |
| eventsReceivedByTopWindow++; |
| testPassed('Parent frame received "message" event', e.data); |
| finishIfNecessary(); |
| }); |
| setTimeout(() => { |
| testFrame.remove(); |
| setTimeout(finishJSTest, 100); |
| }, 0); |
| }; |
| </script> |
| <iframe id="testFrame"></iframe> |
| </body> |
| </html> |