mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-23 10:07:19 +00:00
Savetrails: Download before and after files for destructive modifications
This commit is contained in:
parent
97e995e0c7
commit
3d8249dc7a
@ -1,3 +0,0 @@
|
||||
title: $:/config/SaveTrailPlugin/save-filter
|
||||
|
||||
[is[tiddler]] -[[$:/HistoryList]] -[[$:/StoryList]] -[prefix[$:/config/]] -[prefix[$:/temp/]] -[prefix[$:/state/]] -[prefix[$:/status/]]
|
@ -0,0 +1,3 @@
|
||||
title: $:/config/SaveTrailPlugin/sync-drafts-filter
|
||||
|
||||
[is[tiddler]has[draft.of]]
|
@ -1,13 +1,20 @@
|
||||
title: $:/plugins/tiddlywiki/savetrail/readme
|
||||
|
||||
This plugin causes TiddlyWiki to continuously save the contents of each tiddler that is changed as a JSON file. Configured correctly, the browser will download the files silently in the background, and they can be used as a backup in case of accidental data loss.
|
||||
This plugin causes TiddlyWiki to continuously download (as a JSON file) the contents of each tiddler that is changed through any means:
|
||||
|
||||
* Confirming an edit
|
||||
* Deleting tiddlers
|
||||
* Imports
|
||||
* Renames/relinks
|
||||
|
||||
Where appropriate, separate 'before' and 'after' files are downloaded. Configured correctly, the browser will download the files silently in the background, and they can be used as a backup in case of accidental data loss.
|
||||
|
||||
''CAUTION'': Using this plugin will generate a //lot// of files in your downloads folder! Some points to watch:
|
||||
|
||||
* This plugin is pretty much unusable unless your browser is set up to download files automatically, without prompting for the location
|
||||
* Automatic file downloading doesn't work in all browsers - in particular, Safari and Internet Explorer do not currently support the [[necessary HTML5 feature|http://caniuse.com/download]]
|
||||
* Be aware of the privacy implications of leaving a plaintext trail of all of your edits. You should only enable this plugin on computers that your trust and with content that is not sensitive
|
||||
* The plugin uses the tiddler title plus a timestamp to generate a filename for the downloaded file, but some browsers don't respect
|
||||
* The plugin uses the tiddler title plus a timestamp to generate a filename for the downloaded file, but some browsers ignore the specified title and generate their own title for each downloaded file
|
||||
|
||||
Other points to note:
|
||||
|
||||
|
@ -19,19 +19,55 @@ exports.after = ["startup"];
|
||||
exports.synchronous = true;
|
||||
|
||||
// Favicon tiddler
|
||||
var SAVE_FILTER_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/save-filter",
|
||||
ENABLE_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable",
|
||||
ENABLE_DRAFTS_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable-drafts";
|
||||
var ENABLE_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable",
|
||||
ENABLE_DRAFTS_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable-drafts",
|
||||
SYNC_DRAFTS_FILTER_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/sync-drafts-filter";
|
||||
|
||||
exports.startup = function() {
|
||||
$tw.savetrail = $tw.savetrail || {};
|
||||
// Create a syncer to handle autosaving
|
||||
$tw.savetrail.syncadaptor = new SaveTrailSyncAdaptor();
|
||||
$tw.savetrail.syncer = new $tw.Syncer({
|
||||
wiki: $tw.wiki,
|
||||
syncadaptor: $tw.savetrail.syncadaptor,
|
||||
titleSyncFilter: SAVE_FILTER_TIDDLER_TITLE,
|
||||
titleSyncFilter: SYNC_DRAFTS_FILTER_TIDDLER_TITLE,
|
||||
logging: false
|
||||
});
|
||||
// Add hooks for trapping user actions
|
||||
$tw.hooks.addHook("th-saving-tiddler",function(tiddler) {
|
||||
var oldTiddler = $tw.wiki.getTiddler(tiddler.fields.title);
|
||||
if(oldTiddler) {
|
||||
saveTiddlerFile(oldTiddler,{reason: "overwritten"});
|
||||
}
|
||||
saveTiddlerFile(tiddler,{reason: "saved"});
|
||||
return tiddler;
|
||||
});
|
||||
$tw.hooks.addHook("th-renaming-tiddler",function(newTiddler,oldTiddler) {
|
||||
if(oldTiddler) {
|
||||
saveTiddlerFile(oldTiddler,{reason: "deleted"});
|
||||
}
|
||||
saveTiddlerFile(newTiddler,{reason: "renamed"});
|
||||
return newTiddler;
|
||||
});
|
||||
$tw.hooks.addHook("th-relinking-tiddler",function(newTiddler,oldTiddler) {
|
||||
if(oldTiddler) {
|
||||
saveTiddlerFile(oldTiddler,{reason: "overwritten"});
|
||||
}
|
||||
saveTiddlerFile(newTiddler,{reason: "relinked"});
|
||||
return newTiddler;
|
||||
});
|
||||
$tw.hooks.addHook("th-importing-tiddler",function(tiddler) {
|
||||
var oldTiddler = $tw.wiki.getTiddler(tiddler.fields.title);
|
||||
if(oldTiddler) {
|
||||
saveTiddlerFile(oldTiddler,{reason: "overwritten"});
|
||||
}
|
||||
saveTiddlerFile(tiddler,{reason: "imported"});
|
||||
return tiddler;
|
||||
});
|
||||
$tw.hooks.addHook("th-deleting-tiddler",function(tiddler) {
|
||||
saveTiddlerFile(tiddler,{reason: "deleted"});
|
||||
return tiddler;
|
||||
});
|
||||
};
|
||||
|
||||
function SaveTrailSyncAdaptor(options) {
|
||||
@ -53,10 +89,10 @@ SaveTrailSyncAdaptor.prototype.getTiddlerInfo = function(tiddler) {
|
||||
Save a tiddler and invoke the callback with (err,adaptorInfo,revision)
|
||||
*/
|
||||
SaveTrailSyncAdaptor.prototype.saveTiddler = function(tiddler,callback) {
|
||||
if($tw.wiki.getTiddlerText(ENABLE_TIDDLER_TITLE).toLowerCase() === "yes") {
|
||||
if($tw.wiki.checkTiddlerText(ENABLE_TIDDLER_TITLE,"yes")) {
|
||||
var isDraft = $tw.utils.hop(tiddler.fields,"draft.of");
|
||||
if(!isDraft || $tw.wiki.getTiddlerText(ENABLE_DRAFTS_TIDDLER_TITLE).toLowerCase() === "yes") {
|
||||
saveTiddlerFile(tiddler);
|
||||
if(!isDraft || $tw.wiki.checkTiddlerText(ENABLE_DRAFTS_TIDDLER_TITLE,"yes")) {
|
||||
saveTiddlerFile(tiddler,{reason: "modified"});
|
||||
}
|
||||
}
|
||||
callback(null);
|
||||
@ -64,8 +100,6 @@ SaveTrailSyncAdaptor.prototype.saveTiddler = function(tiddler,callback) {
|
||||
|
||||
/*
|
||||
Load a tiddler and invoke the callback with (err,tiddlerFields)
|
||||
|
||||
We don't need to implement loading for the file system adaptor, because all the tiddler files will have been loaded during the boot process.
|
||||
*/
|
||||
SaveTrailSyncAdaptor.prototype.loadTiddler = function(title,callback) {
|
||||
callback(null,null);
|
||||
@ -78,11 +112,13 @@ SaveTrailSyncAdaptor.prototype.deleteTiddler = function(title,callback,options)
|
||||
callback(null);
|
||||
};
|
||||
|
||||
function saveTiddlerFile(tiddler) {
|
||||
var illegalFilenameCharacters = /<|>|\:|\"|\/|\\|\||\?|\*|\^|\s/g,
|
||||
function saveTiddlerFile(tiddler,options) {
|
||||
options = options || {};
|
||||
var reason = options.reason || "changed",
|
||||
illegalFilenameCharacters = /<|>|\:|\"|\/|\\|\||\?|\*|\^|\s/g,
|
||||
fixedTitle = tiddler.fields.title.replace(illegalFilenameCharacters,"_"),
|
||||
formattedDate = $tw.utils.stringifyDate(new Date()),
|
||||
filename = fixedTitle + "." + formattedDate + ".json",
|
||||
filename = fixedTitle + "." + formattedDate + "." + reason + ".json",
|
||||
fields = new Object();
|
||||
for(var field in tiddler.fields) {
|
||||
fields[field] = tiddler.getFieldString(field);
|
||||
|
@ -4,8 +4,3 @@ title: $:/plugins/tiddlywiki/savetrail/settings
|
||||
<$checkbox tiddler="$:/config/SaveTrailPlugin/enable" field="text" checked="yes" unchecked="no"> Enable automatic saving of modified tiddlers</$checkbox>
|
||||
|
||||
<$checkbox tiddler="$:/config/SaveTrailPlugin/enable-drafts" field="text" checked="yes" unchecked="no"> Include automatic saving of draft tiddlers (warning: generates a lot of download files)</$checkbox>
|
||||
|
||||
[[Filter|$:/config/SaveTrailPlugin/save-filter]] used to determine tiddlers that should be autosaved:
|
||||
|
||||
<$edit-text tiddler="$:/config/SaveTrailPlugin/save-filter" tag="textarea" class="tc-edit-texteditor"/>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user