mirror of
https://github.com/schollz/cowyo.git
synced 2023-08-10 21:13:00 +03:00
Add inline images
Still need to fix the POST URL
This commit is contained in:
parent
9d87359c62
commit
e1b0fec50c
449
static/js/inline-attachment.js
Normal file
449
static/js/inline-attachment.js
Normal file
@ -0,0 +1,449 @@
|
||||
/*! inline-attachment - v2.0.3 - 2016-08-20 */
|
||||
/*jslint newcap: true */
|
||||
/*global XMLHttpRequest: false, FormData: false */
|
||||
/*
|
||||
* Inline Text Attachment
|
||||
*
|
||||
* Author: Roy van Kaathoven
|
||||
* Contact: ik@royvankaathoven.nl
|
||||
*/
|
||||
(function(document, window) {
|
||||
'use strict';
|
||||
|
||||
var inlineAttachment = function(options, instance) {
|
||||
this.settings = inlineAttachment.util.merge(options, inlineAttachment.defaults);
|
||||
this.editor = instance;
|
||||
this.filenameTag = '{filename}';
|
||||
this.lastValue = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Will holds the available editors
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
inlineAttachment.editors = {};
|
||||
|
||||
/**
|
||||
* Utility functions
|
||||
*/
|
||||
inlineAttachment.util = {
|
||||
|
||||
/**
|
||||
* Simple function to merge the given objects
|
||||
*
|
||||
* @param {Object[]} object Multiple object parameters
|
||||
* @returns {Object}
|
||||
*/
|
||||
merge: function() {
|
||||
var result = {};
|
||||
for (var i = arguments.length - 1; i >= 0; i--) {
|
||||
var obj = arguments[i];
|
||||
for (var k in obj) {
|
||||
if (obj.hasOwnProperty(k)) {
|
||||
result[k] = obj[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Append a line of text at the bottom, ensuring there aren't unnecessary newlines
|
||||
*
|
||||
* @param {String} appended Current content
|
||||
* @param {String} previous Value which should be appended after the current content
|
||||
*/
|
||||
appendInItsOwnLine: function(previous, appended) {
|
||||
return (previous + "\n\n[[D]]" + appended)
|
||||
.replace(/(\n{2,})\[\[D\]\]/, "\n\n")
|
||||
.replace(/^(\n*)/, "");
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts the given value at the current cursor position of the textarea element
|
||||
*
|
||||
* @param {HtmlElement} el
|
||||
* @param {String} value Text which will be inserted at the cursor position
|
||||
*/
|
||||
insertTextAtCursor: function(el, text) {
|
||||
var scrollPos = el.scrollTop,
|
||||
strPos = 0,
|
||||
browser = false,
|
||||
range;
|
||||
|
||||
if ((el.selectionStart || el.selectionStart === '0')) {
|
||||
browser = "ff";
|
||||
} else if (document.selection) {
|
||||
browser = "ie";
|
||||
}
|
||||
|
||||
if (browser === "ie") {
|
||||
el.focus();
|
||||
range = document.selection.createRange();
|
||||
range.moveStart('character', -el.value.length);
|
||||
strPos = range.text.length;
|
||||
} else if (browser === "ff") {
|
||||
strPos = el.selectionStart;
|
||||
}
|
||||
|
||||
var front = (el.value).substring(0, strPos);
|
||||
var back = (el.value).substring(strPos, el.value.length);
|
||||
el.value = front + text + back;
|
||||
strPos = strPos + text.length;
|
||||
if (browser === "ie") {
|
||||
el.focus();
|
||||
range = document.selection.createRange();
|
||||
range.moveStart('character', -el.value.length);
|
||||
range.moveStart('character', strPos);
|
||||
range.moveEnd('character', 0);
|
||||
range.select();
|
||||
} else if (browser === "ff") {
|
||||
el.selectionStart = strPos;
|
||||
el.selectionEnd = strPos;
|
||||
el.focus();
|
||||
}
|
||||
el.scrollTop = scrollPos;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Default configuration options
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
inlineAttachment.defaults = {
|
||||
/**
|
||||
* URL where the file will be send
|
||||
*/
|
||||
uploadUrl: 'upload_attachment.php',
|
||||
|
||||
/**
|
||||
* Which method will be used to send the file to the upload URL
|
||||
*/
|
||||
uploadMethod: 'POST',
|
||||
|
||||
/**
|
||||
* Name in which the file will be placed
|
||||
*/
|
||||
uploadFieldName: 'file',
|
||||
|
||||
/**
|
||||
* Extension which will be used when a file extension could not
|
||||
* be detected
|
||||
*/
|
||||
defaultExtension: 'png',
|
||||
|
||||
/**
|
||||
* JSON field which refers to the uploaded file URL
|
||||
*/
|
||||
jsonFieldName: 'filename',
|
||||
|
||||
/**
|
||||
* Allowed MIME types
|
||||
*/
|
||||
allowedTypes: [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/jpg',
|
||||
'image/gif'
|
||||
],
|
||||
|
||||
/**
|
||||
* Text which will be inserted when dropping or pasting a file.
|
||||
* Acts as a placeholder which will be replaced when the file is done with uploading
|
||||
*/
|
||||
progressText: '![Uploading file...]()',
|
||||
|
||||
/**
|
||||
* When a file has successfully been uploaded the progressText
|
||||
* will be replaced by the urlText, the {filename} tag will be replaced
|
||||
* by the filename that has been returned by the server
|
||||
*/
|
||||
urlText: "![file]({filename})",
|
||||
|
||||
/**
|
||||
* Text which will be used when uploading has failed
|
||||
*/
|
||||
errorText: "Error uploading file",
|
||||
|
||||
/**
|
||||
* Extra parameters which will be send when uploading a file
|
||||
*/
|
||||
extraParams: {},
|
||||
|
||||
/**
|
||||
* Extra headers which will be send when uploading a file
|
||||
*/
|
||||
extraHeaders: {},
|
||||
|
||||
/**
|
||||
* Before the file is send
|
||||
*/
|
||||
beforeFileUpload: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers when a file is dropped or pasted
|
||||
*/
|
||||
onFileReceived: function() {},
|
||||
|
||||
/**
|
||||
* Custom upload handler
|
||||
*
|
||||
* @return {Boolean} when false is returned it will prevent default upload behavior
|
||||
*/
|
||||
onFileUploadResponse: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom error handler. Runs after removing the placeholder text and before the alert().
|
||||
* Return false from this function to prevent the alert dialog.
|
||||
*
|
||||
* @return {Boolean} when false is returned it will prevent default error behavior
|
||||
*/
|
||||
onFileUploadError: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* When a file has succesfully been uploaded
|
||||
*/
|
||||
onFileUploaded: function() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Uploads the blob
|
||||
*
|
||||
* @param {Blob} file blob data received from event.dataTransfer object
|
||||
* @return {XMLHttpRequest} request object which sends the file
|
||||
*/
|
||||
inlineAttachment.prototype.uploadFile = function(file) {
|
||||
var me = this,
|
||||
formData = new FormData(),
|
||||
xhr = new XMLHttpRequest(),
|
||||
settings = this.settings,
|
||||
extension = settings.defaultExtension || settings.defualtExtension;
|
||||
|
||||
if (typeof settings.setupFormData === 'function') {
|
||||
settings.setupFormData(formData, file);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
formData.append(settings.uploadFieldName, file, remoteFilename);
|
||||
|
||||
// Append the extra parameters to the formdata
|
||||
if (typeof settings.extraParams === "object") {
|
||||
for (var key in settings.extraParams) {
|
||||
if (settings.extraParams.hasOwnProperty(key)) {
|
||||
formData.append(key, settings.extraParams[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xhr.open('POST', settings.uploadUrl);
|
||||
|
||||
// Add any available extra headers
|
||||
if (typeof settings.extraHeaders === "object") {
|
||||
for (var header in settings.extraHeaders) {
|
||||
if (settings.extraHeaders.hasOwnProperty(header)) {
|
||||
xhr.setRequestHeader(header, settings.extraHeaders[header]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onload = function() {
|
||||
// If HTTP status is OK or Created
|
||||
if (xhr.status === 200 || xhr.status === 201) {
|
||||
me.onFileUploadResponse(xhr);
|
||||
} else {
|
||||
me.onFileUploadError(xhr);
|
||||
}
|
||||
};
|
||||
if (settings.beforeFileUpload(xhr) !== false) {
|
||||
xhr.send(formData);
|
||||
}
|
||||
return xhr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns if the given file is allowed to handle
|
||||
*
|
||||
* @param {File} clipboard data file
|
||||
*/
|
||||
inlineAttachment.prototype.isFileAllowed = function(file) {
|
||||
if (file.kind === 'string') { return false; }
|
||||
if (this.settings.allowedTypes.indexOf('*') === 0){
|
||||
return true;
|
||||
} else {
|
||||
return this.settings.allowedTypes.indexOf(file.type) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles upload response
|
||||
*
|
||||
* @param {XMLHttpRequest} xhr
|
||||
* @return {Void}
|
||||
*/
|
||||
inlineAttachment.prototype.onFileUploadResponse = function(xhr) {
|
||||
if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
|
||||
var result = JSON.parse(xhr.responseText),
|
||||
filename = result[this.settings.jsonFieldName];
|
||||
|
||||
if (result && filename) {
|
||||
var newValue;
|
||||
if (typeof this.settings.urlText === 'function') {
|
||||
newValue = this.settings.urlText.call(this, filename, result);
|
||||
} else {
|
||||
newValue = this.settings.urlText.replace(this.filenameTag, filename);
|
||||
}
|
||||
var text = this.editor.getValue().replace(this.lastValue, newValue);
|
||||
this.editor.setValue(text);
|
||||
this.settings.onFileUploaded.call(this, filename);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called when a file has failed to upload
|
||||
*
|
||||
* @param {XMLHttpRequest} xhr
|
||||
* @return {Void}
|
||||
*/
|
||||
inlineAttachment.prototype.onFileUploadError = function(xhr) {
|
||||
if (this.settings.onFileUploadError.call(this, xhr) !== false) {
|
||||
var text = this.editor.getValue().replace(this.lastValue, "");
|
||||
this.editor.setValue(text);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when a file has been inserted, either by drop or paste
|
||||
*
|
||||
* @param {File} file
|
||||
* @return {Void}
|
||||
*/
|
||||
inlineAttachment.prototype.onFileInserted = function(file) {
|
||||
if (this.settings.onFileReceived.call(this, file) !== false) {
|
||||
this.lastValue = this.settings.progressText;
|
||||
this.editor.insertValue(this.lastValue);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called when a paste event occured
|
||||
* @param {Event} e
|
||||
* @return {Boolean} if the event was handled
|
||||
*/
|
||||
inlineAttachment.prototype.onPaste = function(e) {
|
||||
var result = false,
|
||||
clipboardData = e.clipboardData,
|
||||
items;
|
||||
|
||||
if (typeof clipboardData === "object") {
|
||||
items = clipboardData.items || clipboardData.files || [];
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if (this.isFileAllowed(item)) {
|
||||
result = true;
|
||||
this.onFileInserted(item.getAsFile());
|
||||
this.uploadFile(item.getAsFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result) { e.preventDefault(); }
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when a drop event occures
|
||||
* @param {Event} e
|
||||
* @return {Boolean} if the event was handled
|
||||
*/
|
||||
inlineAttachment.prototype.onDrop = function(e) {
|
||||
var result = false;
|
||||
for (var i = 0; i < e.dataTransfer.files.length; i++) {
|
||||
var file = e.dataTransfer.files[i];
|
||||
if (this.isFileAllowed(file)) {
|
||||
result = true;
|
||||
this.onFileInserted(file);
|
||||
this.uploadFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
window.inlineAttachment = inlineAttachment;
|
||||
|
||||
})(document, window);
|
||||
|
||||
/*jslint newcap: true */
|
||||
/*global inlineAttachment: false */
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
inlineAttachment.editors.input = {
|
||||
Editor: function(instance) {
|
||||
|
||||
var input = instance;
|
||||
|
||||
return {
|
||||
getValue: function() {
|
||||
return input.value;
|
||||
},
|
||||
insertValue: function(val) {
|
||||
inlineAttachment.util.insertTextAtCursor(input, val);
|
||||
},
|
||||
setValue: function(val) {
|
||||
input.value = val;
|
||||
}
|
||||
};
|
||||
},
|
||||
attachToInput: function(input, options) {
|
||||
options = options || {};
|
||||
|
||||
var editor = new inlineAttachment.editors.input.Editor(input),
|
||||
inlineattach = new inlineAttachment(options, editor);
|
||||
|
||||
input.addEventListener('paste', function(e) {
|
||||
inlineattach.onPaste(e);
|
||||
}, false);
|
||||
input.addEventListener('drop', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
inlineattach.onDrop(e);
|
||||
}, false);
|
||||
input.addEventListener('dragenter', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}, false);
|
||||
input.addEventListener('dragover', function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}, false);
|
||||
}
|
||||
};
|
||||
|
||||
})();
|
467
static/js/jquery.inline-attachment.js
Normal file
467
static/js/jquery.inline-attachment.js
Normal file
@ -0,0 +1,467 @@
|
||||
/*! inline-attachment - v2.0.3 - 2016-08-20 */
|
||||
/*jslint newcap: true */
|
||||
/*global XMLHttpRequest: false, FormData: false */
|
||||
/*
|
||||
* Inline Text Attachment
|
||||
*
|
||||
* Author: Roy van Kaathoven
|
||||
* Contact: ik@royvankaathoven.nl
|
||||
*/
|
||||
(function(document, window) {
|
||||
'use strict';
|
||||
|
||||
var inlineAttachment = function(options, instance) {
|
||||
this.settings = inlineAttachment.util.merge(options, inlineAttachment.defaults);
|
||||
this.editor = instance;
|
||||
this.filenameTag = '{filename}';
|
||||
this.lastValue = null;
|
||||
};
|
||||
|
||||
/**
|
||||
* Will holds the available editors
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
inlineAttachment.editors = {};
|
||||
|
||||
/**
|
||||
* Utility functions
|
||||
*/
|
||||
inlineAttachment.util = {
|
||||
|
||||
/**
|
||||
* Simple function to merge the given objects
|
||||
*
|
||||
* @param {Object[]} object Multiple object parameters
|
||||
* @returns {Object}
|
||||
*/
|
||||
merge: function() {
|
||||
var result = {};
|
||||
for (var i = arguments.length - 1; i >= 0; i--) {
|
||||
var obj = arguments[i];
|
||||
for (var k in obj) {
|
||||
if (obj.hasOwnProperty(k)) {
|
||||
result[k] = obj[k];
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
|
||||
/**
|
||||
* Append a line of text at the bottom, ensuring there aren't unnecessary newlines
|
||||
*
|
||||
* @param {String} appended Current content
|
||||
* @param {String} previous Value which should be appended after the current content
|
||||
*/
|
||||
appendInItsOwnLine: function(previous, appended) {
|
||||
return (previous + "\n\n[[D]]" + appended)
|
||||
.replace(/(\n{2,})\[\[D\]\]/, "\n\n")
|
||||
.replace(/^(\n*)/, "");
|
||||
},
|
||||
|
||||
/**
|
||||
* Inserts the given value at the current cursor position of the textarea element
|
||||
*
|
||||
* @param {HtmlElement} el
|
||||
* @param {String} value Text which will be inserted at the cursor position
|
||||
*/
|
||||
insertTextAtCursor: function(el, text) {
|
||||
var scrollPos = el.scrollTop,
|
||||
strPos = 0,
|
||||
browser = false,
|
||||
range;
|
||||
|
||||
if ((el.selectionStart || el.selectionStart === '0')) {
|
||||
browser = "ff";
|
||||
} else if (document.selection) {
|
||||
browser = "ie";
|
||||
}
|
||||
|
||||
if (browser === "ie") {
|
||||
el.focus();
|
||||
range = document.selection.createRange();
|
||||
range.moveStart('character', -el.value.length);
|
||||
strPos = range.text.length;
|
||||
} else if (browser === "ff") {
|
||||
strPos = el.selectionStart;
|
||||
}
|
||||
|
||||
var front = (el.value).substring(0, strPos);
|
||||
var back = (el.value).substring(strPos, el.value.length);
|
||||
el.value = front + text + back;
|
||||
strPos = strPos + text.length;
|
||||
if (browser === "ie") {
|
||||
el.focus();
|
||||
range = document.selection.createRange();
|
||||
range.moveStart('character', -el.value.length);
|
||||
range.moveStart('character', strPos);
|
||||
range.moveEnd('character', 0);
|
||||
range.select();
|
||||
} else if (browser === "ff") {
|
||||
el.selectionStart = strPos;
|
||||
el.selectionEnd = strPos;
|
||||
el.focus();
|
||||
}
|
||||
el.scrollTop = scrollPos;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Default configuration options
|
||||
*
|
||||
* @type {Object}
|
||||
*/
|
||||
inlineAttachment.defaults = {
|
||||
/**
|
||||
* URL where the file will be send
|
||||
*/
|
||||
uploadUrl: 'upload_attachment.php',
|
||||
|
||||
/**
|
||||
* Which method will be used to send the file to the upload URL
|
||||
*/
|
||||
uploadMethod: 'POST',
|
||||
|
||||
/**
|
||||
* Name in which the file will be placed
|
||||
*/
|
||||
uploadFieldName: 'file',
|
||||
|
||||
/**
|
||||
* Extension which will be used when a file extension could not
|
||||
* be detected
|
||||
*/
|
||||
defaultExtension: 'png',
|
||||
|
||||
/**
|
||||
* JSON field which refers to the uploaded file URL
|
||||
*/
|
||||
jsonFieldName: 'filename',
|
||||
|
||||
/**
|
||||
* Allowed MIME types
|
||||
*/
|
||||
allowedTypes: [
|
||||
'image/jpeg',
|
||||
'image/png',
|
||||
'image/jpg',
|
||||
'image/gif'
|
||||
],
|
||||
|
||||
/**
|
||||
* Text which will be inserted when dropping or pasting a file.
|
||||
* Acts as a placeholder which will be replaced when the file is done with uploading
|
||||
*/
|
||||
progressText: '![Uploading file...]()',
|
||||
|
||||
/**
|
||||
* When a file has successfully been uploaded the progressText
|
||||
* will be replaced by the urlText, the {filename} tag will be replaced
|
||||
* by the filename that has been returned by the server
|
||||
*/
|
||||
urlText: "![file]({filename})",
|
||||
|
||||
/**
|
||||
* Text which will be used when uploading has failed
|
||||
*/
|
||||
errorText: "Error uploading file",
|
||||
|
||||
/**
|
||||
* Extra parameters which will be send when uploading a file
|
||||
*/
|
||||
extraParams: {},
|
||||
|
||||
/**
|
||||
* Extra headers which will be send when uploading a file
|
||||
*/
|
||||
extraHeaders: {},
|
||||
|
||||
/**
|
||||
* Before the file is send
|
||||
*/
|
||||
beforeFileUpload: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Triggers when a file is dropped or pasted
|
||||
*/
|
||||
onFileReceived: function() {},
|
||||
|
||||
/**
|
||||
* Custom upload handler
|
||||
*
|
||||
* @return {Boolean} when false is returned it will prevent default upload behavior
|
||||
*/
|
||||
onFileUploadResponse: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Custom error handler. Runs after removing the placeholder text and before the alert().
|
||||
* Return false from this function to prevent the alert dialog.
|
||||
*
|
||||
* @return {Boolean} when false is returned it will prevent default error behavior
|
||||
*/
|
||||
onFileUploadError: function() {
|
||||
return true;
|
||||
},
|
||||
|
||||
/**
|
||||
* When a file has succesfully been uploaded
|
||||
*/
|
||||
onFileUploaded: function() {}
|
||||
};
|
||||
|
||||
/**
|
||||
* Uploads the blob
|
||||
*
|
||||
* @param {Blob} file blob data received from event.dataTransfer object
|
||||
* @return {XMLHttpRequest} request object which sends the file
|
||||
*/
|
||||
inlineAttachment.prototype.uploadFile = function(file) {
|
||||
var me = this,
|
||||
formData = new FormData(),
|
||||
xhr = new XMLHttpRequest(),
|
||||
settings = this.settings,
|
||||
extension = settings.defaultExtension || settings.defualtExtension;
|
||||
|
||||
if (typeof settings.setupFormData === 'function') {
|
||||
settings.setupFormData(formData, file);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
formData.append(settings.uploadFieldName, file, remoteFilename);
|
||||
|
||||
// Append the extra parameters to the formdata
|
||||
if (typeof settings.extraParams === "object") {
|
||||
for (var key in settings.extraParams) {
|
||||
if (settings.extraParams.hasOwnProperty(key)) {
|
||||
formData.append(key, settings.extraParams[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xhr.open('POST', settings.uploadUrl);
|
||||
|
||||
// Add any available extra headers
|
||||
if (typeof settings.extraHeaders === "object") {
|
||||
for (var header in settings.extraHeaders) {
|
||||
if (settings.extraHeaders.hasOwnProperty(header)) {
|
||||
xhr.setRequestHeader(header, settings.extraHeaders[header]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
xhr.onload = function() {
|
||||
// If HTTP status is OK or Created
|
||||
if (xhr.status === 200 || xhr.status === 201) {
|
||||
me.onFileUploadResponse(xhr);
|
||||
} else {
|
||||
me.onFileUploadError(xhr);
|
||||
}
|
||||
};
|
||||
if (settings.beforeFileUpload(xhr) !== false) {
|
||||
xhr.send(formData);
|
||||
}
|
||||
return xhr;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns if the given file is allowed to handle
|
||||
*
|
||||
* @param {File} clipboard data file
|
||||
*/
|
||||
inlineAttachment.prototype.isFileAllowed = function(file) {
|
||||
if (file.kind === 'string') { return false; }
|
||||
if (this.settings.allowedTypes.indexOf('*') === 0){
|
||||
return true;
|
||||
} else {
|
||||
return this.settings.allowedTypes.indexOf(file.type) >= 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles upload response
|
||||
*
|
||||
* @param {XMLHttpRequest} xhr
|
||||
* @return {Void}
|
||||
*/
|
||||
inlineAttachment.prototype.onFileUploadResponse = function(xhr) {
|
||||
if (this.settings.onFileUploadResponse.call(this, xhr) !== false) {
|
||||
var result = JSON.parse(xhr.responseText),
|
||||
filename = result[this.settings.jsonFieldName];
|
||||
|
||||
if (result && filename) {
|
||||
var newValue;
|
||||
if (typeof this.settings.urlText === 'function') {
|
||||
newValue = this.settings.urlText.call(this, filename, result);
|
||||
} else {
|
||||
newValue = this.settings.urlText.replace(this.filenameTag, filename);
|
||||
}
|
||||
var text = this.editor.getValue().replace(this.lastValue, newValue);
|
||||
this.editor.setValue(text);
|
||||
this.settings.onFileUploaded.call(this, filename);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called when a file has failed to upload
|
||||
*
|
||||
* @param {XMLHttpRequest} xhr
|
||||
* @return {Void}
|
||||
*/
|
||||
inlineAttachment.prototype.onFileUploadError = function(xhr) {
|
||||
if (this.settings.onFileUploadError.call(this, xhr) !== false) {
|
||||
var text = this.editor.getValue().replace(this.lastValue, "");
|
||||
this.editor.setValue(text);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when a file has been inserted, either by drop or paste
|
||||
*
|
||||
* @param {File} file
|
||||
* @return {Void}
|
||||
*/
|
||||
inlineAttachment.prototype.onFileInserted = function(file) {
|
||||
if (this.settings.onFileReceived.call(this, file) !== false) {
|
||||
this.lastValue = this.settings.progressText;
|
||||
this.editor.insertValue(this.lastValue);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called when a paste event occured
|
||||
* @param {Event} e
|
||||
* @return {Boolean} if the event was handled
|
||||
*/
|
||||
inlineAttachment.prototype.onPaste = function(e) {
|
||||
var result = false,
|
||||
clipboardData = e.clipboardData,
|
||||
items;
|
||||
|
||||
if (typeof clipboardData === "object") {
|
||||
items = clipboardData.items || clipboardData.files || [];
|
||||
|
||||
for (var i = 0; i < items.length; i++) {
|
||||
var item = items[i];
|
||||
if (this.isFileAllowed(item)) {
|
||||
result = true;
|
||||
this.onFileInserted(item.getAsFile());
|
||||
this.uploadFile(item.getAsFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result) { e.preventDefault(); }
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Called when a drop event occures
|
||||
* @param {Event} e
|
||||
* @return {Boolean} if the event was handled
|
||||
*/
|
||||
inlineAttachment.prototype.onDrop = function(e) {
|
||||
var result = false;
|
||||
for (var i = 0; i < e.dataTransfer.files.length; i++) {
|
||||
var file = e.dataTransfer.files[i];
|
||||
if (this.isFileAllowed(file)) {
|
||||
result = true;
|
||||
this.onFileInserted(file);
|
||||
this.uploadFile(file);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
window.inlineAttachment = inlineAttachment;
|
||||
|
||||
})(document, window);
|
||||
|
||||
/*jslint newcap: true */
|
||||
/*global inlineAttachment: false, jQuery: false */
|
||||
/**
|
||||
* jQuery plugin for inline attach
|
||||
*
|
||||
* @param {document} document
|
||||
* @param {window} window
|
||||
* @param {jQuery} $
|
||||
*/
|
||||
(function(document, window, $) {
|
||||
'use strict';
|
||||
|
||||
inlineAttachment.editors.jquery = {};
|
||||
|
||||
/**
|
||||
* Creates a new editor using jQuery
|
||||
*/
|
||||
var editor = function(instance) {
|
||||
|
||||
var $this = $(instance);
|
||||
|
||||
return {
|
||||
getValue: function() {
|
||||
return $this.val();
|
||||
},
|
||||
insertValue: function(val) {
|
||||
inlineAttachment.util.insertTextAtCursor($this[0], val);
|
||||
},
|
||||
setValue: function(val) {
|
||||
$this.val(val);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
$.fn.inlineattachment = function(options) {
|
||||
|
||||
var set = $(this);
|
||||
|
||||
set.each(function() {
|
||||
|
||||
var $this = $(this),
|
||||
ed = new editor($this),
|
||||
inlineattach = new inlineAttachment(options, ed);
|
||||
|
||||
$this.bind({
|
||||
'paste': function(e) {
|
||||
inlineattach.onPaste(e.originalEvent);
|
||||
},
|
||||
'drop': function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
inlineattach.onDrop(e.originalEvent);
|
||||
},
|
||||
'dragenter dragover': function(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
inlineAttachment.editors.jquery.Editor = editor;
|
||||
|
||||
})(document, window, jQuery);
|
@ -23,6 +23,8 @@
|
||||
<meta name="theme-color" content="#fff">
|
||||
|
||||
<script type="text/javascript" src="/static/js/jquery-1.8.3.js"></script>
|
||||
<script type="text/javascript" src="/static/js/inline-attachment.js"></script>
|
||||
<script type="text/javascript" src="/static/js/jquery.inline-attachment.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/github-markdown.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/menus-min.css">
|
||||
<link rel="stylesheet" type="text/css" href="/static/css/base-min.css">
|
||||
@ -481,7 +483,13 @@ Use Markdown for formatting and links (also make links like [[this]])." id="user
|
||||
|
||||
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$('textarea').inlineattachment({
|
||||
uploadUrl: 'upload_attachment.php'
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</body>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user