diff --git a/js/privatebin.js b/js/privatebin.js index 65d81878..bbb2fe76 100644 --- a/js/privatebin.js +++ b/js/privatebin.js @@ -308,6 +308,185 @@ jQuery.PrivateBin = function($, sjcl, Base64, RawDeflate) { baseUri = null; } + me.attachmentHelpers = { + attachmentData: undefined, + file: undefined, + $fileInput: undefined, + + init: function () { + me.attachmentHelpers.$fileInput = $('#file'); + me.attachmentHelpers.addDragDropHandler(); + }, + + /* + * 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… + AttachmentViewer.hideAttachment(); + AttachmentViewer.hideAttachmentPreview(); + Alert.showError(I18n._('Your browser does not support uploading encrypted files. Please use a newer browser.')); + return; + } + + var fileReader = new FileReader(); + if (file === undefined) { + file = me.attachmentHelpers.$fileInput[0].files[0]; + $('#dragAndDropFileName').text(''); + } else { + $('#dragAndDropFileName').text(file.name); + } + + me.attachmentHelpers.file = file; + + fileReader.onload = function (event) { + var dataURL = event.target.result; + me.attachmentHelpers.attachmentData = dataURL; + + if (Editor.isPreview()) { + me.attachmentHelpers.handleAttachmentPreview(AttachmentViewer.$attachmentPreview, dataURL); + } + }; + fileReader.readAsDataURL(file); + }, + + /** + * Handle the preview of files that can either be an image, video, audio or pdf element. + * @argument {DOM Element} targetElement where the preview should be appended. + * @argument {File Data} data of the file to be displayed. + */ + handleAttachmentPreview: function (targetElement, data) { + if (data) { + var mimeType = this.getMimeTypeFromDataURL(data); + + if (mimeType.match(/image\//i)) { + this.showImagePreview(targetElement, data); + } else if (mimeType.match(/video\//i)) { + this.showVideoPreview(targetElement, data, mimeType); + } else if (mimeType.match(/audio\//i)) { + this.showAudioPreview(targetElement, data, mimeType); + } else if (mimeType.match(/\/pdf/i)) { + this.showPDFPreview(targetElement, 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 (targetElement, image) { + targetElement.html( + $(document.createElement('img')) + .attr('src', image) + .attr('class', 'img-thumbnail') + ); + targetElement.removeClass('hidden'); + }, + + showVideoPreview: function (targetElement, 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)); + targetElement.html(videoPlayer); + targetElement.removeClass('hidden'); + }, + + showAudioPreview: function (targetElement, audio, mimeType) { + var audioPlayer = $(document.createElement('audio')) + .attr('controls', 'true') + .attr('autoplay', 'true'); + + audioPlayer.append($(document.createElement('source')) + .attr('type', mimeType) + .attr('src', audio)); + targetElement.html(audioPlayer); + targetElement.removeClass('hidden'); + }, + + showPDFPreview: function (targetElement, 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(); + + targetElement.html( + $(document.createElement('embed')) + .attr('src', pdf) + .attr('type', 'application/pdf') + .attr('class', 'pdfPreview') + .css('height', clientHeight) + ); + targetElement.removeClass('hidden'); + } else { + Alert.showError(I18n._('File too large, to display a preview. Please download the attachment.')); + } + }, + + /** + * Attaches the file attachment drag & drop handler to the page. + * @returns {undefined} + */ + addDragDropHandler: function () { + var fileInput = me.attachmentHelpers.$fileInput; + + if (typeof fileInput === 'undefined' || fileInput.length === 0) { + return; + } + + var ignoreDragDrop = function(event) { + event.stopPropagation(); + event.preventDefault(); + }; + + var drop = function(event) { + event.stopPropagation(); + event.preventDefault(); + + if (fileInput) { + var file = event.dataTransfer.files[0]; + //Clear the file input: + fileInput.wrap('