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(page): autoIdentityLink behavior #5370

Merged
merged 2 commits into from
Nov 23, 2023
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
61 changes: 7 additions & 54 deletions packages/blocks/src/_common/components/rich-text/virgo/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,65 +11,22 @@ const EDGE_IGNORED_ATTRIBUTES = ['code', 'reference'] as const;
const GLOBAL_IGNORED_ATTRIBUTES = ['reference'] as const;

const autoIdentifyLink = (ctx: VHookContext<AffineTextAttributes>) => {
if (ctx.attributes?.link && ctx.data === ' ') {
delete ctx.attributes['link'];
// auto identify link only on pressing space
if (ctx.data !== ' ') {
return;
}

// space is typed at the end of link, remove the link attribute on typed space
if (ctx.attributes?.link) {
const linkDeltaInfo = ctx.vEditor.deltaService
.getDeltasByVRange(ctx.vRange)
.filter(([delta]) => delta.attributes?.link)[0];
const [delta, { index, length }] = linkDeltaInfo;
const rangePositionInDelta = ctx.vRange.index - index;

//It means the link has been custom edited
if (delta.attributes?.link !== delta.insert) {
// If the cursor is at the end of the link, we should not auto identify it
if (rangePositionInDelta === length) {
delete ctx.attributes['link'];
return;
}
// If the cursor is not at the end of the link, we should only update the link text
return;
}
const newText =
delta.insert.slice(0, rangePositionInDelta) +
ctx.data +
delta.insert.slice(rangePositionInDelta);
const isUrl = isStrictUrl(newText);

// If the new text with original link text is not pattern matched, we should reset the text
if (!isUrl) {
ctx.vEditor.resetText({ index, length });
if (ctx.vRange.index === ctx.vEditor.yText.length) {
delete ctx.attributes['link'];
return;
}
// If the new text with original link text is pattern matched, we should update the link text
ctx.vEditor.formatText(
{
index,
length,
},
{
link: newText,
}
);
ctx.attributes = {
...ctx.attributes,
link: newText,
};
return;
}

const [line] = ctx.vEditor.getLine(ctx.vRange.index);

// In delete, context.data is null
const insertText = ctx.data || '';
const verifyData = `${line.textContent.slice(
0,
ctx.vRange.index
)}${insertText}`.split(' ');
const verifyData = line.textContent.slice(0, ctx.vRange.index).split(' ');

const verifyStr = verifyData[verifyData.length - 1];

Expand All @@ -78,7 +35,8 @@ const autoIdentifyLink = (ctx: VHookContext<AffineTextAttributes>) => {
if (!isUrl) {
return;
}
const startIndex = ctx.vRange.index + insertText.length - verifyStr.length;

const startIndex = ctx.vRange.index - verifyStr.length;

ctx.vEditor.formatText(
{
Expand All @@ -89,11 +47,6 @@ const autoIdentifyLink = (ctx: VHookContext<AffineTextAttributes>) => {
link: verifyStr,
}
);

ctx.attributes = {
...ctx.attributes,
link: verifyStr,
};
};

let ifPrefixSpace = false;
Expand Down
5 changes: 4 additions & 1 deletion tests/basic.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ test(scoped`automatic identify url text`, async ({ page }) => {
await enterPlaygroundRoom(page);
await initEmptyParagraphState(page);
await focusRichText(page);
await type(page, 'abc https://google.com');
await type(page, 'abc https://google.com ');

await assertStoreMatchJSX(
page,
Expand All @@ -525,6 +525,9 @@ test(scoped`automatic identify url text`, async ({ page }) => {
insert="https://google.com"
link="https://google.com"
/>
<text
insert=" "
/>
</>
}
prop:type="text"
Expand Down
16 changes: 11 additions & 5 deletions tests/bookmark.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ test(scoped`copy url to create bookmark in page mode`, async ({ page }) => {
await initEmptyParagraphState(page);
await focusRichText(page);

await type(page, 'https://google.com');
await type(page, 'https://google.com ');
await setVRangeInSelectedRichText(page, 0, 18);
await copyByKeyboard(page);
await focusRichText(page);
Expand All @@ -164,7 +164,10 @@ test(scoped`copy url to create bookmark in page mode`, async ({ page }) => {
<>
<text
insert="https://google.com"
link="https://google.com/bookmark"
link="https://google.com"
/>
<text
insert=" "
/>
</>
}
Expand All @@ -189,7 +192,7 @@ test(scoped`copy url to create bookmark in edgeless mode`, async ({ page }) => {
await enterPlaygroundRoom(page);
const ids = await initEmptyEdgelessState(page);
await focusRichText(page);
await type(page, 'https://google.com');
await type(page, 'https://google.com ');

await switchEditorMode(page);

Expand Down Expand Up @@ -217,7 +220,10 @@ test(scoped`copy url to create bookmark in edgeless mode`, async ({ page }) => {
<>
<text
insert="https://google.com"
link="https://google.com/bookmark"
link="https://google.com"
/>
<text
insert=" "
/>
</>
}
Expand All @@ -231,7 +237,7 @@ test(scoped`copy url to create bookmark in edgeless mode`, async ({ page }) => {
prop:icon=""
prop:image=""
prop:type="card"
prop:url="https://google.com"
prop:url="https://google.com "
/>
</affine:note>
</affine:page>`
Expand Down
33 changes: 0 additions & 33 deletions tests/link.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,39 +131,6 @@ async function createLinkBlock(page: Page, str: string, link: string) {
return id;
}

test('text added after a link which has custom edited should not have link formatting', async ({
page,
}) => {
await enterPlaygroundRoom(page);
const id = await createLinkBlock(page, 'link text', 'http://example.com');
await focusRichText(page, 0);
await type(page, 'after link');
await assertStoreMatchJSX(
page,
// XXX This snapshot is not exactly correct, but it's close enough for now.
// The first text after the link should not have the link formatting.
`
<affine:paragraph
prop:text={
<>
<text
insert="Hello"
/>
<text
insert="link text"
link="http://example.com"
/>
<text
insert="after link"
/>
</>
}
prop:type="text"
/>`,
id
);
});

test('type character in link should not jump out link node', async ({
page,
}) => {
Expand Down
Loading