Source: dom/messageHandler.js

/**
 * This file is part of SesaReactComponent.
 *   Copyright 2014-2015, Association Sésamath
 *
 * SesaReactComponent is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License version 3
 * as published by the Free Software Foundation.
 *
 * SesaReactComponent is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with SesaReactComponent (LICENCE.txt).
 * @see http://www.gnu.org/licenses/agpl.txt
 *
 *
 * Ce fichier fait partie de SesaReactComponent, créée par l'association Sésamath.
 *
 * SesaReactComponent est un logiciel libre ; vous pouvez le redistribuer ou le modifier suivant
 * les termes de la GNU Affero General Public License version 3 telle que publiée par la
 * Free Software Foundation.
 * SesaReactComponent est distribué dans l'espoir qu'il sera utile, mais SANS AUCUNE GARANTIE,
 * sans même la garantie tacite de QUALITÉ MARCHANDE ou d'ADÉQUATION à UN BUT PARTICULIER.
 * Consultez la GNU Affero General Public License pour plus de détails.
 * Vous devez avoir reçu une copie de la GNU General Public License en même temps que SesaQcm
 * (cf LICENCE.txt et http://vvlibri.org/fr/Analyse/gnu-affero-general-public-license-v3-analyse
 * pour une explication en français)
 */
'use strict'

/**
 * Retourne deux fonctions pour envoyer ou recevoir des messages sur cette fenêtre
 * @service sesajstools/dom/postMessage
 * @param {Window} targetWindow
 * @returns {{addListener: addListener, send: send}}
 */
module.exports = function messageHandler (targetWindow) {
  /**
   * Liste de listeners, sous la forme {actionX:{listener[]}}
   * @private
   */
  var listeners

  /**
   * Ajoute le listener général sur ce window
   * @private
   */
  function addFirstListener () {
    listeners = {}
    targetWindow.addEventListener('message', function (event) {
      // on teste pas event.origin, on accepte les messages de tous ceux que l'on embarque
      if (event.data && event.data.action) {
        var action = event.data.action
        if (action && listeners[action] && listeners[action].length) {
          listeners[action].forEach(function (listener) {
            listener(event.data.values)
          })
        }
      }
    })
  }

  /**
   * Ajoute un listener pour cette action
   * @param {string} action
   * @param {function} cb sera rappelée avec les values du message
   */
  function addListener (action, cb) {
    if (!listeners) addFirstListener()
    if (!listeners[action]) listeners[action] = []
    listeners[action].push(cb)
  }

  /**
   * Envoie un message (vers le targetWindow courant)
   * @param {string} action
   * @param {object} values
   */
  function send (action, values) {
    targetWindow.postMessage({ action: action, values: values }, '*')
  }

  return {
    addListener: addListener,
    send: send
  }
}