MSEdgeExplainers

Explainer: InputEvent.dataTransfer Feature For Contenteditable Host

Authors:

Participate

Table of Contents

Introduction

Modern web applications rely heavily on rich text editing experiences, especially within contenteditable elements. InputEvent.dataTransfer is a property that provides access to a dataTransfer object during input events triggered by paste, drop, or replacement actions. It allows developers to inspect and handle the data being inserted. However, developers have long faced limitations when handling paste and drop operations due to the absence of the dataTransfer property on Input Event Types objects. This explainer proposes that InputEvent.dataTransfer be exposed for specific input types insertFromPaste, insertReplacementText, and insertFromDrop within contenteditable contexts. This change puts Chromium in alignment with the W3C spec.

User-Facing Problem

A user pastes formatted content (e.g., bold text, lists, links) into a custom editor. The developers listening to the input event with inputType = "insertFromPaste" in the following example couldn’t access InputEvent.dataTransfer — it was null.

<p contenteditable="true">
  Go on, try pasting some content into this editable paragraph and see what
  happens!
</p>

<p class="result"></p>
const editable = document.querySelector("p[contenteditable]");
const result = document.querySelector(".result");
editor.addEventListener("input", (event) => {
  if (event.inputType === "insertFromPaste" && event.dataTransfer) { // fails on the second condition and lines below are not executed as event.dataTransfer is NULL.
    const html = event.dataTransfer.getData("text/html");
    const text = event.dataTransfer.getData("text/plain");
    // Use html/text for sanitization, logging, or formatting
  }
});

When dataTransfer was NULL, Users

After the fix, dataTransfer is exposed on the input event.

Goals

The goal of this feature is to expose the dataTransfer property on InputEvent objects for specific input types insertFromPaste, insertReplacementText, and insertFromDrop in contenteditable contexts. This enables developers to access drag-and-drop and clipboard data during input events, improving support for rich text editors and other interactive content tools. What developers can do with dataTransfer

  1. Access Rich Clipboard Data

    • Developers can inspect dataTransfer.getData("text/html") to:
      • Sanitize pasted HTML for security.
      • Preserve formatting in custom editors.
  2. Customize Paste/Drop Behavior

    • Developers can override default behavior based on:
      • MIME types in dataTransfer.items.
      • Source metadata (e.g., URLs, app-specific formats).
      • User intent (e.g., distinguish between plain text and rich content).
  3. Audit and Logging

    • Developers can log what was pasted or dropped for:
      • Accessibility tracking.
      • Undo/redo history.
      • Security audits.
  4. Improve Accessibility and UX

    • For spelling corrections (insertReplacementText), developers can:
      • Track automated vs manual changes.
      • Provide visual feedback or undo options.
      • Integrate with grammar tools or custom dictionaries.

Non-goals

This feature does not:

Motivation

The W3C Input Events Level 2 specification requires that dataTransfer be available for certain input types. Prior to this feature, Chromium did not expose dataTransfer on InputEvent for insertFromPaste, insertReplacementText, and insertFromDrop, resulting in inconsistent behavior across browsers and limiting developer capabilities.

This feature addresses:

Code Example

Before the Fix

editor.addEventListener("input", (event) => {
  console.log(event.inputType); // e.g., "insertFromDrop"
  console.log(event.dataTransfer); // null
});

After the Fix

editor.addEventListener("input", (event) => {
  console.log(event.inputType); // e.g., "insertFromDrop"
  console.log(event.dataTransfer); // non-null
  if (event.dataTransfer) {
    console.log("Dropped plain data:", event.dataTransfer.getData("text/plain"));
    console.log("Dropped html data:", event.dataTransfer.getData("text/html"));
  }
});

In the implementation, dataTransfer property is attached only when the target is a contenteditable element, excluding form controls (input or textarea).

Considered Alternatives

Security and Privacy

This proposal has no known impact on accessibility or privacy and does not alter the permission or security model. The dataTransfer property is exposed only when the browser determines it is appropriate based on the input event type and context. It is scoped to contenteditable elements and does not alter drag-and-drop security model. No new information is exposed to sites because the same information is also exposed during the beforeinput event.

Performance Impact

The feature introduces minimal overhead, as dataTransfer is conditionally attached only when relevant. No significant performance regressions were observed during testing.

Interoperability

This feature aligns with the W3C Input Events Level 2 specification and matches behavior in Safari and Firefox. It improves cross-browser consistency for developers.

References and Acknowledgements

Many thanks for valuable feedback and advice from: