<html><head>
<title>Test for bug 891247</title>
<link rel="stylesheet" href="/tests/SimpleTest/test.css">
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="/tests/SimpleTest/EventUtils.js"></script>

<script class="testbody" type="application/javascript">
  function ImageTester() {
    var counter = 0;
    var images = [];
    var that = this;

    this.add = function(aFile) {
      images.push(aFile);
    };

    this.test = function() {
      for (var i = 0; i < images.length; i++) {
        testImageSize(images[i]);
      }
    };

    this.returned = function() {
      counter++;
      info("returned=" + counter + " images.length=" + images.length);
      if (counter == images.length) {
        info("test finish");
        SimpleTest.finish();
      }
    };

    function testImageSize(aFile) {
      var source = window.URL.createObjectURL(aFile);
      var image = new Image();
      image.src = source;
      var imageTester = that;
      image.onload = function() {
        is(this.width, 62, "Check generated image width");
        is(this.height, 71, "Check generated image height");
        if (aFile.type == "image/gif") {
          // this test fails for image/jpeg and image/png because the images
          // generated are slightly different
          testImageCanvas(image);
        }

        imageTester.returned();
      }

      document.body.appendChild(image);
    };

    function testImageCanvas(aImage) {
      var canvas = drawToCanvas(aImage);

      var refImage = document.getElementById('image');
      var refCanvas = drawToCanvas(refImage);

      is(canvas.toDataURL(), refCanvas.toDataURL(), "Image should map pixel-by-pixel");
    }

    function drawToCanvas(aImage) {
      var canvas = document.createElement("CANVAS");
      document.body.appendChild(canvas);
      canvas.width = aImage.width;
      canvas.height = aImage.height;
      canvas.getContext('2d').drawImage(aImage, 0, 0);
      return canvas;
    }
  }

  function copyImage(aImageId) {
    // selection of the node
    var node = document.getElementById(aImageId);
    var webnav = SpecialPowers.wrap(window)
                 .QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
                 .getInterface(SpecialPowers.Ci.nsIWebNavigation)

    var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell);

    // let's copy the node
    var documentViewer = docShell.contentViewer
                         .QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit);
    documentViewer.setCommandNode(node);
    documentViewer.copyImage(documentViewer.COPY_IMAGE_ALL);
  }

  function doTest() {
    SimpleTest.waitForExplicitFinish();

    copyImage('image');

    //--------- now check the content of the clipboard
    var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"]
                                 .getService(SpecialPowers.Ci.nsIClipboard);
    // does the clipboard contain text/unicode data ?
    ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard),
       "clipboard contains unicode text");
    // does the clipboard contain text/html data ?
    ok(clipboard.hasDataMatchingFlavors(["text/html"], 1, clipboard.kGlobalClipboard),
       "clipboard contains html text");
    // does the clipboard contain image data ?
    ok(clipboard.hasDataMatchingFlavors(["image/png"], 1, clipboard.kGlobalClipboard),
       "clipboard contains image");

    window.addEventListener("paste", onPaste);

    var textarea = SpecialPowers.wrap(document.getElementById('textarea'));
    textarea.focus();
    textarea.editor.paste(clipboard.kGlobalClipboard);
  }

  function onPaste(e) {
    var imageTester = new ImageTester;
    testFiles(e, imageTester);
    testItems(e, imageTester);
    imageTester.test();
  }

  function testItems(e, imageTester) {
    var items = e.clipboardData.items;
    is(items, e.clipboardData.items,
       "Getting @items twice should return the same object");
    var haveFiles = false;
    ok(items instanceof DataTransferItemList, "@items implements DataTransferItemList");
    ok(items.length > 0, "@items is not empty");
    for (var i = 0; i < items.length; i++) {
      var item = items[i];
      ok(item instanceof DataTransferItem, "each element of @items must implement DataTransferItem");
      if (item.kind == "file") {
        var file = item.getAsFile();
        ok(file instanceof File, ".getAsFile() returns a File object");
        ok(file.size > 0, "Files shouldn't have size 0");
        imageTester.add(file);
      }
    }
  }

  function testFiles(e, imageTester) {
    var files = e.clipboardData.files;

    is(files, e.clipboardData.files,
       "Getting the files array twice should return the same array");
    ok(files.length > 0, "There should be at least one file in the clipboard");
    for (var i = 0; i < files.length; i++) {
      var file = files[i];
      ok(file instanceof File, ".files should contain only File objects");
      ok(file.size > 0, "This file shouldn't have size 0");
      if (file.name == "image.png") {
        is(file.type, "image/png", "This file should be a image/png");
      } else if (file.name == "image.jpeg") {
        is(file.type, "image/jpeg", "This file should be a image/jpeg");
      } else if (file.name == "image.gif") {
        is(file.type, "image/gif", "This file should be a image/gif");
      } else {
        info("file.name=" + file.name);
        ok(false, "Unexpected file name");
      }

      testSlice(file);
      imageTester.add(file);
      // Adding the same image again so we can test concurrency
      imageTester.add(file);
    }
  }

  function testSlice(aFile) {
    var blob = aFile.slice();
    ok(blob instanceof Blob, ".slice returns a blob");
    is(blob.size, aFile.size, "the blob has the same size");

    blob = aFile.slice(123123);
    is(blob.size, 0, ".slice overflow check");

    blob = aFile.slice(123, 123141);
    is(blob.size, aFile.size - 123, ".slice @size check");

    blob = aFile.slice(123, 12);
    is(blob.size, 0, ".slice @size check 2");

    blob = aFile.slice(124, 134, "image/png");
    is(blob.size, 10, ".slice @size check 3");
    is(blob.type, "image/png", ".slice @type check");
  }

</script>
<body onload="doTest();">
  <img id="image" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAD4AAABHCA
  IAAADQjmMaAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3goUAwAgSAORBwAAABl0RVh0Q29
  tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAABPSURBVGje7c4BDQAACAOga//OmuMbJGAurTbq
  6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6urq6s31B0IqAY2/t
  QVCAAAAAElFTkSuQmCC" />
  <form>
    <textarea id="textarea"></textarea>
  </form>
</body>
</html>