クリップボードAPIとイベント

W3C作業草案

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/WD-clipboard-apis-20260624/
最新公開バージョン:
https://www.w3.org/TR/clipboard-apis/
編集者ドラフト:
https://w3c.github.io/clipboard-apis/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/clipboard-apis/
フィードバック:
GitHub
仕様内でインライン
編集者:
(Microsoft)
(Microsoft)
元編集者:
(Google)
(Microsoft)
(Mozilla)
(Microsoft)
説明書:
非同期クリップボードAPI説明書

概要

この文書は、システムのクリップボード上のデータへアクセスするためのAPIについて説明します。デフォルトのクリップボード操作(切り取り、コピー、貼り付け)を上書きするための操作や、クリップボードの内容へ直接アクセスするための操作を提供します。

この文書のステータス

このセクションでは、本書が公開された時点のステータスについて説明します。現在のW3Cの発行物や、この技術レポートの最新版は、W3C標準および草案のインデックスで確認できます。

本書はWeb Editing Working Groupによって 作業草案(Working Draft)として、 勧告プロセスに従い公開されました。 作業草案としての公開は、W3Cおよびその会員による支持を意味するものではありません。

本書はドラフト文書であり、今後随時更新・差し替え、または廃止される可能性があります。 進行中の作業以外として本書を引用するのは適切ではありません。

本書への変更はhttps://github.com/w3c/clipboard-apisで追跡できます。

本書はW3C特許ポリシーのもとで活動するグループによって作成されました。W3Cは、グループの成果物に関連して行われた特許開示の公開リストを管理しています。そのページには特許開示方法も記載されています。ある特許について、その内容が必須請求項(Essential Claim(s))を含むと信じる個人は、W3C特許ポリシー第6節に従い、その情報を開示しなければなりません。

本書は 2025年8月18日付W3C運用プロセス文書 に従って管理されています。

1. はじめに

このセクションは規範的ではありません。

この仕様は、システムクリップボードがウェブアプリケーションにどのように公開されるかを定義します。

本仕様で説明されているAPIは、主に2つあります:

2. ユースケース

このセクションは規範的ではありません。

2.1. デフォルトのクリップボード操作の変更

デフォルトのクリップボード操作(切り取り/コピー/貼り付け)を変更したいシナリオは多数存在します。いくつか例を挙げます:

2.2. リモートクリップボード同期

リモートデバイスと通信するウェブアプリケーション(例: リモートアクセスやリモートシェルアプリケーション)では、2つのデバイス間でクリップボードデータを同期させる必要がある場合があります。

このユースケースで重要なのは、ユーザーのジェスチャや操作がなくてもクリップボードへアクセスできる必要があることです。

リモートデバイスからローカルクリップボードへデータをコピーするには、ウェブアプリケーションがリモートのクリップボードデータを取得し、write()でローカルクリップボードへ書き込みます。
ローカルクリップボードデータをリモートデバイスへコピーするには、ウェブアプリケーションがclipboardchangeイベントを監視し、クリップボードが更新されるたびにread()でクリップボードからデータを取得し、新しいクリップボードデータをリモートデバイスへ送信します。

2.3. クリップボードアクションのトリガー

ユーザーエージェントに対して代替インターフェースを提供するアプリケーションでは、ユーザーエージェント内でクリップボードアクションをトリガーできる必要がある場合があります。

例えば、スクリーンリーダーアプリケーションが標準Webブラウザーによりアクセシブルなインターフェースを提供する場合、リーダーはコンテンツを表示し、ユーザーが操作できるようにしますが、コピーなどのクリップボード操作は基盤となるブラウザ内で行う必要があります(コピー時にブラウザが追加するメタデータなども正しく設定されるように)。

3. 用語

編集可能コンテキストとは、編集ホスト、textarea要素、またはtype属性が"text"、"search"、"tel"、"url"、"email"、"password"、"number"のいずれかに設定されているinput要素のいずれかを指します。

4. モデル

プラットフォームはシステムクリップボードを提供します。

システムクリップボードは、システムクリップボードアイテムのリストを持ち、それらをまとめてシステムクリップボードデータと呼びます。

システムクリップボードアイテムは、システムクリップボード表現のリストを持ちます。

システムクリップボード表現は、name(文字列)と、data(バイト列)を持ちます。

システムクリップボードは、 クリップボード変更 カウントを持つ。これは、システムクリップボードデータが変更されるたびに変化する値である。

5. クリップボードイベント

5.1. クリップボードイベントインターフェース

ClipboardEventインターフェースはEvent インターフェースを拡張します。

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

イベントに関連するデータやメタデータを保持するためのDataTransfer オブジェクトです。

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

clipboardData属性はDataTransfer インターフェースのインスタンスであり、ユーザーによるコピー・切り取り・貼り付け操作の間、スクリプトがシステムクリップボード上の値を読み取り・操作できるようにします。 関連するドラッグデータストアはシステムクリップボードのライブかつフィルタされたビューであり、スクリプトが安全にアクセスできる必須データ型のみが公開されます。合成イベントの場合、ドラッグデータストアにはイベントを作成したスクリプトが追加したデータのみが含まれます。

clipboardDataオブジェクトのitemsfiles プロパティによって、クリップボードのマルチパートや非テキストデータの処理が可能です。

このインターフェースはイベントの構築に使用できます。 以下はその例です:

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

注: 合成クリップボードイベントは実際にクリップボードや 文書を変更しません。つまり、上記のスクリプトでpasteイベントは発火しますが、 データが文書内に貼り付けられることはありません。

5.2. クリップボードイベント

5.2.1. clipboardchangeイベント

clipboardchange イベントはシステムクリップボードの内容が変更されたときに発火します。これらの変更には以下のようなもの(例示)があります:

5.2.1.1. clipboardchange イベントを発火するには

clipboardchange イベントを発火するためには、Document document を与える:

  1. document持続的な活性化を持たず、かつdocumentが クリップボードから読み取る権限を持たない場合、返す。

  2. globalを、document関連するグローバルオブジェクトとする。

  3. documentシステムフォーカスを持つ場合:

    1. typesを、必須データ型のリストであって、システム クリップボード上で利用可能なものとする。

    2. changeIdを、documentを与えてchangeIdを生成するを 実行した結果とする。

    3. eventInitを、新しいClipboardChangeEventInit 辞書であって、そのtypes メンバーがtypesに設定され、そのchangeId メンバーがchangeIdに設定されたものとする。

    4. globalにおいて、clipboardchange という名前のイベントを発火するClipboardChangeEventを使用し、 eventInitを伴う。

  4. documentシステムフォーカスを持たない場合:

    1. documentclipboardchange 保留フラグを trueに設定する。

ユーザーエージェントは、clipboardchange イベントが配信される前に、より新しい変更によって上書きされたクリップボードの変更については、発火を省略することを選択してもよいです。この最適化は、クリップボードの変更が短時間で連続して発生する場合にパフォーマンスの向上につながります。なぜなら、旧いイベント通知を配信してもウェブアプリケーションに価値がなく、処理リソースを消費するだけだからです。

5.2.1.2. Document フォーカス時の手順

Document documentシステムフォーカス を獲得したとき:

  1. documentclipboardchange 保留フラグがtrueである場合:

    1. documentclipboardchange 保留フラグを falseに設定する。

    2. typesを、必須データ型のリストであって、システム クリップボード上で利用可能なものとする。

    3. changeIdを、documentを与えてchangeIdを 生成するを実行した結果とする。

    4. eventInitを、新しいClipboardChangeEventInit 辞書であって、そのtypes メンバーがtypesに設定され、そのchangeId メンバーがchangeIdに設定されたものとする。

    5. globalを、document関連するグローバルオブジェクトとする。

    6. globalにおいて、clipboardchange という名前のイベントを発火するClipboardChangeEventを使用し、 eventInitを伴う。

ネストされた閲覧コンテキスト内の document では、clipboardchange イベントは、それぞれの Document ごとのフォーカス状態に基づき、個別に発火されます。クリップボードの変更が発生すると、システムフォーカスを持つ単一の document でイベントが発火します(該当の document がスティッキーアクティベーションまたは永続的なクリップボード権限を持つ場合)。

注: clipboardchange イベントは、スティッキーアクティベーションの後でのみ利用可能です(document がクリップボードからの読み取りに対する永続的な権限を持つ場合を除く)。 ユーザーエージェントが永続的なクリップボード権限をサポートしている場合、そのような権限を持つサイトはスティッキーアクティベーションなしでもclipboardchangeイベントを受信できます。なぜなら、その許可自体がより機微なクリップボードデータへのアクセスを既に許可しているからです。

changeId は、それぞれのクリップボード変更操作に対する一意識別子を提供します。同じクリップボードの変更について、同じストレージキーを持つすべてのウィンドウおよびタブは、同じ changeId 値を持つイベントを受け取り、複数ウィンドウでのイベントの重複処理を防げます。識別子はストレージキーごとに固有であり、キーをまたぐ相関機能はありません。

clipboardchange イベントはバブルせず、キャンセルもできません。なぜなら、これはユーザー操作によってではなく、システムクリップボードの状態変更によって引き起こされるからです。

dictionary ClipboardChangeEventInit : EventInit {
  sequence<DOMString> types = [];
  bigint changeId = 0;
};
types

システム クリップボード上で利用可能な必須データ型を表す、DOMString のシーケンス。

changeId

クリップボード変更操作の一意な識別子を表すbigint

[Exposed=Window]
interface ClipboardChangeEvent : Event {
  constructor(DOMString type, optional ClipboardChangeEventInit eventInitDict = {});
  readonly attribute FrozenArray<DOMString> types;
  readonly attribute bigint changeId;
};
types

イベントが発火された時点でシステムクリップボード上で利用可能な必須データ型を示す、DOMString オブジェクトのFrozenArrayを返す。任意データ型および カスタム形式は、フィンガープリンティング面を制限するために除外される。

changeId

この特定のクリップボード変更操作の一意な識別子を表すbigintを返す。 この識別子は、同じクリップボード変更について、同じストレージ キーを持つすべてのウィンドウおよびタブで一貫しており、 複数のウィンドウが同じクリップボード変更通知を受け取った場合に、アプリケーションがイベントを重複排除できるようにする。

changeIdは、 暗号学的に導出された128ビット整数である。唯一の保証は、何かが クリップボードに書き込まれた後、changeIdが、 書き込み操作の前とは異なる値を生じるということである。

5.2.1.3. ClipboardChangeEvent コンストラクタのステップ

ClipboardChangeEvent(type, eventInitDict) コンストラクタの手順は次の通り:

  1. this.types に、eventInitDict["types"] の クローン を設定する。

  2. this.changeIdeventInitDict["changeId"] を設定する。

5.2.1.4. ChangeId 生成

Document documentについてchangeIdを 生成するには:

  1. globalChangeIdを、システムクリップボードの現在の 状態を表す、ユーザーエージェント固有の一意な識別子とする。この識別子は、システム クリップボードが変更されるたびに変化し、ユーザーエージェントが再起動するとリセットされる。

  2. storageKeyを、document関連設定オブジェクトを与えて、非ストレージ目的の ストレージキーを取得するを実行した結果とする。

  3. storageKeyBytesを、storageKeyの何らかのユーザーエージェント固有の バイナリ表現とする。

  4. hashedValueを、globalChangeId(バイトとして)と storageKeyBytesの連結に暗号学的ハッシュ関数(SHA-256など)を適用した結果とする。

  5. hashedValueから導出された128ビット整数を返す(たとえば、ハッシュ出力の最初の 128ビットを取る)。

