mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-08-27 19:42:50 +00:00
![Simon Baird](/assets/img/avatar_default.png)
* Show server response as error message in put saver I'd like to use this on Tiddlyhost so users can get more informative error messages if the put save fails for whatever reason. This would make the put saver a viable replacement for the legacy upload saver, which is what Tiddlyhost uses currently. I'm not sure what standard WebDAV servers do, but I would guess they don't provide any response body for put requests, and hence this patch would have no impact for a standard WebDAV server. (That said, it would be a good idea to test it to make sure there aren't any unexpected regressions for WebDAV or other put saver compatible services.) * Access http response status directly in put saver There's no need to extract it from the error string created inside tw.utils.httpRequest if we can get it directly from the xhr object. * Add 'Save starting' notification for put saver There are two related changes here: 1. Add a 'Save starting' notification for the put saver, similar to the upload saver. Not sure if it was intentionally omitted for the put saver, but it seems reasonable to have the two be consistent. 2. Send the 'Save starting' notifications in both upload and put save right before the actual request is sent. While testing I noticed that the save might have failed before the "Save starting" notification appeared which doesn't seem useful.
141 lines
3.1 KiB
JavaScript
141 lines
3.1 KiB
JavaScript
/*\
|
|
title: $:/core/modules/savers/put.js
|
|
type: application/javascript
|
|
module-type: saver
|
|
|
|
Saves wiki by performing a PUT request to the server
|
|
|
|
Works with any server which accepts a PUT request
|
|
to the current URL, such as a WebDAV server.
|
|
|
|
\*/
|
|
(function(){
|
|
|
|
/*jslint node: true, browser: true */
|
|
/*global $tw: false */
|
|
"use strict";
|
|
|
|
/*
|
|
Retrieve ETag if available
|
|
*/
|
|
var retrieveETag = function(self) {
|
|
var headers = {
|
|
Accept: "*/*;charset=UTF-8"
|
|
};
|
|
$tw.utils.httpRequest({
|
|
url: self.uri(),
|
|
type: "HEAD",
|
|
headers: headers,
|
|
callback: function(err,data,xhr) {
|
|
if(err) {
|
|
return;
|
|
}
|
|
var etag = xhr.getResponseHeader("ETag");
|
|
if(!etag) {
|
|
return;
|
|
}
|
|
self.etag = etag.replace(/^W\//,"");
|
|
}
|
|
});
|
|
};
|
|
|
|
|
|
/*
|
|
Select the appropriate saver module and set it up
|
|
*/
|
|
var PutSaver = function(wiki) {
|
|
this.wiki = wiki;
|
|
var self = this;
|
|
var uri = this.uri();
|
|
// Async server probe. Until probe finishes, save will fail fast
|
|
// See also https://github.com/Jermolene/TiddlyWiki5/issues/2276
|
|
$tw.utils.httpRequest({
|
|
url: uri,
|
|
type: "OPTIONS",
|
|
callback: function(err,data,xhr) {
|
|
// Check DAV header http://www.webdav.org/specs/rfc2518.html#rfc.section.9.1
|
|
if(!err) {
|
|
self.serverAcceptsPuts = xhr.status === 200 && !!xhr.getResponseHeader("dav");
|
|
}
|
|
}
|
|
});
|
|
retrieveETag(this);
|
|
};
|
|
|
|
PutSaver.prototype.uri = function() {
|
|
return document.location.toString().split("#")[0];
|
|
};
|
|
|
|
// TODO: in case of edit conflict
|
|
// Prompt: Do you want to save over this? Y/N
|
|
// Merging would be ideal, and may be possible using future generic merge flow
|
|
PutSaver.prototype.save = function(text,method,callback) {
|
|
if(!this.serverAcceptsPuts) {
|
|
return false;
|
|
}
|
|
var self = this;
|
|
var headers = {
|
|
"Content-Type": "text/html;charset=UTF-8"
|
|
};
|
|
if(this.etag) {
|
|
headers["If-Match"] = this.etag;
|
|
}
|
|
$tw.notifier.display("$:/language/Notifications/Save/Starting");
|
|
$tw.utils.httpRequest({
|
|
url: this.uri(),
|
|
type: "PUT",
|
|
headers: headers,
|
|
data: text,
|
|
callback: function(err,data,xhr) {
|
|
if(err) {
|
|
var status = xhr.status,
|
|
errorMsg = err;
|
|
if(status === 412) { // file changed on server
|
|
errorMsg = $tw.language.getString("Error/PutEditConflict");
|
|
} else if(status === 401) { // authentication required
|
|
errorMsg = $tw.language.getString("Error/PutUnauthorized");
|
|
} else if(status === 403) { // permission denied
|
|
errorMsg = $tw.language.getString("Error/PutForbidden");
|
|
}
|
|
if (xhr.responseText) {
|
|
// treat any server response like a plain text error explanation
|
|
errorMsg = errorMsg + "\n\n" + xhr.responseText;
|
|
}
|
|
callback(errorMsg); // fail
|
|
} else {
|
|
self.etag = xhr.getResponseHeader("ETag");
|
|
if(self.etag == null) {
|
|
retrieveETag(self);
|
|
}
|
|
callback(null); // success
|
|
}
|
|
}
|
|
});
|
|
return true;
|
|
};
|
|
|
|
/*
|
|
Information about this saver
|
|
*/
|
|
PutSaver.prototype.info = {
|
|
name: "put",
|
|
priority: 2000,
|
|
capabilities: ["save","autosave"]
|
|
};
|
|
|
|
/*
|
|
Static method that returns true if this saver is capable of working
|
|
*/
|
|
exports.canSave = function(wiki) {
|
|
return /^https?:/.test(location.protocol);
|
|
};
|
|
|
|
/*
|
|
Create an instance of this saver
|
|
*/
|
|
exports.create = function(wiki) {
|
|
return new PutSaver(wiki);
|
|
};
|
|
|
|
})();
|