mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 11:35:55 +01:00
upload changes, show progres in composer
This commit is contained in:
@@ -90,6 +90,7 @@ define(['taskbar'], function(taskbar) {
|
||||
});
|
||||
|
||||
composer.posts[uuid] = post;
|
||||
composer.posts[uuid].uploadsInProgress = [];
|
||||
|
||||
composer.load(uuid);
|
||||
}
|
||||
@@ -118,7 +119,7 @@ define(['taskbar'], function(taskbar) {
|
||||
var postContainer = $(composerTemplate[0]);
|
||||
|
||||
if(config.allowFileUploads || config.hasImageUploadPlugin) {
|
||||
initializeFileReader(post_uuid);
|
||||
initializeDragAndDrop(post_uuid);
|
||||
}
|
||||
|
||||
var postData = composer.posts[post_uuid],
|
||||
@@ -235,11 +236,8 @@ define(['taskbar'], function(taskbar) {
|
||||
$('#files').on('change', function(e) {
|
||||
var files = e.target.files;
|
||||
if(files) {
|
||||
for (var i=0; i<files.length; i++) {
|
||||
loadFile(post_uuid, files[i]);
|
||||
}
|
||||
uploadSubmit(files, post_uuid, '/api/post/upload');
|
||||
}
|
||||
$('#fileForm')[0].reset();
|
||||
});
|
||||
|
||||
postContainer.find('.nav-tabs a').click(function (e) {
|
||||
@@ -256,6 +254,8 @@ define(['taskbar'], function(taskbar) {
|
||||
|
||||
bodyEl.on('blur', function() {
|
||||
socket.emit('modules.composer.renderPreview', bodyEl.val(), function(err, preview) {
|
||||
preview = $(preview);
|
||||
preview.find('img').addClass('img-responsive');
|
||||
postContainer.find('.preview').html(preview);
|
||||
});
|
||||
});
|
||||
@@ -488,134 +488,149 @@ define(['taskbar'], function(taskbar) {
|
||||
taskbar.minimize('composer', post_uuid);
|
||||
}
|
||||
|
||||
function initializeFileReader(post_uuid) {
|
||||
function initializeDragAndDrop(post_uuid) {
|
||||
|
||||
if(jQuery.event.props.indexOf('dataTransfer') === -1) {
|
||||
jQuery.event.props.push('dataTransfer');
|
||||
}
|
||||
|
||||
var draggingDocument = false;
|
||||
|
||||
if(window.FileReader) {
|
||||
var postContainer = $('#cmp-uuid-' + post_uuid),
|
||||
drop = postContainer.find('.imagedrop'),
|
||||
tabContent = postContainer.find('.tab-content'),
|
||||
textarea = postContainer.find('textarea');
|
||||
var postContainer = $('#cmp-uuid-' + post_uuid),
|
||||
fileForm = postContainer.find('#fileForm');
|
||||
drop = postContainer.find('.imagedrop'),
|
||||
tabContent = postContainer.find('.tab-content'),
|
||||
textarea = postContainer.find('textarea');
|
||||
|
||||
$(document).off('dragstart').on('dragstart', function(e) {
|
||||
draggingDocument = true;
|
||||
}).off('dragend').on('dragend', function(e) {
|
||||
draggingDocument = false;
|
||||
});
|
||||
|
||||
textarea.on('dragenter', function(e) {
|
||||
if(draggingDocument) {
|
||||
return;
|
||||
}
|
||||
drop.css('top', tabContent.position().top + 'px');
|
||||
drop.css('height', textarea.height());
|
||||
drop.css('line-height', textarea.height() + 'px');
|
||||
drop.show();
|
||||
|
||||
drop.on('dragleave', function(ev) {
|
||||
drop.hide();
|
||||
drop.off('dragleave');
|
||||
});
|
||||
});
|
||||
|
||||
function cancel(e) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
drop.on('dragover', cancel);
|
||||
drop.on('dragenter', cancel);
|
||||
|
||||
drop.on('drop', function(e) {
|
||||
e.preventDefault();
|
||||
var dt = e.dataTransfer,
|
||||
files = dt.files;
|
||||
|
||||
for (var i=0; i<files.length; i++) {
|
||||
loadFile(post_uuid, files[i]);
|
||||
}
|
||||
|
||||
if(!files.length) {
|
||||
drop.hide();
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
$(window).off('paste').on('paste', function(event) {
|
||||
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||
if(items && items.length) {
|
||||
var blob = items[0].getAsFile();
|
||||
loadFile(post_uuid, blob);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function loadFile(post_uuid, file) {
|
||||
var reader = new FileReader(),
|
||||
dropDiv = $('#cmp-uuid-' + post_uuid).find('.imagedrop');
|
||||
|
||||
$(reader).on('loadend', function(e) {
|
||||
var regex = /^data:.*;base64,(.*)$/;
|
||||
var matches = this.result.match(regex);
|
||||
|
||||
var fileData = {
|
||||
name: file.name || '',
|
||||
data: matches[1]
|
||||
};
|
||||
|
||||
dropDiv.hide();
|
||||
|
||||
if(file.type.match('image.*')) {
|
||||
uploadFile('posts.uploadImage', post_uuid, fileData);
|
||||
} else {
|
||||
if(file.size > parseInt(config.maximumFileSize, 10) * 1024) {
|
||||
return composerAlert('File too big', 'Maximum allowed file size is ' + config.maximumFileSize + 'kbs');
|
||||
}
|
||||
uploadFile('posts.uploadFile', post_uuid, fileData);
|
||||
}
|
||||
$(document).off('dragstart').on('dragstart', function(e) {
|
||||
draggingDocument = true;
|
||||
}).off('dragend').on('dragend', function(e) {
|
||||
draggingDocument = false;
|
||||
});
|
||||
|
||||
reader.readAsDataURL(file);
|
||||
textarea.on('dragenter', function(e) {
|
||||
if(draggingDocument) {
|
||||
return;
|
||||
}
|
||||
drop.css('top', tabContent.position().top + 'px');
|
||||
drop.css('height', textarea.height());
|
||||
drop.css('line-height', textarea.height() + 'px');
|
||||
drop.show();
|
||||
|
||||
drop.on('dragleave', function(ev) {
|
||||
drop.hide();
|
||||
drop.off('dragleave');
|
||||
});
|
||||
});
|
||||
|
||||
function cancel(e) {
|
||||
e.preventDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
drop.on('dragover', cancel);
|
||||
drop.on('dragenter', cancel);
|
||||
|
||||
drop.on('drop', function(e) {
|
||||
e.preventDefault();
|
||||
var dt = e.dataTransfer,
|
||||
files = dt.files;
|
||||
|
||||
if(files.length) {
|
||||
fileForm[0].reset();
|
||||
fileForm.find('#files')[0].files = files;
|
||||
}
|
||||
|
||||
drop.hide();
|
||||
return false;
|
||||
});
|
||||
|
||||
$(window).off('paste').on('paste', function(event) {
|
||||
|
||||
var items = (event.clipboardData || event.originalEvent.clipboardData).items;
|
||||
|
||||
if(items && items.length) {
|
||||
|
||||
var blob = items[0].getAsFile();
|
||||
blob.name = 'upload-'+ utils.generateUUID();
|
||||
|
||||
var fd = new FormData();
|
||||
fd.append('files[]', blob, blob.name);
|
||||
|
||||
fileForm[0].reset();
|
||||
uploadSubmit([blob], post_uuid, '/api/post/upload', fd);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function uploadFile(method, post_uuid, img) {
|
||||
var linkStart = method === 'posts.uploadImage' ? '!' : '',
|
||||
postContainer = $('#cmp-uuid-' + post_uuid),
|
||||
function uploadSubmit(files, post_uuid, route, formData, callback) {
|
||||
var postContainer = $('#cmp-uuid-' + post_uuid),
|
||||
textarea = postContainer.find('textarea'),
|
||||
text = textarea.val(),
|
||||
imgText = linkStart + '[' + img.name + '](uploading...)';
|
||||
uploadForm = postContainer.find('#fileForm');
|
||||
|
||||
text += imgText;
|
||||
textarea.val(text + " ");
|
||||
uploadForm.attr('action', route);
|
||||
|
||||
if(!composer.posts[post_uuid].uploadsInProgress) {
|
||||
composer.posts[post_uuid].uploadsInProgress = [];
|
||||
for(var i=0; i<files.length; ++i) {
|
||||
var isImage = files[i].type.match('image.*');
|
||||
text += (isImage ? '!' : '') + '[' + files[i].name + '](uploading...) ';
|
||||
|
||||
if(files[i].size > parseInt(config.maximumFileSize, 10) * 1024) {
|
||||
uploadForm[0].reset();
|
||||
return composerAlert('File too big', 'Maximum allowed file size is ' + config.maximumFileSize + 'kbs');
|
||||
}
|
||||
}
|
||||
|
||||
composer.posts[post_uuid].uploadsInProgress.push(1);
|
||||
textarea.val(text);
|
||||
|
||||
socket.emit(method, img, function(err, data) {
|
||||
uploadForm.off('submit').submit(function() {
|
||||
|
||||
var currentText = textarea.val();
|
||||
|
||||
if(err) {
|
||||
textarea.val(currentText.replace(imgText, linkStart + '[' + img.name + ']( Error : ' + err.message + ')'));
|
||||
return app.alertError(err.message);
|
||||
$(this).find('#postUploadCsrf').val($('#csrf_token').val());
|
||||
if(formData) {
|
||||
formData.append('_csrf', $('#csrf_token').val());
|
||||
}
|
||||
|
||||
textarea.val(currentText.replace(imgText, linkStart + '[' + data.name + '](' + data.url + ')'));
|
||||
composer.posts[post_uuid].uploadsInProgress.push(1);
|
||||
|
||||
composer.posts[post_uuid].uploadsInProgress.pop();
|
||||
textarea.focus();
|
||||
$(this).ajaxSubmit({
|
||||
resetForm: true,
|
||||
clearForm: true,
|
||||
formData: formData,
|
||||
error: function(xhr) {
|
||||
app.alertError('Error uploading file! ' + xhr.status);
|
||||
composer.posts[post_uuid].uploadsInProgress.pop();
|
||||
},
|
||||
|
||||
uploadProgress: function(event, position, total, percent) {
|
||||
var current = textarea.val();
|
||||
for(var i=0; i<files.length; ++i) {
|
||||
var re = new RegExp(files[i].name + "]\\([^)]+\\)", 'g');
|
||||
textarea.val(current.replace(re, files[i].name+'](uploading ' + percent + '%)'));
|
||||
}
|
||||
},
|
||||
|
||||
success: function(uploads) {
|
||||
|
||||
if(uploads && uploads.length) {
|
||||
for(var i=0; i<uploads.length; ++i) {
|
||||
var current = textarea.val();
|
||||
var re = new RegExp(uploads[i].name + "]\\([^)]+\\)", 'g');
|
||||
textarea.val(current.replace(re, uploads[i].name + '](' + uploads[i].url + ')'));
|
||||
}
|
||||
}
|
||||
|
||||
composer.posts[post_uuid].uploadsInProgress.pop();
|
||||
textarea.focus();
|
||||
}
|
||||
});
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
uploadForm.submit();
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
newTopic: composer.newTopic,
|
||||
newReply: composer.newReply,
|
||||
|
||||
@@ -13,8 +13,10 @@
|
||||
<span class="btn btn-link file-upload-btn hide" tabindex="-1">
|
||||
<i class="fa fa-upload"></i>
|
||||
</span>
|
||||
<form id="fileForm">
|
||||
<input type="file" id="files" name="files[]" multiple class="hide"/>
|
||||
|
||||
<form id="fileForm" method="post" enctype="multipart/form-data">
|
||||
<input type="file" id="files" name="files[]" multiple class="hide"/>
|
||||
<input id="postUploadCsrf" type="hidden" name="_csrf">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
237
public/vendor/jquery/js/jquery.form.js
vendored
237
public/vendor/jquery/js/jquery.form.js
vendored
@@ -1,7 +1,7 @@
|
||||
/*!
|
||||
* jQuery Form Plugin
|
||||
* version: 3.32.0-2013.04.09
|
||||
* @requires jQuery v1.5 or later
|
||||
* version: 3.49.0-2014.02.05
|
||||
* Requires jQuery v1.5 or later
|
||||
* Copyright (c) 2013 M. Alsup
|
||||
* Examples and documentation at: http://malsup.com/jquery/form/
|
||||
* Project repository: https://github.com/malsup/form
|
||||
@@ -9,7 +9,20 @@
|
||||
* https://github.com/malsup/form#copyright-and-license
|
||||
*/
|
||||
/*global ActiveXObject */
|
||||
;(function($) {
|
||||
|
||||
// AMD support
|
||||
(function (factory) {
|
||||
"use strict";
|
||||
if (typeof define === 'function' && define.amd) {
|
||||
// using AMD; register as anon module
|
||||
define(['jquery'], factory);
|
||||
} else {
|
||||
// no AMD; invoke directly
|
||||
factory( (typeof(jQuery) != 'undefined') ? jQuery : window.Zepto );
|
||||
}
|
||||
}
|
||||
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
/*
|
||||
@@ -63,11 +76,13 @@ var hasProp = !!$.fn.prop;
|
||||
// contains inputs with names like "action" or "method"; in those
|
||||
// cases "prop" returns the element
|
||||
$.fn.attr2 = function() {
|
||||
if ( ! hasProp )
|
||||
if ( ! hasProp ) {
|
||||
return this.attr.apply(this, arguments);
|
||||
}
|
||||
var val = this.prop.apply(this, arguments);
|
||||
if ( ( val && val.jquery ) || typeof val === 'string' )
|
||||
if ( ( val && val.jquery ) || typeof val === 'string' ) {
|
||||
return val;
|
||||
}
|
||||
return this.attr.apply(this, arguments);
|
||||
};
|
||||
|
||||
@@ -89,9 +104,12 @@ $.fn.ajaxSubmit = function(options) {
|
||||
if (typeof options == 'function') {
|
||||
options = { success: options };
|
||||
}
|
||||
else if ( options === undefined ) {
|
||||
options = {};
|
||||
}
|
||||
|
||||
method = this.attr2('method');
|
||||
action = this.attr2('action');
|
||||
method = options.type || this.attr2('method');
|
||||
action = options.url || this.attr2('action');
|
||||
|
||||
url = (typeof action === 'string') ? $.trim(action) : '';
|
||||
url = url || window.location.href || '';
|
||||
@@ -103,7 +121,7 @@ $.fn.ajaxSubmit = function(options) {
|
||||
options = $.extend(true, {
|
||||
url: url,
|
||||
success: $.ajaxSettings.success,
|
||||
type: method || 'GET',
|
||||
type: method || $.ajaxSettings.type,
|
||||
iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'
|
||||
}, options);
|
||||
|
||||
@@ -186,11 +204,27 @@ $.fn.ajaxSubmit = function(options) {
|
||||
}
|
||||
};
|
||||
|
||||
if (options.error) {
|
||||
var oldError = options.error;
|
||||
options.error = function(xhr, status, error) {
|
||||
var context = options.context || this;
|
||||
oldError.apply(context, [xhr, status, error, $form]);
|
||||
};
|
||||
}
|
||||
|
||||
if (options.complete) {
|
||||
var oldComplete = options.complete;
|
||||
options.complete = function(xhr, status) {
|
||||
var context = options.context || this;
|
||||
oldComplete.apply(context, [xhr, status, $form]);
|
||||
};
|
||||
}
|
||||
|
||||
// are there files to upload?
|
||||
|
||||
// [value] (issue #113), also see comment:
|
||||
// https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219
|
||||
var fileInputs = $('input[type=file]:enabled[value!=""]', this);
|
||||
var fileInputs = $('input[type=file]:enabled', this).filter(function() { return $(this).val() !== ''; });
|
||||
|
||||
var hasFileInputs = fileInputs.length > 0;
|
||||
var mp = 'multipart/form-data';
|
||||
@@ -226,8 +260,9 @@ $.fn.ajaxSubmit = function(options) {
|
||||
$form.removeData('jqxhr').data('jqxhr', jqxhr);
|
||||
|
||||
// clear element array
|
||||
for (var k=0; k < elements.length; k++)
|
||||
for (var k=0; k < elements.length; k++) {
|
||||
elements[k] = null;
|
||||
}
|
||||
|
||||
// fire 'notify' event
|
||||
this.trigger('form-submit-notify', [this, options]);
|
||||
@@ -235,7 +270,7 @@ $.fn.ajaxSubmit = function(options) {
|
||||
|
||||
// utility fn for deep serialization
|
||||
function deepSerialize(extraData){
|
||||
var serialized = $.param(extraData).split('&');
|
||||
var serialized = $.param(extraData, options.traditional).split('&');
|
||||
var len = serialized.length;
|
||||
var result = [];
|
||||
var i, part;
|
||||
@@ -259,9 +294,11 @@ $.fn.ajaxSubmit = function(options) {
|
||||
|
||||
if (options.extraData) {
|
||||
var serializedData = deepSerialize(options.extraData);
|
||||
for (i=0; i < serializedData.length; i++)
|
||||
if (serializedData[i])
|
||||
for (i=0; i < serializedData.length; i++) {
|
||||
if (serializedData[i]) {
|
||||
formdata.append(serializedData[i][0], serializedData[i][1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
options.data = null;
|
||||
@@ -276,7 +313,7 @@ $.fn.ajaxSubmit = function(options) {
|
||||
if (options.uploadProgress) {
|
||||
// workaround because jqXHR does not expose upload property
|
||||
s.xhr = function() {
|
||||
var xhr = jQuery.ajaxSettings.xhr();
|
||||
var xhr = $.ajaxSettings.xhr();
|
||||
if (xhr.upload) {
|
||||
xhr.upload.addEventListener('progress', function(event) {
|
||||
var percent = 0;
|
||||
@@ -293,11 +330,18 @@ $.fn.ajaxSubmit = function(options) {
|
||||
}
|
||||
|
||||
s.data = null;
|
||||
var beforeSend = s.beforeSend;
|
||||
s.beforeSend = function(xhr, o) {
|
||||
var beforeSend = s.beforeSend;
|
||||
s.beforeSend = function(xhr, o) {
|
||||
//Send FormData() provided by user
|
||||
if (options.formData) {
|
||||
o.data = options.formData;
|
||||
}
|
||||
else {
|
||||
o.data = formdata;
|
||||
if(beforeSend)
|
||||
beforeSend.call(this, xhr, o);
|
||||
}
|
||||
if(beforeSend) {
|
||||
beforeSend.call(this, xhr, o);
|
||||
}
|
||||
};
|
||||
return $.ajax(s);
|
||||
}
|
||||
@@ -307,14 +351,21 @@ $.fn.ajaxSubmit = function(options) {
|
||||
var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;
|
||||
var deferred = $.Deferred();
|
||||
|
||||
// #341
|
||||
deferred.abort = function(status) {
|
||||
xhr.abort(status);
|
||||
};
|
||||
|
||||
if (a) {
|
||||
// ensure that every serialized input is still enabled
|
||||
for (i=0; i < elements.length; i++) {
|
||||
el = $(elements[i]);
|
||||
if ( hasProp )
|
||||
if ( hasProp ) {
|
||||
el.prop('disabled', false);
|
||||
else
|
||||
}
|
||||
else {
|
||||
el.removeAttr('disabled');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,10 +375,12 @@ $.fn.ajaxSubmit = function(options) {
|
||||
if (s.iframeTarget) {
|
||||
$io = $(s.iframeTarget);
|
||||
n = $io.attr2('name');
|
||||
if (!n)
|
||||
$io.attr2('name', id);
|
||||
else
|
||||
if (!n) {
|
||||
$io.attr2('name', id);
|
||||
}
|
||||
else {
|
||||
id = n;
|
||||
}
|
||||
}
|
||||
else {
|
||||
$io = $('<iframe name="' + id + '" src="'+ s.iframeSrc +'" />');
|
||||
@@ -359,12 +412,15 @@ $.fn.ajaxSubmit = function(options) {
|
||||
|
||||
$io.attr('src', s.iframeSrc); // abort op in progress
|
||||
xhr.error = e;
|
||||
if (s.error)
|
||||
if (s.error) {
|
||||
s.error.call(s.context, xhr, e, status);
|
||||
if (g)
|
||||
}
|
||||
if (g) {
|
||||
$.event.trigger("ajaxError", [xhr, s, e]);
|
||||
if (s.complete)
|
||||
}
|
||||
if (s.complete) {
|
||||
s.complete.call(s.context, xhr, e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -451,11 +507,14 @@ $.fn.ajaxSubmit = function(options) {
|
||||
// take a breath so that pending repaints get some cpu time before the upload starts
|
||||
function doSubmit() {
|
||||
// make sure form attrs are set
|
||||
var t = $form.attr2('target'), a = $form.attr2('action');
|
||||
var t = $form.attr2('target'),
|
||||
a = $form.attr2('action'),
|
||||
mp = 'multipart/form-data',
|
||||
et = $form.attr('enctype') || $form.attr('encoding') || mp;
|
||||
|
||||
// update form attrs in IE friendly way
|
||||
form.setAttribute('target',id);
|
||||
if (!method) {
|
||||
if (!method || /post/i.test(method) ) {
|
||||
form.setAttribute('method', 'POST');
|
||||
}
|
||||
if (a != s.url) {
|
||||
@@ -480,14 +539,16 @@ $.fn.ajaxSubmit = function(options) {
|
||||
try {
|
||||
var state = getDoc(io).readyState;
|
||||
log('state = ' + state);
|
||||
if (state && state.toLowerCase() == 'uninitialized')
|
||||
if (state && state.toLowerCase() == 'uninitialized') {
|
||||
setTimeout(checkState,50);
|
||||
}
|
||||
}
|
||||
catch(e) {
|
||||
log('Server abort: ' , e, ' (', e.name, ')');
|
||||
cb(SERVER_ABORT);
|
||||
if (timeoutHandle)
|
||||
if (timeoutHandle) {
|
||||
clearTimeout(timeoutHandle);
|
||||
}
|
||||
timeoutHandle = undefined;
|
||||
}
|
||||
}
|
||||
@@ -515,10 +576,12 @@ $.fn.ajaxSubmit = function(options) {
|
||||
if (!s.iframeTarget) {
|
||||
// add iframe to doc and submit the form
|
||||
$io.appendTo('body');
|
||||
if (io.attachEvent)
|
||||
io.attachEvent('onload', cb);
|
||||
else
|
||||
io.addEventListener('load', cb, false);
|
||||
}
|
||||
if (io.attachEvent) {
|
||||
io.attachEvent('onload', cb);
|
||||
}
|
||||
else {
|
||||
io.addEventListener('load', cb, false);
|
||||
}
|
||||
setTimeout(checkState,15);
|
||||
|
||||
@@ -533,6 +596,7 @@ $.fn.ajaxSubmit = function(options) {
|
||||
finally {
|
||||
// reset attrs and remove "extra" input elements
|
||||
form.setAttribute('action',a);
|
||||
form.setAttribute('enctype', et); // #380
|
||||
if(t) {
|
||||
form.setAttribute('target', t);
|
||||
} else {
|
||||
@@ -574,13 +638,16 @@ $.fn.ajaxSubmit = function(options) {
|
||||
|
||||
if (!doc || doc.location.href == s.iframeSrc) {
|
||||
// response not received yet
|
||||
if (!timedOut)
|
||||
if (!timedOut) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (io.detachEvent)
|
||||
if (io.detachEvent) {
|
||||
io.detachEvent('onload', cb);
|
||||
else
|
||||
}
|
||||
else {
|
||||
io.removeEventListener('load', cb, false);
|
||||
}
|
||||
|
||||
var status = 'success', errMsg;
|
||||
try {
|
||||
@@ -607,11 +674,12 @@ $.fn.ajaxSubmit = function(options) {
|
||||
var docRoot = doc.body ? doc.body : doc.documentElement;
|
||||
xhr.responseText = docRoot ? docRoot.innerHTML : null;
|
||||
xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;
|
||||
if (isXml)
|
||||
if (isXml) {
|
||||
s.dataType = 'xml';
|
||||
}
|
||||
xhr.getResponseHeader = function(header){
|
||||
var headers = {'content-type': s.dataType};
|
||||
return headers[header];
|
||||
return headers[header.toLowerCase()];
|
||||
};
|
||||
// support for XHR 'status' & 'statusText' emulation :
|
||||
if (docRoot) {
|
||||
@@ -671,40 +739,52 @@ $.fn.ajaxSubmit = function(options) {
|
||||
|
||||
// ordering of these callbacks/triggers is odd, but that's how $.ajax does it
|
||||
if (status === 'success') {
|
||||
if (s.success)
|
||||
if (s.success) {
|
||||
s.success.call(s.context, data, 'success', xhr);
|
||||
}
|
||||
deferred.resolve(xhr.responseText, 'success', xhr);
|
||||
if (g)
|
||||
if (g) {
|
||||
$.event.trigger("ajaxSuccess", [xhr, s]);
|
||||
}
|
||||
}
|
||||
else if (status) {
|
||||
if (errMsg === undefined)
|
||||
if (errMsg === undefined) {
|
||||
errMsg = xhr.statusText;
|
||||
if (s.error)
|
||||
}
|
||||
if (s.error) {
|
||||
s.error.call(s.context, xhr, status, errMsg);
|
||||
}
|
||||
deferred.reject(xhr, 'error', errMsg);
|
||||
if (g)
|
||||
if (g) {
|
||||
$.event.trigger("ajaxError", [xhr, s, errMsg]);
|
||||
}
|
||||
}
|
||||
|
||||
if (g)
|
||||
if (g) {
|
||||
$.event.trigger("ajaxComplete", [xhr, s]);
|
||||
}
|
||||
|
||||
if (g && ! --$.active) {
|
||||
$.event.trigger("ajaxStop");
|
||||
}
|
||||
|
||||
if (s.complete)
|
||||
if (s.complete) {
|
||||
s.complete.call(s.context, xhr, status);
|
||||
}
|
||||
|
||||
callbackProcessed = true;
|
||||
if (s.timeout)
|
||||
if (s.timeout) {
|
||||
clearTimeout(timeoutHandle);
|
||||
}
|
||||
|
||||
// clean up
|
||||
setTimeout(function() {
|
||||
if (!s.iframeTarget)
|
||||
if (!s.iframeTarget) {
|
||||
$io.remove();
|
||||
}
|
||||
else { //adding else to clean up existing iframe response.
|
||||
$io.attr('src', s.iframeSrc);
|
||||
}
|
||||
xhr.responseXML = null;
|
||||
}, 100);
|
||||
}
|
||||
@@ -732,8 +812,9 @@ $.fn.ajaxSubmit = function(options) {
|
||||
data = xml ? xhr.responseXML : xhr.responseText;
|
||||
|
||||
if (xml && data.documentElement.nodeName === 'parsererror') {
|
||||
if ($.error)
|
||||
if ($.error) {
|
||||
$.error('parsererror');
|
||||
}
|
||||
}
|
||||
if (s && s.dataFilter) {
|
||||
data = s.dataFilter(data, type);
|
||||
@@ -806,7 +887,7 @@ function doAjaxSubmit(e) {
|
||||
var options = e.data;
|
||||
if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed
|
||||
e.preventDefault();
|
||||
$(this).ajaxSubmit(options);
|
||||
$(e.target).ajaxSubmit(options); // #365
|
||||
}
|
||||
}
|
||||
|
||||
@@ -865,8 +946,23 @@ $.fn.formToArray = function(semantic, elements) {
|
||||
}
|
||||
|
||||
var form = this[0];
|
||||
var formId = this.attr('id');
|
||||
var els = semantic ? form.getElementsByTagName('*') : form.elements;
|
||||
if (!els) {
|
||||
var els2;
|
||||
|
||||
if (els && !/MSIE 8/.test(navigator.userAgent)) { // #390
|
||||
els = $(els).get(); // convert to standard array
|
||||
}
|
||||
|
||||
// #386; account for inputs outside the form which use the 'form' attribute
|
||||
if ( formId ) {
|
||||
els2 = $(':input[form=' + formId + ']').get();
|
||||
if ( els2.length ) {
|
||||
els = (els || []).concat(els2);
|
||||
}
|
||||
}
|
||||
|
||||
if (!els || !els.length) {
|
||||
return a;
|
||||
}
|
||||
|
||||
@@ -889,15 +985,17 @@ $.fn.formToArray = function(semantic, elements) {
|
||||
|
||||
v = $.fieldValue(el, true);
|
||||
if (v && v.constructor == Array) {
|
||||
if (elements)
|
||||
if (elements) {
|
||||
elements.push(el);
|
||||
}
|
||||
for(j=0, jmax=v.length; j < jmax; j++) {
|
||||
a.push({name: n, value: v[j]});
|
||||
}
|
||||
}
|
||||
else if (feature.fileapi && el.type == 'file') {
|
||||
if (elements)
|
||||
if (elements) {
|
||||
elements.push(el);
|
||||
}
|
||||
var files = el.files;
|
||||
if (files.length) {
|
||||
for (j=0; j < files.length; j++) {
|
||||
@@ -910,8 +1008,9 @@ $.fn.formToArray = function(semantic, elements) {
|
||||
}
|
||||
}
|
||||
else if (v !== null && typeof v != 'undefined') {
|
||||
if (elements)
|
||||
if (elements) {
|
||||
elements.push(el);
|
||||
}
|
||||
a.push({name: n, value: v, type: el.type, required: el.required});
|
||||
}
|
||||
}
|
||||
@@ -1007,10 +1106,12 @@ $.fn.fieldValue = function(successful) {
|
||||
if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {
|
||||
continue;
|
||||
}
|
||||
if (v.constructor == Array)
|
||||
if (v.constructor == Array) {
|
||||
$.merge(val, v);
|
||||
else
|
||||
}
|
||||
else {
|
||||
val.push(v);
|
||||
}
|
||||
}
|
||||
return val;
|
||||
};
|
||||
@@ -1044,7 +1145,7 @@ $.fieldValue = function(el, successful) {
|
||||
if (op.selected) {
|
||||
var v = op.value;
|
||||
if (!v) { // extra pain for IE...
|
||||
v = (op.attributes && op.attributes['value'] && !(op.attributes['value'].specified)) ? op.text : op.value;
|
||||
v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;
|
||||
}
|
||||
if (one) {
|
||||
return v;
|
||||
@@ -1087,21 +1188,22 @@ $.fn.clearFields = $.fn.clearInputs = function(includeHidden) {
|
||||
else if (tag == 'select') {
|
||||
this.selectedIndex = -1;
|
||||
}
|
||||
else if (t == "file") {
|
||||
if (/MSIE/.test(navigator.userAgent)) {
|
||||
$(this).replaceWith($(this).clone(true));
|
||||
} else {
|
||||
$(this).val('');
|
||||
}
|
||||
}
|
||||
else if (t == "file") {
|
||||
if (/MSIE/.test(navigator.userAgent)) {
|
||||
$(this).replaceWith($(this).clone(true));
|
||||
} else {
|
||||
$(this).val('');
|
||||
}
|
||||
}
|
||||
else if (includeHidden) {
|
||||
// includeHidden can be the value true, or it can be a selector string
|
||||
// indicating a special test; for example:
|
||||
// $('#myForm').clearForm('.special:hidden')
|
||||
// the above would clean hidden inputs that have the class of 'special'
|
||||
if ( (includeHidden === true && /hidden/.test(t)) ||
|
||||
(typeof includeHidden == 'string' && $(this).is(includeHidden)) )
|
||||
(typeof includeHidden == 'string' && $(this).is(includeHidden)) ) {
|
||||
this.value = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
@@ -1160,8 +1262,9 @@ $.fn.ajaxSubmit.debug = false;
|
||||
|
||||
// helper fn for console logging
|
||||
function log() {
|
||||
if (!$.fn.ajaxSubmit.debug)
|
||||
if (!$.fn.ajaxSubmit.debug) {
|
||||
return;
|
||||
}
|
||||
var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');
|
||||
if (window.console && window.console.log) {
|
||||
window.console.log(msg);
|
||||
@@ -1171,4 +1274,4 @@ function log() {
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
||||
}));
|
||||
|
||||
17
src/posts.js
17
src/posts.js
@@ -397,7 +397,7 @@ var db = require('./database'),
|
||||
Posts.uploadPostImage = function(image, callback) {
|
||||
|
||||
if(plugins.hasListeners('filter:uploadImage')) {
|
||||
plugins.fireHook('filter:uploadImage', {base64: image.data, name: image.name}, callback);
|
||||
plugins.fireHook('filter:uploadImage', image, callback);
|
||||
} else {
|
||||
|
||||
if (meta.config.allowFileUploads) {
|
||||
@@ -411,39 +411,36 @@ var db = require('./database'),
|
||||
Posts.uploadPostFile = function(file, callback) {
|
||||
|
||||
if(plugins.hasListeners('filter:uploadFile')) {
|
||||
plugins.fireHook('filter:uploadFile', {base64: file.data, name: file.name}, callback);
|
||||
plugins.fireHook('filter:uploadFile', file, callback);
|
||||
} else {
|
||||
|
||||
if(!meta.config.allowFileUploads) {
|
||||
return callback(new Error('File uploads are not allowed'));
|
||||
}
|
||||
|
||||
if(!file || !file.data) {
|
||||
if(!file) {
|
||||
return callback(new Error('invalid file'));
|
||||
}
|
||||
|
||||
var buffer = new Buffer(file.data, 'base64');
|
||||
|
||||
if(buffer.length > parseInt(meta.config.maximumFileSize, 10) * 1024) {
|
||||
if(file.size > parseInt(meta.config.maximumFileSize, 10) * 1024) {
|
||||
return callback(new Error('File too big'));
|
||||
}
|
||||
|
||||
var filename = 'upload-' + utils.generateUUID() + path.extname(file.name);
|
||||
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
|
||||
|
||||
fs.writeFile(uploadPath, buffer, function (err) {
|
||||
require('./file').saveFileToLocal(filename, file.path, function(err, upload) {
|
||||
if(err) {
|
||||
return callback(err);
|
||||
}
|
||||
|
||||
callback(null, {
|
||||
url: nconf.get('upload_url') + filename,
|
||||
url: upload.url,
|
||||
name: file.name
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Posts.reIndexPids = function(pids, callback) {
|
||||
|
||||
function reIndex(pid, next) {
|
||||
|
||||
@@ -12,6 +12,7 @@ var nconf = require('nconf'),
|
||||
meta = require('../meta'),
|
||||
plugins = require('../plugins'),
|
||||
image = require('./../image'),
|
||||
file = require('./../file'),
|
||||
Languages = require('../languages'),
|
||||
events = require('./../events'),
|
||||
utils = require('./../../public/src/utils'),
|
||||
@@ -102,8 +103,9 @@ var nconf = require('nconf'),
|
||||
});
|
||||
|
||||
app.post('/category/uploadpicture', function(req, res) {
|
||||
if (!req.user)
|
||||
if (!req.user) {
|
||||
return res.redirect('/403');
|
||||
}
|
||||
|
||||
var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'];
|
||||
var params = null;
|
||||
@@ -128,8 +130,9 @@ var nconf = require('nconf'),
|
||||
});
|
||||
|
||||
app.post('/uploadfavicon', function(req, res) {
|
||||
if (!req.user)
|
||||
if (!req.user) {
|
||||
return res.redirect('/403');
|
||||
}
|
||||
|
||||
var allowedTypes = ['image/x-icon', 'image/vnd.microsoft.icon'];
|
||||
|
||||
@@ -140,7 +143,9 @@ var nconf = require('nconf'),
|
||||
return;
|
||||
}
|
||||
|
||||
saveFileToLocal('favicon.ico', req, function(err, image) {
|
||||
file.saveFileToLocal('favicon.ico', req.files.userPhoto.path, function(err, image) {
|
||||
fs.unlink(req.files.userPhoto.path);
|
||||
|
||||
if(err) {
|
||||
return res.send({
|
||||
error: err.message
|
||||
@@ -155,8 +160,9 @@ var nconf = require('nconf'),
|
||||
|
||||
app.post('/uploadlogo', function(req, res) {
|
||||
|
||||
if (!req.user)
|
||||
if (!req.user) {
|
||||
return res.redirect('/403');
|
||||
}
|
||||
|
||||
var allowedTypes = ['image/png', 'image/jpeg', 'image/jpg', 'image/gif'];
|
||||
|
||||
@@ -183,6 +189,8 @@ var nconf = require('nconf'),
|
||||
|
||||
function uploadImage(filename, req, res) {
|
||||
function done(err, image) {
|
||||
fs.unlink(req.files.userPhoto.path);
|
||||
|
||||
if(err) {
|
||||
return res.send({
|
||||
error: err.message
|
||||
@@ -195,41 +203,12 @@ var nconf = require('nconf'),
|
||||
}
|
||||
|
||||
if(plugins.hasListeners('filter:uploadImage')) {
|
||||
plugins.fireHook('filter:uploadImage', {file: req.files.userPhoto.path, name:filename}, done);
|
||||
plugins.fireHook('filter:uploadImage', req.files.userPhoto, done);
|
||||
} else {
|
||||
saveFileToLocal(filename, req, done);
|
||||
file.saveFileToLocal(filename, req.files.userPhoto.path, done);
|
||||
}
|
||||
}
|
||||
|
||||
function saveFileToLocal(filename, req, callback) {
|
||||
|
||||
var tempPath = req.files.userPhoto.path;
|
||||
var extension = path.extname(req.files.userPhoto.name);
|
||||
|
||||
if (!extension) {
|
||||
return callback(new Error('Error uploading file! Error : Invalid extension!'));
|
||||
}
|
||||
|
||||
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
|
||||
|
||||
winston.info('Attempting upload to: ' + uploadPath);
|
||||
var is = fs.createReadStream(tempPath);
|
||||
var os = fs.createWriteStream(uploadPath);
|
||||
|
||||
is.on('end', function () {
|
||||
fs.unlinkSync(tempPath);
|
||||
|
||||
callback(null, {url: nconf.get('upload_url') + filename});
|
||||
});
|
||||
|
||||
os.on('error', function (err) {
|
||||
fs.unlinkSync(tempPath);
|
||||
winston.err(err);
|
||||
});
|
||||
|
||||
is.pipe(os);
|
||||
}
|
||||
|
||||
var custom_routes = {
|
||||
'routes': [],
|
||||
'api': []
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
var path = require('path'),
|
||||
nconf = require('nconf'),
|
||||
async = require('async'),
|
||||
fs = require('fs'),
|
||||
|
||||
db = require('../database'),
|
||||
user = require('../user'),
|
||||
@@ -448,6 +449,44 @@ var path = require('path'),
|
||||
}
|
||||
});
|
||||
|
||||
app.post('/post/upload', function(req, res, next) {
|
||||
if(!req.user) {
|
||||
return res.json(403, {message:'not allowed'});
|
||||
}
|
||||
var files = req.files.files;
|
||||
|
||||
if(!Array.isArray(files)) {
|
||||
return res.json(500, {message: 'invalid files'});
|
||||
}
|
||||
|
||||
// multiple files
|
||||
if(Array.isArray(files[0])) {
|
||||
files = files[0];
|
||||
}
|
||||
|
||||
function deleteTempFiles() {
|
||||
for(var i=0; i<files.length; ++i) {
|
||||
fs.unlink(files[i].path);
|
||||
}
|
||||
}
|
||||
|
||||
async.map(files, function(file, next) {
|
||||
if(file.type.match('image.*')) {
|
||||
posts.uploadPostImage(file, next);
|
||||
} else {
|
||||
posts.uploadPostFile(file, next);
|
||||
}
|
||||
}, function(err, images) {
|
||||
deleteTempFiles();
|
||||
|
||||
if(err) {
|
||||
return res.json(500, {message: err.message});
|
||||
}
|
||||
|
||||
res.json(200, images);
|
||||
});
|
||||
});
|
||||
|
||||
app.get('/reset', function (req, res) {
|
||||
res.json({});
|
||||
});
|
||||
|
||||
@@ -13,6 +13,7 @@ var fs = require('fs'),
|
||||
meta = require('./../meta'),
|
||||
plugins = require('./../plugins'),
|
||||
image = require('./../image'),
|
||||
file = require('./../file'),
|
||||
db = require('./../database');
|
||||
|
||||
(function (User) {
|
||||
@@ -134,6 +135,8 @@ var fs = require('fs'),
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
app.post('/uploadpicture', function (req, res) {
|
||||
if (!req.user) {
|
||||
return res.json(403, {
|
||||
@@ -174,6 +177,7 @@ var fs = require('fs'),
|
||||
}
|
||||
], function(err, result) {
|
||||
function done(err, image) {
|
||||
fs.unlink(req.files.userPhoto.path);
|
||||
if(err) {
|
||||
return res.send({error: err.message});
|
||||
}
|
||||
@@ -190,12 +194,12 @@ var fs = require('fs'),
|
||||
}
|
||||
|
||||
if(plugins.hasListeners('filter:uploadImage')) {
|
||||
plugins.fireHook('filter:uploadImage', {file: req.files.userPhoto.path, name: filename}, done);
|
||||
plugins.fireHook('filter:uploadImage', req.files.userPhoto, done);
|
||||
} else {
|
||||
|
||||
user.getUserField(req.user.uid, 'uploadedpicture', function (err, oldpicture) {
|
||||
if (!oldpicture) {
|
||||
saveFileToLocal(filename, req.files.userPhoto.path, done);
|
||||
file.saveFileToLocal(filename, req.files.userPhoto.path, done);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -206,7 +210,7 @@ var fs = require('fs'),
|
||||
winston.err(err);
|
||||
}
|
||||
|
||||
saveFileToLocal(filename, req.files.userPhoto.path, done);
|
||||
file.saveFileToLocal(filename, req.files.userPhoto.path, done);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -214,31 +218,6 @@ var fs = require('fs'),
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
function saveFileToLocal(filename, tempPath, callback) {
|
||||
|
||||
var uploadPath = path.join(nconf.get('base_dir'), nconf.get('upload_path'), filename);
|
||||
|
||||
winston.info('Saving file '+ filename +' to : ' + uploadPath);
|
||||
|
||||
var is = fs.createReadStream(tempPath);
|
||||
var os = fs.createWriteStream(uploadPath);
|
||||
|
||||
is.on('end', function () {
|
||||
fs.unlinkSync(tempPath);
|
||||
|
||||
callback(null, {url: nconf.get('upload_url') + filename});
|
||||
});
|
||||
|
||||
os.on('error', function (err) {
|
||||
fs.unlinkSync(tempPath);
|
||||
winston.error(err.message);
|
||||
});
|
||||
|
||||
is.pipe(os);
|
||||
}
|
||||
|
||||
|
||||
app.get('/api/user/:userslug/following', function (req, res, next) {
|
||||
var callerUID = req.user ? req.user.uid : '0';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user