# Clipboard API and events

## Editor’s Draft, 1 January 1970

This version:
  https://w3c.github.io/clipboard-apis/
Latest published version:
  https://www.w3.org/TR/clipboard-apis/
Previous Versions:
  https://www.w3.org/TR/2019/WD-clipboard-apis-20190530/
Editors:
  Gary Kacmarcik (Google)
  Grisha Lyukshin (Microsoft)
Former Editor:
  Hallvord R. M. Steen (Mozilla)
Explainer:
  Async Clipboard API Explainer

Copyright © 1970 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.

## Abstract

This document describes APIs for accessing data on the system clipboard. It provides operations for overriding the default clipboard actions (cut, copy and paste), and for directly accessing the clipboard contents.

## Status of this document

This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.

This document was published by the Web Applications Working Group as an Editors Draft. This document is intended to become a W3C Recommendation.

Changes to this document may be tracked at https://github.com/w3c/clipboard-apis.

This document was published by the Web Applications Working Group as a Working Draft. Feedback and comments on this specification are welcome. Please use GitHub issues Historical discussions can be found in the public-webapps@w3.org archives.

Publication as an Editors Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.

This document was produced by a group operating under the W3C Patent Policy. W3C maintains a public list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.

This document is governed by the 1 March 2019 W3C Process Document.

## 1. Introduction

This section is non-normative.

This specification defines how the system clipboard is exposed to web applications.

There are two general APIs described in this specification:

- Clipboard Event API - This API provides a way to hook into the common clipboard operations of cutting, copying and pasting so that web application can adjust the clipboard data as required.

- Async Clipboard API - This API provides direct access to read and write the clipboard data. Since this is considered to be a powerful feature, access to this API is controlled by a permission.

## 2. Use Cases

This section is non-normative.

### 2.1. Changing Default Clipboard Operations

There are many scenarios where it is desireable to change the default clipboard operations (cut/copy/paste). Here are a few examples:

- Metadata When copying text from a repository of documents, it can be useful for the copied text to include metadata about the source of the copied content.
- Rich content editing When copying text which contains hyperlinks or other structure, it is often useful to be able to reformat the content to preserve important information.
- Graphics with built-in semantics In order to make web applications which allow the manipulation of rich text, or of graphic content such as [SVG11], it is useful to provide a mechanism that allows for copying more than just the rendered content.
- Mathematical information With content such as mathematics, simply copying rendered text and pasting it into another application generally leads to most of the semantics being lost. MathML often needs to be transformed to be copied as plain text, for example to make sure "to the power of" is shown with the caret "^" sign in a formula plain-text input. The XML source could also be placed in the clipboard with the appropriate transformation occurring at paste time.

### 2.2. Remote Clipboard Synchronization

For web applications that communicate with remote devices (e.g., remote access or remote shell applications), there is often a need for the clipboard data to be kept in sync between the two devices.

One important aspect of this use case is that it requires access to the clipboard in the absense of a user gesture or interaction.

To copy the clipboard data from a remote device to the local clipboard, a web application would take the remote clipboard data and then `write()` the data to the local clipboard.
To copy the local clipboard data to a remote device, a web application would listen for clipboardchange events, `read()` from the clipboard whenever it is updated, and then send the new clipboard data to the remote device.

### 2.3. Trigger Clipboard Actions

Applications that provide an alternate interface to a user agent sometimes need to be able to trigger clipboard actions in the user agent.

As an example, consider a screen reader application that provides a more accessible interface to a standard web browser. While the reader can display content and allow the user to interact with it, actions like clipboard copy need to occur in the underlying browser to ensure that the clipboard content is set correctly (with any metadata added by the browser during copy).

## 3. Terminology

The term editable context means any element that is either an editing host, a textarea element, or an input element with its type attribute set to any of "text", "search", "tel", "url", "email", "password" or "number".

## 4. Model

The platform provides a system clipboard.

The system clipboard has a list of clipboard items that are collectively called the system clipboard data.

- For the § 6 Clipboard Event API, the system clipboard data is exposed as a `DataTransfer` object that mirrors the contents of the clipboard.

- For the § 7 Asynchronous Clipboard API, the system clipboard data is exposed as a sequence of `ClipboardItem` objects that mirrors the contents of the clipboard.

## 5. Clipboard Events

### 5.1. Clipboard event interfaces

The ClipboardEvent interface extends the `Event` interface.

    dictionary ClipboardEventInit : EventInit {
      DataTransfer? clipboardData = null;
    };

clipboardData

  A `DataTransfer` object to hold data and meta data related to the event.

    [Constructor(DOMString type, optional ClipboardEventInit eventInitDict = {}), Exposed=Window]
    interface ClipboardEvent : Event {
      readonly attribute DataTransfer? clipboardData;
    };

clipboardData

  The clipboardData attribute is an instance of the `DataTransfer` interface which lets a script read and manipulate values on the system clipboard during user-initiated copy, cut and paste operations. The associated drag data store is a live but filtered view of the system clipboard, exposing mandatory data types the implementation knows the script can safely access. For synthetic events, the drag data store contains the data added by the script that created the event.

  The clipboardData object’s `items` and `files` properties enable processing of multi-part or non-textual data from the clipboard.

The interface can be used to construct events. An example is given below:

    var pasteEvent = new ClipboardEvent('paste');
    pasteEvent.clipboardData.items.add('My string', 'text/plain');
    document.dispatchEvent(pasteEvent);

Note: Synthetic clipboard events will not actually modify the clipboard or the document. In other words, while the script above will fire a paste event, the data will not be pasted into the document.

### 5.2. Clipboard events

#### 5.2.1. The clipboardchange event

The clipboardchange event fires whenever the contents of the system clipboard are changed. These changes could be due to any of the following (non-exhaustive):

- User-initiated cut or copy actions

- Scripts that use the § 7 Asynchronous Clipboard API to write to the clipboard

- Actions that update the clipboard outside the user agent

If the clipboard contents are changed outside the user agent, then the clipboardchange event MUST fire when the user agent regains focus.

Since synthetic cut and copy events do not update the system clipboard, they will not trigger a "clipboardchange" event.

#### 5.2.2. The copy event

When the user initiates a copy action, the user agent fires a clipboard event named copy.

If the event is not canceled, the currently selected data will be copied to the system clipboard. The current document selection is not affected.

The copy event bubbles, is cancelable, and is composed.

See § 8.1 The copy action for a detailed description of the processing model for this event.

A synthetic copy event can be manually constructed and dispatched, but it will not affect the contents of the system clipboard.

#### 5.2.3. The cut event

When the user initiates a cut action, the user agent fires a clipboard event named cut.

In an editable context, if the event is not canceled the action will place the currently selected data on the system clipboard and remove the selection from the document. The cut event fires before the selected data is removed. When the cut operation is completed, the selection is collapsed.

In a non-editable context, the `clipboardData` will be an empty list. Note that the cut event will still be fired in this case.

The cut event bubbles, is cancelable, and is composed.

See § 8.2 The cut action for a detailed description of the processing model for this event.

A synthetic cut event can be manually constructed and dispatched, but it will not affect the contents of the document or of the system clipboard.

#### 5.2.4. The paste event

When a user initiates a paste action, the user agent fires a clipboard event named paste. The event fires before any clipboard data is inserted into the document.

If the cursor is in an editable context, the paste action will insert clipboard data in the most suitable format (if any) supported for the given context.

