<!DOCTYPE html>
<meta charset=utf-8>
<title>createImageBitmap: origin-clean flag</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/media.js"></script>
<script src="/common/namespaces.js"></script>
<div id=log></div>
<script>
const crossOriginImageUrl = "http://{{domains[www1]}}:{{ports[http][0]}}/images/red.png";

function assert_origin_unclean(bitmap) {
  const context = document.createElement("canvas").getContext("2d");
  context.drawImage(bitmap, 0, 0);
  assert_throws("SecurityError", () => {
    context.getImageData(0, 0, 1, 1);
  });
}

function makeImage() {
  return new Promise((resolve, reject) => {
    const image = new Image();
    image.onload = () => resolve(image);
    image.onerror = reject;
    image.src = crossOriginImageUrl;
  });
}

const arguments = [
  {
    name: "cross-origin HTMLImageElement",
    factory: makeImage,
  },

  {
    name: "cross-origin SVGImageElement",
    factory: () => {
      return new Promise((resolve, reject) => {
        const image = document.createElementNS(NAMESPACES.svg, "image");
        image.onload = () => resolve(image);
        image.onerror = reject;
        image.setAttribute("externalResourcesRequired", "true");
        image.setAttributeNS(NAMESPACES.xlink, 'xlink:href', crossOriginImageUrl);
        document.body.appendChild(image);
      });
    },
  },

  {
    name: "cross-origin HTMLVideoElement",
    factory: () => {
      return new Promise((resolve, reject) => {
        const video = document.createElement("video");
        video.oncanplaythrough = () => resolve(video);
        video.onerror = reject;
        video.src = getVideoURI("http://{{domains[www1]}}:{{ports[http][0]}}/media/movie_300");
      });
    },
  },

  {
    name: "redirected to cross-origin HTMLVideoElement",
    factory: () => {
      return new Promise((resolve, reject) => {
        const video = document.createElement("video");
        video.oncanplaythrough = () => resolve(video);
        video.onerror = reject;
        video.src = "/common/redirect.py?location=" + getVideoURI("http://{{domains[www1]}}:{{ports[http][0]}}/media/movie_300");
      });
    },
  },

  {
    name: "redirected to same-origin HTMLVideoElement",
    factory: () => {
      return new Promise((resolve, reject) => {
        const video = document.createElement("video");
        video.oncanplaythrough = () => resolve(video);
        video.onerror = reject;
        video.src = "http://{{domains[www1]}}:{{ports[http][0]}}/common/redirect.py?location=" + getVideoURI("http://{{domains[]}}:{{ports[http][0]}}/media/movie_300");
      });
    },
  },

  {
    name: "unclean HTMLCanvasElement",
    factory: () => {
      return makeImage().then(image => {
        const canvas = document.createElement("canvas");
        const context = canvas.getContext("2d");
        context.drawImage(image, 0, 0);
        return canvas;
      });
    },
  },

  {
    name: "unclean ImageBitmap",
    factory: () => {
      return makeImage().then(createImageBitmap);
    },
  },
];

for (let { name, factory } of arguments) {
  promise_test(function() {
    return factory().then(createImageBitmap).then(assert_origin_unclean);
  }, name);
}
</script>