上記のアルゴリズムは、同じオリジンからの、かつ同じ パーティショニングを持つ文書が、同じクリップボード変更について同一の変更IDを受け取ることを保証し、 複数のウィンドウおよびタブにまたがる適切なイベント重複排除を可能にする一方で、トラッキングに 使用され得るパーティション間の相関付けを防ぐ。クライアント側ストレージパーティショニングの変更が ストレージキー定義に組み込まれるにつれて、この手法はパーティション間で自動的に匿名化を提供する。

changeId はブラウザーの再起動をまたいで永続化されない。これは、ユーザー エージェントが再起動するとglobalChangeIdカウンターがリセットされるためである。 同様に、ユーザーがサイトデータを消去した場合、影響を受けるタブは更新されるべきであり、それによって イベントリスナーが再接続され、新しい変更IDを持つ将来のイベントのみを受け取る。

合成されたcut およびcopy イベントはシステムクリップボードを更新しないため、 それらは「clipboardchange」イベントをトリガーしない。

clipboardchange イベントにより、ウェブアプリケーションはクリップボードの変更を効率的に監視し、 利用可能なデータ形式に基づいて動的なユーザーインターフェイスを提供できる:
// 複数のウィンドウを持つアプリケーションでは、重複を避けるために処理済みの変更IDを追跡する
const processedChangeIds = new Set();

// クリップボードの変更をリッスンする
navigator.clipboard.addEventListener('clipboardchange', (e) => {
  // changeIdを使用して複数のウィンドウにまたがるイベントを重複排除する
  if (processedChangeIds.has(e.changeId)) {
    return; // この変更はすでに処理されている
  }
  processedChangeIds.add(e.changeId);

  // クリップボード上で利用可能なデータ型を確認する
  const hasText = e.types.includes('text/plain');
  const hasHTML = e.types.includes('text/html');
  const hasImage = e.types.includes('image/png');

  // 利用可能な形式に基づいてUIを更新する
  document.getElementById('paste-text-btn').disabled = !hasText;
  document.getElementById('paste-html-btn').disabled = !hasHTML;
  document.getElementById('paste-image-btn').disabled = !hasImage;

  // リモートデスクトップアプリでは、変更ごとに一度だけクリップボードをリモートへ同期する
  if (hasText || hasHTML || hasImage) {
    syncClipboardToRemote(e.changeId);
  }
});

// あるいは、onclipboardchangeプロパティを使用できる
// navigator.clipboard.onclipboardchange = (e) => { ... };

このイベント駆動の手法は、read()readText() のようなメソッドでクリップボードをポーリングするより効率的であり、クリップボードアクセスに ユーザー活性化を要求するブラウザーでも動作する。これは、UIがタイマーの発火を待たずに クリップボードの変更に即座に反応できるためである。 changeId は、複数のウィンドウを持つアプリケーションで特に有用であり、 同じストレージキーを持つすべてのウィンドウにまたがって、 各クリップボード変更が一度だけ処理されることを保証する。

5.2.2. copy イベント

ユーザーがコピー操作を開始すると、ユーザーエージェントは クリップボード イベントを発火する。その名前は copyである。

イベントが取り消されなかった場合、現在選択されている データはシステムクリップボードにコピーされる。 現在の文書選択は影響を受けない。

copy イベントはバブルし、取り消し可能であり、composedである。

このイベントの処理モデルの詳細な説明については、§ 8.1 コピー操作を参照。

合成されたcopy イベントは手動で構築してディスパッチできるが、 システムクリップボードの内容には影響しない。

5.2.3. cut イベント

ユーザーが切り取り操作を開始すると、ユーザーエージェントは クリップボード イベントを発火する。その名前は cutである。

編集可能コンテキストでは、 イベントが取り消されなかった場合、この操作は現在選択されているデータを システムクリップボードに置き、 文書からその選択を削除する。 cut イベントは、選択されたデータが削除される前に発火する。切り取り操作が完了すると、 選択は折りたたまれる。

編集可能 コンテキストでは、clipboardData は 空のリストになる。この場合でもcut イベントは発火されることに注意。

cut イベントはバブルし、取り消し可能であり、composedである。

このイベントの処理モデルの詳細な説明については、§ 8.2 切り取り操作を参照。

合成されたcut イベントは手動で構築してディスパッチできるが、 文書の内容にも、システムクリップボードの内容にも影響しない。

5.2.4. paste イベント

ユーザーが貼り付け操作を開始すると、ユーザーエージェントはpasteという名前のクリップボードイベントを発火します。 このイベントは、クリップボードデータが文書に挿入される前に発火します。

カーソルが編集可能コンテキスト内にある場合、貼り付け操作はそのコンテキストでサポートされている最適な形式(あれば)でクリップボードデータを挿入します。

貼り付け操作は非編集可能コンテキストでは効果がありませんが、paste イベントは必ず発火します。

paste イベントはバブルし、キャンセル可能で、構成可能です。

このイベントの処理モデルの詳細は§ 8.3 貼り付けアクションを参照してください。

合成paste イベントは手動で構築してディスパッチできますが、 文書の内容には影響しません。

5.3. 他のスクリプトやイベントとの統合

5.3.1. クリップボードの変更が許可されているイベントハンドラ

以下のいずれかが真の場合、イベントハンドラはクリップボードへ書き込みできます:

実装は、実装者がそのイベントタイプがユーザーの意図を表す可能性が高いと判断した場合、他の信頼できるイベントタイプでもクリップボードの変更を許可してもよいです。また、信頼された特定サイトやアプリがスクリプトスレッドの起源に関係なくクリップボードを変更できるようにする設定をサポートしてもよいです。

合成されたcut およびcopy イベントはシステムクリップボードのデータを変更してはなりません

5.3.2. クリップボードからの読み取りが許可されているイベントハンドラ

以下のいずれかが真の場合、イベントハンドラはシステムクリップボードからデータを読み取ることができます:

合成されたpaste イベントは実際のシステムクリップボード上のデータへのアクセスをスクリプトに与えてはなりません

5.3.3. リッチテキスト編集APIとの統合

実装がスクリプトからクリップボードコマンドを実行する方法(例: document.execCommand() メソッドで "cut"、"copy"、"paste" コマンドを呼び出す)をサポートしている場合、実装は必ず対応するアクションをトリガーし、それに応じたクリップボードイベントをディスパッチします。

スクリプトAPIからコピー・切り取り・貼り付けアクションをトリガーする際の手順:

  1. 対応するアクションを同期的に実行する。

  2. アクションの戻り値をAPI呼び出しの戻り値として使用する。

注: スクリプトAPI経由でトリガーされたコピーや切り取りコマンドは、イベントが信頼できユーザーによってトリガーされた場合、または実装がそれを許可するように設定されている場合のみ、実際のクリップボードの内容に影響します。スクリプトAPI経由の貼り付けコマンドは、実装がそれを許可するよう設定されている場合のみ、貼り付けイベントを発火しクリップボード内容へのアクセスを許可します。クリップボードの読み書きアクセスを許可する実装設定方法は本仕様の範囲外です。

5.3.4. 他のイベントとの相互作用

クリップボード操作がキーボード入力でトリガーされた場合、実装は必ずその操作を開始するイベントを発火しなければなりません。イベントは非同期ですが、関連するキーのkeyupイベントの前にディスパッチされなければなりません。

切り取り・貼り付け操作は、実装がサポートする他のイベント(textInput、input、change、検証イベント、DOMCharacterDataModified、DOMNodeRemoved/DOMNodeInsertedなど)をディスパッチする場合があります。これらのイベントは、切り取り・貼り付けイベントの処理が完了した後に発火するようキューされます。

実装はコピー操作に応じて、textInput、input、change、検証イベントなど、他の入力関連イベントをディスパッチしてはなりません。

5.3.5. 選択やフォーカスを変更するイベントリスナー

イベントリスナーが選択やフォーカス可能領域を変更した場合、クリップボード操作は 必ず変更後の選択に対して完了しなければなりません。

6. クリップボードイベントAPI

クリップボードイベントAPIを使用すると、ユーザーエージェントのデフォルトの切り取り、コピー、貼り付け動作を上書きできます。

クリップボードへのアクセスは、標準のDataTransfer のメソッドを使って、itemsClipboardEventclipboardData 属性で操作します。 この結果、これらのクリップボードAPIはClipboardEvent ハンドラのコンテキスト内でのみクリップボードデータにアクセスできます。

注: クリップボードイベントハンドラの外部でクリップボードにアクセスしたい場合は、§ 7 非同期クリップボードAPIを参照してください。

注: クリップボードイベントAPIは同期的であり、できることに制限があります。権限取得や画像のトランスコードなど、ブロッキングの可能性がある操作はこれらのAPIではサポートされていません。ブロッキングや時間のかかる操作に対応するより強力なAPIについては§ 7 非同期クリップボードAPIを参照してください。

6.1. copyイベントの上書き

デフォルトのcopy イベントの動作を上書きするには、copy イベントハンドラを追加し、そのイベントハンドラ内でpreventDefault() を呼び出してイベントをキャンセルする必要があります。

イベントをキャンセルすることで、システムクリップボードclipboardData のデータで更新されます。 ClipboardEvent がキャンセルされない場合は、現在のドキュメント選択のデータがコピーされます。

// クリップボードにコピーされる内容を上書きする例
document.addEventListener('copy', function(e) {
  // e.clipboardDataは初期状態では空ですが、コピーしたいデータを設定できます。
  e.clipboardData.setData('text/plain', 'Hello, world!');
  e.clipboardData.setData('text/html', '<b>Hello, world!</b>');

  // ドキュメント選択範囲がクリップボードに書き込まれるのを防ぐために必要です。
  e.preventDefault();
});

6.2. cutイベントの上書き

デフォルトのcut イベントの動作を上書きするには、cut イベントハンドラを追加し、そのイベントハンドラ内でpreventDefault() を呼び出してイベントをキャンセルする必要があります。

イベントをキャンセルすることで、システムクリップボードclipboardData のデータで更新されます。 ClipboardEvent がキャンセルされない場合は、現在のドキュメント選択のデータがコピーされます。

cut イベントをキャンセルすると、ドキュメントが更新されなくなります(つまり、現在選択されているテキストは削除されません)。選択されたテキストを削除するには、イベントハンドラ内で手動でドキュメントを更新する必要があります。

// クリップボードにコピーされる内容を上書きする例
document.addEventListener('cut', function(e) {
  // e.clipboardDataは初期状態では空ですが、切り取り時にコピーしたいデータを設定できます。
  // クリップボードにコピーしたいデータを書き込みます。
  e.clipboardData.setData('text/plain', 'Hello, world!');
  e.clipboardData.setData('text/html', '<b>Hello, world!</b>');

  // cut操作をキャンセルするため、選択されたテキストを手動で削除する必要があります。
  deleteCurrentDocumentSelection();

  // ドキュメント選択範囲がクリップボードに書き込まれるのを防ぐために必要です。
  e.preventDefault();
});

6.3. pasteイベントの上書き

デフォルトのpaste イベントの動作を上書きするには、paste イベントハンドラを追加し、そのイベントハンドラ内でpreventDefault() を呼び出してイベントをキャンセルする必要があります。

