form.js
328 lines
| 9.2 KiB
| application/javascript
|
JavascriptLexer
neko259
|
r1461 | var ITEM_FILE_SOURCE = 'fileSource'; | ||
neko259
|
r1766 | var URL_STICKERS = '/api/stickers'; | ||
neko259
|
r1702 | var MIN_INPUT_LENGTH = 3; | ||
neko259
|
r1766 | var URL_DELIMITER = '\n'; | ||
neko259
|
r1998 | // TODO This needs to be the same for attachment download time limit. | ||
var POST_AJAX_TIMEOUT = 30000; | ||||
neko259
|
r2034 | var REPLY_TO_MSG = '.reply-to-message'; | ||
neko259
|
r1461 | |||
neko259
|
r1985 | var pastedImages = []; | ||
neko259
|
r680 | $('input[name=image]').wrap($('<div class="file_wrap"></div>')); | ||
neko259
|
r676 | |||
$('body').on('change', 'input[name=image]', function(event) { | ||||
neko259
|
r673 | var file = event.target.files[0]; | ||
if(file.type.match('image.*')) { | ||||
var fileReader = new FileReader(); | ||||
fileReader.addEventListener("load", function(event) { | ||||
neko259
|
r680 | var wrapper = $('.file_wrap'); | ||
wrapper.find('.file-thumb').remove(); | ||||
wrapper.append( | ||||
$('<div class="file-thumb" style="background-image: url('+event.target.result+')"></div>') | ||||
neko259
|
r673 | ); | ||
}); | ||||
fileReader.readAsDataURL(file); | ||||
} | ||||
neko259
|
r1005 | }); | ||
var form = $('#form'); | ||||
$('textarea').keypress(function(event) { | ||||
r1577 | if ((event.which == 10 || event.which == 13) && event.ctrlKey) { | |||
neko259
|
r1428 | form.find('input[type=submit]').click(); | ||
neko259
|
r1005 | } | ||
neko259
|
r1217 | }); | ||
$('#preview-button').click(function() { | ||||
var data = { | ||||
neko259
|
r1768 | raw_text: $('textarea#id_text').val() | ||
neko259
|
r1217 | } | ||
var diffUrl = '/api/preview/'; | ||||
$.post(diffUrl, | ||||
data, | ||||
function(data) { | ||||
var previewTextBlock = $('#preview-text'); | ||||
previewTextBlock.html(data); | ||||
previewTextBlock.show(); | ||||
neko259
|
r1717 | |||
addScriptsToPost(previewTextBlock); | ||||
neko259
|
r1217 | }) | ||
neko259
|
r1428 | }); | ||
/** | ||||
* Show text in the errors row of the form. | ||||
* @param form | ||||
* @param text | ||||
*/ | ||||
function showAsErrors(form, text) { | ||||
form.children('.form-errors').remove(); | ||||
if (text.length > 0) { | ||||
var errorList = $('<div class="form-errors">' + text + '<div>'); | ||||
errorList.appendTo(form); | ||||
} | ||||
} | ||||
function addHiddenInput(form, name, value) { | ||||
form.find('input[name=' + name + ']').val(value); | ||||
} | ||||
neko259
|
r1461 | function selectFileChoice() { | ||
var file_input = $('#id_file'); | ||||
var url_input = $('#id_file_url'); | ||||
var file_input_row = file_input.parent().parent(); | ||||
var url_input_row = url_input.parent().parent(); | ||||
file_input_row.toggle(); | ||||
url_input_row.toggle(); | ||||
url_input.val(''); | ||||
file_input.val(''); | ||||
var source; | ||||
if (file_input_row.is(':visible')) { | ||||
source = 'file'; | ||||
} else { | ||||
source = 'url'; | ||||
} | ||||
localStorage.setItem(ITEM_FILE_SOURCE, source); | ||||
} | ||||
neko259
|
r1769 | function getPostTextarea() { | ||
return $('textarea#id_text'); | ||||
} | ||||
neko259
|
r1985 | function addOnImagePaste() { | ||
$('#id_file_1').on('paste', function(event) { | ||||
var items = (event.clipboardData || event.originalEvent.clipboardData).items; | ||||
for (index in items) { | ||||
var item = items[index]; | ||||
if (item.kind === 'file') { | ||||
var blob = item.getAsFile(); | ||||
pastedImages.push(blob); | ||||
var pastedImagesList = $('#pasted-images'); | ||||
if (pastedImagesList.length === 0) { | ||||
pastedImagesList = $('<div id="pasted-images" />'); | ||||
$('#id_file_1').parent().append(pastedImagesList); | ||||
} | ||||
neko259
|
r1989 | var fr = new FileReader(); | ||
fr.onload = function () { | ||||
var img = $('<img class="image-preview" />'); | ||||
img.attr('src', fr.result); | ||||
pastedImagesList.append(img); | ||||
neko259
|
r1991 | img.on("click", function() { | ||
// Remove the image from all lists | ||||
var itemIndex = $(this).index(); | ||||
pastedImages.splice(itemIndex, 1); | ||||
$(this).remove(); | ||||
}); | ||||
neko259
|
r1989 | }; | ||
fr.readAsDataURL(blob); | ||||
neko259
|
r1985 | } | ||
} | ||||
}); | ||||
} | ||||
neko259
|
r1998 | /** | ||
* When the form is posted, this method will be run as a callback | ||||
*/ | ||||
function updateOnPost(response, statusText, xhr, form) { | ||||
var json = $.parseJSON(response); | ||||
var status = json.status; | ||||
var url = json.url; | ||||
showAsErrors(form, ''); | ||||
$('.post-form-w').unblock(); | ||||
if (status === 'ok') { | ||||
if (url) { | ||||
document.location = url; | ||||
} else { | ||||
resetForm(); | ||||
getThreadDiff(); | ||||
scrollToBottom(); | ||||
} | ||||
} else { | ||||
var errors = json.errors; | ||||
for (var i = 0; i < errors.length; i++) { | ||||
var fieldErrors = errors[i]; | ||||
var error = fieldErrors.errors; | ||||
showAsErrors(form, error); | ||||
} | ||||
} | ||||
} | ||||
function initAjaxForm(openingPostId) { | ||||
var form = $('#form'); | ||||
var url = '/api/add_post/'; | ||||
if (openingPostId) { | ||||
url += openingPostId + '/'; | ||||
} | ||||
if (form.length > 0) { | ||||
var options = { | ||||
beforeSubmit: function(arr, form, options) { | ||||
$('.post-form-w').block({ message: gettext('Sending message...') }); | ||||
$.each(pastedImages, function(i, blob) { | ||||
arr.push({ | ||||
name: "file_0", | ||||
value: blob | ||||
}); | ||||
}); | ||||
}, | ||||
success: updateOnPost, | ||||
error: function(xhr, textStatus, errorString) { | ||||
var errorText = gettext('Server error: ') + textStatus; | ||||
if (errorString) { | ||||
errorText += ' / ' + errorString; | ||||
} | ||||
showAsErrors(form, errorText); | ||||
$('.post-form-w').unblock(); | ||||
}, | ||||
url: url, | ||||
timeout: POST_AJAX_TIMEOUT | ||||
}; | ||||
form.ajaxForm(options); | ||||
} | ||||
} | ||||
neko259
|
r2034 | function getForm() { | ||
return $('.post-form-w'); | ||||
} | ||||
/** | ||||
* Clear all entered values in the form fields | ||||
*/ | ||||
function resetForm() { | ||||
var form = getForm(); | ||||
form.find('input:text, input:password, input:file, textarea').val(''); | ||||
pastedImages = []; | ||||
$('#pasted-images').remove(); | ||||
$('.file_wrap').find('.file-thumb').remove(); | ||||
$('#preview-text').hide(); | ||||
resetFormPosition(form); | ||||
} | ||||
function resetFormPosition(form) { | ||||
form.insertBefore($('footer')); | ||||
$(REPLY_TO_MSG).hide(); | ||||
} | ||||
neko259
|
r1428 | $(document).ready(function() { | ||
var powDifficulty = parseInt($('body').attr('data-pow-difficulty')); | ||||
neko259
|
r1465 | if (powDifficulty > 0 && typeof SharedWorker != 'undefined') { | ||
neko259
|
r1468 | var worker = new SharedWorker($('.post-form').attr('data-pow-script')); | ||
neko259
|
r1462 | worker.port.onmessage = function(e) { | ||
neko259
|
r1428 | var form = $('#form'); | ||
addHiddenInput(form, 'timestamp', e.data.timestamp); | ||||
addHiddenInput(form, 'iteration', e.data.iteration); | ||||
addHiddenInput(form, 'guess', e.data.guess); | ||||
form.submit(); | ||||
neko259
|
r1451 | $('.post-form-w').unblock(); | ||
neko259
|
r1428 | }; | ||
neko259
|
r1466 | worker.onerror = function(event){ | ||
throw new Error(event.message + " (" + event.filename + ":" + event.lineno + ")"); | ||||
neko259
|
r1464 | }; | ||
neko259
|
r1462 | worker.port.start(); | ||
neko259
|
r1428 | |||
var form = $('#form'); | ||||
var submitButton = form.find('input[type=submit]'); | ||||
submitButton.click(function() { | ||||
showAsErrors(form, gettext('Computing PoW...')); | ||||
neko259
|
r1451 | $('.post-form-w').block({ message: gettext('Computing PoW...') }) | ||
neko259
|
r1428 | |||
neko259
|
r1768 | var msg = $('textarea#id_text').val().trim(); | ||
neko259
|
r1428 | |||
var data = { | ||||
msg: msg, | ||||
difficulty: parseInt($('body').attr('data-pow-difficulty')), | ||||
neko259
|
r1468 | hasher: $('.post-form').attr('data-hasher') | ||
neko259
|
r1428 | }; | ||
neko259
|
r1462 | worker.port.postMessage(data); | ||
neko259
|
r1428 | |||
return false; | ||||
}); | ||||
} | ||||
neko259
|
r1461 | |||
r1639 | var $fileSourceButton = $('#file-source-button'); | |||
if (window.localStorage) { | ||||
var source = localStorage.getItem(ITEM_FILE_SOURCE); | ||||
if (source == null) { | ||||
source = 'file'; | ||||
} | ||||
if (source == 'file') { | ||||
$('#id_file_url').parent().parent().hide(); | ||||
} else { | ||||
$('#id_file').parent().parent().hide(); | ||||
} | ||||
$fileSourceButton.click(function() { | ||||
selectFileChoice(); | ||||
}); | ||||
neko259
|
r1461 | } else { | ||
r1639 | $fileSourceButton.hide(); | |||
neko259
|
r1461 | } | ||
neko259
|
r1702 | |||
neko259
|
r1985 | addOnImagePaste(); | ||
neko259
|
r1766 | // Stickers autocomplete | ||
function split( val ) { | ||||
return val.split(URL_DELIMITER); | ||||
} | ||||
function extractLast( term ) { | ||||
return split(term).pop(); | ||||
} | ||||
$('#id_file_1').autocomplete({ | ||||
neko259
|
r1702 | source: function( request, response ) { | ||
$.getJSON(URL_STICKERS, { | ||||
neko259
|
r1766 | term: extractLast( request.term ) | ||
neko259
|
r1702 | }, response); | ||
}, | ||||
search: function() { | ||||
// custom minLength | ||||
neko259
|
r1766 | var term = extractLast( this.value ); | ||
neko259
|
r1702 | if (term.length < MIN_INPUT_LENGTH) { | ||
return false; | ||||
} | ||||
}, | ||||
focus: function() { | ||||
// prevent value inserted on focus | ||||
return false; | ||||
}, | ||||
select: function( event, ui ) { | ||||
neko259
|
r1766 | var terms = split( this.value ); | ||
// remove the current input | ||||
terms.pop(); | ||||
// add the selected item | ||||
terms.push( ui.item.alias ); | ||||
// add placeholder to get the comma-and-space at the end | ||||
terms.push(""); | ||||
this.value = terms.join(URL_DELIMITER); | ||||
neko259
|
r1702 | return false; | ||
} | ||||
}) | ||||
.autocomplete( "instance" )._renderItem = function( ul, item ) { | ||||
return $( "<li>" ) | ||||
.append( "<div>" + '<img src="' + item.thumb + '">' + '<br />' + item.alias + "</div>" ) | ||||
.appendTo( ul ); | ||||
}; | ||||
neko259
|
r1428 | }); | ||