The paste action has no effect in a non-editable context, but the paste event fires regardless.

The paste event bubbles, is cancelable, and is composed.

See § 8.3 The paste action for a detailed description of the processing model for this event.

A synthetic paste event can be manually constructed and dispatched, but it will not affect the contents of the document.

### 5.3. Integration with other scripts and events

#### 5.3.1. Event handlers that are allowed to modify the clipboard

Event handlers may write to the clipboard if any of the following is true:

- The action which triggers the event is invoked from the user-agent’s own user interface, e.g. from a "Copy" menu entry or shortcut key.

- The action which triggers the event is invoked from a scripting thread which is allowed to show a popup.

The implementation may allow other trusted event types to modify the clipboard if the implementation authors believe that those event types are likely to express user intention. The implementation may also support configuration that trusts specific sites or apps to modify the clipboard regardless of the origin of the scripting thread.

Synthetic cut and copy events must not modify data on the system clipboard.

#### 5.3.2. Event handlers that are allowed to read from clipboard

Event handlers may read data from the system clipboard if either of the following is true

- The action that triggers the event is invoked from the user-agent’s own user interface, e.g. a "Paste" menu entry or shortcut key.

- The script that triggers the action is running on a site which through an implementation-dependant mechanism is given permission to read data from the clipboard.

- The action that triggers the event is triggered in an app with permissions to read the clipboard.

Synthetic paste events must not give a script access to data on the real system clipboard.

#### 5.3.3. Integration with rich text editing APIs

If an implementation supports ways to execute clipboard commands through scripting, for example by calling the `document.execCommand()` method with the commands "cut", "copy" and "paste", the implementation must trigger the corresponding action, which again will dispatch the associated clipboard event.

These are the steps to follow when triggering copy, cut or paste actions through a scripting API:

1. Execute the corresponding action synchronously.

2. Use the action’s return value as the return value for the API call.

Note: Copy and cut commands triggered through a scripting API will only affect the contents of the real clipboard if the event is dispatched from an event that is trusted and triggered by the user, or if the implementation is configured to allow this. Paste commands triggered through a scripting API will only fire paste events and give access to clipboard contents if the implementation is configured to allow this. How implementations can be configured to allow read or write access to the clipboard is outside the scope of this specification.

#### 5.3.4. Interaction with other events

If the clipboard operation is triggered by keyboard input, the implementation must fire the corresponding event that initiates the clipboard operation. The event is asynchronous but must be dispatched before keyup events for the relevant keys.

The cut and paste actions may cause the implementation to dispatch other supported events, such as textInput, input, change, validation events, DOMCharacterDataModified and DOMNodeRemoved / DOMNodeInserted. Any such events are queued up to fire after processing of the cut/paste event is finished.

The implementation must not dispatch other input-related events like textInput, input, change, and validation events in response to the copy operation.

#### 5.3.5. Event listeners that modify selection or focus

If the event listener modifies the selection or focusable area, the clipboard action must be completed on the modified selection.

## 6. Clipboard Event API

The Clipboard Event API allows you to override the default cut, copy and paste behavior of the user agent.

Access to the clipboard is performed using the standard `DataTransfer` methods to mutate the `items` on a `ClipboardEvent`'s `clipboardData` attribute. One consequence of this is that these clipboard APIs can only access clipboard data in the context of a `ClipboardEvent` handler.

Note: If you need to access the clipboard outside of a clipboard event handler, see § 7 Asynchronous Clipboard API.

Note: The Clipboard Event APIs are synchronous, so they are limited in what they can do. Actions which are potentially blocking (like asking for permission or transcoding a image) are not supported by these APIs. See § 7 Asynchronous Clipboard API for a more powerful API that can support blocking or other time-consuming actions.

### 6.1. Overriding the copy event

To override the default copy event behavior, a copy event handler must be added and this event handler must call `preventDefault()` to cancel the event.

Canceling the event is required in order for the system clipboard to be updated with the data in `clipboardData`. If the `ClipboardEvent` is not canceled, then the data from the current document selection will be copied instead.

    // Overwrite what is being copied to the clipboard.
    document.addEventListener('copy', function(e) {
      // e.clipboardData is initially empty, but we can set it to the
      // data that we want copied onto the clipboard.
      e.clipboardData.setData('text/plain', 'Hello, world!');
      e.clipboardData.setData('text/html', '<b>Hello, world!</b>');

      // This is necessary to prevent the current document selection from
      // being written to the clipboard.
      e.preventDefault();
    });

### 6.2. Overriding the cut event

To override the default cut event behavior, a cut event handler must be added and this event handler must call `preventDefault()` to cancel the event.

Canceling the event is required in order for the system clipboard to be updated with the data in `clipboardData`. If the `ClipboardEvent` is not canceled, then the data from the current document selection will be copied instead.

Note that canceling the cut event will also prevent the document from being updated (i.e., the current selection will not be removed). The event handler will need to manually update the document to remove the currently selected text.

    // Overwrite what is copied to the clipboard.
    document.addEventListener('cut', function(e) {
      // e.clipboardData is initially empty, but we can set it to the
      // data that we want copied onto the clipboard as part of the cut.
      // Write the data that we want copied onto the clipboard.
      e.clipboardData.setData('text/plain', 'Hello, world!');
      e.clipboardData.setData('text/html', '<b>Hello, world!</b>');

      // Since we will be canceling the cut operation, we need to manually
      // update the document to remove the currently selected text.
      deleteCurrentDocumentSelection();

      // This is necessary to prevent the document selection from being
      // written to the clipboard.
      e.preventDefault();
    });

### 6.3. Overriding the paste event

To override the default paste event behavior, a paste event handler must be added and this event handler must call `preventDefault()` to cancel the event.

Canceling the event is required so that the user agent does not update the document with data from the system clipboard.

Note that canceling the paste event will also prevent the document from being updated (i.e., nothing will be pasted into the document). The event handler will need to manually paste the data into the document.

Also note that, when pasting, the drag data store mode flag is read-only, hence calling `setData()` from a paste event handler will not modify the data that is inserted, and not modify the data on the clipboard.

    // Overwrite what is being pasted onto the clipboard.
    document.addEventListener('paste', function(e) {
      // e.clipboardData contains the data that is about to be pasted.
      if (e.clipboardData.types.indexOf('text/html') > -1) {
        var oldData = e.clipboardData.getData('text/html');
        var newData = '<b>Ha Ha!</b> ' + oldData;

        // Since we are canceling the paste operation, we need to manually
        // paste the data into the document.
        pasteClipboardData(newData);

        // This is necessary to prevent the default paste action.
        e.preventDefault();
      }
    });

### 6.4. Mandatory data types

The implementation must recognise the native OS clipboard format description for the following data types, to be able to populate the `DataTransferItemList` with the correct description for paste events, and set the correct data format on the OS clipboard in response to copy and cut events.

#### 6.4.1. Reading from the clipboard

These data types must be exposed by paste events if a corresponding native type exists on the clipboard:

- text/plain

- text/uri-list

- text/csv

- text/css

- text/html

- application/xhtml+xml

- image/png

- image/jpg, image/jpeg

- image/gif

- image/svg+xml

- application/xml, text/xml

- application/javascript

- application/json

- application/octet-stream

#### 6.4.2. Writing to the clipboard

These data types must be placed on the clipboard with a corresponding native type description if added to a `DataTransfer` object during copy and cut events.