イベントをキャンセルすることで、ユーザーエージェントがシステムクリップボードのデータでドキュメントを更新しなくなります。

paste イベントをキャンセルすると、ドキュメントが更新されなくなります(つまり、何も貼り付けられません)。データをドキュメントに貼り付けるには、イベントハンドラ内で手動で貼り付け処理を行う必要があります。

また、貼り付け時にはドラッグデータストアモードのフラグが読み取り専用になるため、setData()paste イベントハンドラ内で呼び出しても、挿入されるデータやクリップボード上のデータは変更されません。

// クリップボードから貼り付けられる内容を上書きする例
document.addEventListener('paste', function(e) {
  // e.clipboardDataは貼り付け直前のデータを含みます。
  if (e.clipboardData.types.indexOf('text/html') > -1) {
    var oldData = e.clipboardData.getData('text/html');
    var newData = '<b>Ha Ha!</b> ' + oldData;

    // 貼り付け操作をキャンセルするため、手動でデータをドキュメントに貼り付けます。
    pasteClipboardData(newData);

    // デフォルトの貼り付け動作を防ぐために必要です。
    e.preventDefault();
  }
});

6.4. 必須データ型

実装は、以下のデータ型についてOSのクリップボード形式の説明を認識し、DataTransferItemListClipboardItem を適切に記述することで、貼り付けイベント時に正しい内容を提供し、コピー・切り取りイベント時にはOSクリップボード上に正しいデータ形式を設定しなければなりません。

6.4.1. クリップボードからの読み取り

これらのデータ型は、クリップボード上に対応するネイティブ型が存在する場合、pasteイベントで公開されなければなりません:

6.4.2. クリップボードへの書き込み

これらのデータ型は、copycutイベント時にDataTransfer オブジェクトに追加された場合、対応するネイティブ型の説明と共にクリップボードへ配置されなければなりません。

警告!信頼されていないスクリプトがクリップボードへ書き込めるデータ型は、セキュリティ対策として制限されています。信頼されていないスクリプトは、ローカルソフトウェアの脆弱性を引き起こす既知のデータをクリップボードに配置しようとする場合があります。

6.5. 任意データ型

実装は、以下のデータ型についてOSのクリップボード形式の説明を認識してもよく、ClipboardItem を貼り付けイベント時に適切に記述し、コピー・切り取りイベント時にはOSクリップボード上に正しいデータ形式を設定してもよいです。

これらのデータ型は、クリップボード上に対応するネイティブ型が存在する場合、UAによって公開されることがあります:

6.6. 未サニタイズデータ型

このセクションは規範的ではありません。

以下のデータ型はUAによってサニタイズされてはなりません:

以下のデータ型はUAによってサニタイズされない場合があります:

任意未サニタイズデータ型とは、ウェブ著者が指定するもので、UAによってサニタイズされない場合があるmime typeです。 有効な任意未サニタイズデータ型は以下の通りです:

任意未サニタイズデータ型は、UAのプライバシー要件によってサポートされない場合があります。

7. 非同期クリップボードAPI

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

7.2. ClipboardItemインターフェース

typedef Promise<(DOMString or Blob)> ClipboardItemData;

[SecureContext, Exposed=Window]
interface ClipboardItem {
  constructor(record<DOMString, ClipboardItemData> items,
              optional ClipboardItemOptions options = {});

  readonly attribute PresentationStyle presentationStyle;
  readonly attribute FrozenArray<DOMString> types;

  Promise<Blob> getType(DOMString type);

  static boolean supports(DOMString type);
};

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

dictionary ClipboardItemOptions {
  PresentationStyle presentationStyle = "unspecified";
};
clipboardItem = new ClipboardItem([items, options])
新しいClipboardItem オブジェクトを作成します。items表現のリストを表し、各表現mime typeと、対応するPromiseBlobまたはDOMStringを持ちます。optionsClipboardItemOptions の値を設定するために使います。下記の例を参照してください。
const format1 = 'text/plain';
const promise_text_blob = Promise.resolve(new Blob(['hello'], {type: format1}));
const clipboardItemInput = new ClipboardItem(
  {[format1]: promise_text_blob},
  {presentationStyle: "unspecified"});
clipboardItem.getType(type)
mime type typeに対応するPromiseBlobとして返します。
clipboardItem.types
このクリップボードアイテムオブジェクト内のmime typeのリストを返します。
ClipboardItem.supports(type)
type必須データ型または任意データ型に含まれていればtrue、そうでなければfalseを返します。

クリップボード項目は、 概念的には、ユーザーが「cut」または「copy」 コマンドを呼び出すことによって共有可能にしたいという意思を示したデータである。クリップボード項目は 2つの目的を果たす。第一に、ユーザーによってシステムクリップボードにコピーされたデータをウェブサイトが読み取れるようにする。第二に、 ウェブサイトがシステムクリップボードへデータを書き込めるようにする。

たとえば、ユーザーがネイティブアプリケーションのスプレッドシートからセル範囲をコピーした場合、それは 1つのクリップボード項目になる。ユーザーが デスクトップからファイルの集合をコピーした場合、そのファイル一覧は複数のクリップボード項目として表される。

一部のプラットフォームでは、クリップボード上に一度に複数のクリップボード項目を持つことをサポートする場合がある一方で、他のプラットフォームでは 以前のクリップボード 項目が新しいものに置き換えられる。

クリップボード項目は、表現の リストを持ち、各表現は、関連付けられたMIME 型MIME 型)、初期値が falseであるisCustomフラグを持ち、このフラグは この表現を(システムクリップボードの よく知られた形式ではなく)ウェブカスタム形式として扱うべきかどうかを示し、さらにデータClipboardItemData)を持つ。

ウェブカスタム形式は、 isCustomtrueに設定されている。

ユーザーがスプレッドシートからセル範囲をコピーする例では、それは画像 (image/png)、HTML表(text/html)、プレーンテキスト(text/plain)、またはウェブカスタム形式(web text/csv)として表される場合がある。

これらのMIME 型はそれぞれ、同じクリップボード項目の異なる 忠実度レベルの表現を記述し、貼り付け時に対象アプリケーションが クリップボード項目をより利用しやすくする。

セル範囲を画像として利用可能にすると、ユーザーはそのセルを写真編集 アプリに貼り付けられるようになり、一方でtext/plain形式はテキストエディターアプリで使用できる。

クリップボード項目は、表示スタイルPresentationStyle)を持つ。 これは、クリップボード項目を「貼り付ける」アプリが、適切な表現の内容を 貼り付け位置にインラインで挿入すべきか、それとも添付ファイルとして扱うべきかを区別するのに役立つ。

単一のクリップボード項目のみの貼り付けをサポートするウェブアプリは、最初のクリップボード項目を使用するべきである。

write() は最後のクリップボード 項目を選択する。

複数のクリップボード項目の貼り付けをサポートするウェブアプリは、たとえば、 各クリップボード項目の内容をプレビューし、どれを貼り付けるかを ユーザーが選択できるユーザーインターフェイスを提供できる。さらに、アプリは貼り付けるクリップボード項目MIME 型を列挙し、 何らかのアプリ固有のアルゴリズムに従って、そのアプリに最も適したものを選択することが期待される。 あるいは、アプリはクリップボード項目をどのように貼り付けるか、たとえば「画像として貼り付け」や「書式付きテキストを貼り付け」などの選択肢をユーザーに提示できる。

ClipboardItem オブジェクトには、関連付けられたクリップボード項目があり、これはクリップボード項目である。

ClipboardItem オブジェクトには、関連付けられたtypes 配列があり、これはFrozenArray<DOMString>である。

ClipboardItem オブジェクトには、関連付けられた読み取り時のクリップボード変更 カウントがあり、これは初期値がnullである。

ClipboardItem オブジェクトには、関連付けられた元のシステムクリップボード 項目があり、これはシステムクリップボード項目またはnullであり、初期値はnullである。

ClipboardItem オブジェクトには、関連付けられたサニタイズされていないMIME型があり、これはsequence<DOMString>で、 初期値は空である。

ClipboardItem オブジェクトには、関連付けられたリゾルバー付き表現があり、 これは文字列(getType()に渡されたMIME 型で、 存在する場合は`"web "`接頭辞を含む)からPromise<Blob>へのmapで、 初期値は空である。各エントリーは、その型について完了済みまたは現在進行中のOSクリップボード読み取りを表す。

Note: このmapは、read() から取得したClipboardItemに対する、同じMIME型の同時getType() 呼び出しが、単一のOSクリップボード読み取りを共有することを保証する。最初の呼び出しは保留中のPromise をmapに挿入して読み取りを開始し、同じMIME型に対する後続の呼び出しは、システムクリップボードを再読み取りすることなく既存のPromise を返す。

read()によってClipboardItem が作成された場合、それはデータスナップショットではなく遅延フェッチャーとして機能する。そのtypes 配列は、read() 呼び出し時点でシステムクリップボード上で利用可能な 形式を反映するが、実際のペイロードバイトはgetType() が呼び出されるまで読み取られない。read() 呼び出しと後続のgetType() 呼び出しの間にシステム クリップボードの内容が変更された場合、getType() 呼び出しは拒否される。ClipboardItem(items, options) コンストラクターを介して直接構築されたClipboardItem は、この挙動の対象ではない。

クリップボード項目 clipboardItemおよびRealm realmが与えられたとき、ClipboardItem オブジェクトを作成するには、次の手順を実行する:

  1. clipboardItemObjectを、realmを伴う新しいClipboardItem とする。

  2. clipboardItemObjectクリップボード項目clipboardItemに設定する。

new ClipboardItem(items, options) コンストラクター手順は次のとおり:

  1. itemsが空である場合、TypeErrorを投げる。

  2. optionsが空である場合、options["presentationStyle"] = "unspecified"に設定する。

  3. thisクリップボード項目を、新しいクリップボード項目に設定する。

  4. thisクリップボード項目表示スタイルを、 options["presentationStyle"]に設定する。

  5. typesDOMStringのリストとする。

  6. items内の各(key, value)について:

    1. representationを新しい表現とする。

    2. isCustomfalseとする。

    3. keyが`"web "`接頭辞で始まる場合、

      1. `"web "`接頭辞を削除し、残りの文字列をkeyに代入する。

      2. isCustomtrueに設定する

    4. representationisCustomフラグをisCustomに設定する。

    5. mimeTypeを、keyを与えてMIME 型を解析する結果とする。

    6. mimeTypeがfailureである場合、TypeErrorを投げる。

    7. thisクリップボード項目表現の リストが、MIME 型mimeTypeであり、かつ[representation/isCustom]がisCustomである表現含む場合、TypeErrorを投げる。

    上記の手順は、ユーザー エージェントによく知られているMIME型と、作者がカスタム型として扱うことを意図したものとの衝突を防ぐ。たとえば、 作者の項目リストに"text/html"と "web text/html"の両方の表現を含めることが可能である。

    1. representationMIME 型mimeTypeに設定する。

    2. representationデータvalueに設定する。

    3. representationthisクリップボード項目表現の リストに追加する。

    4. mimeTypeStringを、mimeTypeMIME 型を直列化する結果とする。

    5. isCustomtrueである場合、mimeTypeStringの前に`"web "`を付加する。

    6. mimeTypeStringtypesに追加する。

  7. thistypes 配列を、typesから凍結配列を作成するを実行した結果に設定する。

7.2.1. presentationStyle

