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/cheesesteak.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'js/cheesesteak.js') 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/cheesesteak.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/cheesesteak.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 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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/cheesesteak.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 -- 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/cheesesteak.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 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/cheesesteak.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/cheesesteak.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 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/cheesesteak.js | 49 +++++++++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 22 deletions(-) (limited to 'js/cheesesteak.js') 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 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/cheesesteak.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/cheesesteak.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 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'js/cheesesteak.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; } -- 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/cheesesteak.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/cheesesteak.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