feat: improve editor performance (#14429)

#### PR Dependency Tree


* **PR #14429** 👈

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**
* HTML import now splits lines on <br> into separate paragraphs while
preserving inline formatting.

* **Bug Fixes**
* Paste falls back to inserting after the first paragraph when no
explicit target is found.

* **Style**
  * Improved page-mode viewport styling for consistent content layout.

* **Tests**
* Added snapshot tests for <br>-based paragraph splitting; re-enabled an
e2e drag-page test.

* **Chores**
* Deferred/deduplicated font loading, inline text caching,
drag-handle/pointer optimizations, and safer inline render
synchronization.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
DarkSky
2026-02-14 00:43:36 +08:00
committed by GitHub
parent 98e5747fdc
commit 72df9cb457
14 changed files with 873 additions and 111 deletions
@@ -86,6 +86,7 @@ export class PageClipboard extends ReadOnlyClipboard {
if (this.std.store.readonly) return;
this.std.store.captureSync();
let hasPasteTarget = false;
this.std.command
.chain()
.try<{}>(cmd => [
@@ -144,18 +145,39 @@ export class PageClipboard extends ReadOnlyClipboard {
if (!ctx.parentBlock) {
return;
}
hasPasteTarget = true;
this.std.clipboard
.paste(
e,
this.std.store,
ctx.parentBlock.model.id,
ctx.blockIndex ? ctx.blockIndex + 1 : 1
ctx.blockIndex !== undefined ? ctx.blockIndex + 1 : 1
)
.catch(console.error);
return next();
})
.run();
if (hasPasteTarget) return;
// If no valid selection target exists (for example, stale block selection
// right after cut), create/focus the default paragraph and paste after it.
const firstParagraphId = document
.querySelector('affine-page-root')
?.focusFirstParagraph?.()?.id;
const parentModel = firstParagraphId
? this.std.store.getParent(firstParagraphId)
: null;
const paragraphIndex =
firstParagraphId && parentModel
? parentModel.children.findIndex(child => child.id === firstParagraphId)
: -1;
const insertIndex = paragraphIndex >= 0 ? paragraphIndex + 1 : undefined;
this.std.clipboard
.paste(e, this.std.store, parentModel?.id, insertIndex)
.catch(console.error);
};
override mounted() {