tor-browser

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

frames.https.html (8295B)


      1 <!DOCTYPE html>
      2 <meta charset=utf-8>
      3 <title>Web Locks API: Frames</title>
      4 <link rel=help href="https://w3c.github.io/web-locks/">
      5 <script src="/resources/testharness.js"></script>
      6 <script src="/resources/testharnessreport.js"></script>
      7 <script src="resources/helpers.js"></script>
      8 <style>iframe { display: none; }</style>
      9 <script>
     10 'use strict';
     11 
     12 promise_test(async t => {
     13  assert_implements(navigator.locks);
     14  const res = uniqueName(t);
     15 
     16  const frame = await iframe('resources/iframe.html');
     17  t.add_cleanup(() => { frame.remove(); });
     18 
     19  const lock_id = (await postToFrameAndWait(
     20    frame, {op: 'request', name: res, mode: 'shared'})).lock_id;
     21 
     22  await navigator.locks.request(res, {mode: 'shared'}, async lock => {
     23    await postToFrameAndWait(frame, {op: 'release', lock_id});
     24  });
     25 
     26 }, 'Window and Frame - shared mode');
     27 
     28 promise_test(async t => {
     29  assert_implements(navigator.locks);
     30  const res = uniqueName(t);
     31 
     32  const frame = await iframe('resources/iframe.html');
     33  t.add_cleanup(() => { frame.remove(); });
     34 
     35  // frame acquires the lock.
     36  const lock_id = (await postToFrameAndWait(
     37    frame, {op: 'request', name: res})).lock_id;
     38 
     39  // This request should be blocked.
     40  let lock_granted = false;
     41  const blocked = navigator.locks.request(res, lock => { lock_granted = true; });
     42 
     43  // Verify that we can't get it.
     44  let available = undefined;
     45  await navigator.locks.request(
     46    res, {ifAvailable: true}, lock => { available = lock !== null; });
     47  assert_false(available);
     48  assert_false(lock_granted);
     49 
     50  // Ask the frame to release it.
     51  await postToFrameAndWait(frame, {op: 'release', lock_id});
     52 
     53  await blocked;
     54  // Now we've got it.
     55  assert_true(lock_granted);
     56 }, 'Window and Frame - exclusive mode');
     57 
     58 promise_test(async t => {
     59  assert_implements(navigator.locks);
     60  const res = uniqueName(t);
     61 
     62  const frame1 = await iframe('resources/iframe.html');
     63  const frame2 = await iframe('resources/iframe.html');
     64 
     65  // frame1 acquires the lock.
     66  const lock_id = (await postToFrameAndWait(
     67    frame1, {op: 'request', name: res})).lock_id;
     68 
     69  // frame2's request should be blocked.
     70  let lock_granted = false;
     71  const blocked = postToFrameAndWait(
     72    frame2, {op: 'request', name: res});
     73  blocked.then(f => { lock_granted = true; });
     74 
     75  // Verify that frame2 can't get it.
     76  assert_true((await postToFrameAndWait(frame2, {
     77    op: 'request', name: res, ifAvailable: true
     78  })).failed, 'Lock request should have failed');
     79  assert_false(lock_granted);
     80 
     81  // Ask frame1 to release it.
     82  await postToFrameAndWait(frame1, {op: 'release', lock_id});
     83 
     84  await blocked;
     85  // Now frame2 can get it.
     86  assert_true(lock_granted);
     87  frame1.parentElement.removeChild(frame1);
     88  frame2.parentElement.removeChild(frame2);
     89 }, 'Frame and Frame - exclusive mode');
     90 
     91 promise_test(async t => {
     92  assert_implements(navigator.locks);
     93  const res = uniqueName(t);
     94 
     95  const frame = await iframe('resources/iframe.html');
     96 
     97  // Frame acquires the lock.
     98  await postToFrameAndWait(frame, {op: 'request', name: res});
     99 
    100  // This request should be blocked.
    101  let lock_granted = false;
    102  const blocked = navigator.locks.request(
    103    res, lock => { lock_granted = true; });
    104 
    105  // Verify that we can't get it.
    106  let available = undefined;
    107  await navigator.locks.request(
    108    res, {ifAvailable: true}, lock => { available = lock !== null; });
    109  assert_false(available);
    110  assert_false(lock_granted);
    111 
    112  // Implicitly release it by terminating the frame.
    113  frame.remove();
    114  await blocked;
    115  // Now we've got it.
    116  assert_true(lock_granted);
    117 
    118 }, 'Terminated Frame with held lock');
    119 
    120 promise_test(async t => {
    121  assert_implements(navigator.locks);
    122  const res = uniqueName(t);
    123 
    124  const frame = await iframe('resources/iframe.html');
    125 
    126  // Frame acquires the lock.
    127  await postToFrameAndWait(frame, {op: 'request', name: res});
    128 
    129  // This request should be blocked.
    130  let lock_granted = false;
    131  const blocked = navigator.locks.request(
    132    res, lock => { lock_granted = true; });
    133 
    134  // Verify that we can't get it.
    135  let available = undefined;
    136  await navigator.locks.request(
    137    res, {ifAvailable: true}, lock => { available = lock !== null; });
    138  assert_false(available);
    139  assert_false(lock_granted);
    140 
    141  // Implicitly release it by navigating the frame.
    142  frame.src = 'about:blank';
    143  await blocked;
    144  // Now we've got it.
    145  assert_true(lock_granted);
    146 
    147 }, 'Navigated Frame with held lock');
    148 
    149 promise_test(async t => {
    150  assert_implements(navigator.locks);
    151  const res = uniqueName(t);
    152 
    153  // frame1 requests and holds res - should be granted immediately.
    154  // frame2 requests res - should be blocked.
    155  // frame3 requests res - should be blocked.
    156  // frame2 is navigated.
    157  // frame1 releases res.
    158  // frame3's request should be granted.
    159 
    160  const frame1 = await iframe('resources/iframe.html');
    161  const frame2 = await iframe('resources/iframe.html');
    162  const frame3 = await iframe('resources/iframe.html');
    163  t.add_cleanup(() => { frame1.remove(); });
    164  t.add_cleanup(() => { frame2.remove(); });
    165  t.add_cleanup(() => { frame3.remove(); });
    166 
    167  // frame1 requests and holds res - should be granted immediately.
    168  const lock_id = (await postToFrameAndWait(
    169    frame1, {op: 'request', name: res})).lock_id;
    170 
    171  // frame2 requests res - should be blocked.
    172  // (don't attach listeners as they will keep the frame alive)
    173  frame2.contentWindow.postMessage({op: 'request', name: res}, '*');
    174 
    175  // frame3 requests res - should be blocked.
    176  let lock_granted = false;
    177  const blocked = postToFrameAndWait(frame3, {op: 'request', name: res});
    178  blocked.then(f => { lock_granted = true; });
    179 
    180  // Verify that frame3 can't get it.
    181  assert_true((await postToFrameAndWait(frame3, {
    182    op: 'request', name: res, ifAvailable: true
    183  })).failed, 'Lock request should have failed');
    184  assert_false(lock_granted);
    185 
    186  // Navigate frame2.
    187  frame2.src = 'about:blank';
    188 
    189  // frame1 releases lock
    190  await postToFrameAndWait(frame1, {op: 'release', lock_id});
    191 
    192  // frame3's request should be granted.
    193  await blocked;
    194  assert_true(lock_granted);
    195 
    196 }, 'Navigated Frame with pending request');
    197 
    198 promise_test(async t => {
    199  assert_implements(navigator.locks);
    200  const res = uniqueName(t);
    201 
    202  // frame1 requests and holds res - should be granted immediately.
    203  // frame2 requests res - should be blocked.
    204  // frame3 requests res - should be blocked.
    205  // frame2 is removed.
    206  // frame1 drops lock.
    207  // frame3's request should be granted.
    208 
    209  const frame1 = await iframe('resources/iframe.html');
    210  const frame2 = await iframe('resources/iframe.html');
    211  const frame3 = await iframe('resources/iframe.html');
    212  t.add_cleanup(() => { frame1.remove(); });
    213  t.add_cleanup(() => { frame3.remove(); });
    214 
    215  // frame1 requests and holds res - should be granted immediately.
    216  const lock_id = (await postToFrameAndWait(
    217    frame1, {op: 'request', name: res})).lock_id;
    218 
    219  // frame2 requests res - should be blocked.
    220  // (don't attach listeners as they will keep the frame alive)
    221  frame2.contentWindow.postMessage({op: 'request', name: res}, '*');
    222 
    223  // frame3 requests res - should be blocked.
    224  let lock_granted = false;
    225  const blocked = postToFrameAndWait(frame3, {op: 'request', name: res});
    226  blocked.then(f => { lock_granted = true; });
    227 
    228  // So frame3 can't get it
    229  assert_true((await postToFrameAndWait(frame3, {
    230    op: 'request', name: res, ifAvailable: true
    231  })).failed, 'Lock request should have failed');
    232  assert_false(lock_granted);
    233 
    234  // Remove frame2.
    235  frame2.remove();
    236 
    237  // frame1 releases lock
    238  await postToFrameAndWait(frame1, {op: 'release', lock_id});
    239 
    240  // frame3's request should be granted.
    241  await blocked;
    242  assert_true(lock_granted);
    243 
    244 }, 'Removed Frame with pending request');
    245 
    246 promise_test(async t => {
    247  assert_implements(navigator.locks);
    248  const res = uniqueName(t);
    249 
    250  const frame = await iframe('about:blank');
    251 
    252  // Remove a frame while it is in the process of requesting a lock.
    253  // The promise returned by `request` will never resolve since its frame no
    254  // longer exists, but the lock should still be released.
    255  await new Promise(resolve => {
    256    frame.contentWindow.navigator.locks.request(res, () => {
    257      frame.remove();
    258      resolve();
    259    });
    260  });
    261 
    262  assert_false((await navigator.locks.query()).held.includes(res));
    263 }, 'Removed Frame as lock is granted');
    264 
    265 </script>