Rovak / InlineAttachment

Easily paste and upload files/images in plain textareas
http://git.razko.nl/InlineAttachment
MIT License
618 stars 77 forks source link

WebDAV support #88

Open tbruckmaier opened 2 years ago

tbruckmaier commented 2 years ago

Thanks for this package, still perfectly usable 5 years after the last commit! It would be nice if uploading to WebDAV could be supported.

I have successfully implemented it, but the requests/response from and to WebDAV are quite different than the package currently supports. A proper pull request would need quite a bit of refactoring, and I am also not so sure how to stay backwards comptible.

Since I /only/ need WebDAV support, I have overridden the uploadFile method, maybe someone will find it useful or it can be included in the package core one day.

WebDAV uses a dynamic uploadUrl (uploading a file foo.jpg to https://example.com needs a PUT request to https://example.com/foo.jpg, while the file contents should not be encapsulated in any FormData, rendering uploadFieldName obsolete). The response does not contain any data, only the HTTP status code tells if the upload was successful. The resulting filename is the same as the request url, and cannot be extracted from the response.

This is my adaption of uploadFile, to support WebDAV (and only WebDAV), override it like this:

inlineAttachment.prototype.uploadFile = function(file) {

    var me = this,
      xhr = new XMLHttpRequest(),
      settings = this.settings,
      extension = settings.defaultExtension || settings.defualtExtension;

    // Attach the file. If coming from clipboard, add a default filename (only works in Chrome for now)
    // http://stackoverflow.com/questions/6664967/how-to-give-a-blob-uploaded-as-formdata-a-file-name
    if (file.name) {
      var fileNameMatches = file.name.match(/\.(.+)$/);
      if (fileNameMatches) {
        extension = fileNameMatches[1];
      }
    }

    var remoteFilename = "image-" + Date.now() + "." + extension;
    if (typeof settings.remoteFilename === 'function') {
      remoteFilename = settings.remoteFilename(file);
    }

    xhr.open('PUT', settings.uploadUrl + '/' + remoteFilename);

    xhr.onload = () => {
        var filename, newValue;
        if (xhr.status === 200 || xhr.status === 201 || xhr.status === 204) {
            filename = xhr.responseURL;
            newValue = this.settings.urlText.replace(this.filenameTag, filename);
        } else {
            newValue = "";
        }
        var text = this.editor.getValue().replace(this.lastValue, newValue);
        this.editor.setValue(text);
        return false;
    };
    xhr.send(file);
    return xhr;
};

// use it like regular
inlineAttachment.editors.codemirror4.attach(this.codeMirror, {
    progressText: '[[Uploading file...]]',
    urlText: '[[{filename}]]',
    uploadUrl: 'http://examplecom:8000/uploads',
});