feat(editor): add experimental feature citation (#11984)

Closes: [BS-3122](https://linear.app/affine-design/issue/BS-3122/footnote-definition-adapter-适配)
Closes: [BS-3123](https://linear.app/affine-design/issue/BS-3123/几个-block-card-view-适配-footnote-态)

<!-- This is an auto-generated comment: release notes by coderabbit.ai -->
## Summary by CodeRabbit

- **New Features**
  - Introduced a new citation card component and web element for displaying citations.
  - Added support for citation-style rendering in attachment, bookmark, and linked document blocks.
  - Enabled citation parsing from footnote definitions in markdown for attachments, bookmarks, and linked docs.
  - Added a feature flag to enable or disable citation features.
  - Provided new toolbar logic to disable downloads for citation-style attachments.

- **Improvements**
  - Updated block models and properties to support citation identifiers.
  - Added localization and settings for the citation experimental feature.
  - Enhanced markdown adapters to recognize and process citation footnotes.
  - Included new constants and styles for citation card display.

- **Bug Fixes**
  - Ensured readonly state is respected in block interactions and rendering for citation blocks.

- **Documentation**
  - Added exports and effects for new citation components and features.

- **Tests**
  - Updated snapshots to include citation-related properties in block data.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
donteatfriedrice
2025-04-29 06:59:27 +00:00
parent a326eac1bb
commit 83670ab335
58 changed files with 832 additions and 151 deletions
@@ -22,10 +22,12 @@ export {
type BlockMarkdownAdapterMatcher,
BlockMarkdownAdapterMatcherIdentifier,
FOOTNOTE_DEFINITION_PREFIX,
getFootnoteDefinitionText,
IN_PARAGRAPH_NODE_CONTEXT_KEY,
InlineDeltaToMarkdownAdapterExtension,
type InlineDeltaToMarkdownAdapterMatcher,
InlineDeltaToMarkdownAdapterMatcherIdentifier,
isFootnoteDefinitionNode,
isMarkdownAST,
type Markdown,
MarkdownAdapter,
@@ -1,4 +1,4 @@
import type { Root, RootContentMap } from 'mdast';
import type { FootnoteDefinition, Root, RootContentMap } from 'mdast';
export type Markdown = string;
@@ -16,5 +16,17 @@ export const isMarkdownAST = (node: unknown): node is MarkdownAST =>
'type' in (node as object) &&
(node as MarkdownAST).type !== undefined;
export const isFootnoteDefinitionNode = (
node: MarkdownAST
): node is FootnoteDefinition => node.type === 'footnoteDefinition';
export const getFootnoteDefinitionText = (node: FootnoteDefinition) => {
const childNode = node.children[0];
if (childNode.type !== 'paragraph') return '';
const paragraph = childNode.children[0];
if (paragraph.type !== 'text') return '';
return paragraph.value;
};
export const FOOTNOTE_DEFINITION_PREFIX = 'footnoteDefinition:';
export const IN_PARAGRAPH_NODE_CONTEXT_KEY = 'mdast:paragraph';
@@ -31,6 +31,7 @@ export const EMBED_CARD_WIDTH: Record<EmbedCardStyle, number> = {
html: 752,
syncedDoc: 800,
pdf: 537 + 24 + 2,
citation: 752,
};
export const EMBED_CARD_HEIGHT: Record<EmbedCardStyle, number> = {
@@ -45,6 +46,7 @@ export const EMBED_CARD_HEIGHT: Record<EmbedCardStyle, number> = {
html: 544,
syncedDoc: 455,
pdf: 759 + 46 + 24 + 2,
citation: 52,
};
export const EMBED_BLOCK_FLAVOUR_LIST = [
@@ -20,6 +20,7 @@ export interface BlockSuiteFlags {
enable_edgeless_scribbled_style: boolean;
enable_embed_doc_with_alias: boolean;
enable_turbo_renderer: boolean;
enable_citation: boolean;
}
export class FeatureFlagService extends StoreExtension {
@@ -44,6 +45,7 @@ export class FeatureFlagService extends StoreExtension {
enable_edgeless_scribbled_style: false,
enable_embed_doc_with_alias: false,
enable_turbo_renderer: false,
enable_citation: false,
});
setFlag(key: keyof BlockSuiteFlags, value: boolean) {