mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-27 03:57:21 +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
|
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:
|
''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
|
* 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]]
|
* 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
|
* 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:
|
Other points to note:
|
||||||
|
|
||||||
|
@ -19,19 +19,55 @@ exports.after = ["startup"];
|
|||||||
exports.synchronous = true;
|
exports.synchronous = true;
|
||||||
|
|
||||||
// Favicon tiddler
|
// Favicon tiddler
|
||||||
var SAVE_FILTER_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/save-filter",
|
var ENABLE_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable",
|
||||||
ENABLE_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable",
|
ENABLE_DRAFTS_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable-drafts",
|
||||||
ENABLE_DRAFTS_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/enable-drafts";
|
SYNC_DRAFTS_FILTER_TIDDLER_TITLE = "$:/config/SaveTrailPlugin/sync-drafts-filter";
|
||||||
|
|
||||||
exports.startup = function() {
|
exports.startup = function() {
|
||||||
$tw.savetrail = $tw.savetrail || {};
|
$tw.savetrail = $tw.savetrail || {};
|
||||||
|
// Create a syncer to handle autosaving
|
||||||
$tw.savetrail.syncadaptor = new SaveTrailSyncAdaptor();
|
$tw.savetrail.syncadaptor = new SaveTrailSyncAdaptor();
|
||||||
$tw.savetrail.syncer = new $tw.Syncer({
|
$tw.savetrail.syncer = new $tw.Syncer({
|
||||||
wiki: $tw.wiki,
|
wiki: $tw.wiki,
|
||||||
syncadaptor: $tw.savetrail.syncadaptor,
|
syncadaptor: $tw.savetrail.syncadaptor,
|
||||||
titleSyncFilter: SAVE_FILTER_TIDDLER_TITLE,
|
titleSyncFilter: SYNC_DRAFTS_FILTER_TIDDLER_TITLE,
|
||||||
logging: false
|
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) {
|
function SaveTrailSyncAdaptor(options) {
|
||||||
@ -53,10 +89,10 @@ SaveTrailSyncAdaptor.prototype.getTiddlerInfo = function(tiddler) {
|
|||||||
Save a tiddler and invoke the callback with (err,adaptorInfo,revision)
|
Save a tiddler and invoke the callback with (err,adaptorInfo,revision)
|
||||||
*/
|
*/
|
||||||
SaveTrailSyncAdaptor.prototype.saveTiddler = function(tiddler,callback) {
|
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");
|
var isDraft = $tw.utils.hop(tiddler.fields,"draft.of");
|
||||||
if(!isDraft || $tw.wiki.getTiddlerText(ENABLE_DRAFTS_TIDDLER_TITLE).toLowerCase() === "yes") {
|
if(!isDraft || $tw.wiki.checkTiddlerText(ENABLE_DRAFTS_TIDDLER_TITLE,"yes")) {
|
||||||
saveTiddlerFile(tiddler);
|
saveTiddlerFile(tiddler,{reason: "modified"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback(null);
|
callback(null);
|
||||||
@ -64,8 +100,6 @@ SaveTrailSyncAdaptor.prototype.saveTiddler = function(tiddler,callback) {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
Load a tiddler and invoke the callback with (err,tiddlerFields)
|
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) {
|
SaveTrailSyncAdaptor.prototype.loadTiddler = function(title,callback) {
|
||||||
callback(null,null);
|
callback(null,null);
|
||||||
@ -78,11 +112,13 @@ SaveTrailSyncAdaptor.prototype.deleteTiddler = function(title,callback,options)
|
|||||||
callback(null);
|
callback(null);
|
||||||
};
|
};
|
||||||
|
|
||||||
function saveTiddlerFile(tiddler) {
|
function saveTiddlerFile(tiddler,options) {
|
||||||
var illegalFilenameCharacters = /<|>|\:|\"|\/|\\|\||\?|\*|\^|\s/g,
|
options = options || {};
|
||||||
|
var reason = options.reason || "changed",
|
||||||
|
illegalFilenameCharacters = /<|>|\:|\"|\/|\\|\||\?|\*|\^|\s/g,
|
||||||
fixedTitle = tiddler.fields.title.replace(illegalFilenameCharacters,"_"),
|
fixedTitle = tiddler.fields.title.replace(illegalFilenameCharacters,"_"),
|
||||||
formattedDate = $tw.utils.stringifyDate(new Date()),
|
formattedDate = $tw.utils.stringifyDate(new Date()),
|
||||||
filename = fixedTitle + "." + formattedDate + ".json",
|
filename = fixedTitle + "." + formattedDate + "." + reason + ".json",
|
||||||
fields = new Object();
|
fields = new Object();
|
||||||
for(var field in tiddler.fields) {
|
for(var field in tiddler.fields) {
|
||||||
fields[field] = tiddler.getFieldString(field);
|
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" 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>
|
<$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