presentationStyle ゲッターの手順は、thisclipboard itempresentation styleを返すこと。

7.2.2. types

types ゲッターの手順は、thistypes arrayを返すこと。

7.2.3. getType(type)

このメソッドは以下の手順を実行する:

  1. realmを、this関連Realmとする。

  2. isCustomfalseとする。

  3. typeが`"web "`接頭辞で始まる場合:

    1. `"web "`接頭辞を削除し、残りの文字列をtypeに代入する。

    2. isCustomtrueに設定する。

  4. mimeTypeを、typeを与えてMIME 型を解析する結果とする。

  5. mimeTypeがfailureである場合、TypeErrorを投げる。

  6. itemTypeListを、thisクリップボード項目表現の リストとする。

  7. pを、realm内の新しいpromiseとする。

  8. itemTypeList内の各representationについて:

    1. representationMIME 型mimeTypeであり、かつ representationisCustomisCustomである場合:

      1. this読み取り時のクリップボード変更 カウントがnullでなく、かつ現在のクリップボード 変更カウントthis読み取り時のクリップボード変更 カウントと等しくない場合、realm内の"InvalidStateError" DOMExceptionp拒否し、 pを返す。

        Note: これにより、古くなった データが返されないことが保証される。read() が呼び出されてからシステムクリップボードの内容が変更されている場合、 現在のシステムクリップボード状態に対応しないデータを返すのではなく、 これは失敗しなければならない。

        Note: nullの読み取り時のクリップボード変更 カウントは、このClipboardItem が作者によって直接構築された(たとえばClipboardItem(items, options)を介して) ものであり、read() から取得されたものではないことを示す。その場合、データはシステムクリップボードに由来しないため、古いデータかどうかのチェックは不要である。

      2. this読み取り時のクリップボード変更 カウントがnullでない場合:

        Note: この分岐は、ClipboardItemのうち、 read() から取得されたものを扱う。この場合、OSクリップボードの読み取りはこの時点まで遅延される。同じMIME型に対してgetType() が複数回同時に呼び出された場合でも、読み取りが型ごとに高々一度だけ発生するようにするため、結果のPromise は、正規化された型文字列をキーとしてthisリゾルバー付き 表現mapにキャッシュされる。これにより、`"text/html"`と `"web text/html"`は別々に追跡される一方で、同じ型の大文字小文字の異なる表記 (たとえば`"text/HTML"`と`"text/html"`)は単一のエントリーにまとめられる。

        1. keyを、mimeTypeessenceとする。isCustomが trueである場合、keyの前に`"web "`を付加する。

        2. thisリゾルバー付き 表現[key]が存在する場合、thisリゾルバー付き 表現[key]を返す。

        3. 設定する:thisリゾルバー付き 表現[key]をpに。

        4. 以下の手順を並列に実行する:

          1. clipboardItemを、this元の システムクリップボード項目とする。

          2. clipboardItemがnullである場合、realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは クリップボードタスクソース上で、 realm内の"InvalidStateError" DOMExceptionp拒否するためのものであり、その後これらの手順を中止する。

          3. isCustomがtrueである場合:

            1. mapNameを、OS固有の カスタムマップ名とする。

            2. mapRepresentationを、clipboardItemシステム クリップボード表現のリスト内にあるシステム クリップボード表現であって、その名前mapNameであるものとする。そのようなシステム クリップボード表現がない場合、realmグローバルオブジェクトを与えて、 グローバル タスクをキューに入れる。これはクリップボードタスク ソース上で、realm内の "NotFoundError" DOMExceptionp拒否するためのものであり、その後これらの手順を中止する。

            3. webCustomFormatMapStringを、mapRepresentationデータから逆シリアル化されたJSON文字列とする。

            4. osFormatNameを、直列化されたmimeTypeと一致するキーを持つ、 webCustomFormatMapString内の値とする。

            5. osFormatNameが見つからない場合、realmグローバルオブジェクトを与えて、 グローバル タスクをキューに入れる。これはクリップボードタスク ソース上で、realm内の "NotFoundError" DOMExceptionp拒否するためのものであり、その後これらの手順を中止する。

          4. そうでなければ、osFormatNameを、mimeTypeを与えてOS固有の 既知形式を実行した結果とする。

          5. clipboardRepresentationを、clipboardItemシステムクリップボード 表現のリスト内にあるシステムクリップボード 表現であって、その名前osFormatNameであるものとする。そのようなシステムクリップボード 表現がない場合、realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは クリップボードタスクソース上で、 realm内の"NotFoundError" DOMExceptionp拒否するためのものであり、その後これらの手順を中止する。

          6. rawDataを、clipboardRepresentationデータとする。

          7. cleanDataを、rawDataのコピーとする。

          8. mimeTypeessencethisサニタイズされていない MIME 型内にあり、かつmimeTypeessence任意の サニタイズされていないデータ型リスト内にある場合、何もしない。

          9. そうでなく、mimeTypeessenceが"image/png"でない場合、 ユーザーエージェントはcleanDataをサニタイズしてもよい。

          10. blobを、Blob とする。そのtype直列化されたmimeTypeであり、その 基になるバイト列はcleanDataである。

          11. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは クリップボードタスクソース上で、 pblobで解決するためのものである。

        Note: pが settledになると、それはthisリゾルバー付き 表現map内に残る。同じMIME型に対する後続のgetType() 呼び出しは、システムクリップボードを再読み取りすることなく、 キャッシュされたsettledのPromise を返す。ただし、上記の古いデータかどうかのチェックは、すべての呼び出しに引き続き適用される。すなわち、read() が呼び出されてからシステムクリップボード が変更されている場合、このClipboardItem上のすべてのgetType() 呼び出しは、以前にキャッシュされたデータであっても、"InvalidStateError" で拒否される。

        1. pを返す。

      3. representationDataPromiseを、representationデータとする。

      4. representationDataPromise反応する:

        1. representationDataPromiseが値 vで履行された場合:

          1. vDOMStringである場合、 以下の手順に従う:

            1. dataAsBytesを、vUTF-8符号化 した結果とする。

            2. blobDataを、dataAsBytesを用いて作成されたBlob とし、そのtype直列化されたmimeTypeに設定される。

            3. pblobDataで解決する。

          2. vBlobである場合、 以下の手順に従う:

            1. pvで解決する。

        2. representationDataPromiseが拒否された場合:

          1. realm内の"NotFoundError" DOMExceptionp拒否する。

            ウェブ開発者は、 根本的な拒否理由に関心を持つ可能性がある。

      5. pを返す。

  9. realm内の"NotFoundError" DOMExceptionp拒否する。

  10. pを返す。

7.2.4. supports(type)

このメソッドは以下の手順を実行する:

  1. type必須データ型または任意データ型に含まれる場合、trueを返す。

  2. そうでなければ、falseを返す。

7.3. Clipboardインターフェース

typedef sequence<ClipboardItem> ClipboardItems;

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

dictionary ClipboardUnsanitizedFormats {
  sequence<DOMString> unsanitized;
};

Clipboard インターフェイスの一部のメソッドは、複数のClipboardItem オブジェクトを受け取る、または返す。しかし、すべてのプラットフォームが複数のクリップボード項目をサポートしているわけではない。そのようなプラットフォームでは、以下のアルゴリズムは write()に渡された、最初のものを超える ClipboardItem オブジェクトを無視し、 read() およびreadText() はOSから1つのクリップボード項目のみを取得する。

クリップボード項目群 オブジェクトは、クリップボード項目sequenceである。

ウェブ作者は、write(data) メソッドを使用してシステムクリップボードに内容を書き込むために、ClipboardItemの配列である dataを作成する必要がある。 read() は、システムクリップボードデータの内容を表す クリップボード項目群オブジェクトへのPromise を返す。

unsanitized は、作者が任意のサニタイズされていないデータ型として扱われることを望むMIME型に対応する、DOMStringsequenceである。

unsanitized オプションはユーザーエージェントによってサポートされない場合がある。プライバシーモードなど、このオプションが許可されない場合があり得るため、 ウェブ作者は、unsanitized に列挙されたMIME型の内容がサニタイズされないと仮定すべきではない。

クリップボードタスク ソースは、システムクリップボードデータの読み取りまたは書き込みに応答してトリガーされる。

7.3.1. read(formats)

read(formats) メソッドは次の手順を実行しなければならない:
  1. realmを、this関連Realmとする。

  2. pを、realm内の新しい promiseとする。

  3. formatsが空でない場合:

    1. formats["unsanitized"]内の各formatについて:

      1. format任意のサニタイズされていないデータ 型内にない場合、realm内のformat "NotAllowedError" DOMExceptionp拒否する。

  4. 次の手順を並列に実行する:

    1. rを、クリップボード読み取り 権限を確認するを実行した結果とする。

    2. rがfalseである場合:

      1. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは権限タスクソース上で、 realm内の"NotAllowedError" DOMExceptionp拒否するためのものである。

      2. これらの手順を中止する。

    3. dataを、システムクリップボードデータとする。

    4. snapshotChangeCountを、現在のクリップボード 変更カウントとする。

      Note: この時点では、dataからの名前(形式 識別子)のみが列挙される。各表現の基になる ペイロードバイトは、getType() が呼び出されるまで読み取られない。

    5. itemssequenceordered mapとし、各エントリーはキー"item"(クリップボード項目)と"originating"(システムクリップボード項目またはnull)を持つものとする。

    6. data内の各systemClipboardItemについて:

      1. itemを新しいクリップボード項目とする。

      2. systemClipboardItem内の各systemClipboardRepresentationについて:

        1. mimeTypeを、systemClipboardRepresentation名前を与えてOS固有形式からの 既知MIME型アルゴリズムを実行した結果とする。

        2. mimeTypeがnullである場合、このループを継続する。

        3. representationを新しい表現とする。

        4. representationMIME型mimeTypeに設定する。

        5. representationデータを、realm内の新しいpromiseに設定する。

          Note: この表現のOS クリップボードデータは、作者が結果のClipboardItem オブジェクト上でgetType() を呼び出すまで取得されない。

        6. representationitem表現の リストに追加する。

      3. item表現のリストのサイズが 0より大きい場合、ordered map «[ "item" → item, "originating" → systemClipboardItem ]» をitemsに追加する。

    7. itemsのサイズが0より大きい場合:

      1. firstItemitems[0]["item"]とする

      2. firstItemを与えてウェブカスタム形式を読み取るアルゴリズムを 実行する。

    8. そうでなければ:

      1. customItemを新しいクリップボード項目とする。

      2. customItemを与えてウェブカスタム形式を読み取る アルゴリズムを実行する。

      3. customItem表現のリストのサイズが 0より大きい場合、ordered map «[ "item" → customItem, "originating" → null ]» をitemsに追加する。

    9. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これはクリップボードタスクソース上で、以下の 手順を実行するためのものである:

      1. clipboardItemssequence<ClipboardItem>とする。

      2. itemsの各ordered map entryについて:

        1. clipboardItemを、entry["item"]および realmを与えてClipboardItemオブジェクトを 作成するの手順を実行した結果とする。

        2. clipboardItem読み取り時のクリップボード 変更カウントsnapshotChangeCountに設定する。

        3. clipboardItem元の システムクリップボード項目entry["originating"]に設定する。

        4. formatsが空でない場合、clipboardItemサニタイズされていない MIME型formats["unsanitized"]に設定する。

        5. clipboardItemclipboardItemsに追加する。

      3. pclipboardItemsで解決する。

  5. pを返す。

