<!doctype html>
<meta charset={{GET[encoding]}}> <!-- ends up as <meta charset> by default which is windows-1252 -->
<meta name=variant content="?encoding=windows-1252">
<meta name=variant content="?encoding=x-cp1251">
<meta name=variant content="?encoding=utf8">
<script src=/resources/testharness.js></script>
<script src=/resources/testharnessreport.js></script>
<script src="/common/utils.js"></script>
<link rel=help href=https://html.spec.whatwg.org/multipage/#following-hyperlinks>
<link rel=help href=https://html.spec.whatwg.org/multipage/#hyperlink-auditing>
<link rel=help href=https://html.spec.whatwg.org/multipage/#attr-meta-http-equiv-refresh>
<div id=log></div>
<script>
function expected(encoding) {
  return {
    "UTF-8": "%C3%BF",
    "windows-1251": "%26%23255%3B",
    "windows-1252": "%FF"
  }[encoding];
}
var encoding = document.characterSet;
var blank = 'resources/blank.py?encoding=' + encoding;
var stash_put = 'resources/stash.py?q=\u00FF&action=put&id=';
var stash_take = 'resources/stash.py?action=take&id=';
var input_url_html = 'resources/resource.py?q=\u00FF&encoding=' + encoding + '&type=html';
var expected_current = expected(encoding);
var expected_utf8 = expected('UTF-8');

function assert_ends_with(input, endsWith) {
  assert_true(input.endsWith(endsWith), input + " did not end with " + endsWith);
}


function poll_for_stash(test_obj, uuid, expected) {
  var start = new Date();
  var poll = test_obj.step_func(function () {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', stash_take + uuid);
    xhr.onload = test_obj.step_func(function(e) {
      if (xhr.response == "") {
        if (new Date() - start > 10000) {
          // If we set the status to TIMEOUT here we avoid a race between the
          // page and the test timing out
          test_obj.force_timeout();
        }
        test_obj.step_timeout(poll, 200);
      } else {
        assert_equals(xhr.response, expected);
        test_obj.done();
      }
    });
    xhr.send();
  })
  test_obj.step_timeout(poll, 200);
}

function setup_navigation(elm, iframe, id, test_obj) {
  iframe.name = id;
  elm.target = id;
  elm.setAttribute('href', input_url_html);
  document.body.appendChild(iframe);
  document.body.appendChild(elm);
  test_obj.add_cleanup(function() {
    document.body.removeChild(iframe);
    document.body.removeChild(elm);
  });
}

// follow hyperlink
function test_follow_link(tag) {
  async_test(function() {
    var elm = document.createElement(tag);
    var iframe = document.createElement('iframe');
    setup_navigation(elm, iframe, 'test_follow_link_'+tag, this);
    iframe.onload = this.step_func_done(function() { // when the page navigated to has loaded
      assert_equals(iframe.contentDocument.body.textContent, expected_current);
    });
    // follow the hyperlink
    elm.click();
    // check that navigation succeeded by ...??? XXX
  }, 'follow hyperlink <'+tag+' href>');
}

'a, area'.split(', ').forEach(function(str) {
  test_follow_link(str);
});

async_test(function() {
  const iframe = document.createElement('iframe');
  iframe.name = 'test_dont_follow_link';
  document.body.appendChild(iframe);

  const link = document.createElement('link');
  link.target = iframe.name;
  link.setAttribute('href', input_url_html);
  document.body.appendChild(link);

  const anchor = document.createElement('a');
  anchor.target = iframe.name;
  anchor.setAttribute('href', blank);
  document.body.appendChild(anchor);

  this.add_cleanup(function() {
    iframe.remove();
    link.remove();
    anchor.remove();
  });

  iframe.onload = this.step_func_done(() => {
    assert_equals(
      iframe.contentDocument.location.pathname,
      '/html/infrastructure/urls/resolving-urls/query-encoding/resources/blank.py',
      'The <a> navigation should occur instead of the <link> navigation.');
  });

  anchor.click();
  link.click();
}, `don't follow hyperlink <link href>`);

// follow hyperlink with ping attribute
function test_follow_link_ping(tag) {
  async_test(function() {
    var uuid = token();
    var elm = document.createElement(tag);
    // check if ping is supported
    assert_true('ping' in elm, 'ping not supported');
    elm.setAttribute('ping', stash_put + uuid);
    var iframe = document.createElement('iframe');
    setup_navigation(elm, iframe, 'test_follow_link_ping_'+tag, this);
    // follow the hyperlink
    elm.click();
    // check that navigation succeeded by ...??? XXX
    // check that the right URL was requested for the ping
    poll_for_stash(this, uuid, expected_current);
  }, 'hyperlink auditing <'+tag+' ping>');
}

'a, area'.split(', ').forEach(function(str) {
  test_follow_link_ping(str);
});

// navigating with meta refresh
async_test(function() {
  var iframe = document.createElement('iframe');
  iframe.src = blank;
  document.body.appendChild(iframe);
  this.add_cleanup(function() {
    document.body.removeChild(iframe);
  });
  iframe.onload = this.step_func_done(function() {
    var doc = iframe.contentDocument;
    var got = doc.body.textContent;
    if (got == '') {
      doc.write('<meta http-equiv=refresh content="0; URL='+input_url_html+'">REFRESH');
      doc.close();
      return;
    }
    assert_equals(got, expected_current);
  });
}, 'meta refresh');

</script>
