or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

index.md
tile.json

tessl/npm-ckeditor--ckeditor5-word-count

Word and character count feature for CKEditor 5.

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/@ckeditor/ckeditor5-word-count@46.0.x

To install, run

npx @tessl/cli install tessl/npm-ckeditor--ckeditor5-word-count@46.0.0

index.mddocs/

CKEditor 5 Word Count

CKEditor 5 Word Count is a plugin that provides real-time word and character counting functionality for CKEditor 5. It calculates text statistics by converting editor model data to plain text and supports configurable display options, custom update callbacks, and seamless integration with the CKEditor 5 architecture.

Package Information

  • Package Name: @ckeditor/ckeditor5-word-count
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install ckeditor5 (part of the main CKEditor 5 package)
  • Dependencies: @ckeditor/ckeditor5-core, @ckeditor/ckeditor5-ui, @ckeditor/ckeditor5-utils, es-toolkit

Core Imports

import { WordCount } from "@ckeditor/ckeditor5-word-count";

For accessing configuration types:

import type { WordCountConfig } from "@ckeditor/ckeditor5-word-count";

Basic Usage

import { ClassicEditor } from "@ckeditor/ckeditor5-editor-classic";
import { WordCount } from "@ckeditor/ckeditor5-word-count";

// Basic plugin usage
ClassicEditor
    .create(document.querySelector('#editor'), {
        plugins: [WordCount],
        wordCount: {
            displayWords: true,
            displayCharacters: true,
            onUpdate: (stats) => {
                console.log(`Words: ${stats.words}, Characters: ${stats.characters}`);
            }
        }
    })
    .then(editor => {
        const wordCountPlugin = editor.plugins.get('WordCount');
        
        // Access current counts
        console.log('Current words:', wordCountPlugin.words);
        console.log('Current characters:', wordCountPlugin.characters);
        
        // Get the display container
        const container = wordCountPlugin.wordCountContainer;
        document.body.appendChild(container);
    });

Architecture

The Word Count plugin is built around several key components:

  • WordCount Plugin Class: The main plugin that extends CKEditor 5's Plugin base class
  • Real-time Counting: Uses throttled model change detection (250ms) for performance via es-toolkit's throttle function
  • Text Conversion: Converts editor model data to plain text using intelligent block handling
  • UI Integration: Provides self-updating HTML containers with CKEditor 5's template system
  • Configuration System: Flexible options for display and callback customization, validated using es-toolkit's isElement utility

Capabilities

Plugin Class

The main WordCount plugin class that provides word and character counting functionality.

class WordCount extends Plugin {
    /** The number of characters in the editor (observable, readonly, computed via getter) */
    readonly characters: number;
    
    /** The number of words in the editor (observable, readonly, computed via getter) */
    readonly words: number;
    
    /** Creates a self-updating HTML element for displaying counts */
    readonly wordCountContainer: HTMLElement;
    
    /** Plugin name identifier */
    static readonly pluginName: 'WordCount';
    
    /** Indicates this is an official CKEditor 5 plugin */
    static readonly isOfficialPlugin: true;
    
    /**
     * Creates a new WordCount plugin instance
     * @param editor - The editor instance this plugin will be attached to
     */
    constructor(editor: Editor);
    
    /** Initialize the plugin functionality */
    init(): void;
    
    /** Clean up plugin resources */
    destroy(): void;
}

Usage Examples:

// Access plugin instance
const wordCountPlugin = editor.plugins.get('WordCount');

// Get current statistics - properties are computed on access via getters
const currentWords = wordCountPlugin.words;
const currentCharacters = wordCountPlugin.characters;

// Get display container and add to DOM
const displayContainer = wordCountPlugin.wordCountContainer;
document.getElementById('word-count-area').appendChild(displayContainer);

// Listen for updates
wordCountPlugin.on('update', (evt, data) => {
    console.log(`Updated: ${data.words} words, ${data.characters} characters`);
});

Configuration

Configuration interface for customizing word count behavior and display.

interface WordCountConfig {
    /** Show/hide word counter in display container (default: true) */
    displayWords?: boolean;
    
    /** Show/hide character counter in display container (default: true) */
    displayCharacters?: boolean;
    
    /** Callback function executed when counts are updated */
    onUpdate?: (data: { words: number; characters: number }) => void;
    
    /** HTML element to automatically append the word count container to */
    container?: HTMLElement;
}

Usage Examples:

// Hide word counter, show only characters
const config: WordCountConfig = {
    displayWords: false,
    displayCharacters: true
};

// Custom update handler
const config: WordCountConfig = {
    onUpdate: (stats) => {
        // Update external UI
        document.getElementById('word-display').textContent = `${stats.words} words`;
        document.getElementById('char-display').textContent = `${stats.characters} characters`;
        
        // Validate against limits
        if (stats.words > 1000) {
            console.warn('Word limit exceeded');
        }
    }
};

// Auto-append to specific container
const config: WordCountConfig = {
    container: document.getElementById('editor-stats')
};

Update Events

Event type fired when word and character counts are updated.

type WordCountUpdateEvent = {
    name: 'update';
    args: [{ words: number; characters: number }];
};

Usage Example:

// Listen for count updates
wordCountPlugin.on('update', (evt, data) => {
    console.log(`Words: ${data.words}, Characters: ${data.characters}`);
    
    // Update progress bars, validation, etc.
    updateProgressIndicator(data.words, 500); // 500 word limit
});

// Note: The plugin also maintains private observable properties _wordsLabel and _charactersLabel
// that are automatically updated and used to display localized text in the wordCountContainer

Text Conversion Utility

Internal utility function for converting model elements to plain text (exported for advanced use cases).

/**
 * Returns a plain text representation of an element and its children
 * @param item - Model item to convert to plain text
 * @returns Plain text representing the model's data
 */
function modelElementToPlainText(item: ModelItem): string;

Note: This function is exported as modelElementToPlainText as _modelElementToPlainText from the main index, indicating it's intended for internal use but available for advanced use cases where custom text processing is needed.

Types

// Core model types from CKEditor 5 engine
interface ModelItem {
    is(type: string): boolean;
}

interface ModelElement extends ModelItem {
    getChildren(): Iterable<ModelItem>;
}

// Editor types from CKEditor 5 core
interface Editor {
    model: {
        document: {
            getRoots(): Iterable<ModelElement>;
            on(event: string, callback: Function): void;
        };
    };
    config: {
        get(path: string): any;
    };
    plugins: {
        get(name: string): Plugin;
    };
    t(message: string, ...values: any[]): string;
}

interface Plugin {
    constructor(editor: Editor);
    init?(): void;
    destroy?(): void;
    static pluginName?: string;
    static isOfficialPlugin?: boolean;
}

Error Handling

The plugin handles several common scenarios:

  • Model Changes: Gracefully handles rapid content changes through throttling
  • Container Management: Safely manages DOM element creation and cleanup
  • Unicode Support: Automatically detects and uses appropriate regex for word counting based on browser support
  • Memory Management: Properly cleans up event listeners and DOM elements on destroy

Common Error Scenarios:

// Plugin not loaded
try {
    const wordCount = editor.plugins.get('WordCount');
} catch (error) {
    console.error('WordCount plugin not available:', error);
}

// Invalid container element
const config: WordCountConfig = {
    container: document.getElementById('nonexistent') // Will be ignored if null
};

// Cleanup on editor destruction
editor.destroy().then(() => {
    // WordCount plugin automatically cleaned up
    console.log('Editor and plugins destroyed');
});