// clipboard.read() は型メタデータのみを含むClipboardItemを返す。
// この時点ではOSクリップボードデータは読み取られない。
const items = await navigator.clipboard.read();

// getType()が呼び出されると、この時点でOSクリップボードの読み取りが遅延して行われる。
const textBlob = await items[0].getType("text/plain");
const text = await (new Response(textBlob)).text();

7.3.2. readText()

readText() メソッドは次の手順を実行しなければならない:
  1. realmを、this関連Realmとする。

  2. pを、realm内の新しい promiseとする。

  3. 次の手順を並列に実行する:

    1. rを、クリップボード読み取り 権限を確認するを実行した結果とする。

    2. rがfalseである場合:

      1. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは権限タスクソース上で、 realm内の"NotAllowedError" DOMExceptionp拒否するためのものである。

      2. これらの手順を中止する。

    3. dataを、システム クリップボードデータのコピーとする。

      一部のOSには複数のクリップボードがある(例:Linuxの「primary」、「secondary」、 「selection」)。それらのうち、どのデータから読み取るかを定義する。

      サニタイズ済みコピーの定義を追加する。

    4. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これはクリップボードタスクソース上で、以下の 手順を実行するためのものである:

      1. data内の各systemClipboardItemについて:

        1. systemClipboardItem内の各systemClipboardRepresentationについて:

          1. mimeTypeを、systemClipboardRepresentation名前を与えてOS固有形式からの 既知MIME型アルゴリズムを実行した結果とする。

          2. mimeTypeがnullである場合、このループを継続する。

          3. representationを新しい表現とする。

          4. representationMIME型essenceが "text/plain"である場合:

            1. representationMIME 型mimeTypeに設定する。

            2. representationDataPromiseを、 representationデータとする。

            3. representationDataPromise反応 する:

              1. representationDataPromiseが値vで 履行された場合:

                1. vDOMStringである場合、 以下の手順に従う:

                  1. pvで解決する。

                  2. pを返す。

                2. vBlobである場合、 以下の手順に従う:

                  1. stringを、 vの基になる バイト列をUTF-8 復号 した結果とする。

                  2. pstringで解決する。

                  3. pを返す。

              2. representationDataPromiseが 拒否された場合:

                1. realm内の"NotFoundError" DOMExceptionp拒否する。

                2. pを返す。

      2. realm内の"NotFoundError" DOMExceptionp拒否する。

      3. pを返す。

navigator.clipboard.readText().then(function(data) {
  console.log("取得した文字列: ", data);
});

7.3.3. write(data)

write(data) メソッドは以下の手順を実行する:
  1. realmを、this関連Realmとする。

  2. pを、realm内の新しい promiseとする。

  3. 次の手順を並列に実行する:

    1. rを、クリップボード書き込み 権限を確認するを実行した結果とする。

      clipboard-writeはhttps://github.com/w3c/clipboard-apis/pull/164で削除された。

    2. rがfalseである場合:

      1. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは権限タスクソース上で、 realm内の"NotAllowedError" DOMExceptionp拒否するためのものである。

      2. これらの手順を中止する。

    3. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これはクリップボードタスクソース上で、以下の 手順を実行するためのものである:

      1. itemListおよびcleanItemListを、空のsequence<Blob>とする。

      2. dataListsequence<ClipboardItem>とする。

      3. datasizeが1より大きく、かつ現在の オペレーティングシステムがシステムクリップボード上の複数のネイティブクリップボード項目をサポートしない場合、 data[0]をdataListに追加し、そうでなければ、dataListdataに設定する。

        dataが複数の項目を含み、 かつオペレーティングシステムが複数のネイティブクリップボード項目をサポートする場合、 現在のアルゴリズムはそれらの項目をまとめて書き込むのではなく、 システムクリップボードへ順番に書き込む。

      4. dataList内の各clipboardItemについて:

        1. clipboardItemクリップボード項目表現の リスト内の各representationについて:

          1. representationDataPromiseを、 representationデータとする。

          2. representationDataPromise反応 する:

            1. representationDataPromiseが値vで履行された場合:

              1. vDOMStringである場合、 以下の手順に従う:

                1. dataAsBytesを、 vUTF-8 符号化した結果とする。

                2. blobDataを、dataAsBytesを用いて作成されたBlob とし、そのtyperepresentationMIME 型に設定する。

                3. blobDataitemListに追加する。

              2. vBlobである場合、 vitemListに追加する。

            2. representationDataPromiseが拒否された場合:

              1. realm内の"NotAllowedError" DOMExceptionp拒否する。

              2. これらの手順を中止する。

        2. itemList内の各blobについて:

          1. typeを、blobtypeとする。

          2. type必須データ 型または任意データ 型リスト内にない場合、realm内の"NotAllowedError" DOMExceptionp拒否し、これらの手順を中止する。

          3. cleanItemを、blobの任意でサニタイズされたコピーとする。

            サニタイズ済み コピーの定義を追加する。

          4. サニタイズが試みられ、かつ正常に 完了しなかった場合、以下の手順に従う:

            1. realm内の"NotAllowedError" DOMExceptionでp拒否する。

            2. これらの手順を中止する。

          5. cleanItemcleanItemListに追加する。

        3. optionを、clipboardItemクリップボード項目表示スタイルとする。

        4. cleanItemList およびoptionを用いて、Blob群と optionをクリップボードへ書き込む

      5. pを解決する。

  4. pを返す。

var data = [new ClipboardItem({ "text/plain": Promise.resolve(new Blob(["Text data"], { type: "text/plain" })) })];
navigator.clipboard.write(data).then(function() {
  console.log("クリップボードへのコピーに成功しました!");
}, function() {
  console.error("クリップボードへの書き込みに失敗しました :-(");
});

7.3.4. writeText(data)

writeText(data) メソッドは以下の手順を実行する:
  1. realmを、this関連Realmとする。

  2. pを、realm内の新しい promiseとする。

  3. 次の手順を並列に実行する:

    1. rを、クリップボード書き込み 権限を確認するを実行した結果とする。

      clipboard-writeはhttps://github.com/w3c/clipboard-apis/pull/164で削除された。

    2. rがfalseである場合:

      1. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは権限タスクソース上で、 realm内の"NotAllowedError" DOMExceptionでp拒否するためのものである。

      2. これらの手順を中止する。

    3. realmグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これはクリップボードタスクソース上で、以下の 手順を実行するためのものである:

      1. itemListを空のsequence<Blob>とする。

      2. textBlobを、次によって作成された新しいBlob とする: type 属性を"text/plain;charset=utf-8"に設定し、 その基になるバイト列をdataUTF-8符号化に設定する。

        Note: Windowsでは、 textBlobを作成する前にdata内の`\n`文字を`\r\n`に置き換える。

      3. textBlobitemListに追加する。

      4. optionを"unspecified"に設定する。

      5. itemListおよび optionを用いて、Blob群と optionをクリップボードへ書き込む

      6. pを解決する。

  4. pを返す。

await navigator.clipboard.writeText("こんにちは!");

8. クリップボードアクション

このセクションでは、クリップボードアクションおよびイベント発火の処理モデルについて定義します。

各クリップボードアクションには、script-triggeredscript-may-access-clipboardという2つのフラグがあります。

script-triggeredフラグは、例えばdocument.execCommand()の呼び出しなど、スクリプトによってアクションが実行された場合にセットされます。今後クリップボードと連携するスクリプトAPIもこれらのアクションを利用し、script-triggeredフラグを適切にセットする必要があります。

script-may-access-clipboardフラグは、以下のように設定されます:

  1. アクションがcopyまたはcutであり、スクリプトスレッドがクリップボードの変更が許可されている場合、

    1. アクションのscript-may-access-clipboardフラグをセットする

  2. アクションがpasteであり、スクリプトスレッドがクリップボードからの読み取りが許可されている場合、

    1. アクションのscript-may-access-clipboardフラグをセットする。

8.1. コピーアクション

コピーアクションは次の手順で構成されます:

  1. script-triggered フラグが設定されている場合、

    1. script-may-access-clipboard フラグが未設定の場合、

      1. コピー操作から false を返し、このアルゴリズムを終了する

  2. クリップボードイベントを発火する。イベント名は copy

  3. もしイベントがキャンセルされなかった場合、

    1. 選択されている内容があれば、それをクリップボードにコピーする。実装は 可能なら、ウェブページ内の選択内容に対し text/html および text/plain の代替クリップボードフォーマットを作成するべきである。

    2. クリップボードイベントを発火する。イベント名は clipboardchange

  4. さもなければ、イベントがキャンセルされた場合、

    1. クリップボードへ内容を書き込むアルゴリズムを呼び出す。その際、DataTransferItemList リスト itemsclear-was-called フラグおよび types-to-clear リストを渡す。

  5. コピー操作から true を返す

8.2. 切り取りアクション

切り取りアクションは次の手順で構成されます:

  1. script-triggered フラグが設定されている場合、

    1. script-may-access-clipboard フラグが未設定の場合、

      1. カットアクションから false を返し、このアルゴリズムを終了する

  2. クリップボードイベントを発火する。イベント名は cut

  3. イベントがキャンセルされなかった場合、

    1. もし 編集可能コンテキスト かつカットが有効な箇所に選択範囲がある場合、

      1. 選択された内容があればそれをクリップボードにコピーする。実装は 可能なら、ウェブページで選択された内容について text/html および text/plain の代替クリップボード形式を生成するべきである。

      2. 選択内容をドキュメントから削除し、選択範囲を折りたたむ。

      3. クリップボードイベントを発火する。イベント名は clipboardchange

      4. この修正によって発火すべき他のイベントを発火させるためのタスクをキューする。詳細は § 5.3 他のスクリプトやイベントとの統合 を参照。

    2. そうでない場合(選択がない、またはコンテキストが編集不可の場合)、

      1. false を返す

  4. さもなければ、イベントがキャンセルされた場合、

    1. クリップボードに内容を書き込むアルゴリズムを呼び出す。その際、DataTransferItemList リスト itemsclear-was-called フラグ、types-to-clear リストを渡す。

    2. クリップボードイベントを発火する。イベント名は clipboardchange

  5. カットアクションから true を返す

8.3. 貼り付けアクション

貼り付けアクションについては、script-may-access-clipboardフラグは、クリップボードから読み取れるサイトやアプリを決定する実装依存の権限機構に依存します。スクリプトによって貼り付けアクションがトリガーされた場合、実装はユーザーの許可なしにクリップボードの内容を利用可能にしてはなりません。権限が未付与の場合、許可ダイアログにはスクリプトスレッドに関連付けられたドキュメントのホスト名を含めなければなりません。

貼り付けアクションは次の手順で構成されます:

  1. script-triggeredフラグがセットされている場合、

    1. script-may-access-clipboardが未セットの場合、

      1. 貼り付けアクションからfalseを返し、このアルゴリズムを終了する

  2. pasteという名前のクリップボードイベントを発火する

  3. イベントがキャンセルされなかった場合、

    1. 編集可能コンテキスト内で貼り付けが有効な選択やカーソルがある場合、

      1. クリップボード上の最適な内容(あれば)をそのコンテキストに挿入する。

      2. 変更によって発火すべきイベントをキューに追加する。詳細は§ 5.3 他のスクリプトやイベントとの統合を参照。

    2. それ以外の場合、

      1. falseを返す

  4. イベントがキャンセルされた場合

    1. falseを返す

  5. アクションからtrueを返す

