Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Impressum head.js

  Interaktion und
PortierbarkeitJAVA
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


"use strict";

ChromeUtils.defineESModuleGetters(this, {
  CustomizableUI:
    "moz-src:///browser/components/customizableui/CustomizableUI.sys.mjs",
  CustomizableUITestUtils:
    "resource://testing-common/CustomizableUITestUtils.sys.mjs",
});

/**
 * Instance of CustomizableUITestUtils for the current browser window.
 */

var gCUITestUtils = new CustomizableUITestUtils(window);

Services.prefs.setBoolPref("browser.uiCustomization.skipSourceNodeCheck"true);
registerCleanupFunction(() =>
  Services.prefs.clearUserPref("browser.uiCustomization.skipSourceNodeCheck")
);

ChromeUtils.defineLazyGetter(this"SidebarTestUtils", () => {
  const { SidebarTestUtils: utils } = ChromeUtils.importESModule(
    "resource://testing-common/SidebarTestUtils.sys.mjs"
  );
  utils.init(this);
  return utils;
});

var { synthesizeDrop, synthesizeMouseAtCenter } = EventUtils;

// As of bug 1960002, this width no longer technically forces overflow.
// Instead, use `ensureToolbarOverflow()` below.
const kForceOverflowWidthPx = 500;

function createDummyXULButton(id, label, win = window) {
  let btn = win.document.createXULElement("toolbarbutton");
  btn.id = id;
  btn.setAttribute("label", label || id);
  btn.className = "toolbarbutton-1 chromeclass-toolbar-additional";
  win.gNavToolbox.palette.appendChild(btn);
  return btn;
}

var gAddedToolbars = new Set();

function createToolbarWithPlacements(id, placements = [], properties = {}) {
  gAddedToolbars.add(id);
  let tb = document.createXULElement("toolbar");
  tb.id = id;
  tb.setAttribute("customizable""true");

  properties.type = CustomizableUI.TYPE_TOOLBAR;
  properties.defaultPlacements = placements;
  CustomizableUI.registerArea(id, properties);
  gNavToolbox.appendChild(tb);
  CustomizableUI.registerToolbarNode(tb);
  return tb;
}

function createOverflowableToolbarWithPlacements(id, placements) {
  gAddedToolbars.add(id);

  let tb = document.createXULElement("toolbar");
  tb.id = id;
  tb.setAttribute("customizationtarget", id + "-target");

  let customizationtarget = document.createXULElement("hbox");
  customizationtarget.id = id + "-target";
  customizationtarget.setAttribute("flex""1");
  tb.appendChild(customizationtarget);

  let overflowPanel = document.createXULElement("panel");
  overflowPanel.id = id + "-overflow";
  document.getElementById("mainPopupSet").appendChild(overflowPanel);

  let overflowList = document.createXULElement("vbox");
  overflowList.id = id + "-overflow-list";
  overflowPanel.appendChild(overflowList);

  let chevron = document.createXULElement("toolbarbutton");
  chevron.id = id + "-chevron";
  tb.appendChild(chevron);

  CustomizableUI.registerArea(id, {
    type: CustomizableUI.TYPE_TOOLBAR,
    defaultPlacements: placements,
    overflowable: true,
  });

  tb.setAttribute("customizable""true");
  tb.setAttribute("overflowable""true");
  tb.setAttribute("default-overflowpanel", overflowPanel.id);
  tb.setAttribute("default-overflowtarget", overflowList.id);
  tb.setAttribute("default-overflowbutton", chevron.id);
  tb.setAttribute("addon-webext-overflowbutton""unified-extensions-button");
  tb.setAttribute("addon-webext-overflowtarget""overflowed-extensions-list");

  gNavToolbox.appendChild(tb);
  CustomizableUI.registerToolbarNode(tb);
  return tb;
}

function removeCustomToolbars() {
  CustomizableUI.reset();
  for (let toolbarId of gAddedToolbars) {
    CustomizableUI.unregisterArea(toolbarId, true);
    let tb = document.getElementById(toolbarId);
    if (tb.hasAttribute("overflowpanel")) {
      let panel = document.getElementById(tb.getAttribute("overflowpanel"));
      if (panel) {
        panel.remove();
      }
    }
    tb.remove();
  }
  gAddedToolbars.clear();
}

function resetCustomization() {
  return CustomizableUI.reset();
}

function isInDevEdition() {
  return AppConstants.MOZ_DEV_EDITION;
}

function removeNonReleaseButtons(areaPanelPlacements) {
  if (isInDevEdition() && areaPanelPlacements.includes("developer-button")) {
    areaPanelPlacements.splice(
      areaPanelPlacements.indexOf("developer-button"),
      1
    );
  }
}

function removeNonOriginalButtons() {
  CustomizableUI.removeWidgetFromArea("sync-button");
}

function assertAreaPlacements(areaId, expectedPlacements) {
  let actualPlacements = getAreaWidgetIds(areaId);
  placementArraysEqual(areaId, actualPlacements, expectedPlacements);
}

function placementArraysEqual(areaId, actualPlacements, expectedPlacements) {
  info("Actual placements: " + actualPlacements.join(", "));
  info("Expected placements: " + expectedPlacements.join(", "));
  is(
    actualPlacements.length,
    expectedPlacements.length,
    "Area " + areaId + " should have " + expectedPlacements.length + " items."
  );
  let minItems = Math.min(expectedPlacements.length, actualPlacements.length);
  for (let i = 0; i < minItems; i++) {
    if (typeof expectedPlacements[i] == "string") {
      is(
        actualPlacements[i],
        expectedPlacements[i],
        "Item " + i + " in " + areaId + " should match expectations."
      );
    } else if (expectedPlacements[i] instanceof RegExp) {
      ok(
        expectedPlacements[i].test(actualPlacements[i]),
        "Item " +
          i +
          " (" +
          actualPlacements[i] +
          ") in " +
          areaId +
          " should match " +
          expectedPlacements[i]
      );
    } else {
      ok(
        false,
        "Unknown type of expected placement passed to " +
          " assertAreaPlacements. Is your test broken?"
      );
    }
  }
}

function todoAssertAreaPlacements(areaId, expectedPlacements) {
  let actualPlacements = getAreaWidgetIds(areaId);
  let isPassing = actualPlacements.length == expectedPlacements.length;
  let minItems = Math.min(expectedPlacements.length, actualPlacements.length);
  for (let i = 0; i < minItems; i++) {
    if (typeof expectedPlacements[i] == "string") {
      isPassing = isPassing && actualPlacements[i] == expectedPlacements[i];
    } else if (expectedPlacements[i] instanceof RegExp) {
      isPassing = isPassing && expectedPlacements[i].test(actualPlacements[i]);
    } else {
      ok(
        false,
        "Unknown type of expected placement passed to " +
          " assertAreaPlacements. Is your test broken?"
      );
    }
  }
  todo(
    isPassing,
    "The area placements for " +
      areaId +
      " should equal the expected placements."
  );
}

function getAreaWidgetIds(areaId) {
  return CustomizableUI.getWidgetIdsInArea(areaId);
}

function simulateItemDrag(aToDrag, aTarget, aEvent = {}, aOffset = 2) {
  let ev = aEvent;
  if (ev == "end" || ev == "start") {
    let win = aTarget.documentGlobal;
    const dwu = win.windowUtils;
    let bounds = dwu.getBoundsWithoutFlushing(aTarget);
    if (ev == "end") {
      ev = {
        clientX: bounds.right - aOffset,
        clientY: bounds.bottom - aOffset,
      };
    } else {
      ev = { clientX: bounds.left + aOffset, clientY: bounds.top + aOffset };
    }
  }
  ev._domDispatchOnly = true;
  synthesizeDrop(
    aToDrag.parentNode,
    aTarget,
    null,
    null,
    aToDrag.documentGlobal,
    aTarget.documentGlobal,
    ev
  );
  // Ensure dnd suppression is cleared.
  synthesizeMouseAtCenter(aTarget, { type: "mouseup" }, aTarget.documentGlobal);
}

