Added preview for
- Video (HTML5) - Audio (HTML5) - PDF (Browser capabilities) attachment. Added drag & drop functionality Added attachment preview to preview before submitting
This commit is contained in:
parent
dd721c651b
commit
faf596aeb7
8 changed files with 238 additions and 58 deletions
|
@ -64,7 +64,7 @@ languageselection = false
|
|||
; scripts or run your site behind certain DDoS-protection services.
|
||||
; Check the documentation at https://content-security-policy.com/
|
||||
; Note: If you use a bootstrap theme, you can remove the allow-popups from the sandbox restrictions.
|
||||
; cspheader = "default-src 'none'; manifest-src 'self'; connect-src *; script-src 'self'; style-src 'self'; font-src 'self'; img-src 'self' data:; referrer no-referrer; sandbox allow-same-origin allow-scripts allow-forms allow-popups"
|
||||
; cspheader = "default-src 'none'; manifest-src 'self'; connect-src *; script-src 'self'; style-src 'self'; font-src 'self'; img-src 'self' data:; media-src 'self' data:; object-src 'self' data:; Referrer-Policy: 'no-referrer'"
|
||||
|
||||
; stay compatible with PrivateBin Alpha 0.19, less secure
|
||||
; if enabled will use base64.js version 1.7 instead of 2.1.9 and sha1 instead of
|
||||
|
|
|
@ -64,12 +64,25 @@ body.navbar-spacing {
|
|||
margin-right: 8px;
|
||||
}
|
||||
|
||||
#image img {
|
||||
#attachmentPreview img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
#attachmentPreview .pdfPreview {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.dragAndDropFile{
|
||||
color:#777;
|
||||
font-size:1em;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
|
||||
#deletelink {
|
||||
float: right;
|
||||
}
|
||||
|
|
|
@ -104,11 +104,23 @@ h3.title {
|
|||
font-family: Consolas, "Lucida Console", "DejaVu Sans Mono", Monaco, monospace;
|
||||
}
|
||||
|
||||
#image img {
|
||||
#attachmentPreview img {
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
#attachmentPreview .pdfPreview {
|
||||
width: 100%;
|
||||
height: 100vh;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.dragAndDropFile{
|
||||
color:#777;
|
||||
font-size:1em;
|
||||
display:inline;
|
||||
}
|
||||
|
||||
#status {
|
||||
clear: both;
|
||||
padding: 5px 10px;
|
||||
|
@ -249,7 +261,7 @@ input {
|
|||
font-weight: bold !important;
|
||||
}
|
||||
|
||||
#image, .nonworking {
|
||||
#attachmentPreview, .nonworking {
|
||||
background-color: #fff;
|
||||
color: #000;
|
||||
width: 100%;
|
||||
|
|
|
@ -131,6 +131,8 @@
|
|||
"Download attachment": "Anhang herunterladen",
|
||||
"Cloned file attached.": "Kopierte Datei angehängt.",
|
||||
"Attach a file": "Datei anhängen",
|
||||
"or drag & drop file": "oder per Drag & Drop einfügen",
|
||||
"File too large, to display a preview. Please download the attachment.": "Datei zu groß, um als Vorschau angezeigt zu werden. Bitte Anhang herunterladen.",
|
||||
"Remove attachment": "Anhang entfernen",
|
||||
"Your browser does not support uploading encrypted files. Please use a newer browser.":
|
||||
"Dein Browser unterstützt das hochladen von verschlüsselten Dateien nicht. Bitte verwende einen neueren Browser.",
|
||||
|
|
233
js/privatebin.js
233
js/privatebin.js
|
@ -339,6 +339,180 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* static attachment helper methods
|
||||
*
|
||||
* @name helper
|
||||
* @class
|
||||
*/
|
||||
var attachmentHelpers = {
|
||||
attachmentData: undefined,
|
||||
file: undefined,
|
||||
|
||||
/*
|
||||
* Read file data as dataURL using the FileReader API
|
||||
* https://developer.mozilla.org/en-US/docs/Web/API/FileReader#readAsDataURL()
|
||||
*/
|
||||
readFileData: function (file) {
|
||||
if (typeof FileReader === undefined) {
|
||||
// revert loading status…
|
||||
this.stateNewPaste();
|
||||
this.showError(i18n._('Your browser does not support uploading encrypted files. Please use a newer browser.'));
|
||||
return;
|
||||
}
|
||||
|
||||
var fr = new FileReader();
|
||||
if (file === undefined) {
|
||||
file = controller.fileInput[0].files[0];
|
||||
$('#dragAndDropFileName').text('');
|
||||
} else {
|
||||
$('#dragAndDropFileName').text(file.name);
|
||||
}
|
||||
|
||||
attachmentHelpers.file = file;
|
||||
|
||||
fr.onload = function (e) {
|
||||
var dataURL = e.target.result;
|
||||
attachmentHelpers.attachmentData = dataURL;
|
||||
|
||||
if (controller.messagePreview.parent().hasClass('active')) {
|
||||
attachmentHelpers.handleFilePreviews(controller.attachmentPreview, dataURL);
|
||||
}
|
||||
};
|
||||
fr.readAsDataURL(file);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle the preview of files.
|
||||
* @argument {DOM Element} element where the preview should be appended.
|
||||
* @argument {File Data} data of the file to be displayed.
|
||||
*/
|
||||
handleFilePreviews: function (element, data) {
|
||||
if (data) {
|
||||
var mimeType = this.getMimeTypeFromDataURL(data);
|
||||
|
||||
if (mimeType.match(/image\//i)) {
|
||||
this.showImagePreview(element, data);
|
||||
} else if (mimeType.match(/video\//i)) {
|
||||
this.showVideoPreview(element, data, mimeType);
|
||||
} else if (mimeType.match(/audio\//i)) {
|
||||
this.showAudioPreview(element, data, mimeType);
|
||||
} else if (mimeType.match(/\/pdf/i)) {
|
||||
this.showPDFPreview(element, data);
|
||||
}
|
||||
//else {
|
||||
//console.log("file but no image/video/audio/pdf");
|
||||
//}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get Mime Type from a DataURL
|
||||
*
|
||||
* @param {type} dataURL
|
||||
* @returns Mime Type from a dataURL as obtained for a file using the FileReader API https://developer.mozilla.org/en-US/docs/Web/API/FileReader#readAsDataURL()
|
||||
*/
|
||||
getMimeTypeFromDataURL: function (dataURL) {
|
||||
return dataURL.slice(dataURL.indexOf('data:') + 5, dataURL.indexOf(';base64,'));
|
||||
},
|
||||
|
||||
showImagePreview: function (element, image) {
|
||||
element.html(
|
||||
$(document.createElement('img'))
|
||||
.attr('src', image)
|
||||
.attr('class', 'img-thumbnail')
|
||||
);
|
||||
element.removeClass('hidden');
|
||||
},
|
||||
|
||||
showVideoPreview: function (element, video, mimeType) {
|
||||
var videoPlayer = $(document.createElement('video'))
|
||||
.attr('controls', 'true')
|
||||
.attr('autoplay', 'true')
|
||||
.attr('loop', 'true')
|
||||
.attr('class', 'img-thumbnail');
|
||||
|
||||
videoPlayer.append($(document.createElement('source'))
|
||||
.attr('type', mimeType)
|
||||
.attr('src', video));
|
||||
element.html(videoPlayer);
|
||||
element.removeClass('hidden');
|
||||
},
|
||||
|
||||
showAudioPreview: function (element, audio, mimeType) {
|
||||
var audioPlayer = $(document.createElement('audio'))
|
||||
.attr('controls', 'true')
|
||||
.attr('autoplay', 'true');
|
||||
|
||||
audioPlayer.append($(document.createElement('source'))
|
||||
.attr('type', mimeType)
|
||||
.attr('src', audio));
|
||||
element.html(audioPlayer);
|
||||
element.removeClass('hidden');
|
||||
},
|
||||
|
||||
showPDFPreview: function (element, pdf) {
|
||||
//PDFs are only displayed if the filesize is smaller than about 1MB (after base64 encoding).
|
||||
//Bigger filesizes currently cause crashes in various browsers.
|
||||
//See also: https://code.google.com/p/chromium/issues/detail?id=69227
|
||||
|
||||
//Firefox crashes with files that are about 1.5MB
|
||||
//The performance with 1MB files is bareable
|
||||
if (pdf.length < 1398488) {
|
||||
|
||||
//Fallback for browsers, that don't support the vh unit
|
||||
var clientHeight = $(window).height();
|
||||
|
||||
element.html(
|
||||
$(document.createElement('embed'))
|
||||
.attr('src', pdf)
|
||||
.attr('type', 'application/pdf')
|
||||
.attr('class', 'pdfPreview')
|
||||
.css('height', clientHeight)
|
||||
);
|
||||
element.removeClass('hidden');
|
||||
} else {
|
||||
controller.showError(i18n._('File too large, to display a preview. Please download the attachment.'));
|
||||
}
|
||||
},
|
||||
|
||||
addDragDropHandler: function () {
|
||||
var fileInput = controller.fileInput;
|
||||
|
||||
if (fileInput.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
function ignoreDragDrop(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
}
|
||||
|
||||
function drop(e) {
|
||||
e.stopPropagation();
|
||||
e.preventDefault();
|
||||
|
||||
if (fileInput) {
|
||||
var file = e.dataTransfer.files[0];
|
||||
//Clear the file input:
|
||||
fileInput.wrap('<form>').closest('form').get(0).reset();
|
||||
fileInput.unwrap();
|
||||
//Only works in Chrome:
|
||||
//fileInput[0].files = e.dataTransfer.files;
|
||||
|
||||
attachmentHelpers.readFileData(file);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("drop", drop, false);
|
||||
document.addEventListener("dragenter", ignoreDragDrop, false);
|
||||
document.addEventListener("dragover", ignoreDragDrop, false);
|
||||
fileInput.on("change", function () {
|
||||
attachmentHelpers.readFileData();
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* internationalization methods
|
||||
*
|
||||
|
@ -748,18 +922,8 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
}
|
||||
this.attachmentLink.attr('href', attachment);
|
||||
this.attachment.removeClass('hidden');
|
||||
attachmentHelpers.handleFilePreviews(this.attachmentPreview, attachment);
|
||||
|
||||
// if the attachment is an image, display it
|
||||
var imagePrefix = 'data:image/';
|
||||
if (attachment.substring(0, imagePrefix.length) === imagePrefix)
|
||||
{
|
||||
this.image.html(
|
||||
$(document.createElement('img'))
|
||||
.attr('src', attachment)
|
||||
.attr('class', 'img-thumbnail')
|
||||
);
|
||||
this.image.removeClass('hidden');
|
||||
}
|
||||
}
|
||||
var cleartext = filter.decipher(key, password, paste.data);
|
||||
if (cleartext.length === 0 && password.length === 0 && !paste.attachment)
|
||||
|
@ -1018,11 +1182,12 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
sendData: function(event)
|
||||
{
|
||||
event.preventDefault();
|
||||
var file = document.getElementById('file'),
|
||||
files = (file && file.files) ? file.files : null; // FileList object
|
||||
|
||||
var fileName = attachmentHelpers.file ? attachmentHelpers.file.name : this.attachmentLink.attr('download');
|
||||
var attachmentData = attachmentHelpers.attachmentData || this.attachmentLink.attr('href');
|
||||
|
||||
// do not send if no data.
|
||||
if (this.message.val().length === 0 && !(files && files[0]))
|
||||
if (this.message.val().length === 0 && !(fileName && attachmentData))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@ -1045,35 +1210,12 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
|
||||
var randomkey = sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0),
|
||||
password = this.passwordInput.val();
|
||||
if(files && files[0])
|
||||
if(fileName)
|
||||
{
|
||||
if(typeof FileReader === undefined)
|
||||
{
|
||||
// revert loading status…
|
||||
this.stateNewPaste();
|
||||
this.showError(i18n._('Your browser does not support uploading encrypted files. Please use a newer browser.'));
|
||||
return;
|
||||
}
|
||||
var reader = new FileReader();
|
||||
// closure to capture the file information
|
||||
reader.onload = (function(theFile)
|
||||
{
|
||||
return function(e) {
|
||||
controller.sendDataContinue(
|
||||
randomkey,
|
||||
filter.cipher(randomkey, password, e.target.result),
|
||||
filter.cipher(randomkey, password, theFile.name)
|
||||
);
|
||||
};
|
||||
})(files[0]);
|
||||
reader.readAsDataURL(files[0]);
|
||||
}
|
||||
else if(this.attachmentLink.attr('href'))
|
||||
{
|
||||
this.sendDataContinue(
|
||||
randomkey,
|
||||
filter.cipher(randomkey, password, this.attachmentLink.attr('href')),
|
||||
this.attachmentLink.attr('download')
|
||||
filter.cipher(randomkey, password, attachmentData),
|
||||
filter.cipher(randomkey, password, fileName)
|
||||
);
|
||||
}
|
||||
else
|
||||
|
@ -1199,6 +1341,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
{
|
||||
this.message.text('');
|
||||
this.attachment.addClass('hidden');
|
||||
this.attachmentPreview.addClass('hidden');
|
||||
this.cloneButton.addClass('hidden');
|
||||
this.rawTextButton.addClass('hidden');
|
||||
this.remainingTime.addClass('hidden');
|
||||
|
@ -1317,6 +1460,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
this.preview.addClass('hidden');
|
||||
}
|
||||
|
||||
this.attachmentPreview.removeClass('hidden');
|
||||
this.pasteResult.addClass('hidden');
|
||||
this.message.addClass('hidden');
|
||||
this.clearText.addClass('hidden');
|
||||
|
@ -1547,6 +1691,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
this.message.focus();
|
||||
this.stateExistingPaste(true);
|
||||
this.formatPaste($('#pasteFormatter').val(), this.message.val());
|
||||
attachmentHelpers.handleFilePreviews(this.attachmentPreview, attachmentHelpers.attachmentData);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1602,6 +1747,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
this.message.text('');
|
||||
this.changeBurnAfterReading();
|
||||
this.changeOpenDisc();
|
||||
attachmentHelpers.addDragDropHandler();
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1618,6 +1764,9 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
// the only way to deselect the file is to recreate the input
|
||||
this.fileWrap.html(this.fileWrap.html());
|
||||
this.fileWrap.removeClass('hidden');
|
||||
|
||||
attachmentHelpers.file = undefined;
|
||||
attachmentHelpers.attachmentData = undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1776,7 +1925,8 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
this.fileRemoveButton = $('#fileremovebutton');
|
||||
this.fileWrap = $('#filewrap');
|
||||
this.formatter = $('#formatter');
|
||||
this.image = $('#image');
|
||||
this.attachmentPreview = $('#attachmentPreview');
|
||||
this.fileInput = $('#file');
|
||||
this.loadingIndicator = $('#loadingindicator');
|
||||
this.message = $('#message');
|
||||
this.messageEdit = $('#messageedit');
|
||||
|
@ -1846,6 +1996,7 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) {
|
|||
|
||||
return {
|
||||
helper: helper,
|
||||
attachmentHelpers: attachmentHelpers,
|
||||
i18n: i18n,
|
||||
filter: filter,
|
||||
controller: controller
|
||||
|
|
|
@ -51,7 +51,7 @@ class Configuration
|
|||
'languagedefault' => '',
|
||||
'urlshortener' => '',
|
||||
'icon' => 'identicon',
|
||||
'cspheader' => 'default-src \'none\'; manifest-src \'self\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\' data:; referrer no-referrer; sandbox allow-same-origin allow-scripts allow-forms allow-popups',
|
||||
'cspheader' => 'default-src \'none\'; manifest-src \'self\'; connect-src *; script-src \'self\'; style-src \'self\'; font-src \'self\'; img-src \'self\' data:; media-src \'self\' data:; object-src \'self\' data:; Referrer-Policy: \'no-referrer\'',
|
||||
'zerobincompatibility' => false,
|
||||
),
|
||||
'expire' => array(
|
||||
|
|
|
@ -69,7 +69,7 @@ if ($MARKDOWN):
|
|||
<?php
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-vYYJYraxQNOf41XtehLBU2JbIQ2Uffe+n8TjHyWkpqoZdZX4aL5zyABrUNvRUP02+AxoRsmNJkpvIbmeQqcIXg==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-/n0xL/OCmeki+nYzqkpLjJNaoEcEBR3cVxvjXF9ESuqVuD81WpicSm2ZF/bHA+pjNuC0QzMBzsKaQwBI96/6JA==" crossorigin="anonymous"></script>
|
||||
<!--[if lt IE 10]>
|
||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
||||
<![endif]-->
|
||||
|
@ -292,8 +292,9 @@ if ($FILEUPLOAD):
|
|||
<ul class="dropdown-menu">
|
||||
<li id="filewrap">
|
||||
<div>
|
||||
<input type="file" id="file" name="file" />
|
||||
<input type="file" id="file" name="file"/>
|
||||
</div>
|
||||
<div id="dragAndDropFileName" class="dragAndDropFile"><?php echo I18n::_('or drag & drop file'); ?></div>
|
||||
</li>
|
||||
<li>
|
||||
<a id="fileremovebutton" href="#">
|
||||
|
@ -447,7 +448,7 @@ endif;
|
|||
</header>
|
||||
<section class="container">
|
||||
<article class="row">
|
||||
<div id="image" class="col-md-12 text-center hidden"></div>
|
||||
<div id="attachmentPreview" class="col-md-12 text-center hidden"></div>
|
||||
<div id="prettymessage" class="col-md-12 hidden">
|
||||
<pre id="prettyprint" class="col-md-12 prettyprint linenums:1"></pre>
|
||||
</div>
|
||||
|
|
|
@ -47,7 +47,7 @@ if ($MARKDOWN):
|
|||
<?php
|
||||
endif;
|
||||
?>
|
||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-vYYJYraxQNOf41XtehLBU2JbIQ2Uffe+n8TjHyWkpqoZdZX4aL5zyABrUNvRUP02+AxoRsmNJkpvIbmeQqcIXg==" crossorigin="anonymous"></script>
|
||||
<script type="text/javascript" src="js/privatebin.js?<?php echo rawurlencode($VERSION); ?>" integrity="sha512-/n0xL/OCmeki+nYzqkpLjJNaoEcEBR3cVxvjXF9ESuqVuD81WpicSm2ZF/bHA+pjNuC0QzMBzsKaQwBI96/6JA==" crossorigin="anonymous"></script>
|
||||
<!--[if lt IE 10]>
|
||||
<style type="text/css">body {padding-left:60px;padding-right:60px;} #ienotice {display:block;} #oldienotice {display:block;}</style>
|
||||
<![endif]-->
|
||||
|
@ -203,6 +203,7 @@ if ($FILEUPLOAD):
|
|||
<div id="attach" class="hidden">
|
||||
<span id="clonedfile" class="hidden"><?php echo I18n::_('Cloned file attached.'); ?></span>
|
||||
<span id="filewrap"><?php echo I18n::_('Attach a file'); ?>: <input type="file" id="file" name="file" /></span>
|
||||
<span id="dragAndDropFileName" class="dragAndDropFile"><?php echo I18n::_('or drag & drop file'); ?></span>
|
||||
<button id="fileremovebutton"><?php echo I18n::_('Remove attachment'); ?></button>
|
||||
</div>
|
||||
<?php
|
||||
|
@ -212,7 +213,7 @@ endif;
|
|||
<button id="messageedit"><?php echo I18n::_('Editor'); ?></button>
|
||||
<button id="messagepreview"><?php echo I18n::_('Preview'); ?></button>
|
||||
</div>
|
||||
<div id="image" class="hidden"></div>
|
||||
<div id="attachmentPreview" class="hidden"></div>
|
||||
<div id="prettymessage" class="hidden">
|
||||
<pre id="prettyprint" class="prettyprint linenums:1"></pre>
|
||||
</div>
|
||||
|
|
Loading…
Reference in a new issue