<!DOCTYPE html>
<script src="../resources/testharness.js"></script>
<script src="../resources/testharnessreport.js"></script>
<body>
<script type="text/javascript">
// Verify that when the 'src' attribute for an <img> element is changed, the
// element transitions properly between states where primary content is shown,
// fallback content is shown, and when the element is collapsed.
//
// This test is carried out using a matrix of <img> elements. Initially, all
// images in the first row are set to show primary content, all images in the
// second row are set to show fallback content, etc. Once everything is loaded,
// the 'src' URLs are changed so that all images in the first column should show
// primary content, in the second column fallback content, etc.

var INITIAL_URLS = {
  "primary": "resources/alpha.png",
  "fallback": "resources/non-existent-1.png",
  "collapsed": "resources/gamma.png"
};

var FINAL_URLS = {
  "primary": "resources/beta.png",
  "fallback": "resources/non-existent-2.png",
  "collapsed": "resources/delta.png"
};

var EXPECTED_LOADEND_EVENT = {
  "primary": "load",
  "fallback": "error",
  "collapsed": "error"
};

var EXPECTED_WIDTH = {
  "primary": 100,
  "fallback": 0,
  "collapsed": 0
};

var EXPECTED_DISPLAY = {
  "primary": "inline",
  "fallback": "inline",
  "collapsed": "none",
};

var numPendingImages =
    Object.keys(INITIAL_URLS).length * Object.keys(FINAL_URLS).length;

if (window.testRunner)
  testRunner.setDisallowedSubresourcePathSuffixes(["gamma.png", "delta.png"], true /* block_subresources */);

let table = document.createElement("table");
let headerRow = table.insertRow();

headerRow.insertCell().innerHTML = "- - - - \\ Final<br>Initial \\";
for (let finalState of Object.keys(FINAL_URLS)) {
  headerRow.insertCell().textContent = finalState;
}

for (let [initialState, initialUrl] of Object.entries(INITIAL_URLS)) {
  let row = table.insertRow();
  row.insertCell().textContent = initialState;
  for (let [finalState, finalUrl] of Object.entries(FINAL_URLS)) {
    let cell = row.insertCell();
    let img = document.createElement("img");
    img.src = initialUrl;
    async_test(t => {
      let eventWatcher = new EventWatcher(t, img, ["load", "error"]);
      eventWatcher.wait_for(EXPECTED_LOADEND_EVENT[initialState])
        .then(_ => {
          window.setTimeout(_ => img.src = finalUrl);
          return eventWatcher.wait_for(EXPECTED_LOADEND_EVENT[finalState]);
        })
        .then(t.step_func_done(_ => {
          assert_equals(img.clientWidth, EXPECTED_WIDTH[finalState],
              "Image has incorrect width for the expected final state.");
          let style = window.getComputedStyle(img);
          assert_equals(style.display, EXPECTED_DISPLAY[finalState],
              "Images has incorrect computed style for the final state.");
        }));
    }, "State transition " + initialState + " to " + finalState + ". ");
    cell.append(img);
  }
}
document.body.append(table);
</script>