9. Permissions APIとの統合

[permissions] APIは、ウェブサイトが強力な機能(クリップボードなど)へアクセスするための統一的な方法を提供します。これにより、ウェブサイトはユーザーから権限を要求したり、どの権限があるかを照会できます。

クリップボードについては、1つの権限が定義されています:"clipboard-write"

注: クリップボード権限は現在、非同期クリップボードAPIのみに適用されます。将来の本仕様のバージョンでは、他のクリップボード操作にもこの権限が適用される可能性があります。

これらのクリップボード権限は強力な機能であり、権限関連のアルゴリズムと型は以下のように定義されます:

permission descriptor type
dictionary ClipboardPermissionDescriptor : PermissionDescriptor {
  boolean allowWithoutGesture = false;
};

クリップボード権限は4種類あります:

それぞれの関係は次の通りです:

ユーザーエージェントは本仕様で記載されたClipboardPermissionDescriptor を必ずサポートしなければなりませんが、デフォルト設定やユーザーへの表示方法(あるいは表示しない方法)については完全に制御できます。

ユーザーエージェントがクリップボードへの書き込みを個別にユーザーが設定でき、常にユーザー操作が必要となるよう制御したい場合、各ディスクリプタは以下のように扱われます:

9.1. クリップボード読み取り権限

9.1.1. クリップボード読み取り権限の確認

  1. hasGesture を、this関連グローバルオブジェクト一時的アクティベーション を持つ場合 true、そうでない場合は false とする。

  2. もしhasGestureなら、

    1. 現在のスクリプトがユーザーエージェントまたはOSが作成した「貼り付け」要素のユーザー操作により実行されている場合trueを返す。

  3. falseを返す。

9.2. クリップボード書き込み権限

9.2.1. クリップボード書き込み権限の確認

  1. writeWithoutGesture{ name: "clipboard-write", allowWithoutGesture: true }権限の権限状態とする。

  2. writeWithoutGesturegrantedならtrueを返す。

  3. hasGesture を、this関連グローバルオブジェクト一時的アクティベーション を持つ場合 true、そうでない場合は false とする。

    もしhasGestureなら、

    1. 現在のスクリプトがユーザーエージェントまたはOSが作成した「cut」または「copy」要素のユーザー操作により実行されている場合systemCopyをtrueとする。

    2. systemCopyがtrueならtrueを返す。

    3. 権限の利用要求{ name: "clipboard-write", allowWithoutGesture: false }権限に対して実行した結果を返す。

      注: ユーザーエージェントは、より強い権限を要求し、暗黙的にこの権限を更新する選択も可能です。

  4. 権限の利用要求{ name: "clipboard-write", allowWithoutGesture: true }権限に対して実行した結果を返す。

10. セキュリティに関する考慮事項

著者がユーザーによってコピーされる内容を変更したり、選択されたことのないデータを自動的にコピーしたり、情報の貼り付けを無制限に許可することは、様々なセキュリティ上の懸念を引き起こす可能性があります。

例えば以下のようなシナリオがあります:

10.1. HTMLやマルチパートデータの貼り付け

このセクションは規範的ではありません。

フォーマット済みデータやマルチパートデータの貼り付けには特定のセキュリティリスクがあります。

どのようなポリシーを採用するかは、以下の要素を考慮して判断します:

シナリオと考えられるセキュリティポリシーの概要:

データのオリジン スクリプトのオリジン ルール
オンラインソース由来 データと同じ HTMLをサニタイズしない。ローカルファイルへのアクセスはしない。
異なるオリジン コンテンツをサニタイズする場合がある。ローカルファイルへのアクセスはしない。
ローカルアプリケーション由来 任意 HTMLをサニタイズしない。ローカルファイルへのアクセスを許可。

一部の実装は、リッチテキスト貼り付け時にSCRIPT要素やjavascript:リンクなど悪意のある可能性のある内容をデフォルトで除去することでリスクを軽減しますが、pasteイベントハンドラで元の未サニタイズデータを取得・処理できるようにしています。

10.2. 一般的なセキュリティポリシー

実装は、参照されたオンラインリソースをダウンロードしたり、その内容をfiles リストやDataTransferItemListで公開してはなりません

クリップボード上のデータがローカルアプリケーション由来でない場合、実装は参照されているローカルファイルへのアクセスを許可してはなりません。例えば、データに<img src="file://localhost/example.jpg">が含まれていても、データのオリジンがオンラインリソースであれば、example.jpgのエントリをclipboardData.itemsリストに追加してはなりません。

10.3. 画像のトランスコード

悪意のある画像データがクリップボードに置かれるのを防ぐため、画像データは安全なバージョンにトランスコードされる場合があります。これによって、ウェブサイトが他のアプリケーションの脆弱性を悪用するのを防止します。

実装は、クリップボードから画像を読み取る場合はトランスコードすべきではありません。画像のトランスコードは、画像の物理的な解像度など重要なメタデータを失う可能性があります。 これは、画像がウェブサイトと共有される他の方法(たとえば`<input type=file>`)とも一貫しています。

10.4. 迷惑行為対策

スクリプトはDataTransfer APIを使って、コピーや切り取りイベントでシステムクリップボード上のデータを変更し、ユーザーを困惑・混乱させる場合があります。本仕様はこうした迷惑行為の防止までは意図していませんが、実装は追加の制限を設けてもかまいません。

実装は、スクリプトが過剰な量のデータをクリップボードに置こうとした場合も、適切に処理しなければなりません。

11. プライバシーに関する考慮事項

これらのAPIはユーザーのクリップボードデータへのアクセスを提供するため、クリップボードに氏名や住所、パスワードなど個人を特定できる情報(PII)が含まれている可能性があり、重大なプライバシー上の懸念があります。

一般的に、ユーザーエージェントは信頼されていないスクリプトがこれらのAPIを使ってユーザーのクリップボードデータに無制限にアクセスすることを許可してはなりません

11.1. プライバシーとクリップボードイベントAPI

Clipboard Event APIは、クリップボードイベントハンドラのコンテキスト内で実行されているスクリプトに、システムクリップボードのコピーへのアクセスと、クリップボードに書き込まれるデータの変更の可能性を提供します。

ユーザーエージェントは、Clipboard Event APIでアクセスできるデータのセキュリティを確保するため、以下の点に注意すべきです:

Clipboard Event APIはClipboard permissionの対象ではありませんが、ユーザーエージェントはこのAPI自体を無効化したり、アクセスを許可するサイトを設定できる方法を提供してもかまいません。

11.2. プライバシーと非同期クリップボードAPI

非同期クリップボードAPIは強力な機能であり、すべてのスクリプトからクリップボードデータにアクセスできる(Clipboard Eventハンドラに限定されない)上に、ユーザー操作なしでもデータにアクセス可能となる場合があります。

悪用防止のため、このAPIはスクリプトがフォーカスを持つ文書のコンテキスト内で実行されている場合にのみ利用可能でなければなりません

11.2.1. プライバシーとクリップボード権限

クリップボード権限はこのAPIへのアクセスを制御しますが、ユーザーエージェントは権限のデフォルト値やユーザーが設定可能な権限項目を選択できます。例えば、ユーザーエージェントはユーザー操作がある場合のみ非同期クリップボードAPIへのアクセスを許可し、操作なしの場合はスクリプトからのアクセス要求を常に拒否するようにできます。

ユーザーエージェントは、ユーザーが権限を与えてから一定時間が経過した後や、ユーザーがサイトを最後に訪問してから一定時間が経過した後、あるいはユーザーがページから離れた場合などに、権限を自動的に失効させる選択も可能です:

11.3. その他のプライバシー懸念

ユーザーエージェントがdocument.execCommand("paste")を使ってクリップボードデータの読み取りを許可する場合、ユーザーが明示的にそのアクセスを許可したことを必ず確認しなければなりません。

12. 謝辞

このセクションは規範的ではありません

編集者は本仕様の現行状態に導くため、様々な会議やメーリングリストで支えてくださった前任編集者の貢献に感謝します。

編集者はまた、MicrosoftによるData Transfer機能のドキュメント[MICROSOFT-CLIP-OP][HTML5]仕様の初期ドラフトから得られた知的財産にも謝意を表します。Paul Libbrecht氏によるドラフト「安全なコピー&ペースト」にも感謝します(このドラフトはWeb上から入手できなくなっています)。

最後に、下記の方々の貢献にも感謝いたします:

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, Bo Cupp, mbrodesser および Boris Zbarsky.

付録A: アルゴリズム

クリップボードに内容を書き込む

入力

items: DataTransferItemList の書き込むアイテムリスト

clear-was-called: boolean型

types-to-clear: リスト型

出力

なし

  1. itemsリストが空でない場合、

    1. クリップボードをクリアする

    2. リスト内の各パートについて、

      1. データ型がtext/plainの場合、

        1. OSやロケールの規則に従ってエンコーディングが正しいことを保証する

        2. プラットフォームの規則に従って改行コードを正規化する

        3. テキストを適切なOSクリップボード形式記述子でクリップボードに配置する

      2. それ以外でデータ型が必須データ型リストに含まれている場合、

        1. パートを適切なOSクリップボード形式記述子でクリップボードに配置する

      3. その他

        1. この部分は実装依存・・・

          実装依存にするのは好ましくありません。どうすべきか?

          注: OSクリップボードの実装制限により、スクリプトはカスタムフォーマットが他のアプリケーションで利用可能になると仮定すべきではありません。例えばMicrosoft Windowsでは、登録できるカスタムクリップボードフォーマット数に制限があります。setData()のtype引数には任意の文字列が使えますが、必須データ型を使うのが強く推奨されます。

  2. それ以外の場合(itemsリストが空の場合)、クリップボードをクリアするかどうか以下の手順で判断する:

    1. アイテムリストが空で、clear-was-calledフラグがtrueの場合、

      1. types-to-clearリストが空なら、

        1. クリップボードをクリアする

      2. それ以外の場合、

        1. OS・実装依存の方法でtypes-to-clearリストに含まれる型をクリップボードから削除する

          「クリップボードから特定の型のみ削除する」機能はリスクがある。重要性が低く、主要プラットフォームで簡易に実装できるか疑問です。

BLOBとoptionをクリップボードに書き込む

入力

itemsBlobsequence

presentationStyleクリップボード項目表示スタイル

出力

なし

  1. webCustomFormatsを、Blobsequenceとする。

  2. items内の各itemについて:

    1. formatStringを、itemtypeを与えてOS 固有の既知形式を実行した結果とする。

    2. formatStringが空である場合、以下の手順に従う:

      1. webCustomFormatStringを、itemtypeとする。

      2. webCustomFormatを空のtypeとする。

      3. webCustomFormatStringが`"web "`接頭辞で始まる場合、 `"web "`接頭辞を削除し、残りの文字列を webMimeTypeStringに格納する。

      4. webMimeTypeを、webMimeTypeStringを与えてMIME型を解析する結果とする。

      5. webMimeTypeがfailureである場合、すべての手順を中止する。

      6. webCustomFormattypeessencewebMimeTypeに等しくする。

      7. itemtypewebCustomFormatに設定する。

      8. webCustomFormatwebCustomFormatsに追加する。

    3. payloadを、itemの基になるバイト列をUTF-8復号した結果とする。

    4. formatStringをネイティブクリップボード形式として使用して、 payloadおよびpresentationStyleシステム クリップボードに挿入する。

    一部のOSには 複数のクリップボードがある(例:Linuxの「primary」、「secondary」、「selection」)。それらのうち どれにデータを書き込むかを定義する。

  3. webCustomFormatsを与えてウェブカスタム形式を書き込む

