tor-browser

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

browser_976792_insertNodeInWindow.js (17337B)


      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 "use strict";
      6 
      7 const kToolbarName = "test-insertNodeInWindow-placements-toolbar";
      8 const kTestWidgetPrefix = "test-widget-for-insertNodeInWindow-placements-";
      9 
     10 /*
     11 Tries to replicate the situation of having a placement list like this:
     12 
     13 exists-1,trying-to-insert-this,doesn't-exist,exists-2
     14 */
     15 add_task(async function () {
     16  let testWidgetExists = [true, false, false, true];
     17  let widgetIds = [];
     18  for (let i = 0; i < testWidgetExists.length; i++) {
     19    let id = kTestWidgetPrefix + i;
     20    widgetIds.push(id);
     21    if (testWidgetExists[i]) {
     22      let spec = {
     23        id,
     24        type: "button",
     25        removable: true,
     26        label: "test",
     27        tooltiptext: "" + i,
     28      };
     29      CustomizableUI.createWidget(spec);
     30    }
     31  }
     32 
     33  let toolbarNode = createToolbarWithPlacements(kToolbarName, widgetIds);
     34  assertAreaPlacements(kToolbarName, widgetIds);
     35 
     36  let btnId = kTestWidgetPrefix + 1;
     37  let btn = createDummyXULButton(btnId, "test");
     38  CustomizableUI.ensureWidgetPlacedInWindow(btnId, window);
     39 
     40  is(
     41    btn.parentNode.id,
     42    kToolbarName,
     43    "New XUL widget should be placed inside new toolbar"
     44  );
     45 
     46  is(
     47    btn.previousElementSibling.id,
     48    toolbarNode.firstElementChild.id,
     49    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
     50  );
     51 
     52  widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
     53  btn.remove();
     54  removeCustomToolbars();
     55  await resetCustomization();
     56 });
     57 
     58 /*
     59 Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
     60 situation similar to:
     61 
     62 exists-1,exists-2,overflow-1,trying-to-insert-this,overflow-2
     63 */
     64 add_task(async function () {
     65  let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
     66 
     67  let widgetIds = [];
     68  for (let i = 0; i < 5; i++) {
     69    let id = kTestWidgetPrefix + i;
     70    widgetIds.push(id);
     71    let spec = {
     72      id,
     73      type: "button",
     74      removable: true,
     75      label: "insertNodeInWindow test",
     76      tooltiptext: "" + i,
     77    };
     78    CustomizableUI.createWidget(spec);
     79    CustomizableUI.addWidgetToArea(id, "nav-bar");
     80  }
     81 
     82  for (let id of widgetIds) {
     83    document.getElementById(id).style.minWidth = "200px";
     84  }
     85 
     86  let originalWindowWidth = window.outerWidth;
     87  window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
     88  await TestUtils.waitForCondition(
     89    () =>
     90      navbar.hasAttribute("overflowing") &&
     91      !navbar.querySelector("#" + widgetIds[0])
     92  );
     93 
     94  let testWidgetId = kTestWidgetPrefix + 3;
     95 
     96  CustomizableUI.destroyWidget(testWidgetId);
     97 
     98  let btn = createDummyXULButton(testWidgetId, "test");
     99  CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
    100 
    101  ok(
    102    navbar.overflowable.isInOverflowList(btn),
    103    "New XUL widget should be placed inside overflow of toolbar"
    104  );
    105  is(
    106    btn.previousElementSibling.id,
    107    kTestWidgetPrefix + 2,
    108    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    109  );
    110  is(
    111    btn.nextElementSibling.id,
    112    kTestWidgetPrefix + 4,
    113    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    114  );
    115 
    116  window.resizeTo(originalWindowWidth, window.outerHeight);
    117 
    118  widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
    119  CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName);
    120  btn.remove();
    121  await resetCustomization();
    122  await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
    123 });
    124 
    125 /*
    126 Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
    127 placements situation similar to:
    128 
    129 exists-1,exists-2,overflow-1,doesn't-exist,trying-to-insert-this,overflow-2
    130 */
    131 add_task(async function () {
    132  let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
    133 
    134  let widgetIds = [];
    135  for (let i = 0; i < 5; i++) {
    136    let id = kTestWidgetPrefix + i;
    137    widgetIds.push(id);
    138    let spec = {
    139      id,
    140      type: "button",
    141      removable: true,
    142      label: "insertNodeInWindow test",
    143      tooltiptext: "" + i,
    144    };
    145    CustomizableUI.createWidget(spec);
    146    CustomizableUI.addWidgetToArea(id, "nav-bar");
    147  }
    148 
    149  for (let id of widgetIds) {
    150    document.getElementById(id).style.minWidth = "200px";
    151  }
    152 
    153  let originalWindowWidth = window.outerWidth;
    154  window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
    155  await TestUtils.waitForCondition(
    156    () =>
    157      navbar.hasAttribute("overflowing") &&
    158      !navbar.querySelector("#" + widgetIds[0])
    159  );
    160 
    161  let testWidgetId = kTestWidgetPrefix + 3;
    162 
    163  CustomizableUI.destroyWidget(kTestWidgetPrefix + 2);
    164  CustomizableUI.destroyWidget(testWidgetId);
    165 
    166  let btn = createDummyXULButton(testWidgetId, "test");
    167  CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
    168 
    169  ok(
    170    navbar.overflowable.isInOverflowList(btn),
    171    "New XUL widget should be placed inside overflow of toolbar"
    172  );
    173  is(
    174    btn.previousElementSibling.id,
    175    kTestWidgetPrefix + 1,
    176    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    177  );
    178  is(
    179    btn.nextElementSibling.id,
    180    kTestWidgetPrefix + 4,
    181    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    182  );
    183 
    184  window.resizeTo(originalWindowWidth, window.outerHeight);
    185 
    186  widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
    187  CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName);
    188  btn.remove();
    189  await resetCustomization();
    190  await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
    191 });
    192 
    193 /*
    194 Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
    195 placements situation similar to:
    196 
    197 exists-1,exists-2,overflow-1,doesn't-exist,trying-to-insert-this,doesn't-exist
    198 */
    199 add_task(async function () {
    200  let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
    201 
    202  let widgetIds = [];
    203  for (let i = 0; i < 5; i++) {
    204    let id = kTestWidgetPrefix + i;
    205    widgetIds.push(id);
    206    let spec = {
    207      id,
    208      type: "button",
    209      removable: true,
    210      label: "insertNodeInWindow test",
    211      tooltiptext: "" + i,
    212    };
    213    CustomizableUI.createWidget(spec);
    214    CustomizableUI.addWidgetToArea(id, "nav-bar");
    215  }
    216 
    217  for (let id of widgetIds) {
    218    document.getElementById(id).style.minWidth = "200px";
    219  }
    220 
    221  let originalWindowWidth = window.outerWidth;
    222  window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
    223  await TestUtils.waitForCondition(
    224    () =>
    225      navbar.hasAttribute("overflowing") &&
    226      !navbar.querySelector("#" + widgetIds[0])
    227  );
    228 
    229  let testWidgetId = kTestWidgetPrefix + 3;
    230 
    231  CustomizableUI.destroyWidget(kTestWidgetPrefix + 2);
    232  CustomizableUI.destroyWidget(testWidgetId);
    233  CustomizableUI.destroyWidget(kTestWidgetPrefix + 4);
    234 
    235  let btn = createDummyXULButton(testWidgetId, "test");
    236  CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
    237 
    238  ok(
    239    navbar.overflowable.isInOverflowList(btn),
    240    "New XUL widget should be placed inside overflow of toolbar"
    241  );
    242  is(
    243    btn.previousElementSibling.id,
    244    kTestWidgetPrefix + 1,
    245    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    246  );
    247  is(
    248    btn.nextElementSibling,
    249    null,
    250    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    251  );
    252 
    253  window.resizeTo(originalWindowWidth, window.outerHeight);
    254 
    255  widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
    256  CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName);
    257  btn.remove();
    258  await resetCustomization();
    259  await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
    260 });
    261 
    262 /*
    263 Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
    264 placements situation similar to:
    265 
    266 exists-1,exists-2,overflow-1,can't-overflow,trying-to-insert-this,overflow-2
    267 */
    268 add_task(async function () {
    269  let navbar = document.getElementById(CustomizableUI.AREA_NAVBAR);
    270 
    271  let widgetIds = [];
    272  for (let i = 5; i >= 0; i--) {
    273    let id = kTestWidgetPrefix + i;
    274    widgetIds.push(id);
    275    let spec = {
    276      id,
    277      type: "button",
    278      removable: true,
    279      label: "insertNodeInWindow test",
    280      tooltiptext: "" + i,
    281    };
    282    CustomizableUI.createWidget(spec);
    283    CustomizableUI.addWidgetToArea(id, "nav-bar", 0);
    284  }
    285 
    286  for (let i = 10; i < 15; i++) {
    287    let id = kTestWidgetPrefix + i;
    288    widgetIds.push(id);
    289    let spec = {
    290      id,
    291      type: "button",
    292      removable: true,
    293      label: "insertNodeInWindow test",
    294      tooltiptext: "" + i,
    295    };
    296    CustomizableUI.createWidget(spec);
    297    CustomizableUI.addWidgetToArea(id, "nav-bar");
    298  }
    299 
    300  for (let id of widgetIds) {
    301    document.getElementById(id).style.minWidth = "200px";
    302  }
    303 
    304  let originalWindowWidth = window.outerWidth;
    305  window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
    306  // Wait for all the widgets to overflow. We can't just wait for the
    307  // `overflowing` attribute because we leave time for layout flushes
    308  // inbetween, so it's possible for the timeout to run before the
    309  // navbar has "settled"
    310  await TestUtils.waitForCondition(() => {
    311    return (
    312      navbar.hasAttribute("overflowing") &&
    313      CustomizableUI.getCustomizationTarget(
    314        navbar
    315      ).lastElementChild.getAttribute("overflows") == "false"
    316    );
    317  });
    318 
    319  // Find last widget that doesn't allow overflowing
    320  let nonOverflowing =
    321    CustomizableUI.getCustomizationTarget(navbar).lastElementChild;
    322  is(
    323    nonOverflowing.getAttribute("overflows"),
    324    "false",
    325    "Last child is expected to not allow overflowing"
    326  );
    327  isnot(
    328    nonOverflowing.getAttribute("skipintoolbarset"),
    329    "true",
    330    "Last child is expected to not be skipintoolbarset"
    331  );
    332 
    333  let testWidgetId = kTestWidgetPrefix + 10;
    334  CustomizableUI.destroyWidget(testWidgetId);
    335 
    336  let btn = createDummyXULButton(testWidgetId, "test");
    337  CustomizableUI.ensureWidgetPlacedInWindow(testWidgetId, window);
    338 
    339  ok(
    340    navbar.overflowable.isInOverflowList(btn),
    341    "New XUL widget should be placed inside overflow of toolbar"
    342  );
    343  is(
    344    btn.nextElementSibling.id,
    345    kTestWidgetPrefix + 11,
    346    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    347  );
    348 
    349  window.resizeTo(originalWindowWidth, window.outerHeight);
    350 
    351  widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
    352  CustomizableUI.removeWidgetFromArea(btn.id, kToolbarName);
    353  btn.remove();
    354  await resetCustomization();
    355  await TestUtils.waitForCondition(() => !navbar.hasAttribute("overflowing"));
    356 });
    357 
    358 /*
    359 Tests nodes get placed inside the toolbar's overflow as expected. Replicates a
    360 placements situation similar to:
    361 
    362 exists-1,exists-2,overflow-1,trying-to-insert-this,can't-overflow,overflow-2
    363 */
    364 add_task(async function () {
    365  let widgetIds = [];
    366  let missingId = 2;
    367  let nonOverflowableId = 3;
    368  for (let i = 0; i < 5; i++) {
    369    let id = kTestWidgetPrefix + i;
    370    widgetIds.push(id);
    371    if (i != missingId) {
    372      // Setting min-width to make the overflow state not depend on styling of the button and/or
    373      // screen width
    374      let spec = {
    375        id,
    376        type: "button",
    377        removable: true,
    378        label: "test",
    379        tooltiptext: "" + i,
    380        onCreated(node) {
    381          node.style.minWidth = "200px";
    382          if (id == kTestWidgetPrefix + nonOverflowableId) {
    383            node.setAttribute("overflows", false);
    384          }
    385        },
    386      };
    387      info("Creating: " + id);
    388      CustomizableUI.createWidget(spec);
    389    }
    390  }
    391 
    392  let toolbarNode = createOverflowableToolbarWithPlacements(
    393    kToolbarName,
    394    widgetIds
    395  );
    396  assertAreaPlacements(kToolbarName, widgetIds);
    397  ok(
    398    !toolbarNode.hasAttribute("overflowing"),
    399    "Toolbar shouldn't overflow to start with."
    400  );
    401 
    402  let originalWindowWidth = window.outerWidth;
    403  window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
    404  await TestUtils.waitForCondition(
    405    () =>
    406      toolbarNode.hasAttribute("overflowing") &&
    407      !toolbarNode.querySelector("#" + widgetIds[1])
    408  );
    409  ok(
    410    toolbarNode.hasAttribute("overflowing"),
    411    "Should have an overflowing toolbar."
    412  );
    413 
    414  let btnId = kTestWidgetPrefix + missingId;
    415  let btn = createDummyXULButton(btnId, "test");
    416  CustomizableUI.ensureWidgetPlacedInWindow(btnId, window);
    417 
    418  is(
    419    btn.parentNode.id,
    420    kToolbarName + "-overflow-list",
    421    "New XUL widget should be placed inside new toolbar's overflow"
    422  );
    423  is(
    424    btn.previousElementSibling.id,
    425    kTestWidgetPrefix + 1,
    426    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    427  );
    428  is(
    429    btn.nextElementSibling.id,
    430    kTestWidgetPrefix + 4,
    431    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    432  );
    433 
    434  window.resizeTo(originalWindowWidth, window.outerHeight);
    435  await TestUtils.waitForCondition(
    436    () => !toolbarNode.hasAttribute("overflowing")
    437  );
    438 
    439  btn.remove();
    440  widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
    441  removeCustomToolbars();
    442  await resetCustomization();
    443 });
    444 
    445 /*
    446 Tests nodes do *not* get placed in the toolbar's overflow. Replicates a
    447 plcements situation similar to:
    448 
    449 exists-1,trying-to-insert-this,exists-2,overflowed-1
    450 */
    451 add_task(async function () {
    452  let widgetIds = [];
    453  let missingId = 1;
    454  for (let i = 0; i < 5; i++) {
    455    let id = kTestWidgetPrefix + i;
    456    widgetIds.push(id);
    457    if (i != missingId) {
    458      // Setting min-width to make the overflow state not depend on styling of the button and/or
    459      // screen width
    460      let spec = {
    461        id,
    462        type: "button",
    463        removable: true,
    464        label: "test",
    465        tooltiptext: "" + i,
    466        onCreated(node) {
    467          node.style.minWidth = "200px";
    468        },
    469      };
    470      info("Creating: " + id);
    471      CustomizableUI.createWidget(spec);
    472    }
    473  }
    474 
    475  let toolbarNode = createOverflowableToolbarWithPlacements(
    476    kToolbarName,
    477    widgetIds
    478  );
    479  assertAreaPlacements(kToolbarName, widgetIds);
    480  ok(
    481    !toolbarNode.hasAttribute("overflowing"),
    482    "Toolbar shouldn't overflow to start with."
    483  );
    484 
    485  let originalWindowWidth = window.outerWidth;
    486  window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
    487  await TestUtils.waitForCondition(() =>
    488    toolbarNode.hasAttribute("overflowing")
    489  );
    490  ok(
    491    toolbarNode.hasAttribute("overflowing"),
    492    "Should have an overflowing toolbar."
    493  );
    494 
    495  let btnId = kTestWidgetPrefix + missingId;
    496  let btn = createDummyXULButton(btnId, "test");
    497  CustomizableUI.ensureWidgetPlacedInWindow(btnId, window);
    498 
    499  is(
    500    btn.parentNode.id,
    501    kToolbarName + "-target",
    502    "New XUL widget should be placed inside new toolbar"
    503  );
    504 
    505  window.resizeTo(originalWindowWidth, window.outerHeight);
    506  await TestUtils.waitForCondition(
    507    () => !toolbarNode.hasAttribute("overflowing")
    508  );
    509 
    510  btn.remove();
    511  widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
    512  removeCustomToolbars();
    513  await resetCustomization();
    514 });
    515 
    516 /*
    517 Tests inserting a node onto the end of an overflowing toolbar *doesn't* put it in
    518 the overflow list when the widget disallows overflowing. ie:
    519 
    520 exists-1,exists-2,overflows-1,trying-to-insert-this
    521 
    522 Where trying-to-insert-this has overflows=false
    523 */
    524 add_task(async function () {
    525  let widgetIds = [];
    526  let missingId = 3;
    527  for (let i = 0; i < 5; i++) {
    528    let id = kTestWidgetPrefix + i;
    529    widgetIds.push(id);
    530    if (i != missingId) {
    531      // Setting min-width to make the overflow state not depend on styling of the button and/or
    532      // screen width
    533      let spec = {
    534        id,
    535        type: "button",
    536        removable: true,
    537        label: "test",
    538        tooltiptext: "" + i,
    539        onCreated(node) {
    540          node.style.minWidth = "200px";
    541        },
    542      };
    543      info("Creating: " + id);
    544      CustomizableUI.createWidget(spec);
    545    }
    546  }
    547 
    548  let toolbarNode = createOverflowableToolbarWithPlacements(
    549    kToolbarName,
    550    widgetIds
    551  );
    552  assertAreaPlacements(kToolbarName, widgetIds);
    553  ok(
    554    !toolbarNode.hasAttribute("overflowing"),
    555    "Toolbar shouldn't overflow to start with."
    556  );
    557 
    558  let originalWindowWidth = window.outerWidth;
    559  window.resizeTo(kForceOverflowWidthPx, window.outerHeight);
    560  await TestUtils.waitForCondition(() =>
    561    toolbarNode.hasAttribute("overflowing")
    562  );
    563  ok(
    564    toolbarNode.hasAttribute("overflowing"),
    565    "Should have an overflowing toolbar."
    566  );
    567 
    568  let btnId = kTestWidgetPrefix + missingId;
    569  let btn = createDummyXULButton(btnId, "test");
    570  btn.setAttribute("overflows", false);
    571  CustomizableUI.ensureWidgetPlacedInWindow(btnId, window);
    572 
    573  is(
    574    btn.parentNode.id,
    575    kToolbarName + "-target",
    576    "New XUL widget should be placed inside new toolbar"
    577  );
    578  is(
    579    btn.nextElementSibling,
    580    null,
    581    "insertNodeInWindow should have placed new XUL widget in correct place in DOM according to placements"
    582  );
    583 
    584  window.resizeTo(originalWindowWidth, window.outerHeight);
    585  await TestUtils.waitForCondition(
    586    () => !toolbarNode.hasAttribute("overflowing")
    587  );
    588 
    589  btn.remove();
    590  widgetIds.forEach(id => CustomizableUI.destroyWidget(id));
    591  removeCustomToolbars();
    592  await resetCustomization();
    593 });
    594 
    595 add_task(async function asyncCleanUp() {
    596  await resetCustomization();
    597 });