diff options
author | toasted-nutbread <toasted-nutbread@users.noreply.github.com> | 2020-10-10 16:54:52 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-10 16:54:52 -0400 |
commit | 199dd7d763e259accb0301a4aa5621c7b1f948c8 (patch) | |
tree | 40fb12db9d33971118ea23b3c1f1c2707761b6d7 | |
parent | 3174f3c6578de7a525a629f1acd0d2f04d06da66 (diff) |
Storage controller refactor (#905)
* Use hidden instead of storage-hidden class
* Refactor storage events
* Make ID more generic
* Update how persistent storage is activated
* Add null checks
* Update HTML/ID
* Disallow disabling persistent storage
* Refactoring
* Update more IDs
* Disable multiple simultaneous stats updates
* Store node references
* Move undefined assignment
-rw-r--r-- | ext/bg/css/settings.css | 2 | ||||
-rw-r--r-- | ext/bg/js/settings/storage-controller.js | 107 | ||||
-rw-r--r-- | ext/bg/settings.html | 37 |
3 files changed, 98 insertions, 48 deletions
diff --git a/ext/bg/css/settings.css b/ext/bg/css/settings.css index 4a49b98d..9ec2e964 100644 --- a/ext/bg/css/settings.css +++ b/ext/bg/css/settings.css @@ -16,7 +16,7 @@ */ -.storage-hidden { +.help-block[hidden] { display: none; } diff --git a/ext/bg/js/settings/storage-controller.js b/ext/bg/js/settings/storage-controller.js index 24c6d7ef..0d58ce91 100644 --- a/ext/bg/js/settings/storage-controller.js +++ b/ext/bg/js/settings/storage-controller.js @@ -20,15 +20,35 @@ class StorageController { this._mostRecentStorageEstimate = null; this._storageEstimateFailed = false; this._isUpdating = false; + this._persistentStorageCheckbox = false; + this._storageUsageNode = null; + this._storageQuotaNode = null; + this._storageUseFiniteNode = null; + this._storageUseInfiniteNode = null; + this._storageUseUndefinedNode = null; + this._storageUseNode = null; + this._storageErrorNode = null; } prepare() { + this._persistentStorageCheckbox = document.querySelector('#storage-persistent-checkbox'); + this._storageUsageNode = document.querySelector('#storage-usage'); + this._storageQuotaNode = document.querySelector('#storage-quota'); + this._storageUseFiniteNode = document.querySelector('#storage-use-finite'); + this._storageUseInfiniteNode = document.querySelector('#storage-use-infinite'); + this._storageUseUndefinedNode = document.querySelector('#storage-use-undefined'); + this._storageUseNode = document.querySelector('#storage-use'); + this._storageErrorNode = document.querySelector('#storage-error'); + this._preparePersistentStorage(); this.updateStats(); + this._persistentStorageCheckbox.addEventListener('change', this._onPersistentStorageCheckboxChange.bind(this), false); document.querySelector('#storage-refresh').addEventListener('click', this.updateStats.bind(this), false); } async updateStats() { + if (this._isUpdating) { return; } + try { this._isUpdating = true; @@ -39,15 +59,16 @@ class StorageController { // Firefox reports usage as 0 when persistent storage is enabled. const finite = (estimate.usage > 0 || !(await this._isStoragePeristent())); if (finite) { - document.querySelector('#storage-usage').textContent = this._bytesToLabeledString(estimate.usage); - document.querySelector('#storage-quota').textContent = this._bytesToLabeledString(estimate.quota); + this._storageUsageNode.textContent = this._bytesToLabeledString(estimate.usage); + this._storageQuotaNode.textContent = this._bytesToLabeledString(estimate.quota); } - document.querySelector('#storage-use-finite').classList.toggle('storage-hidden', !finite); - document.querySelector('#storage-use-infinite').classList.toggle('storage-hidden', finite); + this._storageUseFiniteNode.hidden = !finite; + this._storageUseInfiniteNode.hidden = finite; } - document.querySelector('#storage-use').classList.toggle('storage-hidden', !valid); - document.querySelector('#storage-error').classList.toggle('storage-hidden', valid); + if (this._storageUseUndefinedNode !== null) { this._storageUseUndefinedNode.hidden = !valid; } + if (this._storageUseNode !== null) { this._storageUseNode.hidden = !valid; } + if (this._storageErrorNode !== null) { this._storageErrorNode.hidden = valid; } return valid; } finally { @@ -63,35 +84,53 @@ class StorageController { return; } - const info = document.querySelector('#storage-persist-info'); - const button = document.querySelector('#storage-persist-button'); - const checkbox = document.querySelector('#storage-persist-button-checkbox'); + const info = document.querySelector('#storage-persistent-info'); + if (info !== null) { info.hidden = false; } - info.classList.remove('storage-hidden'); - button.classList.remove('storage-hidden'); + const isStoragePeristent = await this._isStoragePeristent(); + this._updateCheckbox(isStoragePeristent); - let persisted = await this._isStoragePeristent(); - checkbox.checked = persisted; + const button = document.querySelector('#storage-persistent-button'); + if (button !== null) { + button.hidden = false; + button.addEventListener('click', this._onPersistStorageButtonClick.bind(this), false); + } + } - button.addEventListener('click', async () => { - if (persisted) { - return; - } - let result = false; - try { - result = await navigator.storage.persist(); - } catch (e) { - // NOP - } + _onPersistentStorageCheckboxChange(e) { + const node = e.currentTarget; + if (!node.checked) { + node.checked = true; + return; + } + this._attemptPersistStorage(); + } - if (result) { - persisted = true; - checkbox.checked = true; - this.updateStats(); - } else { - document.querySelector('.storage-persist-fail-warning').classList.remove('storage-hidden'); - } - }, false); + _onPersistStorageButtonClick() { + const {checked} = this._persistentStorageCheckbox; + if (checked) { return; } + this._persistentStorageCheckbox.checked = !checked; + this._persistentStorageCheckbox.dispatchEvent(new Event('change')); + } + + async _attemptPersistStorage() { + if (await this._isStoragePeristent()) { return; } + + let isStoragePeristent = false; + try { + isStoragePeristent = await navigator.storage.persist(); + } catch (e) { + // NOP + } + + this._updateCheckbox(isStoragePeristent); + + if (isStoragePeristent) { + this.updateStats(); + } else { + const node = document.querySelector('#storage-persistent-fail-warning'); + if (node !== null) { node.hidden = false; } + } } async _storageEstimate() { @@ -128,4 +167,10 @@ class StorageController { } return false; } + + _updateCheckbox(isStoragePeristent) { + const checkbox = this._persistentStorageCheckbox; + checkbox.checked = isStoragePeristent; + checkbox.readOnly = isStoragePeristent; + } } diff --git a/ext/bg/settings.html b/ext/bg/settings.html index 795cdd54..45ae172f 100644 --- a/ext/bg/settings.html +++ b/ext/bg/settings.html @@ -796,7 +796,7 @@ <h3>Storage</h3> </div> - <div id="storage-persist-info" class="storage-hidden"> + <div id="storage-persistent-info" hidden> <p class="help-block"> Web browsers may sometimes clear stored data if the device is running low on storage space. This can result in the stored dictionary data being deleted unexpectedly, causing Yomichan to stop working for no apparent reason. @@ -804,16 +804,19 @@ </p> </div> - <div id="storage-use" class="storage-hidden"> - <p class="help-block storage-hidden" id="storage-use-finite"> + <div id="storage-use" hidden> + <p class="help-block" id="storage-use-undefined"> + Yomichan is using an indeterminate amount of storage. + </p> + <p class="help-block" id="storage-use-finite" hidden> Yomichan is using approximately <strong id="storage-usage"></strong> of <strong id="storage-quota"></strong>. </p> - <p class="help-block storage-hidden" id="storage-use-infinite"> + <p class="help-block" id="storage-use-infinite" hidden> Yomichan is permitted <strong>unlimited storage</strong>. </p> </div> - <div id="storage-error" class="storage-hidden"> + <div id="storage-error" hidden> <p class="help-block"> Could not detect how much storage Yomichan is using. </p> @@ -832,22 +835,24 @@ <div> <button class="btn btn-default" id="storage-refresh"><span class="btn-inner-middle">Refresh</span></button> - <button class="btn btn-default storage-hidden ignore-form-changes" id="storage-persist-button"><span class="storage-button-inner"><input type="checkbox" class="btn-inner-middle storage-button-checkbox" id="storage-persist-button-checkbox" readonly /><span class="btn-inner-middle">Persistent Storage</span></span></button> + <button class="btn btn-default ignore-form-changes" id="storage-persistent-button" hidden><span class="storage-button-inner"><input type="checkbox" class="btn-inner-middle storage-button-checkbox" id="storage-persistent-checkbox" readonly /><span class="btn-inner-middle">Persistent Storage</span></span></button> </div> <p></p> - <div data-show-for-browser="firefox-mobile"><div class="alert alert-warning storage-persist-fail-warning storage-hidden"> - <p>It may not be possible to enable Persistent Storage on Firefox for Android.</p> - </div></div> + <div id="storage-persistent-fail-warning" hidden> + <div data-show-for-browser="firefox-mobile"><div class="alert alert-warning"> + <p>It may not be possible to enable Persistent Storage on Firefox for Android.</p> + </div></div> - <div data-show-for-browser="chrome"><div class="alert alert-warning storage-persist-fail-warning storage-hidden"> - <p> - It may not be possible to enable Persistent Storage on Chrome-based browsers. - However, the Yomichan extension has permission for unlimited storage which should - prevent Chrome from deleting data.<sup><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=680392#c15" target="_blank" rel="noopener">[1]</a></sup> - </p> - </div></div> + <div data-show-for-browser="chrome"><div class="alert alert-warning"> + <p> + It may not be possible to enable Persistent Storage on Chrome-based browsers. + However, the Yomichan extension has permission for unlimited storage which should + prevent Chrome from deleting data.<sup><a href="https://bugs.chromium.org/p/chromium/issues/detail?id=680392#c15" target="_blank" rel="noopener">[1]</a></sup> + </p> + </div></div> + </div> </div> <div> |