function endCustomizing(aWindow = window) {
  if (!aWindow.document.documentElement.hasAttribute("customizing")) {
    return true;
  }
  let afterCustomizationPromise = BrowserTestUtils.waitForEvent(
    aWindow.gNavToolbox,
    "aftercustomization"
  );
  aWindow.gCustomizeMode.exit();
  return afterCustomizationPromise;
}

async function startCustomizing(aWindow = window) {
  if (aWindow.document.documentElement.hasAttribute("customizing")) {
    return;
  }
  let customizationReadyPromise = BrowserTestUtils.waitForEvent(
    aWindow.gNavToolbox,
    "customizationready"
  );
  aWindow.gCustomizeMode.enter();
  await customizationReadyPromise;

  if (document.hasPendingL10nMutations) {
    await BrowserTestUtils.waitForEvent(document, "L10nMutationsFinished");
  }
}

function promiseObserverNotified(aTopic) {
  return new Promise(resolve => {
    Services.obs.addObserver(function onNotification(subject, topic, data) {
      Services.obs.removeObserver(onNotification, topic);
      resolve({ subject, data });
    }, aTopic);
  });
}

function openAndLoadWindow(aOptions, aWaitForDelayedStartup = false) {
  return new Promise(resolve => {
    let win = OpenBrowserWindow(aOptions);
    if (aWaitForDelayedStartup) {
      Services.obs.addObserver(function onDS(aSubject) {
        if (aSubject != win) {
          return;
        }
        Services.obs.removeObserver(onDS, "browser-delayed-startup-finished");
        resolve(win);
      }, "browser-delayed-startup-finished");
    } else {
      win.addEventListener(
        "load",
        function () {
          resolve(win);
        },
        { once: true }
      );
    }
  });
}

function promiseWindowClosed(win) {
  return new Promise(resolve => {
    win.addEventListener(
      "unload",
      function () {
        resolve();
      },
      { once: true }
    );
    win.close();
  });
}

function promiseOverflowShown(win) {
  let panelEl = win.document.getElementById("widget-overflow");
  return promisePanelElementShown(win, panelEl);
}

function promisePanelElementShown(win, aPanel) {
  return new Promise((resolve, reject) => {
    let timeoutId = win.setTimeout(() => {
      reject("Panel did not show within 20 seconds.");
    }, 20000);
    function onPanelOpen() {
      aPanel.removeEventListener("popupshown", onPanelOpen);
      win.clearTimeout(timeoutId);
      resolve();
    }
    aPanel.addEventListener("popupshown", onPanelOpen);
  });
}

function promiseOverflowHidden(win) {
  let panelEl = win.PanelUI.overflowPanel;
  return promisePanelElementHidden(win, panelEl);
}

function hideOverflow() {
  let panelHidePromise = promiseOverflowHidden(window);
  PanelUI.overflowPanel.hidePopup();
  return panelHidePromise;
}

function promisePanelElementHidden(win, aPanel) {
  return new Promise((resolve, reject) => {
    let timeoutId = win.setTimeout(() => {
      reject("Panel did not hide within 20 seconds.");
    }, 20000);
    function onPanelClose() {
      aPanel.removeEventListener("popuphidden", onPanelClose);
      win.clearTimeout(timeoutId);
      executeSoon(resolve);
    }
    aPanel.addEventListener("popuphidden", onPanelClose);
  });
}

function isPanelUIOpen() {
  return PanelUI.panel.state == "open" || PanelUI.panel.state == "showing";
}

