CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-wangeditor

Lightweight web-based rich text editor (WYSIWYG editor) built with JavaScript and CSS for modern browsers

Pending
Overview
Eval results
Files

selection.mddocs/

Selection Management

Text selection and cursor positioning APIs for programmatic text selection control.

Capabilities

Get Current Range

Get the current text selection range in the editor.

/**
 * Get current selection range
 * @returns Range object representing current selection, or null if no selection
 */
getRange(): Range | null;

Usage Examples:

// Get current selection
const range = editor.selection.getRange();
if (range) {
    console.log('Selection start:', range.startOffset);
    console.log('Selection end:', range.endOffset);
    console.log('Selected text:', range.toString());
} else {
    console.log('No selection');
}

// Check if text is selected
function hasSelection() {
    const range = editor.selection.getRange();
    return range && !range.collapsed;
}

// Get selection info
function getSelectionInfo() {
    const range = editor.selection.getRange();
    if (!range) return null;
    
    return {
        text: range.toString(),
        collapsed: range.collapsed,
        startOffset: range.startOffset,
        endOffset: range.endOffset
    };
}

Save Current Range

Save the current selection range for later restoration.

/**
 * Save current selection range
 * @param range - Optional specific range to save, defaults to current selection
 */
saveRange(range?: Range): void;

Usage Examples:

// Save current selection
editor.selection.saveRange();

// Save specific range
const range = editor.selection.getRange();
if (range) {
    editor.selection.saveRange(range);
}

// Save selection before modal/dialog
function openModal() {
    editor.selection.saveRange(); // Save current position
    showModal(); // User interaction may lose focus
}

// Save selection in event handler
editor.customConfig.onblur = function() {
    editor.selection.saveRange(); // Preserve selection when editor loses focus
};

Restore Saved Selection

Restore a previously saved selection range.

/**
 * Restore previously saved selection
 * Must be called after saveRange()
 */
restoreSelection(): void;

Usage Examples:

// Save and restore selection pattern
editor.selection.saveRange();
// ... some operation that may change selection
editor.selection.restoreSelection();

// Restore after modal close
function closeModal() {
    hideModal();
    editor.selection.restoreSelection(); // Restore saved position
}

// Maintain selection during operations
function insertAtSelection(html) {
    editor.selection.saveRange();
    editor.cmd.do('insertHTML', html);
    // Selection automatically moves to after inserted content
}

Create Range by Element

Create a selection range based on a DOM element.

/**
 * Create selection range by DOM element
 * @param elem - Target DOM element
 * @param toStart - Whether to position at start of element
 * @param isCollapseToEnd - Whether to collapse selection to end
 */
createRangeByElem(elem: Element, toStart: boolean, isCollapseToEnd: boolean): void;

Usage Examples:

// Select entire paragraph
const paragraph = editor.$textElem.find('p').get(0);
if (paragraph) {
    editor.selection.createRangeByElem(paragraph, true, false);
}

// Position cursor at start of element
const heading = editor.$textElem.find('h1').get(0);
if (heading) {
    editor.selection.createRangeByElem(heading, true, true);
}

// Position cursor at end of element
const lastParagraph = editor.$textElem.find('p').last().get(0);
if (lastParagraph) {
    editor.selection.createRangeByElem(lastParagraph, false, true);
}

Get Selection Container

Get the DOM element that contains the current selection.

/**
 * Get container element of current selection
 * @param range - Optional specific range, defaults to current selection
 * @returns DOM element containing the selection
 */
getSelectionContainerElem(range?: Range): Element;

Usage Examples:

// Get container of current selection
const container = editor.selection.getSelectionContainerElem();
console.log('Selection is in:', container.tagName);

// Get container of specific range
const range = editor.selection.getRange();
if (range) {
    const container = editor.selection.getSelectionContainerElem(range);
    console.log('Container:', container);
}

// Check if selection is in specific element type
function isSelectionInElement(tagName) {
    const container = editor.selection.getSelectionContainerElem();
    return container && container.tagName.toLowerCase() === tagName.toLowerCase();
}

// Usage
if (isSelectionInElement('h1')) {
    console.log('Selection is in a heading');
}

Get Selection Start Element

Get the DOM element at the start of the current selection.

/**
 * Get DOM element at selection start
 * @param range - Optional specific range, defaults to current selection
 * @returns DOM element at start of selection
 */
getSelectionStartElem(range?: Range): Element;

Get Selection End Element

Get the DOM element at the end of the current selection.

/**
 * Get DOM element at selection end
 * @param range - Optional specific range, defaults to current selection
 * @returns DOM element at end of selection
 */
getSelectionEndElem(range?: Range): Element;

Collapse Range

Collapse the current selection range to a single point.

/**
 * Collapse current selection to start or end
 * @param toStart - Whether to collapse to start (true) or end (false)
 */
collapseRange(toStart?: boolean): void;

Get Selection Text

Get the plain text content of the current selection.

/**
 * Get plain text of current selection
 * @returns Selected text as string, empty string if no selection
 */
getSelectionText(): string;

Check If Selection Is Empty

Check whether the current selection is empty (collapsed).

/**
 * Check if current selection is empty/collapsed
 * @returns True if selection is empty, false otherwise
 */
isSelectionEmpty(): boolean;

