chore: 对齐 Obsidian ESLint 并提升最低应用版本至 1.8.7

- 同步 manifest 与 versions.json,满足当前代码所用 API(含 getLanguage)

- DOM 与 Electron 路径改用 activeDocument,导出与模态框使用 createEl/createDiv

- 文案语言解析改用 getLanguage(),清理未使用代码与未使用参数

- 在 ESLint 中声明 activeDocument/activeWindow 全局

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
熊猫别熬夜 2026-05-16 09:52:31 +08:00
parent 2f1f00b78b
commit b0121f1817
7 changed files with 20 additions and 30 deletions

View file

@ -8,6 +8,8 @@ export default tseslint.config(
languageOptions: {
globals: {
...globals.browser,
activeDocument: "readonly",
activeWindow: "readonly",
},
parserOptions: {
projectService: {

View file

@ -2,7 +2,7 @@
"id": "password-manager",
"name": "Password Manager",
"version": "1.0.9",
"minAppVersion": "0.15.0",
"minAppVersion": "1.8.7",
"description": "A lightweight local password manager with encryption, backup, trash, and import/export support.",
"author": "PandaNocturne",
"authorUrl": "https://github.com/PandaNocturne",

View file

@ -43,10 +43,6 @@ function matchLookupKey(value: string, aliases: readonly string[]) {
return aliases.some((alias) => normalizeLookupKey(alias) === normalized);
}
function getMarkdownFieldLabel(key: keyof typeof MARKDOWN_FIELD_LABELS) {
return MARKDOWN_FIELD_LABELS[key][0];
}
function parseMarkdownFieldLabel(label: string) {
if (matchLookupKey(label, MARKDOWN_FIELD_LABELS.username)) {
return 'username';
@ -378,9 +374,9 @@ export function parseImportPayload(text: string): PasswordManagerExportPayload {
export function downloadText(filename: string, content: string, mimeType: string) {
const blob = new Blob([content], { type: mimeType });
const url = URL.createObjectURL(blob);
const anchor = document.createElement('a');
anchor.href = url;
anchor.download = filename;
const anchor = activeDocument.body.createEl('a', {
attr: { href: url, download: filename },
});
anchor.click();
URL.revokeObjectURL(url);
}
@ -538,7 +534,7 @@ export function parseCsvGroup(text: string) {
};
}
export function parseMarkdownItems(text: string, data: PasswordManagerData, defaultGroupId: string) {
export function parseMarkdownItems(text: string, _data: PasswordManagerData, _defaultGroupId: string) {
const groupedItems = parseGroupedMarkdownGroups(text)
.flatMap((group) => group.items)
.filter((item) => item.title || item.username || item.password || item.urls?.length || item.notes);

View file

@ -1,14 +1,11 @@
import { getLanguage } from 'obsidian';
import { PWM_TEXT as EN_TEXT } from './en';
import { PWM_TEXT as ZH_CN_TEXT } from './zh-cn';
type PwmText = typeof EN_TEXT;
const resolveLocale = () => {
const language = (
globalThis.localStorage?.getItem('language')
|| globalThis.navigator?.language
|| 'zh-CN'
).toLowerCase();
const language = getLanguage().toLowerCase();
if (language.startsWith('en')) {
return 'en';

View file

@ -359,15 +359,11 @@ export class PasswordEncryptionService {
await adapter.mkdir(path).catch(() => undefined);
const absolutePath = `${adapter.getBasePath()}/${path}`.replace(/[/\\]+/g, '/');
const electronWindow = window as Window & {
type WindowWithElectronRequire = Window & {
require?: (module: string) => unknown;
};
const electronGlobal = globalThis as typeof globalThis & {
require?: (module: string) => unknown;
};
const electronModule =
(electronWindow.require?.('electron') as ElectronShellModule | undefined) ??
(electronGlobal.require?.('electron') as ElectronShellModule | undefined);
const scopedWindow = activeDocument.defaultView as WindowWithElectronRequire | null;
const electronModule = scopedWindow?.require?.('electron') as ElectronShellModule | undefined;
const shell = electronModule?.shell;
const opened = shell ? await shell.openPath(absolutePath) : undefined;
if (opened === '') {

View file

@ -304,7 +304,7 @@ export class PasswordManagerModal extends Modal {
const minDetailWidth = 340;
handle.addClass('is-resizing');
document.body.addClass('pwm-column-resizing');
activeDocument.body.addClass('pwm-column-resizing');
handle.setPointerCapture(pointerId);
const updateWidths = (clientX: number) => {
@ -334,7 +334,7 @@ export class PasswordManagerModal extends Modal {
const finishResize = () => {
handle.removeClass('is-resizing');
document.body.removeClass('pwm-column-resizing');
activeDocument.body.removeClass('pwm-column-resizing');
handle.removeEventListener('pointermove', onPointerMove);
handle.removeEventListener('pointerup', onPointerUp);
handle.removeEventListener('pointercancel', onPointerCancel);
@ -373,7 +373,7 @@ export class PasswordManagerModal extends Modal {
handle.releasePointerCapture(pointerId);
}
handle.removeClass('is-resizing');
document.body.removeClass('pwm-column-resizing');
activeDocument.body.removeClass('pwm-column-resizing');
handle.removeEventListener('pointermove', onPointerMove);
handle.removeEventListener('pointerup', onPointerUp);
handle.removeEventListener('pointercancel', onPointerCancel);
@ -458,8 +458,9 @@ export class PasswordManagerModal extends Modal {
titleContainer.addClass('pwm-modal-title-row');
if (!this.titleCountEl) {
this.titleCountEl = document.createElement('div');
this.titleCountEl.addClass('pwm-badge', 'pwm-modal-title-count');
this.titleCountEl = titleContainer.createDiv({
cls: ['pwm-badge', 'pwm-modal-title-count'],
});
this.titleEl.insertAdjacentElement('afterend', this.titleCountEl);
}
@ -2048,9 +2049,7 @@ export class PasswordManagerModal extends Modal {
}
private handleImport(importer: (text: string) => void | Promise<void>, accept = 'application/json,.json'): Promise<void> {
const input = document.createElement('input');
input.type = 'file';
input.accept = accept;
const input = this.contentEl.createEl('input', { type: 'file', attr: { accept } });
return new Promise<void>((resolve, reject) => {
input.addEventListener('change', () => {
void (async () => {

View file

@ -2,5 +2,5 @@
"1.0.0": "0.15.0",
"1.0.7": "0.15.0",
"1.0.8": "0.15.0",
"1.0.9": "0.15.0"
"1.0.9": "1.8.7"
}