diff --git a/editions/prerelease/tiddlywiki.info b/editions/prerelease/tiddlywiki.info index d29305576..7cfc207af 100644 --- a/editions/prerelease/tiddlywiki.info +++ b/editions/prerelease/tiddlywiki.info @@ -14,7 +14,8 @@ "tiddlywiki/external-attachments", "tiddlywiki/dynaview", "tiddlywiki/codemirror", - "tiddlywiki/comments" + "tiddlywiki/comments", + "tiddlywiki/browser-storage" ], "themes": [ "tiddlywiki/vanilla", diff --git a/plugins/tiddlywiki/browser-storage/plugin.info b/plugins/tiddlywiki/browser-storage/plugin.info new file mode 100644 index 000000000..23b22b983 --- /dev/null +++ b/plugins/tiddlywiki/browser-storage/plugin.info @@ -0,0 +1,7 @@ +{ + "title": "$:/plugins/tiddlywiki/browser-storage", + "description": "Local storage in the browser", + "author": "Jeremy Ruston ", + "core-version": ">=5.0.0", + "list": "readme" +} diff --git a/plugins/tiddlywiki/browser-storage/rawmarkup.js b/plugins/tiddlywiki/browser-storage/rawmarkup.js new file mode 100644 index 000000000..7aa273211 --- /dev/null +++ b/plugins/tiddlywiki/browser-storage/rawmarkup.js @@ -0,0 +1,63 @@ +/*\ +title: $:/plugins/tiddlywiki/browser-storage/rawmarkup.js +type: application/javascript +module-type: library + +Startup code injected as raw markup + +\*/ + +(function() { + +// Need to initialise these because we run before bootprefix.js and boot.js +$tw = window.$tw || Object.create(null); +$tw.hooks = $tw.hooks || { names: {}}; + +// Hook the point in the startup process when the tiddlers have been loaded but plugins not unpacked +var hookName = "th-boot-tiddlers-loaded"; +if(Object.prototype.hasOwnProperty.call($tw.hooks.names,hookName)) { + $tw.hooks.names[hookName].push(hookBootTiddlersLoaded); +} else { + $tw.hooks.names[hookName] = [hookBootTiddlersLoaded]; +} + +// Load tiddlers from browser storage +function hookBootTiddlersLoaded() { + var url = window.location.protocol === "file:" ? window.location.pathname : ""; + // Step through each browsder storage item + for(var index=0; index` +{{$:/plugins/tiddlywiki/browser-storage/rawmarkup.js}} +`` diff --git a/plugins/tiddlywiki/browser-storage/readme.tid b/plugins/tiddlywiki/browser-storage/readme.tid new file mode 100644 index 000000000..1e0fc1521 --- /dev/null +++ b/plugins/tiddlywiki/browser-storage/readme.tid @@ -0,0 +1,18 @@ +title: $:/plugins/tiddlywiki/browser-storage/readme + +This plugin enables TiddlyWiki to save tiddlers in [[browser local storage|https://en.wikipedia.org/wiki/Web_storage#localStorage]]. This means that changes are stored within the browser, and automatically re-applied any time the base wiki is reloaded. + +At startup, the plugin reads tiddlers from local storage. Any tiddlers that are identical to those built into the file are deleted from local storage. Once the wiki is up and running, any tiddler changes are written straight to local storage. + +Browser local storage is not a panacea for TiddlyWiki: + +* Browsers limit the amount of local storage available to a page, typically to 5 or 10MB +* Keeping personal data in browser local storage can lead to unexpected privacy violations +* Browsers reserve the right to without warning delete data stored in local storage at any time +* Browsers tie local storage to a URL which can lead to problems if you move a wiki to a URL previously occupied by a different wiki + +Please use this plugin with caution. There are a number of unresolved issues and open questions: + +* An "red screen of embarrassment" error is raised when local storage is full +* Innerwikis read the local storage of their parent wikis +* This plugin does not interfere with the existing saver mechanism, so you'll still get warnings when refreshing the page, even if your changes are safely committed to local storage diff --git a/plugins/tiddlywiki/browser-storage/startup.js b/plugins/tiddlywiki/browser-storage/startup.js new file mode 100644 index 000000000..dd8ceab49 --- /dev/null +++ b/plugins/tiddlywiki/browser-storage/startup.js @@ -0,0 +1,41 @@ +/*\ +title: $:/plugins/tiddlywiki/browser-storage/startup.js +type: application/javascript +module-type: startup + +Startup initialisation + +\*/ +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +// Export name and synchronous status +exports.name = "browser-storage"; +exports.platforms = ["browser"]; +exports.after = ["load-modules"]; +exports.synchronous = true; + +exports.startup = function() { + // Compute our prefix for local storage keys + var url = window.location.protocol === "file:" ? window.location.pathname : "", + prefix = "tw5#" + url + "#" + // Track tiddler changes + $tw.wiki.addEventListener("change",function(changes) { + $tw.utils.each(changes,function(change,title) { + var tiddler = $tw.wiki.getTiddler(title); + if(tiddler) { + var json = JSON.stringify(tiddler.getFieldStrings()); + window.localStorage.setItem(prefix + title,json); + console.log("browser-storage: Saving",title); + } else { + window.localStorage.removeItem(prefix + title); + console.log("browser-storage: Deleting",title); + } + }); + }); +}; + +})();