diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..2c2f69c --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,39 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "root": true, + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/recommended", + "prettier" + ], + "overrides": [], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["@typescript-eslint"], + "rules": { + "@typescript-eslint/ban-ts-comment": ["warn", "allow-with-description"], + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-explicit-any": ["off", { "ignoreRestArgs": true }], + "@typescript-eslint/no-non-null-assertion": "off" + }, + "ignorePatterns": [ + "**/dist/**", + "**/node_modules/**", + "**/abbrevIso*", + "**/example*", + "**/*.bak", + "coverage/**", + "docs-shared/lib/**", + "packages/*/assets/**", + "packages/*/lib/**", + "!.vuepress/**", + "**/.vuepress/.cache/**", + "**/.vuepress/.temp/**" + ] +} diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..94f480d --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..1d7ac85 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["dbaeumer.vscode-eslint", "esbenp.prettier-vscode"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json index dac8cca..2c524b2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,28 +1,22 @@ { - // 使用 IntelliSense 了解相关属性。 - // 悬停以查看现有属性的描述。 - // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "node", - "request": "launch", - "name": "Restart", - "runtimeExecutable": "npm", - "runtimeArgs": [ - "run", - "restart" - ], - }, - { - "type": "node", - "request": "launch", - "name": "Restart in Prod Mode", - "runtimeExecutable": "npm", - "runtimeArgs": [ - "run", - "restart-prod" - ], - } - ] -} \ No newline at end of file + // 使用 IntelliSense 了解相关属性。 + // 悬停以查看现有属性的描述。 + // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "launch", + "name": "Restart", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "restart"] + }, + { + "type": "node", + "request": "launch", + "name": "Restart in Prod Mode", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "restart-prod"] + } + ] +} diff --git a/.vscode/setting.json b/.vscode/setting.json new file mode 100644 index 0000000..fa49336 --- /dev/null +++ b/.vscode/setting.json @@ -0,0 +1,7 @@ +{ + "editor.formatOnType": false, + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.fixAll.eslint": true + } +} \ No newline at end of file diff --git a/.vscode/toolkit.code-snippets b/.vscode/toolkit.code-snippets index ab0b6da..425b7dd 100644 --- a/.vscode/toolkit.code-snippets +++ b/.vscode/toolkit.code-snippets @@ -1,45 +1,45 @@ { - "appendElement - full": { - "scope": "javascript,typescript", - "prefix": "appendElement", - "body": [ - "appendElement({", - "\ttag: '${1:div}',", - "\tid: '${2:id}',", - "\tnamespace: '${3:html}',", - "\tclassList: ['${4:class}'],", - "\tstyles: {${5:style}: '$6'},", - "\tproperties: {},", - "\tattributes: {},", - "\t[{ '${7:onload}', (e: Event) => $8, ${9:false} }],", - "\tcheckExistanceParent: ${10:HTMLElement},", - "\tignoreIfExists: ${11:true},", - "\tskipIfExists: ${12:true},", - "\tremoveIfExists: ${13:true},", - "\tcustomCheck: (doc: Document, options: ElementOptions) => ${14:true},", - "\tchildren: [$15]", - "}, ${16:container});" - ] - }, - "appendElement - minimum": { - "scope": "javascript,typescript", - "prefix": "appendElement", - "body": "appendElement({ tag: '$1' }, $2);" - }, - "register Notifier": { - "scope": "javascript,typescript", - "prefix": "registerObserver", - "body": [ - "registerObserver({", - "\t notify: (", - "\t\tevent: _ZoteroTypes.Notifier.Event,", - "\t\ttype: _ZoteroTypes.Notifier.Type,", - "\t\tids: string[],", - "\t\textraData: _ZoteroTypes.anyObj", - "\t) => {", - "\t\t$0", - "\t}", - "});" - ] - } + "appendElement - full": { + "scope": "javascript,typescript", + "prefix": "appendElement", + "body": [ + "appendElement({", + "\ttag: '${1:div}',", + "\tid: '${2:id}',", + "\tnamespace: '${3:html}',", + "\tclassList: ['${4:class}'],", + "\tstyles: {${5:style}: '$6'},", + "\tproperties: {},", + "\tattributes: {},", + "\t[{ '${7:onload}', (e: Event) => $8, ${9:false} }],", + "\tcheckExistanceParent: ${10:HTMLElement},", + "\tignoreIfExists: ${11:true},", + "\tskipIfExists: ${12:true},", + "\tremoveIfExists: ${13:true},", + "\tcustomCheck: (doc: Document, options: ElementOptions) => ${14:true},", + "\tchildren: [$15]", + "}, ${16:container});" + ] + }, + "appendElement - minimum": { + "scope": "javascript,typescript", + "prefix": "appendElement", + "body": "appendElement({ tag: '$1' }, $2);" + }, + "register Notifier": { + "scope": "javascript,typescript", + "prefix": "registerObserver", + "body": [ + "registerObserver({", + "\t notify: (", + "\t\tevent: _ZoteroTypes.Notifier.Event,", + "\t\ttype: _ZoteroTypes.Notifier.Type,", + "\t\tids: string[],", + "\t\textraData: _ZoteroTypes.anyObj", + "\t) => {", + "\t\t$0", + "\t}", + "});" + ] + } } diff --git a/addon/chrome/content/zoteroPane.css b/addon/chrome/content/zoteroPane.css index 8ab857d..8c95c1e 100644 --- a/addon/chrome/content/zoteroPane.css +++ b/addon/chrome/content/zoteroPane.css @@ -1,3 +1,3 @@ .makeItRed { - background-color: tomato; -} \ No newline at end of file + background-color: tomato; +} diff --git a/package.json b/package.json index 1ddaf46..e3e3715 100644 --- a/package.json +++ b/package.json @@ -24,7 +24,9 @@ "restart-prod": "npm run build-prod && npm run stop && npm run start", "restart": "npm run restart-dev", "release": "release-it", - "test": "echo \"Error: no test specified\" && exit 1" + "lint": "prettier --write . && eslint . --ext .ts --fix", + "test": "echo \"Error: no test specified\" && exit 1", + "update-deps": "npm update --save" }, "repository": { "type": "git", @@ -41,14 +43,22 @@ }, "devDependencies": { "@types/node": "^18.11.17", + "@typescript-eslint/eslint-plugin": "^5.59.1", + "@typescript-eslint/parser": "^5.59.1", "compressing": "^1.6.3", "concurrently": "^7.6.0", "cross-env": "^7.0.3", "esbuild": "^0.17.4", + "eslint": "^8.39.0", + "eslint-config-prettier": "^8.8.0", "minimist": "^1.2.7", + "prettier": "2.8.8", "release-it": "^15.6.0", "replace-in-file": "^6.3.5", "typescript": "^4.9.4", "zotero-types": "^1.0.12" + }, + "prettier": { + "tabWidth": 2 } } diff --git a/scripts/zotero-cmd-default.json b/scripts/zotero-cmd-default.json index 9bb8011..743b1d9 100644 --- a/scripts/zotero-cmd-default.json +++ b/scripts/zotero-cmd-default.json @@ -6,4 +6,4 @@ "6": "/path/to/zotero6.exe", "7": "/path/to/zotero7.exe" } -} \ No newline at end of file +} diff --git a/src/addon.ts b/src/addon.ts index bf24463..d26c77f 100644 --- a/src/addon.ts +++ b/src/addon.ts @@ -21,7 +21,7 @@ class Addon { // Lifecycle hooks public hooks: typeof hooks; // APIs - public api: {}; + public api: object; constructor() { this.data = { diff --git a/src/modules/locale.ts b/src/modules/locale.ts index 64c221d..09034d8 100644 --- a/src/modules/locale.ts +++ b/src/modules/locale.ts @@ -8,10 +8,7 @@ export function initLocale() { }; } -export function getString( - localString: string, - noReload: boolean = false -): string { +export function getString(localString: string, noReload = false): string { try { return addon.data.locale?.stringBundle.GetStringFromName(localString); } catch (e) { diff --git a/src/modules/preferenceScript.ts b/src/modules/preferenceScript.ts index 5ed7d23..292ee77 100644 --- a/src/modules/preferenceScript.ts +++ b/src/modules/preferenceScript.ts @@ -46,7 +46,8 @@ async function updatePrefsUI() { // with addon.data.prefs.window.document // Or bind some events to the elements const renderLock = ztoolkit.getGlobal("Zotero").Promise.defer(); - const tableHelper = new ztoolkit.VirtualizedTable(addon.data.prefs?.window!) + if (addon.data.prefs?.window == undefined) return; + const tableHelper = new ztoolkit.VirtualizedTable(addon.data.prefs?.window) .setContainerId(`${config.addonRef}-table-container`) .setProp({ id: `${config.addonRef}-prefs-table`, @@ -122,7 +123,7 @@ function bindPrefEvents() { }); addon.data - .prefs!!.window.document.querySelector( + .prefs!.window.document.querySelector( `#zotero-prefpane-${config.addonRef}-input` ) ?.addEventListener("change", (e) => {