tor-browser

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

browser_dbg-editor-horizontal-scroll.js (8227B)


      1 /* This Source Code Form is subject to the terms of the Mozilla Public
      2 * License, v. 2.0. If a copy of the MPL was not distributed with this
      3 * file, You can obtain one at <http://mozilla.org/MPL/2.0/>. */
      4 
      5 // Tests that the editor scrolls correctly when pausing on location that
      6 // requires horizontal scrolling.
      7 
      8 "use strict";
      9 
     10 add_task(async function testHorizontalScrolling() {
     11  // Ensure having the default fixed height, as it can impact the number of displayed lines
     12  await pushPref("devtools.toolbox.footer.height", 250);
     13 
     14  // Also set a precise size for side panels, as it can impact the number of displayed columns
     15  await pushPref("devtools.debugger.start-panel-size", 300);
     16  await pushPref("devtools.debugger.end-panel-size", 300);
     17 
     18  // Strengthen the test by ensuring we always use the same Firefox window size.
     19  // Note that the inner size is the important one as that's the final space available for DevTools.
     20  // The outer size will be different based on OS/Environment.
     21  const expectedWidth = 1280;
     22  const expectedHeight = 1040;
     23  if (
     24    window.innerWidth != expectedWidth ||
     25    window.innerHeight != expectedHeight
     26  ) {
     27    info("Resize the top level window to match the expected size");
     28    const onResize = once(window, "resize");
     29    const deltaW = window.outerWidth - window.innerWidth;
     30    const deltaH = window.outerHeight - window.innerHeight;
     31    const originalWidth = window.outerWidth;
     32    const originalHeight = window.outerHeight;
     33    window.resizeTo(expectedWidth + deltaW, expectedHeight + deltaH);
     34    await onResize;
     35    registerCleanupFunction(() => {
     36      window.resizeTo(originalWidth, originalHeight);
     37    });
     38  }
     39  is(window.innerWidth, expectedWidth);
     40 
     41  const dbg = await initDebugger(
     42    "doc-editor-scroll.html",
     43    "scroll.js",
     44    "long.js"
     45  );
     46 
     47  await selectSource(dbg, "horizontal-scroll.js");
     48  const editor = getCMEditor(dbg);
     49 
     50  const global = editor.codeMirror.contentDOM.ownerGlobal;
     51  const font = new global.FontFace(
     52    "Ahem",
     53    "url(chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/examples/Ahem.ttf)"
     54  );
     55  const loadedFont = await font.load();
     56  global.document.fonts.add(loadedFont);
     57 
     58  is(global.devicePixelRatio, 1);
     59  is(global.browsingContext.top.window.devicePixelRatio, 1);
     60  global.browsingContext.top.overrideDPPX = 1;
     61  is(global.browsingContext.fullZoom, 1);
     62  is(global.browsingContext.textZoom, 1);
     63 
     64  // /!\ Change the Codemirror font to use a fixed font across all OSes
     65  // and always have the same number of characters displayed.
     66  // Note that this devtools mono makes the "o" characters almost invisible.
     67  editor.codeMirror.contentDOM.style.fontFamily = "Ahem";
     68  editor.codeMirror.contentDOM.style.fontSize = "10px";
     69  editor.codeMirror.contentDOM.style.lineHeight = "15px";
     70  editor.codeMirror.contentDOM.style.fontWeight = "normal";
     71  editor.codeMirror.contentDOM.style.fontStyle = "normal";
     72  editor.codeMirror.contentDOM.style.fontStretch = "normal";
     73  is(global.getComputedStyle(editor.codeMirror.contentDOM).fontFamily, "Ahem");
     74 
     75  await wait(1000);
     76 
     77  is(
     78    Math.round(editor.codeMirror.dom.getBoundingClientRect().width),
     79    679,
     80    "Sanity check to ensure we have a fixed editor width, so that we have the expected displayed columns"
     81  );
     82 
     83  // All the following methods lookup for first/last visible position in the current viewport.
     84  // Also note that the element at the returned position may only be partially visible.
     85  function getFirstVisibleColumn() {
     86    const { x, y } = editor.codeMirror.dom.getBoundingClientRect();
     87    const gutterWidth =
     88      editor.codeMirror.dom.querySelector(".cm-gutters").clientWidth;
     89    // This is hardcoded to match the second line, which is around 20px from the top.
     90    // Also append the gutter width as it would pick hidden columns displayed behind it
     91    const pos = editor.codeMirror.posAtCoords({
     92      x: x + gutterWidth + 2,
     93      y: y + 20,
     94    });
     95    // /!\ the column is 0-based while lines are 1-based
     96    return pos - editor.codeMirror.state.doc.lineAt(pos).from;
     97  }
     98  function getLastVisibleColumn() {
     99    const { x, y, width } = editor.codeMirror.dom.getBoundingClientRect();
    100    // This is hardcoded to match the second line, which is around 20px from the top
    101    const pos = editor.codeMirror.posAtCoords({ x: x + width, y: y + 20 });
    102    // /!\ the column is 0-based while lines are 1-based
    103    return pos - editor.codeMirror.state.doc.lineAt(pos).from;
    104  }
    105 
    106  info("Pause in middle of the screen, we should not scroll on pause");
    107  await addBreakpoint(dbg, "horizontal-scroll.js", 2, 25);
    108  invokeInTab("horizontal");
    109  await waitForPaused(dbg);
    110 
    111  const lastColumn = getLastVisibleColumn();
    112  is(lastColumn, 55);
    113  ok(
    114    isScrolledPositionVisible(dbg, 2, 1),
    115    "The 2nd line, first column is visible"
    116  );
    117  ok(
    118    isScrolledPositionVisible(dbg, 2, lastColumn - 1),
    119    "The 2nd line, column before the last is visible"
    120  );
    121  ok(
    122    !isScrolledPositionVisible(dbg, 2, lastColumn),
    123    "The last column is hidden"
    124  );
    125 
    126  info("Step to the last visible column, the editor shouldn't scroll");
    127  // There is one breakable position every two column.
    128  // We can see the column breakpoint for the column after the last visible one.
    129  // Setting a breakpoint on that column and pausing shouldn't cause to scroll the viewport.
    130  await addBreakpoint(dbg, "horizontal-scroll.js", 2, lastColumn);
    131  await resume(dbg);
    132  await waitForPaused(dbg);
    133 
    134  is(getLastVisibleColumn(), lastColumn, "We did not scroll horizontaly");
    135  ok(
    136    isScrolledPositionVisible(dbg, 2, lastColumn - 1),
    137    "The column before the last column is still visible"
    138  );
    139  ok(
    140    !isScrolledPositionVisible(dbg, 2, lastColumn),
    141    "The last colunm is still hidden"
    142  );
    143 
    144  info(
    145    "Step to the next column, and the editor should scroll it into the center"
    146  );
    147 
    148  info("Step into the next breakable column, the editor should now scroll");
    149  // Set a breakpoint on the first column that would cause a scroll
    150  // (there is one breakable position every two column)
    151  await addBreakpoint(dbg, "horizontal-scroll.js", 2, lastColumn + 2);
    152  await resume(dbg);
    153  await waitForPaused(dbg);
    154 
    155  const lastColumn2 = getLastVisibleColumn();
    156 
    157  is(lastColumn2, 74);
    158  ok(
    159    isScrolledPositionVisible(dbg, 2, lastColumn2),
    160    "The new last column is visible"
    161  );
    162  ok(
    163    !isScrolledPositionVisible(dbg, 2, lastColumn2 + 1),
    164    "The column after the last is hidden"
    165  );
    166  const firstColumn = getFirstVisibleColumn();
    167  is(firstColumn, 30);
    168  ok(
    169    !isScrolledPositionVisible(dbg, 2, firstColumn),
    170    "The new first column is partially visible and considered hidden"
    171  );
    172  ok(
    173    isScrolledPositionVisible(dbg, 2, firstColumn + 1),
    174    "The column after the first visible is visible"
    175  );
    176 
    177  await resume(dbg);
    178 });
    179 
    180 // Tests the limit of the no of column breakpoint markers in a minified source with a long line.
    181 add_task(async function testColumnBreakpointsLimitAfterHorizontalScroll() {
    182  // Keep the layout consistent
    183  await pushPref("devtools.debugger.end-panel-size", 300);
    184 
    185  const dbg = await initDebugger(
    186    "doc-large-sources.html",
    187    "codemirror-bundle.js"
    188  );
    189 
    190  info("Select the minified bundle and add a breakpoint");
    191  await selectSource(dbg, "codemirror-bundle.js");
    192  await addBreakpoint(dbg, "codemirror-bundle.js", 1);
    193 
    194  let columnBreakpointMarkers = await waitForAllElements(
    195    dbg,
    196    "columnBreakpoints"
    197  );
    198 
    199  is(
    200    columnBreakpointMarkers.length,
    201    100,
    202    "We have the expected limit of column breakpoint markers on the minified source"
    203  );
    204 
    205  info("Scroll horizintally far to the right of the file");
    206  await scrollEditorIntoView(dbg, 0, 300000);
    207 
    208  columnBreakpointMarkers = findAllElements(dbg, "columnBreakpoints");
    209  is(
    210    columnBreakpointMarkers.length,
    211    0,
    212    "There are no column breakpoint marker as the source has horizontally scrolled the viewport over the limit"
    213  );
    214 
    215  info("Scroll back to the start of the line");
    216  await scrollEditorIntoView(dbg, 0, 0);
    217 
    218  columnBreakpointMarkers = await waitForAllElements(dbg, "columnBreakpoints");
    219  is(
    220    columnBreakpointMarkers.length,
    221    100,
    222    "We still have the expected limit of column breakpoint markers on the minified source"
    223  );
    224 });