fix(editor): can not undo and redo of color of edgeless blocks (#12414)

Close [BS-3507](https://linear.app/affine-design/issue/BS-3507/edgeless-text-颜色无法-undoredo)
Close [BS-3426](https://linear.app/affine-design/issue/BS-3426/frame-修改背景色后不能撤销)

This PR fixes the issue where the color change of edgeless blocks could not be undone/redone, including notes, edgeless-text, and frames. It also addresses the problem of a tiny shape being unexpectedly retained on the canvas. The key changes are:
- Removal of `transact` from the `pop` method of edgeless elements.
- Refactoring of `onPickColor` for all edgeless elements and blocks to better control the lifecycle of custom color property changes.
- Addition of the missing custom background color feature for notes.
- Addition of undo/redo color tests for notes, frames, and edgeless-text.

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Added undo and redo support for color changes in frames, notes, and text blocks, allowing users to revert or reapply background and text color modifications.

- **Bug Fixes**
  - Improved reliability of color picker interactions, ensuring consistent state management and transactional updates during color changes.

- **Tests**
  - Introduced new end-to-end tests to verify undo/redo functionality for color changes in frames, notes, and text blocks.

- **Refactor**
  - Streamlined color picker event handling for better maintainability and consistency across toolbars and style panels.
  - Updated style panel structure and event handling for improved interaction and state management.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
L-Sun
2025-05-22 04:10:16 +00:00
parent 9ac1da9fc1
commit 573c2faf76
11 changed files with 372 additions and 113 deletions

View File

@@ -6,7 +6,9 @@ import {
autoFit,
captureHistory,
cutByKeyboard,
dblclickView,
dragBetweenIndices,
edgelessCommonSetup,
enterPlaygroundRoom,
getEdgelessSelectedRect,
getPageSnapshot,
@@ -19,6 +21,7 @@ import {
pressBackspace,
pressEnter,
pressEscape,
redoByKeyboard,
selectAllByKeyboard,
setEdgelessTool,
switchEditorMode,
@@ -598,3 +601,62 @@ test('press backspace at the start of first line when edgeless text exist', asyn
`${testInfo.title}_finial.json`
);
});
test('undo/redo should work when changing text color', async ({ page }) => {
await edgelessCommonSetup(page);
await dblclickView(page, [100, 100]);
await type(page, 'abc');
await pressEscape(page, 3);
await waitNextFrame(page);
const edgelessText = page.locator('affine-edgeless-text');
await edgelessText.click();
const getTextColor = async () => {
return edgelessText.locator('span[data-v-text="true"]').evaluate(el => {
return getComputedStyle(el).color;
});
};
const colorPanel = page.locator('edgeless-color-picker-button');
let prevTextColor = await getTextColor();
// preset color
{
await colorPanel.click();
await colorPanel.getByLabel('LightRed').click();
expect(await getTextColor()).not.toBe(prevTextColor);
await undoByKeyboard(page);
await waitNextFrame(page);
expect(await getTextColor()).toBe(prevTextColor);
await redoByKeyboard(page);
await waitNextFrame(page);
expect(await getTextColor()).not.toBe(prevTextColor);
}
prevTextColor = await getTextColor();
// custom color
{
await colorPanel.click();
await colorPanel.locator('edgeless-color-custom-button').click();
await page.locator('.color-palette').click({
position: {
x: 100,
y: 100,
},
});
await pressEscape(page);
expect(await getTextColor()).not.toBe(prevTextColor);
await undoByKeyboard(page);
await waitNextFrame(page);
expect(await getTextColor()).toBe(prevTextColor);
await redoByKeyboard(page);
await waitNextFrame(page);
expect(await getTextColor()).not.toBe(prevTextColor);
}
});