e
 
JSConf, Singapore June 2019
Léonie Watson, TetraLogical
HTML > DOM > Accessibility Tree > User Interface
<button> element<button>Play</button><button> element<button>Play</button><button> element<button> element 
class CustomButton extends HTMLButtonElement {
    constructor() {
        super();
    }
}
customElements.define("custom-button", CustomButton, { extends: "button" });connectedCallback() {
    this.addEventListener("click", doSomething);
}is attribute<button is="custom-button">Play</button>is attribute<button is="custom-button">Play</button>is attributeis="custom-button" attributeclass ToggleButton extends HTMLElement {
    constructor() {
        super();
    }
}
customElements.define("toggle-button", ToggleButton);connectedCallback() {
    this.setAttribute("role", "button");
    this.setAttribute("tabindex", "0");
    this.setAttribute("aria-pressed", "false");
    this.addEventListener("click", togglePressed);
    this.addEventListener("keydown", function (e) {
        if (e.keyCode == 13 || e.keyCode == 32) {
            togglePressed();
        }
    });
}<toggle-button> elementfunction togglePressed() {
    if (this.getAttribute("aria-pressed") == "false") {
        this.setAttribute("aria-pressed", "true");
    } else {
        this.setAttribute("aria-pressed", "false");
    }
}<toggle-button> element<toggle-button>Play</toggle-button><toggle-button> element<toggle-button role="button" tabindex="0" aria-pressed="false">Play</toggle-button><toggle-button> element<toggle-button> elementWeb Platform Incubator Community Group (WICG)
https://wicg.github.io/aom
Will enable reflection of:
Adds two interface mixins to ARIA 1.2
connectedCallback() {
    this.role = "button";
    this.tabIndex = "0";
    this.ariaPressed = "false";
    ...
}connectedCallback() {
    this.ariaDescribedByElements = [description1];
    ...
}https://w3c-test.org/wai-aria/idlharness.window.html
|  |  |  |  | 
| Chrome | Edge (Chromium beta) | Firefox | Safari | 
| 65/95 | 65/95 | 1/95 | 79/95 | 
Will enable semantics to be provided in two ways:
class ToggleButton extends HTMLElement {
    constructor() {
        super();
    }
}
customElements.define("toggle-button", ToggleButton, { role: "button", tabIndex: "0" });class ToggleButton extends HTMLElement {
    var internals = null;
	constructor() {
        super();
        this.internals = customElements.createInternals(this);
        this.internals.ariaPressed = "false";
    }
}
customElements.define("toggle-button", ToggleButton, { role: "button", tabIndex: "0" });Will enable listening for Assistive Technology (AT) events
To protect AT user privacy, AT events will trigger synthesized DOM events
New AT events will be introduced:
Will allow virtual nodes to be added to the accessibility tree
Will provide access to:
<speak-content> element<speak-content>
    <span slot="control">Speak this</span>
    <div slot="speak">1 tequila... 2 tequila... 3 tequila... floor!</div>
</speak-content>class SpeakContent extends HTMLElement {
    constructor() {
        super();
        this.attachShadow({ mode: "open" });
        this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
}
const template = document.createElement("template");
template.innerHTML = `<style> ... </style>
                      <button id="control">
                        <slot name="control"></slot>
                      </button>
                      <slot name="speak" id="speak"></slot>`;
customElements.define("speak-content", SpeakContent);   connectedCallback() {
        var control = this.shadowRoot.querySelector("button");
        control.setAttribute("aria-pressed", "false");
        var speak = this.querySelector("div");
        var speakContent = speak.textContent;
        control.addEventListener("click", speakThis);
    }    function speakThis(e) {
        if (control.getAttribute("aria-pressed") == "false") {
            control.setAttribute("aria-pressed", "true");
            var utterance = new SpeechSynthesisUtterance();
            utterance.text = speakContent;
            window.speechSynthesis.speak(utterance);
            setTimeout(resetPressedState, 500);
        }
    }    function resetPressedState() {
        if (window.speechSynthesis.speaking === false) {
            control.setAttribute("aria-pressed", "false");
        }
        else {
            setTimeout(resetPressedState, 500);
        }
    }const template = document.createElement("template");
template.innerHTML = 
    `<style>
    ...
    #control[aria-pressed="true"] {
        color: #fff;
        padding: 11px 12px 9px 16px;
        text-shadow: 0 -1px 0 #444, 0 0 5px #ffd, 0 0 8px #fff;
        box-shadow: 0 1px 0 #666, 0 2px 0 #444, 0 2px 2px rgba(0, 0, 0, 0.9);
    }
    ...
    </style>`;<speak-content> elementLéonie Watson, TetraLogical