article/FontSizer.js

import Cookies from '../vendor/jscookie';

/**
 * Font Sizer
 *
 * @example
 * <div class="c-fontSizer">
 *	<button class="c-fontSizer__button c-fontSizer__button--decrease">
 *		<span class="sr-only">Descrease article font</span>
 *		<div class="c-fontSizer__letter">-A</div>
 *	</button>
 *	<button class="c-fontSizer__button c-fontSizer__button--increase">
 *		<span class="sr-only">Increase article font</span>
 *		<div class="c-fontSizer__letter">A+</div>
 *	</button>
 * </div>
 *
 *
 * Allows user to increase or decrease article font size between 8px and 30px
 *
 * @module FontSizer
 * @prop {Element} fontSizer - DOM reference to font sizer button container
 * @prop {Element} fontIncrease - DOM reference to text increase button
 * @prop {Element} fontDecrease - DOM reference to text decrease button
 * @prop {String} storedValue - Font size cookie
 * @prop {Element} storyText - DOM reference to story text container
 * @prop {Integer} size - Font size is initially set to 16, then overriden by cookie if it's set.
 * @prop {Integer} magnifyCount - Number tracking the font increase or decrease for analytics
 * @prop {String} context - Text created for analytics when font size is increased or decreased
 */
const FontSizer = {
	fontSizer: null,
	fontIncrease: null,
	fontDecrease: null,
	storedValue: null,
	storyTextElements: [],
	size: 18,
	magnifyCount: 0,
	context: null,

	/**
	 * Initializes font sizer on the page
	 *
	 * @method init
	 */
	init() {
		this.fontSizer = document.querySelector( '.c-fontSizer' );
		this.fontIncrease = document.querySelector( '.c-fontSizer__button--increase' );
		this.fontDecrease = document.querySelector( '.c-fontSizer__button--decrease' );
		this.storedValue = parseFloat( Cookies.get( 'article-font-size' ) );
		this.storyTextElements = document.querySelectorAll( '.js-story-text' );

		/* If the font sizer buttons are not on the page, then don't bother running the plugin */
		if ( ! this.fontSizer ) {
			return;
		}

		/* Bail Iif there is no text that should be affected by font sizer buttons */
		if ( 0 === this.storyTextElements.length ) {
			return;
		}

		// Set current text size to article
		if ( this.storedValue ) {
			this.modifyFontSize( this.storedValue, false );
		}

		// Set up click events on the increase/decrease buttons
		this.fontIncrease.addEventListener( 'click', () => {
			this.modifyFontSize( this.size + 2, true );
			this.magnifyCount = this.magnifyCount + 1;
		});

		this.fontDecrease.addEventListener( 'click', () => {
			this.modifyFontSize( this.size - 2, true );
			this.magnifyCount = this.magnifyCount - 1;
		});
	},

	/**
	 * Increases or decreases font size and line height. Sets font size cookie.
	 *
	 * @method modifyFontSize
	 * @param {integer} size - updated font size
	 * @param {boolean} shouldSave - true if cookie needs to be saved
	 */
	modifyFontSize( size, shouldSave ) {
		if ( size <= 30 && size >= 14 ) {
			this.size = size;

			// Note: IE11 does not support .forEach method on Object, use Object.keys
			Object.keys( this.storyTextElements ).forEach( ( key ) => {
				const $element = this.storyTextElements[key];
				$element.style.fontSize = `${this.size}px`;
				$element.style.lineHeight = `${this.size + this.size * 0.5}px`;
			});

			if ( shouldSave ) {
				Cookies.set( 'article-font-size', String( this.size ), { path: '/' });
			}
		}
	},
};

export default FontSizer;