feat(desktop): add edit popover apply-edit with optimistic preview + diff

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
程序员阿江(Relakkes) 2026-05-29 13:28:19 +08:00
parent 31359a9cd2
commit 14e7228e33
2 changed files with 31 additions and 0 deletions

View File

@ -0,0 +1,15 @@
import { describe, expect, it, beforeEach } from 'vitest'
import { applyEdit } from './popover'
beforeEach(() => { document.body.innerHTML = `<h1 id="t" style="color:rgb(0,0,0)">Old</h1>` })
describe('applyEdit', () => {
it('applies text + color to the live DOM and returns a diff', () => {
const el = document.getElementById('t')!
const diff = applyEdit(el, { text: 'New', color: 'rgb(255,0,0)' })
expect(el.textContent).toBe('New')
expect(el.style.color).toBe('rgb(255, 0, 0)')
expect(diff.text).toEqual({ from: 'Old', to: 'New' })
expect(diff.color?.to).toBe('rgb(255,0,0)')
})
})

View File

@ -0,0 +1,16 @@
export type EditInput = { text?: string; color?: string; background?: string; opacity?: string; fontFamily?: string }
export type EditDiff = {
text?: { from: string; to: string }; color?: { from: string; to: string }
background?: { from: string; to: string }; opacity?: { from: string; to: string }; fontFamily?: { from: string; to: string }
}
export function applyEdit(el: HTMLElement, input: EditInput): EditDiff {
const cs = window.getComputedStyle(el)
const diff: EditDiff = {}
if (input.text != null && input.text !== el.textContent) { diff.text = { from: el.textContent ?? '', to: input.text }; el.textContent = input.text }
if (input.color) { diff.color = { from: cs.color, to: input.color }; el.style.color = input.color }
if (input.background) { diff.background = { from: cs.backgroundColor, to: input.background }; el.style.background = input.background }
if (input.opacity) { diff.opacity = { from: cs.opacity, to: input.opacity }; el.style.opacity = input.opacity }
if (input.fontFamily) { diff.fontFamily = { from: cs.fontFamily, to: input.fontFamily }; el.style.fontFamily = input.fontFamily }
return diff
}