Skip to content

Type Editor


Type Editor / @type-editor/dom-change-util

@type-editor/dom-change-util

This module was part of the ProseMirror view module.

DOM mutation detection and processing utilities for Type Editor. This module handles reading changes from the DOM and converting them into editor transactions.

Installation

bash
npm install @type-editor/dom-change-util

Overview

This module provides the core functionality for detecting and processing DOM mutations in a content-editable editor. It bridges the gap between browser DOM changes and the Type Editor's document model, handling various browser-specific quirks and edge cases.

Key Responsibilities

  • Parse DOM changes and convert them to document changes
  • Handle browser-specific quirks (Chrome, Safari, IE11, Android, iOS)
  • Detect and optimize mark changes (bold, italic, etc.)
  • Manage selection reconstruction after DOM mutations
  • Handle composition events and IME input

API

readDOMChange

The main entry point for processing DOM mutations. Reads changes from the DOM and converts them into editor transactions.

typescript
import { readDOMChange } from "@type-editor/dom-change-util";

readDOMChange(view, from, to, typeOver, addedNodes);

Parameters

ParameterTypeDescription
viewEditorViewThe editor view containing the DOM and document state
fromnumberStart position of the change. Negative values indicate selection-only changes
tonumberEnd position of the change
typeOverbooleanWhether this change is part of typing over an active selection
addedNodesReadonlyArray<Node>DOM nodes added during the mutation

Processing Pipeline

  1. Selection-only changes: When from < 0, handles pure selection updates without content changes
  2. Range adjustment: Expands the change range to block boundaries for accurate parsing
  3. DOM parsing: Parses the changed DOM range into a document representation
  4. Diff detection: Compares parsed content with the current document to find differences
  5. Browser adjustments: Applies browser-specific fixes and workarounds
  6. Transaction dispatch: Creates and dispatches appropriate transactions

Browser Compatibility

The module includes specific handling for:

BrowserSpecial Handling
ChromeBackspace behavior, composition deletion quirks
Safari/iOSEnter key detection, selection timing
IE11Non-breaking space insertion, selection positioning
AndroidEnter-and-pick-suggestion action, virtual keyboard quirks
EdgeCursor advancement in empty blocks

Types

DocumentChange

Represents a detected change in the document.

typescript
interface DocumentChange {
  /** Start position of the change */
  start: number;
  /** End position in the old document */
  endA: number;
  /** End position in the new document */
  endB: number;
}

ParseBetweenResult

Result of parsing a DOM range into a document.

typescript
interface ParseBetweenResult {
  /** Parsed document node */
  doc: Node;
  /** Reconstructed selection (anchor/head positions) */
  sel: { anchor: number; head: number } | null;
  /** Start position where parsing began */
  from: number;
  /** End position where parsing ended */
  to: number;
}

Internal Structure

src/
├── index.ts                    # Package exports
└── dom-change/
    ├── read-dom-change.ts      # Main entry point
    ├── constants.ts            # Shared constants
    ├── browser-hacks/          # Browser-specific workarounds
    │   ├── is-android-enter-suggestion-quirk.ts
    │   ├── is-ie11-non-breaking-space-bug.ts
    │   ├── should-handle-mobile-enter-key.ts
    │   └── ...
    ├── parse-change/           # Change detection and parsing
    │   ├── find-diff.ts
    │   ├── parse-between.ts
    │   ├── is-mark-change.ts
    │   ├── looks-like-enter-key.ts
    │   ├── looks-like-backspace-key.ts
    │   └── ...
    ├── types/                  # Type definitions
    │   └── dom-change/
    │       ├── DocumentChange.ts
    │       ├── ParseBetweenResult.ts
    │       └── ...
    └── util/                   # Helper utilities

Notes

All referencing and parsing is done with the start-of-operation selection and document, since that's what the DOM represents. If any changes came in the meantime, the modification is mapped over those before it is applied.

License

MIT

Modules

ModuleDescription

browser-hacks/adjust-for-chrome-backspace-bug

browser-hacks/handle-br-node-rule

browser-hacks/is-android-enter-suggestion-quirk

browser-hacks/is-ie11-non-breaking-space-bug

browser-hacks/looks-likes-enter-key-ios

browser-hacks/should-handle-android-enter-key

browser-hacks/should-handle-mobile-enter-key

browser-hacks/should-suppress-selection-during-composition

constants

parse-change/find-diff

parse-change/get-preferred-diff-position

parse-change/handle-selection-only-change

parse-change/is-mark-change

parse-change/looks-like-backspace

parse-change/looks-like-backspace-key

parse-change/looks-like-enter-key

parse-change/needs-selection-overwrite-adjustment

parse-change/parse-between

parse-change/resolve-selection

parse-change/should-adjust-change-end-to-selection

parse-change/should-adjust-change-start-to-selection

parse-change/should-create-type-over-change

read-dom-change

Remarks

All referencing and parsing is done with the start-of-operation selection and document, since that's the one that the DOM represents. If any changes came in the meantime, the modification is mapped over those before it is applied.

types/dom-change/DocumentChange

types/dom-change/DOMPositionInfo

types/dom-change/MarkChangeInfo

types/dom-change/ParseBetweenResult

util/key-event