function isOverflowOpen() {
  let panel = document.getElementById("widget-overflow");
  return panel.state == "open" || panel.state == "showing";
}

function subviewShown(aSubview) {
  return new Promise((resolve, reject) => {
    let win = aSubview.documentGlobal;
    let timeoutId = win.setTimeout(() => {
      reject("Subview (" + aSubview.id + ") did not show within 20 seconds.");
    }, 20000);
    function onViewShown() {
      aSubview.removeEventListener("ViewShown", onViewShown);
      win.clearTimeout(timeoutId);
      resolve();
    }
    aSubview.addEventListener("ViewShown", onViewShown);
  });
}

function subviewHidden(aSubview) {
  return new Promise((resolve, reject) => {
    let win = aSubview.documentGlobal;
    let timeoutId = win.setTimeout(() => {
      reject("Subview (" + aSubview.id + ") did not hide within 20 seconds.");
    }, 20000);
    function onViewHiding() {
      aSubview.removeEventListener("ViewHiding", onViewHiding);
      win.clearTimeout(timeoutId);
      resolve();
    }
    aSubview.addEventListener("ViewHiding", onViewHiding);
  });
}

function waitFor(aTimeout = 100) {
  return new Promise(resolve => {
    setTimeout(() => resolve(), aTimeout);
  });
}

/**
 * Wait for an attribute on a node to change
 *
 * @param aNode      Node on which the mutation is expected
 * @param aAttribute The attribute we're interested in
 * @param aFilterFn  A function to check if the new value is what we want.
 * @return {Promise} resolved when the requisite mutation shows up.
 */

function promiseAttributeMutation(aNode, aAttribute, aFilterFn) {
  return new Promise(resolve => {
    info("waiting for mutation of attribute '" + aAttribute + "'.");
    let obs = new MutationObserver(mutations => {
      for (let mut of mutations) {
        let attr = mut.attributeName;
        let newValue = mut.target.getAttribute(attr);
        if (aFilterFn(newValue)) {
          ok(
            true,
            "mutation occurred: attribute '" +
              attr +
              "' changed to '" +
              newValue +
              "' from '" +
              mut.oldValue +
              "'."
          );
          obs.disconnect();
          resolve();
        } else {
          info(
            "Ignoring mutation that produced value " +
              newValue +
              " because of filter."
          );
        }
      }
    });
    obs.observe(aNode, { attributeFilter: [aAttribute] });
  });
}

function popupShown(aPopup) {
  return BrowserTestUtils.waitForPopupEvent(aPopup, "shown");
}

function popupHidden(aPopup) {
  return BrowserTestUtils.waitForPopupEvent(aPopup, "hidden");
}

// This is a simpler version of the context menu check that
// exists in contextmenu_common.js.
function checkContextMenu(aContextMenu, aExpectedEntries, aWindow = window) {
  let children = [...aContextMenu.children];
  // Ignore hidden nodes:
  children = children.filter(n => !n.hidden);
  for (let i = 0; i < children.length; i++) {
    let menuitem = children[i];
    try {
      if (aExpectedEntries[i][0] == "---") {
        is(menuitem.localName, "menuseparator""menuseparator expected");
        continue;
      }

      let selector = aExpectedEntries[i][0];
      ok(
        menuitem.matches(selector),
        "menuitem should match " + selector + " selector"
      );
      let commandValue = menuitem.getAttribute("command");
      let relatedCommand = commandValue
        ? aWindow.document.getElementById(commandValue)
        : null;
      let menuItemDisabled = relatedCommand
        ? relatedCommand.hasAttribute("disabled")
        : menuitem.hasAttribute("disabled");
      is(
        menuItemDisabled,
        !aExpectedEntries[i][1],
        "disabled state for " + selector
      );
    } catch (e) {
      ok(false"Exception when checking context menu: " + e);
    }
  }
}