- text/plain

- text/uri-list

- text/csv

- text/html

- image/svg+xml

- application/xml, text/xml

- application/json

Warning! The data types that untrusted scripts are allowed to write to the clipboard are limited as a security precaution. Untrusted scripts can attempt to exploit security vulnerabilities in local software by placing data known to trigger those vulnerabilities on the clipboard.

## 7. Asynchronous Clipboard API

### 7.1. Navigator Interface

    partial interface Navigator {
      [SecureContext, SameObject] readonly attribute Clipboard clipboard;
    };

#### 7.1.1. clipboard

The clipboard attribute must return the `Navigator`'s clipboard object.

### 7.2. Clipboard Interface

    typedef sequence<ClipboardItem> ClipboardItems;

    [SecureContext, Exposed=Window] interface Clipboard : EventTarget {
      Promise<ClipboardItems> read();
      Promise<DOMString> readText();
      Promise<void> write(ClipboardItems data);
      Promise<void> writeText(DOMString data);
    };

    typedef (DOMString or Blob) ClipboardItemDataType;
    typedef Promise<ClipboardItemDataType> ClipboardItemData;

    callback ClipboardItemDelayedCallback = ClipboardItemData ();

    [Constructor(record<DOMString, ClipboardItemData> items,
        optional ClipboardItemOptions options = {}),
     Exposed=Window] interface ClipboardItem {
      static ClipboardItem createDelayed(
          record<DOMString, ClipboardItemDelayedCallback> items,
          optional ClipboardItemOptions options = {});

      readonly attribute PresentationStyle presentationStyle;
      readonly attribute long long lastModified;
      readonly attribute boolean delayed;

      readonly attribute FrozenArray<DOMString> types;

      Promise<Blob> getType(DOMString type);
    };

    enum PresentationStyle { "unspecified", "inline", "attachment" };

    dictionary ClipboardItemOptions {
      PresentationStyle presentationStyle = "unspecified";
    };

#### 7.2.1. read()

The `read()` method must run these steps:

1. Let p be a new Promise.

2. Run the following steps in parallel:

   1. Let r be the result of running check clipboard read permission in parallel

   2. If r is not "granted", then reject p with a "NotAllowedError" DOMException

   3. Let data be a copy of the system clipboard data represented as a sequence of `ClipboardItem`s.

   4. Resolve p with data.

3. Return p.

    const items = await navigator.clipboard.read();
    const textBlob = await items[0].getType("text/plain");
    const text = await (new Response(textBlob)).text();

#### 7.2.2. readText()

The `readText()` method must run these steps:

1. Let p be a new Promise.

2. Run the following steps in parallel:

   1. Let r be the result of running check clipboard read permission in parallel

   2. If r is not "granted", then reject p with a "NotAllowedError" DOMException

   3. Let data be a copy of the system clipboard data.

   4. Let textData be an empty string.

   5. If data contains a "text/plain" item textItem, then:

      1. Set textData to be a copy of textItem’s string data

   6. Resolve p with textData.

3. Return p.

    navigator.clipboard.readText().then(function(data) {
      console.log(“Your string: ”, data);
    });

#### 7.2.3. write(data)

The `write(data)` method must run these steps:

1. Let p be a new Promise.

2. Run the following steps in parallel:

   1. Let r be the result of running check clipboard write permission in parallel

   2. If r is not "granted", then reject p with a "NotAllowedError" DOMException

   3. Let cleanItemList be an empty sequence<`Blob`>.

   4. For each `Blob` item in data:

      1. Let cleanItem be a sanitized copy of item.

      2. If unable to create a sanitized copy, then reject p.

      3. Add cleanItem to cleanItemList.

   5. Replace the system clipboard data with cleanItemList.

   6. Resolve p.

