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));