From 14e7228e339d252299e951c9e55741b89a454e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Fri, 29 May 2026 13:28:19 +0800 Subject: [PATCH] feat(desktop): add edit popover apply-edit with optimistic preview + diff Co-Authored-By: Claude Sonnet 4.6 --- desktop/src/preview-agent/popover.test.ts | 15 +++++++++++++++ desktop/src/preview-agent/popover.ts | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 desktop/src/preview-agent/popover.test.ts create mode 100644 desktop/src/preview-agent/popover.ts diff --git a/desktop/src/preview-agent/popover.test.ts b/desktop/src/preview-agent/popover.test.ts new file mode 100644 index 00000000..f4557995 --- /dev/null +++ b/desktop/src/preview-agent/popover.test.ts @@ -0,0 +1,15 @@ +import { describe, expect, it, beforeEach } from 'vitest' +import { applyEdit } from './popover' + +beforeEach(() => { document.body.innerHTML = `

Old

` }) + +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)') + }) +}) diff --git a/desktop/src/preview-agent/popover.ts b/desktop/src/preview-agent/popover.ts new file mode 100644 index 00000000..35c2fe7d --- /dev/null +++ b/desktop/src/preview-agent/popover.ts @@ -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 +}