import setAttributes from '../dom/set-attributes';
const el = {
containers: [],
};
const state = {
previousMessage: '',
};
/**
* @ignore
*/
const addContainer = ( ariaLive = 'polite' ) => {
const container = document.createElement( 'div' );
setAttributes( container, {
'aria-live': ariaLive,
'aria-relevant': 'additions text',
'aria-atomic': 'true',
style: `position: absolute; margin: -1px; padding: 0; height: 1px; width: 1px; overflow: hidden; clip: rect(1px, 1px, 1px, 1px); -webkit-clip-path: inset(50%); clip-path: inset(50%); border: 0; word-wrap: normal !important;`,
} );
document.body.appendChild( container );
el.containers.push( container );
};
/**
* @ignore
*/
const filterMessage = ( message = '' ) => {
let cleanedMessage = message.replace( /<[^<>]+>/g, ' ' );
if ( state.previousMessage === cleanedMessage ) {
cleanedMessage += '\u00A0';
}
state.previousMessage = cleanedMessage;
return cleanedMessage;
};
/**
* @ignore
*/
const clear = () => el.containers.forEach( ( container ) => container.textContent = '' );
/**
* @ignore
*/
const setup = () => {
if ( el.containers.length ) {
return;
}
addContainer( 'assertive' );
addContainer( 'polite' );
};
/**
* @module speak
* @description A shortened and custom variation of wp.a11y.speak that is lighter on the dom.
*
* @since 1.0.0
*
* @param {string} message The message to announce.
* @param {string} ariaLive The aria-live type attribute. Assertive or polite.
*
* @requires setAttributes
*
* @return {void}
*
* @example
* import { speak } from "@gravityforms/utils";
*
* function Example() {
* speak( i18n.example, 'polite' );
* }
*
*/
export default function speak( message = '', ariaLive = 'polite' ) {
setup();
clear();
const target = el.containers.filter( ( container ) => container.getAttribute( 'aria-live' ) === ariaLive )[ 0 ];
if ( target ) {
target.textContent = filterMessage( message );
}
}