1. はじめに
このセクションは規範的ではありません。
この仕様は、システムクリップボードがウェブアプリケーションにどのように公開されるかを定義します。
本仕様で説明されているAPIは、主に2つあります:
-
クリップボードイベントAPI - このAPIは、切り取り、コピー、貼り付けなど一般的なクリップボード操作にフックし、ウェブアプリケーションが必要に応じてクリップボードデータを調整できるようにします。
-
非同期クリップボードAPI - このAPIは、クリップボードデータの直接読み書きを提供します。これは強力な機能とみなされるため、このAPIへのアクセスは権限によって制御されます。
2. ユースケース
このセクションは規範的ではありません。
2.1. デフォルトのクリップボード操作の変更
デフォルトのクリップボード操作(切り取り/コピー/貼り付け)を変更したいシナリオは多数存在します。いくつか例を挙げます:
- メタデータ 文書リポジトリからテキストをコピーする際、コピーされたテキストに元のコンテンツのメタデータを含めることが有用です。
- リッチコンテンツ編集 ハイパーリンクなどの構造を含むテキストをコピーする場合、重要な情報を保持するために内容を再フォーマットできると便利です。
- 意味を持つグラフィックス リッチテキストや[SVG11]などのグラフィックコンテンツを操作するウェブアプリケーションのために、描画された内容だけでなく、より多くの情報をコピーできる仕組みがあると便利です。
- 数学情報 数学のような内容では、レンダリングされたテキストをコピーして他のアプリケーションに貼り付けただけでは、ほとんどの意味が失われてしまいます。例えばMathMLは、プレーンテキストとしてコピーする際に「べき乗」をキャレット「^」記号で示すなど、適切な変換が必要です。XMLソースも、貼り付け時に適切に変換されるようクリップボードに配置できます。
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オブジェクトの
itemsやfilesプロパティによって、クリップボードのマルチパートや非テキストデータの処理が可能です。
このインターフェースはイベントの構築に使用できます。 以下はその例です:
var pasteEvent = new ClipboardEvent('paste');
pasteEvent.clipboardData.items.add('My string', 'text/plain');
document.dispatchEvent(pasteEvent);
注: 合成クリップボードイベントは実際にクリップボードや 文書を変更しません。つまり、上記のスクリプトでpasteイベントは発火しますが、 データが文書内に貼り付けられることはありません。
5.2. クリップボードイベント
5.2.1.
clipboardchangeイベント
clipboardchange
イベントはシステムクリップボードの内容が変更されたときに発火します。これらの変更には以下のようなもの(例示)があります:
-
ユーザーによる切り取りまたはコピー操作
-
§ 7 非同期クリップボードAPIを使用してスクリプトがクリップボードに書き込んだ場合
-
ユーザーエージェント外でクリップボードが更新された場合
5.2.1.1. clipboardchange イベントを発火するには
clipboardchange イベントを発火するためには、Document
document を与える:
-
documentが持続的な活性化を持たず、かつdocumentが クリップボードから読み取る権限を持たない場合、返す。
-
globalを、documentの関連するグローバルオブジェクトとする。
-
documentがシステムフォーカスを持つ場合:
-
typesを、必須データ型のリストであって、システム クリップボード上で利用可能なものとする。
-
changeIdを、documentを与えてchangeIdを生成するを 実行した結果とする。
-
eventInitを、新しい
ClipboardChangeEventInit辞書であって、そのtypesメンバーがtypesに設定され、そのchangeIdメンバーがchangeIdに設定されたものとする。 -
globalにおいて、
clipboardchangeという名前のイベントを発火する。ClipboardChangeEventを使用し、 eventInitを伴う。
-
-
documentがシステムフォーカスを持たない場合:
-
documentのclipboardchange 保留フラグを trueに設定する。
-
ユーザーエージェントは、clipboardchange
イベントが配信される前に、より新しい変更によって上書きされたクリップボードの変更については、発火を省略することを選択してもよいです。この最適化は、クリップボードの変更が短時間で連続して発生する場合にパフォーマンスの向上につながります。なぜなら、旧いイベント通知を配信してもウェブアプリケーションに価値がなく、処理リソースを消費するだけだからです。
5.2.1.2. Document フォーカス時の手順
Document
document が システムフォーカス を獲得したとき:
-
documentのclipboardchange 保留フラグがtrueである場合:
-
documentのclipboardchange 保留フラグを falseに設定する。
-
typesを、必須データ型のリストであって、システム クリップボード上で利用可能なものとする。
-
changeIdを、documentを与えてchangeIdを 生成するを実行した結果とする。
-
eventInitを、新しい
ClipboardChangeEventInit辞書であって、そのtypesメンバーがtypesに設定され、そのchangeIdメンバーがchangeIdに設定されたものとする。 -
globalを、documentの関連するグローバルオブジェクトとする。
-
globalにおいて、
clipboardchangeという名前のイベントを発火する。ClipboardChangeEventを使用し、 eventInitを伴う。
-
ネストされた閲覧コンテキスト内の document では、clipboardchange
イベントは、それぞれの Document
ごとのフォーカス状態に基づき、個別に発火されます。クリップボードの変更が発生すると、システムフォーカスを持つ単一の document でイベントが発火します(該当の document がスティッキーアクティベーションまたは永続的なクリップボード権限を持つ場合)。
注: clipboardchange イベントは、スティッキーアクティベーションの後でのみ利用可能です(document がクリップボードからの読み取りに対する永続的な権限を持つ場合を除く)。
ユーザーエージェントが永続的なクリップボード権限をサポートしている場合、そのような権限を持つサイトはスティッキーアクティベーションなしでもclipboardchangeイベントを受信できます。なぜなら、その許可自体がより機微なクリップボードデータへのアクセスを既に許可しているからです。
changeId
は、それぞれのクリップボード変更操作に対する一意識別子を提供します。同じクリップボードの変更について、同じストレージキーを持つすべてのウィンドウおよびタブは、同じ changeId
値を持つイベントを受け取り、複数ウィンドウでのイベントの重複処理を防げます。識別子はストレージキーごとに固有であり、キーをまたぐ相関機能はありません。
clipboardchange
イベントはバブルせず、キャンセルもできません。なぜなら、これはユーザー操作によってではなく、システムクリップボードの状態変更によって引き起こされるからです。
dictionary :ClipboardChangeEventInit EventInit {sequence <DOMString >= [];types bigint = 0; };changeId
- 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) コンストラクタの手順は次の通り:
5.2.1.4. ChangeId 生成
Document
documentについてchangeIdを
生成するには:
-
globalChangeIdを、システムクリップボードの現在の 状態を表す、ユーザーエージェント固有の一意な識別子とする。この識別子は、システム クリップボードが変更されるたびに変化し、ユーザーエージェントが再起動するとリセットされる。
-
storageKeyを、documentの関連設定オブジェクトを与えて、非ストレージ目的の ストレージキーを取得するを実行した結果とする。
-
storageKeyBytesを、storageKeyの何らかのユーザーエージェント固有の バイナリ表現とする。
-
hashedValueを、globalChangeId(バイトとして)と storageKeyBytesの連結に暗号学的ハッシュ関数(SHA-256など)を適用した結果とする。
-
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. クリップボードの変更が許可されているイベントハンドラ
以下のいずれかが真の場合、イベントハンドラはクリップボードへ書き込みできます:
-
イベントをトリガーするアクションがユーザーエージェント自身のUI(例:「コピー」メニューやショートカットキー)から呼び出された場合。
-
イベントをトリガーするアクションがポップアップ表示が許可されているスクリプトスレッドから呼び出された場合。
実装は、実装者がそのイベントタイプがユーザーの意図を表す可能性が高いと判断した場合、他の信頼できるイベントタイプでもクリップボードの変更を許可してもよいです。また、信頼された特定サイトやアプリがスクリプトスレッドの起源に関係なくクリップボードを変更できるようにする設定をサポートしてもよいです。
合成されたcut
およびcopy
イベントはシステムクリップボードのデータを変更してはなりません。
5.3.2. クリップボードからの読み取りが許可されているイベントハンドラ
以下のいずれかが真の場合、イベントハンドラはシステムクリップボードからデータを読み取ることができます:
-
イベントをトリガーするアクションがユーザーエージェント自身のUI(例:「貼り付け」メニューやショートカットキー)から呼び出された場合。
-
アクションをトリガーするスクリプトが、実装依存の仕組みによりクリップボードからデータを読み取る権限を与えられているサイト上で実行されている場合。
-
イベントをトリガーするアクションが、クリップボードの読み取り権限を持つアプリでトリガーされた場合。
合成されたpaste
イベントは実際のシステムクリップボード上のデータへのアクセスをスクリプトに与えてはなりません。
5.3.3. リッチテキスト編集APIとの統合
実装がスクリプトからクリップボードコマンドを実行する方法(例: document.execCommand() メソッドで "cut"、"copy"、"paste"
コマンドを呼び出す)をサポートしている場合、実装は必ず対応するアクションをトリガーし、それに応じたクリップボードイベントをディスパッチします。
スクリプトAPIからコピー・切り取り・貼り付けアクションをトリガーする際の手順:
-
対応するアクションを同期的に実行する。
-
アクションの戻り値をAPI呼び出しの戻り値として使用する。
注: スクリプトAPI経由でトリガーされたコピーや切り取りコマンドは、イベントが信頼できユーザーによってトリガーされた場合、または実装がそれを許可するように設定されている場合のみ、実際のクリップボードの内容に影響します。スクリプトAPI経由の貼り付けコマンドは、実装がそれを許可するよう設定されている場合のみ、貼り付けイベントを発火しクリップボード内容へのアクセスを許可します。クリップボードの読み書きアクセスを許可する実装設定方法は本仕様の範囲外です。
5.3.4. 他のイベントとの相互作用
クリップボード操作がキーボード入力でトリガーされた場合、実装は必ずその操作を開始するイベントを発火しなければなりません。イベントは非同期ですが、関連するキーのkeyupイベントの前にディスパッチされなければなりません。
切り取り・貼り付け操作は、実装がサポートする他のイベント(textInput、input、change、検証イベント、DOMCharacterDataModified、DOMNodeRemoved/DOMNodeInsertedなど)をディスパッチする場合があります。これらのイベントは、切り取り・貼り付けイベントの処理が完了した後に発火するようキューされます。
実装はコピー操作に応じて、textInput、input、change、検証イベントなど、他の入力関連イベントをディスパッチしてはなりません。
5.3.5. 選択やフォーカスを変更するイベントリスナー
イベントリスナーが選択やフォーカス可能領域を変更した場合、クリップボード操作は 必ず変更後の選択に対して完了しなければなりません。
6. クリップボードイベントAPI
クリップボードイベントAPIを使用すると、ユーザーエージェントのデフォルトの切り取り、コピー、貼り付け動作を上書きできます。
クリップボードへのアクセスは、標準のDataTransfer
のメソッドを使って、items
をClipboardEventの
clipboardData
属性で操作します。
この結果、これらのクリップボード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のクリップボード形式の説明を認識し、DataTransferItemList
やClipboardItem
を適切に記述することで、貼り付けイベント時に正しい内容を提供し、コピー・切り取りイベント時にはOSクリップボード上に正しいデータ形式を設定しなければなりません。
6.4.1. クリップボードからの読み取り
これらのデータ型は、クリップボード上に対応するネイティブ型が存在する場合、pasteイベントで公開されなければなりません:
-
text/plain
-
text/html
-
image/png
6.4.2. クリップボードへの書き込み
これらのデータ型は、copy・cutイベント時にDataTransfer
オブジェクトに追加された場合、対応するネイティブ型の説明と共にクリップボードへ配置されなければなりません。
-
text/plain
-
text/html
-
image/png
警告!信頼されていないスクリプトがクリップボードへ書き込めるデータ型は、セキュリティ対策として制限されています。信頼されていないスクリプトは、ローカルソフトウェアの脆弱性を引き起こす既知のデータをクリップボードに配置しようとする場合があります。
6.5. 任意データ型
実装は、以下のデータ型についてOSのクリップボード形式の説明を認識してもよく、ClipboardItem
を貼り付けイベント時に適切に記述し、コピー・切り取りイベント時にはOSクリップボード上に正しいデータ形式を設定してもよいです。
これらのデータ型は、クリップボード上に対応するネイティブ型が存在する場合、UAによって公開されることがあります:
-
text/uri-list
-
image/svg+xml
-
カスタムフォーマットで、"web "("web"の後にU+0020 スペース)で始まり、末尾("web "除去後)がMIME型のパースチェックをパスするもの。
6.6. 未サニタイズデータ型
このセクションは規範的ではありません。以下のデータ型はUAによってサニタイズされてはなりません:
-
image/png
以下のデータ型はUAによってサニタイズされない場合があります:
任意未サニタイズデータ型とは、ウェブ著者が指定するもので、UAによってサニタイズされない場合があるmime typeです。 有効な任意未サニタイズデータ型は以下の通りです:
-
text/html
任意未サニタイズデータ型は、UAのプライバシー要件によってサポートされない場合があります。
7. 非同期クリップボードAPI
7.1. Navigatorインターフェース
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 = "unspecified"; };presentationStyle
clipboardItem = new ClipboardItem([items, options])-
新しい
ClipboardItemオブジェクトを作成します。itemsは表現のリストを表し、各表現はmime typeと、対応するPromise とBlobまたはDOMStringを持ちます。optionsはClipboardItemOptionsの値を設定するために使います。下記の例を参照してください。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に対応するPromise をBlobとして返します。
clipboardItem.types- このクリップボードアイテムオブジェクト内のmime typeのリストを返します。
ClipboardItem.supports(type)- typeが必須データ型または任意データ型に含まれていればtrue、そうでなければfalseを返します。
クリップボード項目は、 概念的には、ユーザーが「cut」または「copy」 コマンドを呼び出すことによって共有可能にしたいという意思を示したデータである。クリップボード項目は 2つの目的を果たす。第一に、ユーザーによってシステムクリップボードにコピーされたデータをウェブサイトが読み取れるようにする。第二に、 ウェブサイトがシステムクリップボードへデータを書き込めるようにする。
たとえば、ユーザーがネイティブアプリケーションのスプレッドシートからセル範囲をコピーした場合、それは 1つのクリップボード項目になる。ユーザーが デスクトップからファイルの集合をコピーした場合、そのファイル一覧は複数のクリップボード項目として表される。
一部のプラットフォームでは、クリップボード上に一度に複数のクリップボード項目を持つことをサポートする場合がある一方で、他のプラットフォームでは 以前のクリップボード 項目が新しいものに置き換えられる。
クリップボード項目は、表現の
リストを持ち、各表現は、関連付けられたMIME
型(MIME 型)、初期値が
falseであるisCustomフラグを持ち、このフラグは
この表現を(システムクリップボードの
よく知られた形式ではなく)ウェブカスタム形式として扱うべきかどうかを示し、さらにデータ(ClipboardItemData)を持つ。
ウェブカスタム形式は、 isCustomがtrueに設定されている。
ユーザーがスプレッドシートからセル範囲をコピーする例では、それは画像 (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
オブジェクトを作成するには、次の手順を実行する:
-
clipboardItemObjectを、realmを伴う新しい
ClipboardItemとする。 -
clipboardItemObjectのクリップボード項目をclipboardItemに設定する。
new ClipboardItem(items, options)
コンストラクター手順は次のとおり:
-
itemsが空である場合、
TypeErrorを投げる。 -
optionsが空である場合、options["presentationStyle"] = "unspecified"に設定する。
-
thisの クリップボード項目の表示スタイルを、 options["
presentationStyle"]に設定する。 -
typesを
DOMStringのリストとする。 -
items内の各(key, value)について:
-
representationを新しい表現とする。
-
isCustomをfalseとする。
-
keyが`"web "`接頭辞で始まる場合、
-
`"web "`接頭辞を削除し、残りの文字列をkeyに代入する。
-
isCustomをtrueに設定する
-
-
representationのisCustomフラグをisCustomに設定する。
-
mimeTypeを、keyを与えてMIME 型を解析する結果とする。
-
mimeTypeがfailureである場合、
TypeErrorを投げる。 -
thisのクリップボード項目の表現の リストが、MIME 型が mimeTypeであり、かつ[representation/isCustom]がisCustomである表現を含む場合、
TypeErrorを投げる。
上記の手順は、ユーザー エージェントによく知られているMIME型と、作者がカスタム型として扱うことを意図したものとの衝突を防ぐ。たとえば、 作者の項目リストに"text/html"と "web text/html"の両方の表現を含めることが可能である。
-
7.2.1. presentationStyle
presentationStyle
ゲッターの手順は、thisのclipboard itemのpresentation styleを返すこと。
7.2.2. types
types
ゲッターの手順は、thisのtypes
arrayを返すこと。
7.2.3. getType(type)
このメソッドは以下の手順を実行する:
-
isCustomをfalseとする。
-
typeが`"web "`接頭辞で始まる場合:
-
`"web "`接頭辞を削除し、残りの文字列をtypeに代入する。
-
isCustomをtrueに設定する。
-
-
mimeTypeを、typeを与えてMIME 型を解析する結果とする。
-
mimeTypeがfailureである場合、
TypeErrorを投げる。 -
pを、realm内の新しいpromiseとする。
-
itemTypeList内の各representationについて:
-
representationのMIME 型がmimeTypeであり、かつ representationのisCustomがisCustomである場合:
-
thisの読み取り時のクリップボード変更 カウントがnullでなく、かつ現在のクリップボード 変更カウントがthisの読み取り時のクリップボード変更 カウントと等しくない場合、realm内の
"InvalidStateError"DOMExceptionでpを拒否し、 pを返す。Note: これにより、古くなった データが返されないことが保証される。
read()が呼び出されてからシステムクリップボードの内容が変更されている場合、 現在のシステムクリップボード状態に対応しないデータを返すのではなく、 これは失敗しなければならない。Note: nullの読み取り時のクリップボード変更 カウントは、この
ClipboardItemが作者によって直接構築された(たとえばClipboardItem(items, options)を介して) ものであり、read()から取得されたものではないことを示す。その場合、データはシステムクリップボードに由来しないため、古いデータかどうかのチェックは不要である。 -
thisの読み取り時のクリップボード変更 カウントがnullでない場合:
Note: この分岐は、
ClipboardItemのうち、read()から取得されたものを扱う。この場合、OSクリップボードの読み取りはこの時点まで遅延される。同じMIME型に対してgetType()が複数回同時に呼び出された場合でも、読み取りが型ごとに高々一度だけ発生するようにするため、結果のPromiseは、正規化された型文字列をキーとしてthisのリゾルバー付き 表現mapにキャッシュされる。これにより、`"text/html"`と `"web text/html"`は別々に追跡される一方で、同じ型の大文字小文字の異なる表記 (たとえば`"text/HTML"`と`"text/html"`)は単一のエントリーにまとめられる。-
keyを、mimeTypeのessenceとする。isCustomが trueである場合、keyの前に`"web "`を付加する。
-
thisのリゾルバー付き 表現[key]が存在する場合、thisのリゾルバー付き 表現[key]を返す。
-
設定する:thisのリゾルバー付き 表現[key]をpに。
-
以下の手順を並列に実行する:
-
clipboardItemを、thisの元の システムクリップボード項目とする。
-
clipboardItemがnullである場合、realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは クリップボードタスクソース上で、 realm内の
"InvalidStateError"DOMExceptionでpを拒否するためのものであり、その後これらの手順を中止する。 -
isCustomがtrueである場合:
-
mapNameを、OS固有の カスタムマップ名とする。
-
mapRepresentationを、clipboardItemのシステム クリップボード表現のリスト内にあるシステム クリップボード表現であって、その名前 がmapNameであるものとする。そのようなシステム クリップボード表現がない場合、realmのグローバルオブジェクトを与えて、 グローバル タスクをキューに入れる。これはクリップボードタスク ソース上で、realm内の
"NotFoundError"DOMExceptionでpを拒否するためのものであり、その後これらの手順を中止する。 -
webCustomFormatMapStringを、mapRepresentationのデータから逆シリアル化されたJSON文字列とする。
-
osFormatNameを、直列化されたmimeTypeと一致するキーを持つ、 webCustomFormatMapString内の値とする。
-
osFormatNameが見つからない場合、realmのグローバルオブジェクトを与えて、 グローバル タスクをキューに入れる。これはクリップボードタスク ソース上で、realm内の
"NotFoundError"DOMExceptionでpを拒否するためのものであり、その後これらの手順を中止する。
-
-
そうでなければ、osFormatNameを、mimeTypeを与えてOS固有の 既知形式を実行した結果とする。
-
clipboardRepresentationを、clipboardItemのシステムクリップボード 表現のリスト内にあるシステムクリップボード 表現であって、その名前が osFormatNameであるものとする。そのようなシステムクリップボード 表現がない場合、realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは クリップボードタスクソース上で、 realm内の
"NotFoundError"DOMExceptionでpを拒否するためのものであり、その後これらの手順を中止する。 -
rawDataを、clipboardRepresentationのデータとする。
-
cleanDataを、rawDataのコピーとする。
-
mimeTypeのessenceがthisのサニタイズされていない MIME 型内にあり、かつmimeTypeのessenceが任意の サニタイズされていないデータ型リスト内にある場合、何もしない。
-
そうでなく、mimeTypeのessenceが"image/png"でない場合、 ユーザーエージェントはcleanDataをサニタイズしてもよい。
-
blobを、
Blobとする。そのtypeは直列化されたmimeTypeであり、その 基になるバイト列はcleanDataである。 -
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは クリップボードタスクソース上で、 pをblobで解決するためのものである。
-
Note: pが settledになると、それはthisのリゾルバー付き 表現map内に残る。同じMIME型に対する後続の
getType()呼び出しは、システムクリップボードを再読み取りすることなく、 キャッシュされたsettledのPromiseを返す。ただし、上記の古いデータかどうかのチェックは、すべての呼び出しに引き続き適用される。すなわち、read()が呼び出されてからシステムクリップボード が変更されている場合、このClipboardItem上のすべてのgetType()呼び出しは、以前にキャッシュされたデータであっても、"InvalidStateError"で拒否される。-
pを返す。
-
-
representationDataPromiseを、representationのデータとする。
-
representationDataPromiseに反応する:
-
representationDataPromiseが値 vで履行された場合:
-
representationDataPromiseが拒否された場合:
-
realm内の
"NotFoundError"DOMExceptionでpを拒否する。
-
-
-
pを返す。
-
-
-
realm内の
"NotFoundError"DOMExceptionでpを拒否する。 -
pを返す。
7.2.4. supports(type)
このメソッドは以下の手順を実行する:
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型に対応する、DOMStringの
sequenceである。
unsanitized
オプションはユーザーエージェントによってサポートされない場合がある。プライバシーモードなど、このオプションが許可されない場合があり得るため、
ウェブ作者は、unsanitized
に列挙されたMIME型の内容がサニタイズされないと仮定すべきではない。
クリップボードタスク ソースは、システムクリップボードデータの読み取りまたは書き込みに応答してトリガーされる。
7.3.1. read(formats)
read(formats)
メソッドは次の手順を実行しなければならない:
-
pを、realm内の新しい promiseとする。
-
formatsが空でない場合:
-
formats["
unsanitized"]内の各formatについて:-
formatが任意のサニタイズされていないデータ 型内にない場合、realm内のformat
"NotAllowedError"DOMExceptionでpを拒否する。
-
-
-
次の手順を並列に実行する:
-
rを、クリップボード読み取り 権限を確認するを実行した結果とする。
-
rがfalseである場合:
-
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは権限タスクソース上で、 realm内の
"NotAllowedError"DOMExceptionでpを拒否するためのものである。 -
これらの手順を中止する。
-
-
dataを、システムクリップボードデータとする。
-
snapshotChangeCountを、現在のクリップボード 変更カウントとする。
Note: この時点では、dataからの名前(形式 識別子)のみが列挙される。各表現の基になる ペイロードバイトは、
getType()が呼び出されるまで読み取られない。 -
itemsをsequenceのordered mapとし、各エントリーはキー"item"(クリップボード項目)と"originating"(システムクリップボード項目またはnull)を持つものとする。
-
data内の各systemClipboardItemについて:
-
itemを新しいクリップボード項目とする。
-
systemClipboardItem内の各systemClipboardRepresentationについて:
-
mimeTypeを、systemClipboardRepresentationの名前を与えてOS固有形式からの 既知MIME型アルゴリズムを実行した結果とする。
-
mimeTypeがnullである場合、このループを継続する。
-
representationを新しい表現とする。
-
representationのMIME型を mimeTypeに設定する。
-
representationのデータを、realm内の新しいpromiseに設定する。
Note: この表現のOS クリップボードデータは、作者が結果の
ClipboardItemオブジェクト上でgetType()を呼び出すまで取得されない。 -
representationをitemの表現の リストに追加する。
-
-
itemの表現のリストのサイズが 0より大きい場合、ordered map «[ "item" → item, "originating" → systemClipboardItem ]» をitemsに追加する。
-
-
itemsのサイズが0より大きい場合:
-
firstItemをitems[0]["item"]とする
-
firstItemを与えてウェブカスタム形式を読み取るアルゴリズムを 実行する。
-
-
そうでなければ:
-
customItemを新しいクリップボード項目とする。
-
customItemを与えてウェブカスタム形式を読み取る アルゴリズムを実行する。
-
customItemの表現のリストのサイズが 0より大きい場合、ordered map «[ "item" → customItem, "originating" → null ]» をitemsに追加する。
-
-
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これはクリップボードタスクソース上で、以下の 手順を実行するためのものである:
-
clipboardItemsをsequence<
ClipboardItem>とする。 -
itemsの各ordered map entryについて:
-
clipboardItemを、entry["item"]および realmを与えてClipboardItemオブジェクトを 作成するの手順を実行した結果とする。
-
clipboardItemの読み取り時のクリップボード 変更カウントをsnapshotChangeCountに設定する。
-
clipboardItemの元の システムクリップボード項目をentry["originating"]に設定する。
-
formatsが空でない場合、clipboardItemのサニタイズされていない MIME型をformats["
unsanitized"]に設定する。 -
clipboardItemをclipboardItemsに追加する。
-
-
pをclipboardItemsで解決する。
-
-
-
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()
メソッドは次の手順を実行しなければならない:
-
pを、realm内の新しい promiseとする。
-
次の手順を並列に実行する:
-
rを、クリップボード読み取り 権限を確認するを実行した結果とする。
-
rがfalseである場合:
-
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは権限タスクソース上で、 realm内の
"NotAllowedError"DOMExceptionでpを拒否するためのものである。 -
これらの手順を中止する。
-
-
dataを、システム クリップボードデータのコピーとする。
一部のOSには複数のクリップボードがある(例:Linuxの「primary」、「secondary」、 「selection」)。それらのうち、どのデータから読み取るかを定義する。
-
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これはクリップボードタスクソース上で、以下の 手順を実行するためのものである:
-
data内の各systemClipboardItemについて:
-
systemClipboardItem内の各systemClipboardRepresentationについて:
-
mimeTypeを、systemClipboardRepresentationの名前を与えてOS固有形式からの 既知MIME型アルゴリズムを実行した結果とする。
-
mimeTypeがnullである場合、このループを継続する。
-
representationを新しい表現とする。
-
representationのMIME型のessenceが "text/plain"である場合:
-
representationのMIME 型をmimeTypeに設定する。
-
representationDataPromiseを、 representationのデータとする。
-
representationDataPromiseに反応 する:
-
representationDataPromiseが値vで 履行された場合:
-
representationDataPromiseが 拒否された場合:
-
realm内の
"NotFoundError"DOMExceptionでpを拒否する。 -
pを返す。
-
-
-
-
-
-
realm内の
"NotFoundError"DOMExceptionでpを拒否する。 -
pを返す。
-
-
navigator. clipboard. readText(). then( function ( data) { console. log( "取得した文字列: " , data); });
7.3.3. write(data)
write(data)
メソッドは以下の手順を実行する:
-
pを、realm内の新しい promiseとする。
-
次の手順を並列に実行する:
-
rを、クリップボード書き込み 権限を確認するを実行した結果とする。
clipboard-writeはhttps://github.com/w3c/clipboard-apis/pull/164で削除された。
-
rがfalseである場合:
-
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは権限タスクソース上で、 realm内の
"NotAllowedError"DOMExceptionでpを拒否するためのものである。 -
これらの手順を中止する。
-
-
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これはクリップボードタスクソース上で、以下の 手順を実行するためのものである:
-
dataListをsequence<
ClipboardItem>とする。 -
dataのsizeが1より大きく、かつ現在の オペレーティングシステムがシステムクリップボード上の複数のネイティブクリップボード項目をサポートしない場合、 data[0]をdataListに追加し、そうでなければ、dataListを dataに設定する。
dataが複数の項目を含み、 かつオペレーティングシステムが複数のネイティブクリップボード項目をサポートする場合、 現在のアルゴリズムはそれらの項目をまとめて書き込むのではなく、 システムクリップボードへ順番に書き込む。
-
dataList内の各clipboardItemについて:
-
clipboardItemのクリップボード項目の 表現の リスト内の各representationについて:
-
representationDataPromiseを、 representationのデータとする。
-
representationDataPromiseに反応 する:
-
representationDataPromiseが値vで履行された場合:
-
representationDataPromiseが拒否された場合:
-
realm内の
"NotAllowedError"DOMExceptionでpを拒否する。 -
これらの手順を中止する。
-
-
-
-
itemList内の各blobについて:
-
typeを、blobの
typeとする。 -
typeが必須データ 型または任意データ 型リスト内にない場合、realm内の
"NotAllowedError"DOMExceptionでpを拒否し、これらの手順を中止する。 -
cleanItemを、blobの任意でサニタイズされたコピーとする。
-
サニタイズが試みられ、かつ正常に 完了しなかった場合、以下の手順に従う:
-
realm内の
"NotAllowedError"DOMExceptionでpを拒否する。 -
これらの手順を中止する。
-
-
cleanItemをcleanItemListに追加する。
-
-
cleanItemList およびoptionを用いて、Blob群と optionをクリップボードへ書き込む。
-
-
pを解決する。
-
-
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)
メソッドは以下の手順を実行する:
-
pを、realm内の新しい promiseとする。
-
次の手順を並列に実行する:
-
rを、クリップボード書き込み 権限を確認するを実行した結果とする。
clipboard-writeはhttps://github.com/w3c/clipboard-apis/pull/164で削除された。
-
rがfalseである場合:
-
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これは権限タスクソース上で、 realm内の
"NotAllowedError"DOMExceptionでpを拒否するためのものである。 -
これらの手順を中止する。
-
-
realmのグローバルオブジェクトを与えて、グローバルタスクをキューに入れる。これはクリップボードタスクソース上で、以下の 手順を実行するためのものである:
-
textBlobを、次によって作成された新しい
Blobとする:type属性を"text/plain;charset=utf-8"に設定し、 その基になるバイト列をdataのUTF-8符号化に設定する。Note: Windowsでは、 textBlobを作成する前にdata内の`\n`文字を`\r\n`に置き換える。
-
textBlobをitemListに追加する。
-
optionを"unspecified"に設定する。
-
itemListおよび optionを用いて、Blob群と optionをクリップボードへ書き込む。
-
pを解決する。
-
-
pを返す。
await navigator. clipboard. writeText( "こんにちは!" );
8. クリップボードアクション
このセクションでは、クリップボードアクションおよびイベント発火の処理モデルについて定義します。
各クリップボードアクションには、script-triggeredとscript-may-access-clipboardという2つのフラグがあります。
script-triggeredフラグは、例えばdocument.execCommand()の呼び出しなど、スクリプトによってアクションが実行された場合にセットされます。今後クリップボードと連携するスクリプトAPIもこれらのアクションを利用し、script-triggeredフラグを適切にセットする必要があります。
script-may-access-clipboardフラグは、以下のように設定されます:
-
アクションがcopyまたはcutであり、スクリプトスレッドがクリップボードの変更が許可されている場合、
-
アクションのscript-may-access-clipboardフラグをセットする
-
-
アクションがpasteであり、スクリプトスレッドがクリップボードからの読み取りが許可されている場合、
-
アクションのscript-may-access-clipboardフラグをセットする。
-
8.1. コピーアクション
コピーアクションは次の手順で構成されます:
-
script-triggered フラグが設定されている場合、
-
script-may-access-clipboard フラグが未設定の場合、
-
コピー操作から false を返し、このアルゴリズムを終了する
-
-
-
クリップボードイベントを発火する。イベント名は
copy。 -
もしイベントがキャンセルされなかった場合、
-
選択されている内容があれば、それをクリップボードにコピーする。実装は 可能なら、ウェブページ内の選択内容に対し text/html および text/plain の代替クリップボードフォーマットを作成するべきである。
-
クリップボードイベントを発火する。イベント名は
clipboardchange。
-
-
さもなければ、イベントがキャンセルされた場合、
-
クリップボードへ内容を書き込むアルゴリズムを呼び出す。その際、
DataTransferItemListリスト items、clear-was-called フラグおよび types-to-clear リストを渡す。
-
-
コピー操作から true を返す
8.2. 切り取りアクション
切り取りアクションは次の手順で構成されます:
-
script-triggered フラグが設定されている場合、
-
script-may-access-clipboard フラグが未設定の場合、
-
カットアクションから false を返し、このアルゴリズムを終了する
-
-
-
クリップボードイベントを発火する。イベント名は
cut。 -
イベントがキャンセルされなかった場合、
-
もし 編集可能コンテキスト かつカットが有効な箇所に選択範囲がある場合、
-
選択された内容があればそれをクリップボードにコピーする。実装は 可能なら、ウェブページで選択された内容について text/html および text/plain の代替クリップボード形式を生成するべきである。
-
選択内容をドキュメントから削除し、選択範囲を折りたたむ。
-
クリップボードイベントを発火する。イベント名は
clipboardchange。 -
この修正によって発火すべき他のイベントを発火させるためのタスクをキューする。詳細は § 5.3 他のスクリプトやイベントとの統合 を参照。
-
-
そうでない場合(選択がない、またはコンテキストが編集不可の場合)、
-
false を返す
-
-
-
さもなければ、イベントがキャンセルされた場合、
-
クリップボードに内容を書き込むアルゴリズムを呼び出す。その際、
DataTransferItemListリスト items、clear-was-called フラグ、types-to-clear リストを渡す。 -
クリップボードイベントを発火する。イベント名は
clipboardchange。
-
-
カットアクションから true を返す
8.3. 貼り付けアクション
貼り付けアクションについては、script-may-access-clipboardフラグは、クリップボードから読み取れるサイトやアプリを決定する実装依存の権限機構に依存します。スクリプトによって貼り付けアクションがトリガーされた場合、実装はユーザーの許可なしにクリップボードの内容を利用可能にしてはなりません。権限が未付与の場合、許可ダイアログにはスクリプトスレッドに関連付けられたドキュメントのホスト名を含めなければなりません。
貼り付けアクションは次の手順で構成されます:
-
script-triggeredフラグがセットされている場合、
-
script-may-access-clipboardが未セットの場合、
-
貼り付けアクションからfalseを返し、このアルゴリズムを終了する
-
-
-
pasteという名前のクリップボードイベントを発火する
-
イベントがキャンセルされなかった場合、
-
編集可能コンテキスト内で貼り付けが有効な選択やカーソルがある場合、
-
クリップボード上の最適な内容(あれば)をそのコンテキストに挿入する。
-
変更によって発火すべきイベントをキューに追加する。詳細は§ 5.3 他のスクリプトやイベントとの統合を参照。
-
-
それ以外の場合、
-
falseを返す
-
-
-
イベントがキャンセルされた場合
-
falseを返す
-
-
アクションからtrueを返す
9. Permissions APIとの統合
[permissions] APIは、ウェブサイトが強力な機能(クリップボードなど)へアクセスするための統一的な方法を提供します。これにより、ウェブサイトはユーザーから権限を要求したり、どの権限があるかを照会できます。
クリップボードについては、1つの権限が定義されています:"clipboard-write"
注: クリップボード権限は現在、非同期クリップボードAPIのみに適用されます。将来の本仕様のバージョンでは、他のクリップボード操作にもこの権限が適用される可能性があります。
これらのクリップボード権限は強力な機能であり、権限関連のアルゴリズムと型は以下のように定義されます:
- permission descriptor type
-
dictionary :ClipboardPermissionDescriptor PermissionDescriptor {boolean =allowWithoutGesture false ; };
クリップボード権限は4種類あります:
-
{ name: "clipboard-write", allowWithoutGesture: false }
-
{ name: "clipboard-write", allowWithoutGesture: true }
それぞれの関係は次の通りです:
-
{ "clipboard-write" + true }は{ "clipboard-write" + false }より強い権限です。
ユーザーエージェントは本仕様で記載されたClipboardPermissionDescriptor
を必ずサポートしなければなりませんが、デフォルト設定やユーザーへの表示方法(あるいは表示しない方法)については完全に制御できます。
-
{ "clipboard-write" + false }はユーザーが制御可能として公開される -
{ "clipboard-write" + true }は常にdeniedとなる
9.1. クリップボード読み取り権限
9.1.1. クリップボード読み取り権限の確認
-
hasGesture を、this の 関連グローバルオブジェクト が 一時的アクティベーション を持つ場合 true、そうでない場合は false とする。
-
もしhasGestureなら、
-
現在のスクリプトがユーザーエージェントまたはOSが作成した「貼り付け」要素のユーザー操作により実行されている場合trueを返す。
-
-
falseを返す。
9.2. クリップボード書き込み権限
9.2.1. クリップボード書き込み権限の確認
-
writeWithoutGestureを
{ name: "clipboard-write", allowWithoutGesture: true }権限の権限状態とする。 -
writeWithoutGestureが
grantedならtrueを返す。 -
hasGesture を、this の 関連グローバルオブジェクト が 一時的アクティベーション を持つ場合 true、そうでない場合は false とする。
もしhasGestureなら、
-
現在のスクリプトがユーザーエージェントまたはOSが作成した「cut」または「copy」要素のユーザー操作により実行されている場合systemCopyをtrueとする。
-
systemCopyがtrueならtrueを返す。
-
権限の利用要求を
{ name: "clipboard-write", allowWithoutGesture: false }権限に対して実行した結果を返す。注: ユーザーエージェントは、より強い権限を要求し、暗黙的にこの権限を更新する選択も可能です。
-
-
権限の利用要求を
{ name: "clipboard-write", allowWithoutGesture: true }権限に対して実行した結果を返す。
10. セキュリティに関する考慮事項
著者がユーザーによってコピーされる内容を変更したり、選択されたことのないデータを自動的にコピーしたり、情報の貼り付けを無制限に許可することは、様々なセキュリティ上の懸念を引き起こす可能性があります。
例えば以下のようなシナリオがあります:
-
ユーザーがリンクを選択してコピーしたのに、異なるリンクがクリップボードにコピーされる。これは、貼り付け時に予期しない結果を招く場合からフィッシング攻撃の試みまで、影響が及ぶ可能性があります。
-
(Self-XSS) シェルコマンドや実行可能なスクリプトがクリップボードに置かれ、ユーザーが貼り付けた内容を実行することを意図している。
-
OSの画像処理コードのバグを悪用するために細工された画像がクリップボードに書き込まれる。
10.1. HTMLやマルチパートデータの貼り付け
このセクションは規範的ではありません。
フォーマット済みデータやマルチパートデータの貼り付けには特定のセキュリティリスクがあります。
-
ユーザーが隠れたデータを気付かず貼り付けてしまう可能性があります。例えば、マークアップに<input type="hidden">タグやHTMLコメントが含まれている場合です。こうした隠れたデータには機密情報が含まれていることがあります。
-
ユーザーが信頼されたページに悪意のあるJavaScriptを貼り付けてしまう可能性があります。
-
実装が、ユーザーが意図していないローカルファイルへのスクリプトのアクセスを許可する可能性があります。
どのようなポリシーを採用するかは、以下の要素を考慮して判断します:
-
貼り付けるデータのオリジン
-
画像など参照されているデータのサブパーツのオリジン
-
実行中のスクリプトのオリジン
シナリオと考えられるセキュリティポリシーの概要:
| データのオリジン | スクリプトのオリジン | ルール |
|---|---|---|
| オンラインソース由来 | データと同じ | 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でアクセスできるデータのセキュリティを確保するため、以下の点に注意すべきです:
-
DataTransferインターフェースを実装するオブジェクトでクリップボードデータを返す場合、そのオブジェクトはデータが提供されたClipboardEventイベントハンドラの外部では利用可能であってはなりません。 -
スクリプトが
DataTransferインターフェースを実装したオブジェクトへの参照をClipboardEventイベントハンドラ外部で利用しようとした場合、すべてのメソッドはそのコンテキスト外で呼び出されたとき何もしない(no-op)ようにしなければなりません。 -
実装は、スクリプトが合成クリップボードイベントを作成して本物のクリップボードデータにアクセスできるようにしてはなりません(ユーザーがそう設定した場合を除く)。
Clipboard Event APIはClipboard permissionの対象ではありませんが、ユーザーエージェントはこのAPI自体を無効化したり、アクセスを許可するサイトを設定できる方法を提供してもかまいません。
11.2. プライバシーと非同期クリップボードAPI
非同期クリップボードAPIは強力な機能であり、すべてのスクリプトからクリップボードデータにアクセスできる(Clipboard Eventハンドラに限定されない)上に、ユーザー操作なしでもデータにアクセス可能となる場合があります。
悪用防止のため、このAPIはスクリプトがフォーカスを持つ文書のコンテキスト内で実行されている場合にのみ利用可能でなければなりません。
11.2.1. プライバシーとクリップボード権限
クリップボード権限はこのAPIへのアクセスを制御しますが、ユーザーエージェントは権限のデフォルト値やユーザーが設定可能な権限項目を選択できます。例えば、ユーザーエージェントはユーザー操作がある場合のみ非同期クリップボードAPIへのアクセスを許可し、操作なしの場合はスクリプトからのアクセス要求を常に拒否するようにできます。
ユーザーエージェントは、ユーザーが権限を与えてから一定時間が経過した後や、ユーザーがサイトを最後に訪問してから一定時間が経過した後、あるいはユーザーがページから離れた場合などに、権限を自動的に失効させる選択も可能です:
-
権限付与から一定時間経過後
-
ユーザーがサイトを最後に訪問してから一定時間経過後
-
ユーザーがページから離脱したとき
11.3. その他のプライバシー懸念
ユーザーエージェントがdocument.execCommand("paste")を使ってクリップボードデータの読み取りを許可する場合、ユーザーが明示的にそのアクセスを許可したことを必ず確認しなければなりません。
12. 謝辞
このセクションは規範的ではありません
編集者は本仕様の現行状態に導くため、様々な会議やメーリングリストで支えてくださった前任編集者の貢献に感謝します。
-
Hallvord R. M. Steen
編集者はまた、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: リスト型
- 出力
-
なし
-
itemsリストが空でない場合、
-
クリップボードをクリアする
-
リスト内の各パートについて、
-
データ型がtext/plainの場合、
-
OSやロケールの規則に従ってエンコーディングが正しいことを保証する
-
プラットフォームの規則に従って改行コードを正規化する
-
テキストを適切なOSクリップボード形式記述子でクリップボードに配置する
-
-
それ以外でデータ型が必須データ型リストに含まれている場合、
-
パートを適切なOSクリップボード形式記述子でクリップボードに配置する
-
-
その他
-
-
-
それ以外の場合(itemsリストが空の場合)、クリップボードをクリアするかどうか以下の手順で判断する:
BLOBとoptionをクリップボードに書き込む
-
items内の各itemについて:
-
formatStringを、itemの
typeを与えてOS 固有の既知形式を実行した結果とする。 -
formatStringが空である場合、以下の手順に従う:
-
webCustomFormatStringを、itemの
typeとする。 -
webCustomFormatを空の
typeとする。 -
webCustomFormatStringが`"web "`接頭辞で始まる場合、 `"web "`接頭辞を削除し、残りの文字列を webMimeTypeStringに格納する。
-
webMimeTypeを、webMimeTypeStringを与えてMIME型を解析する結果とする。
-
webMimeTypeがfailureである場合、すべての手順を中止する。
-
itemの
typeをwebCustomFormatに設定する。 -
webCustomFormatをwebCustomFormatsに追加する。
-
-
payloadを、itemの基になるバイト列をUTF-8復号した結果とする。
-
formatStringをネイティブクリップボード形式として使用して、 payloadおよびpresentationStyleをシステム クリップボードに挿入する。
一部のOSには 複数のクリップボードがある(例:Linuxの「primary」、「secondary」、「selection」)。それらのうち どれにデータを書き込むかを定義する。
-
-
webCustomFormatsを与えてウェブカスタム形式を書き込む。
OS固有のよく知られたフォーマット
- 入力
-
mimeType、
type - 出力
-
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 を参照。
-
wellKnownFormatを空文字列とする。
-
mimeTypeのessenceが"text/plain"である場合、
Windowsでは、以下に説明する規約に従う:
-
CF_UNICODETEXTをwellKnownFormatに代入する。
MacOSでは、以下に説明する規約に従う:
-
NSPasteboardTypeStringをwellKnownFormatに代入する。
Linux、ChromeOS、およびAndroidでは、以下に説明する規約に従う:
-
"text/plain"をwellKnownFormatに代入する。
-
-
そうでなく、mimeTypeのessenceが"text/html"である場合、
Windowsでは、以下に説明する規約に従う:
-
CF_HTMLをwellKnownFormatに代入する。
MacOSでは、以下に説明する規約に従う:
-
NSPasteboardTypeHTMLをwellKnownFormatに代入する。
Linux、ChromeOS、およびAndroidでは、以下に説明する規約に従う:
-
"text/html"をwellKnownFormatに代入する。
-
-
そうでなく、mimeTypeのessenceが"image/png"である場合、
Windowsでは、以下に説明する規約に従う:
-
"PNG"をwellKnownFormatに代入する。
MacOSでは、以下に説明する規約に従う:
-
NSPasteboardTypePNGをwellKnownFormatに代入する。
Linux、ChromeOS、およびAndroidでは、以下に説明する規約に従う:
-
"image/png"をwellKnownFormatに代入する。
-
-
そうでなく、mimeTypeのessenceが"image/svg+xml"である場合、
Windowsでは、以下に説明する規約に従う:
-
CFSTR_MIME_SVG_XMLをwellKnownFormatに代入する。
MacOSでは、以下に説明する規約に従う:
-
UTTypeSVGをwellKnownFormatに代入する。
Linux、ChromeOS、およびAndroidでは、以下に説明する規約に従う:
-
"image/svg+xml"をwellKnownFormatに代入する。
-
-
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の場合:
-
osFormatNameが"UnicodeText"なら、mimeTypeStringを"text/plain"に設定する。
-
それ以外でosFormatNameが"HTML Format"なら、mimeTypeStringを"text/html"に設定する。
-
それ以外でosFormatNameが"PNG"なら、mimeTypeStringを"image/png"に設定する。
-
それ以外でosFormatNameがCFSTR_MIME_SVG_XMLなら、mimeTypeStringを"image/svg+xml"に設定する。
MacOSの場合:
-
osFormatNameがNSPasteboardTypeStringなら、mimeTypeStringを"text/plain"に設定する。
-
それ以外でosFormatNameがNSPasteboardTypeHTMLなら、mimeTypeStringを"text/html"に設定する。
-
それ以外でosFormatNameがNSPasteboardTypePNGなら、mimeTypeStringを"image/png"に設定する。
-
それ以外でosFormatNameがUTTypeSVGなら、mimeTypeStringを"image/svg+xml"に設定する。
Linux・ChromeOS・Androidの場合:
-
osFormatNameが"text/plain"なら、mimeTypeStringを"text/plain"に設定する。
-
それ以外でosFormatNameが"text/html"なら、mimeTypeStringを"text/html"に設定する。
-
それ以外でosFormatNameが"image/png"なら、mimeTypeStringを"image/png"に設定する。
-
それ以外でosFormatNameが"image/svg+xml"なら、mimeTypeStringを"image/svg+xml"に設定する。
-
mimeTypeをmimeTypeStringに対してMIME型のパースを実行した結果とする。
-
mimeTypeを返す。
Webカスタムフォーマットの読み取り
- 入力
-
item、クリップボード項目
-
webCustomFormatMapを、OS固有の カスタムマップ名とする。
-
システムクリップボードから webCustomFormatMapを読み取る。
-
webCustomFormatMapが空である場合、itemを返す。
-
webCustomFormatMapStringを、 webCustomFormatMapから逆シリアル化されたJSON文字列とする。
Note: webCustomFormatMapから内容を逆シリアル化するには、JSONリーダーが必要である。
-
webCustomFormatMapString内の各(key, value)について:
-
mimeTypeを、keyを与えてMIME型を解析する結果とする。
-
mimeTypeがfailureである場合、このループを継続する。
-
representationを新しい表現とする。
-
representationのMIME型をmimeTypeに設定する。
-
representationのisCustomフラグをtrueに設定する。
-
representationのデータを新しい promiseに設定する。
Note: この ウェブカスタム形式のOSクリップボードデータは、作者が結果の
getType()をClipboardItemオブジェクト上で呼び出すまで取得されない。 -
representationをitemの表現の リストに追加する。
-
Webカスタムフォーマットの書き込み
-
idxを、0に初期化された数値とする。
-
webCustomFormatMapを、OS固有の カスタムマップ名とする。
-
webCustomFormatMapStringを空のJSON文字列とする。
-
items内の各itemについて:
-
webCustomFormatを、OS固有の カスタム名とする。
-
webCustomFormatIdxを、idxを webCustomFormatに追加した結果とする。
-
itemの
typeをキーとして、webCustomFormatIdxを値として、 JSONシリアライザーを使用してwebCustomFormatMapStringに挿入する。Note: 内容をwebCustomFormatMapStringへシリアライズするにはJSONライターが必要である。
-
webCustomFormatIdxを形式として使用して、itemをシステムクリップボードに挿入する。
-
idxをインクリメントする。
-
idxが100より大きい場合、このループを抜ける。
-
-
webCustomFormatMapを形式として使用して、 webCustomFormatMapStringをシステムクリップボードに挿入する。
OS固有のカスタムマップ名
- 出力
-
webCustomFormatMap、文字列
Windowsの場合:
-
webCustomFormatMapに"Web Custom Format Map"を代入する。
-
webCustomFormatMapを返す。
MacOSの場合:
-
webCustomFormatMapに"org.w3.web-custom-format.map"を代入する。
-
webCustomFormatMapを返す。
Linux、ChromeOS、Androidの場合:
-
webCustomFormatMapに"application/web;type=\"custom/formatmap\""を代入する。
-
webCustomFormatMapを返す。
OS固有のカスタム名
- 出力
-
webCustomFormat、文字列
Windowsの場合:
-
webCustomFormatに"Web Custom Format"を代入する。
-
webCustomFormatを返す。
MacOSの場合:
-
webCustomFormatに"org.w3.web-custom-format.type-"を代入する。
-
webCustomFormatを返す。
Linux、ChromeOS、Androidの場合:
-
webCustomFormatに"application/web;type=\"custom/format\""を代入する。
-
webCustomFormatを返す。
クリップボードイベントの発火
- 入力
-
e、発火する
ClipboardEvent - 出力
-
なし
-
clear-was-calledをfalseとする。
-
types-to-clearを空リストとする。
-
clipboard-event-dataを空の
DataTransferオブジェクト(itemsリストは空)とする。 -
clipboard-entryを現在のクリップボード内容のシーケンス番号、またはOSクリップボードがシーケンス番号をサポートしない場合はnullとする。
-
trustedをイベントがユーザーエージェントによって生成された場合true、それ以外はfalseとする。
-
targetを次のように設定する:
-
イベントを次のように処理する:
-
eが"paste"の場合:
-
clipboard-event-dataの内部drag data store modeフラグをread-onlyに設定する。
-
trustedがtrue、または実装がスクリプト生成イベントにOSクリップボードの読み取り権限を与えるよう設定されている場合:
-
OSクリップボード上の各clipboard-partについて以下を実行:
-
clipboard-partがプレーンテキストの場合:
-
テキストがスクリプトエンジン内部のエンコーディングであることを保証する。
-
new-dataを新しい
DataTransferItemとし、drag data item kindはstring、drag data item type stringはtext/plain。 -
new-dataのデータをプレーンテキストに設定する。
-
new-dataをclipboard-event-dataの
itemsリストに追加する。
-
-
clipboard-partがファイル参照の場合、その各ファイル参照について:
-
参照ファイルのMIME型を判定する。
-
new-dataを新しい
DataTransferItemとし、drag data item kindはfile、drag data item type stringはMIME型(不明ならapplication/octet-stream)。 -
new-dataのデータをファイル参照データに設定する。
-
new-dataをclipboard-event-dataの
itemsリストに追加する。
-
-
clipboard-partがOSの規則によるHTMLまたはXHTML形式テキストの場合:
-
実装がHTML貼り付けをサポートしていれば、HTML貼り付けイベントの処理をclipboard-partとclipboard-event-dataで実行する。
-
-
clipboard-partが他のサポートされたバイナリまたはテキスト型(必須データ型参照)の場合:
-
データのMIME型を判定する。
-
new-dataを新しい
DataTransferItemとし、drag data item kindはfile、drag data item type stringはMIME型。 -
new-dataのデータをバイナリまたはテキストデータに設定する。
-
new-dataをclipboard-event-dataの
itemsリストに追加する。
-
-
-
-
-
eが"copy"または"cut"の場合:
-
関連
DataTransferオブジェクトの内部drag data store modeフラグをread/writeに設定する。
-
-
-
eの
clipboardDataをclipboard-event-dataに設定する。 -
eの
isTrustedをtrustedに設定する。 -
eの
composedをtrueに設定する。 -
イベントeをバブル・キャンセル可能として、
ClipboardEventインターフェースを使用しtargetで発火する。イベント発火中のデータアクセス要件は[HTML]で定義されています。追加のクリップボードイベント固有の処理規則は下記の通りです:
-
スクリプトがclearData()または
clear()を呼び出し、かつDataTransferオブジェクトの内部drag data store modeフラグがread/writeの場合:-
clear-was-calledフラグをtrueに設定する。引数が指定されている場合はその引数をtypes-to-clearリストに追加する。
-
-
スクリプトがsetData()を呼び出すかitemsを変更し、clear-was-calledフラグがtrueの場合:
-
types-to-clearリストが空なら:
-
clear-was-calledフラグをfalseに設定する。
-
-
それ以外の場合、setData()の
type引数または新規アイテムのdrag data item type stringが types-to-clearリストに含まれていれば:-
それをリストから除去し、リストが空になったらclear-was-calledフラグをfalseに設定する。
-
-
-
スクリプトがgetData()を呼び出すか
DataTransferItemListのitemsにアクセスし、clipboard-entryがセットされている場合:-
クリップボードデータのシーケンス番号がclipboard-entryと一致するか確認し、一致しない場合は
DataTransferItemListオブジェクトの内部drag data store modeをprotectedに設定する。
-
警告!pasteイベントを監視する悪意のあるスクリプトは、ユーザーが今後クリップボードに置く内容を読み取るため、無限ループを仕掛ける可能性があります。クリップボードのシーケンス番号が取得できないプラットフォームでは、他の制限を実装すべきです。
-
HTML貼り付けイベントの処理
- 入力
-
clipboard-part、処理対象のクリップボードパート
clipboard-event-data、このイベント用の
DataTransferオブジェクト - 出力
-
なし
-
new-dataを新しい
DataTransferItemとし、drag data item kindはPlain Unicode string、drag data item type stringは適宜text/htmlまたはapplication/xhtml+xml。 -
clipboard-partからマークアップを抽出し、適切なパーサーでDOMツリーを構築する。
-
マークアップのソースURLが判明している場合、HREFやSRC属性の相対URLをソースURLを基準に絶対URLに解決し、属性値を絶対URLにする。
-
マークアップのオリジンがローカルアプリケーションの場合、ローカルファイルやOSクリップボード内の他パート参照があるか確認し、参照があればsub-part参照はcid:URLスキーム[RFC2392]でcontent-id参照に必ず置換する。各属性について下記手順で処理:
これらの手順は必要か?内部参照を持つネイティブ(プラットフォーム)クリップボード実装の存在を把握しているか?
この機能は要件不明かつクロスプラットフォームで検証困難なためリスクあり。
-
clipboard-event-dataの
itemsに参照されたファイルまたはクリップボード部品のエントリが既に存在する場合、-
itemNumberに既存エントリのインデックスを設定する。
-
-
それ以外の場合、
-
new-file-dataを新しい
DataTransferItem(drag data item kindは"file"、drag data item type stringはファイルまたはクリップボード部品のMIME型(不明ならapplication/octet-stream))として作成する。 -
file-infoを新しい
Fileオブジェクト(nameはHTML属性内容の名前部分、lastModifiedは参照ファイルのタイムスタンプまたはクリップボード部品参照なら0)として作成する。 -
new-file-dataの内部
Fileオブジェクトにfile-infoを設定する。 -
new-file-dataをclipboard-event-dataの
itemsに追加し、そのエントリのインデックスをitemNumberとする(DataTransferItemList内)。
-
-
ローカルファイルやクリップボード部品を参照していたDOM属性を 'cid:'+itemNumber の文字列に更新する。
-
-
処理後のDOMをシリアライズし、そのHTMLコードでnew-dataを更新する。
-
new-dataをclipboard-event-dataの
itemsに追加する。