{"version":3,"file":"AccessibilityManager.mjs","sources":["../src/AccessibilityManager.ts"],"sourcesContent":["import { extensions, ExtensionType, utils } from 'pixijs/core';\nimport { DisplayObject } from 'pixijs/display';\nimport { FederatedEvent } from 'pixijs/events';\nimport { accessibleTarget } from './accessibleTarget';\n\nimport type { ExtensionMetadata, IRenderer, Rectangle } from 'pixijs/core';\nimport type { Container } from 'pixijs/display';\nimport type { IAccessibleHTMLElement } from './accessibleTarget';\n\n// add some extra variables to the container..\nDisplayObject.mixin(accessibleTarget);\n\nconst KEY_CODE_TAB = 9;\n\nconst DIV_TOUCH_SIZE = 100;\nconst DIV_TOUCH_POS_X = 0;\nconst DIV_TOUCH_POS_Y = 0;\nconst DIV_TOUCH_ZINDEX = 2;\n\nconst DIV_HOOK_SIZE = 1;\nconst DIV_HOOK_POS_X = -1000;\nconst DIV_HOOK_POS_Y = -1000;\nconst DIV_HOOK_ZINDEX = 2;\n\n/**\n * The Accessibility manager recreates the ability to tab and have content read by screen readers.\n * This is very important as it can possibly help people with disabilities access PixiJS content.\n *\n * A DisplayObject can be made accessible just like it can be made interactive. This manager will map the\n * events as if the mouse was being used, minimizing the effort required to implement.\n *\n * An instance of this class is automatically created by default, and can be found at `renderer.plugins.accessibility`\n * @class\n * @memberof PIXI\n */\nexport class AccessibilityManager\n{\n    /** @ignore */\n    static extension: ExtensionMetadata = {\n        name: 'accessibility',\n        type: [\n            ExtensionType.RendererPlugin,\n            ExtensionType.CanvasRendererPlugin,\n        ],\n    };\n\n    /** Setting this to true will visually show the divs. */\n    public debug = false;\n\n    /**\n     * The renderer this accessibility manager works for.\n     * @type {PIXI.CanvasRenderer|PIXI.Renderer}\n     */\n    public renderer: IRenderer;\n\n    /** Internal variable, see isActive getter. */\n    private _isActive = false;\n\n    /** Internal variable, see isMobileAccessibility getter. */\n    private _isMobileAccessibility = false;\n\n    /** Button element for handling touch hooks. */\n    private _hookDiv: HTMLElement;\n\n    /** This is the dom element that will sit over the PixiJS element. This is where the div overlays will go. */\n    private div: HTMLElement;\n\n    /** A simple pool for storing divs. */\n    private pool: IAccessibleHTMLElement[] = [];\n\n    /** This is a tick used to check if an object is no longer being rendered. */\n    private renderId = 0;\n\n    /** The array of currently active accessible items. */\n    private children: DisplayObject[] = [];\n\n    /** Count to throttle div updates on android devices. */\n    private androidUpdateCount = 0;\n\n    /**  The frequency to update the div elements. */\n    private androidUpdateFrequency = 500; // 2fps\n\n    /**\n     * @param {PIXI.CanvasRenderer|PIXI.Renderer} renderer - A reference to the current renderer\n     */\n    constructor(renderer: IRenderer)\n    {\n        this._hookDiv = null;\n\n        if (utils.isMobile.tablet || utils.isMobile.phone)\n        {\n            this.createTouchHook();\n        }\n\n        // first we create a div that will sit over the PixiJS element. This is where the div overlays will go.\n        const div = document.createElement('div');\n\n        div.style.width = `${DIV_TOUCH_SIZE}px`;\n        div.style.height = `${DIV_TOUCH_SIZE}px`;\n        div.style.position = 'absolute';\n        div.style.top = `${DIV_TOUCH_POS_X}px`;\n        div.style.left = `${DIV_TOUCH_POS_Y}px`;\n        div.style.zIndex = DIV_TOUCH_ZINDEX.toString();\n\n        this.div = div;\n        this.renderer = renderer;\n\n        /**\n         * pre-bind the functions\n         * @type {Function}\n         * @private\n         */\n        this._onKeyDown = this._onKeyDown.bind(this);\n\n        /**\n         * pre-bind the functions\n         * @type {Function}\n         * @private\n         */\n        this._onMouseMove = this._onMouseMove.bind(this);\n\n        // let listen for tab.. once pressed we can fire up and show the accessibility layer\n        globalThis.addEventListener('keydown', this._onKeyDown, false);\n    }\n\n    /**\n     * Value of `true` if accessibility is currently active and accessibility layers are showing.\n     * @member {boolean}\n     * @readonly\n     */\n    get isActive(): boolean\n    {\n        return this._isActive;\n    }\n\n    /**\n     * Value of `true` if accessibility is enabled for touch devices.\n     * @member {boolean}\n     * @readonly\n     */\n    get isMobileAccessibility(): boolean\n    {\n        return this._isMobileAccessibility;\n    }\n\n    /**\n     * Creates the touch hooks.\n     * @private\n     */\n    private createTouchHook(): void\n    {\n        const hookDiv = document.createElement('button');\n\n        hookDiv.style.width = `${DIV_HOOK_SIZE}px`;\n        hookDiv.style.height = `${DIV_HOOK_SIZE}px`;\n        hookDiv.style.position = 'absolute';\n        hookDiv.style.top = `${DIV_HOOK_POS_X}px`;\n        hookDiv.style.left = `${DIV_HOOK_POS_Y}px`;\n        hookDiv.style.zIndex = DIV_HOOK_ZINDEX.toString();\n        hookDiv.style.backgroundColor = '#FF0000';\n        hookDiv.title = 'select to enable accessibility for this content';\n\n        hookDiv.addEventListener('focus', () =>\n        {\n            this._isMobileAccessibility = true;\n            this.activate();\n            this.destroyTouchHook();\n        });\n\n        document.body.appendChild(hookDiv);\n        this._hookDiv = hookDiv;\n    }\n\n    /**\n     * Destroys the touch hooks.\n     * @private\n     */\n    private destroyTouchHook(): void\n    {\n        if (!this._hookDiv)\n        {\n            return;\n        }\n        document.body.removeChild(this._hookDiv);\n        this._hookDiv = null;\n    }\n\n    /**\n     * Activating will cause the Accessibility layer to be shown.\n     * This is called when a user presses the tab key.\n     * @private\n     */\n    private activate(): void\n    {\n        if (this._isActive)\n        {\n            return;\n        }\n\n        this._isActive = true;\n\n        globalThis.document.addEventListener('mousemove', this._onMouseMove, true);\n        globalThis.removeEventListener('keydown', this._onKeyDown, false);\n\n        this.renderer.on('postrender', this.update, this);\n        this.renderer.view.parentNode?.appendChild(this.div);\n    }\n\n    /**\n     * Deactivating will cause the Accessibility layer to be hidden.\n     * This is called when a user moves the mouse.\n     * @private\n     */\n    private deactivate(): void\n    {\n        if (!this._isActive || this._isMobileAccessibility)\n        {\n            return;\n        }\n\n        this._isActive = false;\n\n        globalThis.document.removeEventListener('mousemove', this._onMouseMove, true);\n        globalThis.addEventListener('keydown', this._onKeyDown, false);\n\n        this.renderer.off('postrender', this.update);\n        this.div.parentNode?.removeChild(this.div);\n    }\n\n    /**\n     * This recursive function will run through the scene graph and add any new accessible objects to the DOM layer.\n     * @private\n     * @param {PIXI.Container} displayObject - The DisplayObject to check.\n     */\n    private updateAccessibleObjects(displayObject: Container): void\n    {\n        if (!displayObject.visible || !displayObject.accessibleChildren)\n        {\n            return;\n        }\n\n        if (displayObject.accessible && displayObject.interactive)\n        {\n            if (!displayObject._accessibleActive)\n            {\n                this.addChild(displayObject);\n            }\n\n            displayObject.renderId = this.renderId;\n        }\n\n        const children = displayObject.children;\n\n        if (children)\n        {\n            for (let i = 0; i < children.length; i++)\n            {\n                this.updateAccessibleObjects(children[i] as Container);\n            }\n        }\n    }\n\n    /**\n     * Before each render this function will ensure that all divs are mapped correctly to their DisplayObjects.\n     * @private\n     */\n    private update(): void\n    {\n        /* On Android default web browser, tab order seems to be calculated by position rather than tabIndex,\n        *  moving buttons can cause focus to flicker between two buttons making it hard/impossible to navigate,\n        *  so I am just running update every half a second, seems to fix it.\n        */\n        const now = performance.now();\n\n        if (utils.isMobile.android.device && now < this.androidUpdateCount)\n        {\n            return;\n        }\n\n        this.androidUpdateCount = now + this.androidUpdateFrequency;\n\n        if (!this.renderer.renderingToScreen)\n        {\n            return;\n        }\n\n        // update children...\n        if (this.renderer.lastObjectRendered)\n        {\n            this.updateAccessibleObjects(this.renderer.lastObjectRendered as Container);\n        }\n\n        const { x, y, width, height } = this.renderer.view.getBoundingClientRect();\n        const { width: viewWidth, height: viewHeight, resolution } = this.renderer;\n\n        const sx = (width / viewWidth) * resolution;\n        const sy = (height / viewHeight) * resolution;\n\n        let div = this.div;\n\n        div.style.left = `${x}px`;\n        div.style.top = `${y}px`;\n        div.style.width = `${viewWidth}px`;\n        div.style.height = `${viewHeight}px`;\n\n        for (let i = 0; i < this.children.length; i++)\n        {\n            const child = this.children[i];\n\n            if (child.renderId !== this.renderId)\n            {\n                child._accessibleActive = false;\n\n                utils.removeItems(this.children, i, 1);\n                this.div.removeChild(child._accessibleDiv);\n                this.pool.push(child._accessibleDiv);\n                child._accessibleDiv = null;\n\n                i--;\n            }\n            else\n            {\n                // map div to display..\n                div = child._accessibleDiv;\n                let hitArea = child.hitArea as Rectangle;\n                const wt = child.worldTransform;\n\n                if (child.hitArea)\n                {\n                    div.style.left = `${(wt.tx + (hitArea.x * wt.a)) * sx}px`;\n                    div.style.top = `${(wt.ty + (hitArea.y * wt.d)) * sy}px`;\n\n                    div.style.width = `${hitArea.width * wt.a * sx}px`;\n                    div.style.height = `${hitArea.height * wt.d * sy}px`;\n                }\n                else\n                {\n                    hitArea = child.getBounds();\n\n                    this.capHitArea(hitArea);\n\n                    div.style.left = `${hitArea.x * sx}px`;\n                    div.style.top = `${hitArea.y * sy}px`;\n\n                    div.style.width = `${hitArea.width * sx}px`;\n                    div.style.height = `${hitArea.height * sy}px`;\n\n                    // update button titles and hints if they exist and they've changed\n                    if (div.title !== child.accessibleTitle && child.accessibleTitle !== null)\n                    {\n                        div.title = child.accessibleTitle;\n                    }\n                    if (div.getAttribute('aria-label') !== child.accessibleHint\n                        && child.accessibleHint !== null)\n                    {\n                        div.setAttribute('aria-label', child.accessibleHint);\n                    }\n                }\n\n                // the title or index may have changed, if so lets update it!\n                if (child.accessibleTitle !== div.title || child.tabIndex !== div.tabIndex)\n                {\n                    div.title = child.accessibleTitle;\n                    div.tabIndex = child.tabIndex;\n                    if (this.debug) this.updateDebugHTML(div);\n                }\n            }\n        }\n\n        // increment the render id..\n        this.renderId++;\n    }\n\n    /**\n     * private function that will visually add the information to the\n     * accessability div\n     * @param {HTMLElement} div -\n     */\n    public updateDebugHTML(div: IAccessibleHTMLElement): void\n    {\n        div.innerHTML = `type: ${div.type}</br> title : ${div.title}</br> tabIndex: ${div.tabIndex}`;\n    }\n\n    /**\n     * Adjust the hit area based on the bounds of a display object\n     * @param {PIXI.Rectangle} hitArea - Bounds of the child\n     */\n    public capHitArea(hitArea: Rectangle): void\n    {\n        if (hitArea.x < 0)\n        {\n            hitArea.width += hitArea.x;\n            hitArea.x = 0;\n        }\n\n        if (hitArea.y < 0)\n        {\n            hitArea.height += hitArea.y;\n            hitArea.y = 0;\n        }\n\n        const { width: viewWidth, height: viewHeight } = this.renderer;\n\n        if (hitArea.x + hitArea.width > viewWidth)\n        {\n            hitArea.width = viewWidth - hitArea.x;\n        }\n\n        if (hitArea.y + hitArea.height > viewHeight)\n        {\n            hitArea.height = viewHeight - hitArea.y;\n        }\n    }\n\n    /**\n     * Adds a DisplayObject to the accessibility manager\n     * @private\n     * @param {PIXI.DisplayObject} displayObject - The child to make accessible.\n     */\n    private addChild<T extends DisplayObject>(displayObject: T): void\n    {\n        //    this.activate();\n\n        let div = this.pool.pop();\n\n        if (!div)\n        {\n            div = document.createElement('button');\n\n            div.style.width = `${DIV_TOUCH_SIZE}px`;\n            div.style.height = `${DIV_TOUCH_SIZE}px`;\n            div.style.backgroundColor = this.debug ? 'rgba(255,255,255,0.5)' : 'transparent';\n            div.style.position = 'absolute';\n            div.style.zIndex = DIV_TOUCH_ZINDEX.toString();\n            div.style.borderStyle = 'none';\n\n            // ARIA attributes ensure that button title and hint updates are announced properly\n            if (navigator.userAgent.toLowerCase().includes('chrome'))\n            {\n                // Chrome doesn't need aria-live to work as intended; in fact it just gets more confused.\n                div.setAttribute('aria-live', 'off');\n            }\n            else\n            {\n                div.setAttribute('aria-live', 'polite');\n            }\n\n            if (navigator.userAgent.match(/rv:.*Gecko\\//))\n            {\n                // FireFox needs this to announce only the new button name\n                div.setAttribute('aria-relevant', 'additions');\n            }\n            else\n            {\n                // required by IE, other browsers don't much care\n                div.setAttribute('aria-relevant', 'text');\n            }\n\n            div.addEventListener('click', this._onClick.bind(this));\n            div.addEventListener('focus', this._onFocus.bind(this));\n            div.addEventListener('focusout', this._onFocusOut.bind(this));\n        }\n\n        // set pointer events\n        div.style.pointerEvents = displayObject.accessiblePointerEvents;\n        // set the type, this defaults to button!\n        div.type = displayObject.accessibleType;\n\n        if (displayObject.accessibleTitle && displayObject.accessibleTitle !== null)\n        {\n            div.title = displayObject.accessibleTitle;\n        }\n        else if (!displayObject.accessibleHint\n                 || displayObject.accessibleHint === null)\n        {\n            div.title = `displayObject ${displayObject.tabIndex}`;\n        }\n\n        if (displayObject.accessibleHint\n            && displayObject.accessibleHint !== null)\n        {\n            div.setAttribute('aria-label', displayObject.accessibleHint);\n        }\n\n        if (this.debug) this.updateDebugHTML(div);\n\n        displayObject._accessibleActive = true;\n        displayObject._accessibleDiv = div;\n        div.displayObject = displayObject;\n\n        this.children.push(displayObject);\n        this.div.appendChild(displayObject._accessibleDiv);\n        displayObject._accessibleDiv.tabIndex = displayObject.tabIndex;\n    }\n\n    /**\n     * Dispatch events with the EventSystem.\n     * @param e\n     * @param type\n     * @private\n     */\n    private _dispatchEvent(e: UIEvent, type: string[]): void\n    {\n        const { displayObject: target } = e.target as IAccessibleHTMLElement;\n        const boundry = this.renderer.events.rootBoundary;\n        const event: FederatedEvent = Object.assign(new FederatedEvent(boundry), { target });\n\n        boundry.rootTarget = this.renderer.lastObjectRendered as DisplayObject;\n        type.forEach((type) => boundry.dispatchEvent(event, type));\n    }\n\n    /**\n     * Maps the div button press to pixi's EventSystem (click)\n     * @private\n     * @param {MouseEvent} e - The click event.\n     */\n    private _onClick(e: MouseEvent): void\n    {\n        this._dispatchEvent(e, ['click', 'pointertap', 'tap']);\n    }\n\n    /**\n     * Maps the div focus events to pixi's EventSystem (mouseover)\n     * @private\n     * @param {FocusEvent} e - The focus event.\n     */\n    private _onFocus(e: FocusEvent): void\n    {\n        if (!(e.target as Element).getAttribute('aria-live'))\n        {\n            (e.target as Element).setAttribute('aria-live', 'assertive');\n        }\n\n        this._dispatchEvent(e, ['mouseover']);\n    }\n\n    /**\n     * Maps the div focus events to pixi's EventSystem (mouseout)\n     * @private\n     * @param {FocusEvent} e - The focusout event.\n     */\n    private _onFocusOut(e: FocusEvent): void\n    {\n        if (!(e.target as Element).getAttribute('aria-live'))\n        {\n            (e.target as Element).setAttribute('aria-live', 'polite');\n        }\n\n        this._dispatchEvent(e, ['mouseout']);\n    }\n\n    /**\n     * Is called when a key is pressed\n     * @private\n     * @param {KeyboardEvent} e - The keydown event.\n     */\n    private _onKeyDown(e: KeyboardEvent): void\n    {\n        if (e.keyCode !== KEY_CODE_TAB)\n        {\n            return;\n        }\n\n        this.activate();\n    }\n\n    /**\n     * Is called when the mouse moves across the renderer element\n     * @private\n     * @param {MouseEvent} e - The mouse event.\n     */\n    private _onMouseMove(e: MouseEvent): void\n    {\n        if (e.movementX === 0 && e.movementY === 0)\n        {\n            return;\n        }\n\n        this.deactivate();\n    }\n\n    /** Destroys the accessibility manager */\n    public destroy(): void\n    {\n        this.destroyTouchHook();\n        this.div = null;\n\n        globalThis.document.removeEventListener('mousemove', this._onMouseMove, true);\n        globalThis.removeEventListener('keydown', this._onKeyDown);\n\n        this.pool = null;\n        this.children = null;\n        this.renderer = null;\n    }\n}\n\nextensions.add(AccessibilityManager);\n"],"names":[],"mappings":"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"}