function waitForOverflowButtonShown(win = window) {
  info("Waiting for overflow button to show");
  let ov = win.document.getElementById("nav-bar-overflow-button");
  return waitForElementShown(ov.icon);
}
function waitForElementShown(element) {
  return BrowserTestUtils.waitForCondition(() => {
    info("Checking if element has non-0 size");
    // We intentionally flush layout to ensure the element is actually shown.
    let rect = element.getBoundingClientRect();
    return rect.width > 0 && rect.height > 0;
  });
}

/**
 * Opens the history panel through the history toolbarbutton in the
 * navbar and returns a promise that resolves as soon as the panel is open
 * is showing.
 */

async function openHistoryPanel(doc = document) {
  await waitForOverflowButtonShown();
  await doc.getElementById("nav-bar").overflowable.show();
  info("Menu panel was opened");

  let historyButton = doc.getElementById("history-panelmenu");
  Assert.ok(historyButton, "History button appears in Panel Menu");

  historyButton.click();

  let historyPanel = doc.getElementById("PanelUI-history");
  return BrowserTestUtils.waitForEvent(historyPanel, "ViewShown");
}

/**
 * Closes the history panel and returns a promise that resolves as sooon
 * as the panel is closed.
 */

async function hideHistoryPanel(doc = document) {
  let historyView = doc.getElementById("PanelUI-history");
  let historyPanel = historyView.closest("panel");
  let promise = BrowserTestUtils.waitForEvent(historyPanel, "popuphidden");
  historyPanel.hidePopup();
  return promise;
}

/**
 * After bug 1960002, setting the window to its min-width is no longer enough
 * to trigger navbar overflow. So, to keep the overflow tests working, we need
 * to both change the window width and add more buttons to the navbar.
 *
 * Note this helper registers a cleanup function that undoes changes to the
 * supplied window's width and resets its toolbar state. Be sure to call this
 * helper before other cleanup functions that might assert on the state of the
 * window after it is reset.
 *
 * Set the shouldCleanup param to false if you don't need to register another
 * end-of-test cleanup function, for instance, if your test calls
 * `CustomizableUI.reset()` in the middle of asserts that rely on overflow.
 *
 * Returns the original window width in case a test needs to resize the window
 * before the cleanup function runs.
 */

function ensureToolbarOverflow(aWindow, shouldCleanup = true) {
  const originalWindowWidth = aWindow.outerWidth;

  aWindow.resizeTo(kForceOverflowWidthPx, aWindow.outerHeight);
  CustomizableUI.addWidgetToArea(
    "history-panelmenu",
    CustomizableUI.AREA_NAVBAR,
    0
  );
  CustomizableUI.addWidgetToArea(
    "email-link-button",
    CustomizableUI.AREA_NAVBAR,
    0
  );
  CustomizableUI.addWidgetToArea("panic-button", CustomizableUI.AREA_NAVBAR, 0);
  CustomizableUI.addWidgetToArea("print-button", CustomizableUI.AREA_NAVBAR, 0);

  if (shouldCleanup) {
    registerCleanupFunction(() => {
      unensureToolbarOverflow(aWindow, originalWindowWidth);
    });
  }

  return originalWindowWidth;
}

/**
 * Helper function that undoes what `ensureToolbarOverflow` does.
 */

function unensureToolbarOverflow(aWindow, originalWindowWidth) {
  if (originalWindowWidth) {
    aWindow.resizeTo(originalWindowWidth, aWindow.outerHeight);
  }
  CustomizableUI.removeWidgetFromArea("history-panelmenu");
  CustomizableUI.removeWidgetFromArea("email-link-button");
  CustomizableUI.removeWidgetFromArea("panic-button");
  CustomizableUI.removeWidgetFromArea("print-button");
}

Messung V0.5 in Prozent
C=96 H=91 G=93

¤ Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.0.21Bemerkung:  (Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-08-26) ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Statistik
#Sources=277311
#Domains=655579