insertFromYank

How insertFromYank inputType handles yank operations (Vim-style copy) and varies across browsers.

Overview

The insertFromYank inputType is triggered when content is inserted via a "yank" operation. Yank is a Vim-style operation where text is copied to a register without being removed from its original location. This inputType is rarely used in standard web browsers and is more commonly found in specialized editors or browser extensions that implement Vim-like keybindings.

Basic Behavior

Scenario: Text yanked and inserted

Before (Cursor position)

HTML:
<p>Hello|world</p>

After yank operation (inserting "text ")

HTML:
<p>Hellotext world</p>
Yanked content inserted at cursor position

Browser Support

⚠️ Very Limited Browser Support

insertFromYank is not a standard inputType in most browsers. It is rarely, if ever, used by native browser implementations.

This inputType may be used by:

  • Browser extensions that implement Vim-like keybindings
  • Custom editor implementations that simulate Vim behavior
  • Specialized web applications with Vim emulation

In most cases, yank operations will trigger insertFromPaste or insertText instead.

Difference from insertFromPaste

insertFromYank

  • Vim-style operation - text copied to register
  • Original text remains in place (not cut)
  • Very rarely used in standard browsers
  • More common in Vim-like editors or extensions

insertFromPaste

  • Standard clipboard paste operation
  • Content copied from system clipboard
  • Widely supported across all browsers
  • Standard paste behavior (Ctrl/Cmd + V)

Editor-Specific Handling

Since insertFromYank is rarely used, most editors handle it similarly to paste operations. Here's how major editors could implement insertFromYank:

Slate.js

Yank Handling

Slate handles yank similarly to paste:

    import { Editor, Transforms } from 'slate';

element.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'insertFromYank' && e.dataTransfer) {
    e.preventDefault();
    
    // Get yanked content (similar to paste)
    const htmlString = e.dataTransfer.getData('text/html');
    const plainText = e.dataTransfer.getData('text/plain');
    
    // Parse and insert content (same as paste handling)
    const fragment = new DOMParser().parseFromString(htmlString || plainText, 'text/html');
    const nodes = Array.from(fragment.body.childNodes).map(node => {
      return jsx('element', { type: 'paragraph' }, [{ text: node.textContent || '' }]);
    });
    
    Transforms.insertNodes(editor, nodes);
  }
});
  
  • Similar to paste: Uses same handling as insertFromPaste.
  • DataTransfer access: Accesses yanked content via e.dataTransfer.
ProseMirror

Yank Handling

ProseMirror handles yank:

    import { DOMParser } from 'prosemirror-model';
import { schema } from './schema';

view.dom.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'insertFromYank' && e.dataTransfer) {
    e.preventDefault();
    const { state, dispatch } = view;
    
    const htmlString = e.dataTransfer.getData('text/html');
    const dom = new DOMParser(window).parseFromString(htmlString, 'text/html');
    
    // Parse HTML into ProseMirror nodes
    const fragment = DOMParser.fromSchema(schema).parse(dom.body);
    
    // Insert fragment at selection
    const tr = state.tr.replaceSelection(fragment);
    dispatch(tr);
  }
});
  
  • Same as paste: Uses same parsing and insertion logic as paste operations.
Draft.js

Yank Handling

Draft.js handles yank:

    import { EditorState } from 'draft-js';
import { stateFromHTML } from 'draft-js-import-html';

element.addEventListener('beforeinput', (e) => {
  if (e.inputType === 'insertFromYank' && e.dataTransfer) {
    e.preventDefault();
    
    const htmlString = e.dataTransfer.getData('text/html');
    
    // Convert HTML to ContentState
    const contentState = stateFromHTML(htmlString);
    
    // Insert content at selection
    const selection = editorState.getSelection();
    const newContentState = Modifier.replaceWithFragment(
      editorState.getCurrentContent(),
      selection,
      contentState.getBlockMap()
    );
    
    const newState = EditorState.push(
      editorState,
      newContentState,
      'insert-fragment'
    );
    
    setEditorState(newState);
  }
});
  
  • Same as paste: Uses same HTML import and insertion logic as paste operations.

Related resources