Merge branch 'master' into new-uso-urls
This commit is contained in:
commit
4435a44291
|
@ -625,6 +625,18 @@
|
||||||
"message": "Get styles",
|
"message": "Get styles",
|
||||||
"description": "Help link text on the manage page e.g. https://userstyles.org"
|
"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": {
|
"linkStylusWiki": {
|
||||||
"message": "Wiki",
|
"message": "Wiki",
|
||||||
"description": "Wiki link text on the manage page e.g. https://github.com/openstyles/stylus/wiki"
|
"description": "Wiki link text on the manage page e.g. https://github.com/openstyles/stylus/wiki"
|
||||||
|
@ -633,10 +645,6 @@
|
||||||
"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": {
|
||||||
|
|
|
@ -35,6 +35,9 @@
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<h2 class="installed" i18n-text="installButtonInstalled"></h2>
|
<h2 class="installed" i18n-text="installButtonInstalled"></h2>
|
||||||
<button class="install" i18n-text="installButton"></button>
|
<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>
|
<p id="live-reload-install-hint" hidden></p>
|
||||||
<label class="set-update-url">
|
<label class="set-update-url">
|
||||||
<input type="checkbox">
|
<input type="checkbox">
|
||||||
|
@ -74,6 +77,12 @@
|
||||||
<symbol id="svg-icon-checked" viewBox="0 0 1000 1000">
|
<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"/>
|
<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>
|
||||||
|
<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>
|
</svg>
|
||||||
|
|
||||||
<script src="js/dlg/message-box.js"></script>
|
<script src="js/dlg/message-box.js"></script>
|
||||||
|
|
|
@ -305,6 +305,20 @@ label {
|
||||||
animation: none;
|
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 ************/
|
/************ reponsive layouts ************/
|
||||||
|
|
||||||
@media (max-width: 850px) {
|
@media (max-width: 850px) {
|
||||||
|
@ -417,6 +431,10 @@ label {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
}
|
}
|
||||||
|
#message-box.config-dialog > div {
|
||||||
|
top: auto;
|
||||||
|
bottom: 3rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Retina-specific stuff here */
|
/* Retina-specific stuff here */
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
/* global $ $create $createLink $$remove */
|
/* global $ $create $createLink $$remove showSpinner */// dom.js
|
||||||
/* global API */// msg.js
|
/* global API */// msg.js
|
||||||
/* global closeCurrentTab */// toolbox.js
|
/* global closeCurrentTab deepEqual */// toolbox.js
|
||||||
/* global messageBox */
|
/* global messageBox */
|
||||||
/* global prefs */
|
/* global prefs */
|
||||||
/* global preinit */
|
/* global preinit */
|
||||||
|
@ -13,20 +13,16 @@ let installed;
|
||||||
let installedDup;
|
let installedDup;
|
||||||
let liveReload;
|
let liveReload;
|
||||||
let tabId;
|
let tabId;
|
||||||
|
let vars;
|
||||||
|
|
||||||
// "History back" in Firefox (for now) restores the old DOM including the messagebox,
|
// "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.
|
// which stays after installing since we don't want to wait for the fadeout animation before resolving.
|
||||||
document.on('visibilitychange', () => {
|
document.on('visibilitychange', () => {
|
||||||
if (messageBox.element) messageBox.element.remove();
|
$$remove('#message-box:not(.config-dialog)');
|
||||||
if (installed) liveReload.onToggled();
|
if (installed) liveReload.onToggled();
|
||||||
});
|
});
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => !cm && showSpinner($('#header')), 200);
|
||||||
if (!cm) {
|
|
||||||
$('#header').appendChild($create('.lds-spinner',
|
|
||||||
new Array(12).fill($create('div')).map(e => e.cloneNode())));
|
|
||||||
}
|
|
||||||
}, 200);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Preinit starts to download as early as possible,
|
* Preinit starts to download as early as possible,
|
||||||
|
@ -187,11 +183,29 @@ function updateMeta(style, dup = installedDup) {
|
||||||
$('.external-link').appendChild(externalLink);
|
$('.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').dataset.arrivedFast = performance.now() < 500;
|
||||||
$('#header').classList.add('meta-init');
|
$('#header').classList.add('meta-init');
|
||||||
$('#header').classList.remove('meta-init-error');
|
$('#header').classList.remove('meta-init-error');
|
||||||
setTimeout(() => $$remove('.lds-spinner'), 1000);
|
|
||||||
|
|
||||||
|
setTimeout(() => $$remove('.lds-spinner'), 1000);
|
||||||
showError('');
|
showError('');
|
||||||
requestAnimationFrame(adjustCodeHeight);
|
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) {
|
function showError(err) {
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
--onoffswitch-width: 60px;
|
--onoffswitch-width: 60px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#stylus-manage .config-dialog #message-box-contents {
|
.config-dialog {
|
||||||
padding: 2em 16px;
|
--pad: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#stylus-popup .config-dialog #message-box-contents {
|
.config-dialog #message-box-contents {
|
||||||
padding: 8px 16px;
|
padding: var(--pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
#stylus-popup .config-dialog > div {
|
#stylus-popup .config-dialog > div {
|
||||||
|
@ -33,7 +33,7 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
padding: .75em 0;
|
padding: .75em 0;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin-right: -16px; /* for .config-reset-icon */
|
margin-right: calc(-1 * var(--pad)); /* for .config-reset-icon */
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-body .select-resizer {
|
.config-body .select-resizer {
|
||||||
|
@ -120,14 +120,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-reset-icon {
|
.config-reset-icon {
|
||||||
height: 16px;
|
height: var(--pad);
|
||||||
}
|
}
|
||||||
|
|
||||||
.config-reset-icon .svg-icon {
|
.config-reset-icon .svg-icon {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
fill: #aaa;
|
fill: #aaa;
|
||||||
width: 16px;
|
width: var(--pad);
|
||||||
height: 16px;
|
height: var(--pad);
|
||||||
padding: 0 1px;
|
padding: 0 1px;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
|
@ -139,7 +139,7 @@
|
||||||
|
|
||||||
#config-autosave-wrapper {
|
#config-autosave-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0 0 0 16px;
|
padding: 0 0 0 var(--pad);
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,8 +28,9 @@ async function configDialog(style) {
|
||||||
let varsInitial = getInitialValues(varsHash);
|
let varsInitial = getInitialValues(varsHash);
|
||||||
|
|
||||||
const elements = [];
|
const elements = [];
|
||||||
const colorpicker = window.colorpicker();
|
const isInstaller = location.pathname.startsWith('/install-usercss.html');
|
||||||
const isPopup = location.href.includes('popup.html');
|
const isPopup = location.pathname.startsWith('/popup.html');
|
||||||
|
const colorpicker = ((window.CodeMirror || {}).prototype || window).colorpicker();
|
||||||
const buttons = {};
|
const buttons = {};
|
||||||
|
|
||||||
buildConfigForm();
|
buildConfigForm();
|
||||||
|
@ -122,7 +123,7 @@ async function configDialog(style) {
|
||||||
buttons.close.textContent = t(someDirty ? 'confirmCancel' : 'confirmClose');
|
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) {
|
for (let delay = 1; saving && delay < 1000; delay *= 2) {
|
||||||
await new Promise(resolve => setTimeout(resolve, delay));
|
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)) {
|
if (!vars.some(va => va.dirty || anyChangeIsDirty && va.value !== va.savedValue)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!bgStyle) {
|
const bgStyle = !isInstaller && await API.styles.get(style.id).catch(() => ({}));
|
||||||
bgStyle = await API.styles.get(style.id).catch(() => ({}));
|
|
||||||
}
|
|
||||||
style = style.sections ? Object.assign({}, style) : style;
|
style = style.sections ? Object.assign({}, style) : style;
|
||||||
style.enabled = true;
|
style.enabled = true;
|
||||||
style.sourceCode = null;
|
style.sourceCode = null;
|
||||||
style.sections = null;
|
style.sections = null;
|
||||||
const styleVars = style.usercssData.vars;
|
const styleVars = style.usercssData.vars;
|
||||||
const bgVars = (bgStyle.usercssData || {}).vars || {};
|
const bgVars = isInstaller ? styleVars : (bgStyle.usercssData || {}).vars || {};
|
||||||
const invalid = [];
|
const invalid = [];
|
||||||
let numValid = 0;
|
let numValid = 0;
|
||||||
for (const va of vars) {
|
for (const va of vars) {
|
||||||
|
@ -184,7 +183,7 @@ async function configDialog(style) {
|
||||||
}
|
}
|
||||||
saving = true;
|
saving = true;
|
||||||
try {
|
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);
|
varsInitial = getInitialValues(newVars);
|
||||||
vars.forEach(va => onchange({target: va.input, justSaved: true}));
|
vars.forEach(va => onchange({target: va.input, justSaved: true}));
|
||||||
renderValues();
|
renderValues();
|
||||||
|
|
|
@ -40,10 +40,9 @@ messageBox.show = async ({
|
||||||
}) => {
|
}) => {
|
||||||
await require(['/js/dlg/message-box.css']);
|
await require(['/js/dlg/message-box.css']);
|
||||||
if (!messageBox.listeners) initOwnListeners();
|
if (!messageBox.listeners) initOwnListeners();
|
||||||
bindGlobalListeners();
|
|
||||||
createElement();
|
createElement();
|
||||||
|
bindGlobalListeners();
|
||||||
document.body.appendChild(messageBox.element);
|
document.body.appendChild(messageBox.element);
|
||||||
bindElementLiseners();
|
|
||||||
|
|
||||||
messageBox._originalFocus = document.activeElement;
|
messageBox._originalFocus = document.activeElement;
|
||||||
// focus the first focusable child but skip the first external link which is usually `feedback`
|
// 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) {
|
if (focusAccessibility.lastFocusedViaClick && document.activeElement) {
|
||||||
document.activeElement.dataset.focusedViaClick = '';
|
document.activeElement.dataset.focusedViaClick = '';
|
||||||
}
|
}
|
||||||
|
if (document.activeElement === messageBox._originalFocus) {
|
||||||
|
document.body.focus();
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof onshow === 'function') {
|
if (typeof onshow === 'function') {
|
||||||
onshow(messageBox.element);
|
onshow(messageBox.element);
|
||||||
|
@ -132,15 +134,9 @@ messageBox.show = async ({
|
||||||
listening = false;
|
listening = false;
|
||||||
},
|
},
|
||||||
mouseMove(event) {
|
mouseMove(event) {
|
||||||
const x = clamp(event.clientX, 30, innerWidth - 30) - clickX;
|
offsetX = clamp(event.clientX, 30, innerWidth - 30) - clickX;
|
||||||
const y = clamp(event.clientY, 30, innerHeight - 30) - clickY;
|
offsetY = clamp(event.clientY, 30, innerHeight - 30) - clickY;
|
||||||
|
messageBox.element.firstChild.style.transform = `translate(${offsetX}px,${offsetY}px)`;
|
||||||
offsetX = x;
|
|
||||||
offsetY = y;
|
|
||||||
|
|
||||||
$('#message-box > div').style.transform =
|
|
||||||
`translateX(${x}px)
|
|
||||||
translateY(${y}px)`;
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -164,7 +160,7 @@ messageBox.show = async ({
|
||||||
messageBox.element =
|
messageBox.element =
|
||||||
$create({id, className}, [
|
$create({id, className}, [
|
||||||
$create([
|
$create([
|
||||||
$create(`#${id}-title`, title),
|
$create(`#${id}-title`, {onmousedown: messageBox.listeners.mouseDown}, title),
|
||||||
$create(`#${id}-close-icon`, {onclick: messageBox.listeners.closeIcon},
|
$create(`#${id}-close-icon`, {onclick: messageBox.listeners.closeIcon},
|
||||||
$create('SVG:svg.svg-icon', {viewBox: '0 0 20 20'},
|
$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,' +
|
$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);
|
window.on('keydown', messageBox.listeners.key, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
function bindElementLiseners() {
|
|
||||||
$('#message-box-title').on('mousedown', messageBox.listeners.mouseDown, {passive: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
function unbindGlobalListeners() {
|
function unbindGlobalListeners() {
|
||||||
window.off('keydown', messageBox.listeners.key, true);
|
window.off('keydown', messageBox.listeners.key, true);
|
||||||
window.off('scroll', messageBox.listeners.scroll);
|
window.off('scroll', messageBox.listeners.scroll);
|
||||||
window.off('mouseup', messageBox.listeners.mouseUp);
|
window.off('mouseup', messageBox.listeners.mouseUp);
|
||||||
window.off('mousemove', messageBox.listeners.mouseMove);
|
window.off('mousemove', messageBox.listeners.mouseMove);
|
||||||
$('#message-box-title').off('mousedown', messageBox.listeners.mouseDown);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeSelf() {
|
function removeSelf() {
|
||||||
|
|
33
js/dom.js
33
js/dom.js
|
@ -1,5 +1,6 @@
|
||||||
/* global FIREFOX debounce */// toolbox.js
|
/* global FIREFOX debounce */// toolbox.js
|
||||||
/* global prefs */
|
/* global prefs */
|
||||||
|
/* global t */// localization.js
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
/* exported
|
/* exported
|
||||||
|
@ -259,7 +260,7 @@ function moveFocus(rootElement, step) {
|
||||||
const activeIndex = step ? Math.max(step < 0 ? 0 : -1, elements.indexOf(activeEl)) : -1;
|
const activeIndex = step ? Math.max(step < 0 ? 0 : -1, elements.indexOf(activeEl)) : -1;
|
||||||
const num = elements.length;
|
const num = elements.length;
|
||||||
if (!step) step = 1;
|
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];
|
const el = elements[(activeIndex + i * step + num) % num];
|
||||||
if (!el.disabled && el.tabIndex >= 0) {
|
if (!el.disabled && el.tabIndex >= 0) {
|
||||||
el.focus();
|
el.focus();
|
||||||
|
@ -443,6 +444,7 @@ async function waitForSheet({
|
||||||
document.documentElement.setAttribute('lang', chrome.i18n.getUILanguage());
|
document.documentElement.setAttribute('lang', chrome.i18n.getUILanguage());
|
||||||
document.on('keypress', clickDummyLinkOnEnter);
|
document.on('keypress', clickDummyLinkOnEnter);
|
||||||
document.on('wheel', changeFocusedInputOnWheel, {capture: true, passive: false});
|
document.on('wheel', changeFocusedInputOnWheel, {capture: true, passive: false});
|
||||||
|
document.on('click', showTooltipNote);
|
||||||
|
|
||||||
Promise.resolve().then(async () => {
|
Promise.resolve().then(async () => {
|
||||||
if (!chrome.app) addFaviconFF();
|
if (!chrome.app) addFaviconFF();
|
||||||
|
@ -451,6 +453,7 @@ async function waitForSheet({
|
||||||
});
|
});
|
||||||
|
|
||||||
onDOMready().then(() => {
|
onDOMready().then(() => {
|
||||||
|
splitLongTooltips();
|
||||||
debounce(addTooltipsToEllipsized, 500);
|
debounce(addTooltipsToEllipsized, 500);
|
||||||
window.on('resize', () => debounce(addTooltipsToEllipsized, 100));
|
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
|
//#endregion
|
||||||
|
|
17
manage.html
17
manage.html
|
@ -329,13 +329,21 @@
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<div id="manage-text">
|
<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://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>
|
||||||
|
@ -354,7 +362,6 @@
|
||||||
</symbol>
|
</symbol>
|
||||||
|
|
||||||
<symbol id="svg-icon-help" viewBox="0 0 14 16">
|
<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>
|
<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>
|
</symbol>
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ function initFilters() {
|
||||||
$('#search-help').onclick = event => {
|
$('#search-help').onclick = event => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
messageBoxProxy.show({
|
messageBoxProxy.show({
|
||||||
className: 'help-text',
|
className: 'help-text center-dialog',
|
||||||
title: t('search'),
|
title: t('search'),
|
||||||
contents:
|
contents:
|
||||||
$create('ul',
|
$create('ul',
|
||||||
|
|
|
@ -432,33 +432,17 @@ a:hover {
|
||||||
#manage-text {
|
#manage-text {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
align-items: baseline;
|
|
||||||
padding-top: .35rem;
|
padding-top: .35rem;
|
||||||
}
|
}
|
||||||
|
#manage-text > * {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
#manage-text > :not(:last-child):after {
|
#manage-text > :not(:last-child):after {
|
||||||
content: "|";
|
content: "|";
|
||||||
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;
|
||||||
|
|
|
@ -189,7 +189,7 @@ const sorter = (() => {
|
||||||
async function showHelp(event) {
|
async function showHelp(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
messageBoxProxy.show({
|
messageBoxProxy.show({
|
||||||
className: 'help-text',
|
className: 'help-text center-dialog',
|
||||||
title: t('sortStylesHelpTitle'),
|
title: t('sortStylesHelpTitle'),
|
||||||
contents:
|
contents:
|
||||||
$create('div',
|
$create('div',
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
setupLivePrefs();
|
setupLivePrefs();
|
||||||
setupRadioButtons();
|
setupRadioButtons();
|
||||||
$$('input[min], input[max]').forEach(enforceInputRange);
|
$$('input[min], input[max]').forEach(enforceInputRange);
|
||||||
setTimeout(splitLongTooltips);
|
|
||||||
|
|
||||||
if (CHROME_POPUP_BORDER_BUG) {
|
if (CHROME_POPUP_BORDER_BUG) {
|
||||||
const borderOption = $('.chrome-no-popup-border');
|
const borderOption = $('.chrome-no-popup-border');
|
||||||
|
@ -87,15 +86,6 @@ document.onclick = e => {
|
||||||
.filter(input => prefs.knownKeys.includes(input.id))
|
.filter(input => prefs.knownKeys.includes(input.id))
|
||||||
.forEach(input => prefs.reset(input.id));
|
.forEach(input => prefs.reset(input.id));
|
||||||
break;
|
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() {
|
function customizeHotkeys() {
|
||||||
// command name -> i18n id
|
// command name -> i18n id
|
||||||
const hotkeys = new Map([
|
const hotkeys = new Map([
|
||||||
|
|
|
@ -76,8 +76,9 @@ body.search-results-shown {
|
||||||
}
|
}
|
||||||
|
|
||||||
.search-result-title {
|
.search-result-title {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
margin-bottom: .5em;
|
margin-bottom: .5em;
|
||||||
display: block;
|
|
||||||
color: #555;
|
color: #555;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
@ -196,7 +197,8 @@ body.search-results-shown {
|
||||||
color: darkred;
|
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"],
|
.search-result-meta [data-type="weekly"],
|
||||||
|
@ -228,6 +230,28 @@ body.search-results-shown {
|
||||||
cursor: help;
|
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 {
|
.search-results-nav {
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -54,6 +54,13 @@
|
||||||
let totalPages = 1;
|
let totalPages = 1;
|
||||||
let ready;
|
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 $class = sel => (sel instanceof Node ? sel : $(sel)).classList;
|
||||||
const show = sel => $class(sel).remove('hidden');
|
const show = sel => $class(sel).remove('hidden');
|
||||||
const hide = sel => $class(sel).add('hidden');
|
const hide = sel => $class(sel).add('hidden');
|
||||||
|
@ -301,7 +308,9 @@
|
||||||
// screenshot
|
// screenshot
|
||||||
const elShot = $('.search-result-screenshot', entry);
|
const elShot = $('.search-result-screenshot', entry);
|
||||||
if (isUsw) {
|
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 {
|
} else {
|
||||||
const auto = URLS.uso + `auto_style_screenshots/${id}${USO_AUTO_PIC_SUFFIX}`;
|
const auto = URLS.uso + `auto_style_screenshots/${id}${USO_AUTO_PIC_SUFFIX}`;
|
||||||
Object.assign(elShot, {
|
Object.assign(elShot, {
|
||||||
|
@ -432,6 +441,7 @@
|
||||||
saveScrollPosition(entry);
|
saveScrollPosition(entry);
|
||||||
installButton.disabled = true;
|
installButton.disabled = true;
|
||||||
entry.style.setProperty('pointer-events', 'none', 'important');
|
entry.style.setProperty('pointer-events', 'none', 'important');
|
||||||
|
delete entry.dataset.error;
|
||||||
if (!isUsw) {
|
if (!isUsw) {
|
||||||
// FIXME: move this to background page and create an API like installUSOStyle
|
// FIXME: move this to background page and create an API like installUSOStyle
|
||||||
result.pingbackTimer = setTimeout(download, PINGBACK_DELAY,
|
result.pingbackTimer = setTimeout(download, PINGBACK_DELAY,
|
||||||
|
@ -445,7 +455,8 @@
|
||||||
const style = await API.usercss.install({sourceCode, updateUrl});
|
const style = await API.usercss.install({sourceCode, updateUrl});
|
||||||
renderFullInfo(entry, style);
|
renderFullInfo(entry, style);
|
||||||
} catch (reason) {
|
} 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);
|
$remove('.lds-spinner', entry);
|
||||||
installButton.disabled = false;
|
installButton.disabled = false;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user