diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 000000000000..315b45467795 --- /dev/null +++ b/.eslintignore @@ -0,0 +1,11 @@ +bower_components/** +build/** +docs/bower_components/** +docs/app/assets/js/angular-bootstrap/** +docs/config/templates/** +node_modules/** +lib/htmlparser/** +src/angular.bind.js +src/ngParseExt/ucd.js +i18n/closure/** +tmp/** diff --git a/.eslintrc-base.json b/.eslintrc-base.json new file mode 100644 index 000000000000..a22993a7761f --- /dev/null +++ b/.eslintrc-base.json @@ -0,0 +1,116 @@ +{ + "rules": { + // Rules are divided into sections from http://eslint.org/docs/rules/ + + // Possible errors + "comma-dangle": ["error", "never"], + "no-cond-assign": ["error", "except-parens"], + "no-constant-condition": ["error", {"checkLoops": false}], + "no-control-regex": "error", + "no-debugger": "error", + "no-dupe-args": "error", + "no-dupe-keys": "error", + "no-duplicate-case": "error", + "no-empty-character-class": "error", + "no-empty": "error", + "no-ex-assign": "error", + "no-extra-boolean-cast": "error", + "no-extra-semi": "error", + "no-func-assign": "error", + "no-inner-declarations": "error", + "no-invalid-regexp": "error", + "no-irregular-whitespace": "error", + "no-negated-in-lhs": "error", + "no-obj-calls": "error", + "no-regex-spaces": "error", + "no-sparse-arrays": "error", + "no-unreachable": "error", + "use-isnan": "error", + "no-unsafe-finally": "error", + "valid-typeof": "error", + "no-unexpected-multiline": "error", + + // Best practices + "accessor-pairs": "error", + "array-callback-return": "error", + "eqeqeq": ["error", "allow-null"], + "no-alert": "error", + "no-caller": "error", + "no-case-declarations": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-extra-bind": "error", + "no-extra-label": "error", + "no-fallthrough": "error", + "no-floating-decimal": "error", + "no-implied-eval": "error", + "no-invalid-this": "error", + "no-iterator": "error", + "no-multi-str": "error", + "no-new-func": "error", + "no-new-wrappers": "error", + "no-new": "error", + "no-octal-escape": "error", + "no-octal": "error", + "no-proto": "error", + "no-redeclare": "error", + "no-return-assign": "error", + "no-script-url": "error", + "no-self-assign": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-throw-literal": "error", + "no-unmodified-loop-condition": "error", + "no-unused-expressions": "error", + "no-unused-labels": "error", + "no-useless-call": "error", + "no-useless-concat": "error", + "no-useless-escape": "error", + "no-void": "error", + "no-with": "error", + "radix": "error", + "wrap-iife": ["error", "inside"], + + // Strict mode + "strict": ["error", "global"], + + // Variables + "no-delete-var": "error", + "no-label-var": "error", + "no-restricted-globals": ["error", "event"], + "no-shadow-restricted-names": "error", + "no-undef-init": "error", + "no-undef": "error", + "no-unused-vars": ["error", { "vars": "local", "args": "none" }], + + // Node.js + "handle-callback-err": "error", + + // Stylistic issues + "array-bracket-spacing": ["error", "never"], + "brace-style": ["error", "1tbs", { "allowSingleLine": true }], + "comma-style": ["error", "last"], + "eol-last": "error", + "keyword-spacing": "error", + "linebreak-style": ["error", "unix"], + "max-len": ["error", { "code": 200, "ignoreComments": true, "ignoreUrls": true }], + "new-cap": "error", + "new-parens": "error", + "no-array-constructor": "error", + "no-bitwise": "error", + "no-mixed-spaces-and-tabs": "error", + "no-multiple-empty-lines": ["error", { "max": 3, "maxEOF": 1 }], + "no-whitespace-before-property": "error", + "no-spaced-func": "error", + "no-trailing-spaces": "error", + "no-unneeded-ternary": "error", + "semi-spacing": "error", + "semi": "error", + "space-before-blocks": ["error", "always"], + "space-before-function-paren": ["error", "never"], + "space-in-parens": ["error", "never"], + "space-infix-ops": "error", + "space-unary-ops": ["error", { "words": true, "nonwords": false }], + "unicode-bom": ["error", "never"] + } +} diff --git a/.eslintrc-browser.json b/.eslintrc-browser.json new file mode 100644 index 000000000000..44024664ae8f --- /dev/null +++ b/.eslintrc-browser.json @@ -0,0 +1,17 @@ +{ + "extends": "./.eslintrc-base.json", + + "env": { + // Note: don't set `"browser": true`; code in "src/" should be compatible with + // non-browser environments like Node.js with a custom window implementation + // like jsdom. All browser globals should be taken from window. + "browser": false, + "node": false + }, + + "globals": { + "window": false, + + "angular": false + } +} diff --git a/.eslintrc-node.json b/.eslintrc-node.json new file mode 100644 index 000000000000..643f345d88e0 --- /dev/null +++ b/.eslintrc-node.json @@ -0,0 +1,8 @@ +{ + "extends": "./.eslintrc-base.json", + + "env": { + "browser": false, + "node": true + } +} diff --git a/.eslintrc-todo.json b/.eslintrc-todo.json new file mode 100644 index 000000000000..a80e6722b527 --- /dev/null +++ b/.eslintrc-todo.json @@ -0,0 +1,26 @@ +{ + // This config contains proposed rules that we'd like to have enabled but haven't + // converted the code to adhere yet. If a decision comes to not enable one of these + // rules, it should be removed from the file. Every rule that got enabled in the + // end should be moved from here to a respective section in .eslintrc.json + + "rules": { + // Rules are divided into sections from http://eslint.org/docs/rules/ + + // Best practices + "complexity": ["error", 10], + "dot-notation": "error", + "dot-location": ["error", "property"], + + // Stylistic issues + "block-spacing": ["error", "always"], + "comma-spacing": "error", + "id-blacklist": ["error", "event"], + "indent": ["error", 2], + "key-spacing": ["error", { "beforeColon": false, "afterColon": true, "mode": "minimum" }], + "object-curly-spacing": ["error", "never"], + "object-property-newline": ["error", { "allowMultiplePropertiesPerLine": true }], + "operator-linebreak": ["error", "after", { "overrides": { "?": "before", ":": "before" }}], + "quotes": ["error", "single"] + } +} diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 000000000000..d8de7a976909 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,4 @@ +{ + "root": true, + "extends": "./.eslintrc-node.json" +} diff --git a/.jscsrc b/.jscsrc deleted file mode 100644 index 4d2b16f30bcd..000000000000 --- a/.jscsrc +++ /dev/null @@ -1,48 +0,0 @@ -{ - "excludeFiles": ["src/ngLocale/**"], - "disallowKeywords": ["with"], - "disallowKeywordsOnNewLine": ["else"], - "disallowMixedSpacesAndTabs": true, - "disallowMultipleLineStrings": true, - "disallowNewlineBeforeBlockStatements": true, - "disallowSpaceAfterObjectKeys": true, - "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], - "disallowSpaceBeforeBinaryOperators": [","], - "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], - "disallowSpacesInAnonymousFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "disallowSpacesInCallExpression": true, - "disallowSpacesInFunctionDeclaration": { - "beforeOpeningRoundBrace": true - }, - "disallowSpacesInNamedFunctionExpression": { - "beforeOpeningRoundBrace": true - }, - "disallowSpacesInsideArrayBrackets": true, - "requireSpaceBeforeKeywords": [ - "else", - "while", - "catch" - ], - "disallowSpacesInsideParentheses": true, - "disallowTrailingComma": true, - "disallowTrailingWhitespace": true, - "requireCommaBeforeLineBreak": true, - "requireLineFeedAtFileEnd": true, - "requireSpaceAfterBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], - "requireSpaceBeforeBinaryOperators": ["?", ":", "+", "-", "/", "*", "%", "==", "===", "!=", "!==", ">", ">=", "<", "<=", "&&", "||"], - "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch"], - "requireSpaceBeforeBlockStatements": true, - "requireSpacesInConditionalExpression": { - "afterTest": true, - "beforeConsequent": true, - "afterConsequent": true, - "beforeAlternate": true - }, - "requireSpacesInForStatement": true, - "requireSpacesInFunction": { - "beforeOpeningCurlyBrace": true - }, - "validateLineBreaks": "LF" -} diff --git a/.jshintignore b/.jshintignore deleted file mode 100644 index e9cc4f260316..000000000000 --- a/.jshintignore +++ /dev/null @@ -1,2 +0,0 @@ -node_modules/** -lib/htmlparser/** diff --git a/.jshintrc b/.jshintrc deleted file mode 100644 index 7fbaafbc0a8c..000000000000 --- a/.jshintrc +++ /dev/null @@ -1,5 +0,0 @@ -{ - "extends": ".jshintrc-base", - "node": true, - "globals": {} -} diff --git a/.jshintrc-base b/.jshintrc-base deleted file mode 100644 index ace393873d38..000000000000 --- a/.jshintrc-base +++ /dev/null @@ -1,24 +0,0 @@ -{ - "bitwise": true, - "esversion": 6, - "immed": true, - "newcap": true, - "noarg": true, - "noempty": true, - "nonew": true, - "maxlen": 200, - "boss": true, - "eqnull": true, - "expr": true, - "laxbreak": true, - "loopfunc": true, - "strict": "global", - "sub": true, - "undef": true, - "indent": 2, - - "globals": { - "ArrayBuffer": false, - "Uint8Array": false - } -} diff --git a/Gruntfile.js b/Gruntfile.js index e94084cb96cd..bf4b1470d621 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -18,7 +18,7 @@ module.exports = function(grunt) { var NG_VERSION = versionInfo.currentVersion; NG_VERSION.cdn = versionInfo.cdnVersion; - var dist = 'angular-'+ NG_VERSION.full; + var dist = 'angular-' + NG_VERSION.full; if (versionInfo.cdnVersion == null) { throw new Error('Unable to read CDN version, are you offline or has the CDN not been properly pushed?'); @@ -41,7 +41,7 @@ module.exports = function(grunt) { hostname: '0.0.0.0', base: '.', keepalive: true, - middleware: function(connect, options){ + middleware: function(connect, options) { var base = Array.isArray(options.base) ? options.base[options.base.length - 1] : options.base; return [ util.conditionalCsp(), @@ -61,7 +61,7 @@ module.exports = function(grunt) { // to avoid https://github.com/joyent/libuv/issues/826 port: 8000, hostname: '0.0.0.0', - middleware: function(connect, options){ + middleware: function(connect, options) { var base = Array.isArray(options.base) ? options.base[options.base.length - 1] : options.base; return [ function(req, resp, next) { @@ -115,68 +115,24 @@ module.exports = function(grunt) { tmp: ['tmp'] }, - jshint: { - options: { - jshintrc: true, - }, - node: { - files: { src: ['*.js', 'lib/**/*.js'] }, - }, - tests: { - files: { src: 'test/**/*.js' }, - }, - ng: { - files: { src: files['angularSrc'].concat('!src/angular.bind.js') }, - }, - ngAnimate: { - files: { src: 'src/ngAnimate/**/*.js' }, - }, - ngCookies: { - files: { src: 'src/ngCookies/**/*.js' }, - }, - ngLocale: { - files: { src: 'src/ngLocale/**/*.js' }, - }, - ngMessageFormat: { - files: { src: 'src/ngMessageFormat/**/*.js' }, - }, - ngMessages: { - files: { src: 'src/ngMessages/**/*.js' }, - }, - ngMock: { - files: { src: 'src/ngMock/**/*.js' }, - }, - ngParseExt: { - files: { src: 'src/ngParseExt/**/*.js' }, - }, - ngResource: { - files: { src: 'src/ngResource/**/*.js' }, - }, - ngRoute: { - files: { src: 'src/ngRoute/**/*.js' }, - }, - ngSanitize: { - files: { src: 'src/ngSanitize/**/*.js' }, - }, - ngScenario: { - files: { src: 'src/ngScenario/**/*.js' }, - }, - ngTouch: { - files: { src: 'src/ngTouch/**/*.js' }, - }, - ngAria: { - files: {src: 'src/ngAria/**/*.js'}, - } - }, - - jscs: { - src: [ - 'src/**/*.js', - 'test/**/*.js', - '!src/angular.bind.js' // we ignore this file since contains an early return statement - ], - options: { - config: '.jscsrc' + eslint: { + all: { + src: [ + '*.js', + 'benchmarks/**/*.js', + 'docs/**/*.js', + 'lib/**/*.js', + 'scripts/**/*.js', + 'src/**/*.js', + 'test/**/*.js', + 'i18n/**/*.js', + '!docs/app/assets/js/angular-bootstrap/**', + '!docs/bower_components/**', + '!docs/config/templates/**', + '!src/angular.bind.js', + '!i18n/closure/**', + '!src/ngParseExt/ucd.js' + ] } }, @@ -318,7 +274,7 @@ module.exports = function(grunt) { compress: { build: { - options: {archive: 'build/' + dist +'.zip', mode: 'zip'}, + options: {archive: 'build/' + dist + '.zip', mode: 'zip'}, src: ['**'], cwd: 'build', expand: true, @@ -366,7 +322,7 @@ module.exports = function(grunt) { //alias tasks - grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['jshint', 'jscs', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']); + grunt.registerTask('test', 'Run unit, docs and e2e tests with Karma', ['eslint', 'package', 'test:unit', 'test:promises-aplus', 'tests:docs', 'test:protractor']); grunt.registerTask('test:jqlite', 'Run the unit tests with Karma' , ['tests:jqlite']); grunt.registerTask('test:jquery', 'Run the jQuery (latest) unit tests with Karma', ['tests:jquery']); grunt.registerTask('test:jquery-2.2', 'Run the jQuery 2.2 unit tests with Karma', ['tests:jquery-2.2']); @@ -383,6 +339,6 @@ module.exports = function(grunt) { grunt.registerTask('minify', ['bower', 'clean', 'build', 'minall']); grunt.registerTask('webserver', ['connect:devserver']); grunt.registerTask('package', ['bower', 'validate-angular-files', 'clean', 'buildall', 'minall', 'collect-errors', 'docs', 'copy', 'write', 'compress']); - grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'jshint', 'jscs']); + grunt.registerTask('ci-checks', ['ddescribe-iit', 'merge-conflict', 'eslint']); grunt.registerTask('default', ['package']); }; diff --git a/angularFiles.js b/angularFiles.js index 71edff31c567..e32d5da66d7b 100755 --- a/angularFiles.js +++ b/angularFiles.js @@ -244,10 +244,10 @@ var angularFiles = { ] }; -['2.1', '2.2'].forEach(function (jQueryVersion) { +['2.1', '2.2'].forEach(function(jQueryVersion) { angularFiles['karmaJquery' + jQueryVersion] = [] .concat(angularFiles.karmaJquery) - .map(function (path) { + .map(function(path) { if (path.startsWith('bower_components/jquery')) { return path.replace(/^bower_components\/jquery/, 'bower_components/jquery-' + jQueryVersion); } @@ -276,7 +276,7 @@ if (exports) { Array.prototype.slice.call(arguments, 0).forEach(function(filegroup) { angularFiles[filegroup].forEach(function(file) { // replace @ref - var match = file.match(/^\@(.*)/); + var match = file.match(/^@(.*)/); if (match) { files = files.concat(angularFiles[match[1]]); } else { diff --git a/benchmarks/.eslintrc.json b/benchmarks/.eslintrc.json new file mode 100644 index 000000000000..aef8fadbe927 --- /dev/null +++ b/benchmarks/.eslintrc.json @@ -0,0 +1,11 @@ +{ + "root": true, + "extends": "../.eslintrc-browser.json", + + "globals": { + "benchmarkSteps": false, + + // Benchmarks are not run in IE 9 so we're fine. + "console": false + } +} diff --git a/benchmarks/event-delegation-bp/app.js b/benchmarks/event-delegation-bp/app.js index 237193ad4d6f..45d91a03fd9b 100644 --- a/benchmarks/event-delegation-bp/app.js +++ b/benchmarks/event-delegation-bp/app.js @@ -1,3 +1,5 @@ +'use strict'; + var app = angular.module('eventDelegationBenchmark', []); app.directive('noopDir', function() { @@ -5,7 +7,7 @@ app.directive('noopDir', function() { compile: function($element, $attrs) { return function($scope, $element) { return 1; - } + }; } }; }); @@ -13,12 +15,12 @@ app.directive('noopDir', function() { app.directive('nativeClick', ['$parse', function($parse) { return { compile: function($element, $attrs) { - var expr = $parse($attrs.tstEvent); + $parse($attrs.tstEvent); return function($scope, $element) { $element[0].addEventListener('click', function() { console.log('clicked'); }, false); - } + }; } }; }]); @@ -26,13 +28,12 @@ app.directive('nativeClick', ['$parse', function($parse) { app.directive('dlgtClick', function() { return { compile: function($element, $attrs) { - var evt = $attrs.dlgtClick; // We don't setup the global event listeners as the costs are small and one time only... } }; }); -app.controller('DataController', function($rootScope) { +app.controller('DataController', function DataController($rootScope) { this.ngRepeatCount = 1000; this.rows = []; var self = this; @@ -47,8 +48,8 @@ app.controller('DataController', function($rootScope) { self.rows = oldRows; if (self.rows.length !== self.ngRepeatCount) { self.rows = []; - for (var i=0; i 0) { - (function (arg) { + (function(arg) { if (def) { - def = def.then(function () { + def = def.then(function() { return fn(arg); }); } else { def = fn(arg); } - def = def.then(function (res) { + def = def.then(function(res) { results.push(res); }); - }(args.pop())); + })(args.pop()); } - return def.then(function () { + return def.then(function() { return results; }); }; }; -var compareBranches = function (left, right) { +var compareBranches = function(left, right) { console.log('# These commits are in ' + left.name + ' but not in ' + right.name + '\n'); console.log(_(left.log). difference(right.log). - map(function (line) { + map(function(line) { return left.full[left.log.indexOf(line)]; // lol O(n^2) }). value(). @@ -85,44 +85,43 @@ var checkout = oneArg(exec('git checkout %s')); var getCurrentBranch = andThen(noArgs(exec('git rev-parse --abbrev-ref HEAD')), oneLine); var getTags = noArgs(exec('git tag')); -var getShaOfTag = oneArg(exec('git rev-list %s | head -n 1')); var getTheLog = oneArg(exec('git log --pretty=oneline %s..HEAD | cat')); // remember this so we can restore state var currentBranch; getCurrentBranch(). -then(function (branch) { +then(function(branch) { currentBranch = branch; }). then(getTags). -then(function (tags) { +then(function(tags) { return tags. filter(semver.valid). map(semver.clean). sort(semver.rcompare); }). -then(function (tags) { - var major = tags[0].split('.')[0]; +then(function(tags) { + var major = semver(tags[0]).major; return tags. - filter(function (ver) { - return semver(ver).major == major; + filter(function(ver) { + return semver(ver).major === major; }); }). -then(function (tags) { +then(function(tags) { return _(tags). - groupBy(function (tag) { + groupBy(function(tag) { return tag.split('.')[1]; }). - map(function (group) { + map(function(group) { return _.first(group); }). - map(function (tag) { + map(function(tag) { return 'v' + tag; }). value(); }). -then(function (tags) { +then(function(tags) { var master = tags.pop(); var stable = tags.pop(); @@ -131,38 +130,38 @@ then(function (tags) { { name: 'master', tag: master} ]; }). -then(allInSeries(function (branch) { +then(allInSeries(function(branch) { return checkout(branch.name). - then(function () { + then(function() { return getTheLog(branch.tag); }). - then(function (log) { + then(function(log) { return log. filter(identity); }). - then(function (log) { - branch.full = log.map(function (line) { + then(function(log) { + branch.full = log.map(function(line) { line = line.split(' '); var sha = line.shift(); var msg = line.join(' '); return sha + ((/fix\([^\)]+\):/i.test(msg)) ? ' * ' : ' ') + msg; }); - branch.log = log.map(function (line) { + branch.log = log.map(function(line) { return line.substr(41); }); return branch; }); })). -then(function (pairs) { +then(function(pairs) { compareBranches(pairs[0], pairs[1]); console.log('\n'); compareBranches(pairs[1], pairs[0]); return pairs; }). -then(function () { +then(function() { return checkout(currentBranch); }). -catch(function (e) { +catch(function(e) { console.log(e.stack); }); diff --git a/docs/app/assets/js/search-worker.js b/docs/app/assets/js/search-worker.js index 318461ade8ad..22f3b6226a01 100644 --- a/docs/app/assets/js/search-worker.js +++ b/docs/app/assets/js/search-worker.js @@ -1,17 +1,18 @@ -"use strict"; -/* jshint browser: true */ -/* global importScripts, onmessage: true, postMessage, lunr */ +'use strict'; + +/* eslint-env worker */ +/* global importScripts, lunr */ // Load up the lunr library importScripts('../components/lunr.js-0.5.12/lunr.min.js'); // Create the lunr index - the docs should be an array of object, each object containing // the path and search terms for a page -var index = lunr(function() { +var index = lunr(/* @this */function() { this.ref('path'); this.field('titleWords', {boost: 50}); - this.field('members', { boost: 40}); - this.field('keywords', { boost : 20 }); + this.field('members', {boost: 40}); + this.field('keywords', {boost: 20}); }); // Retrieve the searchData which contains the information about each page to be indexed @@ -25,13 +26,13 @@ searchDataRequest.onload = function() { searchData.forEach(function(page) { index.add(page); }); - postMessage({ e: 'index-ready' }); + postMessage({e: 'index-ready'}); }; searchDataRequest.open('GET', 'search-data.json'); searchDataRequest.send(); // The worker receives a message everytime the web app wants to query the index -onmessage = function(oEvent) { +self.onmessage = function(oEvent) { var q = oEvent.data.q; var hits = index.search(q); var results = []; @@ -40,5 +41,5 @@ onmessage = function(oEvent) { results.push(hit.ref); }); // The results of the query are sent back to the web app via a new message - postMessage({ e: 'query-ready', q: q, d: results }); -}; \ No newline at end of file + self.postMessage({e: 'query-ready', q: q, d: results}); +}; diff --git a/docs/app/e2e/.eslintrc.json b/docs/app/e2e/.eslintrc.json new file mode 100644 index 000000000000..6a949b92ffc9 --- /dev/null +++ b/docs/app/e2e/.eslintrc.json @@ -0,0 +1,28 @@ +{ + "root": true, + "extends": "../../../.eslintrc-node.json", + + + "env": { + "jasmine": true, + "protractor": true + }, + + "globals": { + /* testabilityPatch / matchers */ + "inject": false, + "module": false, + "dealoc": false, + "_jQuery": false, + "_jqLiteMode": false, + "sortedHtml": false, + "childrenTagsOf": false, + "assertHidden": false, + "assertVisible": false, + "provideLog": false, + "spyOnlyCallsWithArgs": false, + "createMockStyleSheet": false, + "browserTrigger": false, + "jqLiteCacheSize": false + } +} diff --git a/docs/app/e2e/.jshintrc b/docs/app/e2e/.jshintrc deleted file mode 100644 index 11e0f84740ec..000000000000 --- a/docs/app/e2e/.jshintrc +++ /dev/null @@ -1,45 +0,0 @@ -{ - "extends": "../../../.jshintrc-base", - - "globals": { - - /* jasmine / karma */ - "it": false, - "iit": false, - "describe": false, - "ddescribe": false, - "beforeEach": false, - "afterEach": false, - "expect": false, - "jasmine": false, - "spyOn": false, - "waits": false, - "waitsFor": false, - "runs": false, - "dump": false, - - /* e2e */ - "protractor": false, - "browser": false, - "element": false, - "by": false, - "$": false, - "$$": false, - - /* testabilityPatch / matchers */ - "inject": false, - "module": false, - "dealoc": false, - "_jQuery": false, - "_jqLiteMode": false, - "sortedHtml": false, - "childrenTagsOf": false, - "assertHidden": false, - "assertVisible": false, - "provideLog": false, - "spyOnlyCallsWithArgs": false, - "createMockStyleSheet": false, - "browserTrigger": false, - "jqLiteCacheSize": false - } -} diff --git a/docs/app/e2e/api-docs/api-pages.scenario.js b/docs/app/e2e/api-docs/api-pages.scenario.js index 5c026bfa4feb..f30e4d1cffa7 100644 --- a/docs/app/e2e/api-docs/api-pages.scenario.js +++ b/docs/app/e2e/api-docs/api-pages.scenario.js @@ -12,7 +12,7 @@ describe("doc.angularjs.org", function() { expect(element(by.css('.view-source')).getAttribute('href')).toMatch(/https?:\/\/github\.com\/angular\/angular\.js\/tree\/.+\/src\/ng\/http\.js#L\d+/); }); - it('should change the page content when clicking a link to a service', function () { + it('should change the page content when clicking a link to a service', function() { browser.get('build/docs/index.html'); var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]')); @@ -23,7 +23,7 @@ describe("doc.angularjs.org", function() { }); - it('should show the functioning input directive example', function () { + it('should show the functioning input directive example', function() { browser.get('build/docs/index.html#!/api/ng/directive/input'); // Ensure that the page is loaded before trying to switch frames. @@ -48,4 +48,4 @@ describe("doc.angularjs.org", function() { }); }); }); -}); \ No newline at end of file +}); diff --git a/docs/app/e2e/api-docs/provider-pages.scenario.js b/docs/app/e2e/api-docs/provider-pages.scenario.js index 5b9094c019e1..b83af4614d18 100644 --- a/docs/app/e2e/api-docs/provider-pages.scenario.js +++ b/docs/app/e2e/api-docs/provider-pages.scenario.js @@ -9,4 +9,4 @@ describe("provider pages", function() { expect(serviceLink.getAttribute('href')).toMatch(/api\/ng\/service\/\$compile/); }); -}); \ No newline at end of file +}); diff --git a/docs/app/e2e/app.scenario.js b/docs/app/e2e/app.scenario.js index 7dfe4b15434c..e8e675328845 100644 --- a/docs/app/e2e/app.scenario.js +++ b/docs/app/e2e/app.scenario.js @@ -2,7 +2,7 @@ var webdriver = require('protractor/node_modules/selenium-webdriver'); -describe('docs.angularjs.org', function () { +describe('docs.angularjs.org', function() { beforeEach(function() { // read and clear logs from previous tests @@ -24,7 +24,7 @@ describe('docs.angularjs.org', function () { }); - describe('App', function () { + describe('App', function() { // it('should filter the module list when searching', function () { // browser.get(); // browser.waitForAngular(); @@ -38,7 +38,7 @@ describe('docs.angularjs.org', function () { // }); - it('should change the page content when clicking a link to a service', function () { + it('should change the page content when clicking a link to a service', function() { browser.get('build/docs/index-production.html'); var ngBindLink = element(by.css('.definition-table td a[href="api/ng/directive/ngClick"]')); @@ -83,4 +83,4 @@ describe('docs.angularjs.org', function () { }); -}); \ No newline at end of file +}); diff --git a/docs/app/src/.eslintrc.json b/docs/app/src/.eslintrc.json new file mode 100644 index 000000000000..247b283233ea --- /dev/null +++ b/docs/app/src/.eslintrc.json @@ -0,0 +1,12 @@ +{ + "root": true, + "extends": "../../../.eslintrc-browser.json", + + "globals": { + // ngMocks + "module": false, + "inject": true, + + "lunr": false + } +} diff --git a/docs/app/src/app.js b/docs/app/src/app.js index 157985f05705..607cc0f0e1ec 100644 --- a/docs/app/src/app.js +++ b/docs/app/src/app.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('docsApp', [ 'ngRoute', 'ngCookies', diff --git a/docs/app/src/directives.js b/docs/app/src/directives.js index c7c14eda1e3f..229da10f3bc3 100644 --- a/docs/app/src/directives.js +++ b/docs/app/src/directives.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('directives', []) /** diff --git a/docs/app/src/docs.js b/docs/app/src/docs.js index 44524e38b771..fb6a35565e8c 100644 --- a/docs/app/src/docs.js +++ b/docs/app/src/docs.js @@ -1,3 +1,5 @@ +'use strict'; + angular.module('DocsController', []) .controller('DocsController', [ @@ -27,9 +29,9 @@ angular.module('DocsController', []) path = path.replace(/^\/?(.+?)(\/index)?\/?$/, '$1'); - currentPage = $scope.currentPage = NG_PAGES[path]; + var currentPage = $scope.currentPage = NG_PAGES[path]; - if ( currentPage ) { + if (currentPage) { $scope.partialPath = 'partials/' + path + '.html'; $scope.currentArea = NG_NAVIGATION[currentPage.area]; var pathParts = currentPage.path.split('/'); @@ -37,7 +39,7 @@ angular.module('DocsController', []) var breadcrumbPath = ''; angular.forEach(pathParts, function(part) { breadcrumbPath += part; - breadcrumb.push({ name: (NG_PAGES[breadcrumbPath]&&NG_PAGES[breadcrumbPath].name) || part, url: breadcrumbPath }); + breadcrumb.push({ name: (NG_PAGES[breadcrumbPath] && NG_PAGES[breadcrumbPath].name) || part, url: breadcrumbPath }); breadcrumbPath += '/'; }); } else { diff --git a/docs/app/src/errors.js b/docs/app/src/errors.js index 79f508ec3447..2d9f8b5d91e1 100644 --- a/docs/app/src/errors.js +++ b/docs/app/src/errors.js @@ -1,23 +1,25 @@ +'use strict'; + angular.module('errors', ['ngSanitize']) -.filter('errorLink', ['$sanitize', function ($sanitize) { - var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.\;\,\(\)\{\}<>]/g, +.filter('errorLink', ['$sanitize', function($sanitize) { + var LINKY_URL_REGEXP = /((ftp|https?):\/\/|(mailto:)?[A-Za-z0-9._%+-]+@)\S*[^\s\.;,\(\)\{\}<>]/g, MAILTO_REGEXP = /^mailto:/, STACK_TRACE_REGEXP = /:\d+:\d+$/; - var truncate = function (text, nchars) { + var truncate = function(text, nchars) { if (text.length > nchars) { return text.substr(0, nchars - 3) + '...'; } return text; }; - return function (text, target) { + return function(text, target) { if (!text) return text; var targetHtml = target ? ' target="' + target + '"' : ''; - return $sanitize(text.replace(LINKY_URL_REGEXP, function (url) { + return $sanitize(text.replace(LINKY_URL_REGEXP, function(url) { if (STACK_TRACE_REGEXP.test(url)) { return url; } @@ -25,7 +27,7 @@ angular.module('errors', ['ngSanitize']) // if we did not match ftp/http/mailto then assume mailto if (!/^((ftp|https?):\/\/|mailto:)/.test(url)) url = 'mailto:' + url; - return '' + + return '' + truncate(url.replace(MAILTO_REGEXP, ''), 60) + ''; })); @@ -33,33 +35,33 @@ angular.module('errors', ['ngSanitize']) }]) -.directive('errorDisplay', ['$location', 'errorLinkFilter', function ($location, errorLinkFilter) { - var encodeAngleBrackets = function (text) { +.directive('errorDisplay', ['$location', 'errorLinkFilter', function($location, errorLinkFilter) { + var encodeAngleBrackets = function(text) { return text.replace(//g, '>'); }; - var interpolate = function (formatString) { + var interpolate = function(formatString) { var formatArgs = arguments; - return formatString.replace(/\{\d+\}/g, function (match) { + return formatString.replace(/\{\d+\}/g, function(match) { // Drop the braces and use the unary plus to convert to an integer. // The index will be off by one because of the formatString. var index = +match.slice(1, -1); if (index + 1 >= formatArgs.length) { return match; } - return formatArgs[index+1]; + return formatArgs[index + 1]; }); }; return { - link: function (scope, element, attrs) { + link: function(scope, element, attrs) { var search = $location.search(), formatArgs = [attrs.errorDisplay], formattedText, i; - for (i = 0; angular.isDefined(search['p'+i]); i++) { - formatArgs.push(search['p'+i]); + for (i = 0; angular.isDefined(search['p' + i]); i++) { + formatArgs.push(search['p' + i]); } formattedText = encodeAngleBrackets(interpolate.apply(null, formatArgs)); diff --git a/docs/app/src/examples.js b/docs/app/src/examples.js index eaafd82f93b2..b6e8d5760256 100644 --- a/docs/app/src/examples.js +++ b/docs/app/src/examples.js @@ -1,8 +1,9 @@ +'use strict'; + angular.module('examples', []) -.directive('runnableExample', ['$templateCache', '$document', function($templateCache, $document) { +.directive('runnableExample', [function() { var exampleClassNameSelector = '.runnable-example-file'; - var doc = $document[0]; var tpl = '