From 403049692cfc9248f9c90aca021cb1c2fd9a4b5d Mon Sep 17 00:00:00 2001 From: Rob Garrison Date: Tue, 1 Jan 2019 20:10:38 -0600 Subject: [PATCH] Fix bulk updates --- background/update.js | 12 ++++++++---- manage.html | 2 +- manage/bulk-actions.js | 38 ++++++++++++++++++++++---------------- manage/manage-actions.js | 8 +++++--- manage/manage-ui.js | 6 +++--- manage/updater-ui.js | 21 +++++++++++++++------ options/options.js | 2 +- 7 files changed, 55 insertions(+), 34 deletions(-) diff --git a/background/update.js b/background/update.js index 2a0e02a7..10177550 100644 --- a/background/update.js +++ b/background/update.js @@ -31,7 +31,7 @@ const retrying = new Set(); - API_METHODS.updateCheckAll = checkAllStyles; + API_METHODS.updateCheckBulk = checkBulkStyles; API_METHODS.updateCheck = checkStyle; API_METHODS.getUpdaterStates = () => STATES; @@ -39,18 +39,22 @@ schedule(); chrome.alarms.onAlarm.addListener(onAlarm); - return {checkAllStyles, checkStyle, STATES}; + return {checkBulkStyles, checkStyle, STATES}; - function checkAllStyles({ + function checkBulkStyles({ save = true, ignoreDigest, observe, + styleIds = [], } = {}) { resetInterval(); checkingAll = true; retrying.clear(); const port = observe && chrome.runtime.connect({name: 'updater'}); return styleManager.getAllStyles().then(styles => { + if (styleIds.length) { + styles = styles.filter(style => styleIds.includes(style.id)); + } styles = styles.filter(style => style.updateUrl); if (port) port.postMessage({count: styles.length}); log(''); @@ -247,7 +251,7 @@ } function onAlarm({name}) { - if (name === ALARM_NAME) checkAllStyles(); + if (name === ALARM_NAME) checkBulkStyles(); } function resetInterval() { diff --git a/manage.html b/manage.html index c55c676d..3035e9b6 100644 --- a/manage.html +++ b/manage.html @@ -427,7 +427,7 @@ - + diff --git a/manage/bulk-actions.js b/manage/bulk-actions.js index 4b7645d3..f6032cff 100644 --- a/manage/bulk-actions.js +++ b/manage/bulk-actions.js @@ -1,4 +1,4 @@ -/* global $ $$ API t prefs handleEvent installed exportToFile checkUpdate exportDropbox +/* global $ $$ API t prefs handleEvent installed exportToFile checkUpdateBulk exportDropbox messageBox */ /* exported bulk */ 'use strict'; @@ -11,6 +11,16 @@ const bulk = { $('#bulk-actions-apply').onclick = bulk.handleApply; }, + checkApply: () => { + const checkedEntries = $$('.entry-filter-toggle').filter(entry => entry.checked); + if (checkedEntries.length > 0 && $('#bulk-actions-select').value !== '') { + $('#bulk-actions-apply').removeAttribute('disabled'); + } else { + $('#bulk-actions-apply').setAttribute('disabled', true); + } + $('#bulk-filter-count').textContent = checkedEntries.length || ''; + }, + handleSelect: event => { event.preventDefault(); $$('[data-bulk]').forEach(el => el.classList.add('hidden')); @@ -60,22 +70,25 @@ const bulk = { return exportToFile(styles); } case 'update': - styles = entries.map(entry => entry.styleMeta); - checkUpdate(styles); // TO DO: don't check all styles + checkUpdateBulk(); break; // case 'reset': // break; - case 'delete': + case 'delete': { styles = entries.reduce((acc, entry) => { const style = entry.styleMeta; - acc[style.name] = style.id; + acc[style.id] = style.name; return acc; }, {}); bulk.deleteBulk(event, styles); - $('#toggle-all-filters').checked = false; + const toggle = $('#toggle-all-filters'); + toggle.checked = false; + toggle.indeterminate = false; break; + } } $('#bulk-actions-select').value = ''; + $('#bulk-actions-apply').setAttribute('disabled', true); }, updateBulkFilters: ({target}) => { @@ -102,27 +115,20 @@ const bulk = { } } } - const count = $$('.entry-filter-toggle').filter(entry => entry.checked).length; - $('#bulk-filter-count').textContent = count || ''; - - if (count > 0 && $('#bulk-actions-select').value !== '') { - $('#bulk-actions-apply').removeAttribute('disabled'); - } else { - $('#bulk-actions-apply').setAttribute('disabled', true); - } + bulk.checkApply(); } }, deleteBulk: (event, styles) => { messageBox({ title: t('deleteStyleConfirm'), - contents: Object.keys(styles).join(', '), + contents: Object.values(styles).join(', '), className: 'danger center', buttons: [t('confirmDelete'), t('confirmCancel')], }) .then(({button}) => { if (button === 0) { - Object.values(styles).forEach(id => API.deleteStyle(id)); + Object.keys(styles).forEach(id => API.deleteStyle(Number(id))); installed.dataset.total -= Object.keys(styles).length; bulk.updateBulkFilters({target: $('#toggle-all-filters')}); } diff --git a/manage/manage-actions.js b/manage/manage-actions.js index 47a1d368..bd12fc70 100644 --- a/manage/manage-actions.js +++ b/manage/manage-actions.js @@ -8,7 +8,7 @@ global messageBox getStyleWithNoCode URLS enforceInputRange t getOwnTab getActiveTab openURL animateElement sessionStorageHash debounce scrollElementIntoView FIREFOX - UI + UI bulk */ /* exported updateInjectionOrder */ 'use strict'; @@ -305,7 +305,7 @@ Object.assign(handleEvent, { }); } }).then(() => { - const box = $('#message-box') + const box = $('#message-box'); box.removeEventListener('change', handleEvent.manageFavicons); box.removeEventListener('input', handleEvent.manageFavicons); }); @@ -339,6 +339,8 @@ function handleUpdate(style, {reason, method} = {}) { } entry = entry || UI.createStyleElement({style}); if (oldEntry) { + // Make sure to update the filter checkbox since it's state isn't saved to the style + $('.entry-filter-toggle', entry).checked = $('.entry-filter-toggle', oldEntry).checked; if (oldEntry.styleNameLowerCase === entry.styleNameLowerCase) { installed.replaceChild(entry, oldEntry); } else { @@ -349,6 +351,7 @@ function handleUpdate(style, {reason, method} = {}) { handleUpdateInstalled(entry, reason); } filterAndAppend({entry}).then(sorter.update); + if (!entry.matches('.hidden') && reason !== 'import') { animateElement(entry); requestAnimationFrame(() => scrollElementIntoView(entry)); @@ -421,7 +424,6 @@ function switchUI({styleOnly} = {}) { for (const targets of $$('.entry .targets')) { const items = $$('.target', targets); const extra = $('.applies-to-extra', targets); - const x = items.length === 54; items.splice(0, UI.targets).forEach(el => { if (!el.parentElement.classList.contains('targets')) { targets.insertBefore(el, extra); diff --git a/manage/manage-ui.js b/manage/manage-ui.js index abfdb32e..b5be23db 100644 --- a/manage/manage-ui.js +++ b/manage/manage-ui.js @@ -32,13 +32,13 @@ const UI = { $('.ext-version').textContent = `v${chrome.runtime.getManifest().version}`; // translate CSS manually + // #update-all-no-updates[data-skipped-edited="true"]::after { + // content: " ${t('updateAllCheckSucceededSomeEdited')}"; + // } document.head.appendChild($create('style', ` body.all-styles-hidden-by-filters #installed:after { content: "${t('filteredStylesAllHidden')}"; } - #update-all-no-updates[data-skipped-edited="true"]::after { - content: " ${t('updateAllCheckSucceededSomeEdited')}"; - } `)); }, diff --git a/manage/updater-ui.js b/manage/updater-ui.js index 94ea9f06..24dd6264 100644 --- a/manage/updater-ui.js +++ b/manage/updater-ui.js @@ -3,9 +3,10 @@ /* exported handleUpdateInstalled */ 'use strict'; +let updateTimer; + onDOMready().then(() => { - // $('#check-all-updates').onclick = checkUpdateAll; - $('#check-all-updates-force').onclick = checkUpdateAll; + $('#check-all-updates-force').onclick = checkUpdateBulk; $('#apply-all-updates').onclick = applyUpdateAll; $('#update-history').onclick = showUpdateHistory; }); @@ -27,17 +28,18 @@ function applyUpdateAll() { } -function checkUpdateAll() { +function checkUpdateBulk() { + clearTimeout(updateTimer); document.body.classList.add('update-in-progress'); // const btnCheck = $('#check-all-updates'); const btnCheckForce = $('#check-all-updates-force'); const btnApply = $('#apply-all-updates'); const noUpdates = $('#update-all-no-updates'); + const styleIds = $$('.entry-filter-toggle:checked').map(el => el.closest('.entry').styleMeta.id); // btnCheck.disabled = true; btnCheckForce.classList.add('hidden'); btnApply.classList.add('hidden'); noUpdates.classList.add('hidden'); - const ignoreDigest = this && this.id === 'check-all-updates-force'; $$('.updatable:not(.can-update)' + (ignoreDigest ? '' : ':not(.update-problem)')) .map(checkUpdate); @@ -53,10 +55,11 @@ function checkUpdateAll() { chrome.runtime.onConnect.removeListener(onConnect); }); - API.updateCheckAll({ + API.updateCheckBulk({ save: false, observe: true, ignoreDigest, + styleIds, }); function observer(info, port) { @@ -86,9 +89,15 @@ function checkUpdateAll() { btnApply.disabled = false; renderUpdatesOnlyFilter({check: updated + skippedEdited > 0}); if (!updated) { - noUpdates.dataset.skippedEdited = skippedEdited > 0; + if (skippedEdited > 0) { + noUpdates.dataset.title = t('updateAllCheckSucceededSomeEdited'); + } noUpdates.classList.remove('hidden'); btnCheckForce.classList.toggle('hidden', skippedEdited === 0); + updateTimer = setTimeout(() => { + noUpdates.classList.add('hidden'); + noUpdates.dataset.title = ''; + }, 1e4); } } } diff --git a/options/options.js b/options/options.js index d5ab0ce3..0328641f 100644 --- a/options/options.js +++ b/options/options.js @@ -187,7 +187,7 @@ function checkUpdates() { chrome.runtime.onConnect.removeListener(onConnect); }); - API.updateCheckAll({observe: true}); + API.updateCheckBulk({observe: true}); function observer(info) { if ('count' in info) {