Commit 0787850e authored by James Teh's avatar James Teh
Browse files

Bug 1759971: Support MathML on a cached RemoteAccessible for Windows a11y clients. r=morgan

Windows a11y clients retrieve MathML markup using ISimpleDOMNode::innerHTML.
We cache innerHTML to support this, but only on math elements and only on Windows.
sdnAccessible had to be modified to support RemoteAccessible and to use the cache for this method.

Differential Revision: https://phabricator.services.mozilla.com/D155806
parent 551e1f9b
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -31,6 +31,10 @@ class CacheDomain {
  static constexpr uint64_t Viewport = ((uint64_t)0x1) << 14;
  static constexpr uint64_t ARIA = ((uint64_t)0x1) << 15;
  static constexpr uint64_t Relations = ((uint64_t)0x1) << 16;
#ifdef XP_WIN
  // Used for MathML.
  static constexpr uint64_t InnerHTML = ((uint64_t)0x1) << 17;
#endif
  static constexpr uint64_t All = ~((uint64_t)0x0);
};

+23 −0
Original line number Diff line number Diff line
@@ -2502,6 +2502,20 @@ void LocalAccessible::BindToParent(LocalAccessible* aParent,
    // for the next tick before the cache update is sent.
    mDoc->QueueCacheUpdate(aParent, CacheDomain::Table);
  }

#if defined(XP_WIN)
  if (StaticPrefs::accessibility_cache_enabled_AtStartup() &&
      aParent->HasOwnContent() && aParent->mContent->IsMathMLElement()) {
    // For any change in a MathML subtree, update the innerHTML cache on the
    // root math element.
    for (LocalAccessible* acc = aParent; acc; acc = acc->LocalParent()) {
      if (acc->HasOwnContent() &&
          acc->mContent->IsMathMLElement(nsGkAtoms::math)) {
        mDoc->QueueCacheUpdate(acc, CacheDomain::InnerHTML);
      }
    }
  }
#endif  // defined(XP_WIN)
}

// LocalAccessible protected
@@ -3598,6 +3612,15 @@ already_AddRefed<AccAttributes> LocalAccessible::BundleFieldsForCache(
    }
  }

#if defined(XP_WIN)
  if (aCacheDomain & CacheDomain::InnerHTML && HasOwnContent() &&
      mContent->IsMathMLElement(nsGkAtoms::math)) {
    nsString innerHTML;
    mContent->AsElement()->GetInnerHTML(innerHTML, IgnoreErrors());
    fields->SetAttribute(nsGkAtoms::html, std::move(innerHTML));
  }
#endif  // defined(XP_WIN)

  if (aUpdateType == CacheUpdateType::Initial) {
    // Add fields which never change and thus only need to be included in the
    // initial cache push.
+3 −0
Original line number Diff line number Diff line
@@ -408,6 +408,9 @@ class RemoteAccessibleBase : public Accessible, public HyperTextAccessibleBase {
  friend HyperTextAccessibleBase;
  friend class xpcAccessible;
  friend class CachedTableCellAccessible;
#ifdef XP_WIN
  friend class sdnAccessible;
#endif

  nsTArray<Derived*> mChildren;
  DocAccessibleParent* mDoc;
+2 −0
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ skip-if =
[browser_caching_attributes.js]
[browser_caching_description.js]
[browser_caching_document_props.js]
[browser_caching_innerHTML.js]
skip-if = os != 'win'
[browser_caching_name.js]
skip-if = (os == "linux" && bits == 64) || (debug && os == "mac") || (debug && os == "win") #Bug 1388256
[browser_caching_relations.js]
+55 −0
Original line number Diff line number Diff line
/* 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";

/**
 * Test caching of innerHTML on math elements for Windows clients.
 */
addAccessibleTask(
  `
<p id="p">test</p>
<math id="math"><mfrac><mi>x</mi><mi>y</mi></mfrac></math>
  `,
  async function(browser, docAcc) {
    if (!isCacheEnabled) {
      // Stop the harness from complaining that this file is empty when run with
      // the cache disabled.
      todo(false, "Cache disabled for a cache only test");
      return;
    }

    const p = findAccessibleChildByID(docAcc, "p");
    let hasHtml;
    try {
      p.cache.getStringProperty("html");
      hasHtml = true;
    } catch (e) {
      hasHtml = false;
    }
    ok(!hasHtml, "p doesn't have cached html");

    const math = findAccessibleChildByID(docAcc, "math");
    is(
      math.cache.getStringProperty("html"),
      "<mfrac><mi>x</mi><mi>y</mi></mfrac>",
      "math cached html is correct"
    );

    info("Mutating math");
    await invokeContentTask(browser, [], () => {
      content.document.querySelectorAll("mi")[1].textContent = "z";
    });
    await untilCacheIs(
      () => math.cache.getStringProperty("html"),
      "<mfrac><mi>x</mi><mi>z</mi></mfrac>",
      "math cached html is correct after mutation"
    );
  },
  {
    topLevel: true,
    iframe: isCacheEnabled,
    remoteIframe: isCacheEnabled,
  }
);
Loading