Skip to content

Commit

Permalink
add BroadcastChannel implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
jcubic committed Oct 21, 2018
1 parent 5d9dddd commit 2e073f7
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 28 deletions.
11 changes: 7 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
[![npm](https://img.shields.io/badge/npm-1.1.0-blue.svg)](https://www.npmjs.com/package/sysend)
![bower](https://img.shields.io/badge/bower-1.1.0-yellow.svg)
[![npm](https://img.shields.io/badge/npm-1.2.0-blue.svg)](https://www.npmjs.com/package/sysend)
![bower](https://img.shields.io/badge/bower-1.2.0-yellow.svg)

## sysend.js

sysend.js is small library that allow to send message between pages that are
open in the same browser. They need to be in same domain. The library don't use
any dependencies and use HTML5 LocalStorage API. You can send any object that
can be serialized to JSON or just send empty notification.
any dependencies and use HTML5 LocalStorage API or BroadcastChannel API.
If your browser don't support BroadcastChannel (see [Can I Use](https://caniuse.com/#feat=broadcastchannel))
then you can send any object that can be serialized to JSON with BroadcastChannel you can send any object
(it will not be serialized to string). You can also send empty notification.


Tested on:

Expand Down
1 change: 1 addition & 0 deletions demo.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
}
sysend.on('foo', function(obj) {
message('just get event "foo" with message: ' + obj.message);
console.log(obj.message);
});
sysend.on('notification', function(obj) {
if (typeof obj == 'undefined') {
Expand Down
27 changes: 27 additions & 0 deletions iframe.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE HTML>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta charset="utf-8" />
<title></title>
<meta name="Description" content=""/>
<link rel="shortcut icon" href=""/>
<!--[if IE]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script src="https://jcubic.pl/sysend.js"></script>
<script>
window.onmessage = function(e) {
document.getElementsByTagName('pre')[0].innerHTML += e.origin + '\n';
if (!e.origin.match(/jcubic\.pl$/) && !e.origin.match(/https?:\/\/localhost$/) && !e.origin.match(/codepen.io/)) {
return;
}
var payload = JSON.parse(e.data);
sysend.broadcast(payload.key, payload.data);
document.getElementsByTagName('pre')[0].innerHTML += JSON.stringify(payload.data) + '\n';
};
</script>
</head>
<body>
<pre></pre>
</body>
</html>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "sysend",
"version": "1.1.0",
"version": "1.2.0",
"description": "Send messages to other tabs/windows in the same origin and browser",
"main": "sysend.js",
"scripts": {
Expand Down
67 changes: 44 additions & 23 deletions sysend.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
/**@license
* sysend.js - send messages between browser windows/tabs
* Copyright (C) 2014 Jakub Jankiewicz <http://jcubic.pl>
* sysend.js - send messages between browser windows/tabs version 1.2.0
*
* Copyright (C) 2014-2018 Jakub Jankiewicz <http://jcubic.pl/me>
* Released under the MIT license
*
* The idea for this implementation came from this StackOverflow question:
* The idea for localStorage implementation came from this StackOverflow question:
* http://stackoverflow.com/q/24182409/387194
*
*/
/* global define, module, exports, localStorage, setTimeout */
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define(['sysend'], factory);
Expand Down Expand Up @@ -60,31 +62,50 @@
// object with user events as keys and values arrays of callback functions
var callbacks = {};
var index = 0;
window.addEventListener('storage', function(e) {
// prevent event to be executed on remove in IE
if (e.key.match(re) && index++ % 2 === 0) {
var key = e.key.replace(re, '');
if (callbacks[key]) {
var value = e.newValue || get(key);
if (value && value != random_value) {
var obj = JSON.parse(value);
if (obj && obj[1] != random_value) {
// don't call on remove
callbacks[key].forEach(function(fn) {
fn(obj[2], key);
});
var channel;
if (typeof window.BroadcastChannel === 'function') {
channel = new window.BroadcastChannel(uniq_prefix);
channel.addEventListener('message', function(event) {
if (event.target.name === uniq_prefix) {
var key = event.data && event.data.name;
if (callbacks[key]) {
callbacks[key].forEach(function(fn) {
fn(event.data.data, key);
});
}
}
});
} else {
window.addEventListener('storage', function(e) {
// prevent event to be executed on remove in IE
if (e.key.match(re) && index++ % 2 === 0) {
var key = e.key.replace(re, '');
if (callbacks[key]) {
var value = e.newValue || get(key);
if (value && value != random_value) {
var obj = JSON.parse(value);
if (obj && obj[1] != random_value) {
// don't call on remove
callbacks[key].forEach(function(fn) {
fn(obj[2], key);
});
}
}
}
}
}
}, false);
}, false);
}
return {
broadcast: function(event, message) {
set(event, to_json(message));
// clean up localstorage
setTimeout(function() {
remove(event);
}, 0);
if (channel) {
channel.postMessage({name: event, data: message});
} else {
set(event, to_json(message));
// clean up localstorage
setTimeout(function() {
remove(event);
}, 0);
}
},
on: function(event, fn) {
if (!callbacks[event]) {
Expand Down

0 comments on commit 2e073f7

Please sign in to comment.