myTerminal/page-chatter

View on GitHub
src/scripts/page-chatter.js

Summary

Maintainability
A
0 mins
Test Coverage
/* global window */

let handlers,
    originalHandler;

// Function to post message to a supplied set of handlers
const postMessage = (targetHandlers, event, payLoad) => {
    Object.keys(targetHandlers)
        .forEach(
            k => {
                targetHandlers[k]({
                    event,
                    payLoad
                });
            }
        );
};

// Function to handle all messages
const onMessage = message => {
    // Extract information about the message
    const { data } = message;
    const {
        to: recipient,
        event,
        payLoad
    } = data;

    // Pass as a message or a broadcast
    if (recipient) {
        // Find the recipient's identifier
        const id = Object.keys(handlers).filter(k => k === recipient)[0];

        // Pass the message to the correct recipient, if any
        if (id) {
            postMessage([handlers[id]], event, payLoad);
        }
    } else {
        // Broadcast the message to all participants
        postMessage(handlers, event, payLoad);
    }

    // Also pass the message to the original event handler, if any
    if (originalHandler) {
        originalHandler(message);
    }
};

// Function to initialize page-chatter
export const init = () => {
    // Store the original event handler as one of the many
    originalHandler = window.onmessage;

    // Initialize the handlers collection
    handlers = {};

    // Set up a global event handler for all messages
    window.onmessage = onMessage;
};

// Function to subscribe to events for self
export const listen = (id, handler) => {
    // Append the handler to the list of handlers, against the id
    handlers[id] = handler;
};

// Function to talk to other participants
export const talk = (to, event, payLoad) => {
    // Post message to the chatter
    window.postMessage(
        {
            to,
            event,
            payLoad
        },
        '*'
    );
};

// Function to broadcast message to all participants
export const broadcast = (event, payLoad) => {
    // Post message to the chatter
    window.postMessage(
        {
            event,
            payLoad
        },
        '*'
    );
};

// Function to terminate chatter
export const terminate = () => {
    // Restore the original handler
    window.onmessage = originalHandler;

    // Reset the handlers collection
    handlers = {};
};

export default {
    init,
    listen,
    talk,
    terminate
};