1 
  2 (function ($$, window) {
  3 
  4     "use strict";
  5 
  6     var module =   (function() {
  7 
  8         var internalCallback;
  9 
 10         /**
 11         * @description Pass a message to the target url
 12         * @param {String} message The message to send
 13         * @param {String} target_url Specifies what the origin of the target must be for the event to be dispatched.
 14         * @param {String} [target] The window that is the message's target. Defaults to the parent of the current window.
 15         */
 16         function postMessage(message, target_url, target) {
 17 			var sfdcJson = Sfdc.JSON || JSON;
 18 
 19             // If target url was not supplied (client may have lost it), we could default to '*',
 20             // However there are security implications here as other canvas apps could receive this
 21             // canvas apps oauth token.
 22             if ($$.isNil(target_url)) {
 23                 throw "ERROR: target_url was not supplied on postMessage";
 24             }
 25             var otherWindow = $$.stripUrl(target_url);
 26 
 27             target = target || parent;  // default to parent
 28             if (window.postMessage) {
 29                 // the browser supports window.postMessage, so call it with a targetOrigin
 30                 // set appropriately, based on the target_url parameter.
 31 
 32                 // Add the targetModule as Canvas so we are the only ones interested in these events
 33                 if ($$.isObject(message)) {message.targetModule = "Canvas";}
 34                 message = sfdcJson.stringify(message);
 35                 target.postMessage(message, otherWindow);
 36             }
 37         }
 38         
 39         /**
 40         * @name Sfdc.canvas.xd#receive
 41         * @description Runs the callback function when the message event is received.
 42         * @param {Function} callback Function to run when the message event is received 
 43             if the event origin is acceptable.
 44         * @param {String} source_origin The origin of the desired events
 45         */
 46         function receiveMessage(callback, source_origin) {
 47 
 48             // browser supports window.postMessage (if not not supported for pilot - removed per securities request)
 49             if (window.postMessage) {
 50                 // bind the callback to the actual event associated with window.postMessage
 51                 if (callback) {
 52                     internalCallback = function(e) {
 53 
 54                         var data, r;
 55 						var sfdcJson = Sfdc.JSON || JSON;
 56                         if (!$$.isNil(e)) {
 57                             if (typeof source_origin === 'string' && e.origin !== source_origin) {
 58                                 return false;
 59                             }
 60                             if ($$.isFunction(source_origin)) {
 61                                 r = source_origin(e.origin, e.data);
 62                                 if (r === false) {
 63                                     return false;
 64                                 }
 65                             }
 66                             if ($$.appearsJson(e.data))  {
 67                                 try {
 68                                     data = sfdcJson.parse(e.data);
 69                                 } catch (ignore) {
 70                                     // Ignore parsing errors of any non json objects sent from other frames
 71                                 }
 72                                 // If we could parse the data and there is a targetModule make sure it is for us
 73                                 if (!$$.isNil(data) && ($$.isNil(data.targetModule) || data.targetModule === "Canvas")) {
 74                                     callback(data, r);
 75                                 }
 76                             }
 77                         }
 78                     };
 79                 }
 80                 if (window.addEventListener) {
 81                     window.addEventListener('message', internalCallback, false);
 82                 } else {
 83                     window.attachEvent('onmessage', internalCallback);
 84                 }
 85             }
 86         }
 87         
 88         /**
 89         * @description Removes the message event listener
 90         * @public     
 91         */
 92         function removeListener() {
 93 
 94             // browser supports window.postMessage
 95             if (window.postMessage) {
 96                 if (window.removeEventListener) {
 97                     window.removeEventListener('message', internalCallback, false);
 98                 } else {
 99                     window.detachEvent('onmessage', internalCallback);
100                 }
101             }
102         }
103 
104         return {
105             post : postMessage,
106             receive : receiveMessage,
107             remove : removeListener
108         };
109     }());
110 
111     $$.module('Sfdc.canvas.xd', module);
112 
113 }(Sfdc.canvas, this));