OS固有のよく知られたフォーマット

入力

mimeTypetype

出力

wellKnownFormat、プラットフォーム固有の文字列型。MacではNSPasteboardType、 WindowsではLPCWSTR、Linuxではconst char*である。

Windowsについては、https://docs.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats および https://docs.microsoft.com/en-us/windows/win32/dataxchg/about-atom-tables?redirectedfrom=MSDN を参照。 Macについては、https://developer.apple.com/documentation/appkit/nspasteboardtype を参照。

  1. wellKnownFormatを空文字列とする。

  2. mimeTypeessenceが"text/plain"である場合、

    Windowsでは、以下に説明する規約に従う:

    1. CF_UNICODETEXTをwellKnownFormatに代入する。

    MacOSでは、以下に説明する規約に従う:

    1. NSPasteboardTypeStringをwellKnownFormatに代入する。

    Linux、ChromeOS、およびAndroidでは、以下に説明する規約に従う:

    1. "text/plain"をwellKnownFormatに代入する。

  3. そうでなく、mimeTypeessenceが"text/html"である場合、

    Windowsでは、以下に説明する規約に従う:

    1. CF_HTMLをwellKnownFormatに代入する。

    MacOSでは、以下に説明する規約に従う:

    1. NSPasteboardTypeHTMLをwellKnownFormatに代入する。

    Linux、ChromeOS、およびAndroidでは、以下に説明する規約に従う:

    1. "text/html"をwellKnownFormatに代入する。

  4. そうでなく、mimeTypeessenceが"image/png"である場合、

    Windowsでは、以下に説明する規約に従う:

    1. "PNG"をwellKnownFormatに代入する。

    MacOSでは、以下に説明する規約に従う:

    1. NSPasteboardTypePNGをwellKnownFormatに代入する。

    Linux、ChromeOS、およびAndroidでは、以下に説明する規約に従う:

    1. "image/png"をwellKnownFormatに代入する。

  5. そうでなく、mimeTypeessenceが"image/svg+xml"である場合、

    Windowsでは、以下に説明する規約に従う:

    1. CFSTR_MIME_SVG_XMLをwellKnownFormatに代入する。

    MacOSでは、以下に説明する規約に従う:

    1. UTTypeSVGをwellKnownFormatに代入する。

    Linux、ChromeOS、およびAndroidでは、以下に説明する規約に従う:

    1. "image/svg+xml"をwellKnownFormatに代入する。

  6. wellKnownFormatを返す。

OS固有フォーマットからよく知られたMIME型を得る

入力

osFormatName: プラットフォーム固有の文字列型。MacではNSPasteboardType、WindowsではLPCWSTR、Linuxではconst char*。

出力

mimeType: MIME型

Windowsの詳細は https://docs.microsoft.com/en-us/windows/win32/dataxchg/standard-clipboard-formats および https://docs.microsoft.com/en-us/windows/win32/dataxchg/about-atom-tables?redirectedfrom=MSDN Macの詳細は https://developer.apple.com/documentation/appkit/nspasteboardtype

Windowsの場合:

  1. osFormatNameが"UnicodeText"なら、mimeTypeStringを"text/plain"に設定する。

  2. それ以外でosFormatNameが"HTML Format"なら、mimeTypeStringを"text/html"に設定する。

  3. それ以外でosFormatNameが"PNG"なら、mimeTypeStringを"image/png"に設定する。

  4. それ以外でosFormatNameがCFSTR_MIME_SVG_XMLなら、mimeTypeStringを"image/svg+xml"に設定する。

MacOSの場合:

  1. osFormatNameがNSPasteboardTypeStringなら、mimeTypeStringを"text/plain"に設定する。

  2. それ以外でosFormatNameがNSPasteboardTypeHTMLなら、mimeTypeStringを"text/html"に設定する。

  3. それ以外でosFormatNameがNSPasteboardTypePNGなら、mimeTypeStringを"image/png"に設定する。

  4. それ以外でosFormatNameがUTTypeSVGなら、mimeTypeStringを"image/svg+xml"に設定する。

Linux・ChromeOS・Androidの場合:

  1. osFormatNameが"text/plain"なら、mimeTypeStringを"text/plain"に設定する。

  2. それ以外でosFormatNameが"text/html"なら、mimeTypeStringを"text/html"に設定する。

  3. それ以外でosFormatNameが"image/png"なら、mimeTypeStringを"image/png"に設定する。

  4. それ以外でosFormatNameが"image/svg+xml"なら、mimeTypeStringを"image/svg+xml"に設定する。

  1. mimeTypemimeTypeStringに対してMIME型のパースを実行した結果とする。

  2. mimeTypeを返す。

Webカスタムフォーマットの読み取り

入力

itemクリップボード項目

  1. webCustomFormatMapを、OS固有の カスタムマップ名とする。

  2. システムクリップボードから webCustomFormatMapを読み取る。

    webCustomFormatMapを読み取る処理をより詳細に指定する。

  3. webCustomFormatMapが空である場合、itemを返す。

  4. webCustomFormatMapStringを、 webCustomFormatMapから逆シリアル化されたJSON文字列とする。

    Note: webCustomFormatMapから内容を逆シリアル化するには、JSONリーダーが必要である。

  5. webCustomFormatMapString内の各(key, value)について:

    1. mimeTypeを、keyを与えてMIME型を解析する結果とする。

    2. mimeTypeがfailureである場合、このループを継続する。

    3. representationを新しい表現とする。

    4. representationMIME型mimeTypeに設定する。

    5. representationisCustomフラグをtrueに設定する。

    6. representationデータ新しい promiseに設定する。

      Note: この ウェブカスタム形式のOSクリップボードデータは、作者が結果のgetType()ClipboardItem オブジェクト上で呼び出すまで取得されない。

    7. representationitem表現の リストに追加する。

Webカスタムフォーマットの書き込み

入力

itemsBlobsequence

  1. idxを、0に初期化された数値とする。

  2. webCustomFormatMapを、OS固有の カスタムマップ名とする。

  3. webCustomFormatMapStringを空のJSON文字列とする。

  4. items内の各itemについて:

    1. webCustomFormatを、OS固有の カスタム名とする。

    2. webCustomFormatIdxを、idxwebCustomFormatに追加した結果とする。

    3. itemtype をキーとして、webCustomFormatIdxを値として、 JSONシリアライザーを使用してwebCustomFormatMapStringに挿入する。

      Note: 内容をwebCustomFormatMapStringへシリアライズするにはJSONライターが必要である。

    4. webCustomFormatIdxを形式として使用して、itemシステムクリップボードに挿入する。

    5. idxをインクリメントする。

    6. idxが100より大きい場合、このループを抜ける。

  5. webCustomFormatMapを形式として使用して、 webCustomFormatMapStringシステムクリップボードに挿入する。

OS固有のカスタムマップ名

出力

webCustomFormatMap、文字列

Windowsの場合:

  1. webCustomFormatMapに"Web Custom Format Map"を代入する。

  2. webCustomFormatMapを返す。

MacOSの場合:

  1. webCustomFormatMapに"org.w3.web-custom-format.map"を代入する。

  2. webCustomFormatMapを返す。

Linux、ChromeOS、Androidの場合:

  1. webCustomFormatMapに"application/web;type=\"custom/formatmap\""を代入する。

  2. webCustomFormatMapを返す。

OS固有のカスタム名

出力

webCustomFormat、文字列

Windowsの場合:

  1. webCustomFormatに"Web Custom Format"を代入する。

  2. webCustomFormatを返す。

MacOSの場合:

  1. webCustomFormatに"org.w3.web-custom-format.type-"を代入する。

  2. webCustomFormatを返す。

Linux、ChromeOS、Androidの場合:

  1. webCustomFormatに"application/web;type=\"custom/format\""を代入する。

  2. webCustomFormatを返す。

クリップボードイベントの発火

入力

e、発火するClipboardEvent

出力

なし

  1. clear-was-calledfalseとする。

  2. types-to-clearを空リストとする。

  3. clipboard-event-dataを空のDataTransfer オブジェクト(itemsリストは空)とする。

  4. clipboard-entryを現在のクリップボード内容のシーケンス番号、またはOSクリップボードがシーケンス番号をサポートしない場合はnullとする。

  5. trustedをイベントがユーザーエージェントによって生成された場合true、それ以外はfalseとする。

  6. targetを次のように設定する:

    1. コンテキストが編集可能な場合:

      1. targetを、ドキュメント順で可視選択範囲またはカーソルの開始位置を含む要素、なければbody要素とする。

    2. コンテキストが編集不可の場合:

      1. targetをフォーカスされているノード、なければbody要素とする。

  7. イベントを次のように処理する:

    1. eが"paste"の場合:

      1. clipboard-event-dataの内部drag data store modeフラグをread-onlyに設定する。

      2. trustedtrue、または実装がスクリプト生成イベントにOSクリップボードの読み取り権限を与えるよう設定されている場合:

        1. OSクリップボード上の各clipboard-partについて以下を実行:

          1. clipboard-partがプレーンテキストの場合:

            1. テキストがスクリプトエンジン内部のエンコーディングであることを保証する。

            2. new-dataを新しいDataTransferItem とし、drag data item kindstringdrag data item type stringtext/plain

            3. new-dataのデータをプレーンテキストに設定する。

            4. new-dataclipboard-event-dataitemsリストに追加する。

          2. clipboard-partがファイル参照の場合、その各ファイル参照について:

            1. 参照ファイルのMIME型を判定する。

            2. new-dataを新しいDataTransferItem とし、drag data item kindfiledrag data item type stringはMIME型(不明ならapplication/octet-stream)。

            3. new-dataのデータをファイル参照データに設定する。

            4. new-dataclipboard-event-dataitemsリストに追加する。

          3. clipboard-partがOSの規則によるHTMLまたはXHTML形式テキストの場合:

            1. 実装がHTML貼り付けをサポートしていれば、HTML貼り付けイベントの処理clipboard-partclipboard-event-dataで実行する。

          4. clipboard-partが他のサポートされたバイナリまたはテキスト型(必須データ型参照)の場合:

            1. データのMIME型を判定する。

            2. new-dataを新しいDataTransferItem とし、drag data item kindfiledrag data item type stringはMIME型。

            3. new-dataのデータをバイナリまたはテキストデータに設定する。

            4. new-dataclipboard-event-dataitemsリストに追加する。

      3. clipboard-event-datafiles プロパティをitemsリストに合わせて更新する。

      4. clipboard-event-datatypes プロパティをitemsリストに合わせて更新する。

    2. eが"copy"または"cut"の場合:

      1. 関連DataTransfer オブジェクトの内部drag data store modeフラグをread/writeに設定する。

  8. eclipboardDataclipboard-event-dataに設定する。

  9. eisTrustedtrustedに設定する。

  10. ecomposed をtrueに設定する。

  11. イベントeをバブル・キャンセル可能として、ClipboardEvent インターフェースを使用しtargetで発火する。

    イベント発火中のデータアクセス要件は[HTML]で定義されています。追加のクリップボードイベント固有の処理規則は下記の通りです:

    なぜここに?なぜHTML仕様に記載しない?

    1. スクリプトがclearData()またはclear() を呼び出し、かつDataTransfer オブジェクトの内部drag data store modeフラグがread/writeの場合:

      1. clear-was-calledフラグをtrueに設定する。引数が指定されている場合はその引数をtypes-to-clearリストに追加する。

    2. スクリプトがsetData()を呼び出すかitemsを変更し、clear-was-calledフラグがtrueの場合:

      1. types-to-clearリストが空なら:

        1. clear-was-calledフラグをfalseに設定する。

      2. それ以外の場合、setData()type引数または新規アイテムのdrag data item type stringtypes-to-clearリストに含まれていれば:

        1. それをリストから除去し、リストが空になったらclear-was-calledフラグをfalseに設定する。

    3. スクリプトがgetData()を呼び出すかDataTransferItemList のitemsにアクセスし、clipboard-entryがセットされている場合:

      1. クリップボードデータのシーケンス番号がclipboard-entryと一致するか確認し、一致しない場合はDataTransferItemList オブジェクトの内部drag data store modeprotectedに設定する。

    警告!pasteイベントを監視する悪意のあるスクリプトは、ユーザーが今後クリップボードに置く内容を読み取るため、無限ループを仕掛ける可能性があります。クリップボードのシーケンス番号が取得できないプラットフォームでは、他の制限を実装すべきです。

