223 lines
8.3 KiB
JavaScript
223 lines
8.3 KiB
JavaScript
/*!
|
|
* jQuery postMessage - v0.5 - 9/11/2009
|
|
* http://benalman.com/projects/jquery-postmessage-plugin/
|
|
*
|
|
* Copyright (c) 2009 "Cowboy" Ben Alman
|
|
* Dual licensed under the MIT and GPL licenses.
|
|
* http://benalman.com/about/license/
|
|
*/
|
|
|
|
// Script: jQuery postMessage: Cross-domain scripting goodness
|
|
//
|
|
// *Version: 0.5, Last updated: 9/11/2009*
|
|
//
|
|
// Project Home - http://benalman.com/projects/jquery-postmessage-plugin/
|
|
// GitHub - http://github.com/cowboy/jquery-postmessage/
|
|
// Source - http://github.com/cowboy/jquery-postmessage/raw/master/jquery.ba-postmessage.js
|
|
// (Minified) - http://github.com/cowboy/jquery-postmessage/raw/master/jquery.ba-postmessage.min.js (0.9kb)
|
|
//
|
|
// About: License
|
|
//
|
|
// Copyright (c) 2009 "Cowboy" Ben Alman,
|
|
// Dual licensed under the MIT and GPL licenses.
|
|
// http://benalman.com/about/license/
|
|
//
|
|
// About: Examples
|
|
//
|
|
// This working example, complete with fully commented code, illustrates one
|
|
// way in which this plugin can be used.
|
|
//
|
|
// Iframe resizing - http://benalman.com/code/projects/jquery-postmessage/examples/iframe/
|
|
//
|
|
// About: Support and Testing
|
|
//
|
|
// Information about what version or versions of jQuery this plugin has been
|
|
// tested with and what browsers it has been tested in.
|
|
//
|
|
// jQuery Versions - 1.3.2
|
|
// Browsers Tested - Internet Explorer 6-8, Firefox 3, Safari 3-4, Chrome, Opera 9.
|
|
//
|
|
// About: Release History
|
|
//
|
|
// 0.5 - (9/11/2009) Improved cache-busting
|
|
// 0.4 - (8/25/2009) Initial release
|
|
|
|
(function($){
|
|
'$:nomunge'; // Used by YUI compressor.
|
|
|
|
// A few vars used in non-awesome browsers.
|
|
var interval_id,
|
|
last_hash,
|
|
cache_bust = 1,
|
|
|
|
// A var used in awesome browsers.
|
|
rm_callback,
|
|
|
|
// A few convenient shortcuts.
|
|
window = this,
|
|
FALSE = !1,
|
|
|
|
// Reused internal strings.
|
|
postMessage = 'postMessage',
|
|
addEventListener = 'addEventListener',
|
|
|
|
p_receiveMessage,
|
|
|
|
// I couldn't get window.postMessage to actually work in Opera 9.64!
|
|
has_postMessage = window[postMessage] && !$.browser.opera;
|
|
|
|
// Method: jQuery.postMessage
|
|
//
|
|
// This method will call window.postMessage if available, setting the
|
|
// targetOrigin parameter to the base of the target_url parameter for maximum
|
|
// security in browsers that support it. If window.postMessage is not available,
|
|
// the target window's location.hash will be used to pass the message. If an
|
|
// object is passed as the message param, it will be serialized into a string
|
|
// using the jQuery.param method.
|
|
//
|
|
// Usage:
|
|
//
|
|
// > jQuery.postMessage( message, target_url [, target ] );
|
|
//
|
|
// Arguments:
|
|
//
|
|
// message - (String) A message to be passed to the other frame.
|
|
// message - (Object) An object to be serialized into a params string, using
|
|
// the jQuery.param method.
|
|
// target_url - (String) The URL of the other frame this window is
|
|
// attempting to communicate with. This must be the exact URL (including
|
|
// any query string) of the other window for this script to work in
|
|
// browsers that don't support window.postMessage.
|
|
// target - (Object) A reference to the other frame this window is
|
|
// attempting to communicate with. If omitted, defaults to `parent`.
|
|
//
|
|
// Returns:
|
|
//
|
|
// Nothing.
|
|
|
|
$[postMessage] = function( message, target_url, target ) {
|
|
if ( !target_url ) { return; }
|
|
|
|
// Serialize the message if not a string. Note that this is the only real
|
|
// jQuery dependency for this script. If removed, this script could be
|
|
// written as very basic JavaScript.
|
|
message = typeof message === 'string' ? message : $.param( message );
|
|
|
|
// Default to parent if unspecified.
|
|
target = target || parent;
|
|
|
|
if ( has_postMessage ) {
|
|
// The browser supports window.postMessage, so call it with a targetOrigin
|
|
// set appropriately, based on the target_url parameter.
|
|
target[postMessage]( message, target_url.replace( /([^:]+:\/\/[^\/]+).*/, '$1' ) );
|
|
|
|
} else if ( target_url ) {
|
|
// The browser does not support window.postMessage, so set the location
|
|
// of the target to target_url#message. A bit ugly, but it works! A cache
|
|
// bust parameter is added to ensure that repeat messages trigger the
|
|
// callback.
|
|
target.location = target_url.replace( /#.*$/, '' ) + '#' + (+new Date) + (cache_bust++) + '&' + message;
|
|
}
|
|
};
|
|
|
|
// Method: jQuery.receiveMessage
|
|
//
|
|
// Register a single callback for either a window.postMessage call, if
|
|
// supported, or if unsupported, for any change in the current window
|
|
// location.hash. If window.postMessage is supported and source_origin is
|
|
// specified, the source window will be checked against this for maximum
|
|
// security. If window.postMessage is unsupported, a polling loop will be
|
|
// started to watch for changes to the location.hash.
|
|
//
|
|
// Note that for simplicity's sake, only a single callback can be registered
|
|
// at one time. Passing no params will unbind this event (or stop the polling
|
|
// loop), and calling this method a second time with another callback will
|
|
// unbind the event (or stop the polling loop) first, before binding the new
|
|
// callback.
|
|
//
|
|
// Also note that if window.postMessage is available, the optional
|
|
// source_origin param will be used to test the event.origin property. From
|
|
// the MDC window.postMessage docs: This string is the concatenation of the
|
|
// protocol and "://", the host name if one exists, and ":" followed by a port
|
|
// number if a port is present and differs from the default port for the given
|
|
// protocol. Examples of typical origins are https://example.org (implying
|
|
// port 443), http://example.net (implying port 80), and http://example.com:8080.
|
|
//
|
|
// Usage:
|
|
//
|
|
// > jQuery.receiveMessage( callback [, source_origin ] [, delay ] );
|
|
//
|
|
// Arguments:
|
|
//
|
|
// callback - (Function) This callback will execute whenever a <jQuery.postMessage>
|
|
// message is received, provided the source_origin matches. If callback is
|
|
// omitted, any existing receiveMessage event bind or polling loop will be
|
|
// canceled.
|
|
// source_origin - (String) If window.postMessage is available and this value
|
|
// is not equal to the event.origin property, the callback will not be
|
|
// called.
|
|
// source_origin - (Function) If window.postMessage is available and this
|
|
// function returns false when passed the event.origin property, the
|
|
// callback will not be called.
|
|
// delay - (Number) An optional zero-or-greater delay in milliseconds at
|
|
// which the polling loop will execute (for browser that don't support
|
|
// window.postMessage). If omitted, defaults to 100.
|
|
//
|
|
// Returns:
|
|
//
|
|
// Nothing!
|
|
|
|
$.receiveMessage = p_receiveMessage = function( callback, source_origin, delay ) {
|
|
if ( has_postMessage ) {
|
|
// Since the browser supports window.postMessage, the callback will be
|
|
// bound to the actual event associated with window.postMessage.
|
|
|
|
if ( callback ) {
|
|
// Unbind an existing callback if it exists.
|
|
rm_callback && p_receiveMessage();
|
|
|
|
// Bind the callback. A reference to the callback is stored for ease of
|
|
// unbinding.
|
|
rm_callback = function(e) {
|
|
if ( ( typeof source_origin === 'string' && e.origin !== source_origin )
|
|
|| ( $.isFunction( source_origin ) && source_origin( e.origin ) === FALSE ) ) {
|
|
return FALSE;
|
|
}
|
|
callback( e );
|
|
};
|
|
}
|
|
|
|
if ( window[addEventListener] ) {
|
|
window[ callback ? addEventListener : 'removeEventListener' ]( 'message', rm_callback, FALSE );
|
|
} else {
|
|
window[ callback ? 'attachEvent' : 'detachEvent' ]( 'onmessage', rm_callback );
|
|
}
|
|
|
|
} else {
|
|
// Since the browser sucks, a polling loop will be started, and the
|
|
// callback will be called whenever the location.hash changes.
|
|
|
|
interval_id && clearInterval( interval_id );
|
|
interval_id = null;
|
|
|
|
if ( callback ) {
|
|
delay = typeof source_origin === 'number'
|
|
? source_origin
|
|
: typeof delay === 'number'
|
|
? delay
|
|
: 100;
|
|
|
|
interval_id = setInterval(function(){
|
|
var hash = document.location.hash,
|
|
re = /^#?\d+&/;
|
|
if ( hash !== last_hash && re.test( hash ) ) {
|
|
last_hash = hash;
|
|
callback({ data: hash.replace( re, '' ) });
|
|
}
|
|
}, delay );
|
|
}
|
|
}
|
|
};
|
|
|
|
})(jQuery);
|