CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tiptap--extension-link

Link extension for tiptap rich text editor providing automatic link detection, paste handling, click behavior, and XSS protection.

88

1.23x
Overview
Eval results
Files

task.mdevals/scenario-2/

Link Manager Extension

Build a custom Tiptap extension that integrates the link functionality with proper lifecycle management and state tracking. Your extension should wrap the link extension and maintain statistics about link usage within the editor.

Requirements

Create a LinkManagerExtension that:

  1. Extends the base link functionality: Configure and include the link extension with automatic link detection enabled and links opening on click.

  2. Tracks link statistics: Maintain a count of total links currently in the document. This count should update whenever links are added or removed through any means (commands, typing, pasting, etc.).

  3. Provides lifecycle integration:

    • Initialize the tracking system when the editor is created
    • Clean up resources when the editor is destroyed
    • Ensure the link count stays synchronized with the document state
  4. Exposes a command: Provide a getLinkCount command that returns the current number of links in the document.

  5. Exports the count: Make the current link count accessible from outside the editor instance so it can be displayed in a UI component.

Implementation Details

  • The extension should be named LinkManagerExtension
  • Use proper lifecycle hooks for setup and cleanup
  • Ensure link count updates are transaction-based for undo/redo compatibility
  • The link count should be accurate at all times, regardless of how links are added/removed

Test Cases

Implement test cases in link-manager.test.ts to verify:

@test Basic link command tracking

const editor = new Editor({
  extensions: [Document, Paragraph, Text, LinkManagerExtension],
  content: '<p>Hello world</p>'
})

editor.chain().focus().setTextSelection({ from: 1, to: 6 }).setLink({ href: 'https://example.com' }).run()

// Link count should be 1
expect(editor.commands.getLinkCount()).toBe(1)

@test Multiple links tracking

const editor = new Editor({
  extensions: [Document, Paragraph, Text, LinkManagerExtension],
  content: '<p>First link and second link</p>'
})

editor.chain().focus().setTextSelection({ from: 1, to: 6 }).setLink({ href: 'https://first.com' }).run()
editor.chain().focus().setTextSelection({ from: 16, to: 22 }).setLink({ href: 'https://second.com' }).run()

// Link count should be 2
expect(editor.commands.getLinkCount()).toBe(2)

@test Link removal tracking

const editor = new Editor({
  extensions: [Document, Paragraph, Text, LinkManagerExtension],
  content: '<p><a href="https://example.com">link text</a> and plain text</p>'
})

// Initial count should be 1
expect(editor.commands.getLinkCount()).toBe(1)

editor.chain().focus().setTextSelection({ from: 1, to: 10 }).unsetLink().run()

// After removal, count should be 0
expect(editor.commands.getLinkCount()).toBe(0)

Dependencies { .dependencies }

@tiptap/core { .dependency }

Core Tiptap editor framework providing the extension system, editor lifecycle, and command infrastructure.

@tiptap/extension-link { .dependency }

Provides link mark functionality including commands for creating, toggling, and removing links, with automatic link detection and paste handling.

@tiptap/extension-document { .dependency }

Required document node for Tiptap editor schema.

@tiptap/extension-paragraph { .dependency }

Required paragraph node for Tiptap editor schema.

@tiptap/extension-text { .dependency }

Required text node for Tiptap editor schema.

Install with Tessl CLI

npx tessl i tessl/npm-tiptap--extension-link

tile.json