Merge branch 'master' into new-uso-urls
This commit is contained in:
commit
4435a44291
|
@ -625,6 +625,18 @@
|
|||
"message": "Get styles",
|
||||
"description": "Help link text on the manage page e.g. https://userstyles.org"
|
||||
},
|
||||
"linkGetStylesInfo": {
|
||||
"message": "This archive site was created by a userstyle community member to back up the slow and unresponsive userstyles.org. The archive updates its contents approximately once a day.",
|
||||
"description": "Info shown when clicking the (i) icon of the uso-archive link in the manager"
|
||||
},
|
||||
"linkGetShareStyles": {
|
||||
"message": "Get and share styles",
|
||||
"description": "Link text for https://userstyles.world/ on the manage page"
|
||||
},
|
||||
"linkGetShareStylesInfo": {
|
||||
"message": "The new community-driven userstyles.world site is created by userstyle authors in order to replace userstyles.org, which has been so slow and unresponsive for the past year that many authors stopped updating their styles.",
|
||||
"description": "Info shown when clicking the (i) icon of the userstyles.world link in the manager"
|
||||
},
|
||||
"linkStylusWiki": {
|
||||
"message": "Wiki",
|
||||
"description": "Wiki link text on the manage page e.g. https://github.com/openstyles/stylus/wiki"
|
||||
|
@ -633,10 +645,6 @@
|
|||
"message": "Translate",
|
||||
"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": {
|
||||
"message": "CSSLint doesn't support $preprocessorname$ preprocessor",
|
||||
"placeholders": {
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
<div class="actions">
|
||||
<h2 class="installed" i18n-text="installButtonInstalled"></h2>
|
||||
<button class="install" i18n-text="installButton"></button>
|
||||
<a class="configure-usercss" i18n-title="configureStyle" tabindex="0">
|
||||
<svg class="svg-icon config"><use xlink:href="#svg-icon-config"></use></svg>
|
||||
</a>
|
||||
<p id="live-reload-install-hint" hidden></p>
|
||||
<label class="set-update-url">
|
||||
<input type="checkbox">
|
||||
|
@ -74,6 +77,12 @@
|
|||
<symbol id="svg-icon-checked" viewBox="0 0 1000 1000">
|
||||
<path fill-rule="evenodd" d="M983.2,184.3L853,69.8c-4-3.5-9.3-5.3-14.5-5c-5.3,0.4-10.3,2.8-13.8,6.8L352.3,609.2L184.4,386.9c-3.2-4.2-8-7-13.2-7.8c-5.3-0.8-10.6,0.6-14.9,3.9L18,487.5c-8.8,6.7-10.6,19.3-3.9,28.1L325,927.2c3.6,4.8,9.3,7.7,15.3,8c0.2,0,0.5,0,0.7,0c5.8,0,11.3-2.5,15.1-6.8L985,212.6C992.3,204.3,991.5,191.6,983.2,184.3z"/>
|
||||
</symbol>
|
||||
<symbol id="svg-icon-select-arrow" viewBox="0 0 1792 1792">
|
||||
<path fill-rule="evenodd" d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/>
|
||||
</symbol>
|
||||
<symbol id="svg-icon-config" viewBox="0 0 16 16">
|
||||
<path d="M13.3,12.8l1.5-2.6l-2.2-1.5c0-0.2,0.1-0.5,0.1-0.7c0-0.2,0-0.5-0.1-0.7l2.2-1.5l-1.5-2.6l-2.4,1.2 c-0.4-0.3-0.8-0.5-1.2-0.7L9.5,1h-3L6.3,3.7C5.9,3.8,5.5,4.1,5.1,4.4L2.7,3.2L1.2,5.8l2.2,1.5c0,0.2-0.1,0.5-0.1,0.7 c0,0.2,0,0.5,0.1,0.7l-2.2,1.5l1.5,2.6l2.4-1.2c0.4,0.3,0.8,0.5,1.2,0.7L6.5,15h3l0.2-2.7c0.4-0.2,0.8-0.4,1.2-0.7L13.3,12.8z M8,10.3c-1.3,0-2.3-1-2.3-2.3c0-1.3,1-2.3,2.3-2.3c1.3,0,2.3,1,2.3,2.3C10.3,9.3,9.3,10.3,8,10.3z"/>
|
||||
</symbol>
|
||||
</svg>
|
||||
|
||||
<script src="js/dlg/message-box.js"></script>
|
||||
|
|
|
@ -305,6 +305,20 @@ label {
|
|||
animation: none;
|
||||
}
|
||||
|
||||
.configure-usercss .svg-icon.config {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -3px;
|
||||
}
|
||||
#message-box.config-dialog {
|
||||
width: 0;
|
||||
height: 0;
|
||||
background: none;
|
||||
}
|
||||
#message-box.config-dialog > div {
|
||||
box-shadow: 5px 5px 50px rgba(0, 0, 0, 0.75); /* copied from message-box.css + darkened the color */
|
||||
}
|
||||
|
||||
/************ reponsive layouts ************/
|
||||
|
||||
@media (max-width: 850px) {
|
||||
|
@ -417,6 +431,10 @@ label {
|
|||
flex-shrink: 0;
|
||||
margin-right: 1em;
|
||||
}
|
||||
#message-box.config-dialog > div {
|
||||
top: auto;
|
||||
bottom: 3rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Retina-specific stuff here */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* global $ $create $createLink $$remove */
|
||||
/* global $ $create $createLink $$remove showSpinner */// dom.js
|
||||
/* global API */// msg.js
|
||||
/* global closeCurrentTab */// toolbox.js
|
||||
/* global closeCurrentTab deepEqual */// toolbox.js
|
||||
/* global messageBox */
|
||||
/* global prefs */
|
||||
/* global preinit */
|
||||
|
@ -13,20 +13,16 @@ let installed;
|
|||
let installedDup;
|
||||
let liveReload;
|
||||
let tabId;
|
||||
let vars;
|
||||
|
||||
// "History back" in Firefox (for now) restores the old DOM including the messagebox,
|
||||
// which stays after installing since we don't want to wait for the fadeout animation before resolving.
|
||||
document.on('visibilitychange', () => {
|
||||
if (messageBox.element) messageBox.element.remove();
|
||||
$$remove('#message-box:not(.config-dialog)');
|
||||
if (installed) liveReload.onToggled();
|
||||
});
|
||||
|
||||
setTimeout(() => {
|
||||
if (!cm) {
|
||||
$('#header').appendChild($create('.lds-spinner',
|
||||
new Array(12).fill($create('div')).map(e => e.cloneNode())));
|
||||
}
|
||||
}, 200);
|
||||
setTimeout(() => !cm && showSpinner($('#header')), 200);
|
||||
|
||||
/*
|
||||
* Preinit starts to download as early as possible,
|
||||
|
@ -187,11 +183,29 @@ function updateMeta(style, dup = installedDup) {
|
|||
$('.external-link').appendChild(externalLink);
|
||||
}
|
||||
|
||||
Object.assign($('.configure-usercss'), {
|
||||
hidden: !data.vars,
|
||||
onclick: openConfigDialog,
|
||||
});
|
||||
if (!data.vars) {
|
||||
$$remove('#message-box.config-dialog');
|
||||
} else if (!deepEqual(data.vars, vars)) {
|
||||
vars = data.vars;
|
||||
// Use the user-customized vars from the installed style
|
||||
for (const [dk, dv] of Object.entries(dup && dupData.vars || {})) {
|
||||
const v = vars[dk];
|
||||
if (v && v.type === dv.type) {
|
||||
v.value = dv.value;
|
||||
}
|
||||
}
|
||||
openConfigDialog();
|
||||
}
|
||||
|
||||
$('#header').dataset.arrivedFast = performance.now() < 500;
|
||||
$('#header').classList.add('meta-init');
|
||||
$('#header').classList.remove('meta-init-error');
|
||||
setTimeout(() => $$remove('.lds-spinner'), 1000);
|
||||
|
||||
setTimeout(() => $$remove('.lds-spinner'), 1000);
|
||||
showError('');
|
||||
requestAnimationFrame(adjustCodeHeight);
|
||||
|
||||
|
@ -233,6 +247,11 @@ function updateMeta(style, dup = installedDup) {
|
|||
)),
|
||||
]));
|
||||
}
|
||||
|
||||
async function openConfigDialog() {
|
||||
await require(['/js/dlg/config-dialog']); /* global configDialog */
|
||||
configDialog(style);
|
||||
}
|
||||
}
|
||||
|
||||
function showError(err) {
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
--onoffswitch-width: 60px;
|
||||
}
|
||||
|
||||
#stylus-manage .config-dialog #message-box-contents {
|
||||
padding: 2em 16px;
|
||||
.config-dialog {
|
||||
--pad: 16px;
|
||||
}
|
||||
|
||||
#stylus-popup .config-dialog #message-box-contents {
|
||||
padding: 8px 16px;
|
||||
.config-dialog #message-box-contents {
|
||||
padding: var(--pad);
|
||||
}
|
||||
|
||||
#stylus-popup .config-dialog > div {
|
||||
|
@ -33,7 +33,7 @@
|
|||
display: flex;
|
||||
padding: .75em 0;
|
||||
align-items: center;
|
||||
margin-right: -16px; /* for .config-reset-icon */
|
||||
margin-right: calc(-1 * var(--pad)); /* for .config-reset-icon */
|
||||
}
|
||||
|
||||
.config-body .select-resizer {
|
||||
|
@ -120,14 +120,14 @@
|
|||
}
|
||||
|
||||
.config-reset-icon {
|
||||
height: 16px;
|
||||
height: var(--pad);
|
||||
}
|
||||
|
||||
.config-reset-icon .svg-icon {
|
||||
cursor: pointer;
|
||||
fill: #aaa;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
width: var(--pad);
|
||||
height: var(--pad);
|
||||
padding: 0 1px;
|
||||
box-sizing: border-box;
|
||||
flex-shrink: 0;
|
||||
|
@ -139,7 +139,7 @@
|
|||
|
||||
#config-autosave-wrapper {
|
||||
position: relative;
|
||||
padding: 0 0 0 16px;
|
||||
padding: 0 0 0 var(--pad);
|
||||
display: inline-flex;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,8 +28,9 @@ async function configDialog(style) {
|
|||
let varsInitial = getInitialValues(varsHash);
|
||||
|
||||
const elements = [];
|
||||
const colorpicker = window.colorpicker();
|
||||
const isPopup = location.href.includes('popup.html');
|
||||
const isInstaller = location.pathname.startsWith('/install-usercss.html');
|
||||
const isPopup = location.pathname.startsWith('/popup.html');
|
||||
const colorpicker = ((window.CodeMirror || {}).prototype || window).colorpicker();
|
||||
const buttons = {};
|
||||
|
||||
buildConfigForm();
|
||||
|
@ -122,7 +123,7 @@ async function configDialog(style) {
|
|||
buttons.close.textContent = t(someDirty ? 'confirmCancel' : 'confirmClose');
|
||||
}
|
||||
|
||||
async function save({anyChangeIsDirty = false} = {}, bgStyle) {
|
||||
async function save({anyChangeIsDirty = false} = {}) {
|
||||
for (let delay = 1; saving && delay < 1000; delay *= 2) {
|
||||
await new Promise(resolve => setTimeout(resolve, delay));
|
||||
}
|
||||
|
@ -132,15 +133,13 @@ async function configDialog(style) {
|
|||
if (!vars.some(va => va.dirty || anyChangeIsDirty && va.value !== va.savedValue)) {
|
||||
return;
|
||||
}
|
||||
if (!bgStyle) {
|
||||
bgStyle = await API.styles.get(style.id).catch(() => ({}));
|
||||
}
|
||||
const bgStyle = !isInstaller && await API.styles.get(style.id).catch(() => ({}));
|
||||
style = style.sections ? Object.assign({}, style) : style;
|
||||
style.enabled = true;
|
||||
style.sourceCode = null;
|
||||
style.sections = null;
|
||||
const styleVars = style.usercssData.vars;
|
||||
const bgVars = (bgStyle.usercssData || {}).vars || {};
|
||||
const bgVars = isInstaller ? styleVars : (bgStyle.usercssData || {}).vars || {};
|
||||
const invalid = [];
|
||||
let numValid = 0;
|
||||
for (const va of vars) {
|
||||
|
@ -184,7 +183,7 @@ async function configDialog(style) {
|
|||
}
|
||||
saving = true;
|
||||
try {
|
||||
const newVars = await API.usercss.configVars(style.id, style.usercssData.vars);
|
||||
const newVars = isInstaller ? styleVars : await API.usercss.configVars(style.id, styleVars);
|
||||
varsInitial = getInitialValues(newVars);
|
||||
vars.forEach(va => onchange({target: va.input, justSaved: true}));
|
||||
renderValues();
|
||||
|
|
|
@ -40,10 +40,9 @@ messageBox.show = async ({
|
|||
}) => {
|
||||
await require(['/js/dlg/message-box.css']);
|
||||
if (!messageBox.listeners) initOwnListeners();
|
||||
bindGlobalListeners();
|
||||
createElement();
|
||||
bindGlobalListeners();
|
||||
document.body.appendChild(messageBox.element);
|
||||
bindElementLiseners();
|
||||
|
||||
messageBox._originalFocus = document.activeElement;
|
||||
// focus the first focusable child but skip the first external link which is usually `feedback`
|
||||
|
@ -54,6 +53,9 @@ messageBox.show = async ({
|
|||
if (focusAccessibility.lastFocusedViaClick && document.activeElement) {
|
||||
document.activeElement.dataset.focusedViaClick = '';
|
||||
}
|
||||
if (document.activeElement === messageBox._originalFocus) {
|
||||
document.body.focus();
|
||||
}
|
||||
|
||||
if (typeof onshow === 'function') {
|
||||
onshow(messageBox.element);
|
||||
|
@ -132,15 +134,9 @@ messageBox.show = async ({
|
|||
listening = false;
|
||||
},
|
||||
mouseMove(event) {
|
||||
const x = clamp(event.clientX, 30, innerWidth - 30) - clickX;
|
||||
const y = clamp(event.clientY, 30, innerHeight - 30) - clickY;
|
||||
|
||||
offsetX = x;
|
||||
offsetY = y;
|
||||
|
||||
$('#message-box > div').style.transform =
|
||||
`translateX(${x}px)
|
||||
translateY(${y}px)`;
|
||||
offsetX = clamp(event.clientX, 30, innerWidth - 30) - clickX;
|
||||
offsetY = clamp(event.clientY, 30, innerHeight - 30) - clickY;
|
||||
messageBox.element.firstChild.style.transform = `translate(${offsetX}px,${offsetY}px)`;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -164,7 +160,7 @@ messageBox.show = async ({
|
|||
messageBox.element =
|
||||
$create({id, className}, [
|
||||
$create([
|
||||
$create(`#${id}-title`, title),
|
||||
$create(`#${id}-title`, {onmousedown: messageBox.listeners.mouseDown}, title),
|
||||
$create(`#${id}-close-icon`, {onclick: messageBox.listeners.closeIcon},
|
||||
$create('SVG:svg.svg-icon', {viewBox: '0 0 20 20'},
|
||||
$create('SVG:path', {d: 'M11.69,10l4.55,4.55-1.69,1.69L10,11.69,' +
|
||||
|
@ -191,16 +187,11 @@ messageBox.show = async ({
|
|||
window.on('keydown', messageBox.listeners.key, true);
|
||||
}
|
||||
|
||||
function bindElementLiseners() {
|
||||
$('#message-box-title').on('mousedown', messageBox.listeners.mouseDown, {passive: true});
|
||||
}
|
||||
|
||||
function unbindGlobalListeners() {
|
||||
window.off('keydown', messageBox.listeners.key, true);
|
||||
window.off('scroll', messageBox.listeners.scroll);
|
||||
window.off('mouseup', messageBox.listeners.mouseUp);
|
||||
window.off('mousemove', messageBox.listeners.mouseMove);
|
||||
$('#message-box-title').off('mousedown', messageBox.listeners.mouseDown);
|
||||
}
|
||||
|
||||
function removeSelf() {
|
||||
|
|
33
js/dom.js
33
js/dom.js
|
@ -1,5 +1,6 @@
|
|||
/* global FIREFOX debounce */// toolbox.js
|
||||
/* global prefs */
|
||||
/* global t */// localization.js
|
||||
'use strict';
|
||||
|
||||
/* exported
|
||||
|
@ -259,7 +260,7 @@ function moveFocus(rootElement, step) {
|
|||
const activeIndex = step ? Math.max(step < 0 ? 0 : -1, elements.indexOf(activeEl)) : -1;
|
||||
const num = elements.length;
|
||||
if (!step) step = 1;
|
||||
for (let i = 1; i < num; i++) {
|
||||
for (let i = 1; i <= num; i++) {
|
||||
const el = elements[(activeIndex + i * step + num) % num];
|
||||
if (!el.disabled && el.tabIndex >= 0) {
|
||||
el.focus();
|
||||
|
@ -443,6 +444,7 @@ async function waitForSheet({
|
|||
document.documentElement.setAttribute('lang', chrome.i18n.getUILanguage());
|
||||
document.on('keypress', clickDummyLinkOnEnter);
|
||||
document.on('wheel', changeFocusedInputOnWheel, {capture: true, passive: false});
|
||||
document.on('click', showTooltipNote);
|
||||
|
||||
Promise.resolve().then(async () => {
|
||||
if (!chrome.app) addFaviconFF();
|
||||
|
@ -451,6 +453,7 @@ async function waitForSheet({
|
|||
});
|
||||
|
||||
onDOMready().then(() => {
|
||||
splitLongTooltips();
|
||||
debounce(addTooltipsToEllipsized, 500);
|
||||
window.on('resize', () => debounce(addTooltipsToEllipsized, 100));
|
||||
});
|
||||
|
@ -546,6 +549,34 @@ async function waitForSheet({
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showTooltipNote(event) {
|
||||
const el = event.target.closest('[data-cmd=note]');
|
||||
if (el) {
|
||||
event.preventDefault();
|
||||
window.messageBoxProxy.show({
|
||||
className: 'note center-dialog',
|
||||
contents: el.dataset.title || el.title,
|
||||
buttons: [t('confirmClose')],
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function splitLongTooltips() {
|
||||
for (const el of $$('[title]')) {
|
||||
el.dataset.title = el.title;
|
||||
el.title = el.title.replace(/<\/?\w+>/g, ''); // strip html tags
|
||||
if (el.title.length < 50) {
|
||||
continue;
|
||||
}
|
||||
const newTitle = el.title
|
||||
.split('\n')
|
||||
.map(s => s.replace(/([^.][.。?!]|.{50,60},)\s+/g, '$1\n'))
|
||||
.map(s => s.replace(/(.{50,80}(?=.{40,}))\s+/g, '$1\n'))
|
||||
.join('\n');
|
||||
if (newTitle !== el.title) el.title = newTitle;
|
||||
}
|
||||
}
|
||||
})();
|
||||
|
||||
//#endregion
|
||||
|
|
17
manage.html
17
manage.html
|
@ -329,13 +329,21 @@
|
|||
</details>
|
||||
|
||||
<div id="manage-text">
|
||||
<span><a href="https://33kk.github.io/uso-archive/" target="_blank" i18n-text="linkGetStyles"></a></span>
|
||||
<span>
|
||||
<a href="https://userstyles.world/" target="_blank" i18n-text="linkGetShareStyles"></a>
|
||||
<a tabindex="0" i18n-title="linkGetShareStylesInfo" data-cmd="note">
|
||||
<svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
|
||||
</a>
|
||||
</span>
|
||||
<span>
|
||||
<a href="https://33kk.github.io/uso-archive/" target="_blank" i18n-text="linkGetStyles"></a>
|
||||
<a tabindex="0" i18n-title="linkGetStylesInfo" data-cmd="note">
|
||||
<svg class="svg-icon info"><use xlink:href="#svg-icon-help"/></svg>
|
||||
</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://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>
|
||||
|
@ -354,7 +362,6 @@
|
|||
</symbol>
|
||||
|
||||
<symbol id="svg-icon-help" viewBox="0 0 14 16">
|
||||
<title i18n-text="helpAlt"></title>
|
||||
<path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path>
|
||||
</symbol>
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ function initFilters() {
|
|||
$('#search-help').onclick = event => {
|
||||
event.preventDefault();
|
||||
messageBoxProxy.show({
|
||||
className: 'help-text',
|
||||
className: 'help-text center-dialog',
|
||||
title: t('search'),
|
||||
contents:
|
||||
$create('ul',
|
||||
|
|
|
@ -432,33 +432,17 @@ a:hover {
|
|||
#manage-text {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
padding-top: .35rem;
|
||||
}
|
||||
|
||||
#manage-text > * {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
#manage-text > :not(:last-child):after {
|
||||
content: "|";
|
||||
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:hover .svg-icon.checked {
|
||||
fill: #000;
|
||||
|
|
|
@ -189,7 +189,7 @@ const sorter = (() => {
|
|||
async function showHelp(event) {
|
||||
event.preventDefault();
|
||||
messageBoxProxy.show({
|
||||
className: 'help-text',
|
||||
className: 'help-text center-dialog',
|
||||
title: t('sortStylesHelpTitle'),
|
||||
contents:
|
||||
$create('div',
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
setupLivePrefs();
|
||||
setupRadioButtons();
|
||||
$$('input[min], input[max]').forEach(enforceInputRange);
|
||||
setTimeout(splitLongTooltips);
|
||||
|
||||
if (CHROME_POPUP_BORDER_BUG) {
|
||||
const borderOption = $('.chrome-no-popup-border');
|
||||
|
@ -87,15 +86,6 @@ document.onclick = e => {
|
|||
.filter(input => prefs.knownKeys.includes(input.id))
|
||||
.forEach(input => prefs.reset(input.id));
|
||||
break;
|
||||
|
||||
case 'note': {
|
||||
e.preventDefault();
|
||||
messageBoxProxy.show({
|
||||
className: 'note',
|
||||
contents: target.dataset.title,
|
||||
buttons: [t('confirmClose')],
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -229,22 +219,6 @@ function setupRadioButtons() {
|
|||
});
|
||||
}
|
||||
|
||||
function splitLongTooltips() {
|
||||
for (const el of $$('[title]')) {
|
||||
el.dataset.title = el.title;
|
||||
el.title = el.title.replace(/<\/?\w+>/g, ''); // strip html tags
|
||||
if (el.title.length < 50) {
|
||||
continue;
|
||||
}
|
||||
const newTitle = el.title
|
||||
.split('\n')
|
||||
.map(s => s.replace(/([^.][.。?!]|.{50,60},)\s+/g, '$1\n'))
|
||||
.map(s => s.replace(/(.{50,80}(?=.{40,}))\s+/g, '$1\n'))
|
||||
.join('\n');
|
||||
if (newTitle !== el.title) el.title = newTitle;
|
||||
}
|
||||
}
|
||||
|
||||
function customizeHotkeys() {
|
||||
// command name -> i18n id
|
||||
const hotkeys = new Map([
|
||||
|
|
|
@ -76,8 +76,9 @@ body.search-results-shown {
|
|||
}
|
||||
|
||||
.search-result-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: .5em;
|
||||
display: block;
|
||||
color: #555;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
@ -196,7 +197,8 @@ body.search-results-shown {
|
|||
color: darkred;
|
||||
}
|
||||
|
||||
.search-result-meta [data-type="rating"][data-class="none"] dd {
|
||||
/* Keeping an empty rule so customizers can easily tweak it */
|
||||
search-result-meta [data-type="rating"][data-class="none"] dd {
|
||||
}
|
||||
|
||||
.search-result-meta [data-type="weekly"],
|
||||
|
@ -228,6 +230,28 @@ body.search-results-shown {
|
|||
cursor: help;
|
||||
}
|
||||
|
||||
[data-error],
|
||||
[data-error]:hover {
|
||||
border: calc(var(--pad) / 2) solid red;
|
||||
border-radius: var(--pad);
|
||||
padding: calc(var(--pad) / 2);
|
||||
background: hsl(0, 90%, 85%);
|
||||
}
|
||||
[data-error]::after {
|
||||
content: attr(data-error);
|
||||
display: block;
|
||||
color: hsl(0, 100%, 8%);
|
||||
font-weight: bold;
|
||||
padding-top: var(--pad);
|
||||
hyphens: auto;
|
||||
}
|
||||
[data-error] .search-result-description {
|
||||
display: none;
|
||||
}
|
||||
[data-error] .search-result-meta {
|
||||
background: hsla(0, 100%, 90%, .80);
|
||||
}
|
||||
|
||||
.search-results-nav {
|
||||
flex-direction: row;
|
||||
text-align: center;
|
||||
|
|
|
@ -54,6 +54,13 @@
|
|||
let totalPages = 1;
|
||||
let ready;
|
||||
|
||||
let imgType = '.jpg';
|
||||
// detect WebP support
|
||||
$create('img', {
|
||||
src: 'data:image/webp;base64,UklGRh4AAABXRUJQVlA4TBEAAAAvAAAAAAfQ//73v/+BiOh/AAA=',
|
||||
onload: () => (imgType = '.webp'),
|
||||
});
|
||||
|
||||
const $class = sel => (sel instanceof Node ? sel : $(sel)).classList;
|
||||
const show = sel => $class(sel).remove('hidden');
|
||||
const hide = sel => $class(sel).add('hidden');
|
||||
|
@ -301,7 +308,9 @@
|
|||
// screenshot
|
||||
const elShot = $('.search-result-screenshot', entry);
|
||||
if (isUsw) {
|
||||
elShot.src = /^https?:/i.test(shotName) ? shotName : BLANK_PIXEL;
|
||||
elShot.src = !/^https?:/i.test(shotName) ? BLANK_PIXEL :
|
||||
imgType !== '.jpg' ? shotName.replace(/\.jpg$/, imgType) :
|
||||
shotName;
|
||||
} else {
|
||||
const auto = URLS.uso + `auto_style_screenshots/${id}${USO_AUTO_PIC_SUFFIX}`;
|
||||
Object.assign(elShot, {
|
||||
|
@ -432,6 +441,7 @@
|
|||
saveScrollPosition(entry);
|
||||
installButton.disabled = true;
|
||||
entry.style.setProperty('pointer-events', 'none', 'important');
|
||||
delete entry.dataset.error;
|
||||
if (!isUsw) {
|
||||
// FIXME: move this to background page and create an API like installUSOStyle
|
||||
result.pingbackTimer = setTimeout(download, PINGBACK_DELAY,
|
||||
|
@ -445,7 +455,8 @@
|
|||
const style = await API.usercss.install({sourceCode, updateUrl});
|
||||
renderFullInfo(entry, style);
|
||||
} catch (reason) {
|
||||
error(`Error while downloading usoID:${id}\nReason: ${reason}`);
|
||||
entry.dataset.error = `${t('genericError')}: ${reason}`;
|
||||
entry.scrollIntoView({behavior: 'smooth', block: 'nearest'});
|
||||
}
|
||||
$remove('.lds-spinner', entry);
|
||||
installButton.disabled = false;
|
||||
|
|
Loading…
Reference in New Issue
Block a user