-
Notifications
You must be signed in to change notification settings - Fork 26
/
Copy pathbackground.js
181 lines (166 loc) · 5.66 KB
/
background.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
import { setDefaultSettings } from "./utils.js";
setDefaultSettings();
// Interval (in seconds) to update timer
var UPDATE_INTERVAL = 3;
// Add sites which are not in the top threshold sites to "other" category
// WARNING: Setting the threshold too low will schew the data set
// so that it will favor sites that already have a lot of time but
// trash the ones that are visited frequently for short periods of time
function combineEntries(threshold) {
chrome.storage.local.get(["domains", "other"], function (items) {
var domains = items.domains;
var other = items.other;
// Don't do anything if there are less than threshold domains
if (Object.keys(domains).length <= threshold) {
return;
}
// Sort the domains by decreasing "all" time
var data = [];
chrome.storage.local.get(Object.keys(domains), function (domainItems) {
for (var domain in domains) {
var domain_data = domainItems[domain];
data.push({
domain: domain,
all: domain_data.all,
});
}
data.sort(function (a, b) {
return b.all - a.all;
});
// Delete data after top threshold and add it to other
for (var i = threshold; i < data.length; i++) {
other.all += data[i].all;
var domain = data[i].domain;
chrome.storage.local.remove(domain);
delete domains[domain];
}
chrome.storage.local.set({
other: other,
domains: domains,
});
});
});
}
// Check to make sure data is kept for the same day
function checkDate() {
var todayStr = new Date().toLocaleDateString();
chrome.storage.local.get(["date", "domains", "total"], function (items) {
var saved_day = items.date;
if (saved_day !== todayStr) {
// Reset today's data
var domains = items.domains;
for (var domain in domains) {
chrome.storage.local.get(domain, function (domainData) {
domainData[domain].today = 0;
chrome.storage.local.set({ [domain]: domainData[domain] });
});
}
// Reset total for today
var total = items.total;
total.today = 0;
chrome.storage.local.set({ total: total });
// Combine entries that are not part of top 500 sites
combineEntries(500);
// Keep track of number of days web timer has been used
chrome.storage.local.get("num_days", function (items) {
chrome.storage.local.set({ num_days: items.num_days + 1 });
});
// Update date
chrome.storage.local.set({ date: todayStr });
}
});
}
// Extract the domain from the url
// e.g. http://google.com/ -> google.com
function extractDomain(url) {
var re = /:\/\/(www\.)?(.+?)\//;
return url.match(re)[2];
}
function inBlacklist(url) {
if (!url.match(/^http/)) {
return true;
}
return new Promise((resolve) => {
chrome.storage.local.get("blacklist", function (items) {
var blacklist = items.blacklist;
for (var i = 0; i < blacklist.length; i++) {
if (url.match(blacklist[i])) {
resolve(true);
return;
}
}
resolve(false);
});
});
}
// Update the data
function updateData() {
// Only count time if system has not been idle for 30 seconds
chrome.idle.queryState(30, function (state) {
if (state === "active") {
// Select single active tab from focused window
chrome.tabs.query(
{ lastFocusedWindow: true, active: true },
function (tabs) {
if (tabs.length === 0) {
return;
}
var tab = tabs[0];
// Make sure 'today' is up-to-date
checkDate();
inBlacklist(tab.url).then((isBlacklisted) => {
if (!isBlacklisted) {
var domain = extractDomain(tab.url);
// Add domain to domain list if not already present
chrome.storage.local.get(["domains", domain], function (items) {
var domains = items.domains || {};
if (!(domain in domains)) {
domains[domain] = 1;
chrome.storage.local.set({ domains: domains });
}
var domain_data = items[domain] || {
today: 0,
all: 0,
};
domain_data.today += UPDATE_INTERVAL;
domain_data.all += UPDATE_INTERVAL;
chrome.storage.local.set({ [domain]: domain_data });
// Update total time
chrome.storage.local.get("total", function (items) {
var total = items.total;
total.today += UPDATE_INTERVAL;
total.all += UPDATE_INTERVAL;
chrome.storage.local.set({ total: total });
// Update badge with number of minutes spent on current site
var num_min = Math.floor(domain_data.today / 60).toString();
if (num_min.length < 4) {
num_min += "m";
}
chrome.action.setBadgeText({
text: num_min,
});
});
});
} else {
// Clear badge
chrome.action.setBadgeText({
text: "",
});
}
});
}
);
}
});
}
// Update timer data every UPDATE_INTERVAL seconds
setInterval(updateData, UPDATE_INTERVAL * 1000);
/**
* Call a Chrome API every 25 seconds to keep the service worker alive.
*
* Chrome normally terminates a service worker after 30 seconds of inactivity. Receiving an event or calling an extension API resets this timer.
*/
function keepAlive() {
setInterval(chrome.runtime.getPlatformInfo, 25 * 1000);
}
keepAlive();