From 1db51501a58ccc6021bf869ca21ad8e546427443 Mon Sep 17 00:00:00 2001 From: Bryan Housel Date: Sun, 23 Aug 2015 03:14:20 -0400 Subject: [PATCH] switch jshint to eslint (closes #2733) --- .eslintignore | 2 + .eslintrc | 73 ++++++++++++++++++++++++++++++++++++ .jshintrc | 27 ------------- CONTRIBUTING.md | 12 +++--- README.md | 2 +- js/id/actions/circularize.js | 8 ++-- js/id/actions/connect.js | 4 +- js/id/core/connection.js | 2 +- js/id/end.js | 1 - js/id/id.js | 6 +-- js/id/presets/preset.js | 6 +-- js/id/start.js | 1 - js/id/svg.js | 2 +- js/id/svg/labels.js | 8 ++-- js/id/util.js | 5 ++- package.json | 4 +- 16 files changed, 105 insertions(+), 58 deletions(-) create mode 100644 .eslintignore create mode 100644 .eslintrc delete mode 100644 .jshintrc diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000..cd9ae3522 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,2 @@ +js/id/start.js +js/id/end.js diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..1d4b247c2 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,73 @@ +{ + "extends": "eslint:recommended", + "rules": { + "dot-notation": 2, + "eqeqeq": [2, "smart"], + "indent": [0, 4], + "linebreak-style": [2, "unix"], + "no-caller": 2, + "no-catch-shadow": 2, + "no-div-regex": 2, + "no-empty-label": 2, + "no-extend-native": 2, + "no-extra-bind": 2, + "no-floating-decimal": 2, + "no-implied-eval": 2, + "no-invalid-this": 2, + "no-iterator": 2, + "no-labels": 2, + "no-label-var": 2, + "no-lone-blocks": 2, + "no-loop-func": 2, + "no-multi-str": 2, + "no-native-reassign": 2, + "no-new": 2, + "no-new-func": 2, + "no-new-wrappers": 2, + "no-octal": 2, + "no-octal-escape": 2, + "no-process-env": 2, + "no-proto": 2, + "no-return-assign": 0, + "no-script-url": 2, + "no-self-compare": 2, + "no-sequences": 2, + "no-shadow": 0, + "no-shadow-restricted-names": 2, + "no-throw-literal": 2, + "no-unneeded-ternary": 2, + "no-unused-expressions": 2, + "no-unexpected-multiline": 2, + "no-unused-vars": 1, + "no-void": 2, + "no-warning-comments": 1, + "no-with": 2, + "no-use-before-define": [0, "nofunc"], + "semi": [2, "always"], + "semi-spacing": 2, + "space-return-throw-case": 2, + "space-unary-ops": 2, + "wrap-regex": 0, + "quotes": [2, "single"] + }, + + "globals": { + "d3": false, + "iD": false, + "_": false, + "t": false, + "bootstrap": false, + "Diff3": false, + "rbush": false, + "JXON": false, + "osmAuth": false, + "sexagesimal": false, + "toGeoJSON": false, + "marked": false + }, + + "env": { + "browser": true + } + +} diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 74c9584db..000000000 --- a/.jshintrc +++ /dev/null @@ -1,27 +0,0 @@ -{ - "eqeqeq": true, - "freeze": true, - "latedef": "nofunc", - "noarg": true, - "noempty": true, - "nonew": true, - "quotmark": "single", - "undef": true, - "globals": { - "d3": false, - "iD": false, - "_": false, - "t": false, - "bootstrap": false, - "Diff3": false, - "rbush": false, - "JXON": false, - "osmAuth": false, - "sexagesimal": false, - "toGeoJSON": false, - "marked": false - }, - "browser": true, - "unused": true, - "trailing": true -} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 85f07c526..8771f2a19 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -96,8 +96,8 @@ Use `make` to build the translations with the local changes. ## Contributing Documentation Documentation is maintained as a series of [Markdown](http://daringfireball.net/projects/markdown/) -documents in [core.yaml](/data/core.yaml). The documentation -is in the `help` section (currently starting at line 258). The first line +documents in [core.yaml](/data/core.yaml). The documentation +is in the `help` section (currently starting at line 258). The first line of each new section of documentation should be of the form # GPS @@ -110,8 +110,8 @@ To add a new piece of documentation, simply add to [core.yaml](/data/core.yaml) ## Adding or Refining Presets -Presets save time for iD users by automatically showing them the tags they are -likely to add for a given feature. They are stored in `data/presets/presets`. If +Presets save time for iD users by automatically showing them the tags they are +likely to add for a given feature. They are stored in `data/presets/presets`. If you're going to update the presets, [review the Presets README](/data/presets/README.md). ## Javascript @@ -124,7 +124,7 @@ only one difference: No aligned `=`, no aligned arguments, spaces are either indents or the 1 space between expressions. No hard tabs, ever. -Javascript code should pass through [JSHint](http://www.jshint.com/) with no +Javascript code should pass through [ESLint](http://eslint.org/) with no warnings. ## HTML @@ -191,7 +191,7 @@ them. So let's say you've changed `js/ui/confirm.js`. -1. Run `jshint js/id` to make sure your code is clean +1. Run `eslint js/id` to make sure your code is clean 2. Run tests with `npm test` 3. Commit your changes with an informative commit message 4. [Submit a pull request](https://help.github.com/articles/using-pull-requests) to the `openstreetmap/iD` project. diff --git a/README.md b/README.md index 60c7f9a29..a0d37fcc9 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ [![translation chart](https://www.transifex.com/projects/p/id-editor/chart/image_png)](https://github.com/openstreetmap/iD/blob/master/CONTRIBUTING.md#translating) ## Installation -To run the current development version, fork this project and serve it locally. +To run the current development version, fork this project, run `make`, and serve it locally. If you have Python handy, just `cd` into the project root directory and run python -m SimpleHTTPServer diff --git a/js/id/actions/circularize.js b/js/id/actions/circularize.js index 6e9f44b0a..de720c4e5 100644 --- a/js/id/actions/circularize.js +++ b/js/id/actions/circularize.js @@ -106,16 +106,16 @@ iD.actions.Circularize = function(wayId, projection, maxAngle) { var startIndex1 = way.nodes.lastIndexOf(startNode.id), endIndex1 = way.nodes.lastIndexOf(endNode.id), wayDirection1 = (endIndex1 - startIndex1); - if (wayDirection1 < -1) { wayDirection1 = 1;} + if (wayDirection1 < -1) { wayDirection1 = 1; } - /*jshint -W083 */ + /* eslint-disable no-loop-func */ _.each(_.without(graph.parentWays(keyNodes[i]), way), function(sharedWay) { if (sharedWay.areAdjacent(startNode.id, endNode.id)) { var startIndex2 = sharedWay.nodes.lastIndexOf(startNode.id), endIndex2 = sharedWay.nodes.lastIndexOf(endNode.id), wayDirection2 = (endIndex2 - startIndex2), insertAt = endIndex2; - if (wayDirection2 < -1) { wayDirection2 = 1;} + if (wayDirection2 < -1) { wayDirection2 = 1; } if (wayDirection1 !== wayDirection2) { inBetweenNodes.reverse(); @@ -127,7 +127,7 @@ iD.actions.Circularize = function(wayId, projection, maxAngle) { graph = graph.replace(sharedWay); } }); - /*jshint +W083 */ + /* eslint-enable no-loop-func */ } } diff --git a/js/id/actions/connect.js b/js/id/actions/connect.js index df36c1d39..d82cedd60 100644 --- a/js/id/actions/connect.js +++ b/js/id/actions/connect.js @@ -19,7 +19,7 @@ iD.actions.Connect = function(nodeIds) { for (var i = 0; i < nodeIds.length - 1; i++) { var node = graph.entity(nodeIds[i]); - /*jshint -W083 */ + /* eslint-disable no-loop-func */ graph.parentWays(node).forEach(function(parent) { if (!parent.areAdjacent(node.id, survivor.id)) { graph = graph.replace(parent.replaceNode(node.id, survivor.id)); @@ -29,7 +29,7 @@ iD.actions.Connect = function(nodeIds) { graph.parentRelations(node).forEach(function(parent) { graph = graph.replace(parent.replaceMember(node, survivor)); }); - /*jshint +W083 */ + /* eslint-enable no-loop-func */ survivor = survivor.mergeTags(node.tags); graph = iD.actions.DeleteNode(node.id)(graph); diff --git a/js/id/core/connection.js b/js/id/core/connection.js index 5e54acdfe..6944ed73c 100644 --- a/js/id/core/connection.js +++ b/js/id/core/connection.js @@ -255,7 +255,7 @@ iD.Connection = function(useHttps) { created_by: 'iD ' + iD.version, imagery_used: imageryUsed.join(';').substr(0, 255), host: (window.location.origin + window.location.pathname).substr(0, 255), - locale: detected.locale, + locale: detected.locale }; if (comment) { diff --git a/js/id/end.js b/js/id/end.js index 7885eb370..0319a0fe5 100644 --- a/js/id/end.js +++ b/js/id/end.js @@ -1,2 +1 @@ -/* jshint ignore:start */ })(); diff --git a/js/id/id.js b/js/id/id.js index b3eddc110..293baaab3 100644 --- a/js/id/id.js +++ b/js/id/id.js @@ -7,7 +7,7 @@ window.iD = function () { // https://github.com/openstreetmap/iD/issues/772 // http://mathiasbynens.be/notes/localstorage-pattern#comment-9 - try { storage = localStorage; } catch (e) {} + try { storage = localStorage; } catch (e) {} // eslint-disable-line no-empty storage = storage || (function() { var s = {}; return { @@ -24,9 +24,9 @@ window.iD = function () { else storage.setItem(k, v); } catch(e) { // localstorage quota exceeded - /* jshint devel:true */ + /* eslint-disable no-console */ if (typeof console !== 'undefined') console.error('localStorage quota exceeded'); - /* jshint devel:false */ + /* eslint-enable no-console */ } }; diff --git a/js/id/presets/preset.js b/js/id/presets/preset.js index c893eac06..32411eaab 100644 --- a/js/id/presets/preset.js +++ b/js/id/presets/preset.js @@ -72,7 +72,7 @@ iD.presets.Preset = function(id, preset, fields) { for (var f in preset.fields) { var field = preset.fields[f]; - if (field.matchGeometry(geometry) && field['default'] === tags[field.key]) { + if (field.matchGeometry(geometry) && field.default === tags[field.key]) { delete tags[field.key]; } } @@ -116,8 +116,8 @@ iD.presets.Preset = function(id, preset, fields) { for (var f in preset.fields) { var field = preset.fields[f]; - if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field['default']) { - tags[field.key] = field['default']; + if (field.matchGeometry(geometry) && field.key && !tags[field.key] && field.default) { + tags[field.key] = field.default; } } diff --git a/js/id/start.js b/js/id/start.js index 773daac48..6d6f50c31 100644 --- a/js/id/start.js +++ b/js/id/start.js @@ -1,3 +1,2 @@ -/* jshint ignore:start */ (function () { 'use strict'; diff --git a/js/id/svg.js b/js/id/svg.js index 680107910..993692581 100644 --- a/js/id/svg.js +++ b/js/id/svg.js @@ -31,7 +31,7 @@ iD.svg = { if (entity.id in cache) { return cache[entity.id]; } else { - return cache[entity.id] = path(entity.asGeoJSON(graph)); // jshint ignore:line + return cache[entity.id] = path(entity.asGeoJSON(graph)); } }; }, diff --git a/js/id/svg/labels.js b/js/id/svg/labels.js index fe617d1a9..a76a96afd 100644 --- a/js/id/svg/labels.js +++ b/js/id/svg/labels.js @@ -182,7 +182,7 @@ iD.svg.Labels = function(projection, context) { function reverse(p) { var angle = Math.atan2(p[1][1] - p[0][1], p[1][0] - p[0][0]); - return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > - Math.PI/2); + return !(p[0][0] < p[p.length - 1][0] && angle < Math.PI/2 && angle > -Math.PI/2); } function lineString(nodes) { @@ -279,7 +279,7 @@ iD.svg.Labels = function(projection, context) { if (!icon && !iD.util.displayName(entity)) continue; - for (k = 0; k < label_stack.length; k ++) { + for (k = 0; k < label_stack.length; k++) { if (geometry === label_stack[k][0] && entity.tags[label_stack[k][1]]) { labelable[k].push(entity); break; @@ -302,7 +302,7 @@ iD.svg.Labels = function(projection, context) { // Try and find a valid label for labellable entities for (k = 0; k < labelable.length; k++) { var font_size = font_sizes[k]; - for (i = 0; i < labelable[k].length; i ++) { + for (i = 0; i < labelable[k].length; i++) { entity = labelable[k][i]; var name = iD.util.displayName(entity), width = name && textWidth(name, font_size), @@ -343,7 +343,7 @@ iD.svg.Labels = function(projection, context) { length = iD.geo.pathLength(nodes); if (length < width + 20) return; - for (var i = 0; i < lineOffsets.length; i ++) { + for (var i = 0; i < lineOffsets.length; i++) { var offset = lineOffsets[i], middle = offset / 100 * length, start = middle - width/2; diff --git a/js/id/util.js b/js/id/util.js index 6ed3d388f..4fc4001d4 100644 --- a/js/id/util.js +++ b/js/id/util.js @@ -151,8 +151,9 @@ iD.util.fastMouse = function(container) { }; }; -/* jshint -W103 */ +/* eslint-disable no-proto */ iD.util.getPrototypeOf = Object.getPrototypeOf || function(obj) { return obj.__proto__; }; +/* eslint-enable no-proto */ iD.util.asyncMap = function(inputs, func, callback) { var remaining = inputs.length, @@ -163,7 +164,7 @@ iD.util.asyncMap = function(inputs, func, callback) { func(d, function done(err, data) { errors[i] = err; results[i] = data; - remaining --; + remaining--; if (!remaining) callback(errors, results); }); }); diff --git a/package.json b/package.json index 9671721e3..d6174e3ab 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "test": "test" }, "scripts": { - "test": "jshint js/id && mocha-phantomjs test/index.html && make && mocha-phantomjs test/index_packaged.html" + "test": "eslint js/id && mocha-phantomjs test/index.html && make && mocha-phantomjs test/index_packaged.html" }, "repository": { "type": "git", @@ -25,7 +25,7 @@ "lodash-cli": "3.9.3", "uglify-js": "~2.4.16", "maki": "0.4.5", - "jshint": "2.3.0", + "eslint": "~1.2.1", "mocha": "~1.21.5", "mocha-phantomjs": "~3.5.3", "chai": "~1.9.2",