From 17349dcb05c3e275a91258e22c4ac9cc8f9cba53 Mon Sep 17 00:00:00 2001 From: kkapsner Date: Sat, 30 Nov 2019 02:05:37 +0100 Subject: [PATCH] Linting of .tools and test --- .eslintignore | 1 + .eslintrc.json | 28 +++++- .tools/checkMissingTranslation.js | 2 + .tools/findUnusedMessages.js | 138 ++++++++++++++++++------------ .tools/translate.js | 50 +++++++---- .vscode/settings.json | 9 +- .vscode/tasks.json | 4 +- codebeatsettings | 6 ++ options/settingsDisplay.js | 9 +- test/dataUrlTest.php | 67 ++++++++------- test/detectionTest.js | 1 - test/firstPossibleCall.js | 1 - test/iframeTest.html | 72 ++++++++++++++-- test/iframeTest.js | 2 - test/navigatorTest.js | 4 +- test/navigatorTest.php | 4 +- test/sendFingerprintTest.html | 79 +++++++++-------- test/settingsLoading.php | 22 +++-- test/test.js | 7 -- 19 files changed, 333 insertions(+), 173 deletions(-) create mode 100644 .eslintignore create mode 100644 codebeatsettings diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..10f9b62 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +!/.tools \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 3920238..e7ca071 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,12 +6,17 @@ "webextensions": true }, "parserOptions": { + "ecmaVersion": 8, "ecmaFeatures": { "jsx": true }, "sourceType": "script" }, - "plugins": ["promise", "eslint-comments"], + "plugins": [ + "promise", + "eslint-comments", + "html" + ], "extends": [ "eslint:recommended", "plugin:promise/recommended", @@ -59,9 +64,26 @@ } }, { - "files": ["test/*.js"], + "files": ["test/*"], "rules": { - "no-var": "off" + "no-var": "off", + "no-console": "off" + } + }, + { + "files": [".tools/*.js"], + "env": { + "node": true + }, + "rules": { + "no-console": "off" + } + }, + { + "files": ["*.html", "*.php"], + "rules": { + "no-useless-escape": "off", + "no-undef": "off" } } ] diff --git a/.tools/checkMissingTranslation.js b/.tools/checkMissingTranslation.js index 56e7eef..2a97bbf 100644 --- a/.tools/checkMissingTranslation.js +++ b/.tools/checkMissingTranslation.js @@ -7,6 +7,8 @@ const la = require("../_locales/" + language + "/messages.json"); const laKeys = Object.keys(la); enKeys.forEach(function(key){ + "use strict"; + if (en[key].message){ if (!la[key] || !la[key].message){ console.log(key, "missing"); diff --git a/.tools/findUnusedMessages.js b/.tools/findUnusedMessages.js index d603344..4d10781 100644 --- a/.tools/findUnusedMessages.js +++ b/.tools/findUnusedMessages.js @@ -5,6 +5,8 @@ const util = require("util"); function getMessagesInContent(content){ + "use strict"; + const foundMessages = []; [ /\b(?:_|browser.i18n.getMessage|extension.getTranslation|notify|extension)\(["']([^"']+)["']\s*(?:\)|,)/g, @@ -19,58 +21,58 @@ function getMessagesInContent(content){ } async function getMessagesInFile(path){ - return await util.promisify(fs.exists)(path) - .then(function(exists){ - if (exists){ - return util.promisify(fs.readFile)(path, {encoding: "UTF-8"}) - .then(function(content){ - return getMessagesInContent(content); - }); - } - else { - console.log("file does not exist:", path); - return []; - } - }); + "use strict"; + + const exists = await util.promisify(fs.exists)(path); + if (exists){ + const content = await util.promisify(fs.readFile)(path, {encoding: "UTF-8"}); + return getMessagesInContent(content); + } + else { + // eslint-disable-next-line no-console + console.log("file does not exist:", path); + return []; + } } async function getMessagesInFolder(folder){ - return await util.promisify(fs.readdir)(folder, {encoding: "UTF-8"}) - .then(function(files){ - return Promise.all( - files.filter(function(file){ - return !file.startsWith("."); - }).map(function(file){ - return path.join(folder, file); - }).map(function(path){ - return util.promisify(fs.stat)(path).then(function(stat){ - if (stat.isDirectory()){ - return getMessagesInFolder(path); - } - else { - if (path.endsWith(".js")){ - return getMessagesInFile(path); - } - else { - return []; - } - } - }); - }) - ).then(function(messages){ - const flat = []; - messages.forEach(function(messages){ - messages.forEach(function(message){ - flat.push(message); - }); - }); - return flat; + "use strict"; + + const files = await util.promisify(fs.readdir)(folder, {encoding: "UTF-8"}); + + const messages = await Promise.all( + files.filter(function(file){ + return !file.startsWith("."); + }).map(function(file){ + return path.join(folder, file); + }).map(async function(path){ + const stat = await util.promisify(fs.stat)(path); + if (stat.isDirectory()){ + return getMessagesInFolder(path); + } + else { + if (path.endsWith(".js")){ + return getMessagesInFile(path); + } + else { + return []; + } + } + }) + ); + const flat = []; + messages.forEach(function(messages){ + messages.forEach(function(message){ + flat.push(message); }); - }) + }); + return flat; } -async function getSettingMessages(){ +async function getSettingMessages(){ + "use strict"; + const settingStrings = require("../lib/settingStrings"); const settingDefinitions = require("../lib/settingDefinitions"); function getDefinition(name){ @@ -113,33 +115,53 @@ async function getSettingMessages(){ }); }); }); + const presets = require("../options/presets.json"); + Object.keys(presets).forEach(function(preset){ + foundMessages.push("preset_" + preset + "_title"); + foundMessages.push("preset_" + preset + "_description"); + }); return foundMessages.map(function(message){return message.toLowerCase();}); } async function getKnownMessages(){ + "use strict"; + return [ "addon_title", "addon_description", - "urlsettings_title", + "urlSettings_title", "installnotice", + "presets_installnotice", "updatenotice", - "disablenotifications", + "disableNotifications", "showoptions", - "displayhiddensettings_title", - "displayhiddensettings_description", + "displayHiddenSettings_title", + "displayHiddenSettings_description", "browseraction_settings", "browseraction_test", "browseraction_review", - "browseraction_reportissue", - ]; + "browseraction_reportIssue", + ].map(function(message){ + return message.toLowerCase(); + }); } -const en = require("../_locales/en/messages.json"); -const declaredMessages = Object.keys(en) - // .filter(function(key){return en[key].message;}) - .map(function(key){return key.toLowerCase();}); -Promise.all([getSettingMessages(), getMessagesInFolder(path.join(__dirname, "..")), getKnownMessages()]).then(function([settingMessages, fileMessages, knownMessages]){ +async function main(){ + "use strict"; + const en = require("../_locales/en/messages.json"); + const declaredMessages = Object.keys(en) + // .filter(function(key){return en[key].message;}) + .map(function(key){ + return key.toLowerCase(); + }); + const [settingMessages, fileMessages, knownMessages] = await Promise.all([ + getSettingMessages(), + getMessagesInFolder(path.join(__dirname, "..")), + getKnownMessages()] + ); + declaredMessages.forEach(function(message){ + if ( fileMessages.indexOf(message) === -1 && settingMessages.indexOf(message) === -1 && @@ -148,4 +170,6 @@ Promise.all([getSettingMessages(), getMessagesInFolder(path.join(__dirname, ".." console.log(`usage of ${message} not found`); } }); -}); \ No newline at end of file +} + +main(); \ No newline at end of file diff --git a/.tools/translate.js b/.tools/translate.js index 49d469f..64e14f1 100644 --- a/.tools/translate.js +++ b/.tools/translate.js @@ -8,35 +8,39 @@ const language = process.argv[2]; function getTranslationPath(language){ + "use strict"; + return path.join(__dirname, "../_locales/" + language + "/messages.json"); } async function loadTranslation(language){ + "use strict"; + const path = getTranslationPath(language); - return await util.promisify(fs.exists)(path) - .then(function(exists){ - if (exists){ - console.log("language exists -> load data"); - return util.promisify(fs.readFile)(path, {encoding: "UTF-8"}) - .then(function(data){ - return JSON.parse(data); - }); - } - else { - console.log("language does not exist -> create it"); - return {}; - } - }); + const exists = await util.promisify(fs.exists)(path); + if (exists){ + console.log("language exists -> load data"); + const data = await util.promisify(fs.readFile)(path, {encoding: "UTF-8"}); + return JSON.parse(data); + } + else { + console.log("language does not exist -> create it"); + return {}; + } } async function saveTranslation(language, data){ + "use strict"; + const path = getTranslationPath(language); return await util.promisify(fs.writeFile)(path, JSON.stringify(data, null, "\t")); } async function getInput(prompt){ - return new Promise(function(resolve, reject){ + "use strict"; + + return new Promise(function(resolve){ process.stdout.write(prompt); - process.stdin.setEncoding('utf8'); + process.stdin.setEncoding("utf8"); process.stdin.resume(); process.stdin.on("data", function onData(data){ process.stdin.removeListener("data", onData); @@ -47,18 +51,22 @@ async function getInput(prompt){ } async function askForTranslation(key){ + "use strict"; + const enData = en[key]; console.log("English translation for", key, ":", enData.message); if (enData.description){ console.log("\nDescription:", enData.description); } - return await getInput("Please enter translation: "); + return getInput("Please enter translation: "); } async function translate(language){ + "use strict"; + const originalData = await loadTranslation(language); const data = {}; - for (var i = 0; i < enKeys.length; i += 1){ + for (let i = 0; i < enKeys.length; i += 1){ const key = enKeys[i]; const oldData = originalData[key]; const enData = en[key]; @@ -76,5 +84,11 @@ async function translate(language){ } translate(language).then(function(data){ + "use strict"; + return saveTranslation(language, data); +}).catch(function(error){ + "use strict"; + + console.error(error); }); \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 2b24bee..74fe2da 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -61,5 +61,12 @@ "**/.git/objects/**", ".vscode", ".eslintrc.json" - ] + ], + "eslint.validate": [ + "javascript", + "php", + "html" + ], + "eslint.options": {"--ext": ".js,.html,.php"}, + "eslint.lintTask.enable": true } \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index ba4352c..894f286 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -16,7 +16,9 @@ "command": "eslint" }, "args": [ - "./" + "./", + "--ext", + ".js,.html,.php" ], "presentation": { "echo": true, diff --git a/codebeatsettings b/codebeatsettings new file mode 100644 index 0000000..6f9752d --- /dev/null +++ b/codebeatsettings @@ -0,0 +1,6 @@ +{ + "JAVASCRIPT": { + "LOC": [70, 80, 100, 120], + "BLOCK_NESTING": [4, 5, 6, 7] + } +} \ No newline at end of file diff --git a/options/settingsDisplay.js b/options/settingsDisplay.js index 69c2484..90099ff 100644 --- a/options/settingsDisplay.js +++ b/options/settingsDisplay.js @@ -97,7 +97,14 @@ "name": "clearPersistentRnd", "actions": [ "clearPersistentRnd", - browser.contextualIdentities? "clearPersistentRndForContainer": false + function(){ + try { + return browser.contextualIdentities? "clearPersistentRndForContainer": false; + } + catch (error){ + return false; + } + }() ], "displayDependencies": [ { diff --git a/test/dataUrlTest.php b/test/dataUrlTest.php index 37e4895..fbcd276 100644 --- a/test/dataUrlTest.php +++ b/test/dataUrlTest.php @@ -112,6 +112,7 @@ } function getIsPointInPath(ctx){ "use strict"; + ctx.beginPath(); ctx.moveTo(20, 19); ctx.lineTo(40, 19); @@ -120,8 +121,10 @@ ctx.stroke(); return ctx.isPointInPath(30, 19); - }; + } function hashToString(hash){ + "use strict"; + var chunks = []; (new Uint32Array(hash)).forEach(function(num){ chunks.push(num.toString(16)); @@ -130,35 +133,41 @@ return "0".repeat(8 - chunk.length) + chunk; }).join(""); } - - function send(form, {url, imageData, isPointInPath}){ - var buffer = new TextEncoder("utf-8").encode(url); - Promise.all([ - crypto.subtle.digest("SHA-256", buffer), - crypto.subtle.digest("SHA-256", imageData.data) - ]).then(function(hashes){ - var data = JSON.stringify({ - urlHash: hashToString(hashes[0]), - imageDataHash: hashToString(hashes[1]), - isPointInPath - }, null, "\t"); - form.fingerprint.value = data; - var xhr = new XMLHttpRequest(); - xhr.open("POST", form.action + "?main", true); - xhr.onreadystatechange = function(){ - if (this.readyState === 4){ - const status = this.status; - if (status === 200 || status === 304) { - console.log("Sending xhr successful from main page:", data); + + var send = function(){ + "use strict"; + return function send(form, {url, imageData, isPointInPath}){ + var buffer = new TextEncoder("utf-8").encode(url); + Promise.all([ + crypto.subtle.digest("SHA-256", buffer), + crypto.subtle.digest("SHA-256", imageData.data) + ]).then(function(hashes){ + var data = JSON.stringify({ + urlHash: hashToString(hashes[0]), + imageDataHash: hashToString(hashes[1]), + isPointInPath + }, null, "\t"); + form.fingerprint.value = data; + var xhr = new XMLHttpRequest(); + xhr.open("POST", form.action + "?main", true); + xhr.onreadystatechange = function(){ + if (this.readyState === 4){ + const status = this.status; + if (status === 200 || status === 304) { + console.log("Sending xhr successful from main page:", data); + } + else { + console.log("Sending xhr failed:", this); + } } - else { - console.log("Sending xhr failed:", this); - } - } - }; - xhr.send(new FormData(form)); - }); - } + }; + xhr.send(new FormData(form)); + return; + }).catch(function(error){ + console.error(error); + }); + }; + }(); send(document.getElementById("form"), topTest()); diff --git a/test/detectionTest.js b/test/detectionTest.js index 9b24e47..eef4338 100644 --- a/test/detectionTest.js +++ b/test/detectionTest.js @@ -18,7 +18,6 @@ var addTest = (function(){ status = func(log)? 1: 2; } catch (error){ - // eslint-disable-next-line no-console console.log(error); status = 3; } diff --git a/test/firstPossibleCall.js b/test/firstPossibleCall.js index 01585bc..3d1f0e4 100644 --- a/test/firstPossibleCall.js +++ b/test/firstPossibleCall.js @@ -1,2 +1 @@ -// eslint-disable-next-line no-console console.log("first possible call"); \ No newline at end of file diff --git a/test/iframeTest.html b/test/iframeTest.html index a61c7b7..f58828e 100644 --- a/test/iframeTest.html +++ b/test/iframeTest.html @@ -13,35 +13,91 @@ const iframe = window[0]; log("TEST:", "iframe in html:", compare(test(iframe), reference)); iframe.addEventListener("load", function(){ + "use strict"; + log("TEST:", "iframe after loading:", compare(test(iframe), reference)); }); - document.write(" + \ No newline at end of file diff --git a/test/sendFingerprintTest.html b/test/sendFingerprintTest.html index 911e765..8fac57c 100644 --- a/test/sendFingerprintTest.html +++ b/test/sendFingerprintTest.html @@ -52,8 +52,10 @@ ctx.stroke(); return ctx.isPointInPath(30, 19); - }; + } function hashToString(hash){ + "use strict"; + var chunks = []; (new Uint32Array(hash)).forEach(function(num){ chunks.push(num.toString(16)); @@ -63,42 +65,49 @@ }).join(""); } - function send(form, {url, imageData, isPointInPath}){ - var buffer = new TextEncoder("utf-8").encode(url); - Promise.all([ - crypto.subtle.digest("SHA-256", buffer), - crypto.subtle.digest("SHA-256", imageData.data) - ]).then(function(hashes){ - var data = JSON.stringify({ - urlHash: hashToString(hashes[0]), - imageDataHash: hashToString(hashes[1]), - isPointInPath - }, null, "\t"); - form.fingerprint.value = data; - var xhr = new XMLHttpRequest(); - xhr.open("POST", form.action, true); - xhr.onreadystatechange = function(){ - if (this.readyState === 4){ - const status = this.status; - if (status === 200 || status === 304) { - console.log("Sending xhr successful from", origin, ":", data); + var send = function(){ + "use strict"; + + return function send(form, {url, imageData, isPointInPath}){ + var buffer = new TextEncoder("utf-8").encode(url); + return Promise.all([ + crypto.subtle.digest("SHA-256", buffer), + crypto.subtle.digest("SHA-256", imageData.data) + ]).then(function(hashes){ + var data = JSON.stringify({ + urlHash: hashToString(hashes[0]), + imageDataHash: hashToString(hashes[1]), + isPointInPath + }, null, "\t"); + form.fingerprint.value = data; + var xhr = new XMLHttpRequest(); + xhr.open("POST", form.action, true); + xhr.onreadystatechange = function(){ + if (this.readyState === 4){ + const status = this.status; + if (status === 200 || status === 304) { + console.log("Sending xhr successful from", origin, ":", data); + } + else { + console.log("Sending xhr failed:", this); + } } - else { - console.log("Sending xhr failed:", this); - } - } - }; - xhr.send(new FormData(form)); - window.setTimeout(function(){ - form.submit(); + }; + xhr.send(new FormData(form)); window.setTimeout(function(){ - document.getElementById("log").textContent = "You see the real canvas fingerprint, but it cannot leak from this iFrame."; - }, - 250 - ); - }, 1000); - }); - } + form.submit(); + window.setTimeout( + function(){ + document.getElementById("log").textContent = + "You see the real canvas fingerprint, but it cannot leak from this iFrame."; + }, + 250 + ); + }, 1000); + return; + }); + }; + }(); send(document.getElementById("form"), topTest()); diff --git a/test/settingsLoading.php b/test/settingsLoading.php index fd73855..4845dbc 100644 --- a/test/settingsLoading.php +++ b/test/settingsLoading.php @@ -28,6 +28,8 @@ return canvas.toDataURL(); } function hash(url){ + "use strict"; + var buffer = new TextEncoder("utf-8").encode(url); return crypto.subtle.digest("SHA-256", buffer).then(function(hash){ var chunks = []; @@ -39,12 +41,12 @@ }).join(""); }); } + var firstFingerprint = false; try { - var firstFingerprint = fingerPrint(); + firstFingerprint = fingerPrint(); } catch (error){ console.log(new Date(), error); - var firstFingerprint = false; }