Skip to content

BlockSuite API Documentation / @blocksuite/affine-block-bookmark

@blocksuite/affine-block-bookmark

Classes

Extension

EdgelessClipboardBookmarkConfig

Understanding Extensions

Extensions provide a way to extend the functionality of a system using dependency injection. They allow you to register services, implementations, and factories in the DI container, which can then be retrieved and used by different parts of the application.

Extensions are particularly useful for:

  • Registering different implementations for different types
  • Creating pluggable architecture where components can be added or removed
  • Managing dependencies between different parts of the application

Usage Example: Fruit Processing System

Let's consider a fruit processing system where different types of fruits need different processing methods. We'll show how to implement this using extensions.

Step 1: Define the interfaces

ts
interface FruitProcessor {
  process(fruit: Fruit): void;
}

interface Fruit {
  type: string;
  // other properties
}

Step 2: Create a service identifier

ts
import { createIdentifier } from '@blocksuite/global/di';

const FruitProcessorProvider = createIdentifier<FruitProcessor>('fruit-processor-provider');

Step 3: Create implementations

ts
class AppleProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Slicing apple');
    // Apple-specific processing
  }
}

class BananaProcessor implements FruitProcessor {
  process(fruit: Fruit): void {
    console.log('Peeling banana');
    // Banana-specific processing
  }
}

Step 4: Create an extension factory

ts
const FruitProcessorExtension = (
  fruitType: string,
  implementation: new () => FruitProcessor
): ExtensionType => {
  return {
    setup: di => {
      di.addImpl(FruitProcessorProvider(fruitType), implementation);
    }
  };
};

Step 5: Create concrete extensions

ts
export const AppleProcessorExtension = FruitProcessorExtension('apple', AppleProcessor);
export const BananaProcessorExtension = FruitProcessorExtension('banana', BananaProcessor);

Step 6: Use the extensions

ts
import { Container } from '@blocksuite/global/di';

class FruitProcessingSystem {
  provider: ServiceProvider;

  constructor(extensions: ExtensionType[]) {
    const container = new Container();

    // Set up all extensions
    extensions.forEach(ext => ext.setup(container));

    // Create a provider from the container
    this.provider = container.provider();
  }

  processFruit(fruit: Fruit) {
    // Get the appropriate processor based on fruit type
    const processor = this.provider.get(FruitProcessorProvider(fruit.type));

    // Process the fruit
    processor.process(fruit);
  }
}

// Initialize the system with extensions
const system = new FruitProcessingSystem([
  AppleProcessorExtension,
  BananaProcessorExtension
]);

// Use the system
system.processFruit({ type: 'apple' });  // Output: Slicing apple
system.processFruit({ type: 'banana' }); // Output: Peeling banana

Note: We deliberately used a non-block specific example here. In BlockSuite, the extension pattern can be applied to any entity that can be configured by third parties, not just blocks. This includes different tools in the whiteboard, different column types in database blocks, and many other extensible components. The pattern remains the same regardless of what you're extending.

Extends
Constructors
Properties
key

readonly static key: "affine:bookmark" = 'affine:bookmark'

Overrides

EdgelessClipboardConfig.key

Accessors
Methods
createBlock()

createBlock(bookmark): string | null

Parameters
bookmark

BlockSnapshot

Returns

string | null

Overrides

EdgelessClipboardConfig.createBlock

Other

BookmarkBlockComponent

Extends
Constructors
Other
blockDraggable

blockDraggable: boolean = true

containerStyleMap

protected containerStyleMap: DirectiveResult<typeof StyleMapDirective>

linkPreview$

linkPreview$: ReadonlySignal<{ description: string | null; icon: string | null; image: string | null; title: string | null; }>

Description

Link preview data for actual rendering When the doc is not in readonly mode, and the link preview data are provided (stored in the block model), We will use the model props to render the block. Otherwise, we will use the local link preview data to render the block.

selectedStyle$

selectedStyle$: ReadonlySignal<ClassInfo> | null

blockContainerStyles
Overrides

CaptionedBlockComponent.blockContainerStyles

bookmarkCard
citationService
Get Signature

get citationService(): CitationViewService

Returns

CitationViewService

error
imageProxyService
Get Signature

get imageProxyService(): ImageProxyService

Returns

ImageProxyService

isCitation
Get Signature

get isCitation(): boolean

Returns

boolean

isCommentHighlighted
Get Signature

get isCommentHighlighted(): boolean

Returns

boolean

Get Signature

get link(): string

Returns

string

loading
selectedStyle
Overrides

CaptionedBlockComponent.selectedStyle

