API Docs for: 0.0.8
Show:

File: client/auth/lightbox/iframe_channel.js

  1. /* This Source Code Form is subject to the terms of the Mozilla Public
  2. * License, v. 2.0. If a copy of the MPL was not distributed with this
  3. * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
  4. /**
  5. * Communicate with an iframed content server.
  6. *
  7. * @class IFrameChannel
  8. */
  9. define([
  10. 'p-promise',
  11. 'client/lib/object'
  12. ], function (p, ObjectHelpers) {
  13. 'use strict';
  14. function IFrameChannel(options) {
  15. options = options || {};
  16. this._window = options.window;
  17. this._contentWindow = options.contentWindow;
  18. this._iframeHost = options.iframeHost;
  19. }
  20. IFrameChannel.prototype = {
  21. /**
  22. * Protocol version number. When the protocol to communicate with the
  23. * content server changes, this should be bumped.
  24. * @property version
  25. * @type {String}
  26. */
  27. version: '0.0.0',
  28. /**
  29. * Start listening for messages from the iframe.
  30. * @method attach
  31. */
  32. attach: function () {
  33. this._boundOnMessage = onMessage.bind(this);
  34. this._window.addEventListener('message', this._boundOnMessage, false);
  35. this._deferred = p.defer();
  36. return this._deferred.promise;
  37. },
  38. /**
  39. * Stop listening for messages from the iframe.
  40. * @method detach
  41. */
  42. detach: function () {
  43. this._window.removeEventListener('message', this._boundOnMessage, false);
  44. },
  45. /**
  46. * Send a message to the iframe.
  47. *
  48. * @method send
  49. * @param {String} command
  50. * Message to send.
  51. * @param {Object} [data]
  52. * Data to send.
  53. */
  54. send: function (command, data) {
  55. var dataToSend = ObjectHelpers.extend({ version: this.version }, data);
  56. var msg = stringifyFxAEvent(command, dataToSend);
  57. this._contentWindow.postMessage(msg, this._iframeHost);
  58. }
  59. };
  60. // commands that come from the iframe. They are called
  61. // in the Lightbox object context.
  62. var COMMANDS = {
  63. error: function (command, data) {
  64. this.detach();
  65. this._deferred.reject(data);
  66. },
  67. /*jshint camelcase:false*/
  68. ping: function (command, data) {
  69. // ping is used to get the RP's origin. If the RP's origin is not
  70. // whitelisted, it cannot be iframed.
  71. this.send(command, data);
  72. },
  73. ignore: function (command, data) {
  74. console.log('ignoring command: %s', command);
  75. },
  76. oauth_cancel: function (command, data) {
  77. this.detach();
  78. return this._deferred.reject({ reason: 'cancel' });
  79. },
  80. oauth_complete: function (command, data) {
  81. this.detach();
  82. this._deferred.resolve(data);
  83. }
  84. };
  85. function onMessage(event) {
  86. /*jshint validthis: true*/
  87. if (event.origin !== this._iframeHost) {
  88. return;
  89. }
  90. var parsed = parseFxAEvent(event.data);
  91. var command = parsed.command;
  92. var data = parsed.data;
  93. var handler = COMMANDS[command] || COMMANDS.ignore;
  94. handler.call(this, command, data);
  95. }
  96. function parseFxAEvent(msg) {
  97. return JSON.parse(msg);
  98. }
  99. function stringifyFxAEvent(command, data) {
  100. return JSON.stringify({
  101. command: command,
  102. data: data || {}
  103. });
  104. }
  105. IFrameChannel.stringifyFxAEvent = stringifyFxAEvent;
  106. IFrameChannel.parseFxAEvent = parseFxAEvent;
  107. return IFrameChannel;
  108. });