diff --git a/_locales/en/messages.json b/_locales/en/messages.json index 5575b2ec..3c5964f3 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -1056,6 +1056,10 @@ "message": "Styles before commands", "description": "Label for the checkbox controlling section order in the popup." }, + "popupAutoResort": { + "message": "Resort styles in popup after toggling", + "description": "Label for the checkbox controlling popup resorting." + }, "prefShowBadge": { "message": "Number of styles active for the current site", "description": "Label for the checkbox controlling toolbar badge text." diff --git a/js/prefs.js b/js/prefs.js index 3e30d600..962a7ecf 100644 --- a/js/prefs.js +++ b/js/prefs.js @@ -18,6 +18,7 @@ const prefs = (() => { 'popup.breadcrumbs.usePath': false, // use URL path for 'this URL' 'popup.enabledFirst': true, // display enabled styles before disabled styles 'popup.stylesFirst': true, // display enabled styles before disabled styles + 'popup.autoResort': false, // auto resort styles after toggling 'popup.borders': false, // add white borders on the sides 'popup.findStylesInline': true, // use the inline style search diff --git a/options.html b/options.html index d20834b5..bee5654e 100644 --- a/options.html +++ b/options.html @@ -101,6 +101,13 @@ <span></span> </span> </label> + <label> + <span i18n-text="popupAutoResort"></span> + <span class="onoffswitch"> + <input type="checkbox" id="popup.autoResort" class="slider"> + <span></span> + </span> + </label> <label class="chromium-only"> <span i18n-text="popupBorders" i18n-title="popupBordersTooltip"></span> <span class="onoffswitch"> diff --git a/popup/popup.js b/popup/popup.js index a409e4c0..ccc3acbc 100644 --- a/popup/popup.js +++ b/popup/popup.js @@ -218,6 +218,15 @@ function initPopup() { } +function sortStyles(entries) { + const enabledFirst = prefs.get('popup.enabledFirst'); + entries.sort((a, b) => + enabledFirst && a.styleMeta.enabled !== b.styleMeta.enabled ? + (a.styleMeta.enabled ? -1 : 1) : + a.styleMeta.name.localeCompare(b.styleMeta.name) + ); +} + function showStyles(styles) { if (!styles) { return; @@ -227,25 +236,26 @@ function showStyles(styles) { window.dispatchEvent(new Event('showStyles:done')); return; } - - const enabledFirst = prefs.get('popup.enabledFirst'); - styles.sort((a, b) => ( - enabledFirst && a.enabled !== b.enabled - ? !(a.enabled < b.enabled) ? -1 : 1 - : a.name.localeCompare(b.name) - )); - - const container = document.createDocumentFragment(); - styles.forEach(style => createStyleElement({style, container})); - installed.appendChild(container); + const entries = styles.map(createStyleElement); + sortStyles(entries); + entries.forEach(e => installed.appendChild(e)); window.dispatchEvent(new Event('showStyles:done')); } +function sortStylesInPlace() { + if (!prefs.get('popup.autoResort')) { + return; + } + const entries = $$('.entry', installed); + if (!entries.length) { + return; + } + sortStyles(entries); + entries.forEach(e => installed.appendChild(e)); +} -function createStyleElement({ - style, - container = installed, -}) { + +function createStyleElement(style) { let entry = $(ENTRY_ID_PREFIX + style.id); if (!entry) { entry = template.style.cloneNode(true); @@ -319,9 +329,7 @@ function createStyleElement({ entry.classList.toggle('not-applied', style.excluded || style.sloppy); entry.classList.toggle('regexp-partial', style.sloppy); - if (entry.parentNode !== container) { - container.appendChild(entry); - } + return entry; } @@ -343,7 +351,9 @@ Object.assign(handleEvent, { toggle(event) { // when fired on checkbox, prevent the parent label from seeing the event, see #501 event.stopPropagation(); - API.toggleStyle(handleEvent.getClickedStyleId(event), this.checked); + API + .toggleStyle(handleEvent.getClickedStyleId(event), this.checked) + .then(sortStylesInPlace); }, delete(event) { @@ -475,12 +485,12 @@ function handleUpdate({style, reason}) { return; } if ($(ENTRY_ID_PREFIX + style.id)) { - createStyleElement({style}); + createStyleElement(style); return; } document.body.classList.remove('blocked'); $$.remove('.blocked-info, #no-styles'); - createStyleElement({style}); + createStyleElement(style); }) .catch(console.error);