Skip to content

Commit

Permalink
fix: the code block wrap state shoud be persisted in database
Browse files Browse the repository at this point in the history
  • Loading branch information
akumatus committed May 16, 2024
1 parent f4aabfa commit 73438d8
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 22 deletions.
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
100 changes: 100 additions & 0 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 All @@ -734,6 +824,16 @@ test('should code block wrap active after click', async ({ page }) => {
);
});

test('code block wrap icon hidden in read only mode', async ({ page }) => {
await enterPlaygroundRoom(page);
await initEmptyCodeBlockState(page);
await switchReadonly(page);

const codeBlockController = getCodeBlock(page);
await codeBlockController.codeBlock.hover();
await expect(codeBlockController.wrapButton).toBeHidden();
});

test('should code block works in read only mode', async ({ page }) => {
await enterPlaygroundRoom(page);
await initEmptyCodeBlockState(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

0 comments on commit 73438d8

Please sign in to comment.