-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathutils.js
142 lines (126 loc) · 4.73 KB
/
utils.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
function namespace(code) {
code()
}
namespace(function() {
window.httpGet = function(url, action, onError, onSuccess) {
_httpSend('GET', url, null, action, onError, onSuccess)
}
window.httpPost = function(url, body, action, onError, onSuccess) {
_httpSend('POST', url, body, action, onError, onSuccess)
}
function _httpSend(verb, url, body, action, onError, onSuccess) {
var request = new XMLHttpRequest()
request.onreadystatechange = function() {
if (this.readyState !== XMLHttpRequest.DONE) return
this.onreadystatechange = null
this.ontimeout = null
if (this.status !== 200) {
onError('Received a ' + this.status + ' error while attempting to ' + action)
} else {
onSuccess(JSON.parse(this.responseText))
}
}
request.ontimeout = function() {
this.onreadystatechange = null
this.ontimeout = null
onError('Network timed out while attempting to ' + action)
}
request.timeout = 120000 // 120,000 milliseconds = 2 minutes
request.open(verb, url, true)
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
request.send(body)
}
var storage = null
if (typeof(chrome) !== 'undefined' && chrome.storage) {
storage = chrome.storage
} else if (typeof(browser) !== 'undefined' && browser.storage) {
storage = browser.storage
} else {
storage = {
'local': {
'get': function(key, callback) {
window.setTimeout(function() {
var value = window.localStorage.getItem(key)
try {
value = JSON.parse(value)
} catch (e) { /* JSON parse failed, return original value */ }
callback({[key]: value})
}, 0)
},
'set': function(data) {
for (var key of Object.keys(data)) {
window.localStorage.setItem(key, JSON.stringify(data[key]))
}
},
'clear': function() {window.localStorage.clear()},
}
}
storage.sync = storage.local // No such thing as 'remote storage' if we aren't loaded as an extension.
}
window.getLocal = function(key, callback) {internalGet(storage.local, key, callback)}
window.getRemote = function(key, callback) {internalGet(storage.sync, key, callback)}
window.setLocal = function(key, value) {internalSet(storage.local, key, value)}
window.setRemote = function(key, value) {internalSet(storage.sync, key, value)}
window.delLocal = function() {storage.local.clear()}
window.delRemote = function() {storage.remote.clear()}
// For perf reasons -- I call this quite often.
var inMemory = {}
function internalGet(store, key, callback) {
if (inMemory[key]) {
setTimeout(function() {
callback(inMemory[key])
}, 0)
return
}
store.get([key], function(result) {
value = result == null ? null : result[key] // Chrome returns {}, firefox returns null, localstorage returns {value:null}
inMemory[key] = value
callback(value)
})
}
function internalSet(store, key, value) {
inMemory[key] = value
// This odd syntax is how we construct dictionaries with variable key names.
store.set({[key]: value})
}
window.clearStorage = function() {
storage.local.clear()
}
window.localize = function(key, defaultValue) {
var value = null
if (typeof(chrome) !== 'undefined' && chrome.i18n) {
value = chrome.i18n.getMessage(key)
} else if (typeof(browser) !== 'undefined' && browser.i18n) {
value = browser.i18n.getMessage(key)
}
if (value == null || value == '') {
console.warn('No localized string available for "' + key + '", falling back to english.')
return defaultValue
}
return value
}
window.reparent = function(child, newParent) {
var oldParent = child.parentElement
oldParent.removeChild(child)
newParent.appendChild(child)
}
var logLines = []
var logLinesIndex = 0
function saveLog(level, args) {
logLines[logLinesIndex] = level + Array.prototype.join.call(args, ' ')
logLinesIndex = (logLinesIndex + 1) % 100
}
window.getLog = function() {
return logLines.join('\n')
}
var _console = Object.assign({}, console)
console.debug = function() { saveLog('DEBUG', arguments); _console.debug.apply(null, arguments) }
console.log = function() { saveLog('LOG ', arguments); _console.log.apply(null, arguments) }
console.info = function() { saveLog('INFO ', arguments); _console.info.apply(null, arguments) }
console.warn = function() { saveLog('WARN ', arguments); _console.warn.apply(null, arguments) }
console.error = function() { saveLog('ERROR', arguments); _console.error.apply(null, arguments) }
window.addEventListener('error', function(e) {
saveLog('THROW', e.error ? e.error.stack : e.message)
return false // Call the default handler
})
})