jquery.ba-postmessage.js
10 years ago
jquery.ba-postmessage.min.js
10 years ago
nojquery.ba-postmessage.js
10 years ago
nojquery.ba-postmessage.min.js
10 years ago
postmessage.js
10 years ago
jquery.ba-postmessage.js
223 lines
| 1 | /*! |
| 2 | * jQuery postMessage - v0.5 - 9/11/2009 |
| 3 | * http://benalman.com/projects/jquery-postmessage-plugin/ |
| 4 | * |
| 5 | * Copyright (c) 2009 "Cowboy" Ben Alman |
| 6 | * Dual licensed under the MIT and GPL licenses. |
| 7 | * http://benalman.com/about/license/ |
| 8 | */ |
| 9 | |
| 10 | // Script: jQuery postMessage: Cross-domain scripting goodness |
| 11 | // |
| 12 | // *Version: 0.5, Last updated: 9/11/2009* |
| 13 | // |
| 14 | // Project Home - http://benalman.com/projects/jquery-postmessage-plugin/ |
| 15 | // GitHub - http://github.com/cowboy/jquery-postmessage/ |
| 16 | // Source - http://github.com/cowboy/jquery-postmessage/raw/master/jquery.ba-postmessage.js |
| 17 | // (Minified) - http://github.com/cowboy/jquery-postmessage/raw/master/jquery.ba-postmessage.min.js (0.9kb) |
| 18 | // |
| 19 | // About: License |
| 20 | // |
| 21 | // Copyright (c) 2009 "Cowboy" Ben Alman, |
| 22 | // Dual licensed under the MIT and GPL licenses. |
| 23 | // http://benalman.com/about/license/ |
| 24 | // |
| 25 | // About: Examples |
| 26 | // |
| 27 | // This working example, complete with fully commented code, illustrates one |
| 28 | // way in which this plugin can be used. |
| 29 | // |
| 30 | // Iframe resizing - http://benalman.com/code/projects/jquery-postmessage/examples/iframe/ |
| 31 | // |
| 32 | // About: Support and Testing |
| 33 | // |
| 34 | // Information about what version or versions of jQuery this plugin has been |
| 35 | // tested with and what browsers it has been tested in. |
| 36 | // |
| 37 | // jQuery Versions - 1.3.2 |
| 38 | // Browsers Tested - Internet Explorer 6-8, Firefox 3, Safari 3-4, Chrome, Opera 9. |
| 39 | // |
| 40 | // About: Release History |
| 41 | // |
| 42 | // 0.5 - (9/11/2009) Improved cache-busting |
| 43 | // 0.4 - (8/25/2009) Initial release |
| 44 | |
| 45 | (function($){ |
| 46 | '$:nomunge'; // Used by YUI compressor. |
| 47 | |
| 48 | // A few vars used in non-awesome browsers. |
| 49 | var interval_id, |
| 50 | last_hash, |
| 51 | cache_bust = 1, |
| 52 | |
| 53 | // A var used in awesome browsers. |
| 54 | rm_callback, |
| 55 | |
| 56 | // A few convenient shortcuts. |
| 57 | window = this, |
| 58 | FALSE = !1, |
| 59 | |
| 60 | // Reused internal strings. |
| 61 | postMessage = 'postMessage', |
| 62 | addEventListener = 'addEventListener', |
| 63 | |
| 64 | p_receiveMessage, |
| 65 | |
| 66 | // I couldn't get window.postMessage to actually work in Opera 9.64! |
| 67 | has_postMessage = window[postMessage] && !$.browser.opera; |
| 68 | |
| 69 | // Method: jQuery.postMessage |
| 70 | // |
| 71 | // This method will call window.postMessage if available, setting the |
| 72 | // targetOrigin parameter to the base of the target_url parameter for maximum |
| 73 | // security in browsers that support it. If window.postMessage is not available, |
| 74 | // the target window's location.hash will be used to pass the message. If an |
| 75 | // object is passed as the message param, it will be serialized into a string |
| 76 | // using the jQuery.param method. |
| 77 | // |
| 78 | // Usage: |
| 79 | // |
| 80 | // > jQuery.postMessage( message, target_url [, target ] ); |
| 81 | // |
| 82 | // Arguments: |
| 83 | // |
| 84 | // message - (String) A message to be passed to the other frame. |
| 85 | // message - (Object) An object to be serialized into a params string, using |
| 86 | // the jQuery.param method. |
| 87 | // target_url - (String) The URL of the other frame this window is |
| 88 | // attempting to communicate with. This must be the exact URL (including |
| 89 | // any query string) of the other window for this script to work in |
| 90 | // browsers that don't support window.postMessage. |
| 91 | // target - (Object) A reference to the other frame this window is |
| 92 | // attempting to communicate with. If omitted, defaults to `parent`. |
| 93 | // |
| 94 | // Returns: |
| 95 | // |
| 96 | // Nothing. |
| 97 | |
| 98 | $[postMessage] = function( message, target_url, target ) { |
| 99 | if ( !target_url ) { return; } |
| 100 | |
| 101 | // Serialize the message if not a string. Note that this is the only real |
| 102 | // jQuery dependency for this script. If removed, this script could be |
| 103 | // written as very basic JavaScript. |
| 104 | message = typeof message === 'string' ? message : $.param( message ); |
| 105 | |
| 106 | // Default to parent if unspecified. |
| 107 | target = target || parent; |
| 108 | |
| 109 | if ( has_postMessage ) { |
| 110 | // The browser supports window.postMessage, so call it with a targetOrigin |
| 111 | // set appropriately, based on the target_url parameter. |
| 112 | target[postMessage]( message, target_url.replace( /([^:]+:\/\/[^\/]+).*/, '$1' ) ); |
| 113 | |
| 114 | } else if ( target_url ) { |
| 115 | // The browser does not support window.postMessage, so set the location |
| 116 | // of the target to target_url#message. A bit ugly, but it works! A cache |
| 117 | // bust parameter is added to ensure that repeat messages trigger the |
| 118 | // callback. |
| 119 | target.location = target_url.replace( /#.*$/, '' ) + '#' + (+new Date) + (cache_bust++) + '&' + message; |
| 120 | } |
| 121 | }; |
| 122 | |
| 123 | // Method: jQuery.receiveMessage |
| 124 | // |
| 125 | // Register a single callback for either a window.postMessage call, if |
| 126 | // supported, or if unsupported, for any change in the current window |
| 127 | // location.hash. If window.postMessage is supported and source_origin is |
| 128 | // specified, the source window will be checked against this for maximum |
| 129 | // security. If window.postMessage is unsupported, a polling loop will be |
| 130 | // started to watch for changes to the location.hash. |
| 131 | // |
| 132 | // Note that for simplicity's sake, only a single callback can be registered |
| 133 | // at one time. Passing no params will unbind this event (or stop the polling |
| 134 | // loop), and calling this method a second time with another callback will |
| 135 | // unbind the event (or stop the polling loop) first, before binding the new |
| 136 | // callback. |
| 137 | // |
| 138 | // Also note that if window.postMessage is available, the optional |
| 139 | // source_origin param will be used to test the event.origin property. From |
| 140 | // the MDC window.postMessage docs: This string is the concatenation of the |
| 141 | // protocol and "://", the host name if one exists, and ":" followed by a port |
| 142 | // number if a port is present and differs from the default port for the given |
| 143 | // protocol. Examples of typical origins are https://example.org (implying |
| 144 | // port 443), http://example.net (implying port 80), and http://example.com:8080. |
| 145 | // |
| 146 | // Usage: |
| 147 | // |
| 148 | // > jQuery.receiveMessage( callback [, source_origin ] [, delay ] ); |
| 149 | // |
| 150 | // Arguments: |
| 151 | // |
| 152 | // callback - (Function) This callback will execute whenever a <jQuery.postMessage> |
| 153 | // message is received, provided the source_origin matches. If callback is |
| 154 | // omitted, any existing receiveMessage event bind or polling loop will be |
| 155 | // canceled. |
| 156 | // source_origin - (String) If window.postMessage is available and this value |
| 157 | // is not equal to the event.origin property, the callback will not be |
| 158 | // called. |
| 159 | // source_origin - (Function) If window.postMessage is available and this |
| 160 | // function returns false when passed the event.origin property, the |
| 161 | // callback will not be called. |
| 162 | // delay - (Number) An optional zero-or-greater delay in milliseconds at |
| 163 | // which the polling loop will execute (for browser that don't support |
| 164 | // window.postMessage). If omitted, defaults to 100. |
| 165 | // |
| 166 | // Returns: |
| 167 | // |
| 168 | // Nothing! |
| 169 | |
| 170 | $.receiveMessage = p_receiveMessage = function( callback, source_origin, delay ) { |
| 171 | if ( has_postMessage ) { |
| 172 | // Since the browser supports window.postMessage, the callback will be |
| 173 | // bound to the actual event associated with window.postMessage. |
| 174 | |
| 175 | if ( callback ) { |
| 176 | // Unbind an existing callback if it exists. |
| 177 | rm_callback && p_receiveMessage(); |
| 178 | |
| 179 | // Bind the callback. A reference to the callback is stored for ease of |
| 180 | // unbinding. |
| 181 | rm_callback = function(e) { |
| 182 | if ( ( typeof source_origin === 'string' && e.origin !== source_origin ) |
| 183 | || ( $.isFunction( source_origin ) && source_origin( e.origin ) === FALSE ) ) { |
| 184 | return FALSE; |
| 185 | } |
| 186 | callback( e ); |
| 187 | }; |
| 188 | } |
| 189 | |
| 190 | if ( window[addEventListener] ) { |
| 191 | window[ callback ? addEventListener : 'removeEventListener' ]( 'message', rm_callback, FALSE ); |
| 192 | } else { |
| 193 | window[ callback ? 'attachEvent' : 'detachEvent' ]( 'onmessage', rm_callback ); |
| 194 | } |
| 195 | |
| 196 | } else { |
| 197 | // Since the browser sucks, a polling loop will be started, and the |
| 198 | // callback will be called whenever the location.hash changes. |
| 199 | |
| 200 | interval_id && clearInterval( interval_id ); |
| 201 | interval_id = null; |
| 202 | |
| 203 | if ( callback ) { |
| 204 | delay = typeof source_origin === 'number' |
| 205 | ? source_origin |
| 206 | : typeof delay === 'number' |
| 207 | ? delay |
| 208 | : 100; |
| 209 | |
| 210 | interval_id = setInterval(function(){ |
| 211 | var hash = document.location.hash, |
| 212 | re = /^#?\d+&/; |
| 213 | if ( hash !== last_hash && re.test( hash ) ) { |
| 214 | last_hash = hash; |
| 215 | callback({ data: hash.replace( re, '' ) }); |
| 216 | } |
| 217 | }, delay ); |
| 218 | } |
| 219 | } |
| 220 | }; |
| 221 | |
| 222 | })(jQuery); |
| 223 |