1376c2dee8
Audit-pass over CODE-AUDIT.md (~48 items closed this pass; all verified — typecheck + 234 tests + eslint + prettier green). Correctness / bugs: - B3: match the release checksum to the asset's filename line (no wrong-hash verify) - B4: newline-safe metadata probe (one --print with a unit-separator delimiter) - B5 / L88: guard the meta event against canceled items; progress no longer promotes a queued item outside pump() - B7: cookie-login promise always resolves (handles destroy-without-close) - L146: trim parser rejects >2 colon-group times; M36: Library selection counts only actionable rows - L11 / L50 / L156 / L57 / L159 / L15 / L3: live queue count, empty-cookie message, schedule picker min, dead-code/comment cleanup Type safety: - Enable noUncheckedIndexedAccess + noFallthroughCasesInSwitch (15 real edge cases fixed) Resilience / Windows / metadata: - R5: settings write failure handled (no unhandled IPC rejection; reconciles to truth) - W1 / W5 / W6: min window size, seeded folder picker, parented sign-in window; L147 dead macOS branches removed - CL1: shared stdout markers; package/builder metadata (license, homepage, repository, copyright, tsbuildinfo glob) Copy / docs / tests: - M37 / SR9 dev-jargon cleanup in hints; M8 / M25 / M26 / L66 / L80 / L81 reconciled - New unit tests for L35 (isValidMediaItem) and L36 (compareVersions) This commit also checkpoints the previously-uncommitted feat/tray-background-clipboard work it builds on: background running + auto-download, library clipboard detection, tray, binary management & library scale, credential encryption at rest, the shared jsonStore and ui/ primitives, and the eslint/prettier tooling. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
46 lines
1.8 KiB
TypeScript
46 lines
1.8 KiB
TypeScript
import { Menu, type WebContents, type MenuItemConstructorOptions } from 'electron'
|
|
|
|
/**
|
|
* Give editable fields (and any selected text) the standard Windows Cut / Copy /
|
|
* Paste / Select All right-click menu that Electron does not provide by default
|
|
* (W4) — plus spellcheck suggestions for text areas. The menu items use built-in
|
|
* roles, so the editing works directly in the sandboxed, context-isolated
|
|
* renderer without any extra IPC. Wired onto the main window only; the untrusted
|
|
* cookie sign-in window deliberately keeps its minimal chrome.
|
|
*/
|
|
export function attachEditContextMenu(wc: WebContents): void {
|
|
wc.on('context-menu', (_e, params) => {
|
|
const { isEditable, editFlags, selectionText, dictionarySuggestions } = params
|
|
// Only worth a menu over an editable field or a real text selection.
|
|
if (!isEditable && !selectionText.trim()) return
|
|
|
|
const template: MenuItemConstructorOptions[] = []
|
|
|
|
// Spellcheck suggestions first, when the caret sits on a misspelling.
|
|
if (isEditable && dictionarySuggestions.length > 0) {
|
|
for (const suggestion of dictionarySuggestions) {
|
|
template.push({ label: suggestion, click: () => wc.replaceMisspelling(suggestion) })
|
|
}
|
|
template.push({ type: 'separator' })
|
|
}
|
|
|
|
if (isEditable) {
|
|
template.push(
|
|
{ role: 'cut', enabled: editFlags.canCut },
|
|
{ role: 'copy', enabled: editFlags.canCopy },
|
|
{ role: 'paste', enabled: editFlags.canPaste },
|
|
{ type: 'separator' },
|
|
{ role: 'selectAll', enabled: editFlags.canSelectAll }
|
|
)
|
|
} else {
|
|
// Read-only text with a selection: offer Copy (and Select All).
|
|
template.push(
|
|
{ role: 'copy', enabled: editFlags.canCopy },
|
|
{ role: 'selectAll', enabled: editFlags.canSelectAll }
|
|
)
|
|
}
|
|
|
|
Menu.buildFromTemplate(template).popup()
|
|
})
|
|
}
|