diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 00000000..4c92c7fa --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +_locales +icons +modules/noto-sans/* +modules/color-picker/* +resources diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 00000000..0a6b5ab9 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,196 @@ +{ + "env": { + "browser": true, + "es6": true, + "webextensions": true + }, + "extends": [ + "eslint:recommended" + ], + "globals": { + "Address": true, + "Environment": true, + "Header": true, + "MessageResponse": true, + "Resource": true, + "Setting": true, + "SettingDefaults": true, + "WebRequest": true, + "WebRequestType": true, + "Allowlist": true, + "BrowserType": true, + "IconType": true, + "Regex": true, + "Links": true, + "CDNs": true, + "IgnoredHost": true, + "EncodingTypes": true, + + "fileGuard": true, + "files": true, + "helpers": true, + "interceptor": true, + "mappings": true, + "requestAnalyzer": true, + "requestSanitizer": true, + "resources": true, + "shorthands": true, + "stateManager": true, + "wrappers": true, + "storageManager": true, + "manipulateDOM": true, + "stats": true, + "targets": true, + "ruleGenerator": true, + }, + "overrides": { + "files": [ + "core/constants.js", + "core/files.js", + "core/mappings.js", + "core/resources.js", + "core/shorthands.js" + ], + "rules": { + "no-unused-vars": "off" + } + }, + "rules": { + "array-bracket-newline": "error", + "array-bracket-spacing": "error", + "arrow-body-style": "error", + "arrow-parens": "error", + "arrow-spacing": "error", + "block-spacing": "error", + "brace-style": "error", + "camelcase": "error", + "comma-spacing": "error", + "comma-style": "error", + "computed-property-spacing": "error", + "consistent-this": "error", + "curly": ["error", "multi-line"], + "eol-last": "error", + "eqeqeq": "error", + "func-call-spacing": "error", + "function-paren-newline": "error", + "generator-star-spacing": "error", + "indent": [ + "error", + 4 + ], + "key-spacing": "error", + "keyword-spacing": "error", + "linebreak-style": [ + "error", + "unix" + ], + "new-cap": "error", + "new-parens": "error", + "no-array-constructor": "error", + "no-bitwise": "error", + "no-confusing-arrow": "error", + "no-continue": "error", + "no-console": ["error", { allow: ["warn", "error", "log"] }], + "no-duplicate-imports": "error", + "no-eval": "error", + "no-extend-native": "error", + "no-implicit-coercion": "error", + "no-implied-eval": "error", + "no-invalid-this": "error", + "no-iterator": "error", + "no-label-var": "error", + "no-labels": "error", + "no-lone-blocks": "error", + "no-loop-func": "error", + "no-multi-spaces": "error", + "no-multi-str": "error", + "no-multiple-empty-lines": [ + "error", { + "max": 2, + "maxEOF": 1, + "maxBOF": 0 + } + ], + "max-len": [ + "error", { + "code": 120, + "ignoreUrls": true, + "ignoreStrings": true, + } + ], + "one-var": [2, { + "var": "never", + "let": "always", + "const": "never" + }], + "no-new": "error", + "no-new-func": "error", + "no-new-object": "error", + "no-new-wrappers": "error", + "no-octal-escape": "error", + "no-proto": "error", + "no-return-assign": "error", + "no-return-await": "error", + "no-script-url": "error", + "no-self-compare": "error", + "no-sequences": "error", + "no-shadow-restricted-names": "error", + "no-tabs": "error", + "no-throw-literal": "error", + "no-trailing-spaces": "error", + "no-undef-init": "error", + "no-unmodified-loop-condition": "error", + "no-unused-expressions": "error", + "no-use-before-define": "error", + "no-useless-call": "error", + "no-useless-concat": "error", + "no-useless-constructor": "error", + "no-useless-rename": "error", + "no-useless-return": "error", + "no-void": "error", + "no-warning-comments": "warn", + "no-whitespace-before-property": "error", + "no-with": "error", + "object-curly-spacing": "error", + "object-shorthand": [ + "error", + "consistent-as-needed" + ], + "operator-assignment": "error", + "operator-linebreak": "error", + "prefer-numeric-literals": "error", + "prefer-promise-reject-errors": "error", + "quote-props": "error", + "prefer-rest-params": "error", + "prefer-spread": "error", + "prefer-template": "error", + "quotes": [ + "error", + "single" + ], + "rest-spread-spacing": "error", + "require-await": "error", + "semi": "error", + "semi-spacing": "error", + "semi-style": "error", + "space-before-blocks": "error", + "space-before-function-paren": "error", + "space-in-parens": "error", + "space-infix-ops": "error", + "space-unary-ops": "error", + "spaced-comment": "error", + "strict": [ + "error", + "global" + ], + "switch-colon-spacing": "error", + "symbol-description": "error", + "template-curly-spacing": "error", + "template-tag-spacing": "error", + "unicode-bom": "error", + "vars-on-top": "error", + "wrap-regex": "error", + "yield-star-spacing": "error", + "yoda": "error", + } +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..47cf365a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +test/** diff --git a/core/constants.js b/core/constants.js index db11c251..9daafd3a 100644 --- a/core/constants.js +++ b/core/constants.js @@ -21,7 +21,6 @@ /** * Constants */ - const Address = { 'ANY': '*://*/*', 'ANY_PATH': '/*', @@ -126,8 +125,8 @@ const Allowlist = { }; const BrowserType = { - 'CHROMIUM': chrome.runtime.getURL("/").startsWith("chrome-extension"), - 'FIREFOX': chrome.runtime.getURL("/").startsWith("moz-extension") + 'CHROMIUM': chrome.runtime.getURL('/').startsWith('chrome-extension'), + 'FIREFOX': chrome.runtime.getURL('/').startsWith('moz-extension') }; const IconType = { diff --git a/core/file-guard.js b/core/file-guard.js index 7b2a5102..3ac1245e 100644 --- a/core/file-guard.js +++ b/core/file-guard.js @@ -16,12 +16,14 @@ 'use strict'; + /** * File Guard */ var fileGuard = {}; + /** * Private Methods */ @@ -47,6 +49,7 @@ fileGuard._verifyRequest = function (requestDetails) { } }; + /** * Initializations */ diff --git a/core/interceptor.js b/core/interceptor.js index 69fc61f4..88f0221a 100644 --- a/core/interceptor.js +++ b/core/interceptor.js @@ -18,12 +18,14 @@ 'use strict'; + /** * Interceptor */ var interceptor = {}; + /** * Public Methods */ @@ -69,6 +71,7 @@ interceptor.handleRequest = function (requestDetails, tabIdentifier, tab) { }; }; + /** * Private Methods */ @@ -122,6 +125,7 @@ interceptor._handleStorageChanged = function (changes) { } }; + /** * Initializations */ @@ -146,6 +150,7 @@ storageManager.type.get(interceptor.relatedSettings, function (items) { interceptor.allowedDomainsGoogleFonts = items.allowedDomainsGoogleFonts || {}; }); + /** * Event Handlers */ diff --git a/core/main.js b/core/main.js index bac428ee..806a1c54 100644 --- a/core/main.js +++ b/core/main.js @@ -18,12 +18,14 @@ 'use strict'; + /** * Main */ var main = {}; + /** * Private Methods */ @@ -80,7 +82,7 @@ main._showReleaseNotes = function (details) { if (details.reason === chrome.runtime.OnInstalledReason.INSTALL) { storageManager.type.set({ [Setting.LAST_MAPPING_UPDATE]: mappings.lastMappingUpdate - }, function() { + }, function () { if (details.temporary !== true) { chrome.tabs.create({ 'url': chrome.extension.getURL('pages/welcome/welcome.html'), @@ -107,19 +109,20 @@ main._showReleaseNotes = function (details) { storageManager.type.set(items); } - if ( (mappingUpdate && items.updateNotification == 1) || items.updateNotification == 2 ) { + if ((mappingUpdate && items.updateNotification === 1) || items.updateNotification === 2) { chrome.tabs.create({ - 'url': chrome.extension.getURL('pages/updates/updates.html?mappingupdate=' + mappingUpdate), + 'url': chrome.extension.getURL(`pages/updates/updates.html?mappingupdate=${mappingUpdate}`), 'active': false }); } else { // No mappings.js update - return; + } }); } }; + /** * Initializations */ diff --git a/core/manipulate-dom.js b/core/manipulate-dom.js index be71c4f2..b8b475be 100644 --- a/core/manipulate-dom.js +++ b/core/manipulate-dom.js @@ -28,27 +28,27 @@ var manipulateDOM = {}; manipulateDOM._removeCrossOriginAndIntegrityAttr = function (details) { - if(!BrowserType.FIREFOX) { + if (!BrowserType.FIREFOX) { // Chromium (and other) browsers do not support webRequest.filterResponseData // https://bugs.chromium.org/p/chromium/issues/detail?id=487422 console.warn('[ LocalCDN ] browser.webRequest.filterResponseData not supported by your browser.'); return; } - let initiatorDomain, listedToManipulateDOM, negateHtmlFilter, filtering; + let initiatorDomain, listedToManipulateDOM, negateHtmlFilter, filtering, header; initiatorDomain = helpers.extractDomainFromUrl(details.url, true) || Address.EXAMPLE; - listedToManipulateDOM = stateManager._domainIsListed(initiatorDomain, "manipulate-dom"); + listedToManipulateDOM = stateManager._domainIsListed(initiatorDomain, 'manipulate-dom'); negateHtmlFilter = stateManager.getInvertOption; - if( ( negateHtmlFilter || listedToManipulateDOM ) && !( negateHtmlFilter && listedToManipulateDOM ) ) { + if ((negateHtmlFilter || listedToManipulateDOM) && !(negateHtmlFilter && listedToManipulateDOM)) { filtering = true; } else { filtering = false; } // by Jaap (https://gitlab.com/Jaaap) - let header = details.responseHeaders.find(h => h.name.toLowerCase() === 'content-type'); + header = details.responseHeaders.find((h) => h.name.toLowerCase() === 'content-type'); if (header && filtering) { @@ -59,13 +59,13 @@ manipulateDOM._removeCrossOriginAndIntegrityAttr = function (details) { if (!isAllowlisted && mimeType === 'text/html') { - let asciiDecoder, decoder, encoder, charset, isFirstData, filter; + let asciiDecoder, decoder, encoder, charset, isFirstData, filter, data; - charset = /charset\s*=/.test(header.value) && header.value.replace(/^.*?charset\s*=\s*/, '').replace(/["']?/g, ''); + charset = (/charset\s*=/).test(header.value) && header.value.replace(/^.*?charset\s*=\s*/, '').replace(/["']?/g, ''); // Check if charset is supported by TextDecoder() - if(/charset\s*=/.test(header.value) && !EncodingTypes[charset.toString().toLowerCase()]){ - console.error('[ LocalCDN ] Unsupported charset: ' + charset); + if (/charset\s*=/.test(header.value) && !EncodingTypes[charset.toString().toLowerCase()]) { + console.error(`[ LocalCDN ] Unsupported charset: ${charset}`); return; } @@ -73,35 +73,40 @@ manipulateDOM._removeCrossOriginAndIntegrityAttr = function (details) { encoder = new TextEncoder(); isFirstData = true; filter = browser.webRequest.filterResponseData(details.requestId); - let data = []; + data = []; header.value = 'text/html; charset=UTF-8'; - // Note that should work if the '