170 lines
4.7 KiB
JavaScript
170 lines
4.7 KiB
JavaScript
/* global installed updateStripes */
|
|
/* global messageBox */
|
|
'use strict';
|
|
|
|
const sorterType = {
|
|
alpha: (a, b) => (a < b ? -1 : a === b ? 0 : 1),
|
|
number: (a, b) => a - b
|
|
};
|
|
|
|
const tagData = {
|
|
title: {
|
|
text: t('genericTitle'),
|
|
parse: {
|
|
style: style => style.name.toLowerCase(),
|
|
entry: entry => {
|
|
const el = $('.style-name-link', entry);
|
|
return el ? el.textContent.trim().toLowerCase() : '';
|
|
}
|
|
},
|
|
sorter: sorterType.alpha
|
|
},
|
|
usercss: {
|
|
text: 'Usercss',
|
|
parse: {
|
|
style: style => (style.usercssData ? 0 : 1),
|
|
entry: entry => (entry.classList.contains('usercss') ? 0 : 1)
|
|
},
|
|
sorter: sorterType.number
|
|
},
|
|
disabled: {
|
|
text: '', // added as either "enabled" or "disabled" by the addSortOptions function
|
|
parse: {
|
|
style: style => (style.enabled ? 1 : 0),
|
|
entry: entry => (entry.classList.contains('enabled') ? 1 : 0)
|
|
},
|
|
sorter: sorterType.number
|
|
},
|
|
dateInstalled: {
|
|
text: t('dateInstalled'),
|
|
parse: {
|
|
style: style => style.installDate,
|
|
entry: entry => entry.dataset.installdate
|
|
},
|
|
sorter: sorterType.number
|
|
},
|
|
dateUpdated: {
|
|
text: t('dateUpdated'),
|
|
parse: {
|
|
style: style => style.updateDate,
|
|
entry: entry => entry.dataset.updatedate
|
|
},
|
|
sorter: sorterType.number
|
|
}
|
|
};
|
|
|
|
// Adding (assumed) most commonly used ('title,asc' should always be first)
|
|
// whitespace before & after the comma is ignored
|
|
const sortSelectOptions = [
|
|
'title,asc',
|
|
'title,desc',
|
|
'dateInstalled,desc, title,asc',
|
|
'dateInstalled,asc, title,asc',
|
|
'dateUpdated,desc, title,asc',
|
|
'dateUpdated,asc, title,asc',
|
|
'usercss,asc, title,asc',
|
|
'usercss,desc, title,asc',
|
|
'disabled,asc, title,asc',
|
|
'disabled,desc, title,asc',
|
|
'disabled,desc, usercss,asc, title,asc',
|
|
'usercss,asc, title,desc',
|
|
'usercss,desc, title,desc',
|
|
'disabled,desc, title,desc',
|
|
'disabled,desc, usercss,asc, title,desc'
|
|
];
|
|
|
|
const sortByRegex = /\s*,\s*/;
|
|
|
|
function addSortOptions() {
|
|
const select = $('#options .sorter-selection select');
|
|
const renderBin = document.createDocumentFragment();
|
|
const option = $create('option');
|
|
const meta = {
|
|
enabled: t('genericEnabledLabel'),
|
|
disabled: t('genericDisabledLabel'),
|
|
desc: ` (${t('sortDescending')})`,
|
|
dateNew: ` (${t('sortDateNewestFirst')})`,
|
|
dateOld: ` (${t('sortDateOldestFirst')})`,
|
|
labelFirst: ` (${t('sortLabelFirst')})`,
|
|
labelLast: ` (${t('sortLabelLast')})`
|
|
};
|
|
sortSelectOptions.forEach(sort => {
|
|
const opt = option.cloneNode();
|
|
let lastTag = '';
|
|
opt.textContent = sort.split(sortByRegex).reduce((acc, val) => {
|
|
if (tagData[val]) {
|
|
lastTag = val;
|
|
return acc + (acc !== '' ? ' + ' : '') + tagData[val].text;
|
|
}
|
|
if (lastTag.indexOf('date') > -1) return acc + meta[val === 'desc' ? 'dateNew' : 'dateOld'];
|
|
if (lastTag === 'disabled') return acc + meta[val === 'desc' ? 'enabled' : 'disabled'] + meta['labelFirst'];
|
|
if (lastTag !== 'title') return acc + meta[val === 'desc' ? 'labelLast' : 'labelFirst'];
|
|
return acc + (meta[val] || '');
|
|
}, '');
|
|
opt.value = sort;
|
|
renderBin.appendChild(opt);
|
|
});
|
|
select.appendChild(renderBin);
|
|
select.value = prefs.get('manage.newUI.sort');
|
|
}
|
|
|
|
function sortStyles({styles, parser}) {
|
|
if (!styles) {
|
|
styles = [...installed.children];
|
|
parser = 'entry';
|
|
} else {
|
|
parser = 'style';
|
|
}
|
|
const sortBy = prefs.get('manage.newUI.sort').split(sortByRegex); // 'title,asc'
|
|
const len = sortBy.length;
|
|
return styles.sort((a, b) => {
|
|
let types, direction;
|
|
let result = 0;
|
|
let indx = 0;
|
|
// multi-sort
|
|
while (result === 0 && indx < len) {
|
|
types = tagData[sortBy[indx++]];
|
|
direction = sortBy[indx++] === 'asc' ? 1 : -1;
|
|
result = types.sorter(types.parse[parser](a), types.parse[parser](b)) * direction;
|
|
}
|
|
return result;
|
|
});
|
|
}
|
|
|
|
function manageSort(event) {
|
|
event.preventDefault();
|
|
prefs.set('manage.newUI.sort', this.value);
|
|
updateSort();
|
|
}
|
|
|
|
function updateSort() {
|
|
debounce(() => {
|
|
const renderBin = document.createDocumentFragment();
|
|
const entries = sortStyles({parser: 'entry'});
|
|
for (const entry of entries) {
|
|
renderBin.appendChild(entry);
|
|
}
|
|
installed.appendChild(renderBin);
|
|
updateStripes();
|
|
});
|
|
}
|
|
|
|
function showSortHelp(event) {
|
|
event.preventDefault();
|
|
messageBox({
|
|
className: 'help-text',
|
|
title: t('sortStylesHelpTitle'),
|
|
contents:
|
|
$create('div',
|
|
t('sortStylesHelp').split('\n').map(line =>
|
|
$create('p', line))),
|
|
buttons: [t('confirmOK')],
|
|
});
|
|
}
|
|
|
|
function sortInit() {
|
|
$('#options select').addEventListener('change', manageSort);
|
|
$('#sorter-help').onclick = showSortHelp;
|
|
addSortOptions();
|
|
}
|