forked from TheBrainFamily/react-one-tab-enforcer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
198 lines (169 loc) · 5.54 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.withOneTabEnforcer = withOneTabEnforcer;
var _react = _interopRequireDefault(require("react"));
function _interopRequireDefault(obj) {
return obj && obj.__esModule ? obj : { default: obj };
}
var DefaultOnlyOneTabComponent = function DefaultOnlyOneTabComponent() {
return _react.default.createElement(
"div",
null,
"Sorry! You can only have this application opened in one tab"
);
}; // eslint-disable-next-line import/prefer-default-export
function withOneTabEnforcer() {
var _ref =
arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
_ref$OnlyOneTabCompon = _ref.OnlyOneTabComponent,
OnlyOneTabComponent =
_ref$OnlyOneTabCompon === void 0
? DefaultOnlyOneTabComponent
: _ref$OnlyOneTabCompon,
_ref$localStorageTime = _ref.localStorageTimeout,
localStorageTimeout =
_ref$localStorageTime === void 0 ? 15 * 1000 : _ref$localStorageTime,
_ref$localStorageRese = _ref.localStorageResetInterval,
localStorageResetInterval =
_ref$localStorageRese === void 0 ? 10 * 1000 : _ref$localStorageRese,
_ref$appName = _ref.appName,
appName = _ref$appName === void 0 ? "default-app-name" : _ref$appName;
return function(WrappedComponent) {
// ...and returns another component...
return function(props) {
if (
isDuplicatedWindow(
localStorageTimeout,
localStorageResetInterval,
appName
)
) {
return _react.default.createElement(OnlyOneTabComponent, null);
} else {
return _react.default.createElement(WrappedComponent, props);
}
};
};
}
var isDuplicatedWindow = function isDuplicatedWindow(
localStorageTimeout,
localStorageResetInterval,
localStorageTabKey
) {
var ItemType = {
Session: 1,
Local: 2
};
function setCookie(name, value, days) {
var expires = "";
if (days) {
var date = new Date();
date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000);
expires = "; expires=" + date.toUTCString();
}
document.cookie = name + "=" + (value || "") + expires + "; path=/";
}
function getCookie(name) {
var nameEQ = name + "=";
var ca = document.cookie.split(";");
for (var i = 0; i < ca.length; i++) {
var c = ca[i];
while (c.charAt(0) == " ") {
c = c.substring(1, c.length);
}
if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
}
return null;
}
function GetItem(itemtype) {
var val = "";
switch (itemtype) {
case ItemType.Session:
val = window.name;
break;
case ItemType.Local:
val = decodeURIComponent(getCookie(localStorageTabKey));
if (val == undefined) val = "";
break;
}
return val;
}
function SetItem(itemtype, val) {
switch (itemtype) {
case ItemType.Session:
window.name = val;
break;
case ItemType.Local:
setCookie(localStorageTabKey, val);
break;
}
}
function createGUID() {
var s4 = function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
};
return (
s4() +
s4() +
"-" +
s4() +
"-" +
s4() +
"-" +
s4() +
"-" +
s4() +
s4() +
s4()
);
}
/**
* Compare our tab identifier associated with this session (particular tab)
* with that of one that is in window name Storage (the active one for this browser).
* This browser tab is good if any of the following are true:
* 1. There is no cookie Storage Guid yet (first browser tab).
* 2. The window name Storage Guid matches the cookie Guid. Same tab, refreshed.
* 3. The window name Storage timeout period has ended.
*
* If our current session is the correct active one, an interval will continue
* to re-insert the window name Storage value with an updated timestamp.
*
* Another thing, that should be done (so you can open a tab within 15 seconds of closing it) would be to do the following (or hook onto an existing onunload method):
*/
function isTabDuplicated() {
//console.log("In testTab");
var sessionGuid = GetItem(ItemType.Session) || createGUID();
SetItem(ItemType.Session, sessionGuid);
var val = GetItem(ItemType.Local);
var tabObj = (val == "" ? null : JSON.parse(val)) || null; // If no or stale tab object, our session is the winner. If the guid matches, ours is still the winner
if (
tabObj === null ||
tabObj.timestamp < new Date().getTime() - localStorageTimeout ||
tabObj.guid === sessionGuid
) {
var setTabObj = function setTabObj() {
//console.log("In setTabObj");
var newTabObj = {
guid: sessionGuid,
timestamp: new Date().getTime()
};
SetItem(ItemType.Local, JSON.stringify(newTabObj));
};
setTabObj();
setInterval(setTabObj, localStorageResetInterval); //every x interval refresh timestamp in cookie
window.onunload = function() {
SetItem(ItemType.Local, "");
localStorage.removeItem(localStorageTabKey);
};
return false;
} else {
// An active tab is already open that does not match our session guid.
return true;
}
}
return isTabDuplicated();
};