Instantly share code, notes, and snippets.

Embed
What would you like to do?
Cross document message
Boom.add('xstream', function(C) {
var TICKET = 'any random string 1';
var PING = 'any random string 2';
var PING_BACK = 'any random string 3';
var host = location.protocol + '//' + location.host +
(location.port ? ':' + location.port : '');
var $ = jQuery;
var win = window;
var pool = {};
var listener = new C.Event();
var support = function() {
return 'postMessage' in win ;
}();
var attach = function(fun) {
if (window.addEventListener) {
window.addEventListener('message', fun, false);
} else {
window.attachEvent('onmessage', fun);
}
};
var checkout = function(data) {
if (data.indexOf(TICKET) === 0) {
return data.substring(TICKET.length);
}
return false;
};
var checkin = function(data) {
return TICKET + data;
};
var dispatchMessage = function(data, source, origin) {
if ((data = checkout(data)) === false) {
return;
}
if (data == PING) {
xstream.sendRaw(checkin(PING_BACK), source, origin);
} else if (data == PING_BACK) {
win.clearTimeout(pool[origin].ping);
pool[origin].pingfun = null;
pool[origin].open = true;
$.each(pool[origin].queue, function(index, arg) {
xstream.sendRaw.apply(xstream, arg);
});
pool[origin].queue = [];
} else {
listener.trigger(origin, data, source, origin);
}
};
var xstream = {
send: function(data, target, channel) {
channel = $.isArray(channel) ? channel : [channel];
data = checkin(data);
$.each(channel, function(index, chanel) {
if (pool[chanel] && pool[chanel].open) {
xstream.sendRaw(data, target, chanel);
} else if (pool[chanel]) {
pool[chanel].queue.push([data, target, chanel]);
} else {
pool[chanel] = {
open: false,
ping: null,
queue: [[data, target, chanel]]
}
xstream.ping(target, chanel);
}
})
},
listen: function(channel, callback) {
channel = $.isArray(channel) ? channel : [channel]
$.each(channel, function(index, chanel) {
listener.on(chanel, callback);
});
},
ping: function(target, channel) {
pool[channel].pingfun = function() {
pool[channel].ping = win.setTimeout(pool[channel].pingfun, 1000);
xstream.sendRaw(checkin(PING), target, channel);
}
pool[channel].pingfun();
},
sendRaw: function(data, target, channel) {
try {
if (support) {
target.postMessage(data, channel);
} else {
// alert('[' + host + '] send to [' + channel + '] : ' + data);
typeof win.navigator[channel] == 'function' &&
win.navigator[channel](data, win, host);
}
} catch (e) {
typeof console == 'object' && console.error &&
console.error(e);
}
}
}
if (support) {
attach(function(event) {
var ev = event || window.event;
dispatchMessage(ev.data, ev.source, ev.origin);
})
} else {
navigator[host] = dispatchMessage;
}
return xstream;
}, {requires: ['event', 'jquery']});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment