1
0
mirror of https://github.com/Tygs/0bin.git synced 2023-08-10 21:13:00 +03:00
0bin/static/js/behavior.js

462 lines
13 KiB
JavaScript
Raw Normal View History

2012-04-26 13:38:55 +04:00
;
2012-04-26 23:04:36 +04:00
2012-04-28 19:11:32 +04:00
/* Start random number generator seeding ASAP *%
2012-04-24 22:15:38 +04:00
sjcl.random.startCollectors();
2012-04-28 19:11:32 +04:00
/* Ensure jquery use cache for ajax requests */
$.ajaxSetup({ cache: true });
2012-04-24 22:15:38 +04:00
/** Base64 + compress + encrypt, with callbacks before each operation,
and all of them are executed in a timed continuation to give
a change to the UI to respond.
*/
encrypt: function(key, content, toBase64Callback,
compressCallback, encryptCallback, doneCallback) {
setTimeout (function(){
content = sjcl.codec.utf8String.toBits(content);
if (toBase64Callback) {toBase64Callback()}
setTimeout(function(){
content = sjcl.codec.base64.fromBits(content);
if (compressCallback) {compressCallback()}
setTimeout(function(){
content = lzw.compress(content);
if (encryptCallback) {encryptCallback()}
setTimeout(function(){
content = sjcl.encrypt(key, content);
if (doneCallback) {doneCallback(content)}
}, 250);
}, 250);
}, 250);
}, 250);
2012-04-26 23:04:36 +04:00
},
/** Base64 decoding + uncompress + decrypt, with callbacks before each operation,
and all of them are executed in a timed continuation to give
a change to the UI to respond.
This is where using a library to fake synchronicity could start to be
useful, this code is starting be difficult to read. If anyone read this
and got a suggestion, by all means, speak your mind.
*/
decrypt: function(key, content, errorCallback, uncompressCallback,
fromBase64Callback, toStringCallback, doneCallback) {
/* Decrypt */
setTimeout(function(){
try {
content = sjcl.decrypt(key, content);
if (uncompressCallback) {uncompressCallback()}
/* Decompress */
setTimeout(function(){
try {
content = lzw.decompress(content);
if (fromBase64Callback) {fromBase64Callback()}
/* From base 64 to bits */
setTimeout(function(){
try {
content = sjcl.codec.base64.toBits(content);
if (toStringCallback) {toStringCallback()}
/* From bits to string */
setTimeout(function(){
try {
content = sjcl.codec.utf8String.fromBits(content);
if (doneCallback) {doneCallback(content)}
} catch (err) {
errorCallback(err);
}
}, 250); /* "End of from bits to string" */
} catch (err) {
errorCallback(err);
}
}, 250); /* End of "from base 64 to bits" */
} catch (err) {
errorCallback(err);
}
}, 250); /* End of "decompress" */
} catch (err) {
errorCallback(err);
}
}, 250); /* End of "decrypt" */
2012-04-26 23:04:36 +04:00
},
/** Create a random base64 string long enought to be suitable as
an encryption key */
2012-04-29 22:10:36 +04:00
makeKey: function() {
2012-04-26 17:26:58 +04:00
return sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0);
},
2012-04-29 22:10:36 +04:00
getDate: function(){
var date = new Date();
return date.getDate()+"-"+(date.getMonth()+1)+"-"+date.getFullYear();
},
2012-04-29 22:10:36 +04:00
getTime: function(){
var date = new Date();
var h=date.getHours();
var m=date.getMinutes();
var s=date.getSeconds();
if (h<10) {h = "0" + h}
if (m<10) {m = "0" + m}
if (s<10) {s = "0" + s}
return h+":"+m+":"+s;
},
numOrdA: function(a, b){
return (a-b);
},
2012-04-29 22:10:36 +04:00
getKeys: function(){
var keys = new Array();
for(i=0; i<=localStorage.length; i++){
if(localStorage.key(i) != null)
keys[i] = parseInt(localStorage.key(i),10);
}
return keys.sort(zerobin.numOrdA);
},
2012-04-28 23:13:32 +04:00
/** Get a tinyurl using JSONP */
getTinyURL: function(longURL, success) {
callback = 'zerobin_tiny_url_callback';
window[callback] = function(response){
success(response.tinyurl);
delete window[callback];
};
var api = 'http://json-tinyurl.appspot.com/?url=';
$.getJSON(api + encodeURIComponent(longURL) + '&callback=' + callback);
},
2012-04-29 22:10:36 +04:00
support: {
localstorage: function(){
return !!(localStorage);
},
history: function(){
return !!(window.history && history.pushState);
}
},
2012-04-29 22:10:36 +04:00
storatePaste: function(url){
if (zerobin.support.localstorage){
var date = new Date();
2012-04-29 22:10:36 +04:00
var paste = zerobin.getDate()+" "+zerobin.getTime()+";"+url;
var keys = zerobin.getKeys();
if(keys.length < 1)
keys[0] = 0;
if (localStorage.length > 19)
void localStorage.removeItem(keys[0]);
localStorage.setItem(keys.reverse()[0]+1, paste);
}
},
2012-04-29 22:10:36 +04:00
getPastes: function(){
if (zerobin.support.localstorage){
var pastes = '';
2012-04-29 22:10:36 +04:00
var keys = zerobin.getKeys();
keys.reverse();
for (i=0; i<=keys.length-1; i++)
2012-04-28 21:57:18 +04:00
{
var paste = localStorage.getItem(keys[i]);
2012-04-29 22:10:36 +04:00
if (paste.split(';')[0].split(' ')[0] == zerobin.getDate()){
var display_date = paste.split(';')[0].split(' ')[1];
2012-04-28 21:55:00 +04:00
var on_at = 'at ';
}else{
2012-04-29 22:10:36 +04:00
var display_date = zerobin.getDate();
2012-04-28 21:55:00 +04:00
var on_at = 'on ';
}
pastes = pastes + '<li><a class="items" href="' + paste.split(';')[1] + '">' + on_at + display_date + '</a></li>';
}
if (!pastes){
return '<i class="grey">Your previous pastes will be saved in your browser using <a href="http://www.w3.org/TR/webstorage/">localStorage</a>.</i>';
}
return pastes;
}else{
return 'Sorry your browser does not support LocalStorage, We cannot display your previous pastes.';
}
2012-04-29 01:51:54 +04:00
},
getPasteContent: function(){
2012-04-29 01:51:54 +04:00
var content_clone = '' ;
$("#paste-content li").each(function(index) {
content_clone = content_clone + $(this).text() + '\n';
});
return content_clone;
2012-04-29 22:10:04 +04:00
},
count: function(text, options) {
// Set option defaults
var crlf = /(\r?\n|\r)/g;
var whitespace = /(\r?\n|\r|\s+)/g;
options = options || {};
options.lineBreaks = options.lineBreaks || 1;
var length = text.length,
nonAscii = length - text.replace(/[\u0100-\uFFFF]/g, '').length,
lineBreaks = length - text.replace(crlf, '').length;
return length + nonAscii + Math.max(0, options.lineBreaks * (lineBreaks - 1));
2012-04-26 23:04:36 +04:00
}
};
2012-04-26 13:38:55 +04:00
2012-04-26 17:26:58 +04:00
$(function(){
2012-04-26 13:38:55 +04:00
2012-04-28 19:11:32 +04:00
/**
On the create paste page:
On click on the send button, compress and encrypt data before
posting it using ajax. Then redirect to the address of the
newly created paste, adding the key in the hash.
*/
2012-04-28 16:50:48 +04:00
$('button[type=submit]').live("click", function(e){
2012-04-26 13:38:55 +04:00
e.preventDefault();
var paste = $('textarea').val();
2012-04-29 22:10:04 +04:00
var sizebytes = zerobin.count($('#content').val(), { });
2012-04-29 22:35:28 +04:00
var oversized = sizebytes > zerobin.max_size;
if (oversized){
2012-04-29 22:10:04 +04:00
$('.max-size-reached').show();
$('.file-size').text(Math.round(sizebytes/1024));
2012-04-29 22:35:28 +04:00
}
if (!oversized && paste.trim()) {
$('form.well p').hide();
$loading = $('form.well .progress').show();
var $loading = $('form.well .progress .bar')
.css('width', '25%')
.text('Converting paste to bits...');
/* Encode, compress, encrypt and send the paste then redirect the user
to the new paste. We ensure a loading animation is updated
during the process by passing callbacks.
*/
try {
var expiration = $('#expiration').val();
2012-04-29 22:10:36 +04:00
var key = zerobin.makeKey();
zerobin.encrypt(key, paste,
function(){$loading.text('Encoding to base64...').css('width', '45%')},
function(){$loading.text('Compressing...').css('width', '65%')},
function(){$loading.text('Encrypting...').css('width', '85%')},
/* This block deal with sending the data, redirection or error handling */
function(content){
$loading.text('Sending...').css('width', '95%');
var data = {content: content, expiration: expiration};
$.post('/paste/create', data)
.error(function(error) {
$('form.well p').show();
$loading.hide();
alert('Error: paste could not be saved. Please try again later.');
})
.success(function(data) {
$loading.text('Redirecting to new paste...').css('width', '100%');
var paste_url = '/paste/' + data['paste'] + '#' + key;
2012-04-29 22:10:36 +04:00
zerobin.storatePaste(paste_url);
window.location = (paste_url);
});
}
);
} catch (err) {
$('form.well p').show();
$loading.hide();
alert('Error: paste could not be encrypted. Aborting.');
}
2012-04-26 13:38:55 +04:00
}
2012-04-24 22:15:38 +04:00
2012-04-26 13:38:55 +04:00
});
2012-04-24 22:15:38 +04:00
2012-04-29 22:35:28 +04:00
**
DECRYPTION:
On the display paste page, decrypt and decompress the paste content,
add syntax coloration then setup the copy to clipboard button.
2012-04-28 19:11:32 +04:00
*/
2012-04-26 17:26:58 +04:00
var content = $('#paste-content').text().trim();
var key = window.location.hash.substring(1);
2012-04-28 21:57:18 +04:00
var error = false;
2012-04-26 17:26:58 +04:00
if (content && key) {
2012-04-28 21:57:18 +04:00
var $bar = $('.well form .progress').show();
var $loading = $('.well form .progress .bar').css('width', '25%')
.text('Decrypting paste...');
zerobin.decrypt(key, content,
/* On error*/
function(){
$bar.hide();
alert('Could not decrypt data (Wrong key ?)');
},
/* Update progress bar */
function(){$loading.text('Decompressing...').css('width', '45%')},
function(){$loading.text('Base64 decoding...').css('width', '65%')},
function(){$loading.text('From bits to string...').css('width', '85%')},
/* When done */
function(content){
/* Decrypted content goes back to initial container*/
$('#paste-content').text(content);
content = '';
$loading.text('Code coloration...').css('width', '95%');
/* Add a continuation to let the UI redraw */
setTimeout(function(){
/* Setup link to get the paste short url*/
$('#short-url').click(function(e) {
e.preventDefault();
$('#short-url').text('Loading short url...');
zerobin.getTinyURL(window.location.toString(), function(tinyurl){
clip.setText(tinyurl);
$('#copy-success').hide();
$('#short-url-success')
.html('Short url: <a href="' + tinyurk + '">' + tinyurk + '</a>')
.show('fadeUp');
$('#short-url').text('Get short url');
});
});
2012-04-28 21:57:18 +04:00
/* Setup flash clipboard button */
2012-04-29 22:10:36 +04:00
ZeroClipboard.setMoviePath('/static/js/ZeroClipboard.swf');
2012-04-28 21:57:18 +04:00
var clip = new ZeroClipboard.Client();
clip.addEventListener('mouseup', function(){
clip.setText(zerobin.getPasteContent());
});
clip.addEventListener('complete', function(){
$('#copy-success').show('fadeUp', function(){clip.reposition()});
2012-04-28 23:13:32 +04:00
});
clip.glue('clip-button');
2012-04-28 23:13:32 +04:00
window.onresize = clip.reposition;
2012-04-28 21:57:18 +04:00
/** Syntaxic coloration */
prettyPrint();
2012-04-28 21:57:18 +04:00
/* Display result */
$loading.text('Done').css('width', '100%');
$bar.hide();
}, 250);
2012-04-28 21:57:18 +04:00
}
);
} /* End of "DECRYPTION" */
2012-04-28 21:57:18 +04:00
2012-04-28 19:11:32 +04:00
/* Synchronize expiration select boxes value */
$('.paste-option select').live('change', function(){
var value = $(this).val();
$('.paste-option select').val(value);
});
2012-04-28 19:11:32 +04:00
/* Resize Textarea according to content */
$('#content').elastic();
2012-04-28 15:25:43 +04:00
/* Display bottom paste option buttons when needed */
2012-04-28 14:51:30 +04:00
$('#content').live('keyup change', function(){
2012-04-28 19:11:32 +04:00
if($('#content').height() < 400 ){
$('.paste-option.down').remove();
}
else {
if ($('.paste-option').length == 1) {
$('.paste-option').clone().addClass('down').appendTo('form.well');
}
}
2012-04-29 22:10:04 +04:00
});
/* Display previous pastes */
2012-04-29 22:10:36 +04:00
$('.previous-pastes .items').html(zerobin.getPastes());
2012-04-28 21:58:30 +04:00
2012-04-28 21:55:00 +04:00
/* clone a paste */
$('.btn-clone').click(function(e){
e.preventDefault();
var content_clone = zerobin.getPasteContent();
2012-04-28 21:55:00 +04:00
$('.submit-form').show();
2012-04-28 22:09:51 +04:00
$('.paste-form').remove();
2012-04-28 21:55:00 +04:00
$('#content').val(content_clone);
2012-04-28 22:09:51 +04:00
$('#content').trigger('change');
2012-04-28 21:55:00 +04:00
});
2012-04-29 19:36:26 +04:00
/* Upload file using HTML5 File API */
if (window.File && window.FileReader && window.FileList && window.Blob) {
$('.file-upload').show();
}
var file_upload = function(file) {
var reader = new FileReader();
reader.onload = function(event) {
var content = event.target.result;
$('#content').val(content);
$('#content').trigger('change');
};
reader.readAsText(file[0]);
}
try {
$('#file-upload').change(function() {
file_upload(this.files);
});
}
catch (e) {
alert(e);
}
$('#file-upload').mouseover(function(){
$(this).css( 'cursor', 'pointer' );
});
2012-04-29 22:10:04 +04:00
/* Alerts */
$(".close").click(function(){
$(this).parent().fadeOut();
2012-04-28 21:55:00 +04:00
});
}); /* End of "document ready" jquery callback */