From e14bc69dacdb74380f781976c5545d09557f41ff Mon Sep 17 00:00:00 2001 From: "Simon W. Jackson" Date: Thu, 12 Oct 2017 19:22:51 -0500 Subject: [PATCH] Feature: add linting to build process (#527) * add build task 'lint' * add semi colons across project * add eslint to the 'lint' pipeline * add eslint fule no-tabs --- .eslintrc | 11 +++++++++++ .gitignore | 3 ++- background.js | 18 +++++++++--------- content_scripts/content_scripts.js | 2 +- content_scripts/front.js | 2 +- content_scripts/gist.js | 2 +- content_scripts/normal.js | 8 ++++---- content_scripts/runtime.js | 2 +- content_scripts/visual.js | 2 +- gulpfile.js | 28 ++++++++++++++++++++++++++-- package.json | 8 +++++--- pages/common.js | 2 +- pages/default.js | 4 ++-- pages/editor.js | 20 ++++++++++---------- pages/front.js | 8 ++++---- pages/mermaid.js | 2 +- pages/omnibar.js | 16 ++++++++-------- 17 files changed, 88 insertions(+), 50 deletions(-) create mode 100644 .eslintrc diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 000000000..596bc8dfb --- /dev/null +++ b/.eslintrc @@ -0,0 +1,11 @@ +{ + "env": { + "browser": true, + "node": true, + "es6": true + }, + "rules": { + "semi": ["error", "always"], + "no-tabs": 2 + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore index db6f213e9..e5746af9b 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ node_modules/ dist/ .DS_Store .vscode/ -package-lock.json \ No newline at end of file +package-lock.json +jsconfig.json \ No newline at end of file diff --git a/background.js b/background.js index da0110188..e686222d2 100644 --- a/background.js +++ b/background.js @@ -222,7 +222,7 @@ var ChromeService = (function() { } } else { var type = _port ? "[unexpected port message] " : "[unexpected runtime message] "; - console.log(type + JSON.stringify(_message)) + console.log(type + JSON.stringify(_message)); } } } @@ -377,7 +377,7 @@ var ChromeService = (function() { return handleMessage(message, port.sender, function(resp) { try { if (!port.isDisconnected) { - port.postMessage(resp) + port.postMessage(resp); } } catch (e) { console.log(message.action + ": " + e); @@ -636,7 +636,7 @@ var ChromeService = (function() { _response(message, sendResponse, { urls: tabs }); - }) + }); }; self.getTopSites = function(message, sender, sendResponse) { chrome.topSites.get(function(urls) { @@ -644,7 +644,7 @@ var ChromeService = (function() { _response(message, sendResponse, { urls: urls }); - }) + }); }; function _getHistory(cb, sortByMostUsed) { chrome.history.search({ @@ -821,7 +821,7 @@ var ChromeService = (function() { }); }; - self.closeTabLeft = function(message, sender, senderResponse) { _closeTab(sender, -message.repeats)}; + self.closeTabLeft = function(message, sender, senderResponse) { _closeTab(sender, -message.repeats);}; self.closeTabRight = function(message, sender, senderResponse) { _closeTab(sender, message.repeats); }; self.closeTabsToLeft = function(message, sender, senderResponse) { _closeTab(sender, -sender.tab.index); }; self.closeTabsToRight = function(message, sender, senderResponse) { @@ -921,7 +921,7 @@ var ChromeService = (function() { function normalizeURL(url) { if (!/^view-source:|^javascript:/.test(url) && /^(?:https?:\/\/)?(?:[^@\/\n]+@)?(?:www\.)?([^:\/\n]+)/im.test(url)) { if (/^[\w-]+?:\/\//i.test(url)) { - url = url + url = url; } else { url = "http://" + url; } @@ -1108,8 +1108,8 @@ var ChromeService = (function() { url: newTabUrl }, function(tabs) { chrome.tabs.remove(tabs.map(function(t) { - return t.id - })) + return t.id; + })); }); } }); @@ -1130,7 +1130,7 @@ var ChromeService = (function() { _response(message, sendResponse, { downloads: items }); - }) + }); }; self.executeScript = function(message, sender, sendResponse) { chrome.tabs.executeScript(sender.tab.id, { diff --git a/content_scripts/content_scripts.js b/content_scripts/content_scripts.js index 5cfc72c5d..b400bfc4e 100644 --- a/content_scripts/content_scripts.js +++ b/content_scripts/content_scripts.js @@ -366,7 +366,7 @@ function tabOpenLink(str, simultaneousness) { var urls; if (str.constructor.name === "Array") { - urls = str + urls = str; } else if (str.constructor.name === "jQuery") { urls = str.map(function() { return this.href; diff --git a/content_scripts/front.js b/content_scripts/front.js index 7eaf7481c..9fbe9e4cb 100644 --- a/content_scripts/front.js +++ b/content_scripts/front.js @@ -124,7 +124,7 @@ var Front = (function() { }); }); }; - self.openOmnibar(({type: "OmniQuery", extra: args.query, style: args.style})) + self.openOmnibar(({type: "OmniQuery", extra: args.query, style: args.style})); }; self.openFinder = function() { diff --git a/content_scripts/gist.js b/content_scripts/gist.js index 5b27c940f..596e8ebb5 100644 --- a/content_scripts/gist.js +++ b/content_scripts/gist.js @@ -86,6 +86,6 @@ var Gist = (function() { return self; })(); -Gist.initGist('****************************************') +Gist.initGist('****************************************'); Gist.readComment(1); // Gist.newComment("abc"); diff --git a/content_scripts/normal.js b/content_scripts/normal.js index 1bbda38cc..07574793f 100644 --- a/content_scripts/normal.js +++ b/content_scripts/normal.js @@ -112,7 +112,7 @@ var Mode = (function() { } else { var pathname = window.location.pathname.split('/'); if (pathname.length) { - sl += " - frame: " + pathname[pathname.length - 1] + sl += " - frame: " + pathname[pathname.length - 1]; } } } @@ -389,7 +389,7 @@ var Normal = (function(mode) { var h = n.scrollHeight; if (h > maxHeight) { scrollIndex = i; - maxHeight = h + maxHeight = h; } }); var sn = scrollNodes[scrollIndex]; @@ -645,7 +645,7 @@ var Normal = (function(mode) { var hints = modeKey[1]; return function() { Hints.feedkeys(hints); - } + }; } setTimeout(closureWrapper(), 120 + i*100); } @@ -692,7 +692,7 @@ var Normal = (function(mode) { url: markInfo, scrollLeft: 0, scrollTop: 0 - } + }; } markInfo.tab = { tabbed: newTab, diff --git a/content_scripts/runtime.js b/content_scripts/runtime.js index a701a5fe4..907e6855a 100644 --- a/content_scripts/runtime.js +++ b/content_scripts/runtime.js @@ -78,7 +78,7 @@ var runtime = window.runtime || (function() { } }); } else { - console.log("[unexpected runtime message] " + JSON.stringify(_message)) + console.log("[unexpected runtime message] " + JSON.stringify(_message)); } }); diff --git a/content_scripts/visual.js b/content_scripts/visual.js index 5ee51aa85..eb27d8388 100644 --- a/content_scripts/visual.js +++ b/content_scripts/visual.js @@ -257,7 +257,7 @@ var Visual = (function(mode) { annotation: "make cursor at center of window.", feature_group: 9, code: function() { - document.scrollingElement.scrollTop += cursor.getBoundingClientRect().top - window.innerHeight/2 + document.scrollingElement.scrollTop += cursor.getBoundingClientRect().top - window.innerHeight/2; } }); self.mappings.add("f", { diff --git a/gulpfile.js b/gulpfile.js index 827338aea..bffb22f30 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -5,7 +5,31 @@ var gulp = require('gulp'), zip = require('gulp-zip'), gulpUtil = require('gulp-util'), babel = require('gulp-babel'), - gp_uglify = require('gulp-uglify'); + gp_uglify = require('gulp-uglify'), + eslint = require('gulp-eslint'); + +gulp.task('lint', () => { + // ESLint ignores files with "node_modules" paths. + // So, it's best to have gulp ignore the directory as well. + // Also, Be sure to return the stream from the task; + // Otherwise, the task may end before the stream has finished. + return gulp.src([ + 'background.js', + 'gulpfile.js', + 'content_scripts/*.js', + 'pages/*.js', + '!node_modules/**' + ]) + // eslint() attaches the lint output to the "eslint" property + // of the file object so it can be used by other modules. + .pipe(eslint()) + // eslint.format() outputs the lint results to the console. + // Alternatively use eslint.formatEach() (see Docs). + .pipe(eslint.format()) + // To have the process exit with an error code (1) on + // lint error, return the stream and pipe to failAfterError last. + .pipe(eslint.failAfterError()); +}); gulp.task('clean', function () { return gulp.src('dist', {read: false}) @@ -87,7 +111,7 @@ gulp.task('copy-es-files', ['clean'], function() { .pipe(gulp.dest('dist')); }); -gulp.task('default', ['copy-pretty-default-js', 'build_common_content_min', 'use_common_content_min', 'use_common_content_min_manifest'], function() { +gulp.task('default', ['lint', 'copy-pretty-default-js', 'build_common_content_min', 'use_common_content_min', 'use_common_content_min_manifest'], function() { return gulp.src('dist/**') .pipe(zip('sk.zip')) .pipe(gulp.dest('dist')); diff --git a/package.json b/package.json index eb3af6d66..a0fcf8a1d 100644 --- a/package.json +++ b/package.json @@ -4,17 +4,19 @@ "description": "Map your keys for web surfing, expand your browser with javascript and keyboard.", "main": "background.js", "dependencies": { - "gulp-clean": "^0.3.2", + "babel-preset-es2015": "^6.22.0", "gulp": "^3.9.1", "gulp-babel": "^6.1.2", - "babel-preset-es2015": "^6.22.0", - "gulp-uglify": "^1.5.3", + "gulp-clean": "^0.3.2", "gulp-concat": "^2.6.0", + "gulp-eslint": "^4.0.0", "gulp-replace": "^0.5.4", + "gulp-uglify": "^1.5.3", "gulp-zip": "^3.2.0" }, "devDependencies": { "babel-cli": "^6.24.1", + "babel-eslint": "^8.0.1", "babel-plugin-transform-react-jsx": "^6.24.1", "babel-preset-env": "^1.6.0" }, diff --git a/pages/common.js b/pages/common.js index 28ef2759c..d6c25576e 100644 --- a/pages/common.js +++ b/pages/common.js @@ -22,7 +22,7 @@ $(document).on('surfingkeys:defaultSettingsLoaded', function() { if (meta.annotation && meta.annotation.length && meta.feature_group === 99) { return "
{0}{1}
".format(htmlEncode(w), meta.annotation); } - return null + return null; }).filter(function(w) { return w !== null; }); diff --git a/pages/default.js b/pages/default.js index 4d7b490d6..649f8d9e7 100644 --- a/pages/default.js +++ b/pages/default.js @@ -275,7 +275,7 @@ mapkey('', '#1Mouse out elements.', 'Hints.create("", Hints.dispatchMous mapkey('ya', '#7Copy a link URL to the clipboard', function() { Hints.create('*[href]', function(element) { Front.writeClipboard(element.href); - }) + }); }); mapkey('yma', '#7Copy multiple link URLs to the clipboard', function() { var linksToYank = []; @@ -296,7 +296,7 @@ mapkey('I', '#1Go to edit box with vim editor', function() { }); mapkey('O', '#1Open detected links from text', function() { Hints.create(runtime.conf.clickablePat, function(element) { - $(``)[0].click() + $(``)[0].click(); }, {statusLine: "Open detected links from text"}); }); mapkey(';s', 'Toggle PDF viewer from SurfingKeys', function() { diff --git a/pages/editor.js b/pages/editor.js index 935f7a53c..4c5be8005 100644 --- a/pages/editor.js +++ b/pages/editor.js @@ -90,7 +90,7 @@ var AceEditor = (function(mode, elmId) { value: u.url, score: typedCount*10 + visitCount, meta: 'local' - } + }; }); }); var urlCompleter = { @@ -121,7 +121,7 @@ var AceEditor = (function(mode, elmId) { value: w, score: wordScores[w], meta: 'local' - } + }; }); }; @@ -204,16 +204,16 @@ var AceEditor = (function(mode, elmId) { vim.defineEx("wq", "wq", function(cm, input) { self.exit(self._getValue()); // tell vim editor that command is done - self.state.cm.signal('vim-command-done', '') + self.state.cm.signal('vim-command-done', ''); }); - vim.map('', ':wq', 'normal') + vim.map('', ':wq', 'normal'); vim.defineEx("bnext", "bn", function(cm, input) { Front.contentCommand({ action: 'nextEdit', backward: false }); }); - vim.map('', ':bn', 'normal') + vim.map('', ':bn', 'normal'); vim.defineEx("bprevious", "bp", function(cm, input) { Front.contentCommand({ action: 'nextEdit', @@ -222,7 +222,7 @@ var AceEditor = (function(mode, elmId) { }); vim.defineEx("quit", "q", function(cm, input) { self.exit(); - self.state.cm.signal('vim-command-done', '') + self.state.cm.signal('vim-command-done', ''); }); Front.vimMappings.forEach(function(a) { vim.map.apply(vim, a); @@ -238,7 +238,7 @@ var AceEditor = (function(mode, elmId) { originValue = message.content; $(self.container).find('textarea').focus(); self.enter(); - vim.map('', ':wq', 'insert') + vim.map('', ':wq', 'insert'); self.type = message.type; self.setFontSize(16); if (message.type === 'url') { @@ -252,12 +252,12 @@ var AceEditor = (function(mode, elmId) { } else { self.renderer.setOption('showLineNumbers', true); self.language_tools.setCompleters([pageWordCompleter]); - vim.unmap('', 'insert') - vim.map('', ':wq', 'insert') + vim.unmap('', 'insert'); + vim.map('', ':wq', 'insert'); self.css('height', '30%'); } self.setReadOnly(message.type === 'select'); - vim.map('', '', 'insert') + vim.map('', '', 'insert'); vim.exitInsertMode(self.state.cm); // set cursor at initial line diff --git a/pages/front.js b/pages/front.js index e2da7cb2e..9aa3600d3 100644 --- a/pages/front.js +++ b/pages/front.js @@ -172,13 +172,13 @@ var Front = (function(mode) { tab.html("
{0}
{2}
".format(hintLabels[i], t.favIconUrl, htmlEncode(t.title))); tab.data('url', t.url); tabs_fg.append(tab); - }) + }); tabs_fg.find('div.sk_tab').each(function() { $(this).css('width', $(this).width() + 10); $(this).append($("
{0}
".format($(this).data('url')))); }); _tabs.find('div.sk_tabs_bg').css('width', window.innerWidth).css('height', window.innerHeight); - } + }; _actions['chooseTab'] = function() { runtime.command({ action: 'getTabs' @@ -205,7 +205,7 @@ var Front = (function(mode) { l10n = l10n[lang]; cb(function(str) { return l10n[str] ? l10n[str] : str; - }) + }); } else { cb(function(str) { return str; @@ -508,7 +508,7 @@ var Front = (function(mode) { } }).join(""); if (words.length > 0 && _pendingHint) { - keystroke.html(words) + keystroke.html(words); keystroke.removeClass("expandRichHints").addClass("expandRichHints"); self.flush(); } diff --git a/pages/mermaid.js b/pages/mermaid.js index aa9b37021..8e4c37d96 100644 --- a/pages/mermaid.js +++ b/pages/mermaid.js @@ -48,7 +48,7 @@ $(document).on('surfingkeys:defaultSettingsLoaded', function() { mermaid.parseError = function(err) { Front.showPopup(err); - } + }; function drawDiagram(code) { Front.source = code; $('div.mermaid').removeAttr('data-processed').html(code); diff --git a/pages/omnibar.js b/pages/omnibar.js index 772456de2..5501ed447 100644 --- a/pages/omnibar.js +++ b/pages/omnibar.js @@ -203,7 +203,7 @@ var Omnibar = (function(mode, ui) { handler = SearchEngine; $.extend(SearchEngine, SearchEngine.aliases[alias]); self.resultsDiv.html(""); - self.promptSpan.html(handler.prompt) + self.promptSpan.html(handler.prompt); resultPageSpan.html(""); _items = null; self.collapsingPoint = val; @@ -221,7 +221,7 @@ var Omnibar = (function(mode, ui) { if (lastHandler && handler !== lastHandler && (val === self.collapsingPoint || val === "")) { handler = lastHandler; lastHandler = null; - self.promptSpan.html(handler.prompt) + self.promptSpan.html(handler.prompt); if (val.length) { self.input.val(val.substr(0, val.length - 1)); } @@ -428,8 +428,8 @@ var Omnibar = (function(mode, ui) { handler.onOpen && handler.onOpen(args.extra); lastHandler = handler; handler = handler; - self.promptSpan.html(handler.prompt) - resultPageSpan.html("") + self.promptSpan.html(handler.prompt); + resultPageSpan.html(""); ui[0].scrollTop = 0; }; @@ -568,7 +568,7 @@ var OpenBookmarks = (function() { }, self.onResponse); } self.prompt = fl.prompt; - Omnibar.promptSpan.html(self.prompt) + Omnibar.promptSpan.html(self.prompt); lastFocused = fl.focused; eaten = true; } @@ -584,7 +584,7 @@ var OpenBookmarks = (function() { focused: fi.index() }); self.prompt = fi.data('folder_name') + separator; - Omnibar.promptSpan.html(self.prompt) + Omnibar.promptSpan.html(self.prompt); Omnibar.input.val(''); currentFolderId = folderId; lastFocused = 0; @@ -617,7 +617,7 @@ var OpenBookmarks = (function() { if (event.keyCode === KeyboardUtils.keyCodes.comma) { folderOnly = !folderOnly; self.prompt = folderOnly ? `bookmark folder${separator}` : `bookmark${separator}`; - Omnibar.promptSpan.html(self.prompt) + Omnibar.promptSpan.html(self.prompt); runtime.command({ action: 'getBookmarks', parentId: currentFolderId, @@ -921,7 +921,7 @@ var OpenVIMarks = (function() { url: markInfo, scrollLeft: 0, scrollTop: 0 - } + }; } if (query === "" || markInfo.url.indexOf(query) !== -1) { urls.push({