mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-02-14 05:14:54 +00:00
feat(editor): add highlighter (#10573)
Closes: [BS-2909](https://linear.app/affine-design/issue/BS-2909/新增highlighter) ### What's Changed! Currently the highlighter tool is very similar to brush, but for the future, it's a standalone module. * Added `Highlighter` element model * Added `Highlighter` tool * Added `Highlighter` entry to the global toolbar
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import { test } from '@affine-test/kit/playwright';
|
||||
import {
|
||||
clickEdgelessModeButton,
|
||||
clickView,
|
||||
dragView,
|
||||
locateEditorContainer,
|
||||
locateToolbar,
|
||||
setEdgelessTool,
|
||||
} from '@affine-test/kit/utils/editor';
|
||||
import { openHomePage } from '@affine-test/kit/utils/load-page';
|
||||
import {
|
||||
clickNewPageButton,
|
||||
waitForEditorLoad,
|
||||
} from '@affine-test/kit/utils/page-logic';
|
||||
import { expect } from '@playwright/test';
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await openHomePage(page);
|
||||
await waitForEditorLoad(page);
|
||||
await clickNewPageButton(page);
|
||||
await clickEdgelessModeButton(page);
|
||||
const container = locateEditorContainer(page);
|
||||
await container.click();
|
||||
});
|
||||
|
||||
test('should add highlighter', async ({ page }) => {
|
||||
await setEdgelessTool(page, 'highlighter');
|
||||
await dragView(page, [100, 300], [200, 400]);
|
||||
|
||||
await setEdgelessTool(page, 'default');
|
||||
await clickView(page, [150, 350]);
|
||||
|
||||
const toolbar = locateToolbar(page);
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
|
||||
await expect(toolbar).toBeVisible();
|
||||
|
||||
const lineWidthButton = toolbar
|
||||
.locator('.line-width-button[data-selected]')
|
||||
.last();
|
||||
const defaultLineWidth = await lineWidthButton.getAttribute('aria-label');
|
||||
|
||||
expect(defaultLineWidth).toBe('22');
|
||||
});
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
dblclickView,
|
||||
dragView,
|
||||
locateEditorContainer,
|
||||
locateToolbar,
|
||||
setEdgelessTool,
|
||||
} from '@affine-test/kit/utils/editor';
|
||||
import { openHomePage } from '@affine-test/kit/utils/load-page';
|
||||
@@ -35,7 +36,7 @@ test('should add text to shape, default to pure black', async ({ page }) => {
|
||||
await page.keyboard.type('text');
|
||||
await page.keyboard.press('Escape');
|
||||
|
||||
const toolbar = page.locator('affine-toolbar-widget editor-toolbar');
|
||||
const toolbar = locateToolbar(page);
|
||||
const textColorContainer = toolbar.locator(
|
||||
'edgeless-color-picker-button.text-color'
|
||||
);
|
||||
@@ -74,7 +75,7 @@ test('should add text to shape with pure white', async ({ page }) => {
|
||||
await page.keyboard.type('text');
|
||||
await page.keyboard.press('Escape');
|
||||
|
||||
const toolbar = page.locator('affine-toolbar-widget editor-toolbar');
|
||||
const toolbar = locateToolbar(page);
|
||||
const textColorContainer = toolbar.locator(
|
||||
'edgeless-color-picker-button.text-color'
|
||||
);
|
||||
|
||||
@@ -35,11 +35,12 @@ test('change editor mode when brush color palette opening', async ({
|
||||
await switchEditorMode(page);
|
||||
await setEdgelessTool(page, 'brush');
|
||||
|
||||
const brushMenu = page.locator('edgeless-brush-menu');
|
||||
await expect(brushMenu).toBeVisible();
|
||||
const penMenu = page.locator('edgeless-pen-menu');
|
||||
const colorPalettes = penMenu.locator('edgeless-color-panel');
|
||||
await expect(colorPalettes).toBeVisible();
|
||||
|
||||
await switchEditorMode(page);
|
||||
await expect(brushMenu).toBeHidden();
|
||||
await expect(colorPalettes).toBeHidden();
|
||||
});
|
||||
|
||||
test('add brush element', async ({ page }) => {
|
||||
@@ -118,7 +119,8 @@ test('keep same color when mouse mode switched back to brush', async ({
|
||||
await assertEdgelessColorSameWithHexColor(page, color, pickedColor);
|
||||
});
|
||||
|
||||
test('add brush element with different size', async ({ page }) => {
|
||||
// TODO(@fundon): should add it back?
|
||||
test.skip('add brush element with different size', async ({ page }) => {
|
||||
await enterPlaygroundRoom(page);
|
||||
await initEmptyEdgelessState(page);
|
||||
await switchEditorMode(page);
|
||||
|
||||
@@ -55,7 +55,7 @@ test('shortcut', async ({ page }) => {
|
||||
await expect(shapeButton).toHaveAttribute('active', '');
|
||||
|
||||
await page.keyboard.press('p');
|
||||
const penButton = await locatorEdgelessToolButton(page, 'brush');
|
||||
const penButton = await locatorEdgelessToolButton(page, 'pen');
|
||||
await expect(penButton).toHaveAttribute('active', '');
|
||||
|
||||
await page.keyboard.press('h');
|
||||
|
||||
@@ -159,7 +159,9 @@ type EdgelessTool =
|
||||
| 'pan'
|
||||
| 'note'
|
||||
| 'shape'
|
||||
| 'pen'
|
||||
| 'brush'
|
||||
| 'highlighter'
|
||||
| 'eraser'
|
||||
| 'text'
|
||||
| 'connector'
|
||||
@@ -200,7 +202,9 @@ export async function locatorEdgelessToolButton(
|
||||
default: '.edgeless-default-button',
|
||||
pan: '.edgeless-default-button',
|
||||
shape: '.edgeless-shape-button',
|
||||
pen: '.edgeless-pen-button',
|
||||
brush: '.edgeless-brush-button',
|
||||
highlighter: '.edgeless-highlighter-button',
|
||||
eraser: '.edgeless-eraser-button',
|
||||
text: '.edgeless-mindmap-button',
|
||||
connector: '.edgeless-connector-button',
|
||||
@@ -213,6 +217,10 @@ export async function locatorEdgelessToolButton(
|
||||
let buttonType;
|
||||
switch (type) {
|
||||
case 'brush':
|
||||
case 'highlighter':
|
||||
buttonType = 'div';
|
||||
break;
|
||||
case 'pen':
|
||||
case 'text':
|
||||
case 'eraser':
|
||||
case 'shape':
|
||||
@@ -342,9 +350,20 @@ export async function setEdgelessTool(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'brush':
|
||||
case 'highlighter': {
|
||||
const penButton = await locatorEdgelessToolButton(page, 'pen', false);
|
||||
await penButton.click();
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
|
||||
const button = await locatorEdgelessToolButton(page, mode, false);
|
||||
await button.click();
|
||||
|
||||
break;
|
||||
}
|
||||
case 'lasso':
|
||||
case 'note':
|
||||
case 'brush':
|
||||
case 'eraser':
|
||||
case 'frame':
|
||||
case 'connector': {
|
||||
@@ -648,7 +667,7 @@ export async function rotateElementByHandle(
|
||||
|
||||
export async function selectBrushColor(page: Page, label: string) {
|
||||
const colorButton = page
|
||||
.locator('edgeless-brush-menu')
|
||||
.locator('edgeless-pen-menu')
|
||||
.locator('edgeless-color-panel')
|
||||
.locator(`.color-unit[aria-label="${label}"]`);
|
||||
await colorButton.click();
|
||||
@@ -664,7 +683,7 @@ export async function selectBrushSize(page: Page, size: string) {
|
||||
twelve: 6,
|
||||
};
|
||||
const sizeButton = page.locator(
|
||||
`edgeless-brush-menu .line-width-panel .line-width-button:nth-child(${sizeIndexMap[size]})`
|
||||
`edgeless-pen-menu .line-width-panel .line-width-button:nth-child(${sizeIndexMap[size]})`
|
||||
);
|
||||
await sizeButton.click();
|
||||
}
|
||||
|
||||
@@ -62,7 +62,6 @@ export async function focusDocTitle(page: Page, editorIndex = 0) {
|
||||
await locateDocTitle(page, editorIndex).locator('.inline-editor').focus();
|
||||
}
|
||||
|
||||
// ================== Page ==================
|
||||
export function locateToolbar(page: Page, editorIndex = 0) {
|
||||
return locateEditorContainer(page, editorIndex).locator(
|
||||
'affine-toolbar-widget editor-toolbar'
|
||||
@@ -231,7 +230,9 @@ type EdgelessTool =
|
||||
| 'pan'
|
||||
| 'note'
|
||||
| 'shape'
|
||||
| 'pen'
|
||||
| 'brush'
|
||||
| 'highlighter'
|
||||
| 'eraser'
|
||||
| 'text'
|
||||
| 'connector'
|
||||
@@ -255,7 +256,9 @@ export async function locateEdgelessToolButton(
|
||||
default: '.edgeless-default-button',
|
||||
pan: '.edgeless-default-button',
|
||||
shape: '.edgeless-shape-button',
|
||||
pen: '.edgeless-pen-button',
|
||||
brush: '.edgeless-brush-button',
|
||||
highlighter: '.edgeless-highlighter-button',
|
||||
eraser: '.edgeless-eraser-button',
|
||||
text: '.edgeless-mindmap-button',
|
||||
connector: '.edgeless-connector-button',
|
||||
@@ -268,6 +271,10 @@ export async function locateEdgelessToolButton(
|
||||
let buttonType;
|
||||
switch (type) {
|
||||
case 'brush':
|
||||
case 'highlighter':
|
||||
buttonType = 'div';
|
||||
break;
|
||||
case 'pen':
|
||||
case 'text':
|
||||
case 'eraser':
|
||||
case 'shape':
|
||||
@@ -362,9 +369,30 @@ export async function setEdgelessTool(
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'brush':
|
||||
case 'highlighter': {
|
||||
const penButton = await locateEdgelessToolButton(
|
||||
page,
|
||||
'pen',
|
||||
false,
|
||||
editorIndex
|
||||
);
|
||||
await penButton.click();
|
||||
|
||||
await page.waitForTimeout(250);
|
||||
|
||||
const button = await locateEdgelessToolButton(
|
||||
page,
|
||||
tool,
|
||||
false,
|
||||
editorIndex
|
||||
);
|
||||
await button.click();
|
||||
|
||||
break;
|
||||
}
|
||||
case 'lasso':
|
||||
case 'note':
|
||||
case 'brush':
|
||||
case 'eraser':
|
||||
case 'frame':
|
||||
case 'connector': {
|
||||
|
||||
Reference in New Issue
Block a user