faster install from known sites
This commit is contained in:
parent
0162f39163
commit
78b0e33ba4
|
@ -1,8 +1,8 @@
|
|||
/* global download prefs openURL FIREFOX CHROME
|
||||
URLS ignoreChromeError usercssHelper chromeLocal semverCompare
|
||||
URLS ignoreChromeError chromeLocal semverCompare
|
||||
styleManager msg navigatorUtil workerUtil contentScripts sync
|
||||
findExistingTab activateTab isTabReplaceable getActiveTab
|
||||
tabManager */
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
|
@ -111,14 +111,6 @@ navigatorUtil.onUrlChange(({tabId, frameId}, type) => {
|
|||
}
|
||||
});
|
||||
|
||||
tabManager.onUpdate(({tabId, url, oldUrl = ''}) => {
|
||||
if (usercssHelper.testUrl(url) && !oldUrl.startsWith(URLS.installUsercss)) {
|
||||
usercssHelper.testContents(tabId, url).then(data => {
|
||||
if (data.code) usercssHelper.openInstallerPage(tabId, url, data);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (FIREFOX) {
|
||||
// FF misses some about:blank iframes so we inject our content script explicitly
|
||||
navigatorUtil.onDOMContentLoaded(webNavIframeHelperFF, {
|
||||
|
|
|
@ -1,15 +1,8 @@
|
|||
/* global API_METHODS usercss styleManager deepCopy openURL download URLS */
|
||||
/* global API_METHODS usercss styleManager deepCopy */
|
||||
/* exported usercssHelper */
|
||||
'use strict';
|
||||
|
||||
const usercssHelper = (() => {
|
||||
const installCodeCache = {};
|
||||
const clearInstallCode = url => delete installCodeCache[url];
|
||||
const isResponseText = r => /^text\/(css|plain)(;.*?)?$/i.test(r.headers.get('content-type'));
|
||||
// in Firefox we have to use a content script to read file://
|
||||
const fileLoader = !chrome.app && // not relying on navigator.ua which can be spoofed
|
||||
(tabId => browser.tabs.executeScript(tabId, {file: '/content/install-hook-usercss.js'}).then(r => r[0]));
|
||||
|
||||
API_METHODS.installUsercss = installUsercss;
|
||||
API_METHODS.editSaveUsercss = editSaveUsercss;
|
||||
API_METHODS.configUsercssVars = configUsercssVars;
|
||||
|
@ -17,50 +10,6 @@ const usercssHelper = (() => {
|
|||
API_METHODS.buildUsercss = build;
|
||||
API_METHODS.findUsercss = find;
|
||||
|
||||
API_METHODS.getUsercssInstallCode = url => {
|
||||
// when the installer tab is reloaded after the cache is expired, this will throw intentionally
|
||||
const {code, timer} = installCodeCache[url];
|
||||
clearInstallCode(url);
|
||||
clearTimeout(timer);
|
||||
return code;
|
||||
};
|
||||
|
||||
return {
|
||||
|
||||
testUrl(url) {
|
||||
return url.includes('.user.') &&
|
||||
/^(https?|file|ftps?):/.test(url) &&
|
||||
/\.user\.(css|styl)$/.test(url.split(/[#?]/, 1)[0]);
|
||||
},
|
||||
|
||||
/** @return {Promise<{ code:string, inTab:boolean } | false>} */
|
||||
testContents(tabId, url) {
|
||||
const isFile = url.startsWith('file:');
|
||||
const inTab = isFile && Boolean(fileLoader);
|
||||
return Promise.resolve(isFile || fetch(url, {method: 'HEAD'}).then(isResponseText))
|
||||
.then(ok => ok && (inTab ? fileLoader(tabId) : download(url)))
|
||||
.then(code => /==userstyle==/i.test(code) && {code, inTab});
|
||||
},
|
||||
|
||||
openInstallerPage(tabId, url, {code, inTab} = {}) {
|
||||
const newUrl = `${URLS.installUsercss}?updateUrl=${encodeURIComponent(url)}`;
|
||||
if (inTab) {
|
||||
browser.tabs.get(tabId).then(tab =>
|
||||
openURL({
|
||||
url: `${newUrl}&tabId=${tabId}`,
|
||||
active: tab.active,
|
||||
index: tab.index + 1,
|
||||
openerTabId: tabId,
|
||||
currentWindow: null,
|
||||
}));
|
||||
} else {
|
||||
const timer = setTimeout(clearInstallCode, 10e3, url);
|
||||
installCodeCache[url] = {code, timer};
|
||||
chrome.tabs.update(tabId, {url: newUrl});
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
function buildMeta(style) {
|
||||
if (style.usercssData) {
|
||||
return Promise.resolve(style);
|
||||
|
|
82
background/usercss-install-helper.js
Normal file
82
background/usercss-install-helper.js
Normal file
|
@ -0,0 +1,82 @@
|
|||
/* global API_METHODS openURL download URLS tabManager */
|
||||
'use strict';
|
||||
|
||||
(() => {
|
||||
const installCodeCache = {};
|
||||
const clearInstallCode = url => delete installCodeCache[url];
|
||||
const isContentTypeText = type => /^text\/(css|plain)(;.*?)?$/i.test(type);
|
||||
|
||||
// in Firefox we have to use a content script to read file://
|
||||
const fileLoader = !chrome.app && (
|
||||
async tabId =>
|
||||
(await browser.tabs.executeScript(tabId, {file: '/content/install-hook-usercss.js'}))[0]);
|
||||
|
||||
const urlLoader =
|
||||
async (tabId, url) => (
|
||||
url.startsWith('file:') ||
|
||||
tabManager.get(tabId, isContentTypeText.name) ||
|
||||
isContentTypeText((await fetch(url, {method: 'HEAD'})).headers.get('content-type'))
|
||||
) && download(url);
|
||||
|
||||
API_METHODS.getUsercssInstallCode = url => {
|
||||
// when the installer tab is reloaded after the cache is expired, this will throw intentionally
|
||||
const {code, timer} = installCodeCache[url];
|
||||
clearInstallCode(url);
|
||||
clearTimeout(timer);
|
||||
return code;
|
||||
};
|
||||
|
||||
// Faster installation on known distribution sites to avoid flicker of css text
|
||||
chrome.webRequest.onBeforeSendHeaders.addListener(({tabId, url}) => {
|
||||
openInstallerPage(tabId, url, {});
|
||||
// Silently suppressing navigation like it never happened
|
||||
return {redirectUrl: 'javascript:void 0'}; // eslint-disable-line no-script-url
|
||||
}, {
|
||||
urls: [
|
||||
URLS.usoArchiveRaw + 'usercss/*.user.css',
|
||||
'*://greasyfork.org/scripts/*/code/*.user.css',
|
||||
'*://sleazyfork.org/scripts/*/code/*.user.css',
|
||||
],
|
||||
types: ['main_frame'],
|
||||
}, ['blocking']);
|
||||
|
||||
// Remember Content-Type to avoid re-fetching of the headers in urlLoader as it can be very slow
|
||||
chrome.webRequest.onHeadersReceived.addListener(({tabId, responseHeaders}) => {
|
||||
const h = responseHeaders.find(h => h.name.toLowerCase() === 'content-type');
|
||||
tabManager.set(tabId, isContentTypeText.name, h && isContentTypeText(h.value) || undefined);
|
||||
}, {
|
||||
urls: '%css,%css?*,%styl,%styl?*'.replace(/%/g, '*://*/*.user.').split(','),
|
||||
types: ['main_frame'],
|
||||
}, ['responseHeaders']);
|
||||
|
||||
tabManager.onUpdate(async ({tabId, url, oldUrl = ''}) => {
|
||||
if (url.includes('.user.') &&
|
||||
/^(https?|file|ftps?):/.test(url) &&
|
||||
/\.user\.(css|styl)$/.test(url.split(/[#?]/, 1)[0]) &&
|
||||
!oldUrl.startsWith(URLS.installUsercss)) {
|
||||
const inTab = url.startsWith('file:') && Boolean(fileLoader);
|
||||
const code = await (inTab ? fileLoader : urlLoader)(tabId, url);
|
||||
if (/==userstyle==/i.test(code)) {
|
||||
openInstallerPage(tabId, url, {code, inTab});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function openInstallerPage(tabId, url, {code, inTab} = {}) {
|
||||
const newUrl = `${URLS.installUsercss}?updateUrl=${encodeURIComponent(url)}`;
|
||||
if (inTab) {
|
||||
browser.tabs.get(tabId).then(tab =>
|
||||
openURL({
|
||||
url: `${newUrl}&tabId=${tabId}`,
|
||||
active: tab.active,
|
||||
index: tab.index + 1,
|
||||
openerTabId: tabId,
|
||||
currentWindow: null,
|
||||
}));
|
||||
} else {
|
||||
const timer = setTimeout(clearInstallCode, 10e3, url);
|
||||
installCodeCache[url] = {code, timer};
|
||||
chrome.tabs.update(tabId, {url: newUrl});
|
||||
}
|
||||
}
|
||||
})();
|
|
@ -318,7 +318,9 @@
|
|||
let sequence = null;
|
||||
if (tabId < 0) {
|
||||
getData = DirectDownloader();
|
||||
sequence = API.getUsercssInstallCode(initialUrl).catch(getData);
|
||||
sequence = API.getUsercssInstallCode(initialUrl)
|
||||
.then(code => code || getData())
|
||||
.catch(getData);
|
||||
} else {
|
||||
getData = PortDownloader();
|
||||
sequence = getData({timer: false});
|
||||
|
|
|
@ -72,6 +72,10 @@ const URLS = {
|
|||
url.startsWith(URLS.usoArchiveRaw) &&
|
||||
parseInt(url.match(/\/(\d+)\.user\.css|$/)[1]),
|
||||
|
||||
extractGreasyForkId: url =>
|
||||
/^https:\/\/(?:greasy|sleazy)fork\.org\/scripts\/(\d+)[^/]*\/code\/[^/]*\.user\.css$/.test(url) &&
|
||||
RegExp.$1,
|
||||
|
||||
supported: url => (
|
||||
url.startsWith('http') && (FIREFOX || !url.startsWith(URLS.browserWebStore)) ||
|
||||
url.startsWith('ftp') ||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
"background/icon-manager.js",
|
||||
"background/background.js",
|
||||
"background/usercss-helper.js",
|
||||
"background/usercss-install-helper.js",
|
||||
"background/style-via-api.js",
|
||||
"background/search-db.js",
|
||||
"background/update.js",
|
||||
|
|
Loading…
Reference in New Issue
Block a user