-
Notifications
You must be signed in to change notification settings - Fork 221
/
popup.js
187 lines (178 loc) · 5.83 KB
/
popup.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
/**
* (c) 2013 Rob Wu <rob@robwu.nl>
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/* jshint browser:true, devel:true */
/* globals chrome, get_crx_url, get_zip_name, can_viewsource_crx_url, openCRXasZip */
/* globals encodeQueryString */
/* globals getPlatformInfoAsync */
'use strict';
var cws_url;
var crx_url;
var filename;
// See bg-contextmenu for potential values, at MENU_ID_ACTION_MENU.
var gActionClickAction = 'popup';
initialize();
function initialize() {
var storageIsReady = false;
getPlatformInfoAsync(function() {
// Hack: although not guaranteed by the API, the getPlatformInfoAsync
// call resolves ealier than the later tabs.query call, in practice.
console.assert(!crx_url, 'getPlatformInfoAsync() should run first');
});
// Get CWS URL. On failure, close the popup
chrome.tabs.query({
active: true,
currentWindow: true
}, function(tabs) {
cws_url = tabs[0].url;
// Note: Assuming getPlatformInfoAsync() to have resolved first.
crx_url = get_crx_url(cws_url);
filename = get_zip_name(crx_url);
if (!can_viewsource_crx_url(crx_url)) {
//#if FIREFOX
chrome.pageAction.hide(tabs[0].id);
//#else
chrome.action.disable(tabs[0].id);
//#endif
window.close();
return;
}
ready();
if (storageIsReady) {
ready2();
}
});
chrome.storage.sync.get({
actionClickAction: gActionClickAction,
}, function(items) {
gActionClickAction = items && items.actionClickAction || gActionClickAction;
storageIsReady = true;
if (crx_url) {
ready2();
}
});
}
function ready() {
document.getElementById('download').onclick = doDownload;
document.getElementById('view-source').onclick = doViewSource;
//#if OPERA
document.getElementById('install-as-nex').onclick = doInstall;
//#endif
// When the settings have been read, ready2 will run to finish.
}
function ready2() {
if (gActionClickAction == 'popup') {
// Default action is keeping this popup open.
// Nothing else left to do.
} else if (gActionClickAction == 'download') {
doDownload();
} else if (gActionClickAction == 'view-source') {
doViewSource();
}
}
var hasDownloadedOnce = false;
function doDownload() {
if (hasDownloadedOnce) {
console.log('Download is pending.');
return;
}
openCRXasZip(crx_url, function(blob, publicKey) {
tryTriggerDownload(blob, filename);
}, function(errorMessage) {
hasDownloadedOnce = false;
document.getElementById('download').classList.toggle('downloading', hasDownloadedOnce);
console.error(errorMessage);
alert('Error in CRX Viewer:\n\n' + errorMessage);
}, onXHRprogress.bind(null, document.getElementById('download')));
hasDownloadedOnce = true;
document.getElementById('download').classList.toggle('downloading', hasDownloadedOnce);
}
function doViewSource() {
chrome.tabs.query({
active: true,
lastFocusedWindow: true,
}, function(tabs) {
chrome.tabs.create({
url: chrome.runtime.getURL('crxviewer.html') +
'?' + encodeQueryString({crx: crx_url, zipname: filename}),
active: true,
index: tabs && tabs.length ? tabs[0].index + 1 : undefined,
//#if FIREFOX
cookieStoreId: tabs && tabs[0] && tabs[0].cookieStoreId,
//#endif
}, function() {
window.close();
});
});
}
function onXHRprogress(progressContainer, xhrProgressEvent) {
var progressBar = progressContainer.querySelector('progress');
if (!progressBar) {
progressBar = document.createElement('progress');
progressContainer.appendChild(progressBar);
}
if (xhrProgressEvent.lengthComputable) {
progressBar.max = xhrProgressEvent.total;
progressBar.value = xhrProgressEvent.loaded;
} else {
progressBar.removeAttribute('value');
}
}
//#if OPERA
var hasDownloadedCRX = false;
function doInstall() {
var filename_nex = filename.replace(/\.zip$/, '.nex');
if (hasDownloadedCRX) {
console.log('Download is pending.');
return;
}
var x = new XMLHttpRequest();
x.open('GET', crx_url);
x.responseType = 'blob';
x.onprogress = onXHRprogress.bind(null, document.getElementById('install-as-nex'));
x.onload = function() {
var blob = x.response;
if (!blob) {
hasDownloadedCRX = false;
alert('Unexpected error: no response for ' + crx_url);
return;
}
if (blob.type !== 'application/x-navigator-extension' ||
blob.type !== 'application/x-chrome-extension') {
blob = new Blob([blob], {
type: 'application/x-navigator-extension'
});
}
tryTriggerDownload(blob, filename_nex);
};
x.onerror = function() {
hasDownloadedCRX = false;
alert('Network error for ' + crx_url);
};
x.onabort = function() {
hasDownloadedCRX = false;
};
x.send();
hasDownloadedCRX = true;
}
//#endif
function tryTriggerDownload(blob, filename) {
chrome.downloads.download({
url: URL.createObjectURL(blob),
filename: filename
}, function() {
//#if FIREFOX
// In Firefox, closing too soon may prevent the download from completing
// due to blob:-URL invalidation. So wait a little bit before actually
// closing the popup.
setTimeout(function() {
window.close();
}, 200);
//#else
// The popup should have closed already, but if not, do it now.
window.close();
//#endif
});
}