tor-browser

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

browser_editor_find_again.js (5982B)


      1 /* Any copyright is dedicated to the Public Domain.
      2   http://creativecommons.org/publicdomain/zero/1.0/ */
      3 
      4 "use strict";
      5 
      6 const L10N = new LocalizationHelper(
      7  "devtools/client/locales/sourceeditor.properties"
      8 );
      9 
     10 const { OS } = Services.appinfo;
     11 
     12 // On linux, getting immediately the selection's range here fails, returning
     13 const FIND_KEY = L10N.getStr("find.key");
     14 const FINDNEXT_KEY = L10N.getStr("findNext.key");
     15 const FINDPREV_KEY = L10N.getStr("findPrev.key");
     16 // the replace's key with the appropriate modifiers based on OS
     17 const REPLACE_KEY =
     18  OS == "Darwin"
     19    ? L10N.getStr("replaceAllMac.key")
     20    : L10N.getStr("replaceAll.key");
     21 
     22 // values like it's not selected – even if the selection is visible.
     23 // For the record, setting the selection's range immediately doesn't have
     24 // any effect.
     25 // It's like the <input> is not ready yet.
     26 // Therefore, we trigger the UI focus event to the <input>, waiting for the
     27 // response.
     28 // Using a timeout could also work, but that is more precise, ensuring also
     29 // the execution of the listeners added to the <input>'s focus.
     30 const dispatchAndWaitForFocus = target =>
     31  new Promise(resolve => {
     32    target.addEventListener(
     33      "focus",
     34      function () {
     35        resolve(target);
     36      },
     37      { once: true }
     38    );
     39 
     40    target.dispatchEvent(new UIEvent("focus"));
     41  });
     42 
     43 function openSearchBox(ed) {
     44  const edDoc = ed.container.contentDocument;
     45  const edWin = edDoc.defaultView;
     46 
     47  let input = edDoc.querySelector("input[type=search]");
     48  ok(!input, "search box closed");
     49 
     50  // The editor needs the focus to properly receive the `synthesizeKey`
     51  ed.focus();
     52 
     53  synthesizeKeyShortcut(FINDNEXT_KEY, edWin);
     54  input = edDoc.querySelector("input[type=search]");
     55  ok(input, "find again command key opens the search box");
     56 }
     57 
     58 function testFindAgain(ed, inputLine, expectCursor, isFindPrev = false) {
     59  const edDoc = ed.container.contentDocument;
     60  const edWin = edDoc.defaultView;
     61 
     62  const input = edDoc.querySelector("input[type=search]");
     63  input.value = inputLine;
     64 
     65  // Ensure the input has the focus before send the key – necessary on Linux,
     66  // it seems that during the tests can be lost
     67  input.focus();
     68 
     69  if (isFindPrev) {
     70    synthesizeKeyShortcut(FINDPREV_KEY, edWin);
     71  } else {
     72    synthesizeKeyShortcut(FINDNEXT_KEY, edWin);
     73  }
     74 
     75  ch(
     76    ed.getCursor(),
     77    expectCursor,
     78    "find: " + inputLine + " expects cursor: " + expectCursor.toSource()
     79  );
     80 }
     81 
     82 const testSearchBoxTextIsSelected = async function (ed) {
     83  const edDoc = ed.container.contentDocument;
     84  const edWin = edDoc.defaultView;
     85 
     86  let input = edDoc.querySelector("input[type=search]");
     87  ok(input, "search box is opened");
     88 
     89  // Ensure the input has the focus before send the key – necessary on Linux,
     90  // it seems that during the tests can be lost
     91  input.focus();
     92 
     93  // Close search box
     94  EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
     95 
     96  input = edDoc.querySelector("input[type=search]");
     97  ok(!input, "search box is closed");
     98 
     99  // Re-open the search box
    100  synthesizeKeyShortcut(FIND_KEY, edWin);
    101 
    102  input = edDoc.querySelector("input[type=search]");
    103  ok(input, "find command key opens the search box");
    104 
    105  await dispatchAndWaitForFocus(input);
    106 
    107  let { selectionStart, selectionEnd, value } = input;
    108 
    109  ok(
    110    selectionStart === 0 && selectionEnd === value.length,
    111    "search box's text is selected when re-opened"
    112  );
    113 
    114  // Removing selection
    115  input.setSelectionRange(0, 0);
    116 
    117  synthesizeKeyShortcut(FIND_KEY, edWin);
    118 
    119  ({ selectionStart, selectionEnd } = input);
    120 
    121  ok(
    122    selectionStart === 0 && selectionEnd === value.length,
    123    "search box's text is selected when find key is pressed"
    124  );
    125 
    126  // Close search box
    127  EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
    128 };
    129 
    130 const testReplaceBoxTextIsSelected = async function (ed) {
    131  const edDoc = ed.container.contentDocument;
    132  const edWin = edDoc.defaultView;
    133 
    134  let input = edDoc.querySelector(".CodeMirror-dialog > input");
    135  ok(!input, "dialog box with replace is closed");
    136 
    137  // The editor needs the focus to properly receive the `synthesizeKey`
    138  ed.focus();
    139 
    140  synthesizeKeyShortcut(REPLACE_KEY, edWin);
    141 
    142  input = edDoc.querySelector(".CodeMirror-dialog > input");
    143  ok(input, "dialog box with replace is opened");
    144 
    145  input.value = "line 5";
    146 
    147  // Ensure the input has the focus before send the key – necessary on Linux,
    148  // it seems that during the tests can be lost
    149  input.focus();
    150 
    151  await dispatchAndWaitForFocus(input);
    152 
    153  let { selectionStart, selectionEnd, value } = input;
    154 
    155  ok(
    156    !(selectionStart === 0 && selectionEnd === value.length),
    157    "Text in dialog box is not selected"
    158  );
    159 
    160  synthesizeKeyShortcut(REPLACE_KEY, edWin);
    161 
    162  ({ selectionStart, selectionEnd } = input);
    163 
    164  ok(
    165    selectionStart === 0 && selectionEnd === value.length,
    166    "dialog box's text is selected when replace key is pressed"
    167  );
    168 
    169  // Close dialog box
    170  EventUtils.synthesizeKey("VK_ESCAPE", {}, edWin);
    171 };
    172 
    173 add_task(async function () {
    174  const { ed, win } = await setup();
    175 
    176  ed.setText(
    177    [
    178      "// line 1",
    179      "//  line 2",
    180      "//   line 3",
    181      "//    line 4",
    182      "//     line 5",
    183    ].join("\n")
    184  );
    185 
    186  await promiseWaitForFocus();
    187 
    188  openSearchBox(ed);
    189 
    190  const testVectors = [
    191    // Starting here expect data needs to get updated for length changes to
    192    // "textLines" above.
    193    ["line", { line: 0, ch: 7 }],
    194    ["line", { line: 1, ch: 8 }],
    195    ["line", { line: 2, ch: 9 }],
    196    ["line", { line: 3, ch: 10 }],
    197    ["line", { line: 4, ch: 11 }],
    198    ["ne 3", { line: 2, ch: 11 }],
    199    ["line 1", { line: 0, ch: 9 }],
    200    // Testing find prev
    201    ["line", { line: 4, ch: 11 }, true],
    202    ["line", { line: 3, ch: 10 }, true],
    203    ["line", { line: 2, ch: 9 }, true],
    204    ["line", { line: 1, ch: 8 }, true],
    205    ["line", { line: 0, ch: 7 }, true],
    206  ];
    207 
    208  for (const v of testVectors) {
    209    await testFindAgain(ed, ...v);
    210  }
    211 
    212  await testSearchBoxTextIsSelected(ed);
    213 
    214  await testReplaceBoxTextIsSelected(ed);
    215 
    216  teardown(ed, win);
    217 });