From 33427418763048dc77beb0ef3c06b77e1774f6d9 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 02:30:49 -0400 Subject: [PATCH 1/7] JSHint QUnit helpers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Don’t redefine controller - Mark all functions as exported - Mark the QUnit asyncTest as a global function --- .jshintignore | 1 - test/javascripts/helpers/qunit_helpers.js | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.jshintignore b/.jshintignore index a69f6a1f5..3d225717a 100644 --- a/.jshintignore +++ b/.jshintignore @@ -10,6 +10,5 @@ public/javascripts/ spec/phantom_js/smoke_test.js test/javascripts/helpers/assertions.js test/javascripts/helpers/parse_html.js -test/javascripts/helpers/qunit_helpers.js test/javascripts/test_helper.js vendor/ diff --git a/test/javascripts/helpers/qunit_helpers.js b/test/javascripts/helpers/qunit_helpers.js index 79bccf3ac..448adf8df 100644 --- a/test/javascripts/helpers/qunit_helpers.js +++ b/test/javascripts/helpers/qunit_helpers.js @@ -1,3 +1,5 @@ +/* global asyncTest */ +/* exported integration, testController, controllerFor, asyncTestDiscourse, fixture */ function integration(name, lifecycle) { module("Integration: " + name, { setup: function() { @@ -27,7 +29,7 @@ function testController(klass, model) { } function controllerFor(controller, model) { - var controller = Discourse.__container__.lookup('controller:' + controller); + controller = Discourse.__container__.lookup('controller:' + controller); if (model) { controller.set('model', model ); } return controller; } From 054eca840a6def3456d4492e4fff30cd1e24eff3 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 02:34:17 -0400 Subject: [PATCH 2/7] JSHint parse_html.js - Mark Tautologistics as a global - Mark parseHTML as exported --- .jshintignore | 1 - test/javascripts/helpers/parse_html.js | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.jshintignore b/.jshintignore index 3d225717a..62756bbfb 100644 --- a/.jshintignore +++ b/.jshintignore @@ -9,6 +9,5 @@ lib/javascripts/moment_locale/ public/javascripts/ spec/phantom_js/smoke_test.js test/javascripts/helpers/assertions.js -test/javascripts/helpers/parse_html.js test/javascripts/test_helper.js vendor/ diff --git a/test/javascripts/helpers/parse_html.js b/test/javascripts/helpers/parse_html.js index 8b1f9d13e..4c15c9826 100644 --- a/test/javascripts/helpers/parse_html.js +++ b/test/javascripts/helpers/parse_html.js @@ -1,3 +1,5 @@ +/* global Tautologistics */ +/* exported parseHTML */ function parseHTML(rawHtml) { var builder = new Tautologistics.NodeHtmlParser.HtmlBuilder(), parser = new Tautologistics.NodeHtmlParser.Parser(builder); From 86a9e0db6a64654f625e65f6b31be21a601b8e56 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 02:36:10 -0400 Subject: [PATCH 3/7] JSHint assertions.js Mark all functions as exported --- .jshintignore | 1 - test/javascripts/helpers/assertions.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/.jshintignore b/.jshintignore index 62756bbfb..39fa66750 100644 --- a/.jshintignore +++ b/.jshintignore @@ -8,6 +8,5 @@ lib/javascripts/moment.js lib/javascripts/moment_locale/ public/javascripts/ spec/phantom_js/smoke_test.js -test/javascripts/helpers/assertions.js test/javascripts/test_helper.js vendor/ diff --git a/test/javascripts/helpers/assertions.js b/test/javascripts/helpers/assertions.js index 533a6b9dc..fdba18ca3 100644 --- a/test/javascripts/helpers/assertions.js +++ b/test/javascripts/helpers/assertions.js @@ -1,3 +1,4 @@ +/* exported exists, count, present, blank, containsInstance, not */ // Test helpers function exists(selector) { return !!count(selector); From 62d5a108736578e120e71c56bfe38307849d90a2 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 02:40:27 -0400 Subject: [PATCH 4/7] JSHint test helpers Remove unreferenced globals --- .jshintignore | 1 - test/javascripts/test_helper.js | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.jshintignore b/.jshintignore index 39fa66750..9336d11d8 100644 --- a/.jshintignore +++ b/.jshintignore @@ -8,5 +8,4 @@ lib/javascripts/moment.js lib/javascripts/moment_locale/ public/javascripts/ spec/phantom_js/smoke_test.js -test/javascripts/test_helper.js vendor/ diff --git a/test/javascripts/test_helper.js b/test/javascripts/test_helper.js index abcbdf566..4ae827db9 100644 --- a/test/javascripts/test_helper.js +++ b/test/javascripts/test_helper.js @@ -1,5 +1,5 @@ /*jshint maxlen:250 */ -/*global count:true find:true document:true equal:true sinon:true */ +/*global document, sinon, console, QUnit */ //= require env From 635c0dbf7ae31f62f0ee1601648842d9e155e014 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 03:01:12 -0400 Subject: [PATCH 5/7] JSHint i18n.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Mark the I18n object as an overridable global - Normalize comma first style rather than turning on lax comma - Add missing semicolons - Remove unnecessary semicolons - Fix options overloading in “lookup” - Use strict comparison for typeof checks and remove unnecessary parens --- .jshintignore | 1 - app/assets/javascripts/locales/i18n.js | 118 ++++++++++++------------- 2 files changed, 57 insertions(+), 62 deletions(-) diff --git a/.jshintignore b/.jshintignore index 9336d11d8..26a6c2b7f 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1,5 +1,4 @@ app/assets/javascripts/defer/html-sanitizer-bundle.js -app/assets/javascripts/locales/ lib/autospec/run-qunit.js lib/headless-ember.js lib/javascripts/locale/ diff --git a/app/assets/javascripts/locales/i18n.js b/app/assets/javascripts/locales/i18n.js index 05edb4fe2..84d5f9a21 100644 --- a/app/assets/javascripts/locales/i18n.js +++ b/app/assets/javascripts/locales/i18n.js @@ -1,3 +1,5 @@ +/*global I18n:true */ + // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf if (!Array.prototype.indexOf) { Array.prototype.indexOf = function (searchElement, fromIndex) { @@ -52,7 +54,7 @@ I18n.fallbackRules = {}; I18n.pluralizationRules = { en: function (n) { - return n == 0 ? ["zero", "none", "other"] : n == 1 ? "one" : "other"; + return n === 0 ? ["zero", "none", "other"] : n === 1 ? "one" : "other"; } }; @@ -60,8 +62,8 @@ I18n.getFallbacks = function(locale) { if (locale === I18n.defaultLocale) { return []; } else if (!I18n.fallbackRules[locale]) { - var rules = [] - , components = locale.split("-"); + var rules = [], + components = locale.split("-"); for (var l = 1; l < components.length; l++) { rules.push(components.slice(0, l).join("-")); @@ -73,23 +75,23 @@ I18n.getFallbacks = function(locale) { } return I18n.fallbackRules[locale]; -} +}; I18n.isValidNode = function(obj, node, undefined) { return obj[node] !== null && obj[node] !== undefined; }; I18n.lookup = function(scope, options) { - var options = options || {} - , lookupInitialScope = scope - , translations = this.prepareOptions(I18n.translations) - , locale = options.locale || I18n.currentLocale() - , messages = translations[locale] || {} - , options = this.prepareOptions(options) - , currentScope - ; + options = options || {}; + var lookupInitialScope = scope, + translations = this.prepareOptions(I18n.translations), + locale = options.locale || I18n.currentLocale(), + messages = translations[locale] || {}, + currentScope; - if (typeof(scope) == "object") { + options = this.prepareOptions(options); + + if (typeof scope === "object") { scope = scope.join(this.defaultSeparator); } @@ -130,10 +132,9 @@ I18n.lookup = function(scope, options) { // #=> {name: "John Doe", role: "user"} // I18n.prepareOptions = function() { - var options = {} - , opts - , count = arguments.length - ; + var options = {}, + opts, + count = arguments.length; for (var i = 0; i < count; i++) { opts = arguments[i]; @@ -154,11 +155,10 @@ I18n.prepareOptions = function() { I18n.interpolate = function(message, options) { options = this.prepareOptions(options); - var matches = message.match(this.PLACEHOLDER) - , placeholder - , value - , name - ; + var matches = message.match(this.PLACEHOLDER), + placeholder, + value, + name; if (!matches) { return message; @@ -185,8 +185,8 @@ I18n.translate = function(scope, options) { var translation = this.lookup(scope, options); try { - if (typeof(translation) == "object") { - if (typeof(options.count) == "number") { + if (typeof translation === "object") { + if (typeof options.count === "number") { return this.pluralize(options.count, scope, options); } else { return translation; @@ -221,9 +221,9 @@ I18n.parseDate = function(date) { var matches, convertedDate; // we have a date, so just return it. - if (typeof(date) == "object") { + if (typeof date === "object") { return date; - }; + } // it matches the following formats: // yyyy-mm-dd @@ -247,14 +247,14 @@ I18n.parseDate = function(date) { } else { convertedDate = new Date(matches[1], matches[2], matches[3], matches[4], matches[5], matches[6]); } - } else if (typeof(date) == "number") { + } else if (typeof date === "number") { // UNIX timestamp convertedDate = new Date(); convertedDate.setTime(date); } else if (date.match(/\d+ \d+:\d+:\d+ [+-]\d+ \d+/)) { // a valid javascript format with timezone info convertedDate = new Date(); - convertedDate.setTime(Date.parse(date)) + convertedDate.setTime(Date.parse(date)); } else { // an arbitrary javascript string convertedDate = new Date(); @@ -265,9 +265,8 @@ I18n.parseDate = function(date) { }; I18n.toTime = function(scope, d) { - var date = this.parseDate(d) - , format = this.lookup(scope) - ; + var date = this.parseDate(d), + format = this.lookup(scope); if (date.toString().match(/invalid/i)) { return date.toString(); @@ -289,20 +288,19 @@ I18n.strftime = function(date, format) { options.meridian = options.meridian || ["AM", "PM"]; - var weekDay = date.getDay() - , day = date.getDate() - , year = date.getFullYear() - , month = date.getMonth() + 1 - , hour = date.getHours() - , hour12 = hour - , meridian = hour > 11 ? 1 : 0 - , secs = date.getSeconds() - , mins = date.getMinutes() - , offset = date.getTimezoneOffset() - , absOffsetHours = Math.floor(Math.abs(offset / 60)) - , absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60) - , timezoneoffset = (offset > 0 ? "-" : "+") + (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes) - ; + var weekDay = date.getDay(), + day = date.getDate(), + year = date.getFullYear(), + month = date.getMonth() + 1, + hour = date.getHours(), + hour12 = hour, + meridian = hour > 11 ? 1 : 0, + secs = date.getSeconds(), + mins = date.getMinutes(), + offset = date.getTimezoneOffset(), + absOffsetHours = Math.floor(Math.abs(offset / 60)), + absOffsetMinutes = Math.abs(offset) - (absOffsetHours * 60), + timezoneoffset = (offset > 0 ? "-" : "+") + (absOffsetHours.toString().length < 2 ? "0" + absOffsetHours : absOffsetHours) + (absOffsetMinutes.toString().length < 2 ? "0" + absOffsetMinutes : absOffsetMinutes); if (hour12 > 12) { hour12 = hour12 - 12; @@ -350,13 +348,12 @@ I18n.toNumber = function(number, options) { {precision: 3, separator: ".", delimiter: ",", strip_insignificant_zeros: false} ); - var negative = number < 0 - , string = Math.abs(number).toFixed(options.precision).toString() - , parts = string.split(".") - , precision - , buffer = [] - , formattedNumber - ; + var negative = number < 0, + string = Math.abs(number).toFixed(options.precision).toString(), + parts = string.split("."), + precision, + buffer = [], + formattedNumber; number = parts[0]; precision = parts[1]; @@ -378,8 +375,8 @@ I18n.toNumber = function(number, options) { if (options.strip_insignificant_zeros) { var regex = { - separator: new RegExp(options.separator.replace(/\./, "\\.") + "$") - , zeros: /0+$/ + separator: new RegExp(options.separator.replace(/\./, "\\.") + "$"), + zeros: /0+$/ }; formattedNumber = formattedNumber @@ -409,12 +406,11 @@ I18n.toCurrency = function(number, options) { }; I18n.toHumanSize = function(number, options) { - var kb = 1024 - , size = number - , iterations = 0 - , unit - , precision - ; + var kb = 1024, + size = number, + iterations = 0, + unit, + precision; while (size >= kb && iterations < 4) { size = size / kb; @@ -480,7 +476,7 @@ I18n.pluralize = function(count, scope, options) { var pluralizer = this.pluralizer(this.currentLocale()); var key = pluralizer(Math.abs(count)); - var keys = ((typeof key == "object") && (key instanceof Array)) ? key : [key]; + var keys = ((typeof key === "object") && (key instanceof Array)) ? key : [key]; var message = this.findAndTranslateValidNode(keys, translation); if (message == null) message = this.missingTranslation(scope, keys[0]); From 3782fbed2b817eab148c29592823ec7c8bdccb3e Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 03:10:55 -0400 Subject: [PATCH 6/7] JSHint run-qunit.js MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Turn on devel for console and phantom for the phantomjs globals - Remove unnecessary semicolons - Use strict comparisons - Add missing var statements used by for…in --- .jshintignore | 1 - lib/autospec/run-qunit.js | 12 +++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/.jshintignore b/.jshintignore index 26a6c2b7f..3b28be886 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1,5 +1,4 @@ app/assets/javascripts/defer/html-sanitizer-bundle.js -lib/autospec/run-qunit.js lib/headless-ember.js lib/javascripts/locale/ lib/javascripts/messageformat.js diff --git a/lib/autospec/run-qunit.js b/lib/autospec/run-qunit.js index 15804f269..59d152458 100644 --- a/lib/autospec/run-qunit.js +++ b/lib/autospec/run-qunit.js @@ -1,6 +1,8 @@ +/*jshint devel:true, phantom:true */ +/*global QUnit, ANSI */ // THIS FILE IS CALLED BY "qunit_runner.rb" IN AUTOSPEC -if (phantom.args.length != 1) { +if (phantom.args.length !== 1) { console.log("Usage: " + phantom.scriptName + " "); phantom.exit(1); } @@ -95,7 +97,7 @@ function colorizer() { return colorCode + text + colorEnd; } }; -}; +} function logQUnit() { @@ -144,10 +146,10 @@ function logQUnit() { // display failures if (Object.keys(errors).length > 0) { console.log("Failures:\n"); - for (m in errors) { + for (var m in errors) { var module = errors[m]; console.log("Module Failed: " + ANSI.highlight(m, "red")); - for (t in module) { + for (var t in module) { var test = module[t]; console.log(" Test Failed: " + t); for (var a = 0; a < test.length; a++) { @@ -172,4 +174,4 @@ function logQUnit() { window.qunitResult = context; }); -}; +} From 9f8d608a8d7e10cf0b6ebf4d6ba4828dd3617269 Mon Sep 17 00:00:00 2001 From: Nick Schonning Date: Tue, 11 Mar 2014 03:18:57 -0400 Subject: [PATCH 7/7] JSHint headless-ember - Mark all exported vars - Mark redefined global vars - Suppress leak warning for the redefinition of jQuery --- .jshintignore | 1 - lib/headless-ember.js | 4 ++++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.jshintignore b/.jshintignore index 3b28be886..e99008726 100644 --- a/.jshintignore +++ b/.jshintignore @@ -1,5 +1,4 @@ app/assets/javascripts/defer/html-sanitizer-bundle.js -lib/headless-ember.js lib/javascripts/locale/ lib/javascripts/messageformat.js lib/javascripts/moment.js diff --git a/lib/headless-ember.js b/lib/headless-ember.js index be7dcbdca..2c44eb4f2 100644 --- a/lib/headless-ember.js +++ b/lib/headless-ember.js @@ -1,3 +1,5 @@ +/*global Element:true, document:true, window:true, $:true, jQuery:true */ +/*exported precompileEmberHandlebars, $, jQuery */ // DOM var Element = {}; Element.firstChild = function () { return Element; }; @@ -11,8 +13,10 @@ this.document = document; var console = window.console = {}; console.log = console.info = console.warn = console.error = function(){}; +/*jshint -W120 */ // jQuery var $ = jQuery = window.jQuery = function() { return jQuery; }; +/*jshint +W120*/ jQuery.ready = function() { return jQuery; }; jQuery.inArray = function() { return jQuery; }; jQuery.event = {