HTML貼り付けイベントの処理

入力

clipboard-part、処理対象のクリップボードパート

clipboard-event-data、このイベント用のDataTransferオブジェクト

出力

なし

  1. new-dataを新しいDataTransferItem とし、drag data item kindPlain Unicode stringdrag data item type stringは適宜text/htmlまたはapplication/xhtml+xml

  2. clipboard-partからマークアップを抽出し、適切なパーサーでDOMツリーを構築する。

  3. マークアップのソースURLが判明している場合、HREFやSRC属性の相対URLをソースURLを基準に絶対URLに解決し、属性値を絶対URLにする。

  4. マークアップのオリジンがローカルアプリケーションの場合、ローカルファイルやOSクリップボード内の他パート参照があるか確認し、参照があればsub-part参照はcid:URLスキーム[RFC2392]でcontent-id参照に必ず置換する。各属性について下記手順で処理:

    これらの手順は必要か?内部参照を持つネイティブ(プラットフォーム)クリップボード実装の存在を把握しているか?

    この機能は要件不明かつクロスプラットフォームで検証困難なためリスクあり。

    1. clipboard-event-dataitems に参照されたファイルまたはクリップボード部品のエントリが既に存在する場合、

      1. itemNumberに既存エントリのインデックスを設定する。

    2. それ以外の場合、

      1. new-file-dataを新しいDataTransferItemdrag data item kindは"file"、drag data item type stringはファイルまたはクリップボード部品のMIME型(不明ならapplication/octet-stream))として作成する。

      2. file-infoを新しいFile オブジェクト(nameはHTML属性内容の名前部分、lastModifiedは参照ファイルのタイムスタンプまたはクリップボード部品参照なら0)として作成する。

      3. new-file-dataの内部File オブジェクトにfile-infoを設定する。

      4. new-file-dataclipboard-event-dataitems に追加し、そのエントリのインデックスをitemNumberとする(DataTransferItemList内)。

    3. ローカルファイルやクリップボード部品を参照していたDOM属性を 'cid:'+itemNumber の文字列に更新する。

  5. 処理後のDOMをシリアライズし、そのHTMLコードでnew-dataを更新する。

  6. new-dataclipboard-event-dataitems に追加する。

適合性

文書上の規約

適合性要件は、記述的な断定とRFC 2119の用語の組み合わせで表現されます。 「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」といったキーワードは、 この文書の規範部分でRFC 2119に従って解釈されます。 ただし、可読性のため、これらの単語は本仕様書ではすべて大文字では表記されません。

本仕様のテキストは、明示的に非規範と記載された部分、例、および注釈を除いてすべて規範的です。 [RFC2119]

本仕様書の例は「例えば」で始まるか、またはclass="example"のように規範テキストと区別されて記載されます:

これは参考例です。

参考となる注記は「注」から始まり、class="note"で規範テキストと区別されて記載されます:

注:これは参考となる注記です。

適合するアルゴリズム

アルゴリズムの一部として命令形で記載された要件(例:"先頭の空白文字を除去する" や "falseを返してこれらの手順を中断する" など)は、アルゴリズムの導入部で用いられたキーワード("must"、"should"、"may"など)の意味で解釈されます。

アルゴリズムや特定の手順として記載された適合性要件は、同等の結果が得られる限り、どのような方法でも実装できます。 とくに、本仕様で定義されたアルゴリズムは理解しやすくすることを目的としており、パフォーマンスを意図したものではありません。 実装者は最適化することを推奨します。

索引

本仕様で定義されている用語

参照によって定義される用語

参考文献

規範的参考文献

[DOM]
Anne van Kesteren. DOM標準. リビング標準. URL: https://dom.spec.whatwg.org/
[ENCODING]
Anne van Kesteren. Encoding標準. リビング 標準. URL: https://encoding.spec.whatwg.org/
[FileAPI]
Marijn Kruisselbrink. File API. 2026年6月4日. WD. URL: https://www.w3.org/TR/FileAPI/
[HTML]
Anne van Kesteren; et al. HTML標準. リビング標準. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 標準. リビング標準. URL: https://infra.spec.whatwg.org/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing標準. リビング標準. URL: https://mimesniff.spec.whatwg.org/
[PERMISSIONS]
Marcos Caceres; Mike Taylor. Permissions. 2025年 10月6日. WD. URL: https://www.w3.org/TR/permissions/
[RFC2119]
S. Bradner. RFCにおいて 要件レベルを示すために用いるキーワード. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC2392]
E. Levinson. Content-IDおよびMessage-IDのUniform Resource Locator. 1998年8月. Proposed Standard. URL: https://www.rfc-editor.org/rfc/rfc2392
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL標準. リビング 標準. URL: https://webidl.spec.whatwg.org/

参考情報

[HTML5]
Ian Hickson; 他. HTML5. 2018年3月27日. 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; 他. Scalable Vector Graphics (SVG) 1.1 (Second Edition). 2011年8月16日. REC. URL: https://www.w3.org/TR/SVG11/

IDL索引

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

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

dictionary ClipboardChangeEventInit : EventInit {
  sequence<DOMString> types = [];
  bigint changeId = 0;
};

[Exposed=Window]
interface ClipboardChangeEvent : Event {
  constructor(DOMString type, optional ClipboardChangeEventInit eventInitDict = {});
  readonly attribute FrozenArray<DOMString> types;
  readonly attribute bigint changeId;
};

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

typedef Promise<(DOMString or Blob)> ClipboardItemData;

[SecureContext, Exposed=Window]
interface ClipboardItem {
  constructor(record<DOMString, ClipboardItemData> items,
              optional ClipboardItemOptions options = {});

  readonly attribute PresentationStyle presentationStyle;
  readonly attribute FrozenArray<DOMString> types;

  Promise<Blob> getType(DOMString type);

  static boolean supports(DOMString type);
};

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

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

typedef sequence<ClipboardItem> ClipboardItems;

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

dictionary ClipboardUnsanitizedFormats {
  sequence<DOMString> unsanitized;
};

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

課題索引

ウェブ開発者は、拒否理由の詳細に関心がある場合があります。
一部のOS(例: Linuxの "primary", "secondary", "selection")には複数のクリップボードがあります。どこからデータを読み取るか定義してください。
サニタイズ済みコピーの定義を追加してください。
clipboard-write は https://github.com/w3c/clipboard-apis/pull/164 で削除されました。
data に複数のアイテムが含まれており、かつOSが複数のネイティブクリップボードアイテムをサポートしている場合、現在のアルゴリズムはアイテムをシーケンスでシステムクリップボードに書き込むが、まとめて書き込むべきです。
サニタイズ済みコピーの定義を追加してください。
clipboard-write は https://github.com/w3c/clipboard-apis/pull/164 で削除されました。
実装依存にするのは好ましくありません。どうすべきか?
「クリップボードから特定の型のみ削除する」機能はリスクがあります。重要性が低く、主要なプラットフォームで容易に実装できるか疑問です。
一部のOS(例: Linuxの "primary", "secondary", "selection")には複数のクリップボードがあります。どこにデータを書き込むか定義してください。
webCustomFormatMap の読み取り処理をより詳細に規定すべきです。
なぜここで?なぜHTML仕様に含めないのか?
これらの手順は必要ですか?内部参照を持つ複数部品をサポートするネイティブ(プラットフォーム)クリップボード実装が存在するのでしょうか?
この機能は必要性が不明であり、クロスプラットフォームでテストが難しいためリスクがあります。
MDN

Clipboard/read

Firefox🔰 90+Safari13.1+Chrome?
Opera63+Edge?
Edge (Legacy)NoneIENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet12.0+Opera Mobile54+
MDN

Clipboard/readText

FirefoxNoneSafari13.1+Chrome66+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Clipboard/write

In all current engines.

Firefox87+Safari13.1+Chrome66+
Opera63+Edge79+
Edge (Legacy)NoneIENone
Firefox for Android?iOS Safari?Chrome for Android66+Android WebView?Samsung Internet12.0+Opera Mobile54+
MDN

Clipboard/writeText

In all current engines.

Firefox63+Safari13.1+Chrome66+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Clipboard

In all current engines.

Firefox63+Safari13.1+Chrome66+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ClipboardEvent/ClipboardEvent

In all current engines.

Firefox22+Safari10.1+Chrome58+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ClipboardEvent/clipboardData

In all current engines.

Firefox22+Safari10.1+Chrome41+
Opera?Edge79+
Edge (Legacy)12+IE5+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ClipboardEvent

In all current engines.

Firefox22+Safari10.1+Chrome41+
Opera?Edge79+
Edge (Legacy)12+IE4+
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ClipboardItem/ClipboardItem

In all current engines.

Firefox🔰 87+Safari13.1+Chrome98+
Opera?Edge98+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android98+Android WebView?Samsung Internet?Opera Mobile?
MDN

ClipboardItem/getType

In all current engines.

Firefox🔰 87+Safari13.1+Chrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android84+Android WebView?Samsung Internet?Opera Mobile?
MDN

ClipboardItem/presentationStyle

Firefox🔰 87+Safari13.1+ChromeNone
Opera?EdgeNone
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ClipboardItem/types

In all current engines.

Firefox🔰 87+Safari13.1+Chrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android84+Android WebView?Samsung Internet?Opera Mobile?
MDN

ClipboardItem

In all current engines.

Firefox🔰 87+Safari13.1+Chrome76+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android84+Android WebView?Samsung Internet?Opera Mobile?
MDN

Element/copy_event

In all current engines.

Firefox22+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari3+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

Element/cut_event

In all current engines.

Firefox22+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari3+Chrome for Android?Android WebView?Samsung Internet?Opera Mobile12.1+
MDN

Element/paste_event

In all current engines.

Firefox22+Safari3+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+IE9+
Firefox for Android?iOS Safari3+Chrome for Android?Android WebView37+Samsung Internet?Opera Mobile12.1+
MDN

Navigator/clipboard

In all current engines.

Firefox63+Safari13.1+Chrome66+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?