3. Return p.

    var data = new Blob(["Text data"], {type : "text/plain"});
    navigator.clipboard.write(data).then(function() {
      console.log(“Copied to clipboard successfully!”);
    }, function() {
      console.error(“Unable to write to clipboard. :-(”);
    });

#### 7.2.4. writeText(data)

The `writeText(data)` method must run these steps:

1. Let p be a new Promise.

2. Run the following steps in parallel:

   1. Let r be the result of running check clipboard write permission in parallel

   2. If r is not "granted", then reject p with a "NotAllowedError" DOMException

   3. Let newItemList be an empty sequence<`ClipboardItem`>.

   4. Let textBlob be a new `Blob` created with: type attribute set to text/plain;charset=utf-8, and blobParts set to a sequence containing the string data.

   5. Let newItem be a new `ClipboardItem` created with a single representation: type attribute set to text/plain8, and data set to textBlob.

   6. Add newItem to newItemList.

   7. Replace the system clipboard data with newItemList.

   8. Resolve p.

3. Return p.

    await navigator.clipboard.writeText("Howdy, partner!");

## 8. Clipboard Actions

This section defines clipboard actions and the processing model for event dispatch.

Each clipboard action has two flags called script-triggered and script-may-access-clipboard.

The script-triggered flag is set if the action runs because of a script, for example a `document.execCommand()` call. Future scripting APIs that interact with the clipboard should also use these actions, and the script-triggered flag must be set accordingly.

The script-may-access-clipboard flag is set as follows:

1. If action is copy or cut and the script thread is allowed to modify the clipboard, then

   1. Set the action’s script-may-access-clipboard flag

2. If action is paste and the script thread is allowed to read from clipboard, then

   1. Set the action’s script-may-access-clipboard flag.

### 8.1. The copy action

The copy action consists of the following steps:

1. If the script-triggered flag is set, then

   1. If the script-may-access-clipboard flag is unset, then

      1. Return false from the copy action, terminate this algorithm

2. Fire a clipboard event named copy

3. If the event was not canceled, then

   1. Copy the selected contents, if any, to the clipboard. Implementations should create alternate text/html and text/plain clipboard formats when content in a web page is selected.

   2. Fire a clipboard event named clipboardchange

4. Else, if the event was canceled, then

   1. Call the write content to the clipboard algorithm, passing on the `DataTransferItemList` list items, a clear-was-called flag and a types-to-clear list.

5. Return true from the copy action

### 8.2. The cut action

The cut action consists of the following steps:

1. If the script-triggered flag is set, then

   1. If the script-may-access-clipboard flag is unset, then

      1. Return false from the cut action, terminate this algorithm

2. Fire a clipboard event named cut

3. If the event was not canceled, then

   1. If there is a selection in an editable context where cutting is enabled, then

      1. Copy the selected contents, if any, to the clipboard. Implementations should create alternate text/html and text/plain clipboard formats when content in a web page is selected.

      2. Remove the contents of the selection from the document and collapse the selection.

      3. Fire a clipboard event named clipboardchange

      4. Queue tasks to fire any events that should fire due to the modification, see § 5.3 Integration with other scripts and events for details.

   2. Else, if there is no selection or the context is not editable, then

      1. Return false

4. Else, if the event was canceled, then

   1. Call the write content to the clipboard algorithm, passing on the `DataTransferItemList` list items, a clear-was-called flag and a types-to-clear list.

   2. Fire a clipboard event named clipboardchange

5. Return true from the cut action

### 8.3. The paste action

For the paste action, the script-may-access-clipboard flag depends on an implementation-specific permission mechanism for determining what sites or apps may read from the clipboard. When a paste action is triggered by a script, the implementation must not make clipboard contents available without the user’s permission. If the permission has not already been granted, the permission prompt must include the hostname of the document associated with the script thread.

The paste action consists of the following steps:

1. If the script-triggered flag is set, then

   1. If script-may-access-clipboard is unset, then

      1. Return false from the paste action, terminate this algorithm

2. Fire a clipboard event named paste

3. If the event was not canceled, then

   1. If there is a selection or cursor in an editable context where pasting is enabled, then

      1. Insert the most suitable content found on the clipboard, if any, into the context.

      2. Queue tasks to fire any events that should fire due to the modification, see § 5.3 Integration with other scripts and events for details.

   2. Else

      1. Return false

4. Else, if the event was canceled

   1. Return false

5. Return true from the action

## 9. Permissions API Integration

The [permissions] API provides a uniform way for websites to access powerful features like the clipboard. It allows websites to request permissions from users and query which permissions they have.

For the clipboard, two separate permissions are defined: `"clipboard-read"` and `"clipboard-write"`

Note: Clipboard permissions currently only apply to the Async Clipboard API. Future versions of this specification may be updated to apply this permission to other Clipboard interactions.

These clipboard permissions are powerful features permission-related algorithms and types are defined as follows:

permission descriptor type

      dictionary ClipboardPermissionDescriptor : PermissionDescriptor {
        boolean allowWithoutGesture = false;
      };

  There are 4 clipboard permissions:

  - { name: "clipboard-read", allowWithoutGesture: false }

  - { name: "clipboard-read", allowWithoutGesture: true }

  - { name: "clipboard-write", allowWithoutGesture: false }

  - { name: "clipboard-write", allowWithoutGesture: true }

  With the following relationships:

  - `{ "clipboard-read" + true }` is stronger than `{ "clipboard-read" + false }`

  - `{ "clipboard-write" + true }` is stronger than `{ "clipboard-write" + false }`

  Note: "clipboard-read" and "clipboard-write" are two separate permissions with no inherent strength relationship. However, user agents MAY choose to impose such a strength ordering on these permissions, for example by making the "clipboard-read" permission act stronger than the "clipboard-write" permission. Doing this would effectively turn the "clipboad-read" permission into a way to provide full read/write access to the clipboard since granting (or denying) "clipboard-read" would also grant (deny) "clipboard-write" access.

  While user agents MUST support the `ClipboardPermissionDescriptor` as described in this specification, they, of course, retain complete control over the default settings and how (or if) they are exposed to the user.

  A user agent that wants to have separate user-settable read and write controls over the clipboad and always require a user gesture would handle each descriptor as follows:

  - `{ "clipboard-read" + false }` is exposed for user control

  - `{ "clipboard-read" + true }` is always denied

  - `{ "clipboard-write" + false }` is exposed for user control

  - `{ "clipboard-write" + true }` is always denied

  A user agent that wants to automatically grant "write" access (with a gesture), but have a single user-settable permission that controls full gesture-less access would define "clipboard-read" as being stronger than "clipboard-write" and then handle each descriptor as follows:

  - `{ "clipboard-read" + false }` is inherited from `{ "clipboard-read" + true }`

  - `{ "clipboard-read" + true }` is exposed for user control

  - `{ "clipboard-write" + false }` is inherited from `{ "clipboard-write" + true }`

  - `{ "clipboard-write" + true }` is granted by default, but may be overridden by `{ "clipboard-read" + true }` because "read" is stronger than "write".

  ### 9.1. Clipboard read permission

  #### 9.1.1. check clipboard read permission

  1. Let readWithoutGesture be the permission state of the `{ name: "clipboard-read", allowWithoutGesture: true }` permission.

  2. Let hasGesture be true if the current script is not running as a result of direct user action, false otherwise.

  3. If readWithoutGesture is granted, then return true.

  4. If hasGesture then,

     1. Let systemPaste be true if the current script is running as a result of user interaction with a "Paste" element created by the user agent or operating system.

     2. If systemPaste is true, then return true.

     3. Return the result of request permission to use the `{ name: "clipboard-read", allowWithoutGesture: false }` permission.

        Note: User agents may choose to request a stronger permission that will implicitly update this permission.

  5. Return the result of request permission to use the `{ name: "clipboard-read", allowWithoutGesture: true }` permission.

  ### 9.2. Clipboard write permission

  #### 9.2.1. check clipboard write permission

  1. Let writeWithoutGesture be the permission state of the `{ name: "clipboard-write", allowWithoutGesture: true }` permission.

  2. Let hasGesture be true if the current script is not running as a result of direct user action, false otherwise.

  3. If writeWithoutGesture is granted, then return true.

  4. If hasGesture then,

     1. Let systemCopy be true if the current script is running as a result of user interaction with a "cut" or "copy" element created by the user agent or operating system.

     2. If systemCopy is true, then return true.

     3. Return the result of request permission to use the `{ name: "clipboard-write", allowWithoutGesture: false }` permission.

        Note: User agents may choose to request a stronger permission that will implicitly update this permission.

  5. Return the result of request permission to use the `{ name: "clipboard-write", allowWithoutGesture: true }` permission.

  ## 10. Security Considerations

  Enabling authors to change what is copied by a user, or to make an automated copy of something that was never selected and allowing unrestricted calls to paste information can raise various security concerns.

  Some example scenarios include:

  - A user selects a link and copies it, but a different link is copied to the clipboard. The effect of this can range from an unexpected result on pasting to an attempted "phishing" attack.

  - (Self-XSS) Shell commands or executable script can be placed in the clipboard with the intent that the user will run the pasted content.

  - An image that is specially crafted to exploit bugs in the core OS image handling code can be written to the clipboard.

  ### 10.1. Pasting HTML and multi-part data

  This section is non-normative.

  There are certain security risks associated with pasting formatted or multi-part data.

  - The user might paste hidden data without realising it is there. This may happen if, for example, the markup includes <input type="hidden"> tags or HTML comments. Such hidden data might contain sensitive information.

  - The user might paste malicious JavaScript into a trusted page.

  - The implementation might grant scripts access to local files the user did not intend to expose.

  To determine what policies to use, the factors we consider are:

  - The origin of the data being pasted

  - The origin of data sub-parts such as referenced images

  - The origin of the running script

  This is an overview of the scenarios and the possible security policies:

  Origin of data | Origin of script | Rules
  --- | --- | ---
  Originates from online source | Same as data | Do not sanitize HTML. Do not access any local files.
  Different origin | Optionally sanitize content. Do not access any local files.
  Originates from local application | Any | Do not sanitize HTML. Grant access to local files

  Some implementations mitigate the risks associated with pasting rich text by stripping potentially malicious content such as SCRIPT elements and javascript: links by default when pasting rich text, but allow a paste event handler to retrieve and process the original, un-sanitized data.

  ### 10.2. General security policies

  The implementation must not download referenced online resources, or expose their contents in the `files` list or `DataTransferItemList`.

  If the data on the clipboard is not from a local application, the implementation must not give access to any referenced local files. For example, if the data contains <img src="file://localhost/example.jpg"> but the data’s origin is an online resource, the implementation must not add an entry for example.jpg to the clipboardData.items list.

  ### 10.3. Transcoding images

  To prevent malicious image data from being placed on the clipboard, the image data may be transcoded to produce a safe version of the image.

  ### 10.4. Nuisance considerations

  Scripts may use the `DataTransfer` API to annoy and confuse users by altering the data on the system clipboard from copy and cut events. This specification does not attempt to prevent such nuisances, though implementations may add additional restrictions.

  Implementations must handle scripts that try to place excessive amounts of data on the clipboard gracefully.

  ## 11. Privacy Considerations

  Because these APIs provide access to the user’s clipboard data, there are serious privacy concerns due to the possibility that the clipboard will contain personally-identifiable information (PII) like names, addresses, or passwords.

  In general, user agents must ensure that untrusted scripts do not get uncontrolled access to a user’s clipboard data through these APIs.

  ### 11.1. Privacy and the Clipboard Event API

  The Clipboard Event API allows scripts running in the context of a clipboard event handler to access a copy of the system clipboard and potentially modify the data being written to the clipboard.

  User agents should be aware of the following requirements with regards to securing the data accessed by the Clipboard Event API:

  - Objects implementing the `DataTransfer` interface to return clipboard data must not be available outside the ClipboardEvent event handler that the data is provided to.

  - If a script stores a reference to an object implementing the `DataTransfer` interface to use from outside the ClipboardEvent event handler, all methods must be no-ops when called outside the expected context.

  - Implementations must not let scripts create synthetic clipboard events to get access to real clipboard data (unless the user has configured it to do so).

  Even though the Clipboard Event API is not covered by the Clipboard permission, user agents may choose to provide a method for the user to disable this API or to configure which sites are allowed to access it.

  ### 11.2. Privacy and the Asychronous Clipboard API

  The Asynchronous Clipboard API is a powerful feature because it can allow access to the clipboard data from any script (access is not restricted to Clipboard Event handlers) and data can be accessed in the absence of a user provided gesture.

  To help prevent abuse, this API must not be available unless the script is executing in the context of the currently focused document.

  #### 11.2.1. Privacy and Clipboard Permission

  The Clipboard Permission gates access to this API, but user agents get to choose the permission defaults and which of these permission settings can be set by the user. For example, a user agent may choose to only allow access to the Asynchronous Clipboard API when a user gesture is present and always deny script requests for access without a gesture.

  User agents may opt to have this permission automatically expire sometime after the user grants permission, for example, by having the permission expire:

  - After a set time from when the permission was first granted

  - After a set time from the user’s last visit to a site

  - When the user navigates away from the page

  ### 11.3. Other Privacy Concerns

  If the user agent allows clipboard data to be read using `document.execCommand("paste")` then the user agent must ensure that the user has explicitly allowed that access to take place.

  ## 12. Acknowledgements

  This section is non-normative

  The editors would like to acknowledge the contributions of the former editors who helped shepherd this specification through various meetings and mailing-list discussions to bring it to its current state.

  - Hallvord R. M. Steen

  The editors would also like to acknowledge their intellectual debt to the documentation of Data Transfer functionalities from Microsoft [MICROSOFT-CLIP-OP] and earlier drafts of the [HTML5] specification. We are also grateful for the draft "safe copy and paste" from Paul Libbrecht (this draft is no longer available on the Web).

  And finally, we would like to acknowledge the contributions made by the following:

  Adam Barth, Shawn Carnell, Daniel Cheng, Daniel Dardailler, Domenic Denicola, Al Gilman, James Graham, James Greene, Ian Hickson, Darwin Huang, Lachlan Hunt, Philip Jägenstedt, Anne van Kesteren, Marijn Kruisselbrink, Aaron Leventhal, Jim Ley, Paul Libbrecht, "Martijn", Glenn Maynard, Chris Mills, ms2ger, Ryosuke Niwa, Robert O’Callahan, Dave Poehlman, "ROBO Design", Janina Sajka, Rich Schwerdtfeger, Jonas Sicking, Maciej Stachowiak, Mihai Sucan, Dmitry Titov, Ojan Vafai, Tarquin Wilton-Jones, Tom Wlodkowski, and Boris Zbarsky.

  ## Appendix A: Algorithms

  ### write content to the clipboard

  Input

    items, a `DataTransferItemList` list of items to write

    clear-was-called, a boolean

    types-to-clear, a list

  Output

    None

  1. If the items list is not empty, then

     1. Clear the clipboard

     2. For each part in the list,

        1. If data type is text/plain, then

           1. Ensure encoding is correct per OS and locale conventions

           2. Normalize line endings according to platform conventions

           3. Place text on clipboard with the appropriate OS clipboard format description

        2. Else, if data is of a type listed in the mandatory data types list, then

           1. Place part on clipboard with the appropriate OS clipboard format description

        3. Else

           1. This is left to the implementation...

              It’s not good to leave things up to the implementation. What should happen here?

              Note: Due to limitations in the implementation of operating system clipboards, scripts should not assume that custom formats will be available to other applications on the system. For example, there is a limit to how many custom clipboard formats can be registered in Microsoft Windows. While it is possible to use any string for setData()’s type argument, sticking to the mandatory data types is strongly recommended.

  2. Else, the items list is empty. Follow these steps to determine whether to clear the clipboard:

     1. If the list of items is empty and the clear-was-called flag is true, then

        1. If the types-to-clear list is empty, then

           1. Clear the clipboard

        2. Else

           1. Remove types in the types-to-clear list from the clipboard in an operating system and implementation-specific way

              The "remove specific types from clipboard" feature is at risk. It doesn’t seem all that important, and it’s unclear if it can be implemented easily across relevant platforms.

  ### fire a clipboard event

  Input

    e, the `ClipboardEvent` to fire

  Output

    None

  1. Let clear-was-called be false

  2. Let types-to-clear be an empty list

  3. Let clipboard-event-data be a new `DataTransfer` object with an empty `items` list.

  4. Let clipboard-entry be the sequence number of the current clipboard content, or null if the OS clipboard does not support sequence numbers

  5. Let trusted be true if the event is generated by the user agent, false otherwise

  6. Let target be set as follows:

     1. If the context is editable, then

        1. Set target to be the element that contains the start of the visible selection or cursor in document order, or the body element if there is no visible selection or cursor.

     2. Else, if the context is not editable, then

        1. Set target to the focused node, or the body element if no node has focus.

  7. Process the event as follows:

     1. If e is "paste", then

        1. Set the clipboard-event-data’s internal drag data store mode flag to read-only.

        2. If trusted is true, or the implementation is configured to give script-generated events read access to the OS clipboard

           1. For each clipboard-part on the OS clipboard, carry out these steps:

              1. If clipboard-part contains plain text, then

                 1. Ensure the text is in the encoding the scripting engine uses internally

                 2. Let new-data be a new `DataTransferItem` with drag data item kind set to string and drag data item type string set to text/plain.

                 3. Set new-data’s data to the plain text.

                 4. Add new-data to clipboard-event-data’s `items`

              2. If clipboard-part represents file references, then for each file reference:

                 1. Determine MIME type of referenced file

                 2. Let new-data be a new `DataTransferItem` with drag data item kind set to file and drag data item type string set to the corresponding MIME type, or `application/octet-stream` if the file’s type is unknown.

                 3. Set new-data’s data to the file reference data.

                 4. Add new-data to clipboard-event-data’s `items`

              3. If clipboard-part contains HTML- or XHTML-formatted text, according to the operating system’s convention for describing such clipboard formats, then

                 1. If the implementation supports pasting HTML, then the implementation must process the markup by calling process an html paste event with clipboard-part and clipboard-event-data.

              4. If clipboard-part contains data in another supported binary or text-based format (see mandatory data types), then

                 1. Determine the MIME type of the data

                 2. Let new-data be a new `DataTransferItem` with drag data item kind set to file, drag data item type string set to the corresponding MIME type

                 3. Set new-data’s data to be the binary or text-based data.

                 4. Add new-data to clipboard-event-data’s `items`

        3. Update clipboard-event-data’s `files` property to match entries in clipboard-event-data’s `items`.

        4. Update clipboard-event-data’s `types` property to match entries in clipboard-event-data’s `items`.

     2. If e is "copy" or "cut", then

        1. Set the associated `DataTransfer` object’s internal drag data store mode flag to read/write

  8. Set e’s `clipboardData` to clipboard-event-data.

  9. Set e’s `isTrusted` to trusted.

  10. Set e’s `composed` to true.

  11. Dispatch the event e which bubbles and is cancelable, and which uses the `ClipboardEvent` interface, at target.

      Implementation requirements for access to data during event dispatch are defined in [HTML]. Some additional clipboard event-specific processing rules are given below:

      Why here? Why not in the HTML spec?

      1. If a script calls clearData() or `clear()` and the `DataTransfer` object’s internal drag data store mode flag is read/write, then

         1. Set the clear-was-called flag to true. If an argument is given, add the argument to the types-to-clear list.

      2. If a script calls setData() or modifies items and the clear-was-called flag is true, then

         1. If the types-to-clear list is empty, then

            1. Set the clear-was-called flag to false, then

         2. Else, if setData()’s `type` argument or the new item’s drag data item type string is found in the types-to-clear list, then

            1. Remove it from the list. If the list is now empty, set the clear-was-called flag to false.

      3. If a script calls getData() or accesses items in the `DataTransferItemList` and clipboard-entry is set, then

         1. Check that the clipboard data’s sequence number matches clipboard-entry. If the clipboard no longer contains the same entry, set the `DataTransferItemList` object’s internal drag data store mode to protected.

      Warning! A malicious script listening to a paste event may set up a never-ending loop in order to read what the user places on the clipboard in the future. On platforms where a clipboard sequence number is not available, other limitations should be implemented.

  ### process an HTML paste event

  Input

    clipboard-part, the clipboard part to process

    clipboard-event-data, the `DataTransfer` object for this event

  Output

    None

  1. Let new-data be a new `DataTransferItem` with drag data item kind set to Plain Unicode string, drag data item type string set to text/html or application/xhtml+xml accordingly.

  2. Extract the markup from clipboard-part and use the relevant parser to construct a DOM tree.

  3. If the markup’s source URL is known, then resolve all relative URLs in HREF and SRC attributes using the source URL as base URL, and set the respective attributes to the resolved absolute URL.

  4. If the markup’s origin is from a local application, then check whether there are references to local files and/or other parts of the OS clipboard’s contents. If such references are found, references to sub-parts must be replaced by content-id references using the cid: URL scheme [RFC2392]. To do so, process each attribute referencing a local file or clipboard part according to the following steps:

     Are these steps necessary? Do we know about native (platform) clipboard implementations that support multiple parts with internal references?

     This feature is at risk because it’s unclear whether it is required, and because it’s hard to test in a cross-platform way.

     1. If clipboard-event-data’s `items` already contains an entry for the referenced file or clipboard part, then

        1. Set itemNumber to the index of the existing entry.

     2. Else,

        1. Let new-file-data be a new `DataTransferItem` with drag data item kind set to "file", and drag data item type string set to the MIME type of the file or clipboard part if known, or `application/octet-stream` if the file’s type is unknown.

        2. Let file-info be a new `File` object with `name` set to the name part of the HTML attribute contents, and `lastModified` set to the timestamp of the referenced file or 0 if the entry references a clipboard part.

        3. Set new-file-data’s internal `File` object to file-info.

        4. Add new-file-data to clipboard-event-data’s `items` and let itemNumber be the index of this entry in the `DataTransferItemList`.

     3. Update the DOM attribute that referenced the local file or clipboard part to contain the string 'cid:' followed by itemNumber.

  5. Serialize the processed DOM and update new-data with the resulting HTML code.

  6. Add new-data to clipboard-event-data’s `items`.

## Conformance

### Document conventions

Conformance requirements are expressed with a combination of descriptive assertions and RFC 2119 terminology. The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in the normative parts of this document are to be interpreted as described in RFC 2119. However, for readability, these words do not appear in all uppercase letters in this specification.

All of the text of this specification is normative except sections explicitly marked as non-normative, examples, and notes. [RFC2119]

Examples in this specification are introduced with the words “for example” or are set apart from the normative text with `class="example"`, like this:

This is an example of an informative example.

Informative notes begin with the word “Note” and are set apart from the normative text with `class="note"`, like this:

Note, this is an informative note.

### Conformant Algorithms

Requirements phrased in the imperative as part of algorithms (such as "strip any leading space characters" or "return false and abort these steps") are to be interpreted with the meaning of the key word ("must", "should", "may", etc) used in introducing the algorithm.

Conformance requirements phrased as algorithms or specific steps can be implemented in any manner, so long as the end result is equivalent. In particular, the algorithms defined in this specification are intended to be easy to understand and are not intended to be performant. Implementers are encouraged to optimize.

.

## Index

### Terms defined by this specification

- allowed to modify the clipboard, in §5.3.1
- allowed to read from clipboard, in §5.3.2
- allowWithoutGesture, in §9
- "attachment", in §7.2
- check clipboard read permission, in §9.1.1
- check clipboard write permission, in §9.2.1
- Clipboard, in §7.2
- clipboard
  - attribute for Navigator, in §7.1
  - dfn for Navigator, in §7.1.1
- clipboardchange, in §5.2.1
- clipboardData
  - attribute for ClipboardEvent, in §5.1
  - dfn for ClipboardEvent, in §5.1
  - dfn for ClipboardEventInit, in §5.1
  - dict-member for ClipboardEventInit, in §5.1
- ClipboardEvent, in §5.1
- ClipboardEventInit, in §5.1
- ClipboardItem, in §7.2
- ClipboardItemData, in §7.2
- ClipboardItemDataType, in §7.2
- ClipboardItemDelayedCallback, in §7.2
- ClipboardItemOptions, in §7.2
- ClipboardItems, in §7.2
- ClipboardPermissionDescriptor, in §9
- "clipboard-read", in §9
- "clipboard-write", in §9
- copy, in §5.2.2
- createDelayed(items), in §7.2
- createDelayed(items, options), in §7.2
- cut, in §5.2.3
- delayed, in §7.2
- editable context, in §3
- fire a clipboard event, in §Unnumbered section
- getType(type), in §7.2
- "inline", in §7.2
- lastModified, in §7.2
- Mandatory data types, in §6.4
- paste, in §5.2.4
- PresentationStyle, in §7.2
- presentationStyle
  - attribute for ClipboardItem, in §7.2
  - dict-member for ClipboardItemOptions, in §7.2
- process an HTML paste event, in §Unnumbered section
- read(), in §7.2
- readText(), in §7.2
- script-may-access-clipboard, in §8
- script-triggered, in §8
- system clipboard, in §4
- system clipboard data, in §4
- types, in §7.2
- "unspecified", in §7.2
- write content to the clipboard, in §Unnumbered section
- write(data), in §7.2
- writeText(data), in §7.2

https://dom.spec.whatwg.org/#event Referenced in:

- 5.1. Clipboard event interfaces (2)

https://dom.spec.whatwg.org/#dictdef-eventinit Referenced in:

- 5.1. Clipboard event interfaces

https://dom.spec.whatwg.org/#eventtarget Referenced in:

- 7.2. Clipboard Interface

https://dom.spec.whatwg.org/#dom-event-composed Referenced in:

- fire a clipboard event

https://dom.spec.whatwg.org/#concept-cd-data Referenced in:

- 7.2.4. writeText(data)

https://dom.spec.whatwg.org/#dom-event-istrusted Referenced in:

- fire a clipboard event

https://dom.spec.whatwg.org/#dom-event-preventdefault Referenced in:

- 6.1. Overriding the copy event
- 6.2. Overriding the cut event
- 6.3. Overriding the paste event

http://tc39.github.io/ecma262/#sec-promise-objects Referenced in:

- 7.2.1. read()
- 7.2.2. readText()
- 7.2.3. write(data)
- 7.2.4. writeText(data)

https://w3c.github.io/FileAPI/#dfn-Blob Referenced in:

- 7.2. Clipboard Interface (2)
- 7.2.3. write(data) (2)
- 7.2.4. writeText(data)

https://w3c.github.io/FileAPI/#dfn-file Referenced in:

- process an HTML paste event (2)

https://w3c.github.io/FileAPI/#dfn-lastModified Referenced in:

- process an HTML paste event

https://w3c.github.io/FileAPI/#dfn-name Referenced in:

- process an HTML paste event

https://html.spec.whatwg.org/multipage/dnd.html#datatransfer Referenced in:

- 4. Model
- 5.1. Clipboard event interfaces (2) (3) (4)
- 6. Clipboard Event API
- 6.4.2. Writing to the clipboard
- 10.4. Nuisance considerations
- 11.1. Privacy and the Clipboard Event API (2)
- fire a clipboard event (2) (3)
- process an HTML paste event

https://html.spec.whatwg.org/multipage/dnd.html#datatransferitem Referenced in:

- fire a clipboard event (2) (3)
- process an HTML paste event (2)

https://html.spec.whatwg.org/multipage/dnd.html#datatransferitemlist Referenced in:

- 6.4. Mandatory data types
- 8.1. The copy action
- 8.2. The cut action
- 10.2. General security policies
- write content to the clipboard
- fire a clipboard event (2)
- process an HTML paste event

https://html.spec.whatwg.org/multipage/system-state.html#navigator Referenced in:

- 7.1. Navigator Interface
- 7.1.1. clipboard

https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransferitemlist-clear Referenced in:

- fire a clipboard event

https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-cleardata Referenced in:

- fire a clipboard event

https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-files Referenced in:

- 5.1. Clipboard event interfaces
- 10.2. General security policies
- fire a clipboard event

https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-getdata Referenced in:

- fire a clipboard event

https://html.spec.whatwg.org/multipage/infrastructure.html#in-parallel Referenced in:

- 7.2.1. read() (2)
- 7.2.2. readText() (2)
- 7.2.3. write(data) (2)
- 7.2.4. writeText(data) (2)

https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-items Referenced in:

- 5.1. Clipboard event interfaces
- 6. Clipboard Event API
- fire a clipboard event (2) (3) (4) (5) (6)
- process an HTML paste event (2) (3)

https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-setdata Referenced in:

- 6.3. Overriding the paste event
- write content to the clipboard
- fire a clipboard event (2)

https://html.spec.whatwg.org/multipage/dnd.html#dom-datatransfer-types Referenced in:

- fire a clipboard event

https://w3c.github.io/permissions/#dictdef-permissiondescriptor Referenced in:

- 9. Permissions API Integration

https://w3c.github.io/permissions/#permission-descriptor-type Referenced in:

- 9. Permissions API Integration

https://w3c.github.io/permissions/#permission-state Referenced in:

- 9.1.1. check clipboard read permission
- 9.2.1. check clipboard write permission

https://w3c.github.io/permissions/#powerful-feature Referenced in:

- 1. Introduction
- 9. Permissions API Integration (2)

https://w3c.github.io/permissions/#request-permission-to-use Referenced in:

- 9.1.1. check clipboard read permission (2)
- 9.2.1. check clipboard write permission (2)

https://heycam.github.io/webidl/#idl-DOMString Referenced in:

- 5.1. Clipboard event interfaces
- 7.2. Clipboard Interface (2) (3) (4) (5) (6) (7)

https://heycam.github.io/webidl/#Exposed Referenced in:

- 5.1. Clipboard event interfaces
- 7.2. Clipboard Interface (2)

https://heycam.github.io/webidl/#SameObject Referenced in:

- 7.1. Navigator Interface

https://heycam.github.io/webidl/#SecureContext Referenced in:

- 7.1. Navigator Interface
- 7.2. Clipboard Interface

https://heycam.github.io/webidl/#idl-boolean Referenced in:

- 7.2. Clipboard Interface
- 9. Permissions API Integration

https://heycam.github.io/webidl/#idl-long-long Referenced in:

- 7.2. Clipboard Interface

### Terms defined by reference

- [DOM] defines the following terms:
  - Event
  - EventInit
  - EventTarget
  - composed
  - data
  - isTrusted
  - preventDefault()
- [ECMASCRIPT] defines the following terms:
  - promise
- [FileAPI] defines the following terms:
  - Blob
  - File
  - lastModified
  - name
- [HTML] defines the following terms:
  - DataTransfer
  - DataTransferItem
  - DataTransferItemList
  - Navigator
  - clear()
  - clearData()
  - files
  - getData(format)
  - in parallel
  - items
  - setData(format, data)
  - types
- [permissions] defines the following terms:
  - PermissionDescriptor
  - permission descriptor type
  - permission state
  - powerful feature
  - request permission to use
- [WebIDL] defines the following terms:
  - DOMString
  - Exposed
  - SameObject
  - SecureContext
  - boolean
  - long long

## References

### Normative References

[DOM]
  Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
  ECMAScript Language Specification. URL: https://tc39.github.io/ecma262/
[FileAPI]
  Marijn Kruisselbrink; Arun Ranganathan. File API. 31 May 2019. WD. URL: https://www.w3.org/TR/FileAPI/
[HTML]
  Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[PERMISSIONS]
  Mounir Lamouri; Marcos Caceres; Jeffrey Yasskin. Permissions. 25 September 2017. WD. URL: https://www.w3.org/TR/permissions/
[RFC2119]
  S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
[RFC2392]
  E. Levinson. Content-ID and Message-ID Uniform Resource Locators. August 1998. Proposed Standard. URL: https://tools.ietf.org/html/rfc2392
[WebIDL]
  Boris Zbarsky. Web IDL. 15 December 2016. ED. URL: https://heycam.github.io/webidl/

### Informative References

[HTML5]
  Ian Hickson; et al. HTML5. 27 March 2018. REC. URL: https://www.w3.org/TR/html5/
[MICROSOFT-CLIP-OP]
  About DHTML Data Transfer. Microsoft Developer Network.. URL: https://msdn.microsoft.com/en-us/ie/ms537658(v=vs.94)
[SVG11]
  Erik Dahlström; et al. Scalable Vector Graphics (SVG) 1.1 (Second Edition). 16 August 2011. REC. URL: https://www.w3.org/TR/SVG11/

## IDL Index

    dictionary ClipboardEventInit : EventInit {
      DataTransfer? clipboardData = null;
    };

    [Constructor(DOMString type, optional ClipboardEventInit eventInitDict = {}), Exposed=Window]
    interface ClipboardEvent : Event {
      readonly attribute DataTransfer? clipboardData;
    };

    partial interface Navigator {
      [SecureContext, SameObject] readonly attribute Clipboard clipboard;
    };

    typedef sequence<ClipboardItem> ClipboardItems;

    [SecureContext, Exposed=Window] interface Clipboard : EventTarget {
      Promise<ClipboardItems> read();
      Promise<DOMString> readText();
      Promise<void> write(ClipboardItems data);
      Promise<void> writeText(DOMString data);
    };

    typedef (DOMString or Blob) ClipboardItemDataType;
    typedef Promise<ClipboardItemDataType> ClipboardItemData;

    callback ClipboardItemDelayedCallback = ClipboardItemData ();

    [Constructor(record<DOMString, ClipboardItemData> items,
        optional ClipboardItemOptions options = {}),
     Exposed=Window] interface ClipboardItem {
      static ClipboardItem createDelayed(
          record<DOMString, ClipboardItemDelayedCallback> items,
          optional ClipboardItemOptions options = {});

      readonly attribute PresentationStyle presentationStyle;
      readonly attribute long long lastModified;
      readonly attribute boolean delayed;

      readonly attribute FrozenArray<DOMString> types;

      Promise<Blob> getType(DOMString type);
    };

    enum PresentationStyle { "unspecified", "inline", "attachment" };

    dictionary ClipboardItemOptions {
      PresentationStyle presentationStyle = "unspecified";
    };

    dictionary ClipboardPermissionDescriptor : PermissionDescriptor {
      boolean allowWithoutGesture = false;
    };

## Issues Index

It’s not good to leave things up to the implementation. What should happen here? ↵
The "remove specific types from clipboard" feature is at risk. It doesn’t seem all that important, and it’s unclear if it can be implemented easily across relevant platforms. ↵
Why here? Why not in the HTML spec? ↵
Are these steps necessary? Do we know about native (platform) clipboard implementations that support multiple parts with internal references? ↵
This feature is at risk because it’s unclear whether it is required, and because it’s hard to test in a cross-platform way. ↵
#editable-context Referenced in:

- 5.2.3. The cut event (2)
- 5.2.4. The paste event (2)
- 8.2. The cut action
- 8.3. The paste action

#system-clipboard Referenced in:

- 4. Model
- 5.2.1. The clipboardchange event (2)
- 5.2.2. The copy event (2)
- 5.2.3. The cut event (2)
- 6.1. Overriding the copy event
- 6.2. Overriding the cut event
- 6.3. Overriding the paste event

#system-clipboard-data Referenced in:

- 4. Model (2)
- 7.2.1. read()
- 7.2.2. readText()
- 7.2.3. write(data)
- 7.2.4. writeText(data)

#dictdef-clipboardeventinit Referenced in:

- 5.1. Clipboard event interfaces

#clipboardevent Referenced in:

- 6. Clipboard Event API (2)
- 6.1. Overriding the copy event
- 6.2. Overriding the cut event
- fire a clipboard event (2)

#dom-clipboardevent-clipboarddata Referenced in:

- 5.2.3. The cut event
- 6. Clipboard Event API
- 6.1. Overriding the copy event
- 6.2. Overriding the cut event
- fire a clipboard event

#clipboardchange Referenced in:

- 2.2. Remote Clipboard Synchronization
- 5.2.1. The clipboardchange event (2)
- 8.1. The copy action
- 8.2. The cut action (2)

#copy Referenced in:

- 5.2.1. The clipboardchange event
- 5.2.2. The copy event (2) (3)
- 5.3.1. Event handlers that are allowed to modify the clipboard
- 6.1. Overriding the copy event (2)
- 8.1. The copy action

#cut Referenced in:

- 5.2.1. The clipboardchange event
- 5.2.3. The cut event (2) (3) (4) (5)
- 5.3.1. Event handlers that are allowed to modify the clipboard
- 6.2. Overriding the cut event (2) (3)
- 8.2. The cut action

#paste Referenced in:

- 5.2.4. The paste event (2) (3) (4)
- 5.3.2. Event handlers that are allowed to read from clipboard
- 6.3. Overriding the paste event (2) (3) (4)
- 8.3. The paste action

#allowed-to-modify-the-clipboard Referenced in:

- 8. Clipboard Actions

#allowed-to-read-from-clipboard Referenced in:

- 8. Clipboard Actions

#mandatory-data-types Referenced in:

- 5.1. Clipboard event interfaces
- write content to the clipboard (2)
- fire a clipboard event

#navigator-clipboard Referenced in:

- 7.1.1. clipboard (2)

#typedefdef-clipboarditems Referenced in:

- 7.2. Clipboard Interface (2)

#clipboard Referenced in:

- 7.1. Navigator Interface

#typedefdef-clipboarditemdatatype Referenced in:

- 7.2. Clipboard Interface

#typedefdef-clipboarditemdata Referenced in:

- 7.2. Clipboard Interface (2)

#callbackdef-clipboarditemdelayedcallback Referenced in:

- 7.2. Clipboard Interface

#clipboarditem Referenced in:

- 4. Model
- 7.2. Clipboard Interface (2)
- 7.2.1. read()
- 7.2.4. writeText(data) (2)

#enumdef-presentationstyle Referenced in:

- 7.2. Clipboard Interface (2)

#dictdef-clipboarditemoptions Referenced in:

- 7.2. Clipboard Interface (2)

#dom-clipboard-read Referenced in:

- 2.2. Remote Clipboard Synchronization
- 7.2. Clipboard Interface
- 7.2.1. read()

#dom-clipboard-readtext Referenced in:

- 7.2. Clipboard Interface
- 7.2.2. readText()

#dom-clipboard-write Referenced in:

- 2.2. Remote Clipboard Synchronization
- 7.2. Clipboard Interface
- 7.2.3. write(data)

#dom-clipboard-writetext Referenced in:

- 7.2. Clipboard Interface
- 7.2.4. writeText(data)

#script-triggered Referenced in:

- 8. Clipboard Actions (2)
- 8.1. The copy action
- 8.2. The cut action
- 8.3. The paste action

#script-may-access-clipboard Referenced in:

- 8. Clipboard Actions (2) (3)
- 8.1. The copy action
- 8.2. The cut action
- 8.3. The paste action (2)

#dictdef-clipboardpermissiondescriptor Referenced in:

- 9. Permissions API Integration

#check-clipboard-read-permission Referenced in:

- 7.2.1. read()
- 7.2.2. readText()

#check-clipboard-write-permission Referenced in:

- 7.2.3. write(data)
- 7.2.4. writeText(data)

#write-content-to-the-clipboard Referenced in:

- 8.1. The copy action
- 8.2. The cut action

#fire-a-clipboard-event Referenced in:

- 5.2.2. The copy event
- 5.2.3. The cut event
- 5.2.4. The paste event
- 8.1. The copy action (2)
- 8.2. The cut action (2) (3)
- 8.3. The paste action

#process-an-html-paste-event Referenced in:

- fire a clipboard event