add multi-column mode option
This commit is contained in:
parent
6979958908
commit
ef998e423e
|
@ -762,6 +762,9 @@
|
||||||
"message": "Number of applies-to items",
|
"message": "Number of applies-to items",
|
||||||
"description": "Label for the numeric input box to limit max number of applies-to targets in the new UI on manage page"
|
"description": "Label for the numeric input box to limit max number of applies-to targets in the new UI on manage page"
|
||||||
},
|
},
|
||||||
|
"manageMinColumnWidth": {
|
||||||
|
"message": "Minimum column width (in pixels; 9999 disables multi-column mode)"
|
||||||
|
},
|
||||||
"manageNewStyleAsUsercss": {
|
"manageNewStyleAsUsercss": {
|
||||||
"message": "as Usercss",
|
"message": "as Usercss",
|
||||||
"description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager"
|
"description": "VERY SHORT label for the checkbox next to the 'Write new style' button in the style manager"
|
||||||
|
|
|
@ -37,7 +37,7 @@ async function InjectionOrder(show, el, selector) {
|
||||||
parts.name.href = '/edit.html?id=' + style.id;
|
parts.name.href = '/edit.html?id=' + style.id;
|
||||||
parts.name.textContent = style.name;
|
parts.name.textContent = style.name;
|
||||||
return Object.assign(entry.cloneNode(true), {
|
return Object.assign(entry.cloneNode(true), {
|
||||||
styleNameLowerCase: style.name.toLocaleLowerCase(),
|
styleNameLC: style.name.toLocaleLowerCase(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -314,9 +314,7 @@ function setupLivePrefs(ids) {
|
||||||
function getValue(el) {
|
function getValue(el) {
|
||||||
const type = el.dataset.valueType || el.type;
|
const type = el.dataset.valueType || el.type;
|
||||||
return type === 'checkbox' ? el.checked :
|
return type === 'checkbox' ? el.checked :
|
||||||
// https://stackoverflow.com/questions/18062069/why-does-valueasnumber-return-nan-as-a-value
|
type === 'number' ? parseFloat(el.value) :
|
||||||
// valueAsNumber is not applicable for input[text/radio] or select
|
|
||||||
type === 'number' ? Number(el.value) :
|
|
||||||
el.value;
|
el.value;
|
||||||
}
|
}
|
||||||
function isSame(el, oldValue, value) {
|
function isSame(el, oldValue, value) {
|
||||||
|
@ -465,6 +463,7 @@ prefs.ready.then(() => {
|
||||||
const max = (innerWidth < 850 ? screen.availWidth : innerWidth) / 3;
|
const max = (innerWidth < 850 ? screen.availWidth : innerWidth) / 3;
|
||||||
width = Math.round(Math.max(200, Math.min(max, Number(width) || 0)));
|
width = Math.round(Math.max(200, Math.min(max, Number(width) || 0)));
|
||||||
$.root.style.setProperty('--header-width', width + 'px');
|
$.root.style.setProperty('--header-width', width + 'px');
|
||||||
|
dom.HWval = width;
|
||||||
return width;
|
return width;
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -55,6 +55,7 @@
|
||||||
'manage.actions.expanded': true,
|
'manage.actions.expanded': true,
|
||||||
'manage.backup.expanded': true,
|
'manage.backup.expanded': true,
|
||||||
'manage.filters.expanded': true,
|
'manage.filters.expanded': true,
|
||||||
|
'manage.minColumnWidth': 750,
|
||||||
// the new compact layout doesn't look good on Android yet
|
// the new compact layout doesn't look good on Android yet
|
||||||
'manage.newUI': true,
|
'manage.newUI': true,
|
||||||
'manage.newUI.favicons': false, // show favicons for the sites in applies-to
|
'manage.newUI.favicons': false, // show favicons for the sites in applies-to
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
<a target="_blank" class="homepage"></a>
|
<a target="_blank" class="homepage"></a>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="applies-to">
|
<p class="applies-to">
|
||||||
|
<span class="style-info" data-type="age"></span>.
|
||||||
|
<label i18n="genericSize">:</label><span class="style-info" data-type="size"></span>.
|
||||||
<label i18n="appliesDisplay"></label>
|
<label i18n="appliesDisplay"></label>
|
||||||
<span class="targets"></span>
|
<span class="targets"></span>
|
||||||
</p>
|
</p>
|
||||||
|
@ -29,10 +31,8 @@
|
||||||
<button class="disable" i18n="disableStyleLabel"></button>
|
<button class="disable" i18n="disableStyleLabel"></button>
|
||||||
<button class="delete" i18n="deleteStyleLabel"></button>
|
<button class="delete" i18n="deleteStyleLabel"></button>
|
||||||
<button class="check-update" i18n="checkForUpdate"></button>
|
<button class="check-update" i18n="checkForUpdate"></button>
|
||||||
<button class="update" i18n="installUpdate"></button>
|
<button class="update" i18n="installUpdate" hidden></button>
|
||||||
<button class="configure-usercss" i18n="configureStyle"></button>
|
<button class="configure-usercss" i18n="configureStyle"></button>
|
||||||
<span class="style-info" data-type="size"></span>
|
|
||||||
<span class="style-info" data-type="age"></span>
|
|
||||||
<span class="update-note"></span>
|
<span class="update-note"></span>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
@ -49,9 +49,9 @@
|
||||||
|
|
||||||
<span class="style-info" data-type="version"></span>
|
<span class="style-info" data-type="version"></span>
|
||||||
</a>
|
</a>
|
||||||
|
<a target="_blank" class="homepage" tabindex="0"></a>
|
||||||
</h2>
|
</h2>
|
||||||
<p class="actions">
|
<p class="actions">
|
||||||
<a target="_blank" class="homepage" tabindex="0"></a>
|
|
||||||
<a class="delete" i18n="title:deleteStyleLabel" tabindex="0">
|
<a class="delete" i18n="title:deleteStyleLabel" tabindex="0">
|
||||||
<svg class="svg-icon" viewBox="0 0 20 20">
|
<svg class="svg-icon" viewBox="0 0 20 20">
|
||||||
<polygon points="16.2,5.5 14.5,3.8 10,8.3 5.5,3.8 3.8,5.5 8.3,10 3.8,14.5
|
<polygon points="16.2,5.5 14.5,3.8 10,8.3 5.5,3.8 3.8,5.5 8.3,10 3.8,14.5
|
||||||
|
@ -391,6 +391,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<link rel="stylesheet" href="manage/manage.css">
|
<link rel="stylesheet" href="manage/manage.css">
|
||||||
|
<link rel="stylesheet" href="manage/manage-newui.css" id="newUI">
|
||||||
<script src="js/dark-themer.js"></script> <!-- must be last in HEAD to avoid FOUC -->
|
<script src="js/dark-themer.js"></script> <!-- must be last in HEAD to avoid FOUC -->
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,9 @@ const Events = {
|
||||||
},
|
},
|
||||||
|
|
||||||
name(event, entry) {
|
name(event, entry) {
|
||||||
if (newUI.enabled) Events.edit(event, entry);
|
if (newUI.enabled && !event.target.closest('.homepage')) {
|
||||||
|
Events.edit(event, entry);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
toggle(event, entry) {
|
toggle(event, entry) {
|
||||||
|
@ -193,7 +195,7 @@ function handleUpdate(style, {reason, method} = {}) {
|
||||||
}
|
}
|
||||||
entry = entry || createStyleElement(styleToDummyEntry(style));
|
entry = entry || createStyleElement(styleToDummyEntry(style));
|
||||||
if (oldEntry) {
|
if (oldEntry) {
|
||||||
if (oldEntry.styleNameLowerCase === entry.styleNameLowerCase) {
|
if (oldEntry.styleNameLC === entry.styleNameLC) {
|
||||||
installed.replaceChild(entry, oldEntry);
|
installed.replaceChild(entry, oldEntry);
|
||||||
} else {
|
} else {
|
||||||
oldEntry.remove();
|
oldEntry.remove();
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
let found;
|
let found;
|
||||||
for (const entry of rotated || entries) {
|
for (const entry of rotated || entries) {
|
||||||
if (entry.classList.contains('hidden')) continue;
|
if (entry.classList.contains('hidden')) continue;
|
||||||
const name = entry.styleNameLowerCase;
|
const name = entry.styleNameLC;
|
||||||
const pos = name.indexOf(text);
|
const pos = name.indexOf(text);
|
||||||
if (pos === 0) {
|
if (pos === 0) {
|
||||||
found = entry;
|
found = entry;
|
||||||
|
@ -73,7 +73,7 @@
|
||||||
if (found && found !== focusedEntry) {
|
if (found && found !== focusedEntry) {
|
||||||
focusedEntry = found;
|
focusedEntry = found;
|
||||||
focusedLink = $('a', found);
|
focusedLink = $('a', found);
|
||||||
focusedName = found.styleNameLowerCase;
|
focusedName = found.styleNameLC;
|
||||||
scrollElementIntoView(found, {invalidMarginRatio: .25});
|
scrollElementIntoView(found, {invalidMarginRatio: .25});
|
||||||
animateElement(found, 'highlight-quick');
|
animateElement(found, 'highlight-quick');
|
||||||
replaceInlineStyle({
|
replaceInlineStyle({
|
||||||
|
|
278
manage/manage-newui.css
Normal file
278
manage/manage-newui.css
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
.disabled.entry .svg-icon {
|
||||||
|
color: var(--c50);
|
||||||
|
fill: var(--c80);
|
||||||
|
font-weight: normal;
|
||||||
|
transition: color .5s .1s, fill .5s .1s;
|
||||||
|
}
|
||||||
|
#installed {
|
||||||
|
margin-top: .75rem;
|
||||||
|
margin-bottom: .75rem;
|
||||||
|
}
|
||||||
|
.entry {
|
||||||
|
padding: 0 .5em;
|
||||||
|
display: flex;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
.entry.odd {
|
||||||
|
background-color: rgba(128, 128, 128, 0.05);
|
||||||
|
}
|
||||||
|
.entry > * {
|
||||||
|
padding: .5rem 0;
|
||||||
|
margin: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.entry .actions {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.style-info[data-type=size],
|
||||||
|
.style-info[data-type=age] {
|
||||||
|
color: var(--c50);
|
||||||
|
justify-content: end;
|
||||||
|
}
|
||||||
|
.style-info[data-type=age] {
|
||||||
|
flex: 0 0 4ch;
|
||||||
|
}
|
||||||
|
.style-info[data-type=size] {
|
||||||
|
flex: 0 0 var(--size-width);
|
||||||
|
}
|
||||||
|
.style-info[data-type=version] {
|
||||||
|
color: var(--c40);
|
||||||
|
padding-left: .5em;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
.style-info[data-type=version][data-is-date],
|
||||||
|
.style-info[data-type=version][data-value=""],
|
||||||
|
.style-info[data-type=version][data-value="1.0.0"] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.entry input[type="checkbox"]:not(.slider) {
|
||||||
|
pointer-events: all;
|
||||||
|
}
|
||||||
|
.style-name {
|
||||||
|
font-size: 14px;
|
||||||
|
padding-left: var(--name-padding-left);
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
justify-content: space-between;
|
||||||
|
flex: 0 0 var(--name-width);
|
||||||
|
min-width: 25%;
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
#installed[style*="--num-targets:0"] .style-name {
|
||||||
|
max-width: none;
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
.checkmate {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.style-name-link {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.entry .style-name:hover::before {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
background: linear-gradient(to right, hsla(180, 50%, 30%, 0.2), hsla(180, 20%, 10%, 0.05) 50%, transparent);
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.entry.enabled .style-name:hover .style-name-link {
|
||||||
|
color: var(--accent-1);
|
||||||
|
}
|
||||||
|
.homepage {
|
||||||
|
margin-top: -3px;
|
||||||
|
}
|
||||||
|
.actions {
|
||||||
|
flex: 0 0 calc(3 * (var(--action-size) + var(--action-margin)));
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
z-index: 100;
|
||||||
|
}
|
||||||
|
.actions > * {
|
||||||
|
width: var(--action-size);
|
||||||
|
height: var(--action-size);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.updater-icons > * {
|
||||||
|
transition: opacity 1s;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.entry .svg-icon {
|
||||||
|
fill: var(--c60);
|
||||||
|
}
|
||||||
|
.entry:hover .svg-icon {
|
||||||
|
fill: var(--c40);
|
||||||
|
}
|
||||||
|
.entry .svg-icon.checked,
|
||||||
|
.entry:hover .svg-icon.checked,
|
||||||
|
.entry:hover .svg-icon:hover {
|
||||||
|
fill: var(--fg);
|
||||||
|
}
|
||||||
|
.checking-update .check-update {
|
||||||
|
opacity: 0;
|
||||||
|
display: inline-block;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.can-update .update,
|
||||||
|
.no-update:not(.update-problem):not(.update-done) .up-to-date,
|
||||||
|
.no-update.update-problem .check-update,
|
||||||
|
.update-done .updated {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.up-to-date svg,
|
||||||
|
.updated svg {
|
||||||
|
cursor: auto;
|
||||||
|
}
|
||||||
|
.update-done .updated svg {
|
||||||
|
top: -4px;
|
||||||
|
position: relative;
|
||||||
|
filter: drop-shadow(0 5px 0 currentColor);
|
||||||
|
}
|
||||||
|
.can-update .update,
|
||||||
|
.no-update.update-problem .check-update {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.can-update[data-details$="locally edited"] .update svg,
|
||||||
|
.update-problem .check-update svg {
|
||||||
|
fill: #ef6969;
|
||||||
|
}
|
||||||
|
.can-update[data-details$="locally edited"]:hover .update svg,
|
||||||
|
.entry.update-problem:hover .check-update svg {
|
||||||
|
fill: #fd4040;
|
||||||
|
}
|
||||||
|
.can-update[data-details$="locally edited"]:hover .update svg:hover,
|
||||||
|
.entry.update-problem:hover .check-update svg:hover {
|
||||||
|
fill: red;
|
||||||
|
}
|
||||||
|
.updater-icons > :not(.check-update):after {
|
||||||
|
content: attr(title);
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
width: max-content;
|
||||||
|
max-width: 25vw;
|
||||||
|
padding: 1ex 1.5ex;
|
||||||
|
border: 1px solid #ded597;
|
||||||
|
background-color: #fffbd6;
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 2px 3px 10px rgba(0,0,0,.25);
|
||||||
|
font-size: 90%;
|
||||||
|
animation: fadeout 10s;
|
||||||
|
animation-fill-mode: both;
|
||||||
|
}
|
||||||
|
.update-problem .check-update:after {
|
||||||
|
background-color: red;
|
||||||
|
border: 1px solid #d40000;
|
||||||
|
color: white;
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
.can-update .update:after {
|
||||||
|
animation: none;
|
||||||
|
}
|
||||||
|
.can-update:not([data-details$="locally edited"]) .update:after {
|
||||||
|
background-color: #c0fff0;
|
||||||
|
border: 1px solid #89cac9;
|
||||||
|
}
|
||||||
|
.applies-to {
|
||||||
|
padding: .25em 0 .25em 1em;
|
||||||
|
flex-grow: 999;
|
||||||
|
}
|
||||||
|
#installed[style*="--num-targets:0"] .applies-to {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.targets {
|
||||||
|
overflow: hidden;
|
||||||
|
max-height: calc(var(--num-targets) * 18px);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
.applies-to.expanded .targets {
|
||||||
|
max-height: none;
|
||||||
|
}
|
||||||
|
.target {
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
padding-right: 1em;
|
||||||
|
line-height: 18px;
|
||||||
|
width: 0;
|
||||||
|
min-width: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
.applies-to:not(.has-more) .expander {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.target:hover {
|
||||||
|
background-color: inherit;
|
||||||
|
}
|
||||||
|
.target img {
|
||||||
|
width: 16px;
|
||||||
|
height: 16px;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin: -1px 4px 0 -20px;
|
||||||
|
transition: opacity .5s, filter .5s;
|
||||||
|
/* workaround for the buggy CSS filter: images in the hidden overflow are shown on Mac */
|
||||||
|
backface-visibility: hidden;
|
||||||
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
.favicons-grayed .target img {
|
||||||
|
filter: grayscale(1);
|
||||||
|
opacity: .25;
|
||||||
|
}
|
||||||
|
.has-favicons .target {
|
||||||
|
padding-left: 20px;
|
||||||
|
}
|
||||||
|
.has-favicons .target img[src] {
|
||||||
|
visibility: visible;
|
||||||
|
}
|
||||||
|
.entry:hover .target img {
|
||||||
|
opacity: 1;
|
||||||
|
filter: none;
|
||||||
|
}
|
||||||
|
.target b::after {
|
||||||
|
content: '?';
|
||||||
|
margin: -2px 4px 0 -20px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: baseline;
|
||||||
|
background: var(--c85);
|
||||||
|
width: 16px;
|
||||||
|
line-height: 16px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 50%;
|
||||||
|
color: var(--bg);
|
||||||
|
}
|
||||||
|
@media (max-width: 850px) {
|
||||||
|
.entry {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.entry .checkmate {
|
||||||
|
position: absolute;
|
||||||
|
left: 14px;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
.entry .style-name {
|
||||||
|
text-indent: unset;
|
||||||
|
}
|
||||||
|
.entry .actions {
|
||||||
|
width: 104px;
|
||||||
|
padding: .5rem 0 .5rem 6px;
|
||||||
|
}
|
||||||
|
.entry .applies-to {
|
||||||
|
padding: .25rem .5rem .25rem 0;
|
||||||
|
}
|
||||||
|
.entry .target {
|
||||||
|
max-width: 100%;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
.style-name-link::after {
|
||||||
|
text-indent: 0;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
.entry > .style-info {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,9 @@
|
||||||
:root {
|
:root {
|
||||||
--name-padding-left: 20px;
|
--name-padding-left: 20px;
|
||||||
--name-padding-right: 40px;
|
--name-width: 30ch;
|
||||||
--actions-width: 75px;
|
--size-width: 4ch;
|
||||||
|
--action-size: 20px;
|
||||||
|
--action-margin: 6px;
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
/* Fill the entire viewport to enable json import via drag'n'drop */
|
/* Fill the entire viewport to enable json import via drag'n'drop */
|
||||||
|
@ -124,17 +126,21 @@ a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
#installed {
|
#installed {
|
||||||
position: relative;
|
|
||||||
padding-left: var(--header-width);
|
padding-left: var(--header-width);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
align-self: start;
|
align-self: start;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry {
|
.entry {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 1.25em 2em;
|
padding: 1.25em 2em;
|
||||||
border-top: 1px solid var(--c85);
|
border-top: 1px solid var(--c85);
|
||||||
|
box-sizing: border-box;
|
||||||
|
position: relative;
|
||||||
|
width: calc(100% / var(--columns, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry:first-child {
|
.entry:first-child {
|
||||||
|
@ -158,15 +164,13 @@ a:hover {
|
||||||
margin-top: .25em;
|
margin-top: .25em;
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
.style-name a, .style-edit-link {
|
.style-name a, .style-edit-link {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
.style-name span,
|
||||||
.applies-to {
|
.applies-to {
|
||||||
overflow-wrap: break-word;
|
overflow-wrap: anywhere;
|
||||||
}
|
}
|
||||||
|
|
||||||
.applies-to,
|
.applies-to,
|
||||||
.actions {
|
.actions {
|
||||||
padding-left: 15px;
|
padding-left: 15px;
|
||||||
|
@ -181,11 +185,10 @@ a:hover {
|
||||||
|
|
||||||
.actions > * {
|
.actions > * {
|
||||||
margin-bottom: .25rem;
|
margin-bottom: .25rem;
|
||||||
display: inline-block;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.actions > *:not(:last-child) {
|
.actions > *:not(:last-child) {
|
||||||
margin-right: .25rem;
|
margin-right: var(--action-margin);
|
||||||
}
|
}
|
||||||
|
|
||||||
.applies-to label {
|
.applies-to label {
|
||||||
|
@ -240,8 +243,7 @@ a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
.disabled h2 .style-name-link,
|
.disabled h2 .style-name-link,
|
||||||
.disabled .applies-to,
|
.disabled .applies-to {
|
||||||
.newUI .disabled.entry .svg-icon {
|
|
||||||
color: var(--c50);
|
color: var(--c50);
|
||||||
fill: var(--c80);
|
fill: var(--c80);
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
@ -319,56 +321,8 @@ a:hover {
|
||||||
|
|
||||||
/* compact layout */
|
/* compact layout */
|
||||||
|
|
||||||
.newUI #installed {
|
|
||||||
display: table;
|
|
||||||
margin-top: .75rem;
|
|
||||||
margin-bottom: .75rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry {
|
|
||||||
display: table-row;
|
|
||||||
padding-top: 0;
|
|
||||||
padding-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry.odd {
|
|
||||||
background-color: rgba(128, 128, 128, 0.05);
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry > * {
|
|
||||||
padding: .5rem 0;
|
|
||||||
margin: 0;
|
|
||||||
display: table-cell;
|
|
||||||
vertical-align: middle;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry .actions {
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.style-info[data-type=version] {
|
|
||||||
color: var(--c40);
|
|
||||||
padding-left: .5em;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
.newUI .style-info[data-type=version][data-is-date],
|
|
||||||
.newUI .style-info[data-type=version][data-value=""],
|
|
||||||
.newUI .style-info[data-type=version][data-value="1.0.0"] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.newUI .entry .style-info[data-type=size],
|
|
||||||
.newUI .entry .style-info[data-type=age] {
|
|
||||||
color: var(--c50);
|
|
||||||
text-align: right;
|
|
||||||
padding-right: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/************ checkbox & select************/
|
/************ checkbox & select************/
|
||||||
|
|
||||||
#newUIoptions > div, #newUIoptions > label {
|
|
||||||
margin: 4px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-selection {
|
.filter-selection {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: -9px;
|
left: -9px;
|
||||||
|
@ -393,10 +347,6 @@ a:hover {
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.newUI #newUIoptions > label {
|
|
||||||
padding-left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.filter-selection select {
|
.filter-selection select {
|
||||||
height: 18px;
|
height: 18px;
|
||||||
border: none;
|
border: none;
|
||||||
|
@ -439,7 +389,7 @@ a:hover {
|
||||||
|
|
||||||
.entry .checkmate {
|
.entry .checkmate {
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
margin: -2px 1ex 0 0;
|
margin-right: 1ch;
|
||||||
}
|
}
|
||||||
|
|
||||||
#manage-text {
|
#manage-text {
|
||||||
|
@ -456,179 +406,10 @@ a:hover {
|
||||||
margin: 0 .5em;
|
margin: 0 .5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.newUI .entry input[type="checkbox"]:not(.slider) {
|
button .svg-icon {
|
||||||
pointer-events: all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .style-name {
|
|
||||||
font-size: 14px;
|
|
||||||
padding-left: var(--name-padding-left);
|
|
||||||
padding-right: var(--name-padding-right);
|
|
||||||
position: relative;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry .style-name:hover::before {
|
|
||||||
content: "";
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: linear-gradient(to right, hsla(180, 50%, 30%, 0.2), hsla(180, 20%, 10%, 0.05) 50%, transparent);
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry.enabled .style-name:hover .style-name-link {
|
|
||||||
color: var(--accent-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .style-name:after {
|
|
||||||
text-indent: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .actions:after {
|
|
||||||
text-indent: -25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .actions .homepage[href=""] {
|
|
||||||
display: inline-block;
|
|
||||||
visibility: hidden;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .actions {
|
|
||||||
width: var(--actions-width);
|
|
||||||
height: 20px;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .actions > * {
|
|
||||||
margin: 0 6px 0 0;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .updater-icons > * {
|
|
||||||
transition: opacity 1s;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry .svg-icon {
|
|
||||||
fill: var(--c60);
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry:hover .svg-icon {
|
|
||||||
fill: var(--c40);
|
|
||||||
}
|
|
||||||
|
|
||||||
button .svg-icon,
|
|
||||||
.newUI .entry .svg-icon.checked,
|
|
||||||
.newUI .entry:hover .svg-icon.checked,
|
|
||||||
.newUI .entry:hover .svg-icon:hover {
|
|
||||||
fill: var(--fg);
|
fill: var(--fg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.newUI .checking-update .check-update {
|
|
||||||
opacity: 0;
|
|
||||||
display: inline-block;
|
|
||||||
pointer-events: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .can-update .update,
|
|
||||||
.newUI .no-update:not(.update-problem):not(.update-done) .up-to-date,
|
|
||||||
.newUI .no-update.update-problem .check-update,
|
|
||||||
.newUI .update-done .updated {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .up-to-date svg,
|
|
||||||
.newUI .updated svg {
|
|
||||||
cursor: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .update-done .updated svg {
|
|
||||||
top: -4px;
|
|
||||||
position: relative;
|
|
||||||
filter: drop-shadow(0 5px 0 currentColor);
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .can-update .update,
|
|
||||||
.newUI .no-update.update-problem .check-update {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .can-update[data-details$="locally edited"] .update svg,
|
|
||||||
.newUI .update-problem .check-update svg {
|
|
||||||
fill: #ef6969;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .can-update[data-details$="locally edited"]:hover .update svg,
|
|
||||||
.newUI .entry.update-problem:hover .check-update svg {
|
|
||||||
fill: #fd4040;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .can-update[data-details$="locally edited"]:hover .update svg:hover,
|
|
||||||
.newUI .entry.update-problem:hover .check-update svg:hover {
|
|
||||||
fill: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .actions {
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .updater-icons > :not(.check-update):after {
|
|
||||||
content: attr(title);
|
|
||||||
position: absolute;
|
|
||||||
margin-top: 18px;
|
|
||||||
margin-left: -36px;
|
|
||||||
padding: 1ex 1.5ex;
|
|
||||||
border: 1px solid #ded597;
|
|
||||||
background-color: #fffbd6;
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 2px 3px 10px rgba(0,0,0,.25);
|
|
||||||
font-size: 90%;
|
|
||||||
animation: fadeout 10s;
|
|
||||||
animation-fill-mode: both;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .update-problem .check-update:after {
|
|
||||||
background-color: red;
|
|
||||||
border: 1px solid #d40000;
|
|
||||||
color: white;
|
|
||||||
animation: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .can-update .update:after {
|
|
||||||
animation: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .can-update:not([data-details$="locally edited"]) .update:after {
|
|
||||||
background-color: #c0fff0;
|
|
||||||
border: 1px solid #89cac9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .applies-to {
|
|
||||||
padding-top: .25rem;
|
|
||||||
padding-bottom: .25rem;
|
|
||||||
}
|
|
||||||
.newUI .targets {
|
|
||||||
overflow: hidden;
|
|
||||||
max-height: calc(var(--num-targets) * 18px);
|
|
||||||
}
|
|
||||||
.newUI .applies-to.expanded .targets {
|
|
||||||
max-height: none;
|
|
||||||
}
|
|
||||||
.newUI .target {
|
|
||||||
display: block;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
white-space: nowrap;
|
|
||||||
max-width: calc(75vw - var(--header-width) - var(--actions-width) - var(--name-padding-left) - var(--name-padding-right) - 6rem);
|
|
||||||
box-sizing: border-box;
|
|
||||||
padding-right: 1rem;
|
|
||||||
line-height: 18px;
|
|
||||||
}
|
|
||||||
.expander {
|
.expander {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
@ -643,54 +424,6 @@ button .svg-icon,
|
||||||
transform: rotate(180deg);
|
transform: rotate(180deg);
|
||||||
transform-origin: 8px 8px;
|
transform-origin: 8px 8px;
|
||||||
}
|
}
|
||||||
.newUI .applies-to:not(.has-more) .expander {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.newUI .target:hover {
|
|
||||||
background-color: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .target img {
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin: -1px 4px 0 -20px;
|
|
||||||
transition: opacity .5s, filter .5s;
|
|
||||||
/* workaround for the buggy CSS filter: images in the hidden overflow are shown on Mac */
|
|
||||||
backface-visibility: hidden;
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .favicons-grayed .target img {
|
|
||||||
filter: grayscale(1);
|
|
||||||
opacity: .25;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .has-favicons .target {
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .has-favicons .target img[src] {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry:hover .target img {
|
|
||||||
opacity: 1;
|
|
||||||
filter: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .target b::after {
|
|
||||||
content: '?';
|
|
||||||
margin: -2px 4px 0 -20px;
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: baseline;
|
|
||||||
background: var(--c85);
|
|
||||||
width: 16px;
|
|
||||||
line-height: 16px;
|
|
||||||
text-align: center;
|
|
||||||
border-radius: 50%;
|
|
||||||
color: var(--bg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Default, no update buttons */
|
/* Default, no update buttons */
|
||||||
.updater-icons .update,
|
.updater-icons .update,
|
||||||
|
@ -1032,12 +765,6 @@ button .svg-icon,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1000px) {
|
|
||||||
.newUI .entry > .style-info {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 850px) {
|
@media (max-width: 850px) {
|
||||||
:root {
|
:root {
|
||||||
--name-padding-left: 34px;
|
--name-padding-left: 34px;
|
||||||
|
@ -1058,7 +785,7 @@ button .svg-icon,
|
||||||
left: 3.75rem;
|
left: 3.75rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
html:not(.newUI) .applies-to {
|
.oldUI .applies-to {
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1066,10 +793,6 @@ button .svg-icon,
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.newUI .entry .actions {
|
|
||||||
padding-right: 30px
|
|
||||||
}
|
|
||||||
|
|
||||||
#search-wrapper,
|
#search-wrapper,
|
||||||
#sort-wrapper,
|
#sort-wrapper,
|
||||||
#header summary {
|
#header summary {
|
||||||
|
@ -1127,41 +850,6 @@ button .svg-icon,
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
padding-bottom: .25rem;
|
padding-bottom: .25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.newUI .entry {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry .checkmate {
|
|
||||||
position: absolute;
|
|
||||||
left: 14px;
|
|
||||||
top: 0;
|
|
||||||
bottom: 0;
|
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry .style-name {
|
|
||||||
text-indent: unset;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry .actions {
|
|
||||||
width: 104px;
|
|
||||||
padding: .5rem 0 .5rem 6px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry .applies-to {
|
|
||||||
padding: .25rem .5rem .25rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .entry .target {
|
|
||||||
max-width: 100%;
|
|
||||||
padding-right: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.newUI .style-name-link::after {
|
|
||||||
text-indent: 0;
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@supports (-moz-appearance: none) {
|
@supports (-moz-appearance: none) {
|
||||||
|
|
|
@ -28,9 +28,16 @@ const newUI = {
|
||||||
Object.assign(newUI, {
|
Object.assign(newUI, {
|
||||||
ids: Object.keys(newUI),
|
ids: Object.keys(newUI),
|
||||||
prefKeyForId: id => `manage.newUI.${id}`.replace(/\.enabled$/, ''),
|
prefKeyForId: id => `manage.newUI.${id}`.replace(/\.enabled$/, ''),
|
||||||
|
readPrefs(dest = newUI, cb) {
|
||||||
|
for (const id of newUI.ids) {
|
||||||
|
const val = dest[id] = prefs.get(newUI.prefKeyForId(id));
|
||||||
|
if (cb) cb(id, val);
|
||||||
|
}
|
||||||
|
},
|
||||||
renderClass: () => {
|
renderClass: () => {
|
||||||
$.rootCL.toggle('newUI', newUI.enabled);
|
$.rootCL.toggle('newUI', newUI.enabled);
|
||||||
$.rootCL.toggle('oldUI', !newUI.enabled);
|
$.rootCL.toggle('oldUI', !newUI.enabled);
|
||||||
|
$('#newUI').media = newUI.enabled ? '' : '?';
|
||||||
},
|
},
|
||||||
hasFavs: () => newUI.enabled && newUI.favicons,
|
hasFavs: () => newUI.enabled && newUI.favicons,
|
||||||
badFavsKey: 'badFavs',
|
badFavsKey: 'badFavs',
|
||||||
|
@ -41,9 +48,7 @@ Object.assign(newUI, {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
// ...read the actual values
|
// ...read the actual values
|
||||||
for (const id of newUI.ids) {
|
newUI.readPrefs();
|
||||||
newUI[id] = prefs.get(newUI.prefKeyForId(id));
|
|
||||||
}
|
|
||||||
newUI.renderClass();
|
newUI.renderClass();
|
||||||
|
|
||||||
(async function init() {
|
(async function init() {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
/* global URLS debounce getOwnTab isEmptyObj sessionStore stringAsRegExp */// toolbox.js
|
/* global URLS debounce getOwnTab isEmptyObj sessionStore stringAsRegExp */// toolbox.js
|
||||||
/* global filterAndAppend */// filters.js
|
/* global filterAndAppend */// filters.js
|
||||||
/* global installed newUI */// manage.js
|
/* global installed newUI */// manage.js
|
||||||
/* global prefs */
|
|
||||||
/* global sorter */
|
/* global sorter */
|
||||||
/* global t */// localization.js
|
/* global t */// localization.js
|
||||||
'use strict';
|
'use strict';
|
||||||
|
@ -18,6 +17,7 @@ const AGES = [
|
||||||
[Infinity, 'y', t('dateAbbrYear', '\x01')],
|
[Infinity, 'y', t('dateAbbrYear', '\x01')],
|
||||||
];
|
];
|
||||||
const groupThousands = num => `${num}`.replace(/\d(?=(\d{3})+$)/g, '$&\xA0');
|
const groupThousands = num => `${num}`.replace(/\d(?=(\d{3})+$)/g, '$&\xA0');
|
||||||
|
const renderSize = size => groupThousands(Math.round(size / 1024)) + 'k';
|
||||||
|
|
||||||
(() => {
|
(() => {
|
||||||
const proto = HTMLImageElement.prototype;
|
const proto = HTMLImageElement.prototype;
|
||||||
|
@ -79,7 +79,7 @@ function calcObjSize(obj) {
|
||||||
Object.entries(obj).reduce((sum, [k, v]) => sum + k.length + calcObjSize(v), 0);
|
Object.entries(obj).reduce((sum, [k, v]) => sum + k.length + calcObjSize(v), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
function createStyleElement({styleMeta: style, styleNameLowerCase: nameLC, styleSize: size}) {
|
function createStyleElement({styleMeta: style, styleNameLC: nameLC, styleSize: size}) {
|
||||||
// query the sub-elements just once, then reuse the references
|
// query the sub-elements just once, then reuse the references
|
||||||
if ((elementParts || {}).newUI !== newUI.enabled) {
|
if ((elementParts || {}).newUI !== newUI.enabled) {
|
||||||
const entry = t.template[newUI.enabled ? 'styleNewUI' : 'style'].cloneNode(true);
|
const entry = t.template[newUI.enabled ? 'styleNewUI' : 'style'].cloneNode(true);
|
||||||
|
@ -105,7 +105,6 @@ function createStyleElement({styleMeta: style, styleNameLowerCase: nameLC, style
|
||||||
},
|
},
|
||||||
oldConfigure: !newUI.enabled && $('.configure-usercss', entry),
|
oldConfigure: !newUI.enabled && $('.configure-usercss', entry),
|
||||||
oldCheckUpdate: !newUI.enabled && $('.check-update', entry),
|
oldCheckUpdate: !newUI.enabled && $('.check-update', entry),
|
||||||
oldUpdate: !newUI.enabled && $('.update', entry),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
const parts = elementParts;
|
const parts = elementParts;
|
||||||
|
@ -126,12 +125,11 @@ function createStyleElement({styleMeta: style, styleNameLowerCase: nameLC, style
|
||||||
}
|
}
|
||||||
createAgeText(parts.infoAge, style);
|
createAgeText(parts.infoAge, style);
|
||||||
parts.infoSize.dataset.value = Math.log10(size || 1) >> 0; // for CSS to target big/small styles
|
parts.infoSize.dataset.value = Math.log10(size || 1) >> 0; // for CSS to target big/small styles
|
||||||
parts.infoSize.textContent = groupThousands(Math.round(size / 1024)) + 'k';
|
parts.infoSize.textContent = renderSize(size);
|
||||||
parts.infoSize.title = `${t('genericSize')}: ${groupThousands(size)} B`;
|
parts.infoSize.title = `${t('genericSize')}: ${groupThousands(size)} B`;
|
||||||
if (!newUI.enabled) {
|
if (!newUI.enabled) {
|
||||||
parts.oldConfigure.classList.toggle('hidden', !configurable);
|
parts.oldConfigure.classList.toggle('hidden', !configurable);
|
||||||
parts.oldCheckUpdate.classList.toggle('hidden', !style.updateUrl);
|
parts.oldCheckUpdate.classList.toggle('hidden', !style.updateUrl);
|
||||||
parts.oldUpdate.classList.toggle('hidden', !style.updateUrl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// clear the code to free up some memory
|
// clear the code to free up some memory
|
||||||
|
@ -142,7 +140,7 @@ function createStyleElement({styleMeta: style, styleNameLowerCase: nameLC, style
|
||||||
const entry = parts.entry.cloneNode(true);
|
const entry = parts.entry.cloneNode(true);
|
||||||
entry.id = ENTRY_ID_PREFIX_RAW + style.id;
|
entry.id = ENTRY_ID_PREFIX_RAW + style.id;
|
||||||
entry.styleId = style.id;
|
entry.styleId = style.id;
|
||||||
entry.styleNameLowerCase = nameLC;
|
entry.styleNameLC = nameLC;
|
||||||
entry.styleMeta = style;
|
entry.styleMeta = style;
|
||||||
entry.styleSize = size;
|
entry.styleSize = size;
|
||||||
entry.className = parts.entryClassBase + ' ' +
|
entry.className = parts.entryClassBase + ' ' +
|
||||||
|
@ -166,6 +164,12 @@ function createStyleElement({styleMeta: style, styleNameLowerCase: nameLC, style
|
||||||
}
|
}
|
||||||
|
|
||||||
function createTargetsElement({entry, expanded, style = entry.styleMeta}) {
|
function createTargetsElement({entry, expanded, style = entry.styleMeta}) {
|
||||||
|
const maxTargets = expanded ? 1000 : newUI.enabled ? newUI.targets : 10;
|
||||||
|
if (!maxTargets) {
|
||||||
|
entry._numTargets = 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const displayed = new Set();
|
||||||
const entryTargets = $('.targets', entry);
|
const entryTargets = $('.targets', entry);
|
||||||
const expanderCls = $('.applies-to', entry).classList;
|
const expanderCls = $('.applies-to', entry).classList;
|
||||||
const targets = elementParts.targets.cloneNode(true);
|
const targets = elementParts.targets.cloneNode(true);
|
||||||
|
@ -173,8 +177,6 @@ function createTargetsElement({entry, expanded, style = entry.styleMeta}) {
|
||||||
let el = entryTargets.firstElementChild;
|
let el = entryTargets.firstElementChild;
|
||||||
let numTargets = 0;
|
let numTargets = 0;
|
||||||
let allTargetsRendered = true;
|
let allTargetsRendered = true;
|
||||||
const maxTargets = expanded ? 1000 : newUI.enabled ? newUI.targets : 10;
|
|
||||||
const displayed = new Set();
|
|
||||||
for (const type of TARGET_TYPES) {
|
for (const type of TARGET_TYPES) {
|
||||||
for (const section of style.sections) {
|
for (const section of style.sections) {
|
||||||
for (const targetValue of section[type] || []) {
|
for (const targetValue of section[type] || []) {
|
||||||
|
@ -352,26 +354,43 @@ function padLeft(val, width) {
|
||||||
return ' '.repeat(Math.max(0, width - val.length)) + val;
|
return ' '.repeat(Math.max(0, width - val.length)) + val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function fitNameColumn(styles) {
|
||||||
|
const align = 1e9; // required by sort()
|
||||||
|
const lengths = styles.map(s => align +
|
||||||
|
(s = s.displayName || s.name || '').length +
|
||||||
|
s.replace(/[^\u3000-\uFE00]+/g, '').length).sort(); // CJK glyphs are twice as wide
|
||||||
|
const len = styles.length;
|
||||||
|
const fringe = len * 5 / 100 | 0; // ignoring 5% of outliers at each end
|
||||||
|
let avgName = 0;
|
||||||
|
for (let i = fringe; i < len - fringe; i++) {
|
||||||
|
avgName = Math.max(avgName, lengths[i] - align);
|
||||||
|
}
|
||||||
|
$.root.style.setProperty('--name-width', avgName + 'ch');
|
||||||
|
}
|
||||||
|
|
||||||
|
function fitSizeColumn(entries) {
|
||||||
|
const max = entries.reduce((res, e) => Math.max(res, e.styleSize), 0);
|
||||||
|
$.root.style.setProperty('--size-width', renderSize(max).length + 'ch');
|
||||||
|
}
|
||||||
|
|
||||||
function showStyles(styles = [], matchUrlIds) {
|
function showStyles(styles = [], matchUrlIds) {
|
||||||
const sorted = sorter.sort(styles.map(styleToDummyEntry));
|
const dummies = styles.map(styleToDummyEntry);
|
||||||
|
const sorted = sorter.sort(dummies);
|
||||||
let index = 0;
|
let index = 0;
|
||||||
let firstRun = true;
|
let firstRun = true;
|
||||||
installed.dataset.total = styles.length;
|
installed.dataset.total = styles.length;
|
||||||
const scrollY = (history.state || {}).scrollY;
|
const scrollY = (history.state || {}).scrollY;
|
||||||
const shouldRenderAll = scrollY > window.innerHeight || sessionStore.justEditedStyleId;
|
const shouldRenderAll = scrollY > window.innerHeight || sessionStore.justEditedStyleId;
|
||||||
const renderBin = document.createDocumentFragment();
|
const renderBin = document.createDocumentFragment();
|
||||||
if (scrollY) {
|
fitNameColumn(styles);
|
||||||
|
fitSizeColumn(dummies);
|
||||||
renderStyles();
|
renderStyles();
|
||||||
} else {
|
|
||||||
requestAnimationFrame(renderStyles);
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderStyles() {
|
function renderStyles() {
|
||||||
const t0 = performance.now();
|
const t0 = performance.now();
|
||||||
while (index < sorted.length && (shouldRenderAll || performance.now() - t0 < 20)) {
|
while (index < sorted.length && (shouldRenderAll || performance.now() - t0 < 50)) {
|
||||||
const info = sorted[index++];
|
const entry = createStyleElement(sorted[index++]);
|
||||||
const entry = createStyleElement(info);
|
if (matchUrlIds && !matchUrlIds.includes(entry.styleMeta.id)) {
|
||||||
if (matchUrlIds && !matchUrlIds.includes(info.style.id)) {
|
|
||||||
entry.classList.add('not-matching');
|
entry.classList.add('not-matching');
|
||||||
}
|
}
|
||||||
renderBin.appendChild(entry);
|
renderBin.appendChild(entry);
|
||||||
|
@ -398,7 +417,7 @@ function styleToDummyEntry(style) {
|
||||||
styleMeta: style,
|
styleMeta: style,
|
||||||
styleSize: calcObjSize(style),
|
styleSize: calcObjSize(style),
|
||||||
// sort case-insensitively the whole list then sort dupes like `Foo` and `foo` case-sensitively
|
// sort case-insensitively the whole list then sort dupes like `Foo` and `foo` case-sensitively
|
||||||
styleNameLowerCase: name.toLocaleLowerCase() + '\n' + name,
|
styleNameLC: name.toLocaleLowerCase() + '\n' + name,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -407,13 +426,11 @@ function switchUI({styleOnly} = {}) {
|
||||||
const current = {};
|
const current = {};
|
||||||
const changed = {};
|
const changed = {};
|
||||||
let someChanged = false;
|
let someChanged = false;
|
||||||
for (const id of newUI.ids) {
|
newUI.readPrefs(current, (id, value) => {
|
||||||
const value = prefs.get(newUI.prefKeyForId(id));
|
|
||||||
const valueChanged = value !== newUI[id] && (id === 'enabled' || current.enabled);
|
const valueChanged = value !== newUI[id] && (id === 'enabled' || current.enabled);
|
||||||
current[id] = value;
|
|
||||||
changed[id] = valueChanged;
|
changed[id] = valueChanged;
|
||||||
someChanged |= valueChanged;
|
someChanged |= valueChanged;
|
||||||
}
|
});
|
||||||
|
|
||||||
if (!styleOnly && !someChanged) {
|
if (!styleOnly && !someChanged) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* global $ $create messageBoxProxy */// dom.js
|
/* global $ $create dom messageBoxProxy */// dom.js
|
||||||
/* global installed */// manage.js
|
/* global installed */// manage.js
|
||||||
/* global prefs */
|
/* global prefs */
|
||||||
/* global t */// localization.js
|
/* global t */// localization.js
|
||||||
|
@ -6,6 +6,10 @@
|
||||||
|
|
||||||
const sorter = (() => {
|
const sorter = (() => {
|
||||||
|
|
||||||
|
const COL_MIN = 300; // same as options.html
|
||||||
|
const COL_MAX = 9999; // same as options.html
|
||||||
|
const COL_PROP = '--columns';
|
||||||
|
|
||||||
const sorterType = {
|
const sorterType = {
|
||||||
alpha: (a, b) => a < b ? -1 : a === b ? 0 : 1,
|
alpha: (a, b) => a < b ? -1 : a === b ? 0 : 1,
|
||||||
number: (a, b) => (a || 0) - (b || 0),
|
number: (a, b) => (a || 0) - (b || 0),
|
||||||
|
@ -14,7 +18,7 @@ const sorter = (() => {
|
||||||
const tagData = {
|
const tagData = {
|
||||||
title: {
|
title: {
|
||||||
text: t('genericTitle'),
|
text: t('genericTitle'),
|
||||||
parse: v => v.styleNameLowerCase,
|
parse: v => v.styleNameLC,
|
||||||
sorter: sorterType.alpha,
|
sorter: sorterType.alpha,
|
||||||
},
|
},
|
||||||
usercss: {
|
usercss: {
|
||||||
|
@ -71,12 +75,13 @@ const sorter = (() => {
|
||||||
const getPref = () => prefs.get(ID) || prefs.defaults[ID];
|
const getPref = () => prefs.get(ID) || prefs.defaults[ID];
|
||||||
|
|
||||||
let columns = 1;
|
let columns = 1;
|
||||||
|
let minWidth;
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
prefs.subscribe(ID, sorter.update);
|
prefs.subscribe(ID, sorter.update);
|
||||||
$('#sorter-help').onclick = showHelp;
|
$('#sorter-help').onclick = showHelp;
|
||||||
addOptions();
|
addOptions();
|
||||||
updateColumnCount();
|
prefs.subscribe('manage.minColumnWidth', updateColumnWidth, {runNow: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
function addOptions() {
|
function addOptions() {
|
||||||
|
@ -172,21 +177,40 @@ const sorter = (() => {
|
||||||
};
|
};
|
||||||
|
|
||||||
function updateColumnCount() {
|
function updateColumnCount() {
|
||||||
let newValue = 1;
|
const useStyle = [].some.call($.root.children,
|
||||||
for (let el = $.root.lastElementChild;
|
el => el.tagName === 'STYLE' && el.textContent.includes(COL_PROP + ':'));
|
||||||
el.localName === 'style';
|
const v = useStyle ? Math.max(1, getComputedStyle($.root).getPropertyValue(COL_PROP) >> 0)
|
||||||
el = el.previousElementSibling) {
|
: minWidth ? onResize()
|
||||||
if (el.textContent.includes('--columns:')) {
|
: columns;
|
||||||
newValue = Math.max(1, getComputedStyle($.root).getPropertyValue('--columns') | 0);
|
if (columns !== v) {
|
||||||
break;
|
columns = v;
|
||||||
}
|
|
||||||
}
|
|
||||||
if (columns !== newValue) {
|
|
||||||
columns = newValue;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateColumnWidth(_, val) {
|
||||||
|
minWidth = Math.max(val, COL_MIN);
|
||||||
|
if (val < COL_MAX) {
|
||||||
|
window.on('resize', onResize);
|
||||||
|
} else {
|
||||||
|
window.off('resize', onResize);
|
||||||
|
$.root.style.removeProperty(COL_PROP);
|
||||||
|
}
|
||||||
|
sorter.updateStripes({onlyWhenColumnsChanged: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onResize(evt) {
|
||||||
|
const c = Math.max(1, (window.innerWidth - dom.HWval) / minWidth >> 0);
|
||||||
|
if (columns !== c) {
|
||||||
|
$.root.style.setProperty(COL_PROP, c);
|
||||||
|
if (evt) {
|
||||||
|
columns = c;
|
||||||
|
sorter.updateStripes();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
async function showHelp(event) {
|
async function showHelp(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
messageBoxProxy.show({
|
messageBoxProxy.show({
|
||||||
|
|
|
@ -240,6 +240,10 @@
|
||||||
<div class="block">
|
<div class="block">
|
||||||
<h1 i18n="openManage"></h1>
|
<h1 i18n="openManage"></h1>
|
||||||
<div class="items">
|
<div class="items">
|
||||||
|
<label>
|
||||||
|
<span i18n="manageMinColumnWidth"></span>
|
||||||
|
<input id="manage.minColumnWidth" type="number" min="300" max="9999">
|
||||||
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<span i18n="manageNewUI"></span>
|
<span i18n="manageNewUI"></span>
|
||||||
<span class="onoffswitch">
|
<span class="onoffswitch">
|
||||||
|
@ -268,7 +272,7 @@
|
||||||
</label>
|
</label>
|
||||||
<label>
|
<label>
|
||||||
<span i18n="manageMaxTargets"></span>
|
<span i18n="manageMaxTargets"></span>
|
||||||
<input id="manage.newUI.targets" type="number" min="1" max="99">
|
<input id="manage.newUI.targets" type="number" min="0" max="99">
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue
Block a user