<!doctype html>
<meta charset=utf-8>
<title></title>
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
  function createInputElement(value, append, suffix) {
    var el = document.createElement("input");
    el.type = "text";
    el.value = value;
    el.id = "input" + (append ? "-appended" : "-not-appended") + (suffix ? suffix : "");
    if (append) {
      document.body.appendChild(el);
    }
    return el;
  };

  function createTextareaElement(value, append, suffix) {
    var el = document.createElement("textarea");
    el.value = value;

    el.id = "textarea" + (append ? "-appended" : "-not-appended") + (suffix ? suffix : "");
    if (append) {
      document.body.appendChild(el);
    }
    return el;
  };

  function createPrefocusedInputElement(value, append) {
    var el = createInputElement(value, append, "-prefocused");
    el.focus();
    el.blur();
    return el;
  }

  function createPrefocusedTextareaElement(value, append) {
    var el = createTextareaElement(value, append, "-prefocused");
    el.focus();
    el.blur();
    return el;
  }

  function createTestElements(value) {
    return [ createInputElement(value, true),
             createInputElement(value, false),
             createPrefocusedInputElement(value, true),
             createPrefocusedInputElement(value, false),
             createTextareaElement(value, true),
             createTextareaElement(value, false),
             createPrefocusedTextareaElement(value, true),
             createPrefocusedTextareaElement(value, false),
           ];
  }

  var testValue = "abcdefghij";

  test(function() {
    assert_equals(testValue.length, 10);
  }, "Sanity check for testValue length; if this fails, variou absolute offsets in the test below need to be adjusted to be less than testValue.length");

  for (let prop of ["selectionStart", "selectionEnd"]) {
    for (let el of createTestElements(testValue)) {
      test(function() {
        assert_equals(el[prop], testValue.length);
      }, `Initial .value set on ${el.id} should set ${prop} to end of value`);
    }
  }

  test(function() {
    for (let el of createTestElements(testValue)) {
      var t = async_test(`onselect should fire when selectionStart is changed on ${el.id}`);
      el.onselect = t.step_func_done(function(e) {
        assert_equals(e.type, "select");
        el.remove();
      });
      el.selectionStart = 2;
    }
  }, "onselect should fire when selectionStart is changed");

  test(function() {
    for (let el of createTestElements(testValue)) {
      var t = async_test(`onselect should fire when selectionEnd is changed on ${el.id}`);
      el.onselect = t.step_func_done(function(e) {
        assert_equals(e.type, "select");
        el.remove();
      });
      el.selectionEnd = 2;
    }
  }, "onselect should fire when selectionEnd is changed");

  test(function() {
    for (let el of createTestElements(testValue)) {
      el.selectionStart = 0;
      el.selectionEnd = 5;
      el.selectionStart = 8;
      assert_equals(el.selectionStart, 8, `selectionStart on ${el.id}`);
      assert_equals(el.selectionEnd, 8, `selectionEnd on ${el.id}`);
      el.remove();
    }
  }, "Setting selectionStart to a value larger than selectionEnd should increase selectionEnd");

  test(function() {
    for (let el of createTestElements(testValue)) {
      el.selectionStart = 8;
      el.selectionEnd = 5;
      assert_equals(el.selectionStart, 5, `selectionStart on ${el.id}`);
      assert_equals(el.selectionEnd, 5, `selectionEnd on ${el.id}`);
      el.remove();
    }
  }, "Setting selectionEnd to a value smaller than selectionStart should decrease selectionStart");

  test(function() {
    for (let el of createTestElements(testValue)) {
      el.selectionStart = 0;
      assert_equals(el.selectionStart, 0, `We just set it on ${el.id}`);
      el.selectionStart = -1;
      assert_equals(el.selectionStart, testValue.length,
                    `selectionStart setter on ${el.id} should convert -1 to 2^32-1`);
      el.selectionStart = Math.pow(2, 32);
      assert_equals(el.selectionStart, 0,
                    `selectionStart setter on ${el.id} should convert 2^32 to 0`);
      el.selectionStart = Math.pow(2, 32) - 1;
      assert_equals(el.selectionStart, testValue.length,
                    `selectionStart setter on ${el.id} should leave 2^32-1 as-is`);
      el.remove();
    }
  }, "selectionStart edge-case values");

  test(function() {
    for (let el of createTestElements(testValue)) {
      el.selectionEnd = 0;
      assert_equals(el.selectionEnd, 0, `We just set it on ${el.id}`);
      el.selectionEnd = -1;
      assert_equals(el.selectionEnd, testValue.length,
                    `selectionEnd setter on ${el.id} should convert -1 to 2^32-1`);
      el.selectionEnd = Math.pow(2, 32);
      assert_equals(el.selectionEnd, 0,
                    `selectionEnd setter on ${el.id} should convert 2^32 to 0`);
      el.selectionEnd = Math.pow(2, 32) - 1;
      assert_equals(el.selectionEnd, testValue.length,
                    `selectionEnd setter on ${el.id} should leave 2^32-1 as-is`);
      el.remove();
    }
  }, "selectionEnd edge-case values");

  test(() => {
    for (let el of createTestElements(testValue)) {
      const start = 1;
      const end = testValue.length - 1;

      el.setSelectionRange(start, end);

      assert_equals(el.selectionStart, start, `selectionStart on ${el.id}`);
      assert_equals(el.selectionEnd, end, `selectionEnd on ${el.id}`);

      el.selectionDirection = "backward";

      assert_equals(el.selectionStart, start,
                    `selectionStart on ${el.id} after setting selectionDirection to "backward"`);
      assert_equals(el.selectionEnd, end,
                    `selectionEnd on ${el.id} after setting selectionDirection to "backward"`);

      el.selectionDirection = "forward";

      assert_equals(el.selectionStart, start,
                    `selectionStart on ${el.id} after setting selectionDirection to "forward"`);
      assert_equals(el.selectionEnd, end,
                    `selectionEnd on ${el.id} after setting selectionDirection to "forward"`);
    }
  }, "selectionStart and selectionEnd should remain the same when selectionDirection is changed");
</script>
