update
This commit is contained in:
@@ -0,0 +1,140 @@
|
||||
/*!
|
||||
* 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/
|
||||
*
|
||||
* Non-jQuery fork by Jeff Lee
|
||||
*
|
||||
* This fork consists of the following changes:
|
||||
* 1. Basic code cleanup and restructuring, for legibility.
|
||||
* 2. The `postMessage` and `receiveMessage` functions can be bound arbitrarily,
|
||||
* in terms of both function names and object scope. Scope is specified by
|
||||
* the the "this" context of NoJQueryPostMessageMixin();
|
||||
* 3. I've removed the check for Opera 9.64, which used `$.browser`. There were
|
||||
* at least three different GitHub users requesting the removal of this
|
||||
* "Opera sniff" on the original project's Issues page, so I figured this
|
||||
* would be a relatively safe change.
|
||||
* 4. `postMessage` no longer uses `$.param` to serialize messages that are not
|
||||
* strings. I actually prefer this structure anyway. `receiveMessage` does
|
||||
* not implement a corresponding deserialization step, and as such it seems
|
||||
* cleaner and more symmetric to leave both data serialization and
|
||||
* deserialization to the client.
|
||||
* 5. The use of `$.isFunction` is replaced by a functionally-identical check.
|
||||
* 6. The `$:nomunge` YUI option is no longer necessary.
|
||||
*/
|
||||
|
||||
function NoJQueryPostMessageMixin(postBinding, receiveBinding) {
|
||||
|
||||
var setMessageCallback, unsetMessageCallback, currentMsgCallback,
|
||||
intervalId, lastHash, cacheBust = 1;
|
||||
|
||||
if (window.postMessage) {
|
||||
|
||||
if (window.addEventListener) {
|
||||
setMessageCallback = function(callback) {
|
||||
window.addEventListener('message', callback, false);
|
||||
}
|
||||
|
||||
unsetMessageCallback = function(callback) {
|
||||
window.removeEventListener('message', callback, false);
|
||||
}
|
||||
} else {
|
||||
setMessageCallback = function(callback) {
|
||||
window.attachEvent('onmessage', callback);
|
||||
}
|
||||
|
||||
unsetMessageCallback = function(callback) {
|
||||
window.detachEvent('onmessage', callback);
|
||||
}
|
||||
}
|
||||
|
||||
this[postBinding] = function(message, targetUrl, target) {
|
||||
if (!targetUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The browser supports window.postMessage, so call it with a targetOrigin
|
||||
// set appropriately, based on the targetUrl parameter.
|
||||
target.postMessage( message, targetUrl.replace( /([^:]+:\/\/[^\/]+).*/, '$1' ) );
|
||||
}
|
||||
|
||||
// Since the browser supports window.postMessage, the callback will be
|
||||
// bound to the actual event associated with window.postMessage.
|
||||
this[receiveBinding] = function(callback, sourceOrigin, delay) {
|
||||
// Unbind an existing callback if it exists.
|
||||
if (currentMsgCallback) {
|
||||
unsetMessageCallback(currentMsgCallback);
|
||||
currentMsgCallback = null;
|
||||
}
|
||||
|
||||
if (!callback) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Bind the callback. A reference to the callback is stored for ease of
|
||||
// unbinding.
|
||||
currentMsgCallback = setMessageCallback(function(e) {
|
||||
switch(Object.prototype.toString.call(sourceOrigin)) {
|
||||
case '[object String]':
|
||||
if (sourceOrigin !== e.origin) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case '[object Function]':
|
||||
if (sourceOrigin(e.origin)) {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
callback(e);
|
||||
});
|
||||
};
|
||||
|
||||
} else {
|
||||
|
||||
this[postBinding] = function(message, targetUrl, target) {
|
||||
if (!targetUrl) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The browser does not support window.postMessage, so set the location
|
||||
// of the target to targetUrl#message. A bit ugly, but it works! A cache
|
||||
// bust parameter is added to ensure that repeat messages trigger the
|
||||
// callback.
|
||||
target.location = targetUrl.replace( /#.*$/, '' ) + '#' + (+new Date) + (cacheBust++) + '&' + message;
|
||||
}
|
||||
|
||||
// Since the browser sucks, a polling loop will be started, and the
|
||||
// callback will be called whenever the location.hash changes.
|
||||
this[receiveBinding] = function(callback, sourceOrigin, delay) {
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
intervalId = null;
|
||||
}
|
||||
|
||||
if (callback) {
|
||||
delay = typeof sourceOrigin === 'number'
|
||||
? sourceOrigin
|
||||
: typeof delay === 'number'
|
||||
? delay
|
||||
: 100;
|
||||
|
||||
intervalId = setInterval(function(){
|
||||
var hash = document.location.hash,
|
||||
re = /^#?\d+&/;
|
||||
if ( hash !== lastHash && re.test( hash ) ) {
|
||||
lastHash = hash;
|
||||
callback({ data: hash.replace( re, '' ) });
|
||||
}
|
||||
}, delay );
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
Reference in New Issue
Block a user