jenkins-bot has submitted this change and it was merged.

Change subject: Replace jshint, jscs, jsbeautify by eslint
......................................................................


Replace jshint, jscs, jsbeautify by eslint

Bug: T151741
Change-Id: Id821b8cebc4d0b43d50aaa0ec46bab9f9538b0d4
---
A .eslintrc.json
D .jsbeautifyrc
D .jscs.json
D .jscsrc
D .jshintignore
D .jshintrc
A .stylelintrc
M Gruntfile.js
M modules/dashboard/ext.cx.recommendtool.client.js
M modules/dashboard/ext.cx.suggestionlist.js
M modules/dashboard/ext.cx.translationlist.js
M modules/editor/ext.cx.editor.js
M modules/entrypoint/ext.cx.contributions.js
M modules/entrypoint/ext.cx.entrypoint.js
M modules/eventlogging/ext.cx.eventlogging.js
M modules/publish/ext.cx.publish.dialog.js
M modules/publish/ext.cx.publish.js
M modules/publish/ext.cx.wikibase.link.js
M modules/source/ext.cx.source.js
M modules/source/ext.cx.source.selector.js
M modules/stats/ext.cx.stats.js
M modules/tools/ext.cx.tools.categories.js
M modules/tools/ext.cx.tools.dictionary.js
M modules/tools/ext.cx.tools.formatter.js
M modules/tools/ext.cx.tools.js
M modules/tools/ext.cx.tools.link.js
M modules/tools/ext.cx.tools.linter.js
M modules/tools/ext.cx.tools.manager.js
M modules/tools/ext.cx.tools.mt.card.js
M modules/tools/ext.cx.tools.mt.js
M modules/tools/ext.cx.tools.reference.js
M modules/translation/ext.cx.translation.aligner.js
M modules/translation/ext.cx.translation.js
M modules/translation/ext.cx.translation.loader.js
M modules/translation/ext.cx.translation.progress.js
M modules/translation/ext.cx.translation.storage.js
M modules/util/ext.cx.util.js
M modules/util/ext.cx.util.selection.js
M modules/widgets/callout/ext.cx.callout.js
M modules/widgets/feedback/ext.cx.feedback.js
M modules/widgets/overlay/ext.cx.overlay.js
M modules/widgets/progressbar/ext.cx.progressbar.js
M modules/widgets/translator/ext.cx.translator.js
M package.json
M tests/qunit/tools/ext.cx.tools.mtabuse.test.js
M tests/qunit/translation/ext.cx.translation.loader.test.js
46 files changed, 487 insertions(+), 420 deletions(-)

Approvals:
  Santhosh: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..ecc2e04
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,18 @@
+{
+       "extends": "wikimedia",
+       "env": {
+               "browser": true,
+               "jquery": true,
+               "qunit": true
+       },
+       "globals": {
+               "mediaWiki": false,
+               "moment": false,
+               "EasyDeflate": false,
+               "OO": false
+       },
+       "rules": {
+               "dot-notation": 0,
+               "wrap-iife": 0
+       }
+}
diff --git a/.jsbeautifyrc b/.jsbeautifyrc
deleted file mode 100644
index cfa5b27..0000000
--- a/.jsbeautifyrc
+++ /dev/null
@@ -1,17 +0,0 @@
-{
-    "preserve_newlines": true,
-    "jslint_happy": true,
-    "keep_array_indentation": true,
-    "space_before_conditional": true,
-    "max_preserve_newlines": 10,
-    "brace_style": "collapse",
-    "keep_function_indentation": false,
-    "break_chained_methods": false,
-    "eval_code": false,
-    "unescape_strings": false,
-    "wrap_line_length": 0,
-    "space_in_paren": true,
-    "git_happy": true,
-    "indent_with_tabs": true,
-    "end_with_newline": true
-}
diff --git a/.jscs.json b/.jscs.json
deleted file mode 100644
index 9d22e3f..0000000
--- a/.jscs.json
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-       "preset": "wikimedia"
-}
diff --git a/.jscsrc b/.jscsrc
deleted file mode 100644
index 9d22e3f..0000000
--- a/.jscsrc
+++ /dev/null
@@ -1,3 +0,0 @@
-{
-       "preset": "wikimedia"
-}
diff --git a/.jshintignore b/.jshintignore
deleted file mode 100644
index 18be9f9..0000000
--- a/.jshintignore
+++ /dev/null
@@ -1,2 +0,0 @@
-# upstream libs
-lib/*
diff --git a/.jshintrc b/.jshintrc
deleted file mode 100644
index dc06253..0000000
--- a/.jshintrc
+++ /dev/null
@@ -1,22 +0,0 @@
-{
-       "bitwise": true,
-       "curly": true,
-       "eqeqeq": true,
-       "forin": false,
-       "freeze": true,
-       "latedef": true,
-       "noarg": true,
-       "nonew": true,
-       "strict": true,
-       "undef": true,
-       "unused": true,
-       "browser": true,
-       "predef": [
-               "EasyDeflate",
-               "mediaWiki",
-               "jQuery",
-               "QUnit",
-               "moment",
-               "OO"
-       ]
-}
diff --git a/.stylelintrc b/.stylelintrc
new file mode 100644
index 0000000..905b08c
--- /dev/null
+++ b/.stylelintrc
@@ -0,0 +1,12 @@
+{
+       "extends": "stylelint-config-wikimedia",
+       "rules": {
+               "no-browser-hacks": [ true, {
+                       "browsers": [ "Chrome >= 1", "Firefox >= 12", "Explorer 
>= 9", "Edge >= 12", "iOS >= 7", "Opera >= 12", "Safari >= 7", "ExplorerMobile 
>= 10", "Android >= 4", "not BlackBerry >= 1", "ChromeAndroid >= 1", 
"FirefoxAndroid >= 1", "OperaMobile >= 12", "not OperaMini >= 1" ]
+               } ],
+
+               "no-unsupported-browser-features": [ true, {
+                       "browsers": [ "Chrome >= 1", "Firefox >= 12", "Explorer 
>= 9", "Edge >= 12", "iOS >= 7", "Opera >= 12", "Safari >= 7", "ExplorerMobile 
>= 10", "Android >= 4", "not BlackBerry >= 1", "ChromeAndroid >= 1", 
"FirefoxAndroid >= 1", "OperaMobile >= 12", "not OperaMini >= 1" ]
+               } ]
+       }
+}
diff --git a/Gruntfile.js b/Gruntfile.js
index e46e25b..8c983ef 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -1,25 +1,38 @@
-/*jshint node:true */
+/* eslint-env node */
 module.exports = function ( grunt ) {
        'use strict';
+
        var conf = grunt.file.readJSON( 'extension.json' );
-       grunt.loadNpmTasks( 'grunt-contrib-jshint' );
+       grunt.loadNpmTasks( 'grunt-eslint' );
        grunt.loadNpmTasks( 'grunt-jsonlint' );
        grunt.loadNpmTasks( 'grunt-banana-checker' );
-       grunt.loadNpmTasks( 'grunt-jscs' );
+       grunt.loadNpmTasks( 'grunt-stylelint' );
 
        grunt.initConfig( {
-               jshint: {
-                       options: {
-                               jshintrc: true
+               eslint: {
+                       fix: {
+                               options: {
+                                       fix: true
+                               },
+                               src: '<%= eslint.main %>'
                        },
-                       all: [
+                       main: [
                                '**/*.js',
                                '!lib/**',
                                '!node_modules/**'
                        ]
                },
-               jscs: {
-                       src: '<%= jshint.all %>'
+               stylelint: {
+                       options: {
+                               syntax: 'less'
+                       },
+                       src: [
+                               '**/*.css',
+                               '**/*.less',
+                               '!lib/**',
+                               '!node_modules/**',
+                               '!vendor/**'
+                       ]
                },
                banana: conf.MessagesDirs,
                jsonlint: {
@@ -30,6 +43,7 @@
                }
        } );
 
-       grunt.registerTask( 'test', [ 'jshint', 'jscs', 'jsonlint', 'banana' ] 
);
+       grunt.registerTask( 'test', [ 'eslint:main', 'jsonlint', 'banana' ] );
+       grunt.registerTask( 'lint', [ 'eslint:main', 'jsonlint', 'stylelint', 
'banana' ] );
        grunt.registerTask( 'default', 'test' );
 };
diff --git a/modules/dashboard/ext.cx.recommendtool.client.js 
b/modules/dashboard/ext.cx.recommendtool.client.js
index e0fe815..ad73ddd 100644
--- a/modules/dashboard/ext.cx.recommendtool.client.js
+++ b/modules/dashboard/ext.cx.recommendtool.client.js
@@ -16,6 +16,8 @@
         * RecommendTool
         *
         * @class
+        * @param {string} from Source language
+        * @param {string} to target language
         */
        function RecommendTool( from, to ) {
                this.sourceLanguage = from;
@@ -121,5 +123,5 @@
                };
        };
 
-       mw.cx.recommendtool = RecommendTool;
+       mw.cx.Recommendtool = RecommendTool;
 }( jQuery, mediaWiki ) );
diff --git a/modules/dashboard/ext.cx.suggestionlist.js 
b/modules/dashboard/ext.cx.suggestionlist.js
index 829ef5b..d8efdb1 100644
--- a/modules/dashboard/ext.cx.suggestionlist.js
+++ b/modules/dashboard/ext.cx.suggestionlist.js
@@ -207,7 +207,7 @@
                        api = new mw.Api();
 
                if ( list.id === 'trex' ) {
-                       this.recommendtool = this.recommendtool || new 
mw.cx.recommendtool(
+                       this.recommendtool = this.recommendtool || new 
mw.cx.Recommendtool(
                                this.filters.sourceLanguage,
                                this.filters.targetLanguage
                        );
@@ -360,6 +360,10 @@
                } );
        };
 
+       function listCompare( listA, listB ) {
+               return listOrder[ listA.type ] > listOrder[ listB.type ];
+       }
+
        /**
         * List all suggestions.
         *
@@ -424,6 +428,7 @@
        /**
         * Build the DOM for suggestion item
         *
+        * @param {Object} suggestion
         * @return {jQuery}
         */
        CXSuggestionList.prototype.buildSuggestionItem = function ( suggestion 
) {
@@ -792,10 +797,6 @@
        CXSuggestionList.prototype.sortLists = function ( lists ) {
                return Object.keys( lists ).sort( listCompare );
        };
-
-       function listCompare( listA, listB ) {
-               return listOrder[ listA.type ] > listOrder[ listB.type ];
-       }
 
        /**
         * Make the list expandable and collapsable.
diff --git a/modules/dashboard/ext.cx.translationlist.js 
b/modules/dashboard/ext.cx.translationlist.js
index 95881f6..a1868c1 100644
--- a/modules/dashboard/ext.cx.translationlist.js
+++ b/modules/dashboard/ext.cx.translationlist.js
@@ -12,6 +12,9 @@
         * CXTranslationList
         *
         * @class
+        * @param {jQuery} $container
+        * @param {string} type
+        * @param {Object} siteMapper
         */
        function CXTranslationList( $container, type, siteMapper ) {
                this.$container = $container;
@@ -206,7 +209,7 @@
         */
        CXTranslationList.prototype.continueTranslation = function ( 
translation ) {
                if ( translation.status === 'deleted' ) {
-                       return false;
+                       return;
                }
 
                // Set CX token as cookie.
@@ -225,13 +228,15 @@
 
        /**
         * List all translations.
+        *
+        * @param {Object[]} translations
         */
        CXTranslationList.prototype.renderTranslations = function ( 
translations ) {
                var i, translation, progress, $translation,
                        $lastUpdated, $image, $progressbar,
                        sourceDir, targetDir, $targetTitle,
                        $translationLink,
-                       $sourceLanguage, $targetLanguage, $languageContainer, 
$status,
+                       $sourceLanguage, $targetLanguage, $languageContainer,
                        $actionsTrigger, $deleteTranslation, $menu, 
$menuContainer,
                        $continueTranslation,
                        $titleLanguageBlock,
@@ -311,10 +316,6 @@
                        $languageContainer = $( '<div>' )
                                .addClass( 'cx-tlitem__languages' )
                                .append( $sourceLanguage, $targetLanguage );
-
-                       $status = $( '<div>' )
-                               .addClass( 'status status-' + 
translation.status )
-                               .text( mw.msg( 'cx-translation-status-' + 
translation.status ) );
 
                        $actionsTrigger = $( '<div>' )
                                .addClass( 'cx-tlitem__actions__trigger' );
@@ -459,7 +460,7 @@
 
                deferred = $.Deferred();
 
-               overlay = new mw.cx.widgets.overlay();
+               overlay = new mw.cx.widgets.Overlay();
 
                if ( this.$confirmationDialog ) {
                        $cancelButton = this.$confirmationDialog.find( 
'.cx-draft-discard-dialog__cancel' );
diff --git a/modules/editor/ext.cx.editor.js b/modules/editor/ext.cx.editor.js
index bf1d086..a0513f8 100644
--- a/modules/editor/ext.cx.editor.js
+++ b/modules/editor/ext.cx.editor.js
@@ -13,6 +13,7 @@
        /**
         * CXSectionEditor - Editor for each sections in the translation
         *
+        * @param {Element} element
         * @class
         */
        function CXSectionEditor( element ) {
@@ -50,6 +51,8 @@
 
        /**
         * Paste handler. Adapts pasted text.
+        * @param {jQuery.Event} e
+        * @return {boolean}
         */
        CXSectionEditor.prototype.pasteHandler = function ( e ) {
                // Enforce plain text pasting
@@ -62,6 +65,8 @@
 
        /**
         * Drop handler. Adapts pasted text.
+        * @param {jQuery.Event} e
+        * @return {boolean}
         */
        CXSectionEditor.prototype.dropHandler = function ( e ) {
                var text = e.originalEvent.dataTransfer.getData( 'text' ) ||
@@ -112,6 +117,7 @@
         * The CXSectionEditor plugin.
         * Sets common properties on all editable elements
         * in the translation column.
+        * @return {jQuery}
         */
        $.fn.cxEditor = function () {
                return this.each( function () {
diff --git a/modules/entrypoint/ext.cx.contributions.js 
b/modules/entrypoint/ext.cx.contributions.js
index 7092d9d..71224c7 100644
--- a/modules/entrypoint/ext.cx.contributions.js
+++ b/modules/entrypoint/ext.cx.contributions.js
@@ -11,6 +11,7 @@
 
        /**
         * @class
+        * @param {Element} element
         */
        function CXContributions( element ) {
                this.$element = $( element );
@@ -61,19 +62,19 @@
                return [
                        {
                                text: mw.msg( 'cx-contributions-new-article' ),
-                               class: 'cx-contributions-new-article',
+                               'class': 'cx-contributions-new-article',
                                url: mw.util.getUrl( 'Special:WantedPages' ),
                                tooltip: mw.msg( 
'cx-contributions-new-article-tooltip' )
                        },
                        {
                                text: mw.msg( 'cx-contributions-upload' ),
-                               class: 'cx-contributions-upload',
+                               'class': 'cx-contributions-upload',
                                url: 
'https://commons.wikimedia.org/wiki/Special:UploadWizard',
                                tooltip: mw.msg( 
'cx-contributions-upload-tooltip' )
                        },
                        {
                                text: mw.msg( 'cx-contributions-translation' ),
-                               class: 'cx-contributions-translation ' + ( 
isNewToCX() ? 'cx-contributions-new' : '' ),
+                               'class': 'cx-contributions-translation ' + ( 
isNewToCX() ? 'cx-contributions-new' : '' ),
                                url: mw.util.getUrl( 
'Special:ContentTranslation', {
                                        campaign: entrypointName
                                } ),
@@ -84,6 +85,8 @@
 
        /**
         * CXContributions entry point plugin
+        * @param {Object} options
+        * @return {jQuery}
         */
        $.fn.cxContributions = function ( options ) {
                return this.each( function () {
diff --git a/modules/entrypoint/ext.cx.entrypoint.js 
b/modules/entrypoint/ext.cx.entrypoint.js
index 19516cd..c41031c 100644
--- a/modules/entrypoint/ext.cx.entrypoint.js
+++ b/modules/entrypoint/ext.cx.entrypoint.js
@@ -12,6 +12,8 @@
 
        /**
         * @class
+        * @param {jQuery} $trigger
+        * @param {Object} options
         */
        function CXEntryPoint( $trigger, options ) {
                this.$trigger = $( $trigger );
@@ -180,6 +182,8 @@
 
        /**
         * CXEntryPoint plugin
+        * @param {Object} options
+        * @return {jQuery}
         */
        $.fn.cxEntryPoint = function ( options ) {
                return this.each( function () {
diff --git a/modules/eventlogging/ext.cx.eventlogging.js 
b/modules/eventlogging/ext.cx.eventlogging.js
index 4f827d3..9df5708 100644
--- a/modules/eventlogging/ext.cx.eventlogging.js
+++ b/modules/eventlogging/ext.cx.eventlogging.js
@@ -244,7 +244,7 @@
        };
 
        $( function () {
-               /*jshint -W031*/
+               /* eslint no-new:off */
                new ContentTranslationEventLogging();
        } );
 }( jQuery, mediaWiki ) );
diff --git a/modules/publish/ext.cx.publish.dialog.js 
b/modules/publish/ext.cx.publish.dialog.js
index ad505dd..3d28ec4 100644
--- a/modules/publish/ext.cx.publish.dialog.js
+++ b/modules/publish/ext.cx.publish.dialog.js
@@ -14,6 +14,7 @@
         * Handles show the publishing options dialog.
         *
         * @class
+        * @param {Element} trigger
         */
        function CXPublishingDialog( trigger ) {
                this.$trigger = $( trigger );
@@ -42,9 +43,8 @@
         * @param {string} title The title of the existing article
         */
        CXPublishingDialog.prototype.render = function ( title ) {
-               var $buttons, username, namespace;
+               var $buttons, namespace;
 
-               username = mw.user.getName();
                namespace = mw.config.get( 
'wgContentTranslationTargetNamespace' );
 
                this.$dialog = $( '<div>' )
@@ -156,6 +156,7 @@
 
        /**
         * CXPublishingDialog Plugin
+        * @return {jQuery}
         */
        $.fn.cxPublishingDialog = function () {
                return this.each( function () {
diff --git a/modules/publish/ext.cx.publish.js 
b/modules/publish/ext.cx.publish.js
index 07c63cc..7eda0ff 100644
--- a/modules/publish/ext.cx.publish.js
+++ b/modules/publish/ext.cx.publish.js
@@ -12,6 +12,8 @@
         * Handles the actual submission to the MediaWiki via the API, 
including captchas.
         *
         * @class
+        * @param {Element} trigger
+        * @param {Object} siteMapper
         */
        function CXPublish( trigger, siteMapper ) {
                this.trigger = trigger;
@@ -125,6 +127,25 @@
        };
 
        /**
+        * Increase the version number of a title starting with 1.
+        *
+        * @param {string} title The title to increase the version on.
+        * @return {string}
+        */
+       function increaseVersion( title ) {
+               var match, version;
+
+               match = title.match( /^.*\((\d+)\)$/ );
+               if ( match ) {
+                       version = parseInt( match[ 1 ], 10 ) + 1;
+
+                       return title.replace( /\(\d+\)$/, '(' + version + ')' );
+               }
+
+               return title + ' (1)';
+       }
+
+       /**
         * Generate an alternate title in case of title collision.
         *
         * @param {string} title The title
@@ -174,25 +195,6 @@
                        } );
                } );
        };
-
-       /**
-        * Increase the version number of a title starting with 1.
-        *
-        * @param {string} title The title to increase the version on.
-        * @return {string}
-        */
-       function increaseVersion( title ) {
-               var match, version;
-
-               match = title.match( /^.*\((\d+)\)$/ );
-               if ( match ) {
-                       version = parseInt( match[ 1 ], 10 ) + 1;
-
-                       return title.replace( /\(\d+\)$/, '(' + version + ')' );
-               }
-
-               return title + ' (1)';
-       }
 
        /**
         * Get categories for the current translation pair.
@@ -312,7 +314,7 @@
 
        /**
         * Prepare the translated content for publishing by removing unwanted 
parts.
-        *
+        * @param {jQuery} $content
         * @return {string} processed html
         */
        CXPublish.prototype.prepareTranslationForPublish = function ( $content 
) {
diff --git a/modules/publish/ext.cx.wikibase.link.js 
b/modules/publish/ext.cx.wikibase.link.js
index 02af16c..a2b6117 100644
--- a/modules/publish/ext.cx.wikibase.link.js
+++ b/modules/publish/ext.cx.wikibase.link.js
@@ -11,6 +11,10 @@
 
        /**
         * Link the source and target articles in the Wikibase repo
+        * @param {string} sourceLanguage
+        * @param {string} targetLanguage
+        * @param {string} sourceTitle
+        * @param {string} targetTitle
         */
        var addWikibaseLink = function ( sourceLanguage, targetLanguage, 
sourceTitle, targetTitle ) {
                var title, sourceApi;
diff --git a/modules/source/ext.cx.source.js b/modules/source/ext.cx.source.js
index 4c0fa28..0568e62 100644
--- a/modules/source/ext.cx.source.js
+++ b/modules/source/ext.cx.source.js
@@ -13,6 +13,9 @@
        /**
         * ContentTranslationSource
         *
+        * @param {Element} element
+        * @param {Object} siteMapper
+        * @param {Object} options
         * @class
         */
        function ContentTranslationSource( element, siteMapper, options ) {
@@ -172,6 +175,16 @@
                this.showLoadingIndicator();
        };
 
+       /**
+        * Remove the leading ./ added by parsoid.
+        *
+        * @param {string} href Link target
+        * @return {string} Cleaned up href
+        */
+       function cleanupLinkHref( href ) {
+               return href && href.replace( /^\.*\//, '' );
+       }
+
        ContentTranslationSource.prototype.load = function ( content ) {
                var self = this;
 
@@ -200,16 +213,6 @@
                        mw.hook( 'mw.cx.source.ready' ).fire();
                } );
        };
-
-       /**
-        * Remove the leading ./ added by parsoid.
-        *
-        * @param {string} href Link target
-        * @return {string} Cleaned up href
-        */
-       function cleanupLinkHref( href ) {
-               return href && href.replace( /^\.*\//, '' );
-       }
 
        ContentTranslationSource.prototype.showLoadingIndicator = function () {
                var $loadingIndicator,
diff --git a/modules/source/ext.cx.source.selector.js 
b/modules/source/ext.cx.source.selector.js
index f84da9d..6ab2047 100644
--- a/modules/source/ext.cx.source.selector.js
+++ b/modules/source/ext.cx.source.selector.js
@@ -14,9 +14,12 @@
         * CXSourceSelector
         *
         * @class
+        * @param {Element} trigger
+        * @param {Object} siteMapper
+        * @param {Object} options
         */
-       function CXSourceSelector( $trigger, siteMapper, options ) {
-               this.$trigger = $( $trigger );
+       function CXSourceSelector( trigger, siteMapper, options ) {
+               this.$trigger = $( trigger );
                this.options = $.extend( {}, options );
                this.siteMapper = siteMapper;
 
@@ -55,7 +58,7 @@
         * Return the appropriate menuWidth parameter for a given language 
count.
         *
         * @param {number} languagesCount Number of languages
-        * return {string} wide, medium or narrow
+        * @return {string} wide, medium or narrow
         */
        function getUlsMenuWidth( languagesCount ) {
                if ( languagesCount <= 12 ) {
@@ -348,6 +351,8 @@
 
        /**
         * Handles Enter (Return) keypress.
+        *
+        * @param {jQuery.Event} e
         */
        CXSourceSelector.prototype.enterKeyHandler = function ( e ) {
                if ( e.which === 13 ) {
@@ -577,7 +582,7 @@
                } );
 
                if ( !this.overlay ) {
-                       this.overlay = new mw.cx.widgets.overlay();
+                       this.overlay = new mw.cx.widgets.Overlay();
                }
 
                this.overlay.show();
@@ -858,6 +863,8 @@
 
        /**
         * CXEntryPoint Plugin
+        * @param {Object} options
+        * @return {jQuery}
         */
        $.fn.cxSourceSelector = function ( options ) {
                return this.each( function () {
diff --git a/modules/stats/ext.cx.stats.js b/modules/stats/ext.cx.stats.js
index 32d9869..5e470b9 100644
--- a/modules/stats/ext.cx.stats.js
+++ b/modules/stats/ext.cx.stats.js
@@ -361,6 +361,40 @@
                }
        };
 
+       /**
+        * Sorts in descending order
+        * @param {number} a
+        * @param {number} b
+        * @return {number}
+        */
+       function sortByCount( a, b ) {
+               if ( parseInt( a.count ) > parseInt( b.count ) ) {
+                       return -1;
+               }
+               if ( parseInt( a.count ) < parseInt( b.count ) ) {
+                       return 1;
+               }
+               // a must be equal to b
+               return 0;
+       }
+
+       /**
+        * Sorts in descending order
+        * @param {number} a
+        * @param {number} b
+        * @return {number}
+        */
+       function sortByTranslators( a, b ) {
+               if ( parseInt( a.translators ) > parseInt( b.translators ) ) {
+                       return -1;
+               }
+               if ( parseInt( a.translators ) < parseInt( b.translators ) ) {
+                       return 1;
+               }
+               // a must be equal to b
+               return 0;
+       }
+
        CXStats.prototype.drawTranslationsChart = function ( direction, status, 
property ) {
                var $chart, $bar, translations, $translations, model, i, j, 
$rows = [],
                        $callout,
@@ -506,6 +540,7 @@
 
        /**
         * Get the Content Translation stats.
+        * @return {jQuery.Promise}
         */
        CXStats.prototype.getCXStats = function () {
                var api = new mw.Api();
@@ -534,7 +569,7 @@
        };
 
        CXStats.prototype.drawCumulativeGraph = function ( type ) {
-               var data, cxCumulativeGraph, ctx;
+               var data, ctx;
 
                ctx = this.$cumulativeGraph[ 0 ].getContext( '2d' );
 
@@ -571,16 +606,16 @@
                };
 
                /* global Chart:false */
-               cxCumulativeGraph = new Chart( ctx, {
+               /* eslint no-new:off */
+               new Chart( ctx, {
                        type: 'line',
                        data: data,
                        options: {}
                } );
-
        };
 
        CXStats.prototype.drawLanguageCumulativeGraph = function ( type ) {
-               var data, cxCumulativeGraph, ctx;
+               var data, ctx;
 
                ctx = this.$languageCumulativeGraph[ 0 ].getContext( '2d' );
 
@@ -629,16 +664,15 @@
                };
 
                /* global Chart:false */
-               cxCumulativeGraph = new Chart( ctx, {
+               new Chart( ctx, {
                        type: 'line',
                        data: data,
                        options: {}
                } );
-
        };
 
        CXStats.prototype.drawTranslationTrend = function () {
-               var data, cxTrendChart, ctx, type = 'delta';
+               var data, ctx, type = 'delta';
 
                ctx = this.$translatonTrendBarChart[ 0 ].getContext( '2d' );
                data = {
@@ -668,16 +702,15 @@
                };
 
                /* global Chart:false */
-               cxTrendChart = new Chart( ctx, {
+               new Chart( ctx, {
                        type: 'bar',
                        data: data,
                        options: {}
                } );
-
        };
 
        CXStats.prototype.drawLangTranslationTrend = function () {
-               var ctx, data, cxTrendChart,
+               var ctx, data,
                        type = 'delta';
 
                ctx = this.$langTranslatonTrendBarChart[ 0 ].getContext( '2d' );
@@ -717,7 +750,7 @@
                };
 
                /* global Chart:false */
-               cxTrendChart = new Chart( ctx, {
+               new Chart( ctx, {
                        type: 'bar',
                        data: data,
                        options: {}
@@ -781,34 +814,6 @@
                        }
                }
        };
-
-       /**
-        * Sorts in descending order
-        */
-       function sortByTranslators( a, b ) {
-               if ( parseInt( a.translators ) > parseInt( b.translators ) ) {
-                       return -1;
-               }
-               if ( parseInt( a.translators ) < parseInt( b.translators ) ) {
-                       return 1;
-               }
-               // a must be equal to b
-               return 0;
-       }
-
-       /**
-        * Sorts in descending order
-        */
-       function sortByCount( a, b ) {
-               if ( parseInt( a.count ) > parseInt( b.count ) ) {
-                       return -1;
-               }
-               if ( parseInt( a.count ) < parseInt( b.count ) ) {
-                       return 1;
-               }
-               // a must be equal to b
-               return 0;
-       }
 
        $( function () {
                var cxLink, cxstats, header, $header, $container;
diff --git a/modules/tools/ext.cx.tools.categories.js 
b/modules/tools/ext.cx.tools.categories.js
index 7258b14..95abc0c 100644
--- a/modules/tools/ext.cx.tools.categories.js
+++ b/modules/tools/ext.cx.tools.categories.js
@@ -40,6 +40,8 @@
         * an incorrect result when RTL is involved:
         * e.g. margin-left will not be flipped correctly if
         * the target language is French, but the UI language is Hebrew.
+        *
+        * @return {string}
         */
        function getCategorySpacer() {
                return $( '<span>' ).addClass( 'cx-category__spacer' );
@@ -207,7 +209,6 @@
        function sourceClickHandler( e ) {
                var $listItem, categoryId, categoryTool, title, count;
 
-               /*jshint validthis:true */
                $listItem = $( this );
                categoryId = $listItem.attr( 'cx-category-id' );
                categoryTool = e.data.tool;
@@ -242,7 +243,6 @@
        function targetClickHandler( e ) {
                var $remove, $listItem, categoryId, categoryTool, count;
 
-               /*jshint validthis:true */
                $remove = $( this );
                $listItem = $remove.parent();
                categoryId = $listItem.attr( 'cx-category-id' );
@@ -271,7 +271,6 @@
         * Highlights the category and connected category list items.
         */
        function highlightCategory() {
-               /*jshint validthis:true */
                var categoryId,
                        $category = $( this );
 
@@ -289,7 +288,6 @@
         * Remove the highlight on the category and connected category list 
items.
         */
        function removeCategoryHighlight() {
-               /*jshint validthis:true */
                var categoryId,
                        $category = $( this );
 
diff --git a/modules/tools/ext.cx.tools.dictionary.js 
b/modules/tools/ext.cx.tools.dictionary.js
index 7f5ac36..060ce65 100644
--- a/modules/tools/ext.cx.tools.dictionary.js
+++ b/modules/tools/ext.cx.tools.dictionary.js
@@ -19,6 +19,7 @@
         * converting explicit line endings to <br /> elements
         *
         * @param {string} text
+        * @return {jQuery}
         */
        $.fn.multiline = function ( text ) {
                this.text( text );
diff --git a/modules/tools/ext.cx.tools.formatter.js 
b/modules/tools/ext.cx.tools.formatter.js
index f43f4b6..816e0b2 100644
--- a/modules/tools/ext.cx.tools.formatter.js
+++ b/modules/tools/ext.cx.tools.formatter.js
@@ -155,6 +155,8 @@
 
        /**
         * Shortcut key press handler
+        * @param {jQuery.Event} e
+        * @return {boolean}
         */
        FormatTool.prototype.shortCutHandler = function ( e ) {
                if ( e.ctrlKey && e.which === 66 ) {
diff --git a/modules/tools/ext.cx.tools.js b/modules/tools/ext.cx.tools.js
index ad1c030..369796a 100644
--- a/modules/tools/ext.cx.tools.js
+++ b/modules/tools/ext.cx.tools.js
@@ -14,6 +14,7 @@
         * ContentTranslationTools
         *
         * @class
+        * @param {Element} element
         */
        function ContentTranslationTools( element ) {
                this.$container = $( element );
diff --git a/modules/tools/ext.cx.tools.link.js 
b/modules/tools/ext.cx.tools.link.js
index e4d36e8..4dff768 100644
--- a/modules/tools/ext.cx.tools.link.js
+++ b/modules/tools/ext.cx.tools.link.js
@@ -293,7 +293,21 @@
        };
 
        /**
+        * Target link class - A link in translation section
+        *
+        * @param {Element} [link]
+        * @param {Object} [options]
+        */
+       function CXTargetLink( link, options ) {
+               CXLink.call( this, link, options );
+               this.language = mw.cx.targetLanguage;
+               this.init();
+       }
+
+       /**
         * Convert a current selection if present, if editable to a link
+        *
+        * @return {string}
         */
        CXLink.prototype.createLinkFromLink = function () {
                var $link, selection;
@@ -606,18 +620,6 @@
                        return false;
                } );
        };
-
-       /**
-        * Target link class - A link in translation section
-        *
-        * @param {Element} [link]
-        * @param {Object} [options]
-        */
-       function CXTargetLink( link, options ) {
-               CXLink.call( this, link, options );
-               this.language = mw.cx.targetLanguage;
-               this.init();
-       }
 
        // CXTargetLink inherits CXLink
        CXTargetLink.prototype = new CXLink();
@@ -1040,9 +1042,9 @@
                                $link = this.$link;
                                // Change the link target
                                $link.prop( {
-                                               href: target.title,
-                                               title: target.title
-                                       } )
+                                       href: target.title,
+                                       title: target.title
+                               } )
                                        // Remove the classes that represent a 
different state for link.
                                        .removeClass( 'cx-selection 
cx-highlight--blue new cx-target-link-unadapted' )
                                        .removeData( 'cxTargetLink' ) // Unbind
@@ -1051,10 +1053,10 @@
                                $link = $( '.cx-selection' );
                                // Convert the selection to a mw link.
                                $link.prop( {
-                                               rel: 'mw:WikiLink',
-                                               href: target.title,
-                                               title: target.title
-                                       } )
+                                       rel: 'mw:WikiLink',
+                                       href: target.title,
+                                       title: target.title
+                               } )
                                        .text( this.selection || target.title )
                                        .addClass( 'cx-link cx-target-link' )
                                        .removeClass( 'cx-selection 
cx-highlight--blue' )
@@ -1084,6 +1086,8 @@
 
        /**
         * Expand the linker tool card
+        *
+        * @return {boolean} false
         */
        LinkerTool.prototype.expand = function () {
                var self = this;
diff --git a/modules/tools/ext.cx.tools.linter.js 
b/modules/tools/ext.cx.tools.linter.js
index 3a77162..b08019e 100644
--- a/modules/tools/ext.cx.tools.linter.js
+++ b/modules/tools/ext.cx.tools.linter.js
@@ -97,10 +97,10 @@
 
        LinterCard.prototype.getTriggerEvents = function () {
                return [
-                               'mw.cx.translation.focus',
-                               'mw.cx.translation.validation.success',
-                               'mw.cx.translation.validation.error'
-                       ];
+                       'mw.cx.translation.focus',
+                       'mw.cx.translation.validation.success',
+                       'mw.cx.translation.validation.error'
+               ];
        };
 
        mw.cx.tools.linter = LinterCard;
diff --git a/modules/tools/ext.cx.tools.manager.js 
b/modules/tools/ext.cx.tools.manager.js
index daf8a90..615ec2b 100644
--- a/modules/tools/ext.cx.tools.manager.js
+++ b/modules/tools/ext.cx.tools.manager.js
@@ -29,6 +29,9 @@
 
        /**
         * @class
+        *
+        * @param {jQuery} container The tools container
+        * @param {object} options Options
         */
        function CXToolManager( container, options ) {
                this.options = $.extend( {}, $.fn.cxtoolmanager.defaults, 
options );
@@ -208,6 +211,8 @@
 
        /**
         * $.fn.cxtoolmanager jQuery plugin
+        * @param {object} option
+        * @return {jQuery}
         */
        $.fn.cxtoolmanager = function ( option ) {
                return this.each( function () {
diff --git a/modules/tools/ext.cx.tools.mt.card.js 
b/modules/tools/ext.cx.tools.mt.card.js
index 0d58b0d..32e9fe8 100644
--- a/modules/tools/ext.cx.tools.mt.card.js
+++ b/modules/tools/ext.cx.tools.mt.card.js
@@ -177,6 +177,7 @@
         * Get a menu item for the providers list.
         *
         * @param {string} providerId Provider id.
+        * @param {boolean} newProvider Is Provider is new?
         * @return {jQuery}
         */
        MTControlCard.prototype.getProviderMenuItem = function ( providerId, 
newProvider ) {
diff --git a/modules/tools/ext.cx.tools.mt.js b/modules/tools/ext.cx.tools.mt.js
index 4f51818..419d2b7 100644
--- a/modules/tools/ext.cx.tools.mt.js
+++ b/modules/tools/ext.cx.tools.mt.js
@@ -148,11 +148,11 @@
                                cxserverToken.promise = undefined;
                        } )
                        .then( function ( response ) {
-                                       cxserverToken.jwt = response.jwt;
-                                       cxserverToken.expires = response.exp;
+                               cxserverToken.jwt = response.jwt;
+                               cxserverToken.expires = response.exp;
 
-                                       return response.jwt;
-                               },
+                               return response.jwt;
+                       },
                                // Not all MT services require token, so let 
the caller try
                                // with empty token to see if it fails.
                                function () {
@@ -307,6 +307,20 @@
                this.translate();
        };
 
+       function initTranslationRequest( sourceSectionId ) {
+               var mt;
+               mt = new MachineTranslation( sourceSectionId );
+               mt.init().then( function () {
+                       // Make sure that the current provider is an MT service.
+                       if ( mt.provider === sourceMT || mt.provider === noMT 
|| mt.provider === resetMT ) {
+                               return;
+                       }
+                       // If so, start an MT request.
+                       mt.getTranslatedSection();
+               } );
+               mw.log( '[CX][MT] Prefetching MT for section ' + 
sourceSectionId );
+       }
+
        MachineTranslation.prototype.translate = function () {
                var self = this;
 
@@ -389,7 +403,7 @@
         */
        MachineTranslation.prototype.getMTProviderStorageKey = function () {
                return [ 'cxMTProvider', this.sourceLanguage, 
this.targetLanguage
-                               ].join( '-' );
+               ].join( '-' );
        };
 
        /**
@@ -443,20 +457,6 @@
                sourceLanguage: mw.cx.sourceLanguage,
                targetLanguage: mw.cx.targetLanguage
        };
-
-       function initTranslationRequest( sourceSectionId ) {
-               var mt;
-               mt = new MachineTranslation( sourceSectionId );
-               mt.init().then( function () {
-                       // Make sure that the current provider is an MT service.
-                       if ( mt.provider === sourceMT || mt.provider === noMT 
|| mt.provider === resetMT ) {
-                               return;
-                       }
-                       // If so, start an MT request.
-                       mt.getTranslatedSection();
-               } );
-               mw.log( '[CX][MT] Prefetching MT for section ' + 
sourceSectionId );
-       }
 
        $( function () {
                mw.hook( 'mw.cx.source.ready' ).add( function () {
diff --git a/modules/tools/ext.cx.tools.reference.js 
b/modules/tools/ext.cx.tools.reference.js
index 24d5763..f3e452e 100644
--- a/modules/tools/ext.cx.tools.reference.js
+++ b/modules/tools/ext.cx.tools.reference.js
@@ -84,6 +84,15 @@
                }
        };
 
+       function referenceClickHandler() {
+               var $reference = $( this );
+               mw.hook( 'mw.cx.select.reference' ).fire(
+                       $reference.data( 'sourceid' ), mw.cx.targetLanguage );
+
+               // Avoid bubbling of event.
+               return false;
+       }
+
        /**
         * Add the reference to the cursor position in translation
         */
@@ -321,16 +330,6 @@
                // Fire and event indicating this particular reference was 
adapted.
                mw.hook( 'mw.cx.adapted.reference' ).fire( mwData.body.id );
        };
-
-       function referenceClickHandler() {
-               /*jshint validthis:true */
-               var $reference = $( this );
-               mw.hook( 'mw.cx.select.reference' ).fire(
-                       $reference.data( 'sourceid' ), mw.cx.targetLanguage );
-
-               // Avoid bubbling of event.
-               return false;
-       }
 
        function processReferences( $section ) {
                var $sourceSection, referenceAdaptor, isRestoredFromDraft, 
$referenceLists;
diff --git a/modules/translation/ext.cx.translation.aligner.js 
b/modules/translation/ext.cx.translation.aligner.js
index a60a5d5..6af3f77 100644
--- a/modules/translation/ext.cx.translation.aligner.js
+++ b/modules/translation/ext.cx.translation.aligner.js
@@ -86,18 +86,6 @@
                }
        }
 
-       /**
-        * @param {jQuery} $sourceFigure
-        * @param {jQuery} $targetFigure
-        */
-       function keepFigureAlignment( $sourceFigure, $targetFigure ) {
-               var $source, $target;
-
-               $source = $sourceFigure.find( 'figcaption' );
-               $target = $targetFigure.find( 'figcaption' );
-               keepAlignment( $source, $target );
-       }
-
        function getHeight( $element ) {
                if ( $element.prop( 'tagName' ) === 'FIGURE' ) {
                        return getFigureHeight( $element );
@@ -112,6 +100,26 @@
                        return getTemplateHeight( $element );
                }
                return parseInt( $element.height(), 10 );
+       }
+
+       function setHeight( $element, height ) {
+               if ( $element.prop( 'tagName' ) === 'FIGURE' ) {
+                       $element.css( {
+                               height: height
+                       } );
+                       return;
+               }
+
+               if ( $element.prop( 'tagName' ) === 'TABLE' ) {
+                       $element.css( {
+                               height: height
+                       } );
+                       return;
+               }
+
+               $element.css( {
+                       'min-height': height
+               } );
        }
 
        function getDisplayStyles( $element ) {
@@ -148,26 +156,6 @@
                };
        }
 
-       function setHeight( $element, height ) {
-               if ( $element.prop( 'tagName' ) === 'FIGURE' ) {
-                       $element.css( {
-                               height: height
-                       } );
-                       return;
-               }
-
-               if ( $element.prop( 'tagName' ) === 'TABLE' ) {
-                       $element.css( {
-                               height: height
-                       } );
-                       return;
-               }
-
-               $element.css( {
-                       'min-height': height
-               } );
-       }
-
        /**
         * @param {jQuery} $source
         * @param {jQuery} $target
@@ -193,6 +181,7 @@
                }
 
                if ( sectionTagName === 'FIGURE' ) {
+                       /* eslint no-use-before-define:off */
                        return keepFigureAlignment( $source, $target );
                }
 
@@ -219,6 +208,18 @@
        }
 
        /**
+        * @param {jQuery} $sourceFigure
+        * @param {jQuery} $targetFigure
+        */
+       function keepFigureAlignment( $sourceFigure, $targetFigure ) {
+               var $source, $target;
+
+               $source = $sourceFigure.find( 'figcaption' );
+               $target = $targetFigure.find( 'figcaption' );
+               keepAlignment( $source, $target );
+       }
+
+       /**
         * Keep the height of the source and translation sections equal
         * so that they will appear top-aligned.
         *
diff --git a/modules/translation/ext.cx.translation.js 
b/modules/translation/ext.cx.translation.js
index fe6a7f3..f2e2d51 100644
--- a/modules/translation/ext.cx.translation.js
+++ b/modules/translation/ext.cx.translation.js
@@ -14,6 +14,10 @@
         * ContentTranslationEditor
         *
         * @class
+        *
+        * @param {element} element
+        * @param {jQuery} siteMapper
+        * @param {Object} options
         */
        function ContentTranslationEditor( element, siteMapper, options ) {
                this.$container = $( element );
@@ -108,7 +112,6 @@
        function saveCursorPosition() {
                var $container, selection, anchorNode, focusNode;
 
-               /*jshint validthis:true */
                $container = $( this );
                selection = mw.cx.selection.get();
 
@@ -179,6 +182,10 @@
                        mw.hook( 'mw.cx.translation.focus' ).fire( 
cxTranslation.$title );
                } );
        };
+
+       function sourceSectionClickHandler() {
+               mw.cx.getTranslationSection( $( this ).attr( 'id' ) ).click();
+       }
 
        /**
         * Post-process the section after MT is applied.
@@ -318,7 +325,6 @@
 
        function sectionClick() {
                var sourceSectionId,
-                       /*jshint validthis:true */
                        $currentSection = $( this );
 
                sourceSectionId = $currentSection.data( 'source' );
@@ -328,28 +334,38 @@
        }
 
        function sectionMouseEnterHandler() {
-               /*jshint validthis:true */
                mw.cx.getSourceSection( $( this ).data( 'source' ) ).addClass( 
'cx-highlight' );
        }
 
        function sectionMouseLeaveHandler() {
-               /*jshint validthis:true */
                mw.cx.getSourceSection( $( this ).data( 'source' ) 
).removeClass( 'cx-highlight' );
        }
 
-       function sourceSectionClickHandler() {
-               /*jshint validthis:true */
-               mw.cx.getTranslationSection( $( this ).attr( 'id' ) ).click();
-       }
-
        function sourceSectionMouseEnterHandler() {
-               /*jshint validthis:true */
                mw.cx.getTranslationSection( $( this ).attr( 'id' ) 
).mouseenter();
        }
 
        function sourceSectionMouseLeaveHandler() {
-               /*jshint validthis:true */
                mw.cx.getTranslationSection( $( this ).attr( 'id' ) 
).mouseleave();
+       }
+
+       /**
+        * Get a placeholder div for the given source section.
+        *
+        * @param {string} sourceSectionId
+        * @return {jQuery} The placeholder jQuery object
+        */
+       function getPlaceholder( sourceSectionId ) {
+               return $( '<div>' )
+                       .addClass( 'placeholder' )
+                       .hover( sectionMouseEnterHandler, 
sectionMouseLeaveHandler )
+                       .on( 'click', sectionClick )
+                       .attr( {
+                               id: 'cx' + sourceSectionId,
+                               'data-source': sourceSectionId
+                       } )
+                       .keepAlignment()
+                       .text( mw.msg( 'cx-translation-add-translation' ) );
        }
 
        /**
@@ -387,25 +403,6 @@
                // Append the placeholders to the translation column.
                this.$container.find( '.cx-column__content' ).append( 
placeholders );
        };
-
-       /**
-        * Get a placeholder div for the given source section.
-        *
-        * @param {string} sourceSectionId
-        * @return {jQuery} The placeholder jQuery object
-        */
-       function getPlaceholder( sourceSectionId ) {
-               return $( '<div>' )
-                       .addClass( 'placeholder' )
-                       .hover( sectionMouseEnterHandler, 
sectionMouseLeaveHandler )
-                       .on( 'click', sectionClick )
-                       .attr( {
-                               id: 'cx' + sourceSectionId,
-                               'data-source': sourceSectionId
-                       } )
-                       .keepAlignment()
-                       .text( mw.msg( 'cx-translation-add-translation' ) );
-       }
 
        $.fn.cxTranslation = function ( siteMapper, options ) {
                return this.each( function () {
diff --git a/modules/translation/ext.cx.translation.loader.js 
b/modules/translation/ext.cx.translation.loader.js
index 231d604..1d66c96 100644
--- a/modules/translation/ext.cx.translation.loader.js
+++ b/modules/translation/ext.cx.translation.loader.js
@@ -267,6 +267,26 @@
        };
 
        /**
+        * Get html content of a translation unit to restore.
+        *
+        * @param {Object} translationUnit
+        * @return {string} translation
+        */
+       function getTranslation( translationUnit ) {
+               var translation;
+
+               if ( translationUnit.user && translationUnit.user.content ) {
+                       translation = translationUnit.user.content;
+               } else if ( translationUnit.mt ) {
+                       translation = translationUnit.mt.content;
+               } else if ( translationUnit.source ) {
+                       translation = translationUnit.source.content;
+               }
+
+               return translation;
+       }
+
+       /**
         * Add an orphan translation unit. Orphan translation is a translation 
without
         * source section. We add a dummy source section for such cases. Dummy 
source section
         * is a placeholder - a white block in source column.
@@ -274,6 +294,7 @@
         * @param {string} sourceSectionId The translation unit id.
         * @param {jQuery} $section Add it before/after this section.
         * @param {string} afterOrBefore Whether the orphan to be added after 
or before $section.
+        * @return {string} translation
         */
        ContentTranslationLoader.prototype.addOprhanTranslationUnit = function 
( sourceSectionId, $section, afterOrBefore ) {
                var translationUnit, $translation, $dummySourceSection;
@@ -306,26 +327,6 @@
 
                return $translation;
        };
-
-       /**
-        * Get html content of a translation unit to restore.
-        *
-        * @param {Object} translationUnit
-        * @return {string}
-        */
-       function getTranslation( translationUnit ) {
-               var translation;
-
-               if ( translationUnit.user && translationUnit.user.content ) {
-                       translation = translationUnit.user.content;
-               } else if ( translationUnit.mt ) {
-                       translation = translationUnit.mt.content;
-               } else if ( translationUnit.source ) {
-                       translation = translationUnit.source.content;
-               }
-
-               return translation;
-       }
 
        /**
         * Restore a section to the appropriate placeholders
diff --git a/modules/translation/ext.cx.translation.progress.js 
b/modules/translation/ext.cx.translation.progress.js
index 1f42e2b..9b0268b 100644
--- a/modules/translation/ext.cx.translation.progress.js
+++ b/modules/translation/ext.cx.translation.progress.js
@@ -45,29 +45,6 @@
        }
 
        /**
-        * Calculate the percentage of machine translation out of the whole 
article.
-        *
-        * @return {Object} Map of weights
-        * @return {number} return.any Weight of sections with content
-        * @return {number} return.human Weight of sections with human modified 
content
-        * @return {number} return.mt Weight of sections with unmodified mt 
content
-        * @return {number} return.mtSectionsCount Count of sections with 
unmodified mt content
-        */
-       mw.cx.getProgress = function () {
-               var sourceWeight, weights;
-
-               sourceWeight = getTotalSourceWeight();
-               weights = getTranslationWeights( getSectionsWithContent() );
-               if ( sourceWeight > 0 ) {
-                       weights.any /= sourceWeight;
-                       weights.human /= sourceWeight;
-                       weights.mt /= sourceWeight;
-               }
-
-               return weights;
-       };
-
-       /**
         * Calculate the percentage of machine translation for the given 
sections.
         *
         * @param {jQuery} $sections List of sections.
@@ -115,6 +92,29 @@
        }
 
        /**
+        * Calculate the percentage of machine translation out of the whole 
article.
+        *
+        * @return {Object} Map of weights
+        * @return {number} return.any Weight of sections with content
+        * @return {number} return.human Weight of sections with human modified 
content
+        * @return {number} return.mt Weight of sections with unmodified mt 
content
+        * @return {number} return.mtSectionsCount Count of sections with 
unmodified mt content
+        */
+       mw.cx.getProgress = function () {
+               var sourceWeight, weights;
+
+               sourceWeight = getTotalSourceWeight();
+               weights = getTranslationWeights( getSectionsWithContent() );
+               if ( sourceWeight > 0 ) {
+                       weights.any /= sourceWeight;
+                       weights.human /= sourceWeight;
+                       weights.mt /= sourceWeight;
+               }
+
+               return weights;
+       };
+
+       /**
         * Update/Change handler for section.
         *
         * @param {jQuery} $section The source section
diff --git a/modules/translation/ext.cx.translation.storage.js 
b/modules/translation/ext.cx.translation.storage.js
index bcda598..8ee04f7 100644
--- a/modules/translation/ext.cx.translation.storage.js
+++ b/modules/translation/ext.cx.translation.storage.js
@@ -27,6 +27,7 @@
         * Get the content to save. Clean up the content by removing
         * all unwanted classes and placeholders.
         *
+        * @param {string} $section Section
         * @return {string} HTML to save
         */
        ContentTranslationStorage.prototype.getContent = function ( $section ) {
diff --git a/modules/util/ext.cx.util.js b/modules/util/ext.cx.util.js
index 5e7b49a..4846cbe 100644
--- a/modules/util/ext.cx.util.js
+++ b/modules/util/ext.cx.util.js
@@ -126,8 +126,8 @@
                domain = siteMapper.getWikiDomainCode( language );
                url = siteMapper.config.restbase.replace( '$1', domain );
                url += '/transform/wikitext/to/html';
-               // jscs:disable requireCamelCaseOrUpperCaseIdentifiers
                return $.post( url, {
+               /* eslint camelcase:off */
                        body_only: true,
                        wikitext: wikitext
                } );
diff --git a/modules/util/ext.cx.util.selection.js 
b/modules/util/ext.cx.util.selection.js
index 2767ed6..48a2a26 100644
--- a/modules/util/ext.cx.util.selection.js
+++ b/modules/util/ext.cx.util.selection.js
@@ -72,6 +72,26 @@
        };
 
        /**
+        * Get parent of the given range.
+        *
+        * @param {Object} range The range to get parent from
+        * @return {Object}
+        */
+       function getRangeParent( range ) {
+               var parent;
+
+               if ( range.commonAncestorContainer ) {
+                       parent = range.commonAncestorContainer;
+                       if ( parent.nodeType !== 1 ) {
+                               parent = parent.parentNode;
+                       }
+               } else if ( range.parentElement ) {
+                       parent = range.parentElement();
+               }
+               return parent;
+       }
+
+       /**
         * Sets focus on parent element of range
         * Required for restoring selections on FireFox
         *
@@ -91,24 +111,6 @@
                if ( parent ) {
                        parent.focus();
                }
-       }
-       /**
-        * Get parent of the given range.
-        *
-        * @param {Object} range The range to get parent from
-        */
-       function getRangeParent( range ) {
-               var parent;
-
-               if ( range.commonAncestorContainer ) {
-                       parent = range.commonAncestorContainer;
-                       if ( parent.nodeType !== 1 ) {
-                               parent = parent.parentNode;
-                       }
-               } else if ( range.parentElement ) {
-                       parent = range.parentElement();
-               }
-               return parent;
        }
 
        /**
@@ -225,7 +227,7 @@
         * Wrap the selection corresponding to the given key with the given 
element
         *
         * @param {string} key the key for the saved selection range
-        * @param  {Element} element The element that wraps the selection
+        * @param {Element} element The element that wraps the selection
         */
        Selection.prototype.wrap = function ( key, element ) {
                var range;
diff --git a/modules/widgets/callout/ext.cx.callout.js 
b/modules/widgets/callout/ext.cx.callout.js
index 6d9a5fa..4e2691e 100644
--- a/modules/widgets/callout/ext.cx.callout.js
+++ b/modules/widgets/callout/ext.cx.callout.js
@@ -8,6 +8,10 @@
 
        /**
         * Depending on type, return function call result or just the thing.
+        *
+        * @param {Mixed} thing
+        * @param {Object} context
+        * @return {Mixed} Function call result or thing.
         */
        function maybeCall( thing, context ) {
                return $.isFunction( thing ) ? ( thing.call( context ) ) : 
thing;
@@ -119,79 +123,79 @@
                actualWidth = $dialog[ 0 ].offsetWidth;
                actualHeight = $dialog[ 0 ].offsetHeight;
                switch ( direction ) {
-               case '0':
-               case '12':
-                       position = {
-                               top: pos.top + pos.height + this.options.offset,
-                               left: pos.left + pos.width / 2 - actualWidth / 2
-                       };
-                       break;
-               case '1':
-                       position = {
-                               top: pos.top + pos.height + this.options.offset,
-                               left: pos.left + pos.width - actualWidth
-                       };
-                       break;
-               case '11':
-                       position = {
-                               top: pos.top + pos.height + this.options.offset,
-                               left: pos.left
-                       };
-                       break;
-               case '2':
-                       position = {
-                               top: pos.top - pos.height / 2,
-                               left: pos.left - actualWidth - 
this.options.offset
-                       };
-                       break;
-               case '3':
-                       position = {
-                               top: pos.top + pos.height / 2 - actualHeight / 
2,
-                               left: pos.left - actualWidth - 
this.options.offset
-                       };
-                       break;
-               case '4':
-                       position = {
-                               top: pos.top + pos.height - actualHeight + 
this.options.offset,
-                               left: pos.left - actualWidth - 
this.options.offset
-                       };
-                       break;
-               case '5':
-                       position = {
-                               top: pos.top - actualHeight - 
this.options.offset,
-                               left: pos.left + pos.width - actualWidth
-                       };
-                       break;
-               case '6':
-                       position = {
-                               top: pos.top - actualHeight - 
this.options.offset,
-                               left: pos.left + pos.width / 2 - actualWidth / 2
-                       };
-                       break;
-               case '7':
-                       position = {
-                               top: pos.top - actualHeight - 
this.options.offset,
-                               left: pos.left
-                       };
-                       break;
-               case '8':
-                       position = {
-                               top: pos.top + pos.height - actualHeight + 
this.options.offset,
-                               left: pos.left + pos.width + this.options.offset
-                       };
-                       break;
-               case '9':
-                       position = {
-                               top: pos.top + pos.height / 2 - actualHeight / 
2,
-                               left: pos.left + pos.width + this.options.offset
-                       };
-                       break;
-               case '10':
-                       position = {
-                               top: pos.top - pos.height / 2,
-                               left: pos.left + pos.width + this.options.offset
-                       };
-                       break;
+                       case '0':
+                       case '12':
+                               position = {
+                                       top: pos.top + pos.height + 
this.options.offset,
+                                       left: pos.left + pos.width / 2 - 
actualWidth / 2
+                               };
+                               break;
+                       case '1':
+                               position = {
+                                       top: pos.top + pos.height + 
this.options.offset,
+                                       left: pos.left + pos.width - actualWidth
+                               };
+                               break;
+                       case '11':
+                               position = {
+                                       top: pos.top + pos.height + 
this.options.offset,
+                                       left: pos.left
+                               };
+                               break;
+                       case '2':
+                               position = {
+                                       top: pos.top - pos.height / 2,
+                                       left: pos.left - actualWidth - 
this.options.offset
+                               };
+                               break;
+                       case '3':
+                               position = {
+                                       top: pos.top + pos.height / 2 - 
actualHeight / 2,
+                                       left: pos.left - actualWidth - 
this.options.offset
+                               };
+                               break;
+                       case '4':
+                               position = {
+                                       top: pos.top + pos.height - 
actualHeight + this.options.offset,
+                                       left: pos.left - actualWidth - 
this.options.offset
+                               };
+                               break;
+                       case '5':
+                               position = {
+                                       top: pos.top - actualHeight - 
this.options.offset,
+                                       left: pos.left + pos.width - actualWidth
+                               };
+                               break;
+                       case '6':
+                               position = {
+                                       top: pos.top - actualHeight - 
this.options.offset,
+                                       left: pos.left + pos.width / 2 - 
actualWidth / 2
+                               };
+                               break;
+                       case '7':
+                               position = {
+                                       top: pos.top - actualHeight - 
this.options.offset,
+                                       left: pos.left
+                               };
+                               break;
+                       case '8':
+                               position = {
+                                       top: pos.top + pos.height - 
actualHeight + this.options.offset,
+                                       left: pos.left + pos.width + 
this.options.offset
+                               };
+                               break;
+                       case '9':
+                               position = {
+                                       top: pos.top + pos.height / 2 - 
actualHeight / 2,
+                                       left: pos.left + pos.width + 
this.options.offset
+                               };
+                               break;
+                       case '10':
+                               position = {
+                                       top: pos.top - pos.height / 2,
+                                       left: pos.left + pos.width + 
this.options.offset
+                               };
+                               break;
                }
 
                $dialog.css( position );
@@ -265,6 +269,9 @@
 
        /**
         * The callout plugin
+        *
+        * @param {Object} options
+        * @return {jQuery}
         */
        $.fn.callout = function ( options ) {
                return this.each( function () {
diff --git a/modules/widgets/feedback/ext.cx.feedback.js 
b/modules/widgets/feedback/ext.cx.feedback.js
index c30d6b8..ad3a614 100644
--- a/modules/widgets/feedback/ext.cx.feedback.js
+++ b/modules/widgets/feedback/ext.cx.feedback.js
@@ -13,6 +13,8 @@
         * ContentTranslationFeedback
         *
         * @class
+        *
+        * @param {Element} element
         */
        function ContentTranslationFeedback( element ) {
                this.$container = $( element );
diff --git a/modules/widgets/overlay/ext.cx.overlay.js 
b/modules/widgets/overlay/ext.cx.overlay.js
index 2909530..6376146 100644
--- a/modules/widgets/overlay/ext.cx.overlay.js
+++ b/modules/widgets/overlay/ext.cx.overlay.js
@@ -9,6 +9,8 @@
 
        /**
         * An overlay UI for the page.
+        * @param {Element} element
+        * @param {Object} options
         */
        function CXOverlay( element, options ) {
                this.$container = $( element || 'body' );
@@ -48,7 +50,7 @@
                this.$container.removeClass( 'cx-noscroll' );
        };
 
-       mw.cx.widgets.overlay = CXOverlay;
+       mw.cx.widgets.Overlay = CXOverlay;
 
        $.fn.cxoverlay = function ( option ) {
                return this.each( function () {
@@ -57,7 +59,7 @@
                                options = typeof option === 'object' && option;
 
                        if ( !data ) {
-                               $this.data( 'cxoverlay', ( data = new 
mw.cx.widgets.overlay( this, options ) ) );
+                               $this.data( 'cxoverlay', ( data = new 
mw.cx.widgets.Overlay( this, options ) ) );
                        }
 
                        if ( typeof option === 'string' ) {
diff --git a/modules/widgets/progressbar/ext.cx.progressbar.js 
b/modules/widgets/progressbar/ext.cx.progressbar.js
index f8e3e72..5577aa3 100644
--- a/modules/widgets/progressbar/ext.cx.progressbar.js
+++ b/modules/widgets/progressbar/ext.cx.progressbar.js
@@ -14,6 +14,9 @@
         * ProgressBar
         *
         * @class
+        *
+        * @param {Element} element
+        * @param {Object} options
         */
        function ProgressBar( element, options ) {
                this.$container = $( element );
diff --git a/modules/widgets/translator/ext.cx.translator.js 
b/modules/widgets/translator/ext.cx.translator.js
index 13b9761..1498c14 100644
--- a/modules/widgets/translator/ext.cx.translator.js
+++ b/modules/widgets/translator/ext.cx.translator.js
@@ -12,7 +12,8 @@
        mw.cx.widgets = mw.cx.widgets || {};
 
        function drawChart( ctx, stats ) {
-               var cxTrendChart, data;
+               var data;
+
                data = {
                        labels: Object.keys( 
stats.cxtranslatorstats.publishTrend ),
                        datasets: [
@@ -26,8 +27,9 @@
                                }
                        ]
                };
-               /*global Chart:false */
-               cxTrendChart = cxTrendChart = new Chart( ctx, {
+               /* global Chart:false */
+               /* eslint no-new:off */
+               new Chart( ctx, {
                        type: 'bar',
                        data: data,
                        options: {
diff --git a/package.json b/package.json
index 1087c8a..ec4d980 100644
--- a/package.json
+++ b/package.json
@@ -4,11 +4,12 @@
     "test": "grunt test"
   },
   "devDependencies": {
-    "grunt": "0.4.5",
-    "grunt-cli": "0.1.13",
-    "grunt-contrib-jshint": "0.11.3",
-    "grunt-banana-checker": "0.4.0",
-    "grunt-jscs": "2.3.0",
-    "grunt-jsonlint": "1.0.7"
+    "grunt": "1.0.1",
+    "eslint-config-wikimedia": "0.3.0",
+    "grunt-banana-checker": "0.5.0",
+    "grunt-eslint": "19.0.0",
+    "grunt-jsonlint": "1.0.8",
+    "grunt-stylelint": "0.6.0",
+    "stylelint-config-wikimedia": "0.3.0"
   }
 }
diff --git a/tests/qunit/tools/ext.cx.tools.mtabuse.test.js 
b/tests/qunit/tools/ext.cx.tools.mtabuse.test.js
index 18c8a5d..0ac4ed5 100644
--- a/tests/qunit/tools/ext.cx.tools.mtabuse.test.js
+++ b/tests/qunit/tools/ext.cx.tools.mtabuse.test.js
@@ -11,6 +11,7 @@
        QUnit.module( 'ext.cx.tools.mtabuse', QUnit.newMwEnvironment() );
 
        QUnit.test( 'MT Abuse - isAbuse method tests', 5, function ( assert ) {
+               /* eslint new-cap:off */
                var progress, mtAbuseCard = new mw.cx.tools.mtabuse();
                progress = {
                        any: 0,
diff --git a/tests/qunit/translation/ext.cx.translation.loader.test.js 
b/tests/qunit/translation/ext.cx.translation.loader.test.js
index f9eeb68..3f4fe8b 100644
--- a/tests/qunit/translation/ext.cx.translation.loader.test.js
+++ b/tests/qunit/translation/ext.cx.translation.loader.test.js
@@ -7,12 +7,12 @@
        'use strict';
 
        var tests = [ {
-                       description: 'All ids of source and draft match 
perfectly',
-                       source: '<div><p id="mw1">Paragraph 1</p></div>',
-                       placeholders: '<div><div id="cxmw1" data-source="mw1" 
class="placeholder"></div></div>',
-                       draft: '<p id="cxmw1">PARAGRAPH 1</p>',
-                       translation: '<p id="cxmw1" data-cx-draft="true" 
data-source="mw1">PARAGRAPH 1</p>'
-               },
+               description: 'All ids of source and draft match perfectly',
+               source: '<div><p id="mw1">Paragraph 1</p></div>',
+               placeholders: '<div><div id="cxmw1" data-source="mw1" 
class="placeholder"></div></div>',
+               draft: '<p id="cxmw1">PARAGRAPH 1</p>',
+               translation: '<p id="cxmw1" data-cx-draft="true" 
data-source="mw1">PARAGRAPH 1</p>'
+       },
                {
                        description: 'All ids of source and draft match 
perfectly, Restoring old draft using sequence ids',
                        source: '<div><p id="mw1" data-seqid="1">Paragraph 
1</p></div>',

-- 
To view, visit https://gerrit.wikimedia.org/r/323790
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Id821b8cebc4d0b43d50aaa0ec46bab9f9538b0d4
Gerrit-PatchSet: 16
Gerrit-Project: mediawiki/extensions/ContentTranslation
Gerrit-Branch: master
Gerrit-Owner: Santhosh <[email protected]>
Gerrit-Reviewer: KartikMistry <[email protected]>
Gerrit-Reviewer: Nikerabbit <[email protected]>
Gerrit-Reviewer: Santhosh <[email protected]>
Gerrit-Reviewer: jenkins-bot <>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to