medialize / ally.js

JavaScript library to help modern web applications with accessibility concerns
http://allyjs.io/
MIT License
1.53k stars 82 forks source link

Investigate MathML #113

Open rodneyrehm opened 8 years ago

rodneyrehm commented 8 years ago

MathML is supported by Firefox and Safari and allows linking by mere existenence of an href attribute.

A quick test shows that links only work in Firefox, but are ignored in Safari 9.

Apparently MathML elements are instances of Element, which does not have Element.prototype.focus.

rodneyrehm commented 8 years ago

Blink 152430: Enabling support for MathML.

Even though MathML is not supported in Chrome, it does weird things to <math tabindex="0">. It looks like the element is added to the document's tabbing order, but lacks element.focus() (like Firefox and Internet Explorer on SVG elements), so should be considered only-tabbable.

rodneyrehm commented 8 years ago

<foobarxyz> is of type HTMLUnknownElement, while <math> is of type Element (in Firefox, Chrome, IE11 and Edge13).

Chrome used to have an implementation for MathML, but deactivated it. IE has never known MathML, but behaves the same way. Why?

remy commented 8 years ago

Have you tried using the XHTML strict doctype. IIRC it's what makes mathml work (or was one of the sole reasons to use XHTML, other than making you think this was x-men-html).

rodneyrehm commented 8 years ago

I have not tried the XHTML doctype, mostly because I assumed it was dead. That said, HTML5 should not be a problem?!

ttepasse commented 8 years ago

MathML has DOM Bindings for its elements. These bindings subclass only the general vanilla DOM for XML documents. HTML subclasses the same general DOM with a special interfaces in the inheritance tree for HTML-specific stuff. HTML elements and MathML elements still are in different families and live in different XML namespaces.

When the WHATWG imported MathML into HTML it didn't reassign MathML elements to the HTML namespace nor did it change the DOM bindings for the MathML elements. What it did in their strange vendetta against namespaces was some parser magic (⌘F here for “A start tag whose tag name is "math"”) to enable writing MathML in HTML syntax without writing xmlns namespace declarations.

Other non-specified elements that are not recognized foreign elements in HTML (= having a SVG or MathML namespace) get to live in the HTML namespace and the corresponding DOM node gets created as HTMLUnknownElement.

In short: XMLs concepts like namespaces still live on in the DOM, but the WHATWGification of the ecosystem made the notations much more irregular and less understandable.

Your example does what the current specifications proscibe, even it is not what a user would expect. (Apart from the mathml:href-Link in Safari, of course. Try an xlink:xhref, I believe Safari is still on MathML 2, presentation mode).

rodneyrehm commented 8 years ago

Safari does not respond to <math xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="…"> (with and without the xmlns declaration). Firefox handles both.


Summary of findings:


I'd say identifying the focusable (actually only-tabbable) items in order to remove them from the document's tabbing order in ally.element.disabled is all that's needed here.

rodneyrehm commented 8 years ago

https://www.peterkrautzberger.org/0186/ doesn't read like we need to support MathML…

Yaffle commented 4 years ago

Identifying MathML link support is impossible, hello UA sniffing…

var isSupported = container.querySelector(":link");
Yaffle commented 4 years ago

focus method was added as well as "MathMLElement" to the "MathML Core" specification - https://mathml-refresh.github.io/mathml-core/#dom-and-javascript

Chrome still does not support it, but I have came to a polyfill like this and would like to get your opinion:

// focus method polyfill for MathML elements in Chrome:
Element.prototype.focus = function () {
  console.assert(this.id !== '' && this.getAttribute('tabindex') === '0', 'the element should have id attribute and tabindex=0');
  var state = window.history.state;
  var href = window.location.href;
  window.location.replace('#' + this.id); //! this will focus the element
  window.history.replaceState(state, document.title, href);
};