Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/devtools/client/shared/test/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 14 kB image not shown  

Quelle  browser_spectrum.js   Sprache: JAVA

 
/* Any copyright is dedicated to the Public Domain.
   http://creativecommons.org/publicdomain/zero/1.0/ */


"use strict";

// Tests that the spectrum color picker works correctly

const Spectrum = require("resource://devtools/client/shared/widgets/Spectrum.js");
const {
  accessibility: {
    SCORES: { FAIL, AAA, AA },
  },
} = require("resource://devtools/shared/constants.js");

loader.lazyRequireGetter(
  this,
  "cssColors",
  "resource://devtools/shared/css/color-db.js",
  true
);

const TEST_URI = CHROME_URL_ROOT + "doc_spectrum.html";
const REGULAR_TEXT_PROPS = {
  "font-size": { value: "11px" },
  "font-weight": { value: "bold" },
  opacity: { value: "1" },
};
const SINGLE_BG_COLOR = {
  value: cssColors.white,
};
const ZERO_ALPHA_COLOR = [0, 255, 255, 0];

add_task(async function () {
  const { host, doc } = await createHost("bottom", TEST_URI);

  const container = doc.getElementById("spectrum-container");
  await testCreateAndDestroyShouldAppendAndRemoveElements(container);
  await testPassingAColorAtInitShouldSetThatColor(container);
  await testSettingAndGettingANewColor(container);
  await testChangingColorShouldEmitEvents(container, doc);
  await testSettingColorShoudUpdateTheUI(container);
  await testChangingColorShouldUpdateColorPreview(container);
  await testNotSettingTextPropsShouldNotShowContrastSection(container);
  await testSettingTextPropsAndColorShouldUpdateContrastValue(container);
  await testOnlySelectingLargeTextWithNonZeroAlphaShouldShowIndicator(
    container
  );
  await testSettingMultiColoredBackgroundShouldShowContrastRange(container);

  host.destroy();
});

/**
 * Helper method for extracting the rgba overlay value of the color preview's background
 * image style.
 *
 * @param   {String} linearGradientStr
 *          The linear gradient CSS string.
 * @return  {String} Returns the rgba string for the color overlay.
 */

function extractRgbaOverlayString(linearGradientStr) {
  const start = linearGradientStr.indexOf("(");
  const end = linearGradientStr.indexOf(")");

  return linearGradientStr.substring(start + 1, end + 1);
}

function testColorPreviewDisplay(
  spectrum,
  expectedRgbCssString,
  expectedBorderColor
) {
  const { colorPreview } = spectrum;
  const colorPreviewStyle = window.getComputedStyle(colorPreview);
  expectedBorderColor =
    expectedBorderColor === "transparent"
      ? "rgba(0, 0, 0, 0)"
      : expectedBorderColor;

  spectrum.updateUI();

  // Extract the first rgba value from the linear gradient
  const linearGradientStr =
    colorPreviewStyle.getPropertyValue("background-image");
  const colorPreviewValue = extractRgbaOverlayString(linearGradientStr);

  is(
    colorPreviewValue,
    expectedRgbCssString,
    `Color preview should be ${expectedRgbCssString}`
  );

  info("Test if color preview has a border or not.");
  // Since border-color is a shorthand CSS property, using getComputedStyle will return
  // an empty string. Instead, use one of the border sides to find the border-color value
  // since they will all be the same.
  const borderColorTop = colorPreviewStyle.getPropertyValue("border-top-color");
  is(
    borderColorTop,
    expectedBorderColor,
    "Color preview border color is correct."
  );
}

async function testCreateAndDestroyShouldAppendAndRemoveElements(container) {
  ok(container, "We have the root node to append spectrum to");
  is(container.childElementCount, 0, "Root node is empty");

  const s = await createSpectrum(container, cssColors.white);
  Assert.greater(
    container.childElementCount,
    0,
    "Spectrum has appended elements"
  );

  s.destroy();
  is(container.childElementCount, 0, "Destroying spectrum removed all nodes");
}

