Request permission to protect local storage from eviction (#7398)

* Request the browser to never evict the persistent storage

* Store browser storage persisted state in a tiddler

* Factor out some code into helper functions

* Display status of persistence request in the settings page
This commit is contained in:
btheado 2023-06-13 04:50:00 -05:00 committed by GitHub
parent 106f121133
commit 86d45f1c3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 58 additions and 1 deletions

View File

@ -28,6 +28,16 @@ This setting allows a custom alert message to be displayed when an attempt to st
<$link to="$:/config/BrowserStorage/QuotaExceededAlert">Quota Exceeded Alert</$link>: <$edit-text tiddler="$:/config/BrowserStorage/QuotaExceededAlert" default="" tag="input" size="50"/>
! Prevent browser from evicting local storage
Permission for local storage persistence: ''{{$:/info/browser/storage/persisted}}''
The first time a tiddler is saved to local storage a request will be made to prevent automatic eviction of local storage for this site. This means the data will not be cleared unless the user manually clears it.
Old browsers may not support this feature. New browsers might not support the feature if the wiki is hosted on a non-localhost unencrypted http connection.
Some browsers will explicitly prompt the user for permission. Other browsers may automatically grant or deny the request based on site usage or based on whether the site is bookmarked.
! Startup Log
The tiddler $:/temp/BrowserStorage/Log contains a log of the tiddlers that were loaded from local storage at startup:

View File

@ -19,7 +19,8 @@ exports.after = ["startup"];
exports.synchronous = true;
var ENABLED_TITLE = "$:/config/BrowserStorage/Enabled",
SAVE_FILTER_TITLE = "$:/config/BrowserStorage/SaveFilter";
SAVE_FILTER_TITLE = "$:/config/BrowserStorage/SaveFilter",
PERSISTED_STATE_TITLE = "$:/info/browser/storage/persisted";
var BrowserStorageUtil = require("$:/plugins/tiddlywiki/browser-storage/util.js").BrowserStorageUtil;
@ -53,6 +54,48 @@ exports.startup = function() {
$tw.wiki.addTiddler({title: ENABLED_TITLE, text: "no"});
$tw.browserStorage.clearLocalStorage();
});
// Helpers for protecting storage from eviction
var setPersistedState = function(state) {
$tw.wiki.addTiddler({title: PERSISTED_STATE_TITLE, text: state});
},
requestPersistence = function() {
setPersistedState("requested");
navigator.storage.persist().then(function(persisted) {
console.log("Request for persisted storage " + (persisted ? "granted" : "denied"));
setPersistedState(persisted ? "granted" : "denied");
});
},
persistPermissionRequested = false,
requestPersistenceOnFirstSave = function() {
$tw.hooks.addHook("th-saving-tiddler", function(tiddler) {
if (!persistPermissionRequested) {
var filteredChanges = filterFn.call($tw.wiki, function(iterator) {
iterator(tiddler,tiddler.getFieldString("title"));
});
if (filteredChanges.length > 0) {
// The tiddler will be saved to local storage, so request persistence
requestPersistence();
persistPermissionRequested = true;
}
}
return tiddler;
});
};
// Request the browser to never evict the localstorage. Some browsers such as firefox
// will prompt the user. To make the decision easier for the user only prompt them
// when they click the save button on a tiddler which will be stored to localstorage.
if (navigator.storage && navigator.storage.persist) {
navigator.storage.persisted().then(function(isPersisted) {
if (!isPersisted) {
setPersistedState("not requested yet");
requestPersistenceOnFirstSave();
} else {
setPersistedState("granted");
}
});
} else {
setPersistedState("feature not available");
}
// Track tiddler changes
$tw.wiki.addEventListener("change",function(changes) {
// Bail if browser storage is disabled
@ -76,6 +119,10 @@ exports.startup = function() {
if(title === ENABLED_TITLE) {
return;
}
// This should always be queried from the browser, so don't store it in local storage
if(title === PERSISTED_STATE_TITLE) {
return;
}
// Save the tiddler
$tw.browserStorage.saveTiddlerToLocalStorage(title);
});