Source: lang/Goog.js

/**
 * @module nyc/lang/Goog
 */

import $ from 'jquery'

import Translate from 'nyc/lang/Translate'

/**
 * @desc Class for language translation using the Google Translate Gadget
 * @public
 * @class
 * @extends module:nyc/lang/Translate~Translate
 * @constructor
 * @fires module:nyc/lang/Translate~Translate#ready
 * @fires module:nyc/lang/Translate~Translate#change
 */
class Goog extends Translate {
  /**
   * @desc Create an instance of Goog
   * @public
   * @constructor
   * @param {module:nyc/lang/Translate~Translate.Options} options Constructor options
   */
  constructor(options) {
    super(options)
		/**
     * @private
     * @member {boolean}
     */
		this.monitoring = false
    $.getScript('https://translate.google.com/translate_a/element.js?cb=nycTranslateInstance.init')
  }
  /**
	 * @desc Callback to set up Google Translate
	 * @public
	 * @method
	 */
  init() {
		nycTranslateInstance.goog = new google.translate.TranslateElement({
			pageLanguage: 'en',
			includedLanguages: nycTranslateInstance.codes,
			layout: google.translate.TranslateElement.InlineLayout.SIMPLE,
			autoDisplay: false
		}, 'lng-goog')
		nycTranslateInstance.hack()
		nycTranslateInstance.trigger('ready', nycTranslateInstance)
	}
  /**
	 * @desc Sets the chosen language and initiates Google Translation
	 * @public
   * @override
	 * @method
   * @param {jQuery.Event} event
	 */
   translate(event) {
		const choices = $('iframe.goog-te-menu-frame:first').contents().find('.goog-te-menu2-item span.text')
		clearTimeout(nycTranslateInstance.timeout)
		if (event && choices.length) {
			this.code = $(event.target).val()
			const lang =  this.languages[this.code].name
			if (lang === 'English') {
				this.showOriginalText()
			} else {
				$(choices).each((_, choice) => {
					if ($(choice).text() === lang) {
						$(choice).trigger('click')
						nycTranslateInstance.monitor()
						return false
					}
				})
			}
			this.css('goog')
			this.trigger('change', this)
		} else {
			nycTranslateInstance.timeout = setTimeout(() => {nycTranslateInstance.translate(event)}, 200)
		}
	}
  /**
	 * @desc Gets the google translate cookie value
	 * @access protected
	 * @override
	 * @method
	 * @return {string}
	 */
	getCookieValue() {
		let cookie = this.getCookie()
		if (cookie) {
			cookie = cookie.split('/')
			cookie = cookie[2]
			return cookie
		}
    return ''
	}
	/**
	 * @private
	 * @method
	 */
	monitor() {
		if (!this.monitoring) {
			this.monitoring = true
			if ('MutationObserver' in window) {
				new MutationObserver(this.hack)
					.observe(document.body, {childList: true, subtree: true})
			} else {
				setInterval(this.hack, 500)
			}
		}
	}
  /**
   * @private
   * @method
   * @override
   * @return {string}
   */
  getCookie() {
    const cookies = document.cookie.split(';')
    for (let i = 0; i < cookies.length; i++) {
      let cookie = cookies[i]
      while (cookie.charAt(0) === ' ') cookie = cookie.substring(1, cookie.length)
      if (cookie.indexOf('googtrans=') === 0 ) {
        return cookie.substring(10, cookie.length)
      }
    }
  }
  /**
	 * @private
	 * @method
	 */
	hack() {
		/*
		 * google translate doesn't translate placeholder attributes
		 * so we'll add a hidden span after input elements that have placeholders
		 * then use the placeholder text for the span
		 * then apply the translation of the span back to the placeholder
		 */
		$('input[placeholder]').each(function(_, input) {
			const next = $(input).next()
			if (!next.hasClass('lng-placeholder')) {
				$(input).after(`<span class="lng-placeholder">${$(input).attr('placeholder')}</span>`)
			} else {
				const fonts = next.find('font')
				let text = next.html()
				$.each(next.find('font'), (_, font) => {
					text = $(font).html()
				})
				$(input).attr('placeholder', text)
			}
		})
		$('body').css('top', 'auto')
		$('#goog-gt-tt').remove()
	}
  /**
   * @private
   * @method
   */
  showOriginalText() {
    const googBar = $('iframe.goog-te-banner-frame:first')
    $(googBar.contents().find('.goog-te-button button')).each((_, button) => {
    	if ($(button).text() === 'Show original') {
        const code = this.find('select').val()
        $(button).trigger('click')
    		if (this.languages[code].name !== 'English') {
    			this.find('select').val('en')
				}
    		return false
    	}
    })
  }
}

export default Goog