main/IframeAccessibility.js

/**
 * Some 3rd party iframes render without a 'title' attribute
 * For accessibility, we are adding 'title' to them on our end
 *
 * @module IframeAccessibility
 * @prop {Array} oEmbedSelectors - DOM element selectors for oEmbed container div
 * @prop {Array} shortcodeSelectors - DOM element selectors for
 * WP native shortcodes rendering without 'title'
 * @prop {Array} adSelectors - DOM element selectors for ad iframes
 * @prop {Object} iframes - Object of found iframes organised by selectors
 * @prop {Object} adIframes - Object of found ad iframes organised by adSelectors
 */
const IframeAccessibility = {
	oEmbedSelectors: ['embed-instagram', 'embed-youtube', 'embed-soundcloud', 'exco'],

	shortcodeSelectors: ['scribd', 'protected-iframe', 'wayin', 'googlemaps'],

	adSelectors: ['#fsk_frame_splitbox', '.display-frame'],

	iframes: {},

	adIframes: {},

	/**
	 * Find any embed iframes by type
	 *
	 * @method init
	 */
	init() {
		setTimeout( () => {
			Object.keys( this.oEmbedSelectors ).forEach( ( key ) => {
				let selector = this.oEmbedSelectors[key];
				const instances = document.querySelectorAll( `.${selector}` );
				// Playbuzz oEmbeds render without the class like 'embed-playbuzz',
				// but container div has class 'exco'
				if ( 'exco' === selector ) {
					selector = 'playbuzz';
				}
				this.iframes[selector] = instances;
			});

			Object.keys( this.shortcodeSelectors ).forEach( ( key ) => {
				const selector = this.shortcodeSelectors[key];
				const instances = document.querySelectorAll( `[data-shortcode="${selector}"]` );
				this.iframes[selector] = instances;
			});

			Object.keys( this.iframes ).forEach( ( key ) => {
				const iframesArray = this.iframes[key];
				if ( 0 < iframesArray.length ) {
					// Let iframes render before checking the title
					this.addTitle( key, iframesArray );
				}
			});
		}, 5000 );

		setTimeout( () => {
			Object.keys( this.adSelectors ).forEach( ( key ) => {
				const selector = this.adSelectors[key];
				const instances = document.querySelectorAll( selector );
				this.adIframes[selector] = instances;
			});

			Object.keys( this.adIframes ).forEach( ( key ) => {
				const iframesArray = this.adIframes[key];
				if ( 0 < iframesArray.length ) {
					this.addAdIframeTitle( iframesArray );
				}
			});
		}, 5000 );
	},

	addTitle( type, $iframes ) {
		let count = 1;
		Object.keys( $iframes ).forEach( ( key ) => {
			const $iframeContainer = $iframes[key];
			const $iframe = $iframeContainer.querySelector( 'iframe' );
			if ( $iframe ) {
				// Check if it has title
				// It is possible that provider might add title in the future
				// so we don't want to override it
				let title = $iframe.getAttribute( 'title' );
				if ( title ) {
					return;
				}
				// If there is no title, add one
				let embedName = type.replace( 'embed-', '' );
				embedName = embedName.replace( '-', ' ' );
				title = `${embedName} embed ${count}`;
				$iframe.setAttribute( 'title', title );
				count += 1;
			}
		});
	},

	addAdIframeTitle( $iframes ) {
		let count = 1;
		Object.keys( $iframes ).forEach( ( key ) => {
			const $iframe = $iframes[key];
			if ( $iframe ) {
				// Check if it has title
				// It is possible that provider might add title in the future
				// so we don't want to override it
				const title = $iframe.getAttribute( 'title' );
				if ( title ) {
					return;
				}
				$iframe.setAttribute( 'title', `3rd party iframe ${count}` );
				count += 1;
			}
		});
	},
};

export default IframeAccessibility;