diff --git a/plugins/tiddlywiki/browser-storage/rawmarkup.js b/plugins/tiddlywiki/browser-storage/rawmarkup.js index ad788476b..bf7c41e0a 100644 --- a/plugins/tiddlywiki/browser-storage/rawmarkup.js +++ b/plugins/tiddlywiki/browser-storage/rawmarkup.js @@ -14,7 +14,6 @@ $tw = window.$tw || Object.create(null); $tw.hooks = $tw.hooks || { names: {}}; $tw.boot = $tw.boot || {}; $tw.boot.preloadDirty = $tw.boot.preloadDirty || []; - // 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)) { diff --git a/plugins/tiddlywiki/browser-storage/startup.js b/plugins/tiddlywiki/browser-storage/startup.js index 33989e8a7..69cc5119e 100644 --- a/plugins/tiddlywiki/browser-storage/startup.js +++ b/plugins/tiddlywiki/browser-storage/startup.js @@ -19,19 +19,29 @@ exports.after = ["startup"]; exports.synchronous = true; var ENABLED_TITLE = "$:/config/BrowserStorage/Enabled", - SAVE_FILTER_TITLE = "$:/config/BrowserStorage/SaveFilter", - QUOTA_EXCEEDED_ALERT_TITLE = "$:/config/BrowserStorage/QuotaExceededAlert", - DEFAULT_QUOTA_EXCEEDED_ALERT_PREFIX = "Quota exceeded attempting to store `", - DEFAULT_QUOTA_EXCEEDED_ALERT_SUFFIX = "` in browser local storage"; + SAVE_FILTER_TITLE = "$:/config/BrowserStorage/SaveFilter"; + +var BrowserStorageUtil = require("$:/plugins/tiddlywiki/browser-storage/util.js").BrowserStorageUtil; exports.startup = function() { var self = this; + + // If not exists, add ENABLED tiddler with default value "yes" + if(!$tw.wiki.getTiddler(ENABLED_TITLE)) { + $tw.wiki.addTiddler({title: ENABLED_TITLE, text: "yes"}); + } // Compute our prefix for local storage keys var prefix = "tw5#" + window.location.pathname + "#"; // Make a logger var logger = new $tw.utils.Logger("browser-storage",{ colour: "cyan" }); + // Add browserStorage object to $tw + $tw.browserStorage = new BrowserStorageUtil($tw.wiki,{ + enabledTitle: ENABLED_TITLE, + prefix: prefix, + logger: logger + }); // Function to compile the filter var filterFn, compileFilter = function() { @@ -41,7 +51,7 @@ exports.startup = function() { // Listen for tm-clear-browser-storage messages $tw.rootWidget.addEventListener("tm-clear-browser-storage",function(event) { $tw.wiki.addTiddler({title: ENABLED_TITLE, text: "no"}); - clearLocalStorage(); + $tw.browserStorage.clearLocalStorage(); }); // Track tiddler changes $tw.wiki.addEventListener("change",function(changes) { @@ -67,65 +77,9 @@ exports.startup = function() { return; } // Save the tiddler - saveTiddlerToLocalStorage(title,{ - logger: logger, - prefix: prefix - }); + $tw.browserStorage.saveTiddlerToLocalStorage(title); }); }); }; -function saveTiddlerToLocalStorage(title,options) { - options = options || {}; - // Get the tiddler - var tiddler = $tw.wiki.getTiddler(title); - if(tiddler) { - console.log("browser-storage: Saving",title); - // Get the JSON of the tiddler - var json = JSON.stringify(tiddler.getFieldStrings()); - // Try to save it to local storage - try { - window.localStorage.setItem(options.prefix + title,json); - } catch(e) { - if(e.name === "QuotaExceededError") { - // Complain if we failed - var msg = $tw.wiki.getTiddlerText(QUOTA_EXCEEDED_ALERT_TITLE,DEFAULT_QUOTA_EXCEEDED_ALERT_PREFIX + title + DEFAULT_QUOTA_EXCEEDED_ALERT_SUFFIX); - if(options.logger) { - options.logger.alert(msg); - } - // No point in keeping old values around for this tiddler - window.localStorage.removeItem(options.prefix + title); - } else { - console.log("Browser-storage error:",e); - } - } - } else { - // In local storage, use the special value of empty string to mark the tiddler as deleted - // On future page loads, if the tiddler is already gone from startup then the blank entry - // will be removed from localstorage. Otherwise, the tiddler will be deleted. - console.log("browser-storage: Blanking",title); - try { - window.localStorage.setItem(options.prefix + title, ""); - } catch(e) { - console.log("Browser-storage error:",e); - } - } -} - -function clearLocalStorage() { - var url = window.location.pathname, - log = []; - // Step through each browser storage item - if(window.localStorage) { - for(var index=window.localStorage.length - 1; index>=0; index--) { - var key = window.localStorage.key(index), - parts = key.split("#"); - // Delete it if it is ours - if(parts[0] === "tw5" && parts[1] === url) { - window.localStorage.removeItem(key); - } - } - } -} - })(); diff --git a/plugins/tiddlywiki/browser-storage/util.js b/plugins/tiddlywiki/browser-storage/util.js new file mode 100644 index 000000000..a88c358f6 --- /dev/null +++ b/plugins/tiddlywiki/browser-storage/util.js @@ -0,0 +1,106 @@ +/*\ +title: $:/plugins/tiddlywiki/browser-storage/util.js +type: application/javascript +module-type: library + +Utility methods for browser-storage plugin + +\*/ + +(function(){ + +/*jslint node: true, browser: true */ +/*global $tw: false */ +"use strict"; + +function BrowserStorageUtil(wiki,options) { + this.options = options || {}; + this.wiki = wiki; + this.cachedTiddlers = []; + this.QUOTA_EXCEEDED_ALERT_TITLE = "$:/config/BrowserStorage/QuotaExceededAlert"; + this.DEFAULT_QUOTA_EXCEEDED_ALERT_PREFIX = "Quota exceeded attempting to store `"; + this.DEFAULT_QUOTA_EXCEEDED_ALERT_SUFFIX = "` in browser local storage"; +} + +BrowserStorageUtil.prototype.isEnabled = function() { + return $tw.wiki.getTiddlerText(this.options.enabledTitle) === "yes"; +}; + +BrowserStorageUtil.prototype.cachePreloadTiddlers = function() { + var self = this; + $tw.utils.each($tw.boot.preloadDirty, function(item){ + var tiddler = $tw.wiki.getTiddler(item); + self.cachedTiddlers.push(tiddler); + }); +}; + +BrowserStorageUtil.prototype.addCachedTiddlers = function() { + var self = this; + if(this.cachedTiddlers.length > 0) { + $tw.utils.each(this.cachedTiddlers, function(item){ + $tw.wiki.addTiddler(item); + }); + this.cachedTiddlers.length = 0; + } +}; + +BrowserStorageUtil.prototype.removeTiddlerFromLocalStorage = function(title) { + console.log("browser-storage: Removing", title); + window.localStorage.removeItem(this.options.prefix + title); +}; + +BrowserStorageUtil.prototype.saveTiddlerToLocalStorage = function(title) { + // Get the tiddler + var tiddler = $tw.wiki.getTiddler(title); + if(tiddler) { + console.log("browser-storage: Saving",title); + // Get the JSON of the tiddler + var json = JSON.stringify(tiddler.getFieldStrings()); + // Try to save it to local storage + try { + window.localStorage.setItem(this.options.prefix + title,json); + } catch(e) { + if(e.name === "QuotaExceededError") { + // Complain if we failed + var msg = $tw.wiki.getTiddlerText(this.QUOTA_EXCEEDED_ALERT_TITLE,this.DEFAULT_QUOTA_EXCEEDED_ALERT_PREFIX + title + this.DEFAULT_QUOTA_EXCEEDED_ALERT_SUFFIX); + if(this.options.logger) { + this.options.logger.alert(msg); + } + // No point in keeping old values around for this tiddler + window.localStorage.removeItem(this.options.prefix + title); + } else { + console.log("Browser-storage error:",e); + } + } + } else { + // In local storage, use the special value of empty string to mark the tiddler as deleted + // On future page loads, if the tiddler is already gone from startup then the blank entry + // will be removed from localstorage. Otherwise, the tiddler will be deleted. + console.log("browser-storage: Blanking",title); + try { + window.localStorage.setItem(this.options.prefix + title, ""); + } catch(e) { + console.log("Browser-storage error:",e); + } + } +}; + +BrowserStorageUtil.prototype.clearLocalStorage = function() { + var url = window.location.pathname, + log = []; + // Step through each browser storage item + if(window.localStorage) { + for(var index=window.localStorage.length - 1; index>=0; index--) { + var key = window.localStorage.key(index), + parts = key.split("#"); + // Delete it if it is ours + if(parts[0] === "tw5" && parts[1] === url) { + window.localStorage.removeItem(key); + } + } + } +}; + +exports.BrowserStorageUtil = BrowserStorageUtil; + +})(); diff --git a/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js b/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js index 712077974..15fbaa4fd 100644 --- a/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js +++ b/plugins/tiddlywiki/tiddlyweb/tiddlywebadaptor.js @@ -76,6 +76,10 @@ TiddlyWebAdaptor.prototype.getStatus = function(callback) { if(err) { return callback(err); } + //If Browser-Storage plugin is present, cache pre-loaded tiddlers and add back after sync from server completes + if($tw.browserStorage && $tw.browserStorage.isEnabled()) { + $tw.browserStorage.cachePreloadTiddlers(); + } // Decode the status JSON var json = null; try { @@ -188,6 +192,10 @@ TiddlyWebAdaptor.prototype.getSkinnyTiddlers = function(callback) { } // Invoke the callback with the skinny tiddlers callback(null,tiddlers); + // If Browswer Storage tiddlers were cached on reloading the wiki, add them after sync from server completes in the above callback. + if($tw.browserStorage && $tw.browserStorage.isEnabled()) { + $tw.browserStorage.addCachedTiddlers(); + } } }); }; @@ -211,6 +219,10 @@ TiddlyWebAdaptor.prototype.saveTiddler = function(tiddler,callback,options) { if(err) { return callback(err); } + //If Browser-Storage plugin is present, remove tiddler from local storage after successful sync to the server + if($tw.browserStorage && $tw.browserStorage.isEnabled()) { + $tw.browserStorage.removeTiddlerFromLocalStorage(tiddler.fields.title) + } // Save the details of the new revision of the tiddler var etag = request.getResponseHeader("Etag"); if(!etag) {