Commit 87e2c021 authored by James Teh's avatar James Teh
Browse files

Bug 1829603 part 2: Include the src of images without names in the parent...

Bug 1829603 part 2: Include the src of images without names in the parent process a11y cache. r=morgan

This is used by some clients to help remediate inaccessible images.

Differential Revision: https://phabricator.services.mozilla.com/D176905
parent d1c3206f
Loading
Loading
Loading
Loading
+19 −1
Original line number Diff line number Diff line
@@ -1419,7 +1419,7 @@ void LocalAccessible::DOMAttributeChanged(int32_t aNameSpaceID,
    SendCache(CacheDomain::Actions, CacheUpdateType::Update);
  }

  if (aAttribute == nsGkAtoms::href) {
  if (aAttribute == nsGkAtoms::href || aAttribute == nsGkAtoms::src) {
    mDoc->QueueCacheUpdate(this, CacheDomain::Value);
  }

@@ -3208,6 +3208,24 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
        fields->SetAttribute(nsGkAtoms::aria_valuetext, DeleteEntry());
      }
    }

    if (IsImage()) {
      // Cache the src of images. This is used by some clients to help remediate
      // inaccessible images. If the image has a name, it's accessible, so this
      // isn't necessary.
      MOZ_ASSERT(mContent, "Image must have mContent");
      nsAutoString name;
      Name(name);
      if (name.IsEmpty()) {
        nsString src;
        mContent->AsElement()->GetAttr(kNameSpaceID_None, nsGkAtoms::src, src);
        if (!src.IsEmpty()) {
          fields->SetAttribute(nsGkAtoms::src, std::move(src));
        } else if (aUpdateType == CacheUpdateType::Update) {
          fields->SetAttribute(nsGkAtoms::src, DeleteEntry());
        }
      }
    }
  }

  if (aCacheDomain & CacheDomain::Viewport && IsDoc()) {
+8 −0
Original line number Diff line number Diff line
@@ -1427,6 +1427,14 @@ already_AddRefed<AccAttributes> RemoteAccessibleBase<Derived>::Attributes() {
    if (!className.IsEmpty()) {
      attributes->SetAttribute(nsGkAtoms::_class, std::move(className));
    }

    if (IsImage()) {
      nsString src;
      mCachedFields->GetAttribute(nsGkAtoms::src, src);
      if (!src.IsEmpty()) {
        attributes->SetAttribute(nsGkAtoms::src, std::move(src));
      }
    }
  }

  nsAutoString name;
+35 −0
Original line number Diff line number Diff line
@@ -603,3 +603,38 @@ addAccessibleTask(
  },
  { chrome: true, topLevel: true }
);

/**
 * Test the src attribute.
 */
const kImgUrl = "https://example.com/a11y/accessible/tests/mochitest/moz.png";
addAccessibleTask(
  `
<img id="noAlt" src="${kImgUrl}">
<img id="alt" alt="alt" src="${kImgUrl}">
<img id="mutate">
  `,
  async function(browser, docAcc) {
    const noAlt = findAccessibleChildByID(docAcc, "noAlt");
    testAttrs(noAlt, { src: kImgUrl }, true);
    if (isCacheEnabled && browser.isRemoteBrowser) {
      // To avoid wasting memory, we don't cache src if there's a name.
      const alt = findAccessibleChildByID(docAcc, "alt");
      testAbsentAttrs(alt, { src: "" });
    }

    const mutate = findAccessibleChildByID(docAcc, "mutate");
    testAbsentAttrs(mutate, { src: "" });
    info("Adding src to mutate");
    await invokeContentTask(browser, [kImgUrl], url => {
      content.document.getElementById("mutate").src = url;
    });
    await untilCacheAttrIs(mutate, "src", kImgUrl, "mutate src correct");
    info("Removing src from mutate");
    await invokeContentTask(browser, [], () => {
      content.document.getElementById("mutate").removeAttribute("src");
    });
    await untilCacheAttrAbsent(mutate, "src", "mutate src not present");
  },
  { chrome: true, topLevel: true }
);