async function testPassingAColorAtInitShouldSetThatColor(container) {
  const initRgba = cssColors.white;

  const s = await createSpectrum(container, initRgba);

  const setRgba = s.rgb;

  is(initRgba[0], setRgba[0], "Spectrum initialized with the right color");
  is(initRgba[1], setRgba[1], "Spectrum initialized with the right color");
  is(initRgba[2], setRgba[2], "Spectrum initialized with the right color");
  is(initRgba[3], setRgba[3], "Spectrum initialized with the right color");

  s.destroy();
}

async function testSettingAndGettingANewColor(container) {
  const s = await createSpectrum(container, cssColors.black);

  const colorToSet = cssColors.white;
  s.rgb = colorToSet;
  const newColor = s.rgb;

  is(colorToSet[0], newColor[0], "Spectrum set with the right color");
  is(colorToSet[1], newColor[1], "Spectrum set with the right color");
  is(colorToSet[2], newColor[2], "Spectrum set with the right color");
  is(colorToSet[3], newColor[3], "Spectrum set with the right color");

  s.destroy();
}

async function testChangingColorShouldEmitEventsHelper(
  spectrum,
  moveFn,
  expectedColor
) {
  const onChanged = spectrum.once("changed", (rgba, color) => {
    is(rgba[0], expectedColor[0], "New color is correct");
    is(rgba[1], expectedColor[1], "New color is correct");
    is(rgba[2], expectedColor[2], "New color is correct");
    is(rgba[3], expectedColor[3], "New color is correct");
    is(`rgba(${rgba.join(", ")})`, color, "RGBA and css color correspond");
  });

  moveFn();
  await onChanged;
  ok(true"Changed event was emitted on color change");
}

async function testChangingColorShouldEmitEvents(container, doc) {
  const s = await createSpectrum(container, cssColors.white);

  const sendUpKey = () => EventUtils.sendKey("Up");
  const sendDownKey = () => EventUtils.sendKey("Down");
  const sendLeftKey = () => EventUtils.sendKey("Left");
  const sendRightKey = () => EventUtils.sendKey("Right");

  info(
    "Test that simulating a mouse drag move event emits color changed event"
  );
  const draggerMoveFn = () =>
    s.onDraggerMove(s.dragger.offsetWidth / 2, s.dragger.offsetHeight / 2);
  testChangingColorShouldEmitEventsHelper(s, draggerMoveFn, [128, 64, 64, 1]);

  info(
    "Test that moving the dragger with arrow keys emits color changed event."
  );
  // Focus on the spectrum dragger when spectrum is shown
  s.dragger.focus();
  is(
    doc.activeElement.className,
    "spectrum-color spectrum-box",
    "Spectrum dragger has successfully received focus."
  );
  testChangingColorShouldEmitEventsHelper(s, sendDownKey, [125, 62, 62, 1]);
  testChangingColorShouldEmitEventsHelper(s, sendLeftKey, [125, 63, 63, 1]);
  testChangingColorShouldEmitEventsHelper(s, sendUpKey, [128, 64, 64, 1]);
  testChangingColorShouldEmitEventsHelper(s, sendRightKey, [128, 63, 63, 1]);

  info(
    "Test that moving the hue slider with arrow keys emits color changed event."
  );
  // Tab twice to focus on hue slider
  EventUtils.sendKey("Tab");
  is(
    doc.activeElement.className,
    "devtools-button",
    "Eyedropper has focus now."
  );
  EventUtils.sendKey("Tab");
  is(
    doc.activeElement.className,
    "spectrum-hue-input",
    "Hue slider has successfully received focus."
  );
  testChangingColorShouldEmitEventsHelper(s, sendRightKey, [128, 66, 63, 1]);
  testChangingColorShouldEmitEventsHelper(s, sendLeftKey, [128, 63, 63, 1]);

  info(
    "Test that moving the hue slider with arrow keys emits color changed event."
  );
  // Tab to focus on alpha slider
  EventUtils.sendKey("Tab");
  is(
    doc.activeElement.className,
    "spectrum-alpha-input",
    "Alpha slider has successfully received focus."
  );
  testChangingColorShouldEmitEventsHelper(s, sendLeftKey, [128, 63, 63, 0.99]);
  testChangingColorShouldEmitEventsHelper(s, sendRightKey, [128, 63, 63, 1]);

  s.destroy();
}

