add USA/USW/US/GF splitter to Find styles
This commit is contained in:
parent
268c7b758b
commit
bd0e8273c1
|
@ -451,18 +451,6 @@
|
|||
"message": "Find styles",
|
||||
"description": "Text for a link that gets a list of styles for the current site"
|
||||
},
|
||||
"findStylesForSite": {
|
||||
"message": "Find more styles for this site",
|
||||
"description": "Text for a link that gets a list of styles for the current site"
|
||||
},
|
||||
"findStylesInline": {
|
||||
"message": "Inline",
|
||||
"description": "Text for a checkbox that opens search results 'inline' (within the Stylus popup window)"
|
||||
},
|
||||
"findStylesInlineTooltip": {
|
||||
"message": "Display search results inside this window.",
|
||||
"description": "Text for a checkbox that displays search results within the Stylus popup."
|
||||
},
|
||||
"genericAdd": {
|
||||
"message": "Add",
|
||||
"description": "Used in various places for an action that adds something"
|
||||
|
|
|
@ -23,9 +23,6 @@
|
|||
.style-settings input:disabled ~ label {
|
||||
opacity: .5;
|
||||
}
|
||||
.style-settings .rel {
|
||||
position: relative;
|
||||
}
|
||||
.style-settings .w100 {
|
||||
display: block;
|
||||
width: 100%;
|
||||
|
|
|
@ -297,6 +297,12 @@ summary {
|
|||
.hidden {
|
||||
display: none !important;
|
||||
}
|
||||
.rel {
|
||||
position: relative;
|
||||
}
|
||||
.abs {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
:focus,
|
||||
.CodeMirror-focused,
|
||||
|
|
|
@ -42,7 +42,6 @@
|
|||
'popup.stylesFirst': true, // display enabled styles before disabled styles
|
||||
'popup.autoResort': false, // auto resort styles after toggling
|
||||
'popup.borders': false, // add white borders on the sides
|
||||
'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
|
||||
|
||||
|
|
29
popup.html
29
popup.html
|
@ -196,15 +196,6 @@
|
|||
<input id="disableAll" type="checkbox">
|
||||
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
||||
</label>
|
||||
<div id="find-styles">
|
||||
<a id="find-styles-link" i18n="findStyles, title:findStylesForSite"
|
||||
href="https://to.be.replaced.on.click/" target="_blank"></a>
|
||||
<label id="find-styles-inline-group" class="checkbox-wrapper" i18n="title:findStylesInlineTooltip">
|
||||
<input id="popup.findStylesInline" class="checker" type="checkbox">
|
||||
<svg class="svg-icon checked"><use xlink:href="#svg-icon-checked"/></svg>
|
||||
<span i18n="findStylesInline"></span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="write-style">
|
||||
<a id="write-for-frames" title="‹iframe›..." tabindex="0" hidden></a>
|
||||
<span id="write-style-for" i18n="writeStyleFor"></span>
|
||||
|
@ -212,15 +203,25 @@
|
|||
</div>
|
||||
|
||||
<div id="popup-options">
|
||||
<div class="split-btn">
|
||||
<div class="split-btn" id="manage-split">
|
||||
<button id="popup-manage-button" i18n="openManage, title:popupManageTooltip"
|
||||
data-href="manage.html"></button
|
||||
><button class="split-btn-pedal" i18n="menu-site:popupManageSiteStyles"></button>
|
||||
</div>
|
||||
<button id="popup-options-button" i18n="openOptions"></button>
|
||||
<button id="popup-wiki-button"
|
||||
i18n="linkStylusWiki, title:linkGetHelp"
|
||||
data-href="https://github.com/openstyles/stylus/wiki"></button>
|
||||
<div class="split-btn" id="find-split">
|
||||
<button id="find-styles-btn" i18n="findStyles"></button
|
||||
><button class="split-btn-pedal"
|
||||
menu-usoa="UserStyles Archive"
|
||||
menu-usw="UserStyles World"
|
||||
menu-uso="UserStyles"
|
||||
menu-gf="GreasyFork"></button>
|
||||
</div>
|
||||
<button id="options-btn" i18n="title:openOptions" class="rel">
|
||||
<svg class="svg-icon config abs"><use xlink:href="#svg-icon-config"></use></svg>
|
||||
</button>
|
||||
<a href="https://github.com/openstyles/stylus/wiki" target="_blank">
|
||||
<button id="popup-wiki-button" i18n="linkStylusWiki, title:linkGetHelp"></button>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div id="search-results-error" class="hidden"></div>
|
||||
|
|
|
@ -64,11 +64,6 @@ body > div:not(#installed):not(#message-box):not(.colorpicker-popup) {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
#find-styles-link {
|
||||
cursor: pointer;
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
.style-name:hover .checker:checked,
|
||||
.style-name:hover .checker {
|
||||
border-color: var(--c30);
|
||||
|
@ -613,7 +608,7 @@ body.blocked #main-actions > :not(#disableAll-label) {
|
|||
#popup-options .split-btn > :first-child {
|
||||
width: calc(100% - 16px);
|
||||
}
|
||||
.blocked #popup-options .split-btn > :first-child {
|
||||
.blocked #popup-options > * > :first-child {
|
||||
width: 100%;
|
||||
}
|
||||
#popup-options button {
|
||||
|
@ -626,12 +621,30 @@ body.blocked #main-actions > :not(#disableAll-label) {
|
|||
margin-right: 4px;
|
||||
}
|
||||
#popup-options > *,
|
||||
#popup-manage-button {
|
||||
#popup-options .split-btn > :first-child {
|
||||
/* several languages have labels of wildly different lengths so we try to maintain the proportion */
|
||||
flex: 1 1 auto;
|
||||
min-width: 2em;
|
||||
}
|
||||
html:not(.styles-last) #popup-manage-button ~ .split-btn-menu {
|
||||
.blocked #find-split,
|
||||
.blocked #options-btn svg,
|
||||
body:not(.blocked) #popup-options a[href*="wiki"] {
|
||||
display: none;
|
||||
}
|
||||
#options-btn::after {
|
||||
content: '\A0';
|
||||
}
|
||||
.blocked #options-btn::after {
|
||||
content: attr(title);
|
||||
}
|
||||
#options-btn svg {
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
fill: transparent;
|
||||
stroke: currentColor;
|
||||
}
|
||||
html:not(.styles-last) #popup-options .split-btn-menu {
|
||||
bottom: 0;
|
||||
transform: translateY(-20px); /* global button style: 13(font) * 1.2(line) + 4(pad) + 2(border) */
|
||||
}
|
||||
|
|
|
@ -90,27 +90,24 @@ async function initPopup(frames) {
|
|||
};
|
||||
setupLivePrefs();
|
||||
|
||||
Object.assign($('#find-styles-link'), {
|
||||
href: URLS.usoArchive + 'browse/styles',
|
||||
async onclick(e) {
|
||||
e.preventDefault();
|
||||
await require(['/popup/search']);
|
||||
Events.searchOnClick(this, e);
|
||||
},
|
||||
});
|
||||
const elFind = $('#find-styles-btn');
|
||||
elFind.onclick = async e => {
|
||||
elFind.disabled = e.type === 'click';
|
||||
await require(['/popup/search']);
|
||||
Events.searchSite(e);
|
||||
};
|
||||
elFind.on('split-btn', elFind.onclick);
|
||||
|
||||
Object.assign($('#popup-manage-button'), {
|
||||
onclick: Events.openManager,
|
||||
oncontextmenu: Events.openManager,
|
||||
}).on('split-btn', Events.openManager);
|
||||
|
||||
$('#popup-options-button').onclick = () => {
|
||||
$('#options-btn').onclick = () => {
|
||||
API.openManage({options: true});
|
||||
window.close();
|
||||
};
|
||||
|
||||
$('#popup-wiki-button').onclick = Events.openURLandHide;
|
||||
|
||||
$('#confirm').onclick = function (e) {
|
||||
const {id} = this.dataset;
|
||||
switch (e.target.dataset.cmd) {
|
||||
|
|
201
popup/search.js
201
popup/search.js
|
@ -2,7 +2,7 @@
|
|||
/* global $entry tabURL */// popup.js
|
||||
/* global API */// msg.js
|
||||
/* global Events */
|
||||
/* global FIREFOX URLS debounce download tryCatch */// toolbox.js
|
||||
/* global FIREFOX URLS debounce download tryURL */// toolbox.js
|
||||
/* global prefs */
|
||||
/* global t */// localization.js
|
||||
'use strict';
|
||||
|
@ -75,104 +75,98 @@
|
|||
const show = sel => $classList(sel).remove('hidden');
|
||||
const hide = sel => $classList(sel).add('hidden');
|
||||
|
||||
Object.assign(Events, {
|
||||
/**
|
||||
* @param {HTMLAnchorElement} a
|
||||
* @param {Event} event
|
||||
*/
|
||||
searchOnClick(a, event) {
|
||||
if (!prefs.get('popup.findStylesInline') || dom.container) {
|
||||
// use a less specific category if the inline search wasn't used yet
|
||||
if (!category) calcCategory({retry: 1});
|
||||
const search = [
|
||||
category ? '#' + category : '',
|
||||
$('#search-query').value,
|
||||
].filter(Boolean).join(' ');
|
||||
a.search = search ? 'search=' + encodeURIComponent(search) : '';
|
||||
Events.openURLandHide.call(a, event);
|
||||
return;
|
||||
}
|
||||
a.textContent = a.title;
|
||||
a.title = '';
|
||||
init();
|
||||
calcCategory();
|
||||
ready = start();
|
||||
},
|
||||
Events.searchSite = event => {
|
||||
// use a less specific category if the inline search wasn't used yet
|
||||
if (!category) calcCategory({retry: 1});
|
||||
const add = (prefix, str) => str ? prefix + str : '';
|
||||
const where = event.detail;
|
||||
const q = encodeURIComponent($('#search-query').value.trim());
|
||||
const catQ = category + add('+', q);
|
||||
const href =
|
||||
where === 'uso' &&
|
||||
`${URLS.uso}styles/browse${q ? `?search_terms=${catQ}` : `/${category}`}` ||
|
||||
where === 'usoa' &&
|
||||
`${URLS.usoArchive}browse/styles?search=%23${catQ}` ||
|
||||
where === 'usw' &&
|
||||
`${URLS.usw}search?q=${catQ}` ||
|
||||
where === 'gf' &&
|
||||
'https://greasyfork.org/' + ($.root.lang.split('-')[0] || 'en') +
|
||||
`/scripts/by-site/${tryURL(tabURL).hostname}?language=css${add('&q=', q)}`;
|
||||
Events.openURLandHide.call({href}, event);
|
||||
};
|
||||
|
||||
$('#search-globals').onchange = function () {
|
||||
searchGlobals = this.checked;
|
||||
ready = ready.then(start);
|
||||
};
|
||||
$('#search-query').oninput = function () {
|
||||
query = [];
|
||||
const text = this.value.trim().toLocaleLowerCase();
|
||||
const thisYear = new Date().getFullYear();
|
||||
for (let re = /"(.+?)"|(\S+)/g, m; (m = re.exec(text));) {
|
||||
const n = Number(m[2]);
|
||||
query.push(n >= 2000 && n <= thisYear ? n : m[1] || m[2]);
|
||||
}
|
||||
if (category === STYLUS_CATEGORY && !query.includes('stylus')) {
|
||||
query.push('stylus');
|
||||
}
|
||||
ready = ready.then(start);
|
||||
};
|
||||
$('#search-order').value = order;
|
||||
$('#search-order').onchange = function () {
|
||||
order = this.value;
|
||||
prefs.set('popup.findSort', order);
|
||||
results.sort(comparator);
|
||||
render();
|
||||
};
|
||||
dom.list = $('#search-results-list');
|
||||
dom.container = $('#search-results');
|
||||
dom.container.dataset.empty = '';
|
||||
dom.error = $('#search-results-error');
|
||||
dom.nav = {};
|
||||
const navOnClick = {prev, next};
|
||||
for (const place of ['top', 'bottom']) {
|
||||
const nav = $(`.search-results-nav[data-type="${place}"]`);
|
||||
nav.appendChild(t.template.searchNav.cloneNode(true));
|
||||
dom.nav[place] = nav;
|
||||
for (const child of $$('[data-type]', nav)) {
|
||||
const type = child.dataset.type;
|
||||
child.onclick = navOnClick[type];
|
||||
nav['_' + type] = child;
|
||||
}
|
||||
}
|
||||
|
||||
if (FIREFOX) {
|
||||
let lastShift;
|
||||
window.on('resize', () => {
|
||||
const scrollbarWidth = window.innerWidth - document.scrollingElement.clientWidth;
|
||||
const shift = document.body.getBoundingClientRect().left;
|
||||
if (!scrollbarWidth || shift === lastShift) return;
|
||||
lastShift = shift;
|
||||
document.body.style.setProperty('padding',
|
||||
`0 ${scrollbarWidth + shift}px 0 ${-shift}px`, 'important');
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
window.on('styleDeleted', ({detail: {style: {id}}}) => {
|
||||
restoreScrollPosition();
|
||||
const result = results.find(r => r.installedStyleId === id);
|
||||
if (result) {
|
||||
clearTimeout(result.pingbackTimer);
|
||||
renderActionButtons(result.i, -1);
|
||||
}
|
||||
});
|
||||
|
||||
function init() {
|
||||
setTimeout(() => document.body.classList.add('search-results-shown'));
|
||||
hide('#find-styles-inline-group');
|
||||
$('#search-globals').onchange = function () {
|
||||
searchGlobals = this.checked;
|
||||
ready = ready.then(start);
|
||||
};
|
||||
$('#search-query').oninput = function () {
|
||||
query = [];
|
||||
const text = this.value.trim().toLocaleLowerCase();
|
||||
const thisYear = new Date().getFullYear();
|
||||
for (let re = /"(.+?)"|(\S+)/g, m; (m = re.exec(text));) {
|
||||
const n = Number(m[2]);
|
||||
query.push(n >= 2000 && n <= thisYear ? n : m[1] || m[2]);
|
||||
}
|
||||
if (category === STYLUS_CATEGORY && !query.includes('stylus')) {
|
||||
query.push('stylus');
|
||||
}
|
||||
ready = ready.then(start);
|
||||
};
|
||||
$('#search-order').value = order;
|
||||
$('#search-order').onchange = function () {
|
||||
order = this.value;
|
||||
prefs.set('popup.findSort', order);
|
||||
results.sort(comparator);
|
||||
render();
|
||||
};
|
||||
dom.list = $('#search-results-list');
|
||||
dom.container = $('#search-results');
|
||||
dom.container.dataset.empty = '';
|
||||
dom.error = $('#search-results-error');
|
||||
dom.nav = {};
|
||||
const navOnClick = {prev, next};
|
||||
for (const place of ['top', 'bottom']) {
|
||||
const nav = $(`.search-results-nav[data-type="${place}"]`);
|
||||
nav.appendChild(t.template.searchNav.cloneNode(true));
|
||||
dom.nav[place] = nav;
|
||||
for (const child of $$('[data-type]', nav)) {
|
||||
const type = child.dataset.type;
|
||||
child.onclick = navOnClick[type];
|
||||
nav['_' + type] = child;
|
||||
}
|
||||
window.on('styleAdded', async ({detail: {style}}) => {
|
||||
restoreScrollPosition();
|
||||
const id = calcId(style) || calcId(await API.styles.get(style.id));
|
||||
if (id && results.find(r => r.i === id)) {
|
||||
renderActionButtons(id, style.id);
|
||||
}
|
||||
});
|
||||
|
||||
if (FIREFOX) {
|
||||
let lastShift;
|
||||
window.on('resize', () => {
|
||||
const scrollbarWidth = window.innerWidth - document.scrollingElement.clientWidth;
|
||||
const shift = document.body.getBoundingClientRect().left;
|
||||
if (!scrollbarWidth || shift === lastShift) return;
|
||||
lastShift = shift;
|
||||
document.body.style.setProperty('padding',
|
||||
`0 ${scrollbarWidth + shift}px 0 ${-shift}px`, 'important');
|
||||
}, {passive: true});
|
||||
}
|
||||
|
||||
window.on('styleDeleted', ({detail: {style: {id}}}) => {
|
||||
restoreScrollPosition();
|
||||
const result = results.find(r => r.installedStyleId === id);
|
||||
if (result) {
|
||||
clearTimeout(result.pingbackTimer);
|
||||
renderActionButtons(result.i, -1);
|
||||
}
|
||||
});
|
||||
|
||||
window.on('styleAdded', async ({detail: {style}}) => {
|
||||
restoreScrollPosition();
|
||||
const id = calcId(style) || calcId(await API.styles.get(style.id));
|
||||
if (id && results.find(r => r.i === id)) {
|
||||
renderActionButtons(id, style.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
calcCategory();
|
||||
ready = start();
|
||||
|
||||
function next() {
|
||||
displayedPage = Math.min(totalPages, displayedPage + 1);
|
||||
|
@ -196,9 +190,7 @@
|
|||
}
|
||||
|
||||
async function start() {
|
||||
show(dom.container);
|
||||
show(dom.list);
|
||||
hide(dom.error);
|
||||
resetUI.timer = setTimeout(resetUI, 500);
|
||||
try {
|
||||
results = [];
|
||||
for (let retry = 0; !results.length && retry <= 2; retry++) {
|
||||
|
@ -217,6 +209,15 @@
|
|||
} catch (reason) {
|
||||
error(reason);
|
||||
}
|
||||
clearTimeout(resetUI.timer);
|
||||
resetUI();
|
||||
}
|
||||
|
||||
function resetUI() {
|
||||
document.body.classList.add('search-results-shown');
|
||||
show(dom.container);
|
||||
show(dom.list);
|
||||
hide(dom.error);
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
@ -481,9 +482,9 @@
|
|||
* @returns {boolean} true if the category has actually changed
|
||||
*/
|
||||
function calcCategory({retry} = {}) {
|
||||
const u = tryCatch(() => new URL(tabURL));
|
||||
const u = tryURL(tabURL);
|
||||
const old = category;
|
||||
if (!u) {
|
||||
if (!u.href) {
|
||||
// Invalid URL
|
||||
category = '';
|
||||
} else if (u.protocol === 'file:') {
|
||||
|
|
Loading…
Reference in New Issue
Block a user