소스 검색

refactor: enforce semicolons for consistency

+ move overrides to the bottom of eslint config
tophf 2 년 전
부모
커밋
06fb6e6e28

+ 134 - 126
.eslintrc.js

@@ -1,70 +1,5 @@
 const { readGlobalsFile } = require('./scripts/webpack-util');
-
-const FILES_INJECTED = [`src/injected/**/*.js`];
-const FILES_CONTENT = [
-  'src/injected/index.js',
-  'src/injected/content/**/*.js',
-];
-const FILES_WEB = [`src/injected/web/**/*.js`];
-/* Note that `injected` uses several more `common` files indirectly, but we check just these
- * two automatically because they are trivial by design and must always pass the check */
-const FILES_SHARED = [
-  'src/common/browser.js',
-  'src/common/consts.js',
-  'src/common/safe-globals-shared.js',
-];
-
-const GLOBALS_SHARED = getGlobals('*');
-const GLOBALS_COMMON = {
-  ...GLOBALS_SHARED,
-  ...getGlobals('common'),
-  re: false, // transform-modern-regexp with useRe option
-};
-const GLOBALS_INJECTED = {
-  ...getGlobals('injected'),
-  PAGE_MODE_HANDSHAKE: false,
-  VAULT_ID: false,
-};
-const GLOBALS_CONTENT = {
-  INIT_FUNC_NAME: false,
-  ...GLOBALS_SHARED,
-  ...getGlobals('injected/content'),
-  ...GLOBALS_INJECTED,
-};
-const GLOBALS_WEB = {
-  ...GLOBALS_SHARED,
-  ...getGlobals('injected/web'),
-  ...GLOBALS_INJECTED,
-  IS_FIREFOX: false, // passed as a parameter to VMInitInjection in webpack.conf.js
-};
-
-const INJECTED_RULES = {
-  'no-restricted-imports': ['error', {
-    patterns: ['*/common', '*/common/*'],
-  }],
-  'no-restricted-syntax': [
-    'error', {
-      selector: 'ObjectExpression > ExperimentalSpreadProperty',
-      message: 'Object spread adds a polyfill in injected* even if unused by it',
-    }, {
-      selector: 'ArrayPattern',
-      message: 'Destructuring via Symbol.iterator may be spoofed/broken in an unsafe environment',
-    }, {
-      selector: ':matches(ArrayExpression, CallExpression) > SpreadElement',
-      message: 'Spreading via Symbol.iterator may be spoofed/broken in an unsafe environment',
-    }, {
-      selector: '[callee.object.name="Object"], MemberExpression[object.name="Object"]',
-      message: 'Using potentially spoofed methods in an unsafe environment',
-      // TODO: auto-generate the rule using GLOBALS
-    }, {
-      selector: `CallExpression[callee.name="defineProperty"]:not(${[
-        '[arguments.2.properties.0.key.name="__proto__"]',
-        ':has(CallExpression[callee.name="nullObjFrom"])'
-      ].join(',')})`,
-      message: 'Prototype of descriptor may be spoofed/broken in an unsafe environment',
-    }
-  ],
-};
+const ovr = makeOverrides();
 
 module.exports = {
   root: true,
@@ -73,40 +8,57 @@ module.exports = {
     require.resolve('@gera2ld/plaid-common-vue/eslint/vue3-js'),
   ],
   plugins: ['jest'],
+  rules: {
+    'prettier/prettier': 'off',
+    'no-use-before-define': ['error', {
+      'functions': false,
+      'classes': true,
+      'variables': true,
+      'allowNamedExports': true,
+    }],
+    // copied from airbnb-base, replaced 4 with 8
+    'object-curly-newline': ['error', {
+      ObjectExpression: { minProperties: 8, multiline: true, consistent: true },
+      ObjectPattern: { minProperties: 8, multiline: true, consistent: true },
+      ImportDeclaration: { minProperties: 8, multiline: true, consistent: true },
+      ExportDeclaration: { minProperties: 8, multiline: true, consistent: true },
+    }],
+    'semi': ['error'],
+  },
   overrides: [{
     // `browser` is a local variable since we remove the global `chrome` and `browser` in injected*
     // to prevent exposing them to userscripts with `@inject-into content`
     files: ['*'],
-    excludedFiles: [...FILES_INJECTED, ...FILES_SHARED],
+    excludedFiles: [...ovr.FILES_INJECTED, ...ovr.FILES_SHARED],
     globals: {
       browser: false,
-      ...GLOBALS_COMMON,
+      ...ovr.GLOBALS_COMMON,
     },
   }, {
-    files: FILES_SHARED,
-    globals: GLOBALS_COMMON,
+    files: ovr.FILES_SHARED,
+    globals: ovr.GLOBALS_COMMON,
   }, {
-    files: FILES_WEB,
-    globals: GLOBALS_WEB,
+    files: ovr.FILES_WEB,
+    globals: ovr.GLOBALS_WEB,
   }, {
-    files: FILES_CONTENT,
-    globals: GLOBALS_CONTENT,
+    files: ovr.FILES_CONTENT,
+    globals: ovr.GLOBALS_CONTENT,
   }, {
-    files: FILES_INJECTED,
-    excludedFiles: [...FILES_CONTENT, ...FILES_WEB],
+    files: ovr.FILES_INJECTED,
+    excludedFiles: [...ovr.FILES_CONTENT, ...ovr.FILES_WEB],
     // intersection of globals in CONTENT and WEB
-    globals: Object.keys(GLOBALS_CONTENT).reduce((res, key) => (
-      Object.assign(res, key in GLOBALS_WEB && { [key]: false })
+    globals: Object.keys(ovr.GLOBALS_CONTENT).reduce((res, key) => (
+      Object.assign(res, key in ovr.GLOBALS_WEB && { [key]: false })
     ), {}),
   }, {
-    files: [...FILES_INJECTED, ...FILES_SHARED],
-    rules: INJECTED_RULES,
+    files: [...ovr.FILES_INJECTED, ...ovr.FILES_SHARED],
+    rules: ovr.INJECTED_RULES,
   }, {
-    files: FILES_WEB,
+    files: ovr.FILES_WEB,
     rules: {
-      ...INJECTED_RULES,
+      ...ovr.INJECTED_RULES,
       'no-restricted-syntax': [
-        ...INJECTED_RULES['no-restricted-syntax'],
+        ...ovr.INJECTED_RULES['no-restricted-syntax'],
         {
           selector: '[regex], NewExpression[callee.name="RegExp"]',
           message: 'RegExp internally depends on a *ton* of stuff that may be spoofed or broken',
@@ -139,50 +91,106 @@ module.exports = {
       'jest/globals': true,
     },
   }],
-  rules: {
-    'prettier/prettier': 'off',
-    // 'import/extensions': ['error', 'ignorePackages', {
-    //   js: 'never',
-    //   vue: 'never',
-    // }],
-    'no-use-before-define': ['error', {
-      'functions': false,
-      'classes': true,
-      'variables': true,
-      'allowNamedExports': true,
-    }],
-    // copied from airbnb-base, replaced 4 with 8
-    'object-curly-newline': ['error', {
-      ObjectExpression: { minProperties: 8, multiline: true, consistent: true },
-      ObjectPattern: { minProperties: 8, multiline: true, consistent: true },
-      ImportDeclaration: { minProperties: 8, multiline: true, consistent: true },
-      ExportDeclaration: { minProperties: 8, multiline: true, consistent: true },
-    }],
-  },
 };
 
-function getGlobals(path) {
-  const res = {};
-  const { ast } = readGlobalsFile(path, { ast: true });
-  ast.program.body.forEach(body => {
-    const { declarations } = body.declaration || body;
-    if (!declarations) return;
-    declarations.forEach(function processId({
-      id: {
-        left,
-        properties,
-        name = left && left.name,
-      },
-    }) {
-      if (name) {
-        // const NAME = whatever
-        // We consider `let` immutable too to avoid unintentional reassignment
-        res[name] = false;
-      } else if (properties) {
-        // const { NAME1, prototype: { NAME2: ALIAS2 } } = whatever
-        properties.forEach(({ value }) => processId({ id: value }));
-      }
+function makeOverrides() {
+  /* Note that `injected` uses several more `common` files indirectly, but we check just these
+   * two automatically because they are trivial by design and must always pass the check */
+  const GLOBALS_SHARED = getGlobals('*');
+  const GLOBALS_INJECTED = {
+    ...getGlobals('injected'),
+    PAGE_MODE_HANDSHAKE: false,
+    VAULT_ID: false,
+  };
+  function getGlobals(path) {
+    const res = {};
+    const { ast } = readGlobalsFile(path, { ast: true });
+    ast.program.body.forEach(body => {
+      const { declarations } = body.declaration || body;
+      if (!declarations) return;
+      declarations.forEach(function processId({
+        id: {
+          left,
+          properties,
+          name = left && left.name,
+        },
+      }) {
+        if (name) {
+          // const NAME = whatever
+          // We consider `let` immutable too to avoid unintentional reassignment
+          res[name] = false;
+        } else if (properties) {
+          // const { NAME1, prototype: { NAME2: ALIAS2 } } = whatever
+          properties.forEach(({ value }) => processId({ id: value }));
+        }
+      });
     });
-  });
-  return res;
+    return res;
+  }
+
+  return {
+    FILES_CONTENT: [
+      'src/injected/index.js',
+      'src/injected/content/**/*.js',
+    ],
+    FILES_INJECTED: [
+      'src/injected/**/*.js',
+    ],
+    FILES_SHARED: [
+      'src/common/browser.js',
+      'src/common/consts.js',
+      'src/common/safe-globals-shared.js',
+    ],
+    FILES_WEB: [
+      'src/injected/web/**/*.js',
+    ],
+    GLOBALS_INJECTED,
+    GLOBALS_SHARED,
+    GLOBALS_COMMON: {
+      ...GLOBALS_SHARED,
+      ...getGlobals('common'),
+      re: false, // transform-modern-regexp with useRe option
+    },
+    GLOBALS_CONTENT: {
+      INIT_FUNC_NAME: false,
+      ...GLOBALS_SHARED,
+      ...getGlobals('injected/content'),
+      ...GLOBALS_INJECTED,
+    },
+    GLOBALS_WEB: {
+      ...GLOBALS_SHARED,
+      ...getGlobals('injected/web'),
+      ...GLOBALS_INJECTED,
+      IS_FIREFOX: false, // passed as a parameter to VMInitInjection in webpack.conf.js
+    },
+    INJECTED_RULES: {
+      'no-restricted-imports': [
+        'error', {
+          patterns: ['*/common', '*/common/*'],
+        }
+      ],
+      'no-restricted-syntax': [
+        'error', {
+          selector: 'ObjectExpression > ExperimentalSpreadProperty',
+          message: 'Object spread adds a polyfill in injected* even if unused by it',
+        }, {
+          selector: 'ArrayPattern',
+          message: 'Destructuring via Symbol.iterator may be spoofed/broken in an unsafe environment',
+        }, {
+          selector: ':matches(ArrayExpression, CallExpression) > SpreadElement',
+          message: 'Spreading via Symbol.iterator may be spoofed/broken in an unsafe environment',
+        }, {
+          selector: '[callee.object.name="Object"], MemberExpression[object.name="Object"]',
+          message: 'Using potentially spoofed methods in an unsafe environment',
+          // TODO: auto-generate the rule using GLOBALS
+        }, {
+          selector: `CallExpression[callee.name="defineProperty"]:not(${[
+            '[arguments.2.properties.0.key.name="__proto__"]',
+            ':has(CallExpression[callee.name="nullObjFrom"])'
+          ].join(',')})`,
+          message: 'Prototype of descriptor may be spoofed/broken in an unsafe environment',
+        }
+      ],
+    },
+  };
 }

+ 1 - 1
scripts/transifex.mjs

@@ -291,7 +291,7 @@ async function batchHandle(handle, allowedLangs) {
       finished += 1;
       showProgress();
     } catch (err) {
-      process.stderr.write(`\nError pulling ${lang}\n`)
+      process.stderr.write(`\nError pulling ${lang}\n`);
       throw err;
     }
   }));

+ 1 - 1
src/background/utils/preinject.js

@@ -369,7 +369,7 @@ function prepareScript(script, env) {
       + '((define,module,exports)=>{');
   }
   for (const url of meta.require) {
-    const req = require[pathMap[url] || url]
+    const req = require[pathMap[url] || url];
     if (/\S/.test(req)) {
       injectedCode.push(req, NEWLINE_END_RE.test(req) ? ';' : '\n;');
       hasReqs = true;

+ 1 - 1
src/background/utils/script.js

@@ -183,7 +183,7 @@ function inferScriptSupportUrl(script, home = getScriptHome(script)) {
       github\.com
     )\/[^/]+\/[^/]+/x`);
   if (u) {
-    u = `${u[0]}/${u[1] ? 'feedback' : 'issues'}`
+    u = `${u[0]}/${u[1] ? 'feedback' : 'issues'}`;
     script[INFERRED][SUPPORT_URL] = u;
     return u;
   }

+ 1 - 1
src/common/ui/code-js-mixed-mode.js

@@ -136,7 +136,7 @@ CodeMirror.defineMode('javascript-mixed', (config) => {
       Object.defineProperty(this, 'text', { value, configurable: true });
       return value;
     }
-  }
+  };
 
   // a map of all rules, keyed by id/type for quick lookup during matching
   const rulesById = {};

+ 1 - 1
src/common/ui/code-trailing-spaces.js

@@ -11,7 +11,7 @@ if (!''.trimEnd) {
   // TODO: remove when min_chrome_version>=66, strict_min_version>=61
   String.prototype.trimEnd = function _() {
     return this.replace(/\s+$/, '');
-  }
+  };
 }
 
 export const killTrailingSpaces = (cm, placeholders) => {

+ 1 - 1
src/common/ui/message.vue

@@ -65,7 +65,7 @@ export default {
         return { title: text.slice(0, sep), desc: text.slice(sep + 2) };
       }
       return { title: text };
-    })
+    });
 
     onMounted(() => {
       if (refInput.value) {

+ 2 - 2
src/injected/content/inject.js

@@ -201,7 +201,7 @@ function triageScript(script) {
 
 function inject(item, iframeCb) {
   const { code } = item;
-  const isCodeArray = isObject(code)
+  const isCodeArray = isObject(code);
   const script = makeElem('script', !isCodeArray && code);
   // Firefox ignores sourceURL comment when a syntax error occurs so we'll print the name manually
   const onError = IS_FIREFOX && !iframeCb && (e => {
@@ -286,7 +286,7 @@ async function injectPageList(runAt) {
     if (scr.code) {
       if (runAt === 'idle') await nextTask();
       if (runAt === 'end') await 0;
-      tardyQueueCheck([scr])
+      tardyQueueCheck([scr]);
       // Exposing window.vmXXX setter just before running the script to avoid interception
       if (!scr.meta.unwrap) bridge.post('Plant', scr.key);
       inject(scr);