tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

beforeunload-canceling.html (6173B)


      1 <!DOCTYPE html>
      2 <meta charset="utf-8">
      3 <title>beforeunload return value cancelation behavior</title>
      4 <link rel="help" href="https://html.spec.whatwg.org/multipage/webappapis.html#the-event-handler-processing-algorithm">
      5 <link rel="author" title="Domenic Denicola" href="mailto:d@domenic.me">
      6 <script src="/resources/testharness.js"></script>
      7 <script src="/resources/testharnessreport.js"></script>
      8 
      9 <div id="log"></div>
     10 
     11 <script>
     12 "use strict";
     13 
     14 promise_test(t => {
     15  let onbeforeunloadHappened = false;
     16  window.onbeforeunload = t.step_func(() => {
     17    onbeforeunloadHappened = true;
     18    return "cancel me";
     19  });
     20 
     21  const eventWatcher = new EventWatcher(t, window, "beforeunload");
     22  const promise = eventWatcher.wait_for("beforeunload").then(e => {
     23    assert_true(onbeforeunloadHappened, "CustomEvent must be able to trigger the event handler");
     24    assert_false(e.defaultPrevented, "The event must not have been canceled");
     25    window.onbeforeunload = null;
     26  });
     27 
     28  window.dispatchEvent(new CustomEvent("beforeunload"));
     29 
     30  return promise;
     31 }, "Returning a string must not cancel the event: CustomEvent, non-cancelable");
     32 
     33 promise_test(t => {
     34  let onbeforeunloadHappened = false;
     35  window.onbeforeunload = t.step_func(() => {
     36    onbeforeunloadHappened = true;
     37    return "cancel me";
     38  });
     39 
     40  const eventWatcher = new EventWatcher(t, window, "beforeunload");
     41  const promise = eventWatcher.wait_for("beforeunload").then(e => {
     42    assert_true(onbeforeunloadHappened, "CustomEvent must be able to trigger the event handler");
     43    assert_false(e.defaultPrevented, "The event must not have been canceled");
     44    window.onbeforeunload = null;
     45    t.done();
     46  });
     47 
     48  window.dispatchEvent(new CustomEvent("beforeunload", { cancelable: true }));
     49 
     50  return promise;
     51 }, "Returning a string must not cancel the event: CustomEvent, cancelable");
     52 
     53 promise_test(t => {
     54  let onbeforeunloadHappened = false;
     55  window.onbeforeunload = t.step_func(() => {
     56    onbeforeunloadHappened = true;
     57    return false;
     58  });
     59 
     60  const eventWatcher = new EventWatcher(t, window, "beforeunload");
     61  const promise = eventWatcher.wait_for("beforeunload").then(e => {
     62    assert_true(onbeforeunloadHappened, "CustomEvent must be able to trigger the event handler");
     63    assert_false(e.defaultPrevented, "The event must not have been canceled");
     64    window.onbeforeunload = null;
     65    t.done();
     66  });
     67 
     68  window.dispatchEvent(new CustomEvent("beforeunload", { cancelable: true }));
     69 
     70  return promise;
     71 }, "Returning false must not cancel the event, because it's coerced to the DOMString \"false\" which does not cancel " +
     72   "CustomEvents: CustomEvent, cancelable");
     73 
     74 // This test can be removed if we update the DOM Standard to disallow createEvent("BeforeUnloadEvent"). Browser support
     75 // is inconsistent. https://github.com/whatwg/dom/issues/362
     76 promise_test(t => {
     77  const eventWatcher = new EventWatcher(t, window, "click");
     78  const promise = eventWatcher.wait_for("click").then(e => {
     79    assert_false(e.defaultPrevented, "The event must not have been canceled");
     80    window.onbeforeunload = null;
     81    t.done();
     82  });
     83 
     84  const ev = document.createEvent("BeforeUnloadEvent");
     85  ev.initEvent("click", false, true);
     86  window.dispatchEvent(ev);
     87 
     88  return promise;
     89 }, "Returning a string must not cancel the event: BeforeUnloadEvent with type \"click\", cancelable");
     90 
     91 const testCases = [
     92  {
     93    valueToReturn: null,
     94    expectCancelation: false,
     95    expectedReturnValue: ""
     96  },
     97  {
     98    valueToReturn: undefined,
     99    expectCancelation: false,
    100    expectedReturnValue: ""
    101  },
    102  {
    103    valueToReturn: "",
    104    expectCancelation: true,
    105    expectedReturnValue: ""
    106  },
    107  {
    108    valueToReturn: false,
    109    expectCancelation: true,
    110    expectedReturnValue: "false"
    111  },
    112  {
    113    valueToReturn: true,
    114    expectCancelation: true,
    115    expectedReturnValue: "true"
    116  },
    117  {
    118    valueToReturn: 0,
    119    expectCancelation: true,
    120    expectedReturnValue: "0"
    121  },
    122  {
    123    valueToReturn: null,
    124    expectCancelation: false,
    125    setReturnValue: "foo",
    126    expectedReturnValue: "foo"
    127  },
    128  {
    129    valueToReturn: undefined,
    130    expectCancelation: false,
    131    setReturnValue: "foo",
    132    expectedReturnValue: "foo"
    133  },
    134  {
    135    valueToReturn: "",
    136    expectCancelation: true,
    137    setReturnValue: "foo",
    138    expectedReturnValue: "foo"
    139  },
    140  {
    141    valueToReturn: false,
    142    expectCancelation: true,
    143    setReturnValue: "foo",
    144    expectedReturnValue: "foo"
    145  },
    146  {
    147    valueToReturn: true,
    148    expectCancelation: true,
    149    setReturnValue: "foo",
    150    expectedReturnValue: "foo"
    151  },
    152  {
    153    valueToReturn: 0,
    154    expectCancelation: true,
    155    setReturnValue: "foo",
    156    expectedReturnValue: "foo"
    157  },
    158  {
    159    setReturnValue: "",
    160    expectedReturnValue: "",
    161    expectCancelation: false,
    162  },
    163  {
    164    expectCancelation: true,
    165    expectedReturnValue: "",
    166    cancel: true
    167  },
    168  {
    169    setReturnValue: "foo",
    170    expectCancelation: true,
    171    expectedReturnValue: "foo",
    172    cancel: true
    173  },
    174  {
    175    valueToReturn: "foo",
    176    expectedReturnValue: "foo",
    177    expectCancelation: true,
    178    cancel: true
    179  },
    180  {
    181    valueToReturn: "foo",
    182    setReturnValue: "foo",
    183    expectedReturnValue: "foo",
    184    expectCancelation: true,
    185    cancel: true
    186  },
    187  {
    188    valueToReturn: true,
    189    setReturnValue: "",
    190    expectedReturnValue: "true",
    191    expectCancelation: true,
    192    cancel: true
    193  }
    194 ];
    195 
    196 var testCaseIndex = 0;
    197 function runNextTest() {
    198  const testCase = testCases[testCaseIndex];
    199 
    200  const labelAboutReturnValue = testCase.setReturnValue === undefined ? "" :
    201    `; setting returnValue to ${testCase.setReturnValue}`;
    202 
    203  const labelAboutCancel = testCase.cancel === undefined ? "" :
    204    "; calling preventDefault()";
    205 
    206  const suffixLabels = labelAboutReturnValue + labelAboutCancel;
    207 
    208  async_test(t => {
    209    const iframe = document.createElement("iframe");
    210    iframe.onload = t.step_func(() => {
    211      iframe.contentWindow.runTest(t, testCase);
    212      if (++testCaseIndex < testCases.length)
    213        runNextTest();
    214    });
    215 
    216    iframe.src = "beforeunload-canceling-1.html";
    217    document.body.appendChild(iframe);
    218  }, `Returning ${testCase.valueToReturn} with a real iframe unloading${suffixLabels}`);
    219 }
    220 
    221 runNextTest();
    222 </script>