/
worker.js
221 lines (203 loc) · 8.95 KB
/
worker.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
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
/* import a helper library */
dump("************** worker.js is executing ****************\n");
importScripts("workerScript.js");
// just a demo icon that we user for our toolbar button and our
// recommend button.
var RECOMMEND_ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAC7ElEQVQ4jW2TS28bZRSGn7l4xnfHTopNLlYToC1JqMQlIHFRRDdISKWLClFVbIBFfwLsu0GVqi5asegCNiyQ2FCkgqIiVC4toYtCEijNDYckbjKO7x57xjOe72OR0lA1Z3n0nkdH57yvwj4lg0BWWi5OIDFCOjEzRNzUlP20jzRn59bEj1ZHGRrLMZo0iZo6dV+wVbDkq/k0I9mU+n+9CiB7rnA2fhNnL38nTl2eIzBUJswG6XQUI2wQT4RZN8J8fWuWO7/MCK/VFP8BdIDe1iqlC8fJ1Cc5OzxJ/qtPKJy5SFqA4guW6y5rTYVkXcMcmGHlm18Jum2hmTF1F9CwMHqbvJ0o4VevUWYUZ/Emtt+hOvIMDUVF74txx08jDY2B7Dzd+u29DYK7V/Cq4CPBDJPKCA6sfcuXFZ0V5RBus0Op1mWhYPNDT/L+sQDJ0i5AdhuyfP51elIB04BonMhglkvJ01xPvURiaYfSYkFWKk20Ro2D412k61Nenb0P8Fz8WgNCBr4Wpni7xNXWu1x5Ooe0a/R8H2E16d7bJOQ7PDFcQqHBcuH+EaXU6bR0BCqi1yMTl7yZ+4uS8yeDTp2JrMNnkTF+qtq8mLSIe0X8cpHD+fTuG7VkvyIyU6K17YhIQhO5pzQxVrnGh1sf8V7lHJ35BUr36girw6mxP+gPVnBX/yYcfWXviKnpkyx+8TmhtIeeHyDcp3JjcZBLGy9zqxEH9wbvHPF5a3ydTnGbwpxCdmJqz4lB1w1ufnCS8s9XOTSdIpaNqkZUZ7OV5B+rzWOxshzP2+jpBJ7dwkq9wdEzM+pDVq6vF4LvT59ALc6Tfy6qJh+PYkYEIc1D+J5UwgI9KRC5F0gf/xQjM6k+sDJAdChP/uOL2EePsbnQYWe+TGejil+zwfOw3R5z1jTbT557MPxImFrtdnB3aQlr9rrK8u+E3R3UWATlQL9k+Ah9h1/j2eenHgrTvhFtu13Zats4jgsSRkeG9tUB/AvjNVepPwFrSQAAAABJRU5ErkJggg==";
function log(msg) {
dump(new Date().toISOString() + ": [dssworker] " + msg + "\n");
try {
console.log(new Date().toISOString() + ": [dssworker] " + msg);
} catch (e) {}
}
// The social.initialize message is sent from Firefox as a part of startup for
// the worker. We keep track of the port so we can communicate back to Firefox
// for any of our api calls. All other ports come from our content. For this
// demo, we keep track of all our ports in the _broadcastReceivers list. We can
// then broadcast messages to all of our content.
var apiPort;
var _broadcastReceivers = [];
function broadcast(topic, payload)
{
// we need to broadcast to all ports connected to this shared worker
ports = [].concat(_broadcastReceivers);
for (var i = 0; i < ports.length; i++) {
//log("about to broadcast to " + _broadcastReceivers[i]);
try {
ports[i].postMessage({topic: topic, data: payload});
} catch(e) {
_broadcastReceivers.splice(i, 1);
}
}
}
ononline = function() {
dump("!!!!!!! ononline called "+navigator.onLine+"\n");
}
onoffline = function() {
dump("!!!!!!! onoffline called "+navigator.onLine+"\n");
}
// Called when any port connects to the worker
onconnect = function(e) {
try {
var port = e.ports[0];
// this is our basic message handler
port.onmessage = function(e) {
//log("worker onmessage: " + JSON.stringify(e.data));
var msg = e.data;
if (!msg) {
log("onmessage called with no data")
return;
}
// handle the special message that tells us a port is closing.
if (msg.topic && msg.topic == "social.port-closing") {
if (port == apiPort) {
dump("!!!!!!!!!!!!! apiPort has closed!\n");
}
var index = _broadcastReceivers.indexOf(port);
if (index != -1) {
log("removed receiver " + index);
_broadcastReceivers.splice(index, 1);
}
log("bwmworker port closed - now " + _broadcastReceivers.length + " connections.");
return;
}
if (msg.topic && handlers[msg.topic])
handlers[msg.topic](port, msg);
else {
log("message topic not handled: "+msg.topic+" "+JSON.stringify(msg));
// this is just a simple way for content to get a call passed through
// to the worker api in Firefox for our testing.
try {
apiPort.postMessage(msg);
} catch(e) {
log(e+"\n");
}
}
}
// worker.connected is our own message, it is not part of any api. We
// use it as a way to signal content that we are connected to them. This
// is useful if we reload the worker (see social.reload-worker)
port.postMessage({topic: "worker.connected"});
// upon loading of the worker we want to send the user profile, if any.
// an empty profile tells Firefox and other content (if necessary) that
// the user is not currently logged in.
port.postMessage({topic: "social.user-profile", data: userData});
} catch (e) {
log(e);
}
}
var userData = {};
// We have no way to see cookies in the worker, so we have to ask Firefox
// to tell us what the cookies are for our domain. As well, since we are
// relying on cookies as part of our demo login functionality, we need to
// poll the cookies for changes. We start that polling during social.initialize
function checkCookies() {
apiPort.postMessage({topic: 'social.cookies-get'});
}
// Messages from the sidebar and chat windows:
var handlers = {
// worker.reload is our own message and is not defined by socialapi. Our
// test sidebar can send this, letting us know to force a reload of
// this worker script.
'worker.reload': function(port, msg) {
clearInterval(checkCookies);
broadcast(msg.topic, msg.data);
apiPort.postMessage({topic: 'social.reload-worker'});
},
// This is the first call we should receive from Firefox. We track that
// port as teh apiPort, and start our polling of the cookies for login/logout
// tracking
'social.initialize': function(port, data) {
log("social.initialize called, capturing apiPort");
apiPort = port;
setInterval(checkCookies, 1000);
},
// our content (sidebar, etc) can request broadcast messages.
'broadcast.listen': function(port, data) {
if (data)
_broadcastReceivers.push(port);
else {
var i = _broadcastReceivers.indexOf(port);
f (i != -1)
_broadcastReceivers.splice(i, 1);
}
},
// Sent by firefox to the worker. The user has clicked on the recommend button
// in the urlbar
'social.user-recommend': function(port, msg) {
log("demo worker got recommend request for " + msg.data.url);
// tell our content
broadcast(msg.topic, msg.data);
},
// Sent by firefox to the worker. the user has clicked on the recommend button
// in the urlbar a second time, resulting in a request to unrecommend the url.
'social.user-unrecommend': function(port, msg) {
log("demo worker got unrecommend request for " + msg.data.url);
// tell our content
broadcast(msg.topic, msg.data);
},
// Sent by firefox to the worker. Firefox needs some configuration data to
// enable the recommend button in the urlbar. If we do not support the
// recommend button, we do not have to respond to this.
'social.user-recommend-prompt': function(port, msg) {
port.postMessage({topic: 'social.user-recommend-prompt-response',
data: {
messages: {
'shareTooltip': "Recommend this site",
'unshareTooltip': "Remove recommendation",
'sharedLabel': "Love It!",
'unsharedLabel': "Hate It!",
"unshareLabel": "dont do this",
"portraitLabel": "dont do this",
"unshareConfirmLabel": "dont do this",
"unshareConfirmAccessKey": "dont do this",
"unshareCancelLabel": "dont do this",
"unshareCancelAccessKey": "dont do this"
},
images: {
'share': RECOMMEND_ICON,
'unshare': RECOMMEND_ICON
}
}
});
},
// Sent by Firefox as a response to our checkCookies call above. We parse
// the response and set our userData from the cookie. If the cookie contains
// any data, we send back the user-profile message so Firefox can display user
// profile information. We must send a valid user-profile before we can
// setup any notification icons in our toolbar button.
'social.cookies-get-response': function(port, msg) {
try {
let cookies = msg.data;
let newUserData;
for (var i=0; i < cookies.length; i++) {
if (cookies[i].name == "userdata") {
newUserData = cookies[i].value ? JSON.parse(cookies[i].value) : {};
break;
}
}
if (userData.userName != newUserData.userName) {
var end = location.href.indexOf("worker.js");
var baselocation = location.href.substr(0, end);
userData = newUserData;
port.postMessage({topic: "social.user-profile", data: userData});
broadcast('social.user-profile', userData);
if (userData.userName)
port.postMessage({topic: 'social.ambient-notification',
data: {
name: "test",
iconURL: RECOMMEND_ICON,
counter: "10",
contentPanel: baselocation + "/statusPanel.html",
label: "Test Ambient 1",
// normally this would be a url to a web page that works in
// a normal browser tab, we're just reusing this panel for
// testing
menuURL: baselocation + "/statusPanel.html"
}});
}
} catch(e) {
dump(e.stack+"\n");
}
}
}