function setSpectrumProps(spectrum, props, updateUI = true) {
  for (const prop in props) {
    spectrum[prop] = props[prop];

    // Setting textProps implies contrast should be enabled for spectrum
    if (prop === "textProps") {
      spectrum.contrastEnabled = true;
    }
  }

  if (updateUI) {
    spectrum.updateUI();
  }
}

function testAriaAttributesOnSpectrumElements(spectrum, colorName, rgbString) {
  for (const slider of [spectrum.dragger, spectrum.hueSlider]) {
    is(
      slider.getAttribute("aria-describedby"),
      "spectrum-dragger",
      "Slider contains the correct describedby text."
    );
    is(
      slider.getAttribute("aria-valuetext"),
      rgbString,
      "Slider contains the correct valuetext text."
    );
  }

  is(
    spectrum.colorPreview.title,
    colorName,
    "Spectrum element contains the correct title text."
  );
}

async function testSettingColorShoudUpdateTheUI(container) {
  const s = await createSpectrum(container, cssColors.white);
  const dragHelperOriginalPos = [
    s.dragHelper.style.top,
    s.dragHelper.style.left,
  ];
  const alphaSliderOriginalVal = s.alphaSlider.value;
  let hueSliderOriginalVal = s.hueSlider.value;

  setSpectrumProps(s, { rgb: [50, 240, 234, 0.2] });

  Assert.notEqual(
    s.alphaSlider.value,
    alphaSliderOriginalVal,
    "Alpha helper has moved"
  );
  Assert.notStrictEqual(
    s.dragHelper.style.top,
    dragHelperOriginalPos[0],
    "Drag helper has moved"
  );
  Assert.notStrictEqual(
    s.dragHelper.style.left,
    dragHelperOriginalPos[1],
    "Drag helper has moved"
  );
  Assert.notStrictEqual(
    s.hueSlider.value,
    hueSliderOriginalVal,
    "Hue helper has moved"
  );
  testAriaAttributesOnSpectrumElements(
    s,
    "Closest to: aqua",
    "rgba(50, 240, 234, 0.2)",
    0.2
  );

  hueSliderOriginalVal = s.hueSlider.value;

  setSpectrumProps(s, { rgb: ZERO_ALPHA_COLOR });
  is(s.alphaSlider.value, "0""Alpha range UI has been updated again");
  Assert.notStrictEqual(
    hueSliderOriginalVal,
    s.hueSlider.value,
    "Hue slider should have move again"
  );
  testAriaAttributesOnSpectrumElements(s, "aqua""rgba(0, 255, 255, 0)", 0);

  s.destroy();
}

async function testChangingColorShouldUpdateColorPreview(container) {
  const s = await createSpectrum(container, [0, 0, 1, 1]);

  info("Test that color preview is black.");
  testColorPreviewDisplay(s, "rgb(0, 0, 1)""transparent");

  info("Test that color preview is blue.");
  s.rgb = [0, 0, 255, 1];
  testColorPreviewDisplay(s, "rgb(0, 0, 255)""transparent");

  info("Test that color preview is red.");
  s.rgb = [255, 0, 0, 1];
  testColorPreviewDisplay(s, "rgb(255, 0, 0)""transparent");

  info("Test that color preview is white and also has a light grey border.");
  s.rgb = cssColors.white;
  testColorPreviewDisplay(s, "rgb(255, 255, 255)""rgb(204, 204, 204)");

  s.destroy();
}

async function testNotSettingTextPropsShouldNotShowContrastSection(container) {
  const s = await createSpectrum(container, cssColors.white);

  setSpectrumProps(s, { rgb: cssColors.black });
  ok(
    !s.spectrumContrast.classList.contains("visible"),
    "Contrast section is not shown."
  );

  s.destroy();
}

function testSpectrumContrast(
  spectrum,
  contrastValueEl,
  rgb,
  expectedValue,
  expectedBadgeClass = "",
  expectLargeTextIndicator = false
) {
  setSpectrumProps(spectrum, { rgb });

  is(
    contrastValueEl.textContent,
    expectedValue,
    "Contrast value has the correct text."
  );
  is(
    contrastValueEl.className,
    `accessibility-contrast-value${
      expectedBadgeClass ? " " + expectedBadgeClass : ""
    }`,
    `Contrast value contains ${expectedBadgeClass || "base"class.`
  );
  is(
    spectrum.contrastLabel.childNodes.length === 3,
    expectLargeTextIndicator,
    `Large text indicator is ${expectLargeTextIndicator ? "" : "not"} shown.`
  );
}

