tor-browser

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

popover-invoking-attribute.js (5715B)


      1 const actionReflectionLogic = (action) => {
      2  switch (action?.toLowerCase()) {
      3    case "show": return "show";
      4    case "hide": return "hide";
      5    default: return "toggle";
      6  }
      7 }
      8 const noActivationLogic = (action) => {
      9  return "none";
     10 }
     11 function makeElementWithType(element,type) {
     12  return (test) => {
     13    const el = Object.assign(document.createElement(element),{type});
     14    document.body.appendChild(el);
     15    test.add_cleanup(() => el.remove());
     16    return el;
     17  };
     18 }
     19 const supportedButtonTypes = ['button','reset','submit',''].map(type => {
     20  return   {
     21    name: `<button type="${type}">`,
     22    makeElement: makeElementWithType('button',type),
     23    invokeFn: el => {el.focus(); el.click()},
     24    getExpectedLogic: actionReflectionLogic,
     25  };
     26 });
     27 const supportedInputButtonTypes = ['button','reset','submit','image'].map(type => {
     28  return   {
     29    name: `<input type="${type}">`,
     30    makeElement: makeElementWithType('input',type),
     31    invokeFn: el => {el.focus(); el.click()},
     32    getExpectedLogic: actionReflectionLogic,
     33  };
     34 });
     35 const unsupportedTypes = ['text','email','password','search','tel','url','checkbox','radio','range','file','color','date','datetime-local','month','time','week','number'].map(type => {
     36  return {
     37    name: `<input type="${type}">`,
     38    makeElement: makeElementWithType('input',type),
     39    invokeFn: (el) => {el.focus();},
     40    getExpectedLogic: noActivationLogic, // None of these support popover invocation
     41  };
     42 });
     43 const invokers = [
     44  ...supportedButtonTypes,
     45  ...supportedInputButtonTypes,
     46  ...unsupportedTypes,
     47 ];
     48 function runPopoverInvokerTests(popoverTypes) {
     49  window.addEventListener('load', () => {
     50    popoverTypes.forEach(type => {
     51      invokers.forEach(testcase => {
     52        ["toggle","hide","show","ShOw","garbage",null,undefined].forEach(action => {
     53          [false,true].forEach(use_idl_for_target => {
     54            [false,true].forEach(use_idl_for_action => {
     55              promise_test(async test => {
     56                const popover = Object.assign(document.createElement('div'),{popover: type, id: 'my-popover'});
     57                assert_equals(popover.popover,type,'reflection');
     58                const invoker = testcase.makeElement(test);
     59                if (use_idl_for_target) {
     60                  invoker.popoverTargetElement = popover;
     61                  assert_equals(invoker.getAttribute('popovertarget'),'','attribute value');
     62                } else {
     63                  invoker.setAttribute('popovertarget',popover.id);
     64                }
     65                if (use_idl_for_action) {
     66                  invoker.popoverTargetAction = action;
     67                  assert_equals(invoker.getAttribute('popovertargetaction'),String(action),'action reflection');
     68                } else {
     69                  invoker.setAttribute('popovertargetaction',action);
     70                }
     71                assert_true(!document.getElementById(popover.id));
     72                assert_equals(invoker.popoverTargetElement,null,'targetElement should be null before the popover is in the document');
     73                assert_equals(invoker.popoverTargetAction,actionReflectionLogic(action),'action should be correct immediately');
     74                document.body.appendChild(popover);
     75                test.add_cleanup(() => {popover.remove();});
     76                assert_equals(invoker.popoverTargetElement,popover,'target element should be returned once it\'s in the document');
     77                assert_false(popover.matches(':popover-open'));
     78                await testcase.invokeFn(invoker);
     79                assert_equals(document.activeElement,invoker,'Focus should end up on the invoker');
     80                expectedBehavior = testcase.getExpectedLogic(action);
     81                switch (expectedBehavior) {
     82                  case "toggle":
     83                  case "show":
     84                    assert_true(popover.matches(':popover-open'),'Toggle or show should show the popover');
     85                    popover.hidePopover(); // Hide the popover
     86                    break;
     87                  case "hide":
     88                  case "none":
     89                    assert_false(popover.matches(':popover-open'),'Hide or none should leave the popover hidden');
     90                    break;
     91                  default:
     92                    assert_unreached();
     93                }
     94                if (expectedBehavior === "none") {
     95                  // If no behavior is expected, then there is nothing left to test. Even re-focusing
     96                  // a control that has no expected behavior may hide an open popover via light dismiss.
     97                  return;
     98                }
     99                assert_false(popover.matches(':popover-open'));
    100                popover.showPopover(); // Show the popover directly
    101                assert_equals(document.activeElement,invoker,'The popover should not shift focus');
    102                assert_true(popover.matches(':popover-open'));
    103                await testcase.invokeFn(invoker);
    104                switch (expectedBehavior) {
    105                  case "toggle":
    106                  case "hide":
    107                    assert_false(popover.matches(':popover-open'),'Toggle or hide should hide the popover');
    108                    break;
    109                  case "show":
    110                    assert_true(popover.matches(':popover-open'),'Show should leave the popover showing');
    111                    break;
    112                  default:
    113                    assert_unreached();
    114                }
    115              },`Test ${testcase.name}, action=${action}, ${use_idl_for_target ? "popoverTarget IDL" : "popovertarget attr"}, ${use_idl_for_action ? "popoverTargetAction IDL" : "popovertargetaction attr"}, with popover=${type}`);
    116            });
    117          });
    118        });
    119      });
    120    });
    121  });
    122 }