From 5462c603b6b9389fd7ea8e55998045a4452d2d7d Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Sun, 27 Sep 2015 21:41:12 +0000 Subject: Prefix jQuery object variables with a $ While JSCS and ESLint do not detect this yet as of today, my eyes do. The Airbnb style guide wants to do this. This commit doesn't prefix cabinet.js, but the next commit will while addressing another issue. --- js/pomf.js | 92 +++++++++++++++++++++++++++++++------------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'js') diff --git a/js/pomf.js b/js/pomf.js index 1a11543..db68ed8 100644 --- a/js/pomf.js +++ b/js/pomf.js @@ -23,37 +23,37 @@ /* jshint browser:true, jquery:true */ $(function() { - var uploadInput = $('#upload-input'); - var uploadBtn = $('#upload-btn'); - var uploadFiles = $('#upload-filelist'); + var $uploadInput = $('#upload-input'); + var $uploadBtn = $('#upload-btn'); + var $uploadFiles = $('#upload-filelist'); - var btnContent = ''; + var $btnContent = ''; if (!$.hasFileAPI()) { $('#no-file-api').show(); - uploadBtn.hide(); + $uploadBtn.hide(); } - uploadBtn.cabinet(uploadInput); + $uploadBtn.cabinet($uploadInput); - uploadBtn.on('dragenter', function(e) { + $uploadBtn.on('dragenter', function(e) { if (this === e.target) { $(this).addClass('drop'); - btnContent = $(this).html(); + $btnContent = $(this).html(); $(this).html('Drop it here~'); } }); - uploadBtn.on('drop', function(e) { + $uploadBtn.on('drop', function(e) { $(this).trigger('dragleave'); }); - uploadBtn.on('dragleave', function(e) { + $uploadBtn.on('dragleave', function(e) { node = e.target; do { if (node === this) { $(this).removeClass('drop'); - $(this).html(btnContent); + $(this).html($btnContent); break; } } while (node === node.parentNode); @@ -70,48 +70,48 @@ $(function() { ); return num * oneUnit; - })(uploadInput); + })($uploadInput); var createRow = function(filename, size, extra) { - var rowItem = $('
  • '); - var rowName = $(''); - var rowProg = $('
    '); - var rowSize = $(''); - var rowUrl = $(''); + var $rowItem = $('
  • '); + var $rowName = $(''); + var $rowProg = $('
    '); + var $rowSize = $(''); + var $rowUrl = $(''); - rowItem.addClass(extra || ''); + $rowItem.addClass(extra || ''); - $('
    ').appendTo(rowProg); + $('
    ').appendTo($rowProg); - rowItem.attr('data-filename', escape(filename)); - rowName.text(filename); - rowSize.text(size); + $rowItem.attr('data-filename', escape(filename)); + $rowName.text(filename); + $rowSize.text(size); - rowItem.append(rowName, rowProg, rowSize, rowUrl); + $rowItem.append($rowName, $rowProg, $rowSize, $rowUrl); - return rowItem; + return $rowItem; }; - uploadBtn.on('change', function(e) { - uploadFiles.empty().removeClass('error completed'); + $uploadBtn.on('change', function(e) { + $uploadFiles.empty().removeClass('error completed'); - var files = uploadInput[0].filelist; + var files = $uploadInput[0].filelist; files.forEach(function(file) { - createRow(file.name, file.humanSize).appendTo(uploadFiles); + createRow(file.name, file.humanSize).appendTo($uploadFiles); }); var totalRow = createRow('', files.humanSize, 'total'); - totalRow.appendTo(uploadFiles); + totalRow.appendTo($uploadFiles); - var totalName = $('.file-name', totalRow); + var $totalName = $('.file-name', totalRow); var UPLOAD_ERR_MAX_SIZE = 'onii-chan y-your upload is t-too big…'; var UPLOAD_ERR_FAILED = 'Something went wrong; try again later.'; if (files.size > MAX_SIZE) { - uploadFiles.addClass('error'); - totalName.html(UPLOAD_ERR_MAX_SIZE); + $uploadFiles.addClass('error'); + $totalName.html(UPLOAD_ERR_MAX_SIZE); return; } @@ -137,7 +137,7 @@ $(function() { up.on('uploadcomplete', function(e) { $('.progress-inner').width('100%'); - totalName.html('Grabbing URLs…'); + $totalName.html('Grabbing URLs…'); }); up.on('load', function(e, response) { @@ -145,31 +145,31 @@ $(function() { case 200: var res = JSON.parse(response); if (!res.success) { - uploadFiles.addClass('error'); - totalName.text(UPLOAD_ERR_FAILED); + $uploadFiles.addClass('error'); + $totalName.text(UPLOAD_ERR_FAILED); break; } eachRow(res.files, function(row, file, files) { - var link = $(''); + var $link = $(''); - link.attr('href', file.url) - .attr('target', '_BLANK') - .text(file.url.replace('http://', '').replace('https://', '')); + $link.attr('href', file.url) + .attr('target', '_BLANK') + .text(file.url.replace('http://', '').replace('https://', '')); - $('.file-url', row).append(link); + $('.file-url', row).append($link); }); - uploadFiles.addClass('completed'); - totalName.text('Done!'); + $uploadFiles.addClass('completed'); + $totalName.text('Done!'); break; case 413: - uploadFiles.addClass('error completed'); - totalName.html(UPLOAD_ERR_MAX_SIZE); + $uploadFiles.addClass('error completed'); + $totalName.html(UPLOAD_ERR_MAX_SIZE); break; default: - uploadFiles.addClass('error completed'); - totalName.text(UPLOAD_ERR_FAILED); + $uploadFiles.addClass('error completed'); + $totalName.text(UPLOAD_ERR_FAILED); } }); -- cgit v1.2.3 From 408e3cf72b993655ae3b8f8eeb9f8a7b95d21c54 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Mon, 28 Sep 2015 16:08:36 +0000 Subject: Prefix cheesesteak.js jQuery object variables with a $ This fixes Airbnb ES5 style guide violations. --- js/cabinet.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'js') diff --git a/js/cabinet.js b/js/cabinet.js index 2f3a3a6..8414df2 100644 --- a/js/cabinet.js +++ b/js/cabinet.js @@ -27,15 +27,15 @@ }; $.fn.cabinet = function(input) { - input = $(input); + var $input = $(input); var _this = this; var passthrough = function(outer, inner, prevent, fn) { _this.on(outer, function(e) { if (inner === 'click') { - input[0].click(); + $input[0].click(); } else { - input.trigger(inner); + $input.trigger(inner); } if (prevent) { @@ -48,9 +48,9 @@ }, false); }; - input[0].filelist = Object.create(FileList); + $input[0].filelist = Object.create(FileList); - input.on('change', function(e) { + $input.on('change', function(e) { this.filelist = e.target.files; _this.change(); }); @@ -60,7 +60,7 @@ passthrough('dragleave', 'dragleave', true); passthrough('click', 'click', false); passthrough('drop', 'dragleave', true, function(e) { - input[0].filelist = e.dataTransfer.files; + $input[0].filelist = e.dataTransfer.files; _this.change(); }); }; -- cgit v1.2.3 From 08dfe39b91ef17357bfc91734266b560b463aaff Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Mon, 28 Sep 2015 17:05:14 +0000 Subject: Fix assignments to function parameters in JavaScript Fixes ESLint no-param-reassing warning. --- js/cabinet.js | 4 ++-- js/cheesesteak.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'js') diff --git a/js/cabinet.js b/js/cabinet.js index 2f3a3a6..74a250a 100644 --- a/js/cabinet.js +++ b/js/cabinet.js @@ -26,8 +26,8 @@ return (window.FormData !== undefined); }; - $.fn.cabinet = function(input) { - input = $(input); + $.fn.cabinet = function(uploadInput) { + var input = $(uploadInput); var _this = this; var passthrough = function(outer, inner, prevent, fn) { diff --git a/js/cheesesteak.js b/js/cheesesteak.js index ea3dc19..6e5a3ad 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -125,13 +125,13 @@ this.url = url; this.files = files; - opts = opts || {}; + var request = opts || {}; this.opts = merge({ field: 'files[]', method: 'POST', data: {} - }, opts); + }, request); }; FileListUploader.prototype = Object.create(EventEmitter.prototype); -- cgit v1.2.3 From 2751811e56129b14a423e64a6d638ad466268202 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Mon, 28 Sep 2015 18:35:32 +0000 Subject: Name and comment addEventListener functions Using anonymous functions with event handlers is painfully slow according to benchmarks. Anonymous functions are up to 99% slower. It is also illegal to use anonymous functions in this way according to Airbnb ES5 style guide. Fixes some ESLint func-names errors using Airbnb ES5 config. Reference: https://jsperf.com/event-handler-vs-anonymous-function/3 --- js/cheesesteak.js | 34 ++++++++++++++++++++++------------ 1 file changed, 22 insertions(+), 12 deletions(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index ea3dc19..4b00c3e 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -152,13 +152,15 @@ var xhr = new XMLHttpRequest(); xhr.open(opts.method, this.url, true); - xhr.upload.addEventListener('loadstart', function(e) { + + function initProgressBar(e) { for (var i = 0, l = files.length; i < l; i++) { files[i].uploadedSize = 0; } - }); + } + xhr.upload.addEventListener('loadstart', initProgressBar); - xhr.upload.addEventListener('progress', function(e) { + function updateProgressBar(e) { if (e.lengthComputable) { size = e.loaded; @@ -181,23 +183,31 @@ } _this.emit('uploadprogress', e, files); - }, false); + } + xhr.upload.addEventListener('progress', updateProgressBar, false); - xhr.upload.addEventListener('loadstart', function(e) { + function startUpload(e) { _this.emit('uploadstart', e); - }); + } + xhr.upload.addEventListener('loadstart', startUpload); - xhr.upload.addEventListener('load', function(e) { + // The upload is complete, now tell the user to wait for URLs. + function postUpload(e) { _this.emit('uploadcomplete', e); - }); + } + xhr.upload.addEventListener('load', postUpload); - xhr.addEventListener('progress', function(e) { + // Tell the browser the upload completed and wait for response. + function postProgress(e) { _this.emit('progress', e); - }); + } + xhr.upload.addEventListener('progress', postProgress); - xhr.addEventListener('load', function(e) { + // Send a success/error response. Nothing more to do. + function uploadFinished(e) { _this.emit('load', e, xhr.responseText); - }); + } + xhr.upload.addEventListener('load', uploadFinished); xhr.send(data); -- cgit v1.2.3 From 85aec0691ab19aa1f9dcb501c77497fc21765c6c Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Mon, 28 Sep 2015 18:42:04 +0000 Subject: Remove dead uploadstart emitter startUpload() The loadstart even is only triggered once to indicate the progress has begun (initialize the progress bar). Essentially, this is dead code for two reasons: 1. It never gets emitted because initProgressBar() gets emitted first. 2. No JavaScript file in pomf core uses the non-standard uploadstart event. --- js/cheesesteak.js | 5 ----- 1 file changed, 5 deletions(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 4b00c3e..31d6086 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -186,11 +186,6 @@ } xhr.upload.addEventListener('progress', updateProgressBar, false); - function startUpload(e) { - _this.emit('uploadstart', e); - } - xhr.upload.addEventListener('loadstart', startUpload); - // The upload is complete, now tell the user to wait for URLs. function postUpload(e) { _this.emit('uploadcomplete', e); -- cgit v1.2.3 From 187f3000385f136c8766fbfb2d18d24832ecf4b5 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Mon, 28 Sep 2015 19:03:34 +0000 Subject: Fix unexpected use of undefined with Boolean() Airbnb style guide recommends checking booleans this way or using (!!window.FormData). The latter is more confusing for many. While !! is indeed 0.2% faster than Boolean(), it's called micro-optimization. There is no noticeable difference to the user in our use scenario and I prefer more readable code any day. Fixes ESLint no-undefined warning using Airbnb ES5 config. Reference: https://jsperf.com/boolean-conversion-speed --- js/cabinet.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js') diff --git a/js/cabinet.js b/js/cabinet.js index 2f3a3a6..a74bb40 100644 --- a/js/cabinet.js +++ b/js/cabinet.js @@ -23,7 +23,7 @@ /* jshint browser:true, jquery:true */ (function($) { $.hasFileAPI = function hasFileAPI() { - return (window.FormData !== undefined); + return Boolean(window.FormData); }; $.fn.cabinet = function(input) { -- cgit v1.2.3 From 11e9d2d0e6d7266ff119fdab9947e879192bd75e Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Mon, 28 Sep 2015 19:14:49 +0000 Subject: Add missing var declarations to undefined variables Fixes ESLint no-undef warnings using Airbnb ES5 config. --- js/cheesesteak.js | 2 +- js/pomf.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index ea3dc19..1ee32b8 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -160,7 +160,7 @@ xhr.upload.addEventListener('progress', function(e) { if (e.lengthComputable) { - size = e.loaded; + var size = e.loaded; /** * We know the size of the files, the order they're in, and how diff --git a/js/pomf.js b/js/pomf.js index 7dd44ef..71972e1 100644 --- a/js/pomf.js +++ b/js/pomf.js @@ -49,7 +49,7 @@ $(function() { }); uploadBtn.on('dragleave', function(e) { - node = e.target; + var node = e.target; do { if (node === this) { $(this).removeClass('drop'); -- cgit v1.2.3 From 4df31fdd704663107cf2e187e6b55483a0edafd3 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Mon, 28 Sep 2015 19:18:49 +0000 Subject: Add missing var declaration to EventEmitter Previous commit 11e9d2d forgot to add the var declaration here. Fixes ESLint no-undef warnings using Airbnb ES5 config. --- js/cheesesteak.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 1ee32b8..ea3b786 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -23,7 +23,7 @@ /* jshint browser:true, jquery:true */ (function() { // Lightweight EventEmitter implementation - EventEmitter = function() {}; + var EventEmitter = function() {}; EventEmitter.prototype.on = function(evt, fn) { this._events = this._events || {}; -- cgit v1.2.3 From 9bdedb32e61159a78fd9717fdaacf63405fe9e98 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Sun, 4 Oct 2015 18:02:53 +0000 Subject: Remove extra whitespace in variable declarations This is something I would disagree with, because this commit in my opinion reduces readability. I am not going to reinvent the wheel and write for humans, because I enjoy being a slave to ESLint. Any complaints about this commit should be directed at Airbnb to fix their style guide. Alternatively, a documented standard style guide should be created for pantsu.cat, extending the Airbnb config. This fixes ESLint no-multi-spaces errors using airbnb/legacy config. --- js/pomf.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/pomf.js b/js/pomf.js index 7d61160..a108c4b 100644 --- a/js/pomf.js +++ b/js/pomf.js @@ -24,7 +24,7 @@ /* jshint browser:true, jquery:true */ $(function() { var $uploadInput = $('#upload-input'); - var $uploadBtn = $('#upload-btn'); + var $uploadBtn = $('#upload-btn'); var $uploadFiles = $('#upload-filelist'); var $btnContent = ''; @@ -77,7 +77,7 @@ $(function() { var $rowName = $(''); var $rowProg = $('
    '); var $rowSize = $(''); - var $rowUrl = $(''); + var $rowUrl = $(''); $rowItem.addClass(extra || ''); -- cgit v1.2.3 From bcfadb7deb7c8930df3a5142d43097391f4e9fa1 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Sun, 4 Oct 2015 18:11:56 +0000 Subject: Revert "Remove previously added missing brace/bracket commas" The unofficial Airbnb config (eslint-config-airbnb-es5) previously thought this to be an error and so it was removed. The official Airbnb config (airbnb/legacy) now works just like the ES6 config (airbnb). Fixes ESLint comma-dangle errors using airbnb/legacy config. This reverts commit 49d58d98f5866bb9ccc9069a16d131486f04bba2. --- js/cheesesteak.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 4809ca3..7280177 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -64,18 +64,18 @@ return this.reduce(function(prev, curr) { return prev + curr.size; }, 0); - } + }, }); // Utility to convert bytes into human units var humanSize = { get: function humanSize() { var units = [ - 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB' + 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', ]; var e = Math.floor(Math.log(this.size) / Math.log(1024)); return (this.size / Math.pow(1024, e)).toFixed(2) + ' ' + units[e]; - } + }, }; Object.defineProperty(FileList.prototype, 'humanSize', humanSize); Object.defineProperty(File.prototype, 'humanSize', humanSize); @@ -83,7 +83,7 @@ var percentUploaded = { get: function percentUploaded() { return this.uploadedSize / this.size; - } + }, }; Object.defineProperty(FileList.prototype, 'percentUploaded', percentUploaded); @@ -94,14 +94,14 @@ return this.reduce(function(prev, curr) { return prev + (curr.uploadedSize || 0); }, 0); - } + }, }); // Object URL stuff Object.defineProperty(File.prototype, 'url', { get: function getURL() { return window.URL.createObjectURL(this); - } + }, }); File.revokeURL = function revokeURL(url) { window.URL.revokeObjectURL(url); @@ -130,7 +130,7 @@ this.opts = merge({ field: 'files[]', method: 'POST', - data: {} + data: {}, }, request); }; -- cgit v1.2.3 From d3f9e9a2929301b19a69ade53a6051859883f7f8 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Wed, 7 Oct 2015 16:11:23 +0000 Subject: Fix incorrect progress/load event listeners This is a symptom of copy-paste code. A file would be uploaded, but it would return the "Something went wrong" error message without telling why. Me, ewhal@ and bursey on IRC tried had a look to see what was wrong, but none of us could catch this subtle bug. It wasn't until alchimist@ (cenci0) looked at this and found the issue. Thanks. This bug was introduced in commit 2751811. --- js/cheesesteak.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 31d6086..e090a12 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -196,13 +196,13 @@ function postProgress(e) { _this.emit('progress', e); } - xhr.upload.addEventListener('progress', postProgress); + xhr.addEventListener('progress', postProgress); // Send a success/error response. Nothing more to do. function uploadFinished(e) { _this.emit('load', e, xhr.responseText); } - xhr.upload.addEventListener('load', uploadFinished); + xhr.addEventListener('load', uploadFinished); xhr.send(data); -- cgit v1.2.3 From 59502c86ceba164c3ccf1a7fa58bf33560157d2b Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Fri, 9 Oct 2015 13:59:32 +0000 Subject: Lint pomf.js ID length to > 2 characters Fixes ESLint id-length errors using airbnb/legacy config. Some arguments were also unused, so this will also avoid introducing new no-unused-vars lint errors. --- js/pomf.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'js') diff --git a/js/pomf.js b/js/pomf.js index a108c4b..0e2ecee 100644 --- a/js/pomf.js +++ b/js/pomf.js @@ -36,20 +36,20 @@ $(function() { $uploadBtn.cabinet($uploadInput); - $uploadBtn.on('dragenter', function(e) { - if (this === e.target) { + $uploadBtn.on('dragenter', function(evt) { + if (this === evt.target) { $(this).addClass('drop'); $btnContent = $(this).html(); $(this).html('Drop it here~'); } }); - $uploadBtn.on('drop', function(e) { + $uploadBtn.on('drop', function() { $(this).trigger('dragleave'); }); - $uploadBtn.on('dragleave', function(e) { - var node = e.target; + $uploadBtn.on('dragleave', function(evt) { + var node = evt.target; do { if (node === this) { $(this).removeClass('drop'); @@ -92,7 +92,7 @@ $(function() { return $rowItem; }; - $uploadBtn.on('change', function(e) { + $uploadBtn.on('change', function() { $uploadFiles.empty().removeClass('error completed'); var files = $uploadInput[0].filelist; @@ -127,7 +127,7 @@ $(function() { }); }; - up.on('uploadprogress', function(e, files) { + up.on('uploadprogress', function(evt, files) { eachRow(files, function(row, file, files) { $('.progress-inner', row).width((file.percentUploaded * 100) + '%'); }); @@ -135,13 +135,13 @@ $(function() { $('.progress-inner', totalRow).width((files.percentUploaded * 100) + '%'); }); - up.on('uploadcomplete', function(e) { + up.on('uploadcomplete', function() { $('.progress-inner').width('100%'); $totalName.html('Grabbing URLs…'); }); - up.on('load', function(e, response) { - switch (e.target.status) { + up.on('load', function(evt, response) { + switch (evt.target.status) { case 200: var res = JSON.parse(response); if (!res.success) { @@ -150,7 +150,7 @@ $(function() { break; } - eachRow(res.files, function(row, file, files) { + eachRow(res.files, function(row, file) { var $link = $(''); $link.attr('href', file.url) -- cgit v1.2.3 From 575b78b9d679db2243083f9ecc8b1543b2a1af02 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Fri, 9 Oct 2015 15:04:21 +0000 Subject: Lint cheesesteak.js and cabinet.js id-length < 2 Fixes ESLint id-length errors using airbnb/legacy config. Variable "i" is ignored as an exception. I've also avoided creating new errors with these changes, so this also fixes some no-unused-vars and avoids creating vars-on-top errors. --- js/cabinet.js | 14 +++++++------- js/cheesesteak.js | 49 +++++++++++++++++++++++++++---------------------- 2 files changed, 34 insertions(+), 29 deletions(-) (limited to 'js') diff --git a/js/cabinet.js b/js/cabinet.js index 2e2408b..09f4e71 100644 --- a/js/cabinet.js +++ b/js/cabinet.js @@ -31,7 +31,7 @@ var _this = this; var passthrough = function(outer, inner, prevent, fn) { - _this.on(outer, function(e) { + _this.on(outer, function(evt) { if (inner === 'click') { $input[0].click(); } else { @@ -39,19 +39,19 @@ } if (prevent) { - e.preventDefault(); + evt.preventDefault(); } if (fn) { - fn(e); + fn(evt); } }, false); }; $input[0].filelist = Object.create(FileList); - $input.on('change', function(e) { - this.filelist = e.target.files; + $input.on('change', function(evt) { + this.filelist = evt.target.files; _this.change(); }); @@ -59,8 +59,8 @@ passthrough('dragover', 'dragover', true); passthrough('dragleave', 'dragleave', true); passthrough('click', 'click', false); - passthrough('drop', 'dragleave', true, function(e) { - $input[0].filelist = e.dataTransfer.files; + passthrough('drop', 'dragleave', true, function(evt) { + $input[0].filelist = evt.dataTransfer.files; _this.change(); }); }; diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 7280177..661d4b7 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -40,11 +40,14 @@ }; EventEmitter.prototype.emit = function(evt) { + var len = this._events[evt].length; + var i; + if (!this.hasOwnProperty('_events') || evt in this._events === false) { return; } - for (var i = 0, l = this._events[evt].length; i < l; i++) { + for (i = 0; i < len; i++) { this._events[evt][i].apply(this, Array.prototype.slice.call(arguments, 1)); } @@ -73,8 +76,8 @@ var units = [ 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', ]; - var e = Math.floor(Math.log(this.size) / Math.log(1024)); - return (this.size / Math.pow(1024, e)).toFixed(2) + ' ' + units[e]; + var base = Math.floor(Math.log(this.size) / Math.log(1024)); + return (this.size / Math.pow(1024, base)).toFixed(2) + ' ' + units[base]; }, }; Object.defineProperty(FileList.prototype, 'humanSize', humanSize); @@ -136,13 +139,15 @@ FileListUploader.prototype = Object.create(EventEmitter.prototype); FileListUploader.prototype.upload = function(cb) { - if (cb) { - this.on('uploadcomplete', cb); - } - var opts = this.opts; var files = this.files; var _this = this; + var len = files.length; + var i; + + if (cb) { + this.on('uploadcomplete', cb); + } var data = new FormData(); files.forEach(function(file) { @@ -152,15 +157,15 @@ var xhr = new XMLHttpRequest(); xhr.open(opts.method, this.url, true); - xhr.upload.addEventListener('loadstart', function(e) { - for (var i = 0, l = files.length; i < l; i++) { + xhr.upload.addEventListener('loadstart', function() { + for (i = 0; i < len; i++) { files[i].uploadedSize = 0; } }); - xhr.upload.addEventListener('progress', function(e) { - if (e.lengthComputable) { - var size = e.loaded; + xhr.upload.addEventListener('progress', function(evt) { + if (evt.lengthComputable) { + var size = evt.loaded; /** * We know the size of the files, the order they're in, and how @@ -170,7 +175,7 @@ */ // TODO: This math has trouble on later uploads. Leak somewhere. - for (var i = 0, l = files.length; i < l; i++) { + for (i = 0; i < len; i++) { files[i].uploadedSize = Math.min(size, files[i].size); size -= files[i].uploadedSize; if (size <= 0) { @@ -180,23 +185,23 @@ } } - _this.emit('uploadprogress', e, files); + _this.emit('uploadprogress', evt, files); }, false); - xhr.upload.addEventListener('loadstart', function(e) { - _this.emit('uploadstart', e); + xhr.upload.addEventListener('loadstart', function(evt) { + _this.emit('uploadstart', evt); }); - xhr.upload.addEventListener('load', function(e) { - _this.emit('uploadcomplete', e); + xhr.upload.addEventListener('load', function(evt) { + _this.emit('uploadcomplete', evt); }); - xhr.addEventListener('progress', function(e) { - _this.emit('progress', e); + xhr.addEventListener('progress', function(evt) { + _this.emit('progress', evt); }); - xhr.addEventListener('load', function(e) { - _this.emit('load', e, xhr.responseText); + xhr.addEventListener('load', function(evt) { + _this.emit('load', evt, xhr.responseText); }); xhr.send(data); -- cgit v1.2.3 From 24ce733985f9d220067654e51698b41c4b446fe7 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Fri, 9 Oct 2015 15:59:48 +0000 Subject: Lint pomf.js vars declarations to top of function Fixes ESLint vars-on-top errors using airbnb/legacy config. --- js/pomf.js | 93 ++++++++++++++++++++++++++++++-------------------------------- 1 file changed, 45 insertions(+), 48 deletions(-) (limited to 'js') diff --git a/js/pomf.js b/js/pomf.js index 0e2ecee..1e89576 100644 --- a/js/pomf.js +++ b/js/pomf.js @@ -29,36 +29,6 @@ $(function() { var $btnContent = ''; - if (!$.hasFileAPI()) { - $('#no-file-api').show(); - $uploadBtn.hide(); - } - - $uploadBtn.cabinet($uploadInput); - - $uploadBtn.on('dragenter', function(evt) { - if (this === evt.target) { - $(this).addClass('drop'); - $btnContent = $(this).html(); - $(this).html('Drop it here~'); - } - }); - - $uploadBtn.on('drop', function() { - $(this).trigger('dragleave'); - }); - - $uploadBtn.on('dragleave', function(evt) { - var node = evt.target; - do { - if (node === this) { - $(this).removeClass('drop'); - $(this).html($btnContent); - break; - } - } while (node === node.parentNode); - }); - var MAX_SIZE = (function(node) { var max = node.attr('data-max-size') || '120MiB'; var num = parseInt(/([0-9,]+).*/.exec(max)[1].replace(',', ''), 10); @@ -92,40 +62,66 @@ $(function() { return $rowItem; }; - $uploadBtn.on('change', function() { - $uploadFiles.empty().removeClass('error completed'); + if (!$.hasFileAPI()) { + $('#no-file-api').show(); + $uploadBtn.hide(); + } - var files = $uploadInput[0].filelist; + $uploadBtn.cabinet($uploadInput); - files.forEach(function(file) { - createRow(file.name, file.humanSize).appendTo($uploadFiles); - }); + $uploadBtn.on('dragenter', function(evt) { + if (this === evt.target) { + $(this).addClass('drop'); + $btnContent = $(this).html(); + $(this).html('Drop it here~'); + } + }); - var totalRow = createRow('', files.humanSize, 'total'); - totalRow.appendTo($uploadFiles); + $uploadBtn.on('drop', function() { + $(this).trigger('dragleave'); + }); - var $totalName = $('.file-name', totalRow); + $uploadBtn.on('dragleave', function(evt) { + var node = evt.target; + do { + if (node === this) { + $(this).removeClass('drop'); + $(this).html($btnContent); + break; + } + } while (node === node.parentNode); + }); + $uploadBtn.on('change', function() { + var files = $uploadInput[0].filelist; + var totalRow = createRow('', files.humanSize, 'total'); + var $totalName = $('.file-name', totalRow); var UPLOAD_ERR_MAX_SIZE = 'onii-chan y-your upload is t-too big…'; var UPLOAD_ERR_FAILED = 'Something went wrong; try again later.'; - - if (files.size > MAX_SIZE) { - $uploadFiles.addClass('error'); - $totalName.html(UPLOAD_ERR_MAX_SIZE); - return; - } - var up = files.upload('upload.php'); var eachRow = function(files, fn) { var hits = {}; files.forEach(function(file) { - ++hits[file.name]; var row = $($('li[data-filename="' + escape(file.name) + '"]')[hits[file.name] || 0]); + ++hits[file.name]; fn.call(row, row, file, files); }); }; + $uploadFiles.empty().removeClass('error completed'); + + files.forEach(function(file) { + createRow(file.name, file.humanSize).appendTo($uploadFiles); + }); + + totalRow.appendTo($uploadFiles); + + if (files.size > MAX_SIZE) { + $uploadFiles.addClass('error'); + $totalName.html(UPLOAD_ERR_MAX_SIZE); + return; + } up.on('uploadprogress', function(evt, files) { eachRow(files, function(row, file, files) { @@ -141,9 +137,10 @@ $(function() { }); up.on('load', function(evt, response) { + var res = JSON.parse(response); + switch (evt.target.status) { case 200: - var res = JSON.parse(response); if (!res.success) { $uploadFiles.addClass('error'); $totalName.text(UPLOAD_ERR_FAILED); -- cgit v1.2.3 From 25109de5f34842de0ea7a80e1a9f3e9c57e68e34 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Fri, 9 Oct 2015 16:04:58 +0000 Subject: Add missing newline introduced in previous commit Before this, JSCS would print an error about missing newline. This was introduced in previous commit 24ce733. --- js/pomf.js | 1 + 1 file changed, 1 insertion(+) (limited to 'js') diff --git a/js/pomf.js b/js/pomf.js index 1e89576..a8cd248 100644 --- a/js/pomf.js +++ b/js/pomf.js @@ -109,6 +109,7 @@ $(function() { fn.call(row, row, file, files); }); }; + $uploadFiles.empty().removeClass('error completed'); files.forEach(function(file) { -- cgit v1.2.3 From 001cb4bb2419059275cc97e3e9af0ea36d8972d7 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Fri, 9 Oct 2015 16:52:56 +0000 Subject: Lint cheesesteak.js vars to top of function Fixes ESLint vars-on-top errors using airbnb/legacy config. --- js/cheesesteak.js | 96 +++++++++++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 46 deletions(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 661d4b7..8b1f09d 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -25,6 +25,51 @@ // Lightweight EventEmitter implementation var EventEmitter = function() {}; + // Utility to convert bytes into human units + var humanSize = { + get: function humanSize() { + var units = [ + 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', + ]; + var base = Math.floor(Math.log(this.size) / Math.log(1024)); + return (this.size / Math.pow(1024, base)).toFixed(2) + ' ' + units[base]; + }, + }; + + var percentUploaded = { + get: function percentUploaded() { + return this.uploadedSize / this.size; + }, + }; + + // b gets merged as defaults for a + var merge = function merge(base, overlay) { + var out = base; + var key; + + for (key in overlay) { + if (typeof overlay[key] === 'object') { + out[key] = merge(base[key], overlay[key]); + } else { + out[key] = overlay[key]; + } + } + + return out; + }; + + var FileListUploader = function(url, files, opts) { + var request = opts || {}; + + this.url = url; + this.files = files; + this.opts = merge({ + field: 'files[]', + method: 'POST', + data: {}, + }, request); + }; + EventEmitter.prototype.on = function(evt, fn) { this._events = this._events || {}; this._events[evt] = this._events[evt] || []; @@ -70,24 +115,9 @@ }, }); - // Utility to convert bytes into human units - var humanSize = { - get: function humanSize() { - var units = [ - 'B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB', - ]; - var base = Math.floor(Math.log(this.size) / Math.log(1024)); - return (this.size / Math.pow(1024, base)).toFixed(2) + ' ' + units[base]; - }, - }; Object.defineProperty(FileList.prototype, 'humanSize', humanSize); Object.defineProperty(File.prototype, 'humanSize', humanSize); - var percentUploaded = { - get: function percentUploaded() { - return this.uploadedSize / this.size; - }, - }; Object.defineProperty(FileList.prototype, 'percentUploaded', percentUploaded); Object.defineProperty(File.prototype, 'percentUploaded', percentUploaded); @@ -110,52 +140,24 @@ window.URL.revokeObjectURL(url); }; - // b gets merged as defaults for a - var merge = function merge(base, overlay) { - var out = base; - for (var key in overlay) { - if (typeof overlay[key] === 'object') { - out[key] = merge(base[key], overlay[key]); - } else { - out[key] = overlay[key]; - } - } - - return out; - }; - - var FileListUploader = function(url, files, opts) { - this.url = url; - this.files = files; - - var request = opts || {}; - - this.opts = merge({ - field: 'files[]', - method: 'POST', - data: {}, - }, request); - }; - FileListUploader.prototype = Object.create(EventEmitter.prototype); FileListUploader.prototype.upload = function(cb) { var opts = this.opts; var files = this.files; var _this = this; var len = files.length; + var data = new FormData(); + var xhr = new XMLHttpRequest(); var i; if (cb) { this.on('uploadcomplete', cb); } - var data = new FormData(); files.forEach(function(file) { data.append(opts.field, file); }); - var xhr = new XMLHttpRequest(); - xhr.open(opts.method, this.url, true); xhr.upload.addEventListener('loadstart', function() { for (i = 0; i < len; i++) { @@ -164,8 +166,10 @@ }); xhr.upload.addEventListener('progress', function(evt) { + var size; + if (evt.lengthComputable) { - var size = evt.loaded; + size = evt.loaded; /** * We know the size of the files, the order they're in, and how -- cgit v1.2.3 From 251b4d789d13e39436937e98500c5c5e2ab4d427 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Sun, 11 Oct 2015 16:32:08 +0000 Subject: Fix JSCS missing newline errors Using preset "airbnb". --- js/cheesesteak.js | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 3447d97..ba65e48 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -165,6 +165,7 @@ files[i].uploadedSize = 0; } } + xhr.upload.addEventListener('loadstart', initProgressBar); function updateProgressBar(evt) { @@ -193,24 +194,28 @@ _this.emit('uploadprogress', evt, files); } + xhr.upload.addEventListener('progress', updateProgressBar, false); // The upload is complete, now tell the user to wait for URLs. function postUpload(evt) { _this.emit('uploadcomplete', evt); } + xhr.upload.addEventListener('load', postUpload); // Tell the browser the upload completed and wait for response. function postProgress(evt) { _this.emit('progress', evt); } + xhr.addEventListener('progress', postProgress); // Send a success/error response. Nothing more to do. function uploadFinished(evt) { _this.emit('load', evt, xhr.responseText); } + xhr.addEventListener('load', uploadFinished); xhr.send(data); -- cgit v1.2.3 From f413dc9a1b944fd653c3bc089516c3363fb57857 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Wed, 18 Nov 2015 11:54:42 +0000 Subject: Remove unused JavaScript variables (no-unused-vars) Quoting ESLint: > Variables that are declared and not used anywhere in the code are most > likely an error due to incomplete refactoring. Such variables take up > space in the code and can lead to confusion by readers. This commit removes them. Fixes ESLint no-unused-vars errors using airbnb/legacy config. Suggested-by: marc --- js/cheesesteak.js | 2 +- js/pomf.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index ba65e48..905c5f3 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -160,7 +160,7 @@ xhr.open(opts.method, this.url, true); - function initProgressBar(evt) { + function initProgressBar() { for (i = 0; i < len; i++) { files[i].uploadedSize = 0; } diff --git a/js/pomf.js b/js/pomf.js index a8cd248..f1b23f3 100644 --- a/js/pomf.js +++ b/js/pomf.js @@ -125,7 +125,7 @@ $(function() { } up.on('uploadprogress', function(evt, files) { - eachRow(files, function(row, file, files) { + eachRow(files, function(row, file) { $('.progress-inner', row).width((file.percentUploaded * 100) + '%'); }); -- cgit v1.2.3 From d527b2d6769bdc0d2cd6744f1bda9d8da74ef6a6 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Wed, 18 Nov 2015 12:24:32 +0000 Subject: Rename local variables to unique private names When a local variable shares the same name with a variable in its scope, it can cause confusion to the reader and make it impossible to access the global variable. Disallow shadowing. Fixes ESLint no-shadow errors using airbnb/legacy config. Suggested-by: marc --- js/pomf.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'js') diff --git a/js/pomf.js b/js/pomf.js index f1b23f3..4c2f9fe 100644 --- a/js/pomf.js +++ b/js/pomf.js @@ -100,13 +100,13 @@ $(function() { var UPLOAD_ERR_FAILED = 'Something went wrong; try again later.'; var up = files.upload('upload.php'); - var eachRow = function(files, fn) { + var eachRow = function(_files, fn) { var hits = {}; - files.forEach(function(file) { + _files.forEach(function(file) { var row = $($('li[data-filename="' + escape(file.name) + '"]')[hits[file.name] || 0]); ++hits[file.name]; - fn.call(row, row, file, files); + fn.call(row, row, file, _files); }); }; @@ -124,12 +124,12 @@ $(function() { return; } - up.on('uploadprogress', function(evt, files) { - eachRow(files, function(row, file) { + up.on('uploadprogress', function(evt, _files) { + eachRow(_files, function(row, file) { $('.progress-inner', row).width((file.percentUploaded * 100) + '%'); }); - $('.progress-inner', totalRow).width((files.percentUploaded * 100) + '%'); + $('.progress-inner', totalRow).width((_files.percentUploaded * 100) + '%'); }); up.on('uploadcomplete', function() { -- cgit v1.2.3 From a46c5d3a4d7d7bae4e1001923806cfcee8d71b35 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Wed, 18 Nov 2015 13:46:22 +0000 Subject: Rename identifier "$" to "cabinet" in cabinet.js Very short identifier names usually make the code harder to read and potentially less maintainable. Fixes two ESLint id-length errors using airbnb/legacy config. Suggested-by: avail --- js/cabinet.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/cabinet.js b/js/cabinet.js index 09f4e71..b820d9b 100644 --- a/js/cabinet.js +++ b/js/cabinet.js @@ -21,8 +21,8 @@ */ /* jshint browser:true, jquery:true */ -(function($) { - $.hasFileAPI = function hasFileAPI() { +(function(cabinet) { + cabinet.hasFileAPI = function hasFileAPI() { return Boolean(window.FormData); }; -- cgit v1.2.3 From c950e85c8248800f321e280c16a48f15a35e8d4a Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Wed, 18 Nov 2015 15:42:31 +0000 Subject: Workaround undefined length TypeError in cheesesteak this._events[evt].length would run into JavaScript scope issues in EventEmitter.prototype.emit function for-loop. This is an attempt to work around the issue to resolve an innocent looking TypeError. The code seems to work without this patch, but I can't spot if this is some dead code or know what to do with it. Due to technical debt, some sacrifice had to be made in readability for fixing this bug. This bug was introduced in commit 575b78b. For future improvement, this function and other functions in the file should be refactored or replaced with a more efficient implementation. --- js/cheesesteak.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 905c5f3..90802d3 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -85,14 +85,14 @@ }; EventEmitter.prototype.emit = function(evt) { - var len = this._events[evt].length; var i; + var len; if (!this.hasOwnProperty('_events') || evt in this._events === false) { return; } - for (i = 0; i < len; i++) { + for (i = 0, len = this._events[evt].length; i < len; i++) { this._events[evt][i].apply(this, Array.prototype.slice.call(arguments, 1)); } -- cgit v1.2.3 From c257a1c1d63197f5349c12962558eccc7837a0f5 Mon Sep 17 00:00:00 2001 From: Juuso Lapinlampi Date: Wed, 18 Nov 2015 16:24:14 +0000 Subject: Refactor cheesesteak.js EventEmitter emit function Previous commit c950e85 came with a workaround to resolve a TypeError in EventEmitter.prototype.emit for-loop. That workaround sacrificed some readability for bug fixing due to technical debt. bursey came up with a better solution on IRC which seems to work and improves readability. Something needs to emit an event that wasn't bound with "on", thus the event was not in the _events object. Airbnb ES5 style guide requires to have all variables at top, so we leave the len variable undefined at the top to be defined later. After the _events check, we define len to avoid the TypeError issue while conforming to Airbnb ES5 style guide and improving readability. This commit also adds comments to document the function. Suggested-by: bursey (#/g/partyvan @ Partyvan IRC) --- js/cheesesteak.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'js') diff --git a/js/cheesesteak.js b/js/cheesesteak.js index 90802d3..31a8fd9 100644 --- a/js/cheesesteak.js +++ b/js/cheesesteak.js @@ -88,11 +88,15 @@ var i; var len; + // Check whether the event we want to emit actually exists if (!this.hasOwnProperty('_events') || evt in this._events === false) { return; } - for (i = 0, len = this._events[evt].length; i < len; i++) { + len = this._events[evt].length; + + // Call all functions that are bound to the event + for (i = 0; i < len; i++) { this._events[evt][i].apply(this, Array.prototype.slice.call(arguments, 1)); } -- cgit v1.2.3