: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
* 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);
setMessageCallback = function(callback) {
window.attachEvent('onmessage', callback);
unsetMessageCallback = function(callback) {
window.detachEvent('onmessage', callback);
this[postBinding] = function(message, targetUrl, target) {
// 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;
// Bind the callback. A reference to the callback is stored for ease of
currentMsgCallback = setMessageCallback(function(e) {
switch(Object.prototype.toString.call(sourceOrigin)) {
if (sourceOrigin !== e.origin) {
case '[object Function]':
if (sourceOrigin(e.origin)) {
this[postBinding] = function(message, targetUrl, target) {
// 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
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) {
clearInterval(intervalId);
delay = typeof sourceOrigin === 'number'
: typeof delay === 'number'
intervalId = setInterval(function(){
var hash = document.location.hash,
if ( hash !== lastHash && re.test( hash ) ) {
callback({ data: hash.replace( re, '' ) });