Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: the code block wrap state shoud be persisted in database #7062

Merged
merged 1 commit into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions packages/blocks/src/code-block/code-block.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ import { getHighLighter } from './utils/high-lighter.js';
export class CodeBlockComponent extends BlockElement<CodeBlockModel> {
static override styles = codeBlockStyles;

@state()
private _wrap = false;

@query('.lang-button')
private _langButton!: HTMLButtonElement;

Expand Down Expand Up @@ -176,9 +173,9 @@ export class CodeBlockComponent extends BlockElement<CodeBlockModel> {
CodeOptionTemplate({
anchor: this,
model: this.model,
wrap: this._wrap,
onClickWrap: () => {
this._wrap = !this._wrap;
wrap: this.model.wrap,
toggleWrap: () => {
this.setWrap(!this.model.wrap);
updatePortal();
},
abortController,
Expand Down Expand Up @@ -429,6 +426,10 @@ export class CodeBlockComponent extends BlockElement<CodeBlockModel> {
});
}

setWrap(wrap: boolean) {
this.doc.updateBlock(this.model, { wrap });
}

private _onClickLangBtn() {
if (this.readonly) return;
if (this._langListAbortController) return;
Expand Down Expand Up @@ -477,7 +478,9 @@ export class CodeBlockComponent extends BlockElement<CodeBlockModel> {
this.querySelector<HTMLElement>('#line-numbers');
assertExists(lineNumbersContainer);

const next = this._wrap ? generateLineNumberRender() : lineNumberRender;
const next = this.model.wrap
? generateLineNumberRender()
: lineNumberRender;

render(
repeat(Array.from(this.querySelectorAll('v-line')), next),
Expand All @@ -491,7 +494,7 @@ export class CodeBlockComponent extends BlockElement<CodeBlockModel> {
${ref(this._whenHover.setReference)}
class=${classMap({
'affine-code-block-container': true,
wrap: this._wrap,
wrap: this.model.wrap,
})}
>
${this._curLanguageButtonTemplate()}
Expand All @@ -507,7 +510,7 @@ export class CodeBlockComponent extends BlockElement<CodeBlockModel> {
.inlineRangeProvider=${this._inlineRangeProvider}
.enableClipboard=${false}
.enableUndoRedo=${false}
.wrapText=${this._wrap}
.wrapText=${this.model.wrap}
.verticalScrollContainer=${getViewportElement(this.host)}
>
</rich-text>
Expand Down
1 change: 1 addition & 0 deletions packages/blocks/src/code-block/code-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const CodeBlockSchema = defineBlockSchema({
props: internal => ({
text: internal.Text(),
language: FALLBACK_LANG,
wrap: false,
}),
metadata: {
version: 1,
Expand Down
28 changes: 15 additions & 13 deletions packages/blocks/src/code-block/components/code-option.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ export function CodeOptionTemplate({
ref: containerRef,
model,
wrap,
onClickWrap,
toggleWrap,
anchor,
}: {
ref?: RefOrCallback;
anchor: CodeBlockComponent;
model: BlockModel;
wrap: boolean;
abortController: AbortController;
onClickWrap: () => void;
toggleWrap: () => void;
}) {
const page = model.doc;
const readonly = page.readonly;
Expand Down Expand Up @@ -71,17 +71,19 @@ export function CodeOptionTemplate({
>Copy to Clipboard</affine-tooltip
>
</icon-button>
<icon-button
size="32px"
data-testid="wrap-button"
?active=${wrap}
@click=${onClickWrap}
>
${wrap ? CancelWrapIcon : WrapIcon}
<affine-tooltip tip-position="right" .offset=${12}
>${wrap ? 'Cancel wrap' : 'Wrap code'}</affine-tooltip
>
</icon-button>
${readonly
? nothing
: html`<icon-button
size="32px"
data-testid="wrap-button"
?active=${wrap}
@click=${toggleWrap}
>
${wrap ? CancelWrapIcon : WrapIcon}
<affine-tooltip tip-position="right" .offset=${12}
>${wrap ? 'Cancel wrap' : 'Wrap code'}</affine-tooltip
>
</icon-button>`}
${readonly
? nothing
: html`<icon-button
Expand Down
96 changes: 93 additions & 3 deletions tests/code.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,7 @@ test('use markdown syntax can create code block', async ({ page }) => {
>
<affine:code
prop:language="Plain Text"
prop:wrap={false}
/>
<affine:paragraph
prop:text="aaa"
Expand Down Expand Up @@ -277,6 +278,7 @@ test('change code language can work', async ({ page }) => {
/*xml*/ `
<affine:code
prop:language="rust"
prop:wrap={false}
/>`,
codeBlockId
);
Expand All @@ -286,6 +288,7 @@ test('change code language can work', async ({ page }) => {
/*xml*/ `
<affine:code
prop:language="Plain Text"
prop:wrap={false}
/>`,
codeBlockId
);
Expand Down Expand Up @@ -418,10 +421,12 @@ test.skip('use keyboard copy inside code block copy', async ({ page }) => {
<affine:code
prop:language="Plain Text"
prop:text="use"
prop:wrap={false}
/>
<affine:code
prop:language="Plain Text"
prop:text="use"
prop:wrap={false}
/>
</affine:note>
</affine:page>`
Expand Down Expand Up @@ -473,10 +478,12 @@ test.fixme(
<affine:code
prop:language="javascript"
prop:text="use"
prop:wrap={false}
/>
<affine:code
prop:language="javascript"
prop:text="use"
prop:wrap={false}
/>
</affine:note>
</affine:page>`
Expand Down Expand Up @@ -711,6 +718,89 @@ test('should tab works in code block', async ({ page }) => {
await assertRichTexts(page, ['const a = 10;\n \nconst b = "NothingToSay"']);
});

test('toggle code block wrap can work', async ({ page }) => {
await enterPlaygroundRoom(page);
const { codeBlockId } = await initEmptyCodeBlockState(page);
await focusRichText(page);

const codeBlockController = getCodeBlock(page);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:language="Plain Text"
prop:wrap={false}
/>`,
codeBlockId
);

await codeBlockController.codeBlock.hover();
await expect(codeBlockController.wrapButton).toBeVisible();
await codeBlockController.wrapButton.click();
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:language="Plain Text"
prop:wrap={true}
/>`,
codeBlockId
);

await codeBlockController.wrapButton.click();
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:language="Plain Text"
prop:wrap={false}
/>`,
codeBlockId
);
});

test('undo code block wrap can work', async ({ page }) => {
await enterPlaygroundRoom(page);
const { codeBlockId } = await initEmptyCodeBlockState(page);
await focusRichText(page);

const codeBlockController = getCodeBlock(page);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:language="Plain Text"
prop:wrap={false}
/>`,
codeBlockId
);

await codeBlockController.codeBlock.hover();
await expect(codeBlockController.wrapButton).toBeVisible();
await codeBlockController.wrapButton.click();
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:language="Plain Text"
prop:wrap={true}
/>`,
codeBlockId
);

await focusRichText(page);
await undoByKeyboard(page);
await assertStoreMatchJSX(
page,
/*xml*/ `
<affine:code
prop:language="Plain Text"
prop:wrap={false}
/>`,
codeBlockId
);
});

test('should code block wrap active after click', async ({ page }) => {
await enterPlaygroundRoom(page);
await initEmptyCodeBlockState(page);
Expand Down Expand Up @@ -748,9 +838,9 @@ test('should code block works in read only mode', async ({ page }) => {
await codeBlockController.clickLanguageButton();
await expect(codeBlockController.langList).toBeHidden();
await expect(codeBlockController.codeOption).toBeVisible();
await expect(
codeBlockController.codeOption.locator('icon-button')
).toHaveCount(2);
await expect(codeBlockController.copyButton).toBeVisible();
await expect(codeBlockController.wrapButton).toBeHidden();
await expect(codeBlockController.deleteButton).toBeHidden();
});

test('should code block lang input supports alias', async ({ page }) => {
Expand Down
1 change: 1 addition & 0 deletions tests/format-bar.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1318,6 +1318,7 @@ test('should format quick bar show after convert to code block', async ({
<affine:code
prop:language="Plain Text"
prop:text="123\n456\n789"
prop:wrap={false}
/>
</affine:note>`,
noteId
Expand Down
Loading