mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-03-26 09:08:41 +08:00
fix #13459 fix #13707 fix #13924 #### PR Dependency Tree * **PR #14394** 👈 This tree was auto-generated by [Charcoal](https://github.com/danerwilliams/charcoal) <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **New Features** * Improved URL paste: text is split into segments, inserted correctly, and single-URL pastes create linked-page references. * **UI Improvements** * Redesigned layout selector with compact dynamic options. * Number-format options are always available in table headers and mobile menus. * **Bug Fixes** * More consistent paste behavior for mixed text+URL content. * Prevented recursive selection updates when exiting edit mode. * **Tests** * Added tests for URL splitting, paste insertion, number formatting, and selection behavior. * **Chores** * Removed number-formatting feature flag; formatting now applied by default. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
57 lines
1.3 KiB
TypeScript
57 lines
1.3 KiB
TypeScript
import type {
|
|
AffineInlineEditor,
|
|
AffineTextAttributes,
|
|
} from '@blocksuite/affine-shared/types';
|
|
import {
|
|
splitTextByUrl,
|
|
type UrlTextSegment,
|
|
} from '@blocksuite/affine-shared/utils';
|
|
import type { InlineRange } from '@blocksuite/std/inline';
|
|
|
|
type UrlPasteInlineEditor = Pick<
|
|
AffineInlineEditor,
|
|
'insertText' | 'setInlineRange'
|
|
>;
|
|
|
|
export function analyzeTextForUrlPaste(text: string) {
|
|
const segments = splitTextByUrl(text);
|
|
const firstSegment = segments[0];
|
|
const singleUrl =
|
|
segments.length === 1 && firstSegment?.link && firstSegment.text === text
|
|
? firstSegment.link
|
|
: undefined;
|
|
return {
|
|
segments,
|
|
singleUrl,
|
|
};
|
|
}
|
|
|
|
export function insertUrlTextSegments(
|
|
inlineEditor: UrlPasteInlineEditor,
|
|
inlineRange: InlineRange,
|
|
segments: UrlTextSegment[]
|
|
) {
|
|
let index = inlineRange.index;
|
|
let replacedSelection = false;
|
|
segments.forEach(segment => {
|
|
if (!segment.text) return;
|
|
const attributes: AffineTextAttributes | undefined = segment.link
|
|
? { link: segment.link }
|
|
: undefined;
|
|
inlineEditor.insertText(
|
|
{
|
|
index,
|
|
length: replacedSelection ? 0 : inlineRange.length,
|
|
},
|
|
segment.text,
|
|
attributes
|
|
);
|
|
replacedSelection = true;
|
|
index += segment.text.length;
|
|
});
|
|
inlineEditor.setInlineRange({
|
|
index,
|
|
length: 0,
|
|
});
|
|
}
|