API Docs for: 0.0.8
Show:

File: client/auth/lightbox/iframe_channel.js

                        /* This Source Code Form is subject to the terms of the Mozilla Public
                         * License, v. 2.0. If a copy of the MPL was not distributed with this
                         * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
                        
                        /**
                         * Communicate with an iframed content server.
                         *
                         * @class IFrameChannel
                         */
                        define([
                          'p-promise',
                          'client/lib/object'
                        ], function (p, ObjectHelpers) {
                          'use strict';
                        
                          function IFrameChannel(options) {
                            options = options || {};
                        
                            this._window = options.window;
                            this._contentWindow = options.contentWindow;
                            this._iframeHost = options.iframeHost;
                          }
                        
                          IFrameChannel.prototype = {
                            /**
                             * Protocol version number. When the protocol to communicate with the
                             * content server changes, this should be bumped.
                             * @property version
                             * @type {String}
                             */
                            version: '0.0.0',
                        
                            /**
                             * Start listening for messages from the iframe.
                             * @method attach
                             */
                            attach: function () {
                              this._boundOnMessage = onMessage.bind(this);
                              this._window.addEventListener('message', this._boundOnMessage, false);
                        
                              this._deferred = p.defer();
                              return this._deferred.promise;
                            },
                        
                            /**
                             * Stop listening for messages from the iframe.
                             * @method detach
                             */
                            detach: function () {
                              this._window.removeEventListener('message', this._boundOnMessage, false);
                            },
                        
                            /**
                             * Send a message to the iframe.
                             *
                             * @method send
                             * @param {String} command
                             * Message to send.
                             * @param {Object} [data]
                             * Data to send.
                             */
                            send: function (command, data) {
                              var dataToSend = ObjectHelpers.extend({ version: this.version }, data);
                              var msg = stringifyFxAEvent(command, dataToSend);
                        
                              this._contentWindow.postMessage(msg, this._iframeHost);
                            }
                          };
                        
                          // commands that come from the iframe. They are called
                          // in the Lightbox object context.
                          var COMMANDS = {
                            error: function (command, data) {
                              this.detach();
                              this._deferred.reject(data);
                            },
                            /*jshint camelcase:false*/
                            ping: function (command, data) {
                              // ping is used to get the RP's origin. If the RP's origin is not
                              // whitelisted, it cannot be iframed.
                              this.send(command, data);
                            },
                            ignore: function (command, data) {
                              console.log('ignoring command: %s', command);
                            },
                            oauth_cancel: function (command, data) {
                              this.detach();
                              return this._deferred.reject({ reason: 'cancel' });
                            },
                            oauth_complete: function (command, data) {
                              this.detach();
                              this._deferred.resolve(data);
                            }
                          };
                        
                          function onMessage(event) {
                            /*jshint validthis: true*/
                            if (event.origin !== this._iframeHost) {
                              return;
                            }
                        
                            var parsed = parseFxAEvent(event.data);
                            var command = parsed.command;
                            var data = parsed.data;
                        
                            var handler = COMMANDS[command] || COMMANDS.ignore;
                            handler.call(this, command, data);
                          }
                        
                          function parseFxAEvent(msg) {
                            return JSON.parse(msg);
                          }
                        
                          function stringifyFxAEvent(command, data) {
                            return JSON.stringify({
                              command: command,
                              data: data || {}
                            });
                          }
                        
                          IFrameChannel.stringifyFxAEvent = stringifyFxAEvent;
                          IFrameChannel.parseFxAEvent = parseFxAEvent;
                        
                          return IFrameChannel;
                        });