Create Empty Range

Create an empty selection range with a zero-width space marker.

/**
 * Create empty range with invisible marker
 * Used for maintaining cursor position in empty elements
 */
createEmptyRange(): void;

Complete Selection API Interface

interface SelectionAPI {
  /** Get current selection range */
  getRange(): Range | null;
  
  /** Save current selection range */
  saveRange(range?: Range): void;
  
  /** Restore previously saved selection */
  restoreSelection(): void;
  
  /** Create selection range by DOM element */
  createRangeByElem(elem: Element, toStart: boolean, isCollapseToEnd: boolean): void;
  
  /** Get container element of selection */
  getSelectionContainerElem(range?: Range): Element;
  
  /** Get DOM element at selection start */
  getSelectionStartElem(range?: Range): Element;
  
  /** Get DOM element at selection end */
  getSelectionEndElem(range?: Range): Element;
  
  /** Collapse selection to start or end */
  collapseRange(toStart?: boolean): void;
  
  /** Get plain text of selection */
  getSelectionText(): string;
  
  /** Check if selection is empty */
  isSelectionEmpty(): boolean;
  
  /** Create empty range with marker */
  createEmptyRange(): void;
}

Advanced Selection Patterns

Selection State Management

class SelectionManager {
    constructor(editor) {
        this.editor = editor;
        this.savedRanges = [];
    }
    
    pushSelection() {
        const range = this.editor.selection.getRange();
        if (range) {
            this.savedRanges.push(range.cloneRange());
        }
    }
    
    popSelection() {
        const range = this.savedRanges.pop();
        if (range) {
            this.editor.selection.saveRange(range);
            this.editor.selection.restoreSelection();
        }
    }
    
    hasSelection() {
        const range = this.editor.selection.getRange();
        return range && !range.collapsed;
    }
}

// Usage
const selectionManager = new SelectionManager(editor);
selectionManager.pushSelection();
// ... operations
selectionManager.popSelection();

Smart Content Insertion

// Insert content at selection with smart positioning
function smartInsert(html, restoreSelection = true) {
    // Save current selection
    editor.selection.saveRange();
    
    // Insert content
    editor.cmd.do('insertHTML', html);
    
    // Optionally restore selection
    if (restoreSelection) {
        // Move selection to after inserted content
        setTimeout(() => {
            const range = editor.selection.getRange();
            if (range) {
                range.collapse(false); // Collapse to end
                editor.selection.saveRange(range);
                editor.selection.restoreSelection();
            }
        }, 0);
    }
}

// Usage
smartInsert('<strong>Bold text</strong>');
smartInsert('<img src="image.jpg" alt="Image">', false);

Selection-based Formatting

// Apply formatting only to selected text
function formatSelection(command, value) {
    const range = editor.selection.getRange();
    
    if (!range || range.collapsed) {
        console.log('No text selected');
        return false;
    }
    
    // Save selection
    editor.selection.saveRange();
    
    // Apply formatting
    editor.cmd.do(command, value);
    
    // Restore selection to see the result
    editor.selection.restoreSelection();
    
    return true;
}

// Usage
formatSelection('bold');
formatSelection('foreColor', '#ff0000');

Context-aware Operations

// Perform operations based on selection context
function contextAwareOperation() {
    const container = editor.selection.getSelectionContainerElem();
    const tagName = container.tagName.toLowerCase();
    
    switch (tagName) {
        case 'h1':
        case 'h2':
        case 'h3':
            console.log('Selection is in a heading');
            // Heading-specific operations
            break;
            
        case 'p':
            console.log('Selection is in a paragraph');
            // Paragraph-specific operations
            break;
            
        case 'li':
            console.log('Selection is in a list item');
            // List-specific operations
            break;
            
        default:
            console.log('Selection is in:', tagName);
    }
}

Selection Utilities

// Utility functions for common selection tasks
const SelectionUtils = {
    // Check if entire element is selected
    isElementSelected(element) {
        const range = editor.selection.getRange();
        if (!range) return false;
        
        const selection = window.getSelection();
        return selection.containsNode(element, false);
    },
    
    // Select entire word at cursor
    selectWordAtCursor() {
        const range = editor.selection.getRange();
        if (!range) return;
        
        range.expand('word');
        editor.selection.saveRange(range);
        editor.selection.restoreSelection();
    },
    
    // Get selected text with formatting preserved
    getSelectedHTML() {
        const range = editor.selection.getRange();
        if (!range) return '';
        
        const container = document.createElement('div');
        container.appendChild(range.cloneContents());
        return container.innerHTML;
    },
    
    // Move cursor to end of editor
    moveToEnd() {
        const textElem = editor.$textElem.get(0);
        if (textElem) {
            editor.selection.createRangeByElem(textElem, false, true);
        }
    }
};

// Usage
if (SelectionUtils.isElementSelected(someElement)) {
    console.log('Element is fully selected');
}

SelectionUtils.selectWordAtCursor();
const selectedHTML = SelectionUtils.getSelectedHTML();
SelectionUtils.moveToEnd();

Install with Tessl CLI

npx tessl i tessl/npm-wangeditor

docs

commands.md

configuration.md

content-operations.md

editor-management.md

image-upload.md

index.md

menus.md

selection.md

tile.json