Commit 89341e1b authored by Mark Striemer's avatar Mark Striemer
Browse files

Bug 1567600 - Part 1: Better accessibility for about:addons list view. r=flod,Gijs, a=RyanVM

Differential Revision: https://phabricator.services.mozilla.com/D40505

--HG--
extra : rebase_source : 6fc67e87ac72043c805b5e173548569e769ce0ad
extra : source : e8d69e4e6127503ebc595f1a962e3388d7bdc39f
extra : histedit_source : e6f7825ea5892198dbd1c4109b6223fa9019003b
parent dd50d572
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -124,9 +124,16 @@ addon-card[expanded] .addon-card-message {
  font-size: 16px;
  font-weight: 600;
  line-height: 22px;
  margin: 0;
  margin-inline-end: 8px;
}

.addon-name-link,
.addon-name-link:hover {
  color: var(--in-content-text-color);
  text-decoration: none;
}

.addon-badge {
  width: 16px;
  height: 16px;
+8 −4
Original line number Diff line number Diff line
@@ -56,10 +56,9 @@
      <div class="card addon">
        <img class="card-heading-image">
        <div class="addon-card-collapsed">
          <img class="card-heading-icon addon-icon">
          <img class="card-heading-icon addon-icon" alt="">
          <div class="card-contents">
            <div class="addon-name-container">
              <span class="addon-name"></span>
              <div class="addon-badge addon-badge-recommended"
                   data-l10n-id="addon-badge-recommended"
                   hidden></div>
@@ -67,10 +66,15 @@
                   data-l10n-id="addon-badge-private-browsing-allowed"
                   hidden></div>
            </div>
            <span class="addon-description"></span>
            <!-- This ends up in the tab order when the ellipsis happens, but it isn't necessary. -->
            <span class="addon-description" tabindex="-1"></span>
          </div>
          <div class="more-options-menu">
            <button class="more-options-button ghost-button" action="more-options"></button>
            <button
              class="more-options-button ghost-button"
              action="more-options"
              aria-haspopup="menu"
              aria-expanded="false"></button>
          </div>
        </div>
        <message-bar class="addon-card-message" align="center" hidden>
+20 −1
Original line number Diff line number Diff line
@@ -707,6 +707,7 @@ class PanelList extends HTMLElement {
  }

  onHide() {
    requestAnimationFrame(() => this.sendEvent("hidden"));
    this.removeHideListeners();
  }

@@ -1749,6 +1750,9 @@ class AddonCard extends HTMLElement {
      if (action == "more-options") {
        this.panel.toggle(e);
      }
    } else if (e.type === "shown" || e.type === "hidden") {
      let panelOpen = e.type === "shown";
      this.optionsButton.setAttribute("aria-expanded", panelOpen);
    }
  }

@@ -1843,7 +1847,7 @@ class AddonCard extends HTMLElement {
    }

    // Update the name.
    let name = card.querySelector(".addon-name");
    let name = this.addonNameEl;
    if (addon.isActive) {
      name.textContent = addon.name;
      name.removeAttribute("data-l10n-id");
@@ -1944,10 +1948,25 @@ class AddonCard extends HTMLElement {
    this.card = importTemplate("card").firstElementChild;
    this.setAttribute("addon-id", addon.id);

    let nameContainer = this.card.querySelector(".addon-name-container");
    let nameHeading = document.createElement("h3");
    nameHeading.classList.add("addon-name");
    if (!this.expanded) {
      let name = document.createElement("a");
      name.classList.add("addon-name-link");
      name.href = `addons://detail/${addon.id}`;
      nameHeading.appendChild(name);
      this.addonNameEl = name;
    } else {
      this.addonNameEl = nameHeading;
    }
    nameContainer.prepend(nameHeading);

    let panelType = addon.type == "plugin" ? "plugin-options" : "addon-options";
    this.options = document.createElement(panelType);
    this.options.render();
    this.card.querySelector(".more-options-menu").appendChild(this.options);
    this.optionsButton = this.card.querySelector(".more-options-button");

    // Set the contents.
    this.update();
+1 −1
Original line number Diff line number Diff line
@@ -303,7 +303,7 @@ add_task(async function testDetailOperations() {
  ok(expandButton.hidden, "The expand button is hidden");

  // Check toggling disabled.
  let name = card.querySelector(".addon-name");
  let name = card.addonNameEl;
  is(name.textContent, "Test", "The name is set when enabled");
  is(doc.l10n.getAttributes(name).id, "", "There is no l10n name");

+34 −5
Original line number Diff line number Diff line
@@ -96,11 +96,7 @@ add_task(async function testExtensionList() {
  ok(card, "The card is in the enabled section");

  // Check the properties of the card.
  is(
    card.querySelector(".addon-name").textContent,
    "Test extension",
    "The name is set"
  );
  is(card.addonNameEl.textContent, "Test extension", "The name is set");
  let icon = card.querySelector(".addon-icon");
  ok(icon.src.endsWith("/test-icon.png"), "The icon is set");

@@ -463,6 +459,39 @@ add_task(async function testKeyboardSupport() {
  await closeView(win);
});

add_task(async function testOpenDetailFromNameKeyboard() {
  let id = "details@mochi.test";
  let extension = ExtensionTestUtils.loadExtension({
    manifest: {
      name: "Detail extension",
      applications: { gecko: { id } },
    },
    useAddonManager: "temporary",
  });
  await extension.startup();

  let win = await loadInitialView("extension");

  let card = getCardByAddonId(win.document, id);

  info("focus the add-on's name, which should be an <a>");
  card.addonNameEl.focus();

  let detailsLoaded = waitForViewLoad(win);
  EventUtils.synthesizeKey("KEY_Enter", {}, win);
  await detailsLoaded;

  card = getCardByAddonId(win.document, id);
  is(
    card.addonNameEl.textContent,
    "Detail extension",
    "The right detail view is laoded"
  );

  await extension.unload();
  await closeView(win);
});

add_task(async function testExtensionReordering() {
  let extensions = createExtensions([
    { name: "Extension One" },
Loading