install usercss from raw.githubusercontent.com

This commit is contained in:
tophf 2017-11-24 19:33:50 +03:00
parent 59d32e6f2f
commit aedb02bbb1
5 changed files with 120 additions and 37 deletions

View File

@ -28,6 +28,16 @@ chrome.runtime.onMessage.addListener(onRuntimeMessage);
chrome.webNavigation.onReferenceFragmentUpdated.addListener(data =>
listener('styleReplaceAll', data));
if (FIREFOX) {
// FF applies page CSP even to content scripts, https://bugzil.la/1267027
chrome.webNavigation.onCommitted.addListener(webNavUsercssInstallerFF, {
url: [
{urlPrefix: 'https://raw.githubusercontent.com/', urlSuffix: '.user.css'},
{urlPrefix: 'https://raw.githubusercontent.com/', urlSuffix: '.user.styl'},
]
});
}
}
if (chrome.contextMenus) {
@ -242,6 +252,21 @@ function webNavigationListenerChrome(method, data) {
}
function webNavUsercssInstallerFF(data) {
const {tabId} = data;
Promise.all([
sendMessage({tabId, method: 'ping'}),
// we need tab index to open the installer next to the original one
// and also to skip the double-invocation in FF which assigns tab url later
getTab(tabId),
]).then(([pong, tab]) => {
if (pong !== true && tab.url !== 'about:blank') {
usercssHelper.openInstallPage(tab, {direct: true});
}
});
}
function updateIcon(tab, styles) {
if (tab.id < 0) {
return;

View File

@ -203,12 +203,18 @@ function dbExecChromeStorage(method, data) {
case 'getAll':
return chromeLocal.get(null).then(storage => {
const styles = [];
const leftovers = [];
for (const key in storage) {
if (key.startsWith(STYLE_KEY_PREFIX) &&
Number(key.substr(STYLE_KEY_PREFIX.length))) {
styles.push(storage[key]);
} else if (key.startsWith('tempUsercssCode')) {
leftovers.push(key);
}
}
if (leftovers.length) {
chromeLocal.remove(leftovers);
}
return {target: {result: styles}};
});
}

View File

@ -1,4 +1,4 @@
/* global usercss saveStyle getStyles */
/* global usercss saveStyle getStyles chromeLocal */
'use strict';
// eslint-disable-next-line no-var
@ -78,16 +78,29 @@ var usercssHelper = (() => {
);
}
function openInstallPage(tab, request) {
const url = '/install-usercss.html' +
'?updateUrl=' + encodeURIComponent(request.updateUrl) +
'&tabId=' + tab.id;
function openInstallPage(tab, {url = tab.url, direct} = {}) {
if (direct) {
prefetchCodeForInstallation(tab.id, url);
}
return wrapReject(openURL({
url,
url: '/install-usercss.html' +
'?updateUrl=' + encodeURIComponent(url) +
'&tabId=' + (direct ? -tab.id : tab.id),
index: tab.index + 1,
openerTabId: tab.id,
}));
}
function prefetchCodeForInstallation(tabId, url) {
const key = 'tempUsercssCode' + tabId;
Promise.all([
download(url),
chromeLocal.setValue(key, {loading: true}),
]).then(([code]) => {
chromeLocal.setValue(key, code);
setTimeout(() => chromeLocal.remove(key), 60e3);
});
}
return {build, save, findDup, openInstallPage};
})();

View File

@ -65,10 +65,6 @@ function initUsercssInstall() {
let watcher;
chrome.runtime.onConnect.addListener(port => {
// FIXME: is this the correct way to reject a connection?
// https://developer.chrome.com/extensions/messaging#connect
console.assert(port.name === 'usercss-install');
port.onMessage.addListener(msg => {
switch (msg.method) {
case 'getSourceCode':
@ -102,7 +98,7 @@ function initUsercssInstall() {
});
chrome.runtime.sendMessage({
method: 'openUsercssInstallPage',
updateUrl: location.href,
url: location.href,
}, r => r && r.__ERROR__ && alert(r.__ERROR__));
}

View File

@ -1,5 +1,5 @@
/* global CodeMirror semverCompare makeLink closeCurrentTab */
/* global messageBox */
/* global messageBox download chromeLocal */
'use strict';
(() => {
@ -7,30 +7,35 @@
let liveReload = false;
let installed = false;
const port = chrome.tabs.connect(
Number(params.get('tabId')),
{name: 'usercss-install', frameId: 0}
);
port.postMessage({method: 'getSourceCode'});
port.onMessage.addListener(msg => {
switch (msg.method) {
case 'getSourceCodeResponse':
if (msg.error) {
messageBox.alert(msg.error);
} else {
initSourceCode(msg.sourceCode);
}
break;
case 'sourceCodeChanged':
if (msg.error) {
messageBox.alert(msg.error);
} else {
liveReloadUpdate(msg.sourceCode);
}
break;
}
});
port.onDisconnect.addListener(closeCurrentTab);
const tabId = Number(params.get('tabId'));
let port;
if (tabId < 0) {
$('.live-reload').remove();
getCodeDirectly();
} else {
port = chrome.tabs.connect(tabId);
port.postMessage({method: 'getSourceCode'});
port.onMessage.addListener(msg => {
switch (msg.method) {
case 'getSourceCodeResponse':
if (msg.error) {
messageBox.alert(msg.error);
} else {
initSourceCode(msg.sourceCode);
}
break;
case 'sourceCodeChanged':
if (msg.error) {
messageBox.alert(msg.error);
} else {
liveReloadUpdate(msg.sourceCode);
}
break;
}
});
port.onDisconnect.addListener(closeCurrentTab);
}
const cm = CodeMirror($('.main'), {readOnly: true});
let liveReloadPending = Promise.resolve();
@ -183,7 +188,7 @@
sendMessage({method: 'openEditor', id: style.id});
if (!liveReload) {
port.postMessage({method: 'closeTab'});
chrome.runtime.sendMessage({method: 'closeTab'});
}
window.dispatchEvent(new CustomEvent('installed'));
@ -252,6 +257,10 @@
}
};
if (!port) {
return;
}
// live reload
const setLiveReload = $('.live-reload input[type=checkbox]');
if (updateUrl.protocol !== 'file:') {
@ -299,4 +308,38 @@
cm.setSize(null, $('.main').offsetHeight - $('.warnings').offsetHeight);
}
}
function getCodeDirectly() {
// FF applies page CSP even to content scripts, https://bugzil.la/1267027
// To circumvent that, the bg process downloads the code directly
const key = 'tempUsercssCode' + (-tabId);
chrome.storage.local.get(key, data => {
const code = data && data[key];
// bg already downloaded the code
if (typeof code === 'string') {
initSourceCode(code);
chrome.storage.local.remove(key);
return;
}
// bg still downloads the code
if (code && code.loading) {
const waitForCodeInStorage = (changes, area) => {
if (area === 'local' && key in changes) {
initSourceCode(changes[key].newValue);
chrome.storage.onChanged.removeListener(waitForCodeInStorage);
chrome.storage.local.remove(key);
}
};
chrome.storage.onChanged.addListener(waitForCodeInStorage);
return;
}
// on the off-chance dbExecChromeStorage.getAll ran right after bg download was saved
download(params.get('updateUrl'))
.then(initSourceCode)
.catch(err => messageBox.alert(t('styleInstallFailed', String(err))));
});
}
})();