[IDEA] oncompletion/onerror support for tm-save-wiki and tm-download-file
tm-save-wiki and tm-download-file currently offer no way for a widget/message-level consumer to know whether a save actually succeeded or failed, or when it completed. I'd like to propose adding oncompletion/onerror action-string support to both messages, mirroring the pattern already established by tm-http-request and tm-save-dom-to-image.
Current behavior
SaverHandler.prototype.saveWiki (in core/modules/saver-handler.js) already distinguishes success from failure internally:
callback = function(err) {
if(err) {
alert($tw.language.getString("Error/WhileSaving") + ":\n\n" + err);
} else {
...
$tw.notifier.display(self.titleSavedNotification);
if(options.callback) {
options.callback();
}
}
};But options.callback is only reachable by calling saveWiki() directly from JS. The tm-save-wiki/tm-download-file event handlers registered in the constructor only forward filename/type from paramObject, there's no path from the WikiText/widget layer (<$action-sendmessage $message="tm-save-wiki">) to that callback at all.
As a result, the only externally observable signals of save outcome are side effects: a $tw.notifier.display($:/language/Notifications/Save/Done) call on success, or a plain alert() on failure. Reacting to these from a plugin requires monkey-patching window.alert/$tw.notifier.display, which is fragile: it's coupled to internal wording/behavior and risks false positives from unrelated alert()/notifier.display() calls happening elsewhere during the same window.
Proposed change
Add oncompletion and onerror action-string parameters to tm-save-wiki and tm-download-file, consistent with the existing convention used by tm-http-request:
$tw.rootWidget.addEventListener("tm-http-request",function(event) {
var params = event.paramObject || {};
$tw.httpClient.initiateHttpRequest({
...
oncompletion: params.oncompletion,
onprogress: params.onprogress,
...
});
});and by tm-save-dom-to-image:
self.wiki.invokeActionString(oncompletion,self,variables,{parentWidget: $tw.rootWidget});Concretely, this means:
- Threading
oncompletion/onerror(andvar-*passthrough variables, matching the existing convention) fromevent.paramObjectthrough tosaveWiki()'s options. - Inside
saveWiki()'scallback, invokingoptions.oncompletionon success andoptions.onerroron failure viawiki.invokeActionString(...), passing along astatus/errorvariable similar to whattm-http-requestprovides. - This is purely additive, the existing internal
options.callbackmechanism (used by direct JS callers) is untouched, and any wiki not using the new parameters sees no behavior change.
Why this is needed
I'm building a plugin (in-place upgrade) that rewrites the wiki's HTML shell (e.g. to bump the TiddlyWiki core version) and delivers the result through the user's existing saver via tm-save-wiki. This is an inherently risky, semi-destructive operation, so it matters a lot whether the save genuinely completed before telling the user it's safe to reload:
- Without a completion signal, a user could reload before an async save actually finishes, risking data loss.
- Without a failure signal, a failed save could be silently reported as successful.
But this isn't just about my plugin: any plugin doing autosave-driven workflows, "save then navigate/close" sequences, or "save then chain another action" patterns hits the same wall today, and has to either not bother (accepting the risk) or resort to monkey-patching core internals. Given tm-http-request and tm-save-dom-to-image both already establish this exact oncompletion/onerror/var-* convention, extending it to tm-save-wiki/tm-download-file would close a real, precedent-inconsistent gap in the messaging API, with no breaking changes and a fairly small, contained diff in saver-handler.js.
I'm happy to submit a PR implementing this if the maintainers are open to the approach. I wanted to propose it as a feature request first to confirm there isn't a design objection or existing plan that conflicts with it.
Source: TiddlyWiki/TiddlyWiki5