tor-browser

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

promise-job-detached-iframe.html (8311B)


      1 <!DOCTYPE html>
      2 <script src="/resources/testharness.js"></script>
      3 <script src="/resources/testharnessreport.js"></script>
      4 <body>
      5 
      6 <script>
      7 function async_iframe_test(f, name) {
      8  async_test(t => {
      9    const iframe = document.createElement("iframe");
     10    iframe.src = "resources/empty.html";
     11    document.body.append(iframe);
     12 
     13    iframe.onload = () => {
     14      f(t, iframe);
     15    };
     16  }, name);
     17 }
     18 
     19 async_iframe_test((t, iframe) => {
     20  // A promise reaction job is created with the iframe's realm, retrieved
     21  // from the onFulfilled callback function.
     22  const { p, result } = iframe.contentWindow.eval(`
     23 const result = { called: false };
     24 const p = Promise.resolve(1).then(function onFulfilled() {
     25 result.called = true;
     26 });
     27 ({ p, result });
     28 `);
     29 
     30  // The global becomes not-fully-active before the next microtask checkpoint.
     31  iframe.remove();
     32 
     33  // Verify the result after the next microtask checkpoint.
     34  t.step_timeout(() => {
     35    assert_equals(result.called, false);
     36    t.done();
     37  }, 0);
     38 }, "Reaction job should be skipped if onFulfilled handler belongs to detached iframe");
     39 
     40 async_iframe_test((t, iframe) => {
     41  // A promise reaction job is created with the iframe's realm, retrieved
     42  // from the onRejected callback function.
     43  const { p, result } = iframe.contentWindow.eval(`
     44 const result = { called: false };
     45 const p = Promise.reject(1).then(() => {}, function onRejected() {
     46 result.called = true;
     47 });
     48 ({ p, result });
     49 `);
     50 
     51  // The global becomes not-fully-active before the next microtask checkpoint.
     52  iframe.remove();
     53 
     54  t.step_timeout(() => {
     55    assert_equals(result.called, false);
     56    t.done();
     57  }, 0);
     58 }, "Reaction job should be skipped if onRejected handler belongs to detached iframe");
     59 
     60 async_iframe_test((t, iframe) => {
     61  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
     62 
     63  iframe.remove();
     64 
     65  let called = false;
     66 
     67  // A promise reaction job is created with the current realm, retrieved
     68  // from the onFulfilled callback function.
     69  p.then(function onFulfilled() {
     70    called = true;
     71  });
     72 
     73  t.step_timeout(() => {
     74    assert_equals(called, true);
     75    t.done();
     76  }, 0);
     77 }, "Reaction job should not be skipped if onFulfilled handler belongs to fully active global");
     78 
     79 async_iframe_test((t, iframe) => {
     80  const p = iframe.contentWindow.eval(`Promise.reject(1);`);
     81 
     82  iframe.remove();
     83 
     84  let called = false;
     85 
     86  // A promise reaction job is created with the current realm, retrieved
     87  // from the onRejected callback function.
     88  p.then(() => {}, function onRejected() {
     89    called = true;
     90  });
     91 
     92  t.step_timeout(() => {
     93    assert_equals(called, true);
     94    t.done();
     95  }, 0);
     96 }, "Reaction job should not be skipped if onRejected handler belongs to fully active global");
     97 
     98 async_iframe_test((t, iframe) => {
     99  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
    100 
    101  iframe.remove();
    102 
    103  let called = false;
    104 
    105  // A thenable job is created with the iframe's realm, retrieved from p.then
    106  // function.
    107  const p2 = Promise.resolve(p);
    108 
    109  p2.then(function onFulfilled() {
    110    called = true;
    111  });
    112 
    113  t.step_timeout(() => {
    114    assert_equals(called, false);
    115    t.done();
    116  }, 0);
    117 }, "Thenable job for fulfilled promise should be skipped if it belongs to detached iframe");
    118 
    119 async_iframe_test((t, iframe) => {
    120  const p = iframe.contentWindow.eval(`Promise.reject(1);`);
    121 
    122  iframe.remove();
    123 
    124  let called = false;
    125 
    126  // A thenable job is created with the iframe's realm, retrieved from p.then
    127  // function.
    128  const p2 = Promise.resolve(p);
    129 
    130  p2.then(() => {}, function onRejected() {
    131    called = true;
    132  });
    133 
    134  t.step_timeout(() => {
    135    assert_equals(called, false);
    136    t.done();
    137  }, 0);
    138 }, "Thenable job for rejected promise should be skipped if it belongs to detached iframe");
    139 
    140 async_iframe_test((t, iframe) => {
    141  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
    142 
    143  iframe.remove();
    144 
    145  let called = false;
    146 
    147  // In contrast to Promise.resolve, Promise.reject doesn't create a thenable
    148  // job.
    149  const p2 = Promise.reject(p);
    150 
    151  p2.then(() => {}, function onRejected() {
    152    called = true;
    153  });
    154 
    155  t.step_timeout(() => {
    156    assert_equals(called, true);
    157    t.done();
    158  }, 0);
    159 }, "No job with detached iframe's realm should be used for Promise.reject on fulfilled promise");
    160 
    161 async_iframe_test((t, iframe) => {
    162  const p = iframe.contentWindow.eval(`Promise.reject(1);`);
    163 
    164  iframe.remove();
    165 
    166  let called = false;
    167 
    168  // In contrast to Promise.resolve, Promise.reject doesn't create a thenable
    169  // job.
    170  const p2 = Promise.reject(p);
    171 
    172  p2.then(() => {}, function onRejected() {
    173    called = true;
    174  });
    175 
    176  t.step_timeout(() => {
    177    assert_equals(called, true);
    178    t.done();
    179  }, 0);
    180 }, "No job with detached iframe's realm should be used for Promise.reject on rejected promise");
    181 
    182 async_iframe_test((t, iframe) => {
    183  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
    184 
    185  iframe.remove();
    186 
    187  let called = false;
    188 
    189  // Promise.prototype.then resolves the result capability's promise with the
    190  // handler's return value, and a thenable job is created with the iframe's
    191  // realm, retrieved from p.then function.
    192  const p2 = Promise.resolve(1).then(() => p);
    193 
    194  p2.then(function onFulfilled() {
    195    called = true;
    196  });
    197 
    198  t.step_timeout(() => {
    199    assert_equals(called, false);
    200    t.done();
    201  }, 0);
    202 }, "Thenable job created by reaction job for fulfillment should be skipped if it belongs to detached iframe");
    203 
    204 async_iframe_test((t, iframe) => {
    205  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
    206 
    207  iframe.remove();
    208 
    209  let called = false;
    210 
    211  // Promise.prototype.then resolves the result capability's promise with the
    212  // handler's return value, and a thenable job is created with the iframe's
    213  // realm, retrieved from p.then function.
    214  const p2 = Promise.reject(1).then(() => {}, () => p);
    215 
    216  p2.then(function onFulfilled() {
    217    called = true;
    218  });
    219 
    220  t.step_timeout(() => {
    221    assert_equals(called, false);
    222    t.done();
    223  }, 0);
    224 }, "Thenable job created by reaction job for rejection should be skipped if it belongs to detached iframe");
    225 
    226 async_iframe_test((t, iframe) => {
    227  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
    228 
    229  iframe.remove();
    230 
    231  let called = false;
    232 
    233  // Promise.all internally performs Promise.resolve, and a thenable job
    234  // is created with the iframe's realm, retrieved from p.then function.
    235  const p2 = Promise.all([p]);
    236 
    237  p2.then(function onFulfilled() {
    238    called = true;
    239  });
    240 
    241  t.step_timeout(() => {
    242    assert_equals(called, false);
    243    t.done();
    244  }, 0);
    245 }, "Thenable job created by Promise.all should be skipped if it belongs to detached iframe");
    246 
    247 async_iframe_test((t, iframe) => {
    248  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
    249 
    250  iframe.remove();
    251 
    252  let called = false;
    253 
    254  // Promise.allSettled internally performs Promise.resolve, and a thenable job
    255  // is created with the iframe's realm, retrieved from p.then function.
    256  const p2 = Promise.allSettled([p]);
    257 
    258  p2.then(function onFulfilled() {
    259    called = true;
    260  });
    261 
    262  t.step_timeout(() => {
    263    assert_equals(called, false);
    264    t.done();
    265  }, 0);
    266 }, "Thenable job created by Promise.allSettled should be skipped if it belongs to detached iframe");
    267 
    268 async_iframe_test((t, iframe) => {
    269  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
    270 
    271  iframe.remove();
    272 
    273  let called = false;
    274 
    275  // Promise.any internally performs Promise.resolve, and a thenable job
    276  // is created with the iframe's realm, retrieved from p.then function.
    277  const p2 = Promise.any([p]);
    278 
    279  p2.then(function onFulfilled() {
    280    called = true;
    281  });
    282 
    283  t.step_timeout(() => {
    284    assert_equals(called, false);
    285    t.done();
    286  }, 0);
    287 }, "Thenable job created by Promise.any should be skipped if it belongs to detached iframe");
    288 
    289 async_iframe_test((t, iframe) => {
    290  const p = iframe.contentWindow.eval(`Promise.resolve(1);`);
    291 
    292  iframe.remove();
    293 
    294  let called = false;
    295 
    296  // Promise.race internally performs Promise.resolve, and a thenable job
    297  // is created with the iframe's realm, retrieved from p.then function.
    298  const p2 = Promise.race([p]);
    299 
    300  p2.then(function onFulfilled() {
    301    called = true;
    302  });
    303 
    304  t.step_timeout(() => {
    305    assert_equals(called, false);
    306    t.done();
    307  }, 0);
    308 }, "Thenable job created by Promise.race should be skipped if it belongs to detached iframe");
    309 </script>
    310 </body>