tor-browser

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

popover-top-layer-nesting.js (5243B)


      1 function createTopLayerElement(t,topLayerType) {
      2  let element, show, showing;
      3  switch (topLayerType) {
      4    case 'dialog':
      5      element = document.createElement('dialog');
      6      show = () => element.showModal();
      7      showing = () => element.matches(':modal');
      8      break;
      9    case 'fullscreen':
     10      element = document.createElement('div');
     11      show = async (topmostElement) => {
     12        // Be sure to add user activation to the topmost visible target:
     13        await blessTopLayer(topmostElement);
     14        await element.requestFullscreen();
     15      };
     16      showing = () => document.fullscreenElement === element;
     17      break;
     18    default:
     19      assert_unreached('Invalid top layer type');
     20  }
     21  t.add_cleanup(() => element.remove());
     22  return {element,show,showing};
     23 }
     24 function runTopLayerTests(testCases, testAnchorAttribute) {
     25  testAnchorAttribute = testAnchorAttribute || false;
     26  testCases.forEach(test => {
     27    const description = test.firstChild.data.trim();
     28    assert_equals(test.querySelectorAll('.target').length,1,'There should be exactly one target');
     29    const target = test.querySelector('.target');
     30    assert_true(!!target,'Invalid test case');
     31    const popovers = Array.from(test.querySelectorAll('[popover]'));
     32    assert_true(popovers.length > 0,'No popovers found');
     33    ['dialog','fullscreen'].forEach(topLayerType => {
     34      promise_test(async t => {
     35        const {element,show,showing} = createTopLayerElement(t,topLayerType);
     36        target.appendChild(element);
     37 
     38        // Show the popovers.
     39        t.add_cleanup(() => popovers.forEach(popover => popover.hidePopover()));
     40        popovers.forEach(popover => popover.showPopover());
     41        popovers.forEach(popover => assert_true(popover.matches(':popover-open'),'All popovers should be open'));
     42 
     43        // Activate the top layer element.
     44        await show(popovers[popovers.length-1]);
     45        assert_true(showing());
     46        popovers.forEach(popover => assert_equals(popover.matches(':popover-open'),popover.dataset.stayOpen==='true','Incorrect behavior'));
     47 
     48        // Add another popover within the top layer element and make sure entire stack stays open.
     49        const newPopover = document.createElement('div');
     50        t.add_cleanup(() => newPopover.remove());
     51        newPopover.popover = 'hint';
     52        element.appendChild(newPopover);
     53        popovers.forEach(popover => assert_equals(popover.matches(':popover-open'),popover.dataset.stayOpen==='true','Adding another popover shouldn\'t change anything'));
     54        assert_true(showing(),'top layer element should still be top layer');
     55        newPopover.showPopover();
     56        assert_true(newPopover.matches(':popover-open'));
     57        popovers.forEach(popover => assert_equals(popover.matches(':popover-open'),popover.dataset.stayOpen==='true','Showing the popover shouldn\'t change anything'));
     58        assert_true(showing(),'top layer element should still be top layer');
     59      },`${description} with ${topLayerType}`);
     60 
     61      promise_test(async t => {
     62        const {element,show,showing} = createTopLayerElement(t,topLayerType);
     63        element.popover = 'hint';
     64        target.appendChild(element);
     65 
     66        // Show the popovers.
     67        t.add_cleanup(() => popovers.forEach(popover => popover.hidePopover()));
     68        popovers.forEach(popover => popover.showPopover());
     69        popovers.forEach(popover => assert_true(popover.matches(':popover-open'),'All popovers should be open'));
     70        const targetWasOpenPopover = target.matches(':popover-open');
     71 
     72        // Show the top layer element as a popover first.
     73        element.showPopover();
     74        assert_true(element.matches(':popover-open'),'element should be open as a popover');
     75        assert_equals(target.matches(':popover-open'),targetWasOpenPopover,'target shouldn\'t change popover state');
     76 
     77        try {
     78          await show(element);
     79          assert_unreached('It is an error to activate a top layer element that is already a showing popover');
     80        } catch (e) {
     81          // We expect an InvalidStateError for dialogs, and a TypeError for fullscreens.
     82          // Anything else should fall through to the test harness.
     83          if (e.name !== 'InvalidStateError' && e.name !== 'TypeError') {
     84            throw e;
     85          }
     86        }
     87      },`${description} with ${topLayerType}, top layer element *is* a popover`);
     88 
     89      if (testAnchorAttribute) {
     90        promise_test(async t => {
     91          const {element,show,showing} = createTopLayerElement(t,topLayerType);
     92          element.anchorElement = target;
     93          document.body.appendChild(element);
     94 
     95          // Show the popovers.
     96          t.add_cleanup(() => popovers.forEach(popover => popover.hidePopover()));
     97          popovers.forEach(popover => popover.showPopover());
     98          popovers.forEach(popover => assert_true(popover.matches(':popover-open'),'All popovers should be open'));
     99 
    100          // Activate the top layer element.
    101          await show(popovers[popovers.length-1]);
    102          assert_true(showing());
    103          popovers.forEach(popover => assert_equals(popover.matches(':popover-open'),popover.dataset.stayOpen==='true','Incorrect behavior'));
    104        },`${description} with ${topLayerType}, anchor attribute`);
    105      }
    106    });
    107  });
    108 }