useCaptionEditor
Overrides

CaptionedBlockComponent.useCaptionEditor

useZeroWidth
Overrides

CaptionedBlockComponent.useZeroWidth

connectedCallback()

connectedCallback(): void

Returns

void

Overrides

CaptionedBlockComponent.connectedCallback

disconnectedCallback()

disconnectedCallback(): void

Returns

void

Overrides

CaptionedBlockComponent.disconnectedCallback

handleClick()

handleClick(event): void

Parameters
event

MouseEvent

Returns

void

handleDoubleClick()

handleDoubleClick(event): void

Parameters
event

MouseEvent

Returns

void

open()

open(): void

Returns

void

refreshData()

refreshData(): void

Returns

void

renderBlock()

renderBlock(): TemplateResult<1>

Returns

TemplateResult<1>

Overrides

CaptionedBlockComponent.renderBlock

selectBlock()

selectBlock(): void

Returns

void

attributes
controllers
dev-mode
properties
rendering
styles
updates

BookmarkCard

Extends
Constructors
Other
styles

static styles: CSSResult

Overrides

SignalWatcher( WithDisposable(ShadowlessElement) ).styles

bookmark
error
loading
connectedCallback()

connectedCallback(): void

Returns

void

Overrides

SignalWatcher( WithDisposable(ShadowlessElement) ).connectedCallback

attributes
controllers
dev-mode
lifecycle
properties
rendering
render()

render(): TemplateResult<1>

Invoked on each update to perform rendering tasks. This method may return any value renderable by lit-html's ChildPart - typically a TemplateResult. Setting properties inside this method will not trigger the element to update.

Returns

TemplateResult<1>

Overrides

SignalWatcher( WithDisposable(ShadowlessElement) ).render

styles
updates

Variables

BOOKMARK_MIN_WIDTH

const BOOKMARK_MIN_WIDTH: 450 = 450


BookmarkBlockHtmlAdapterExtension

const BookmarkBlockHtmlAdapterExtension: ExtensionType & object

Type Declaration

identifier

identifier: ServiceIdentifier<BlockHtmlAdapterMatcher>


bookmarkBlockHtmlAdapterMatcher

const bookmarkBlockHtmlAdapterMatcher: BlockHtmlAdapterMatcher


BookmarkBlockMarkdownAdapterExtension

const BookmarkBlockMarkdownAdapterExtension: ExtensionType & object

Type Declaration

identifier

identifier: ServiceIdentifier<BlockMarkdownAdapterMatcher>


BookmarkBlockMarkdownAdapterExtensions

const BookmarkBlockMarkdownAdapterExtensions: ExtensionType[]


bookmarkBlockMarkdownAdapterMatcher

const bookmarkBlockMarkdownAdapterMatcher: BlockMarkdownAdapterMatcher


BookmarkBlockMarkdownPreprocessorExtension

const BookmarkBlockMarkdownPreprocessorExtension: ExtensionType & object

Type Declaration

identifier

identifier: ServiceIdentifier<MarkdownAdapterPreprocessor>


BookmarkBlockNotionHtmlAdapterExtension

const BookmarkBlockNotionHtmlAdapterExtension: ExtensionType & object

Type Declaration

identifier

identifier: ServiceIdentifier<BlockNotionHtmlAdapterMatcher>


bookmarkBlockNotionHtmlAdapterMatcher

const bookmarkBlockNotionHtmlAdapterMatcher: BlockNotionHtmlAdapterMatcher


BookmarkBlockPlainTextAdapterExtension

const BookmarkBlockPlainTextAdapterExtension: ExtensionType & object

Type Declaration

identifier

identifier: ServiceIdentifier<BlockPlainTextAdapterMatcher>


bookmarkBlockPlainTextAdapterMatcher

const bookmarkBlockPlainTextAdapterMatcher: BlockPlainTextAdapterMatcher


BookmarkSlashMenuConfigIdentifier

const BookmarkSlashMenuConfigIdentifier: ServiceIdentifier<SlashMenuConfig>


insertBookmarkCommand

const insertBookmarkCommand: Command<{ url: string; }, { blockId: string; flavour: string; }>


insertLinkByQuickSearchCommand

const insertLinkByQuickSearchCommand: Command<{ }, { insertedLinkType: Promise<InsertedLinkType>; }>

Functions

footnoteUrlPreprocessor()

footnoteUrlPreprocessor(content): string

Preprocessor for footnote url We should encode url in footnote definition to avoid markdown link parsing

Example of footnote definition: [^ref]: {"type":"url","url":"https://example.com"}

Parameters

content

string

Returns

string