Skip to content

Commit 2e073f7

Browse files
committed
add BroadcastChannel implementation
1 parent 5d9dddd commit 2e073f7

File tree

5 files changed

+80
-28
lines changed

5 files changed

+80
-28
lines changed

README.md

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1-
[![npm](https://img.shields.io/badge/npm-1.1.0-blue.svg)](https://www.npmjs.com/package/sysend)
2-
![bower](https://img.shields.io/badge/bower-1.1.0-yellow.svg)
1+
[![npm](https://img.shields.io/badge/npm-1.2.0-blue.svg)](https://www.npmjs.com/package/sysend)
2+
![bower](https://img.shields.io/badge/bower-1.2.0-yellow.svg)
33

44
## sysend.js
55

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

1114
Tested on:
1215

demo.html

+1
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
}
1313
sysend.on('foo', function(obj) {
1414
message('just get event "foo" with message: ' + obj.message);
15+
console.log(obj.message);
1516
});
1617
sysend.on('notification', function(obj) {
1718
if (typeof obj == 'undefined') {

iframe.html

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<!DOCTYPE HTML>
2+
<html xmlns="http://www.w3.org/1999/xhtml">
3+
<head>
4+
<meta charset="utf-8" />
5+
<title></title>
6+
<meta name="Description" content=""/>
7+
<link rel="shortcut icon" href=""/>
8+
<!--[if IE]>
9+
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
10+
<![endif]-->
11+
<script src="https://jcubic.pl/sysend.js"></script>
12+
<script>
13+
window.onmessage = function(e) {
14+
document.getElementsByTagName('pre')[0].innerHTML += e.origin + '\n';
15+
if (!e.origin.match(/jcubic\.pl$/) && !e.origin.match(/https?:\/\/localhost$/) && !e.origin.match(/codepen.io/)) {
16+
return;
17+
}
18+
var payload = JSON.parse(e.data);
19+
sysend.broadcast(payload.key, payload.data);
20+
document.getElementsByTagName('pre')[0].innerHTML += JSON.stringify(payload.data) + '\n';
21+
};
22+
</script>
23+
</head>
24+
<body>
25+
<pre></pre>
26+
</body>
27+
</html>

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "sysend",
3-
"version": "1.1.0",
3+
"version": "1.2.0",
44
"description": "Send messages to other tabs/windows in the same origin and browser",
55
"main": "sysend.js",
66
"scripts": {

sysend.js

+44-23
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
/**@license
2-
* sysend.js - send messages between browser windows/tabs
3-
* Copyright (C) 2014 Jakub Jankiewicz <http://jcubic.pl>
2+
* sysend.js - send messages between browser windows/tabs version 1.2.0
43
*
4+
* Copyright (C) 2014-2018 Jakub Jankiewicz <http://jcubic.pl/me>
55
* Released under the MIT license
66
*
7-
* The idea for this implementation came from this StackOverflow question:
7+
* The idea for localStorage implementation came from this StackOverflow question:
88
* http://stackoverflow.com/q/24182409/387194
9+
*
910
*/
11+
/* global define, module, exports, localStorage, setTimeout */
1012
(function (root, factory) {
1113
if (typeof define === 'function' && define.amd) {
1214
define(['sysend'], factory);
@@ -60,31 +62,50 @@
6062
// object with user events as keys and values arrays of callback functions
6163
var callbacks = {};
6264
var index = 0;
63-
window.addEventListener('storage', function(e) {
64-
// prevent event to be executed on remove in IE
65-
if (e.key.match(re) && index++ % 2 === 0) {
66-
var key = e.key.replace(re, '');
67-
if (callbacks[key]) {
68-
var value = e.newValue || get(key);
69-
if (value && value != random_value) {
70-
var obj = JSON.parse(value);
71-
if (obj && obj[1] != random_value) {
72-
// don't call on remove
73-
callbacks[key].forEach(function(fn) {
74-
fn(obj[2], key);
75-
});
65+
var channel;
66+
if (typeof window.BroadcastChannel === 'function') {
67+
channel = new window.BroadcastChannel(uniq_prefix);
68+
channel.addEventListener('message', function(event) {
69+
if (event.target.name === uniq_prefix) {
70+
var key = event.data && event.data.name;
71+
if (callbacks[key]) {
72+
callbacks[key].forEach(function(fn) {
73+
fn(event.data.data, key);
74+
});
75+
}
76+
}
77+
});
78+
} else {
79+
window.addEventListener('storage', function(e) {
80+
// prevent event to be executed on remove in IE
81+
if (e.key.match(re) && index++ % 2 === 0) {
82+
var key = e.key.replace(re, '');
83+
if (callbacks[key]) {
84+
var value = e.newValue || get(key);
85+
if (value && value != random_value) {
86+
var obj = JSON.parse(value);
87+
if (obj && obj[1] != random_value) {
88+
// don't call on remove
89+
callbacks[key].forEach(function(fn) {
90+
fn(obj[2], key);
91+
});
92+
}
7693
}
7794
}
7895
}
79-
}
80-
}, false);
96+
}, false);
97+
}
8198
return {
8299
broadcast: function(event, message) {
83-
set(event, to_json(message));
84-
// clean up localstorage
85-
setTimeout(function() {
86-
remove(event);
87-
}, 0);
100+
if (channel) {
101+
channel.postMessage({name: event, data: message});
102+
} else {
103+
set(event, to_json(message));
104+
// clean up localstorage
105+
setTimeout(function() {
106+
remove(event);
107+
}, 0);
108+
}
88109
},
89110
on: function(event, fn) {
90111
if (!callbacks[event]) {

0 commit comments

Comments
 (0)