From 0e99ca61a24c7c1f649899106925f389f598e2f3 Mon Sep 17 00:00:00 2001 From: Scott Nonnenberg Date: Wed, 25 Apr 2018 15:06:27 -0700 Subject: [PATCH] eslintify file_input_view.js --- Gruntfile.js | 2 + js/views/file_input_view.js | 613 ++++++++++++++++++------------------ 2 files changed, 310 insertions(+), 305 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 51f20eb255..78045eaadd 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -111,6 +111,7 @@ module.exports = function(grunt) { '!js/views/conversation_search_view.js', '!js/views/conversation_view.js', '!js/views/debug_log_view.js', + '!js/views/file_input_view.js', '!js/views/message_view.js', '!js/models/conversations.js', '!js/models/messages.js', @@ -170,6 +171,7 @@ module.exports = function(grunt) { '!js/views/conversation_search_view.js', '!js/views/conversation_view.js', '!js/views/debug_log_view.js', + '!js/views/file_input_view.js', '!js/views/message_view.js', '!js/Mp3LameEncoder.min.js', '!js/WebAudioRecorderMp3.js', diff --git a/js/views/file_input_view.js b/js/views/file_input_view.js index c3d53349a0..084d10bf7b 100644 --- a/js/views/file_input_view.js +++ b/js/views/file_input_view.js @@ -1,236 +1,235 @@ -/* eslint-disable */ - /* global textsecure: false */ +/* global Whisper: false */ +/* global i18n: false */ +/* global loadImage: false */ +/* global Backbone: false */ +// eslint-disable-next-line func-names (function () { - 'use strict'; - window.Whisper = window.Whisper || {}; + 'use strict'; - const { MIME } = window.Signal.Types; + window.Whisper = window.Whisper || {}; - Whisper.FileSizeToast = Whisper.ToastView.extend({ - templateName: 'file-size-modal', - render_attributes: function() { - return { - 'file-size-warning': i18n('fileSizeWarning'), - limit: this.model.limit, - units: this.model.units - }; - } - }); - Whisper.UnsupportedFileTypeToast = Whisper.ToastView.extend({ - template: i18n('unsupportedFileType') - }); + const { MIME } = window.Signal.Types; - function makeThumbnail(size, objectUrl) { - return new Promise(function(resolve, reject) { - var img = document.createElement('img'); - img.onerror = reject; - img.onload = function () { - // using components/blueimp-load-image + Whisper.FileSizeToast = Whisper.ToastView.extend({ + templateName: 'file-size-modal', + render_attributes() { + return { + 'file-size-warning': i18n('fileSizeWarning'), + limit: this.model.limit, + units: this.model.units, + }; + }, + }); + Whisper.UnsupportedFileTypeToast = Whisper.ToastView.extend({ + template: i18n('unsupportedFileType'), + }); - // first, make the correct size - var canvas = loadImage.scale(img, { - canvas: true, - cover: true, - maxWidth: size, - maxHeight: size, - minWidth: size, - minHeight: size, - }); + function makeThumbnail(size, objectUrl) { + return new Promise(((resolve, reject) => { + const img = document.createElement('img'); + img.onerror = reject; + img.onload = () => { + // using components/blueimp-load-image - // then crop - canvas = loadImage.scale(canvas, { - canvas: true, - crop: true, - maxWidth: size, - maxHeight: size, - minWidth: size, - minHeight: size, - }); - - var blob = window.dataURLToBlobSync(canvas.toDataURL('image/png')); - - resolve(blob); - }; - img.src = objectUrl; + // first, make the correct size + let canvas = loadImage.scale(img, { + canvas: true, + cover: true, + maxWidth: size, + maxHeight: size, + minWidth: size, + minHeight: size, }); - } - Whisper.FileInputView = Backbone.View.extend({ - tagName: 'span', - className: 'file-input', - initialize: function(options) { - this.$input = this.$('input[type=file]'); - this.$input.click(function(e) { - e.stopPropagation(); - }); - this.thumb = new Whisper.AttachmentPreviewView(); - this.$el.addClass('file-input'); - this.window = options.window; - this.previewObjectUrl = null; - }, + // then crop + canvas = loadImage.scale(canvas, { + canvas: true, + crop: true, + maxWidth: size, + maxHeight: size, + minWidth: size, + minHeight: size, + }); - events: { - 'change .choose-file': 'previewImages', - 'click .close': 'deleteFiles', - 'click .choose-file': 'open', - 'drop': 'openDropped', - 'dragover': 'showArea', - 'dragleave': 'hideArea', - 'paste': 'onPaste' - }, + const blob = window.dataURLToBlobSync(canvas.toDataURL('image/png')); - open: function(e) { - e.preventDefault(); - // hack - if (this.window && this.window.chrome && this.window.chrome.fileSystem) { - this.window.chrome.fileSystem.chooseEntry({type: 'openFile'}, function(entry) { - if (!entry) { - return; - } - entry.file(function(file) { - this.file = file; - this.previewImages(); - }.bind(this)); - }.bind(this)); - } else { - this.$input.click(); + resolve(blob); + }; + img.src = objectUrl; + })); + } + + Whisper.FileInputView = Backbone.View.extend({ + tagName: 'span', + className: 'file-input', + initialize(options) { + this.$input = this.$('input[type=file]'); + this.$input.click((e) => { + e.stopPropagation(); + }); + this.thumb = new Whisper.AttachmentPreviewView(); + this.$el.addClass('file-input'); + this.window = options.window; + this.previewObjectUrl = null; + }, + + events: { + 'change .choose-file': 'previewImages', + 'click .close': 'deleteFiles', + 'click .choose-file': 'open', + drop: 'openDropped', + dragover: 'showArea', + dragleave: 'hideArea', + paste: 'onPaste', + }, + + open(e) { + e.preventDefault(); + // hack + if (this.window && this.window.chrome && this.window.chrome.fileSystem) { + this.window.chrome.fileSystem.chooseEntry({ type: 'openFile' }, (entry) => { + if (!entry) { + return; + } + entry.file((file) => { + this.file = file; + this.previewImages(); + }); + }); + } else { + this.$input.click(); + } + }, + + addThumb(src) { + this.$('.avatar').hide(); + this.thumb.src = src; + this.$('.attachment-previews').append(this.thumb.render().el); + this.thumb.$('img')[0].onload = () => { + this.$el.trigger('force-resize'); + }; + }, + + autoScale(file) { + if (file.type.split('/')[0] !== 'image' || + file.type === 'image/gif' || + file.type === 'image/tiff') { + // nothing to do + return Promise.resolve(file); + } + + return new Promise(((resolve, reject) => { + const url = URL.createObjectURL(file); + const img = document.createElement('img'); + img.onerror = reject; + img.onload = () => { + URL.revokeObjectURL(url); + + const maxSize = 6000 * 1024; + const maxHeight = 4096; + const maxWidth = 4096; + if (img.width <= maxWidth && img.height <= maxHeight && file.size <= maxSize) { + resolve(file); + return; + } + + const canvas = loadImage.scale(img, { + canvas: true, maxWidth, maxHeight, + }); + + let quality = 0.95; + let i = 4; + let blob; + do { + i -= 1; + blob = window.dataURLToBlobSync(canvas.toDataURL('image/jpeg', quality)); + quality = (quality * maxSize) / blob.size; + // NOTE: During testing with a large image, we observed the + // `quality` value being > 1. Should we clamp it to [0.5, 1.0]? + // See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#Syntax + if (quality < 0.5) { + quality = 0.5; } - }, + } while (i > 0 && blob.size > maxSize); - addThumb: function(src) { - this.$('.avatar').hide(); - this.thumb.src = src; - this.$('.attachment-previews').append(this.thumb.render().el); - this.thumb.$('img')[0].onload = function() { - this.$el.trigger('force-resize'); - }.bind(this); - }, + resolve(blob); + }; + img.src = url; + })); + }, - autoScale: function(file) { - if (file.type.split('/')[0] !== 'image' - || file.type === 'image/gif' - || file.type === 'image/tiff') { - // nothing to do - return Promise.resolve(file); - } + previewImages() { + this.clearForm(); + const file = this.file || this.$input.prop('files')[0]; + if (!file) { return; } - return new Promise(function(resolve, reject) { - var url = URL.createObjectURL(file); - var img = document.createElement('img'); - img.onerror = reject; - img.onload = function () { - URL.revokeObjectURL(url); + let type = file.type.split('/')[0]; + if (file.type === 'image/tiff') { + type = 'file'; + } + switch (type) { + case 'audio': this.addThumb('images/audio.svg'); break; + case 'video': this.addThumb('images/video.svg'); break; + case 'image': + if (!MIME.isJPEG(file.type)) { + this.previewObjectUrl = URL.createObjectURL(file); + this.addThumb(this.previewObjectUrl); + break; + } - var maxSize = 6000 * 1024; - var maxHeight = 4096; - var maxWidth = 4096; - if (img.width <= maxWidth && img.height <= maxHeight && - file.size <= maxSize) { - resolve(file); - return; - } + // NOTE: Temporarily allow `then` until we convert the entire file + // to `async` / `await`: + // eslint-disable-next-line more/no-then + window.autoOrientImage(file) + .then(dataURL => this.addThumb(dataURL)); + break; + default: + this.addThumb('images/file.svg'); break; + } - var canvas = loadImage.scale(img, { - canvas: true, maxWidth: maxWidth, maxHeight: maxHeight - }); + // NOTE: Temporarily allow `then` until we convert the entire file + // to `async` / `await`: + // eslint-disable-next-line more/no-then + this.autoScale(file).then((blob) => { + let limitKb = 1000000; + const blobType = file.type === 'image/gif' ? 'gif' : type; + switch (blobType) { + case 'image': + limitKb = 6000; break; + case 'gif': + limitKb = 25000; break; + case 'audio': + limitKb = 100000; break; + case 'video': + limitKb = 100000; break; + default: + limitKb = 100000; break; + } + if ((blob.size / 1024).toFixed(4) >= limitKb) { + const units = ['kB', 'MB', 'GB']; + let u = -1; + let limit = limitKb * 1000; + do { + limit /= 1000; + u += 1; + } while (limit >= 1000 && u < units.length - 1); + const toast = new Whisper.FileSizeToast({ + model: { limit, units: units[u] }, + }); + toast.$el.insertAfter(this.$el); + toast.render(); + this.deleteFiles(); + } + }); + }, - var quality = 0.95; - var i = 4; - var blob; - do { - i = i - 1; - blob = window.dataURLToBlobSync( - canvas.toDataURL('image/jpeg', quality) - ); - quality = quality * maxSize / blob.size; - // NOTE: During testing with a large image, we observed the - // `quality` value being > 1. Should we clamp it to [0.5, 1.0]? - // See: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob#Syntax - if (quality < 0.5) { - quality = 0.5; - } - } while (i > 0 && blob.size > maxSize); + hasFiles() { + const files = this.file ? [this.file] : this.$input.prop('files'); + return files && files.length && files.length > 0; + }, - resolve(blob); - }; - img.src = url; - }); - }, - - previewImages: function() { - this.clearForm(); - var file = this.file || this.$input.prop('files')[0]; - if (!file) { return; } - - var type = file.type.split('/')[0]; - if (file.type === 'image/tiff') { - type = 'file'; - } - switch (type) { - case 'audio': this.addThumb('images/audio.svg'); break; - case 'video': this.addThumb('images/video.svg'); break; - case 'image': - if (!MIME.isJPEG(file.type)) { - this.previewObjectUrl = URL.createObjectURL(file); - this.addThumb(this.previewObjectUrl); - break; - } - - // NOTE: Temporarily allow `then` until we convert the entire file - // to `async` / `await`: - // eslint-disable-next-line more/no-then - window.autoOrientImage(file) - .then(dataURL => this.addThumb(dataURL)); - break; - default: - this.addThumb('images/file.svg'); break; - } - - // NOTE: Temporarily allow `then` until we convert the entire file - // to `async` / `await`: - // eslint-disable-next-line more/no-then - this.autoScale(file).then(function(blob) { - var limitKb = 1000000; - var blobType = file.type === 'image/gif' ? 'gif' : type; - switch (blobType) { - case 'image': - limitKb = 6000; break; - case 'gif': - limitKb = 25000; break; - case 'audio': - limitKb = 100000; break; - case 'video': - limitKb = 100000; break; - default: - limitKb = 100000; break; - } - if ((blob.size/1024).toFixed(4) >= limitKb) { - var units = ['kB','MB','GB']; - var u = -1; - var limit = limitKb * 1000; - do { - limit /= 1000; - ++u; - } while (limit >= 1000 && u < units.length - 1); - var toast = new Whisper.FileSizeToast({ - model: {limit: limit, units: units[u]} - }); - toast.$el.insertAfter(this.$el); - toast.render(); - this.deleteFiles(); - } - }.bind(this)); - }, - - hasFiles: function() { - var files = this.file ? [this.file] : this.$input.prop('files'); - return files && files.length && files.length > 0; - }, - - /* eslint-enable */ - /* jshint ignore:start */ getFiles() { const files = this.file ? [this.file] : Array.from(this.$input.prop('files')); const promise = Promise.all(files.map(file => this.getFile(file))); @@ -262,109 +261,113 @@ .then(this.readFile) .then(setFlags(attachmentFlags)); }, - /* jshint ignore:end */ - /* eslint-disable */ - getThumbnail: function() { - // Scale and crop an image to 256px square - var size = 256; - var file = this.file || this.$input.prop('files')[0]; - if (file === undefined || file.type.split('/')[0] !== 'image' || file.type === 'image/gif') { - // nothing to do - return Promise.resolve(); - } + getThumbnail() { + // Scale and crop an image to 256px square + const size = 256; + const file = this.file || this.$input.prop('files')[0]; + if (file === undefined || + file.type.split('/')[0] !== 'image' || + file.type === 'image/gif') { + // nothing to do + return Promise.resolve(); + } - const objectUrl = URL.createObjectURL(file); - return makeThumbnail(256, file).then(function(arrayBuffer) { - URL.revokeObjectURL(url); - return this.readFile(arrayBuffer); - }); - }, + const objectUrl = URL.createObjectURL(file); - // File -> Promise Attachment - readFile: function(file) { - return new Promise(function(resolve, reject) { - var FR = new FileReader(); - FR.onload = function(e) { - resolve({ - data: e.target.result, - contentType: file.type, - fileName: file.name, - size: file.size - }); - }; - FR.onerror = reject; - FR.onabort = reject; - FR.readAsArrayBuffer(file); - }); - }, + // eslint-disable-next-line more/no-then + return makeThumbnail(size, objectUrl).then((arrayBuffer) => { + URL.revokeObjectURL(objectUrl); + return this.readFile(arrayBuffer); + }); + }, - clearForm: function() { - if (this.previewObjectUrl) { - URL.revokeObjectURL(this.previewObjectUrl); - this.previewObjectUrl = null; - } + // File -> Promise Attachment + readFile(file) { + return new Promise(((resolve, reject) => { + const FR = new FileReader(); + FR.onload = (e) => { + resolve({ + data: e.target.result, + contentType: file.type, + fileName: file.name, + size: file.size, + }); + }; + FR.onerror = reject; + FR.onabort = reject; + FR.readAsArrayBuffer(file); + })); + }, - this.thumb.remove(); - this.$('.avatar').show(); - this.$el.trigger('force-resize'); - }, + clearForm() { + if (this.previewObjectUrl) { + URL.revokeObjectURL(this.previewObjectUrl); + this.previewObjectUrl = null; + } - deleteFiles: function(e) { - if (e) { e.stopPropagation(); } - this.clearForm(); - this.$input.wrap('
').parent('form').trigger('reset'); - this.$input.unwrap(); - this.file = null; - this.$input.trigger('change'); - this.isVoiceNote = false; - }, + this.thumb.remove(); + this.$('.avatar').show(); + this.$el.trigger('force-resize'); + }, - openDropped: function(e) { - if (e.originalEvent.dataTransfer.types[0] != 'Files') { - return; - } + deleteFiles(e) { + if (e) { e.stopPropagation(); } + this.clearForm(); + this.$input.wrap('').parent('form').trigger('reset'); + this.$input.unwrap(); + this.file = null; + this.$input.trigger('change'); + this.isVoiceNote = false; + }, - e.stopPropagation(); - e.preventDefault(); - this.file = e.originalEvent.dataTransfer.files[0]; - this.previewImages(); - this.$el.removeClass('dropoff'); - }, + openDropped(e) { + if (e.originalEvent.dataTransfer.types[0] !== 'Files') { + return; + } - showArea: function(e) { - if (e.originalEvent.dataTransfer.types[0] != 'Files') { - return; - } + e.stopPropagation(); + e.preventDefault(); - e.stopPropagation(); - e.preventDefault(); - this.$el.addClass('dropoff'); - }, + // eslint-disable-next-line prefer-destructuring + this.file = e.originalEvent.dataTransfer.files[0]; + this.previewImages(); + this.$el.removeClass('dropoff'); + }, - hideArea: function(e) { - if (e.originalEvent.dataTransfer.types[0] != 'Files') { - return; - } + showArea(e) { + if (e.originalEvent.dataTransfer.types[0] !== 'Files') { + return; + } - e.stopPropagation(); - e.preventDefault(); - this.$el.removeClass('dropoff'); - }, - onPaste: function(e) { - var items = e.originalEvent.clipboardData.items; - var imgBlob = null; - for (var i = 0; i < items.length; i++) { - if (items[i].type.split('/')[0] === 'image') { - imgBlob = items[i].getAsFile(); - } - } - if (imgBlob !== null) { - this.file = imgBlob; - this.previewImages(); - } + e.stopPropagation(); + e.preventDefault(); + this.$el.addClass('dropoff'); + }, + + hideArea(e) { + if (e.originalEvent.dataTransfer.types[0] !== 'Files') { + return; + } + + e.stopPropagation(); + e.preventDefault(); + this.$el.removeClass('dropoff'); + }, + onPaste(e) { + const { items } = e.originalEvent.clipboardData; + let imgBlob = null; + for (let i = 0; i < items.length; i += 1) { + if (items[i].type.split('/')[0] === 'image') { + imgBlob = items[i].getAsFile(); } - }); + } + if (imgBlob !== null) { + this.file = imgBlob; + this.previewImages(); + } + }, + }); - Whisper.FileInputView.makeThumbnail = makeThumbnail; -})(); + Whisper.FileInputView.makeThumbnail = makeThumbnail; +}());