<!DOCTYPE html>
<meta charset=utf-8>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<!-- Pull in the with_iframe helper function from the service worker tests -->
<script src="/service-workers/service-worker/resources/test-helpers.sub.js"></script>
<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>
