Add USw to the inline search and proper installing (#1223)
* remember sort order in popup, use "updated" by default * add a USW link in the manager Co-authored-by: tophf <tophf@gmx.com>
This commit is contained in:
parent
892b295897
commit
f10ebffeff
|
@ -630,6 +630,10 @@
|
||||||
"message": "Translate",
|
"message": "Translate",
|
||||||
"description": "Transifex link text on the manage page"
|
"description": "Transifex link text on the manage page"
|
||||||
},
|
},
|
||||||
|
"linkUSW": {
|
||||||
|
"message": "Upload and discover styles on userstyles.world",
|
||||||
|
"description": "Link text for https://userstyles.world/ on the manage page"
|
||||||
|
},
|
||||||
"linterCSSLintIncompatible": {
|
"linterCSSLintIncompatible": {
|
||||||
"message": "CSSLint doesn't support $preprocessorname$ preprocessor",
|
"message": "CSSLint doesn't support $preprocessorname$ preprocessor",
|
||||||
"placeholders": {
|
"placeholders": {
|
||||||
|
|
|
@ -223,7 +223,8 @@ const styleMan = (() => {
|
||||||
style = mergeWithMapped(style);
|
style = mergeWithMapped(style);
|
||||||
const url = !style.url && style.updateUrl && (
|
const url = !style.url && style.updateUrl && (
|
||||||
URLS.extractUsoArchiveInstallUrl(style.updateUrl) ||
|
URLS.extractUsoArchiveInstallUrl(style.updateUrl) ||
|
||||||
URLS.extractGreasyForkInstallUrl(style.updateUrl)
|
URLS.extractGreasyForkInstallUrl(style.updateUrl) ||
|
||||||
|
URLS.extractUSwInstallUrl(style.updateUrl)
|
||||||
);
|
);
|
||||||
if (url) style.url = style.installationUrl = url;
|
if (url) style.url = style.installationUrl = url;
|
||||||
style.originalDigest = await calcStyleDigest(style);
|
style.originalDigest = await calcStyleDigest(style);
|
||||||
|
|
|
@ -36,6 +36,7 @@ bgReady.all.then(() => {
|
||||||
chrome.webRequest.onBeforeSendHeaders.addListener(maybeInstallFromDistro, {
|
chrome.webRequest.onBeforeSendHeaders.addListener(maybeInstallFromDistro, {
|
||||||
urls: [
|
urls: [
|
||||||
URLS.usoArchiveRaw + 'usercss/*.user.css',
|
URLS.usoArchiveRaw + 'usercss/*.user.css',
|
||||||
|
URLS.usw + 'api/style/*.user.css',
|
||||||
'*://greasyfork.org/scripts/*/code/*.user.css',
|
'*://greasyfork.org/scripts/*/code/*.user.css',
|
||||||
'*://sleazyfork.org/scripts/*/code/*.user.css',
|
'*://sleazyfork.org/scripts/*/code/*.user.css',
|
||||||
...[].concat(
|
...[].concat(
|
||||||
|
|
|
@ -37,6 +37,8 @@
|
||||||
'popup.autoResort': false, // auto resort styles after toggling
|
'popup.autoResort': false, // auto resort styles after toggling
|
||||||
'popup.borders': false, // add white borders on the sides
|
'popup.borders': false, // add white borders on the sides
|
||||||
'popup.findStylesInline': true, // use the inline style search
|
'popup.findStylesInline': true, // use the inline style search
|
||||||
|
/** @type {'n' | 'u' | 't' | 'w' | 'r'} see IndexEntry */
|
||||||
|
'popup.findSort': 'u', // the inline style search sort order
|
||||||
|
|
||||||
'manage.onlyEnabled': false, // display only enabled styles
|
'manage.onlyEnabled': false, // display only enabled styles
|
||||||
'manage.onlyLocal': false, // display only styles created locally
|
'manage.onlyLocal': false, // display only styles created locally
|
||||||
|
|
|
@ -78,6 +78,9 @@ const URLS = {
|
||||||
|
|
||||||
usoArchive: 'https://33kk.github.io/uso-archive/',
|
usoArchive: 'https://33kk.github.io/uso-archive/',
|
||||||
usoArchiveRaw: 'https://raw.githubusercontent.com/33kk/uso-archive/flomaster/data/',
|
usoArchiveRaw: 'https://raw.githubusercontent.com/33kk/uso-archive/flomaster/data/',
|
||||||
|
|
||||||
|
usw: 'https://userstyles.world/',
|
||||||
|
|
||||||
extractUsoArchiveId: url =>
|
extractUsoArchiveId: url =>
|
||||||
url &&
|
url &&
|
||||||
url.startsWith(URLS.usoArchiveRaw) &&
|
url.startsWith(URLS.usoArchiveRaw) &&
|
||||||
|
@ -91,6 +94,16 @@ const URLS = {
|
||||||
extractGreasyForkInstallUrl: url =>
|
extractGreasyForkInstallUrl: url =>
|
||||||
/^(https:\/\/(?:greasy|sleazy)fork\.org\/scripts\/\d+)[^/]*\/code\/[^/]*\.user\.css$|$/.exec(url)[1],
|
/^(https:\/\/(?:greasy|sleazy)fork\.org\/scripts\/\d+)[^/]*\/code\/[^/]*\.user\.css$|$/.exec(url)[1],
|
||||||
|
|
||||||
|
extractUSwId: url =>
|
||||||
|
url &&
|
||||||
|
url.startsWith(URLS.usw) &&
|
||||||
|
Number(url.match(/\/(\d+)\.user\.css|$/)[1]),
|
||||||
|
extractUSwInstallUrl: url => {
|
||||||
|
const id = URLS.extractUSwId(url);
|
||||||
|
return id ? `${URLS.usw}style/${id}` : '';
|
||||||
|
},
|
||||||
|
makeUswCodeUrl: id => `${URLS.usw}api/style/${id}.user.css`,
|
||||||
|
|
||||||
supported: url => (
|
supported: url => (
|
||||||
url.startsWith('http') ||
|
url.startsWith('http') ||
|
||||||
url.startsWith('ftp') ||
|
url.startsWith('ftp') ||
|
||||||
|
|
|
@ -333,6 +333,9 @@
|
||||||
<span><a href="https://add0n.com/stylus.html#features" target="_blank" i18n-text="linkGetHelp"></a></span>
|
<span><a href="https://add0n.com/stylus.html#features" target="_blank" i18n-text="linkGetHelp"></a></span>
|
||||||
<span><a href="https://github.com/openstyles/stylus/wiki" target="_blank" i18n-text="linkStylusWiki"></a></span>
|
<span><a href="https://github.com/openstyles/stylus/wiki" target="_blank" i18n-text="linkStylusWiki"></a></span>
|
||||||
<span><a href="https://www.transifex.com/github-7/Stylus" target="_blank" i18n-text="linkTranslate"></a></span>
|
<span><a href="https://www.transifex.com/github-7/Stylus" target="_blank" i18n-text="linkTranslate"></a></span>
|
||||||
|
<span><a href="https://userstyles.world/" target="_blank" i18n-text-append="linkUSW" id="link-usw">
|
||||||
|
<img src="https://userstyles.world/favicon.ico">
|
||||||
|
</a></span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -440,6 +440,24 @@ a:hover {
|
||||||
margin: 0 .5em;
|
margin: 0 .5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#link-usw {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#link-usw img {
|
||||||
|
max-width: 2.5em;
|
||||||
|
max-height: 2.5em;
|
||||||
|
margin-right: .75em;
|
||||||
|
filter: grayscale(1);
|
||||||
|
transition: filter .5s;
|
||||||
|
}
|
||||||
|
|
||||||
|
#link-usw:hover img {
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
|
||||||
.newUI .entry .svg-icon.checked,
|
.newUI .entry .svg-icon.checked,
|
||||||
.newUI .entry:hover .svg-icon.checked {
|
.newUI .entry:hover .svg-icon.checked {
|
||||||
fill: #000;
|
fill: #000;
|
||||||
|
|
|
@ -82,6 +82,12 @@ body.search-results-shown {
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.search-result-title img {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
margin: -6px 4px -6px 0;
|
||||||
|
}
|
||||||
|
|
||||||
.search-result-title span {
|
.search-result-title span {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
|
|
||||||
const RESULT_ID_PREFIX = 'search-result-';
|
const RESULT_ID_PREFIX = 'search-result-';
|
||||||
const INDEX_URL = URLS.usoArchiveRaw + 'search-index.json';
|
const INDEX_URL = URLS.usoArchiveRaw + 'search-index.json';
|
||||||
|
const USW_INDEX_URL = URLS.usw + 'api/index/uso-format';
|
||||||
|
const USW_ICON = $create('img', {
|
||||||
|
src: `${URLS.usw}favicon.ico`,
|
||||||
|
title: URLS.usw,
|
||||||
|
});
|
||||||
const STYLUS_CATEGORY = 'chrome-extension';
|
const STYLUS_CATEGORY = 'chrome-extension';
|
||||||
const PAGE_LENGTH = 10;
|
const PAGE_LENGTH = 10;
|
||||||
// update USO style install counter if the style isn't uninstalled immediately
|
// update USO style install counter if the style isn't uninstalled immediately
|
||||||
|
@ -43,8 +48,7 @@
|
||||||
let searchGlobals = $('#search-globals').checked;
|
let searchGlobals = $('#search-globals').checked;
|
||||||
/** @type string[] */
|
/** @type string[] */
|
||||||
let query = [];
|
let query = [];
|
||||||
/** @type 'n' | 'u' | 't' | 'w' | 'r' */
|
let order = prefs.get('popup.findSort');
|
||||||
let order = 't';
|
|
||||||
let scrollToFirstResult = true;
|
let scrollToFirstResult = true;
|
||||||
let displayedPage = 1;
|
let displayedPage = 1;
|
||||||
let totalPages = 1;
|
let totalPages = 1;
|
||||||
|
@ -98,6 +102,7 @@
|
||||||
$('#search-order').value = order;
|
$('#search-order').value = order;
|
||||||
$('#search-order').onchange = function () {
|
$('#search-order').onchange = function () {
|
||||||
order = this.value;
|
order = this.value;
|
||||||
|
prefs.set('popup.findSort', order);
|
||||||
results.sort(comparator);
|
results.sort(comparator);
|
||||||
render();
|
render();
|
||||||
};
|
};
|
||||||
|
@ -141,10 +146,9 @@
|
||||||
|
|
||||||
window.on('styleAdded', async ({detail: {style}}) => {
|
window.on('styleAdded', async ({detail: {style}}) => {
|
||||||
restoreScrollPosition();
|
restoreScrollPosition();
|
||||||
const usoId = calcUsoId(style) ||
|
const id = calcId(style) || calcId(await API.styles.get(style.id));
|
||||||
calcUsoId(await API.styles.get(style.id));
|
if (id && results.find(r => r.i === id)) {
|
||||||
if (usoId && results.find(r => r.i === usoId)) {
|
renderActionButtons(id, style.id);
|
||||||
renderActionButtons(usoId, style.id);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -181,15 +185,15 @@
|
||||||
show(dom.container);
|
show(dom.container);
|
||||||
show(dom.list);
|
show(dom.list);
|
||||||
hide(dom.error);
|
hide(dom.error);
|
||||||
results = [];
|
|
||||||
try {
|
try {
|
||||||
|
results = [];
|
||||||
for (let retry = 0; !results.length && retry <= 2; retry++) {
|
for (let retry = 0; !results.length && retry <= 2; retry++) {
|
||||||
results = await search({retry});
|
results = await search({retry});
|
||||||
}
|
}
|
||||||
if (results.length) {
|
if (results.length) {
|
||||||
const installedStyles = await API.styles.getAll();
|
const installedStyles = await API.styles.getAll();
|
||||||
const allUsoIds = new Set(installedStyles.map(calcUsoId));
|
const allSupportedIds = new Set(installedStyles.map(calcId));
|
||||||
results = results.filter(r => !allUsoIds.has(r.i));
|
results = results.filter(r => !allSupportedIds.has(r.i));
|
||||||
}
|
}
|
||||||
render();
|
render();
|
||||||
(results.length ? show : hide)(dom.list);
|
(results.length ? show : hide)(dom.list);
|
||||||
|
@ -274,29 +278,39 @@
|
||||||
an: author,
|
an: author,
|
||||||
sa: shotArchived,
|
sa: shotArchived,
|
||||||
sn: shotName,
|
sn: shotName,
|
||||||
|
isUsw,
|
||||||
} = entry._result = result;
|
} = entry._result = result;
|
||||||
entry.id = RESULT_ID_PREFIX + id;
|
entry.id = RESULT_ID_PREFIX + id;
|
||||||
// title
|
// title
|
||||||
Object.assign($('.search-result-title', entry), {
|
Object.assign($('.search-result-title', entry), {
|
||||||
onclick: Events.openURLandHide,
|
onclick: Events.openURLandHide,
|
||||||
href: URLS.usoArchive + `?category=${category}&style=${id}`,
|
href: isUsw ? `${URLS.usw}style/${id}` :
|
||||||
|
`${URLS.usoArchive}?category=${category}&style=${id}`,
|
||||||
});
|
});
|
||||||
|
if (isUsw) $('.search-result-title', entry).prepend(USW_ICON.cloneNode(true));
|
||||||
$('.search-result-title span', entry).textContent =
|
$('.search-result-title span', entry).textContent =
|
||||||
t.breakWord(name.length < 300 ? name : name.slice(0, 300) + '...');
|
t.breakWord(name.length < 300 ? name : name.slice(0, 300) + '...');
|
||||||
// screenshot
|
// screenshot
|
||||||
const auto = URLS.uso + `auto_style_screenshots/${id}${USO_AUTO_PIC_SUFFIX}`;
|
const elShot = $('.search-result-screenshot', entry);
|
||||||
Object.assign($('.search-result-screenshot', entry), {
|
if (isUsw) {
|
||||||
src: shotName && !shotName.endsWith(USO_AUTO_PIC_SUFFIX)
|
elShot.src = /^https?:/i.test(shotName) ? shotName : BLANK_PIXEL;
|
||||||
? `${shotArchived ? URLS.usoArchiveRaw : URLS.uso + 'style_'}screenshots/${shotName}`
|
} else {
|
||||||
: auto,
|
const auto = URLS.uso + `auto_style_screenshots/${id}${USO_AUTO_PIC_SUFFIX}`;
|
||||||
_src: auto,
|
Object.assign(elShot, {
|
||||||
onerror: fixScreenshot,
|
src: shotName && !shotName.endsWith(USO_AUTO_PIC_SUFFIX)
|
||||||
});
|
? `${shotArchived ? URLS.usoArchiveRaw : URLS.uso + 'style_'}screenshots/${shotName}`
|
||||||
|
: auto,
|
||||||
|
_src: auto,
|
||||||
|
onerror: fixScreenshot,
|
||||||
|
});
|
||||||
|
}
|
||||||
// author
|
// author
|
||||||
|
const eAuthor = encodeURIComponent(author);
|
||||||
Object.assign($('[data-type="author"] a', entry), {
|
Object.assign($('[data-type="author"] a', entry), {
|
||||||
textContent: author,
|
textContent: author,
|
||||||
title: author,
|
title: author,
|
||||||
href: URLS.usoArchive + '?author=' + encodeURIComponent(author).replace(/%20/g, '+'),
|
href: isUsw ? `${URLS.usw}user/${eAuthor}` :
|
||||||
|
`${URLS.usoArchive}?author=${eAuthor.replace(/%20/g, '+')}`,
|
||||||
onclick: Events.openURLandHide,
|
onclick: Events.openURLandHide,
|
||||||
});
|
});
|
||||||
// rating
|
// rating
|
||||||
|
@ -398,18 +412,21 @@
|
||||||
async function install() {
|
async function install() {
|
||||||
const entry = this.closest('.search-result');
|
const entry = this.closest('.search-result');
|
||||||
const result = /** @type IndexEntry */ entry._result;
|
const result = /** @type IndexEntry */ entry._result;
|
||||||
const {i: id} = result;
|
const {i: id, isUsw} = result;
|
||||||
const installButton = $('.search-result-install', entry);
|
const installButton = $('.search-result-install', entry);
|
||||||
|
|
||||||
showSpinner(entry);
|
showSpinner(entry);
|
||||||
saveScrollPosition(entry);
|
saveScrollPosition(entry);
|
||||||
installButton.disabled = true;
|
installButton.disabled = true;
|
||||||
entry.style.setProperty('pointer-events', 'none', 'important');
|
entry.style.setProperty('pointer-events', 'none', 'important');
|
||||||
// FIXME: move this to background page and create an API like installUSOStyle
|
if (!isUsw) {
|
||||||
result.pingbackTimer = setTimeout(download, PINGBACK_DELAY,
|
// FIXME: move this to background page and create an API like installUSOStyle
|
||||||
`${URLS.uso}styles/install/${id}?source=stylish-ch`);
|
result.pingbackTimer = setTimeout(download, PINGBACK_DELAY,
|
||||||
|
`${URLS.uso}styles/install/${id}?source=stylish-ch`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateUrl = isUsw ? URLS.makeUswCodeUrl(id) : URLS.makeUsoArchiveCodeUrl(id);
|
||||||
|
|
||||||
const updateUrl = URLS.makeUsoArchiveCodeUrl(id);
|
|
||||||
try {
|
try {
|
||||||
const sourceCode = await download(updateUrl);
|
const sourceCode = await download(updateUrl);
|
||||||
const style = await API.usercss.install({sourceCode, updateUrl});
|
const style = await API.usercss.install({sourceCode, updateUrl});
|
||||||
|
@ -469,8 +486,18 @@
|
||||||
|
|
||||||
async function fetchIndex() {
|
async function fetchIndex() {
|
||||||
const timer = setTimeout(showSpinner, BUSY_DELAY, dom.list);
|
const timer = setTimeout(showSpinner, BUSY_DELAY, dom.list);
|
||||||
index = (await download(INDEX_URL, {responseType: 'json'}))
|
index = [];
|
||||||
.filter(res => res.f === 'uso');
|
await Promise.all([
|
||||||
|
download(INDEX_URL, {responseType: 'json'}).then(res => {
|
||||||
|
index = index.concat(res.filter(res => res.f === 'uso'));
|
||||||
|
}).catch(() => {}),
|
||||||
|
download(USW_INDEX_URL, {responseType: 'json'}).then(res => {
|
||||||
|
for (const style of res.data) {
|
||||||
|
style.isUsw = true;
|
||||||
|
index.push(style);
|
||||||
|
}
|
||||||
|
}).catch(() => {}),
|
||||||
|
]);
|
||||||
clearTimeout(timer);
|
clearTimeout(timer);
|
||||||
$remove(':scope > .lds-spinner', dom.list);
|
$remove(':scope > .lds-spinner', dom.list);
|
||||||
return index;
|
return index;
|
||||||
|
@ -521,6 +548,14 @@
|
||||||
URLS.extractUsoArchiveId(updateUrl);
|
URLS.extractUsoArchiveId(updateUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function calcUswId({updateUrl}) {
|
||||||
|
return URLS.extractUSwId(updateUrl) || 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
function calcId(style) {
|
||||||
|
return calcUsoId(style) || calcUswId(style);
|
||||||
|
}
|
||||||
|
|
||||||
function calcHaystack(res) {
|
function calcHaystack(res) {
|
||||||
if (!res._nLC) res._nLC = res.n.toLocaleLowerCase();
|
if (!res._nLC) res._nLC = res.n.toLocaleLowerCase();
|
||||||
if (!res._year) res._year = new Date(res.u * 1000).getFullYear();
|
if (!res._year) res._year = new Date(res.u * 1000).getFullYear();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user