diff --git a/.eslintrc.json b/.eslintrc.json index 24ac057..bd779ad 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -17,7 +17,15 @@ }, "plugins": ["@typescript-eslint"], "rules": { - "@typescript-eslint/ban-ts-comment": ["warn", "allow-with-description"], + "@typescript-eslint/ban-ts-comment": [ + "warn", + { + "ts-expect-error": "allow-with-description", + "ts-ignore": "allow-with-description", + "ts-nocheck": "allow-with-description", + "ts-check": "allow-with-description" + } + ], "@typescript-eslint/no-unused-vars": "off", "@typescript-eslint/no-explicit-any": ["off", { "ignoreRestArgs": true }], "@typescript-eslint/no-non-null-assertion": "off" diff --git a/README.md b/README.md index 679467a..05ef05a 100644 --- a/README.md +++ b/README.md @@ -143,7 +143,7 @@ This is also how your plugin will be released and used by others.
💡 Start with GitHub Codespace -*GitHub CodeSpace* enables you getting started without the need to download code/IDE/dependencies locally. +_GitHub CodeSpace_ enables you getting started without the need to download code/IDE/dependencies locally. Replace the steps above and build you first plugin in 30 seconds! diff --git a/addon/bootstrap.js b/addon/bootstrap.js index 473c446..05bc161 100644 --- a/addon/bootstrap.js +++ b/addon/bootstrap.js @@ -51,7 +51,7 @@ async function waitForZotero() { resolve(); } }, - false + false, ); }, }; @@ -92,7 +92,7 @@ async function startup({ id, version, resourceURI, rootURI }, reason) { Services.scriptloader.loadSubScript( `${rootURI}/chrome/content/scripts/index.js`, - ctx + ctx, ); } @@ -102,7 +102,7 @@ function shutdown({ id, version, resourceURI, rootURI }, reason) { } if (typeof Zotero === "undefined") { Zotero = Components.classes["@zotero.org/Zotero;1"].getService( - Components.interfaces.nsISupports + Components.interfaces.nsISupports, ).wrappedJSObject; } Zotero.__addonInstance__.hooks.onShutdown(); diff --git a/package.json b/package.json index 2415eac..a1f5348 100644 --- a/package.json +++ b/package.json @@ -41,23 +41,23 @@ }, "homepage": "https://github.com/windingwind/zotero-addon-template#readme", "dependencies": { - "zotero-plugin-toolkit": "^2.1.3" + "zotero-plugin-toolkit": "^2.1.5" }, "devDependencies": { - "@types/node": "^20.1.1", + "@types/node": "^20.4.2", "@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/parser": "^6.0.0", "chokidar-cli": "^3.0.0", "compressing": "^1.9.0", - "concurrently": "^8.0.1", + "concurrently": "^8.2.0", "cross-env": "^7.0.3", - "esbuild": "^0.18.1", - "eslint": "^8.40.0", + "esbuild": "^0.18.12", + "eslint": "^8.44.0", "eslint-config-prettier": "^8.8.0", - "prettier": "3.0.0", + "prettier": "^3.0.0", "release-it": "^16.1.0", "replace-in-file": "^6.3.5", - "typescript": "^5.0.4", - "zotero-types": "^1.0.14" + "typescript": "^5.1.6", + "zotero-types": "^1.0.16" } -} \ No newline at end of file +} diff --git a/scripts/build.mjs b/scripts/build.mjs index 19b96a5..4bb4c7b 100644 --- a/scripts/build.mjs +++ b/scripts/build.mjs @@ -81,7 +81,7 @@ function dateFormat(fmt, date) { if (ret) { fmt = fmt.replace( ret[1], - ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0") + ret[1].length == 1 ? opt[k] : opt[k].padStart(ret[1].length, "0"), ); } } @@ -106,7 +106,7 @@ function renameLocaleFiles() { if (localeSubFile.endsWith(".ftl")) { renameSync( path.join(localeSubDir, localeSubFile), - path.join(localeSubDir, `${config.addonRef}-${localeSubFile}`) + path.join(localeSubDir, `${config.addonRef}-${localeSubFile}`), ); } } @@ -124,7 +124,7 @@ function replaceString() { const replaceTo = [author, description, homepage, version, buildTime]; replaceFrom.push( - ...Object.keys(config).map((k) => new RegExp(`__${k}__`, "g")) + ...Object.keys(config).map((k) => new RegExp(`__${k}__`, "g")), ); replaceTo.push(...Object.values(config)); @@ -154,7 +154,7 @@ function replaceString() { const prefixedLines = lines.map((line) => { // https://regex101.com/r/lQ9x5p/1 const match = line.match( - /^(?[a-zA-Z]\S*)([ ]*=[ ]*)(?.*)$/m + /^(?[a-zA-Z]\S*)([ ]*=[ ]*)(?.*)$/m, ); if (match) { localeMessage.add(match.groups.message); @@ -175,7 +175,7 @@ function replaceString() { if (localeMessage.has(match[2])) { input = input.replace( match[0], - `${match[1]}="${config.addonRef}-${match[2]}"` + `${match[1]}="${config.addonRef}-${match[2]}"`, ); } else { localeMessageMiss.add(match[2]); @@ -191,14 +191,14 @@ function replaceString() { .filter((f) => f.hasChanged) .map((f) => `${f.file} : ${f.numReplacements} / ${f.numMatches}`), replaceResultFlt.filter((f) => f.hasChanged).map((f) => `${f.file} : OK`), - replaceResultXhtml.filter((f) => f.hasChanged).map((f) => `${f.file} : OK`) + replaceResultXhtml.filter((f) => f.hasChanged).map((f) => `${f.file} : OK`), ); if (localeMessageMiss.size !== 0) { console.warn( `[Build] [Warn] Fluent message [${new Array( - ...localeMessageMiss - )}] do not exsit in addon's locale files.` + ...localeMessageMiss, + )}] do not exsit in addon's locale files.`, ); } } @@ -221,7 +221,7 @@ async function main() { console.log( `[Build] BUILD_DIR=${buildDir}, VERSION=${version}, BUILD_TIME=${buildTime}, ENV=${[ env.NODE_ENV, - ]}` + ]}`, ); clearFolder(buildDir); @@ -248,12 +248,12 @@ async function main() { path.join(buildDir, `${name}.xpi`), { ignoreBase: true, - } + }, ); console.log("[Build] Addon pack OK"); console.log( - `[Build] Finished in ${(new Date().getTime() - t.getTime()) / 1000} s.` + `[Build] Finished in ${(new Date().getTime() - t.getTime()) / 1000} s.`, ); } diff --git a/scripts/start.mjs b/scripts/start.mjs index 268d160..3b2cc32 100644 --- a/scripts/start.mjs +++ b/scripts/start.mjs @@ -1,7 +1,7 @@ import { execSync } from "child_process"; import { exit } from "process"; import { existsSync, writeFileSync, readFileSync } from "fs"; -import path from "path" +import path from "path"; import details from "../package.json" assert { type: "json" }; import cmd from "./zotero-cmd.json" assert { type: "json" }; @@ -21,7 +21,7 @@ if (existsSync(profilePath)) { console.log( `[info] Addon proxy file has been updated. \n File path: ${addonProxyFilePath} \n - Addon path: ${buildPath} \n` + Addon path: ${buildPath} \n`, ); } diff --git a/src/hooks.ts b/src/hooks.ts index 9efa694..82e793c 100644 --- a/src/hooks.ts +++ b/src/hooks.ts @@ -18,7 +18,7 @@ async function onStartup() { initLocale(); ztoolkit.ProgressWindow.setIconURI( "default", - `chrome://${config.addonRef}/content/icons/favicon.png` + `chrome://${config.addonRef}/content/icons/favicon.png`, ); const popupWin = new ztoolkit.ProgressWindow(config.addonName, { @@ -97,7 +97,7 @@ async function onNotify( event: string, type: string, ids: Array, - extraData: { [key: string]: any } + extraData: { [key: string]: any }, ) { // You can add your code to the corresponding notify type ztoolkit.log("notify", event, type, ids, extraData); diff --git a/src/modules/examples.ts b/src/modules/examples.ts index eac6f18..79ea9cd 100644 --- a/src/modules/examples.ts +++ b/src/modules/examples.ts @@ -4,7 +4,7 @@ import { getString } from "../utils/locale"; function example( target: any, propertyKey: string | symbol, - descriptor: PropertyDescriptor + descriptor: PropertyDescriptor, ) { const original = descriptor.value; descriptor.value = function (...args: any) { @@ -27,7 +27,7 @@ export class BasicExampleFactory { event: string, type: string, ids: number[] | string[], - extraData: { [key: string]: any } + extraData: { [key: string]: any }, ) => { if (!addon?.data.alive) { this.unregisterNotifier(notifierID); @@ -50,7 +50,7 @@ export class BasicExampleFactory { (e: Event) => { this.unregisterNotifier(notifierID); }, - false + false, ); } @@ -175,7 +175,7 @@ export class KeyExampleFactory { "Conflicting:", conflictingGroups, "All keys:", - ztoolkit.Shortcut.getAll() + ztoolkit.Shortcut.getAll(), ); } } @@ -226,8 +226,8 @@ export class UIExampleFactory { }, "before", document.querySelector( - "#zotero-itemmenu-addontemplate-test" - ) as XUL.MenuItem + "#zotero-itemmenu-addontemplate-test", + ) as XUL.MenuItem, ); } @@ -253,13 +253,13 @@ export class UIExampleFactory { field: string, unformatted: boolean, includeBaseMapped: boolean, - item: Zotero.Item + item: Zotero.Item, ) => { return field + String(item.id); }, { iconPath: "chrome://zotero/skin/cross.png", - } + }, ); } @@ -272,7 +272,7 @@ export class UIExampleFactory { field: string, unformatted: boolean, includeBaseMapped: boolean, - item: Zotero.Item + item: Zotero.Item, ) => { return String(item.id); }, @@ -280,13 +280,13 @@ export class UIExampleFactory { renderCellHook(index, data, column) { const span = document.createElementNS( "http://www.w3.org/1999/xhtml", - "span" + "span", ); span.style.background = "#0dd068"; span.innerText = "⭐" + data; return span; }, - } + }, ); } @@ -300,7 +300,7 @@ export class UIExampleFactory { span.style.background = "rgb(30, 30, 30)"; span.style.color = "rgb(156, 220, 240)"; return span; - } + }, ); await ztoolkit.ItemTree.refresh(); } @@ -322,12 +322,12 @@ export class UIExampleFactory { ztoolkit.ExtraField.setExtraField( item, "itemBoxFieldEditable", - value + value, ); return true; }, index: 1, - } + }, ); await ztoolkit.ItemBox.register( @@ -341,7 +341,7 @@ export class UIExampleFactory { { editable: false, index: 2, - } + }, ); } @@ -385,7 +385,7 @@ export class UIExampleFactory { }, { targetIndex: 1, - } + }, ); } @@ -397,11 +397,11 @@ export class UIExampleFactory { panel: XUL.TabPanel | undefined, deck: XUL.Deck, win: Window, - reader: _ZoteroTypes.ReaderInstance + reader: _ZoteroTypes.ReaderInstance, ) => { if (!panel) { ztoolkit.log( - "This reader do not have right-side bar. Adding reader tab skipped." + "This reader do not have right-side bar. Adding reader tab skipped.", ); return; } @@ -457,7 +457,7 @@ export class UIExampleFactory { }, { targetIndex: 1, - } + }, ); } } @@ -501,7 +501,7 @@ export class PromptExampleFactory { const publicationTitle = item.getField( "publicationTitle", false, - true + true, ); if (publicationTitle) { nodes.push(`${publicationTitle}`); @@ -558,7 +558,7 @@ export class PromptExampleFactory { s.addCondition("itemType", "isNot", "attachment"); let ids = await s.search(); // prompt.exit will remove current container element. - // @ts-ignore + // @ts-ignore ignore prompt.exit(); const container = prompt.createCommandsContainer(); container.classList.add("suggestions"); @@ -593,12 +593,12 @@ export class PromptExampleFactory { s.addCondition( "joinMode", joinMode as Zotero.Search.Operator, - "" + "", ); s.addCondition( conditions[0] as string, conditions[1] as Zotero.Search.Operator, - conditions[2] as string + conditions[2] as string, ); } }); @@ -619,7 +619,7 @@ export class PromptExampleFactory { { type: "mousemove", listener: function () { - // @ts-ignore + // @ts-ignore ignore prompt.selectItem(this); }, }, @@ -666,7 +666,7 @@ export class PromptExampleFactory { container.appendChild(ele); }); } else { - // @ts-ignore + // @ts-ignore ignore prompt.exit(); prompt.showTip("Not Found."); } @@ -693,9 +693,9 @@ export class PromptExampleFactory { `You select ${items.length} items!\n\n${items .map( (item, index) => - String(index + 1) + ". " + item.getDisplayTitle() + String(index + 1) + ". " + item.getDisplayTitle(), ) - .join("\n")}` + .join("\n")}`, ); }, }, @@ -757,7 +757,7 @@ export class HelperExampleFactory { }, properties: { label: "Cell 1,0" }, }, - false + false, ) .addCell(4, 0, { tag: "label", @@ -780,7 +780,7 @@ export class HelperExampleFactory { type: "text", }, }, - false + false, ) .addCell(5, 0, { tag: "h2", @@ -815,7 +815,7 @@ export class HelperExampleFactory { }, ], }, - false + false, ) .addCell( 7, @@ -846,7 +846,7 @@ export class HelperExampleFactory { }, ], }, - false + false, ) .addCell( 8, @@ -877,7 +877,7 @@ export class HelperExampleFactory { }, ], }, - false + false, ) .addCell( 9, @@ -908,7 +908,7 @@ export class HelperExampleFactory { }, ], }, - false + false, ) .addButton("Confirm", "confirm") .addButton("Cancel", "cancel") @@ -916,7 +916,7 @@ export class HelperExampleFactory { noClose: true, callback: (e) => { dialogHelper.window?.alert( - "Help Clicked! Dialog will not be closed." + "Help Clicked! Dialog will not be closed.", ); }, }) @@ -927,7 +927,7 @@ export class HelperExampleFactory { addon.data.dialog = undefined; addon.data.alive && ztoolkit.getGlobal("alert")( - `Close dialog with ${dialogData._lastButtonId}.\nCheckbox: ${dialogData.checkboxValue}\nInput: ${dialogData.inputValue}.` + `Close dialog with ${dialogData._lastButtonId}.\nCheckbox: ${dialogData.checkboxValue}\nInput: ${dialogData.inputValue}.`, ); ztoolkit.log(dialogData); } @@ -937,11 +937,11 @@ export class HelperExampleFactory { new ztoolkit.Clipboard() .addText( "![Plugin Template](https://github.com/windingwind/zotero-plugin-template)", - "text/unicode" + "text/unicode", ) .addText( 'Plugin Template', - "text/html" + "text/html", ) .copy(); ztoolkit.getGlobal("alert")("Copied!"); @@ -956,7 +956,7 @@ export class HelperExampleFactory { ["PNG File(*.png)", "*.png"], ["Any", "*.*"], ], - "image.png" + "image.png", ).open(); ztoolkit.getGlobal("alert")(`Selected ${path}`); } diff --git a/src/modules/preferenceScript.ts b/src/modules/preferenceScript.ts index 122d059..ef6e5b9 100644 --- a/src/modules/preferenceScript.ts +++ b/src/modules/preferenceScript.ts @@ -66,7 +66,7 @@ async function updatePrefsUI() { addon.data.prefs?.rows[index] || { title: "no data", detail: "no data", - } + }, ) // Show a progress window when selection changes .setProp("onSelectionChange", (selection) => { @@ -86,7 +86,7 @@ async function updatePrefsUI() { if (event.key == "Delete" || (Zotero.isMac && event.key == "Backspace")) { addon.data.prefs!.rows = addon.data.prefs?.rows.filter( - (v, i) => !tableHelper.treeInstance.selection.isSelected(i) + (v, i) => !tableHelper.treeInstance.selection.isSelected(i), ) || []; tableHelper.render(); return false; @@ -96,7 +96,7 @@ async function updatePrefsUI() { // For find-as-you-type .setProp( "getRowString", - (index) => addon.data.prefs?.rows[index].title || "" + (index) => addon.data.prefs?.rows[index].title || "", ) // Render the table. .render(-1, () => { @@ -109,23 +109,23 @@ async function updatePrefsUI() { function bindPrefEvents() { addon.data .prefs!.window.document.querySelector( - `#zotero-prefpane-${config.addonRef}-enable` + `#zotero-prefpane-${config.addonRef}-enable`, ) ?.addEventListener("command", (e) => { ztoolkit.log(e); addon.data.prefs!.window.alert( - `Successfully changed to ${(e.target as XUL.Checkbox).checked}!` + `Successfully changed to ${(e.target as XUL.Checkbox).checked}!`, ); }); addon.data .prefs!.window.document.querySelector( - `#zotero-prefpane-${config.addonRef}-input` + `#zotero-prefpane-${config.addonRef}-input`, ) ?.addEventListener("change", (e) => { ztoolkit.log(e); addon.data.prefs!.window.alert( - `Successfully changed to ${(e.target as HTMLInputElement).value}!` + `Successfully changed to ${(e.target as HTMLInputElement).value}!`, ); }); } diff --git a/src/utils/locale.ts b/src/utils/locale.ts index 2642675..f47734c 100644 --- a/src/utils/locale.ts +++ b/src/utils/locale.ts @@ -43,7 +43,7 @@ function getString(localString: string): string; function getString(localString: string, branch: string): string; function getString( localString: string, - options: { branch?: string | undefined; args?: Record } + options: { branch?: string | undefined; args?: Record }, ): string; function getString(...inputs: any[]) { if (inputs.length === 1) { @@ -61,7 +61,7 @@ function getString(...inputs: any[]) { function _getString( localString: string, - options: { branch?: string | undefined; args?: Record } = {} + options: { branch?: string | undefined; args?: Record } = {}, ): string { const localStringWithPrefix = `${config.addonRef}-${localString}`; const { branch, args } = options; diff --git a/src/utils/wait.ts b/src/utils/wait.ts index 604237f..5d2e765 100644 --- a/src/utils/wait.ts +++ b/src/utils/wait.ts @@ -10,7 +10,7 @@ export function waitUntil( condition: () => boolean, callback: () => void, interval = 100, - timeout = 10000 + timeout = 10000, ) { const start = Date.now(); const intervalId = ztoolkit.getGlobal("setInterval")(() => { @@ -32,7 +32,7 @@ export function waitUntil( export function waitUtilAsync( condition: () => boolean, interval = 100, - timeout = 10000 + timeout = 10000, ) { return new Promise((resolve, reject) => { const start = Date.now();