tor-browser

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

test_abs_positioner_positioning_elements.html (9076B)


      1 <!DOCTYPE HTML>
      2 <html>
      3 <head>
      4  <title>Test for positioners of absolute positioned elements</title>
      5  <script src="/tests/SimpleTest/SimpleTest.js"></script>
      6  <script src="/tests/SimpleTest/EventUtils.js"></script>
      7  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
      8  <style>
      9  #target {
     10    background-color: green;
     11  }
     12  </style>
     13 </head>
     14 <body>
     15 <p id="display"></p>
     16 <div id="content" contenteditable style="height: 200px; width: 200px;"></div>
     17 <div id="clickaway" style="position: absolute; top: 250px; width: 10px; height: 10px; z-index: 100;"></div>
     18 <img src="green.png"><!-- for ensuring to load the image at first test of <img> case -->
     19 <pre id="test">
     20 <script type="application/javascript">
     21 "use strict";
     22 
     23 SimpleTest.waitForExplicitFinish();
     24 SimpleTest.waitForFocus(async function() {
     25  document.execCommand("enableAbsolutePositionEditing", false, true);
     26  ok(document.queryCommandState("enableAbsolutePositionEditing"),
     27     "Absolute positioned element editor should be enabled by the call of execCommand");
     28 
     29  let outOfEditor = document.getElementById("clickaway");
     30 
     31  function cancel(e) { e.stopPropagation(); }
     32  let content = document.getElementById("content");
     33  content.addEventListener("mousedown", cancel);
     34  content.addEventListener("mousemove", cancel);
     35  content.addEventListener("mouseup", cancel);
     36 
     37  async function waitForSelectionChange() {
     38    return new Promise(resolve => {
     39      document.addEventListener("selectionchange", () => {
     40        resolve();
     41      }, {once: true});
     42    });
     43  }
     44 
     45  async function doTest(aDescription, aInnerHTML) {
     46    content.innerHTML = aInnerHTML;
     47    let description = aDescription + ": ";
     48    let target = document.getElementById("target");
     49    target.style.position = "absolute";
     50 
     51    async function testPositioner(aDeltaX, aDeltaY) {
     52      ok(true, description + "testPositioner(" + [aDeltaX, aDeltaY].join(", ") + ")");
     53 
     54      // Reset the position of the target.
     55      target.style.top = "50px";
     56      target.style.left = "50px";
     57 
     58      // Click on the target to show the positioner.
     59      let promiseSelectionChangeEvent = waitForSelectionChange();
     60      synthesizeMouseAtCenter(target, {});
     61      await promiseSelectionChangeEvent;
     62 
     63      let rect = target.getBoundingClientRect();
     64 
     65      ok(target.hasAttribute("_moz_abspos"),
     66         description + "While enableAbsolutePositionEditing is enabled, the positioner should appear");
     67 
     68      // left is abs positioned element's left + margin-left + border-left-width + 12.
     69      // XXX Perhaps, we need to add border-left-width here if you add new test to have thick border.
     70      const kPositionerX = 18;
     71      // top is abs positioned element's top + margin-top + border-top-width - 14.
     72      // XXX Perhaps, we need to add border-top-width here if you add new test to have thick border.
     73      const kPositionerY = -7;
     74 
     75      let beforeInputEventExpected = true;
     76      let beforeInputFired = false;
     77      let inputEventExpected = true;
     78      let inputFired = false;
     79      function onBeforeInput(aEvent) {
     80        beforeInputFired = true;
     81        aEvent.preventDefault();  // For making sure this preventDefault() call does not cancel the operation.
     82        if (!beforeInputEventExpected) {
     83          ok(false, '"beforeinput" event should not be fired after stopping resizing');
     84          return;
     85        }
     86        ok(aEvent instanceof InputEvent,
     87           '"beforeinput" event for position changing of absolute position should be dispatched with InputEvent interface');
     88        is(aEvent.cancelable, false,
     89           '"beforeinput" event for position changing of absolute position container should not be cancelable');
     90        is(aEvent.bubbles, true,
     91           '"beforeinput" event for position changing of absolute position should always bubble');
     92        is(aEvent.inputType, "",
     93           'inputType of "beforeinput" event for position changing of absolute position should be empty string');
     94        is(aEvent.data, null,
     95           'data of "beforeinput" event for position changing of absolute position should be null');
     96        is(aEvent.dataTransfer, null,
     97           'dataTransfer of "beforeinput" event for position changing of absolute position should be null');
     98        let targetRanges = aEvent.getTargetRanges();
     99        let selection = document.getSelection();
    100        is(targetRanges.length, selection.rangeCount,
    101           'getTargetRanges() of "beforeinput" event for position changing of absolute position should return selection ranges');
    102        if (targetRanges.length === selection.rangeCount) {
    103          for (let i = 0; i < selection.rangeCount; i++) {
    104            let range = selection.getRangeAt(i);
    105            is(targetRanges[i].startContainer, range.startContainer,
    106               `startContainer of getTargetRanges()[${i}] of "beforeinput" event for position changing of absolute position does not match`);
    107            is(targetRanges[i].startOffset, range.startOffset,
    108               `startOffset of getTargetRanges()[${i}] of "beforeinput" event for position changing of absolute position does not match`);
    109            is(targetRanges[i].endContainer, range.endContainer,
    110               `endContainer of getTargetRanges()[${i}] of "beforeinput" event for position changing of absolute position does not match`);
    111            is(targetRanges[i].endOffset, range.endOffset,
    112               `endOffset of getTargetRanges()[${i}] of "beforeinput" event for position changing of absolute position does not match`);
    113          }
    114        }
    115      }
    116      function onInput(aEvent) {
    117        inputFired = true;
    118        if (!inputEventExpected) {
    119          ok(false, '"input" event should not be fired after stopping resizing');
    120          return;
    121        }
    122        ok(aEvent instanceof InputEvent,
    123           '"input" event for position changing of absolute position container should be dispatched with InputEvent interface');
    124        is(aEvent.cancelable, false,
    125           '"input" event for position changing of absolute position container should be never cancelable');
    126        is(aEvent.bubbles, true,
    127           '"input" event for position changing of absolute position should always bubble');
    128        is(aEvent.inputType, "",
    129           'inputType of "input" event for position changing of absolute position should be empty string');
    130        is(aEvent.data, null,
    131           'data of "input" event for position changing of absolute position should be null');
    132        is(aEvent.dataTransfer, null,
    133           'dataTransfer of "input" event for position changing of absolute position should be null');
    134        is(aEvent.getTargetRanges().length, 0,
    135           'getTargetRanges() of "input" event for position changing of absolute position should return empty array');
    136      }
    137 
    138      content.addEventListener("beforeinput", onBeforeInput);
    139      content.addEventListener("input", onInput);
    140 
    141      // Click on the positioner.
    142      synthesizeMouse(target, kPositionerX, kPositionerY, {type: "mousedown"});
    143      // Drag it delta pixels.
    144      synthesizeMouse(target, kPositionerX + aDeltaX, kPositionerY + aDeltaY, {type: "mousemove"});
    145      // Release the mouse button
    146      synthesizeMouse(target, kPositionerX + aDeltaX, kPositionerY + aDeltaY, {type: "mouseup"});
    147 
    148      ok(beforeInputFired, `${description}"beforeinput" event should be fired by moving absolute position container`);
    149      ok(inputFired, `${description}"input" event should be fired by moving absolute position container`);
    150 
    151      beforeInputEventExpected = false;
    152      inputEventExpected = false;
    153 
    154      // Move the mouse delta more pixels to the same direction to make sure that the
    155      // positioning operation has stopped.
    156      synthesizeMouse(target, kPositionerX + aDeltaX * 2, kPositionerY + aDeltaY * 2, {type: "mousemove"});
    157      // Click outside of the image to hide the positioner.
    158      synthesizeMouseAtCenter(outOfEditor, {});
    159 
    160      content.removeEventListener("beforeinput", onBeforeInput);
    161      content.removeEventListener("input", onInput);
    162 
    163      // Get the new dimensions for the absolute positioned element.
    164      let newRect = target.getBoundingClientRect();
    165      isfuzzy(newRect.x, rect.x + aDeltaX, 1, description + "The left should be increased by " + aDeltaX + " pixels");
    166      isfuzzy(newRect.y, rect.y + aDeltaY, 1, description + "The top should be increased by " + aDeltaY + "pixels");
    167    }
    168 
    169    await testPositioner( 10, 10);
    170    await testPositioner( 10, -10);
    171    await testPositioner(-10, 10);
    172    await testPositioner(-10, -10);
    173  }
    174 
    175  const kTests = [
    176    { description: "Positioner for <img>",
    177      innerHTML: "<img id=\"target\" src=\"green.png\">",
    178    },
    179    { description: "Positioner for <table>",
    180      innerHTML: "<table id=\"target\" border><tr><td>cell</td><td>cell</td></tr></table>",
    181    },
    182    { description: "Positioner for <div>",
    183      innerHTML: "<div id=\"target\">div element</div>",
    184    },
    185  ];
    186 
    187  for (const kTest of kTests) {
    188    await doTest(kTest.description, kTest.innerHTML);
    189  }
    190  content.innerHTML = "";
    191  SimpleTest.finish();
    192 });
    193 </script>
    194 </pre>
    195 </body>
    196 </html>