async function testSettingTextPropsAndColorShouldUpdateContrastValue(
  container
) {
  const s = await createSpectrum(container, cssColors.white);

  ok(
    !s.spectrumContrast.classList.contains("visible"),
    "Contrast value is not available yet."
  );

  info(
    "Test that contrast ratio is calculated on setting 'textProps' and 'rgb'."
  );
  setSpectrumProps(
    s,
    { textProps: REGULAR_TEXT_PROPS, backgroundColorData: SINGLE_BG_COLOR },
    false
  );
  testSpectrumContrast(s, s.contrastValue, [50, 240, 234, 0.8], "1.35", FAIL);

  info("Test that contrast ratio is updated when color is changed.");
  testSpectrumContrast(s, s.contrastValue, cssColors.black, "21.00", AAA);

  info("Test that contrast ratio cannot be calculated with zero alpha.");
  testSpectrumContrast(
    s,
    s.contrastValue,
    ZERO_ALPHA_COLOR,
    "Unable to calculate"
  );

  s.destroy();
}

async function testOnlySelectingLargeTextWithNonZeroAlphaShouldShowIndicator(
  container
) {
  let s = await createSpectrum(container, cssColors.white);

  Assert.notStrictEqual(
    s.contrastLabel.childNodes.length,
    3,
    "Large text indicator is initially hidden."
  );

  info(
    "Test that selecting large text with non-zero alpha shows large text indicator."
  );
  setSpectrumProps(
    s,
    {
      textProps: {
        "font-size": { value: "24px" },
        "font-weight": { value: "normal" },
        opacity: { value: "1" },
      },
      backgroundColorData: SINGLE_BG_COLOR,
    },
    false
  );
  testSpectrumContrast(s, s.contrastValue, cssColors.black, "21.00", AAA, true);

  info(
    "Test that selecting large text with zero alpha hides large text indicator."
  );
  testSpectrumContrast(
    s,
    s.contrastValue,
    ZERO_ALPHA_COLOR,
    "Unable to calculate"
  );

  // Spectrum should be closed and opened again to reflect changes in text size
  s.destroy();
  s = await createSpectrum(container, cssColors.white);

  info("Test that selecting regular text does not show large text indicator.");
  setSpectrumProps(
    s,
    { textProps: REGULAR_TEXT_PROPS, backgroundColorData: SINGLE_BG_COLOR },
    false
  );
  testSpectrumContrast(s, s.contrastValue, cssColors.black, "21.00", AAA);

  s.destroy();
}

async function testSettingMultiColoredBackgroundShouldShowContrastRange(
  container
) {
  const s = await createSpectrum(container, cssColors.white);

  info(
    "Test setting text with non-zero alpha and multi-colored bg shows contrast range and empty single contrast."
  );
  setSpectrumProps(
    s,
    {
      textProps: REGULAR_TEXT_PROPS,
      backgroundColorData: {
        min: cssColors.yellow,
        max: cssColors.green,
      },
    },
    false
  );
  testSpectrumContrast(s, s.contrastValueMin, cssColors.white, "1.07", FAIL);
  testSpectrumContrast(s, s.contrastValueMax, cssColors.white, "5.14", AA);
  testSpectrumContrast(s, s.contrastValue, cssColors.white, "");
  ok(
    s.spectrumContrast.classList.contains("range"),
    "Contrast section contains range class."
  );

  info("Test setting text with zero alpha shows error in contrast min span.");
  testSpectrumContrast(
    s,
    s.contrastValueMin,
    ZERO_ALPHA_COLOR,
    "Unable to calculate"
  );

  s.destroy();
}

async function createSpectrum(...spectrumConstructorParams) {
  const s = new Spectrum(...spectrumConstructorParams);
  await waitFor(() => s.dragger.offsetHeight > 0);
  s.show();
  return s;
}

96%


¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

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 ist noch experimentell.