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を使用してスクリプトがクリップボードに書き込んだ場合
-
ユーザーエージェント外でクリップボードが更新された場合
クリップボードの内容がユーザーエージェント外で変更された場合、ユーザーエージェントがフォーカスを再取得した時点でclipboardchange
イベントが必ず発火します。
合成されたcut
やcopy
イベントはシステムクリップボードを更新しないため、
"clipboardchange"イベントは発火しません。
5.2.2. copy
イベント
ユーザーがコピー操作を開始すると、ユーザーエージェントはcopy
という名前のクリップボードイベントを発火します。
イベントがキャンセルされない場合、現在選択されているデータがシステムクリップボードへコピーされます。 現在のドキュメントの選択範囲は変化しません。
copy
イベントはバブルし、キャンセル可能で、構成可能です。
このイベントの処理モデルの詳細は§ 8.1 コピーアクションを参照してください。
合成copy
イベントは手動で構築してディスパッチできますが、
システムクリップボードの内容には影響しません。
5.2.3. cut
イベント
ユーザーが切り取り操作を開始すると、ユーザーエージェントはcut
という名前のクリップボードイベントを発火します。
編集可能コンテキストの場合、イベントがキャンセルされなければ、現在選択されているデータがシステムクリップボードに配置され、選択範囲が文書から削除されます。
cut
イベントは選択されたデータが削除される前に発火します。切り取り操作が完了すると、選択範囲は折りたたまれます。
非編集可能コンテキストの場合、clipboardData
は空リストになります。この場合でもcut
イベントは発火します。
cut
イベントはバブルし、キャンセル可能で、構成可能です。
このイベントの処理モデルの詳細は§ 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を返します。
クリップボードアイテムは、ユーザーが「切り取り」や「コピー」コマンドを実行することで共有可能にしたいデータを概念的に表します。クリップボードアイテムには2つの役割があります。1つ目は、ウェブサイトがユーザーによってシステムクリップボードにコピーされたデータを読み取れるようにすること。2つ目は、ウェブサイトがシステムクリップボードへデータを書き込めるようにすることです。
例えばユーザーがネイティブアプリのスプレッドシートからセル範囲をコピーした場合、1つのクリップボードアイテムになります。ユーザーがデスクトップから複数のファイルをコピーした場合は、そのファイルリストは複数のクリップボードアイテムとして表現されます。
プラットフォームによっては、クリップボード上に複数のクリップボードアイテムを同時に保持できる場合もあれば、新しいもので前のクリップボードアイテムを置き換える場合もあります。
クリップボードアイテムは表現リストを持ち、各表現は関連するmime type(MIMEタイプ)、初期値falseのisCustomフラグ(この表現をwebカスタムフォーマットとして扱うかどうかを示す)、およびdata(ClipboardItemData
)を持ちます。
webカスタムフォーマットはisCustomがtrueに設定されたものです。
スプレッドシートからセル範囲をコピーした場合、image(image/png)、HTMLテーブル(text/html)、プレーンテキスト(text/plain)、webカスタムフォーマット(web text/csv)として表現されることがあります。
これらのMIMEタイプは、同じクリップボードアイテムを異なる忠実度レベルで表現し、貼り付け時にターゲットアプリがより扱いやすくなります。
セル範囲を画像として利用可能にすることで、ユーザーは画像編集アプリに貼り付けることができますし、text/plainはテキストエディタアプリで利用できます。
クリップボードアイテムは表示スタイル(PresentationStyle
)を持ちます。
これは、アプリがクリップボードアイテムの適切な表現内容を貼り付け時にインライン挿入するか、添付ファイルとして扱うかを区別するために使われます。
1つのクリップボードアイテムのみ貼り付け可能なWebアプリは、最初のクリップボードアイテムを使うべきです。
write()
は最後のクリップボードアイテムを選択します。
複数のクリップボードアイテムを貼り付け可能なWebアプリは、例えば各クリップボードアイテムの内容をプレビューするUIを提供し、ユーザーがどれを貼り付けるか選択できるようにしてもよいです。 また、アプリは貼り付けるMIMEタイプを列挙し、アプリ独自のアルゴリズムで最適なものを選んでもよいです。 あるいは、ユーザーに「画像として貼り付け」「書式付きテキストとして貼り付け」等の選択肢を提示することもできます。
ClipboardItem
オブジェクトには対応するクリップボードアイテム(clipboard item)が関連付けられています。
ClipboardItem
オブジェクトには対応するtypes array(FrozenArray
<DOMString
)が関連付けられています。
ClipboardItem
オブジェクトを作成するには、clipboard item clipboardItemとRealm
realmが与えられたとき、以下の手順を実行します:
-
clipboardItemObjectをnew
ClipboardItem
で realmを使って作成する。 -
clipboardItemObjectのクリップボードアイテムをclipboardItemに設定する。
new ClipboardItem(items, options)
のコンストラクタ手順:
-
itemsが空の場合、
TypeError
をスローする。 -
optionsが空の場合、options["presentationStyle"] = "unspecified"とする。
-
thisの clipboard itemを新しいclipboard itemに設定する。
-
thisの clipboard itemのpresentation styleを options["
presentationStyle
"]で設定する。 -
typesを
DOMString
のリストとして作成する。 -
itemsの各(key, value)について:
-
representationを新しいrepresentationとして作成する。
-
isCustomをfalseとする。
-
keyが"web "で始まる場合、
-
"web "のプレフィックスを取り除き、残りをkeyに代入する。
-
isCustomをtrueに設定する。
-
-
representationのisCustomフラグをisCustomで設定する。
-
mimeTypeをkeyに対してMIME型のパースの結果で設定する。
-
mimeTypeが失敗の場合、
TypeError
をスローする。 -
thisのclipboard itemのlist of representationsが、mimeTypeと[representation/isCustom]がisCustomであるrepresentationを含む場合、
TypeError
をスローする。
上記のステップは、ユーザーエージェントがよく知るmime-typeと著者がカスタム型として扱う意図があるものとの衝突を防ぎます。例えば、著者のitemsリストに"text/html"と"web text/html"の両方のrepresentationを含めることが可能です。
-
representationのMIME typeをmimeTypeで設定する。
-
representationのdataをvalueで設定する。
-
representationをthisのclipboard itemのlist of representationsに追加する。
-
mimeTypeStringをmimeTypeでMIME型をシリアライズした結果で設定する。
-
isCustomがtrueの場合、mimeTypeStringの先頭に"web "を付与する。
-
mimeTypeStringをtypesに追加する。
-
-
thisの types arrayをtypesから凍結配列を作成した結果で設定する。
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が失敗なら、
TypeError
をスローする。 -
itemTypeListをthisのclipboard itemのlist of representationsとする。
-
pをrealm内の新しいPromiseとする。
-
itemTypeListの各representationについて:
-
representationのMIME typeがmimeTypeであり、 representationのisCustomがisCustomなら:
-
representationDataPromiseをrepresentationのdataとする。
-
-
representationDataPromiseが値vでfulfilledされた場合:
-
representationDataPromiseがrejectされた場合:
-
pをrejectし、
"NotFoundError"
DOMException
をrealmで返す。
-
-
-
pを返す。
-
-
-
pをrejectし、
"NotFoundError"
DOMException
をrealmで返す。 -
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
オブジェクトを受け取ったり返したりします。ただし、すべてのプラットフォームが複数のクリップボードアイテムをサポートしているわけではありません。そのようなプラットフォームでは、下記のアルゴリズムでClipboardItem
のうち最初以外は無視されます。write()
へ渡す場合も、read()
やreadText()
もOSからは1つのクリップボードアイテムしか取得しません。
クリップボードアイテム群 オブジェクトは、sequence型のクリップボードアイテムの集合です。
ウェブ著者は、システムクリップボードへwrite(data)
メソッドで内容を書き込むために、dataとしてClipboardItem
の配列を作成する必要があります。read()
は、システムクリップボードデータの内容を表すPromise
型のクリップボードアイテム群を返します。
unsanitized
は、著者が任意未サニタイズデータ型として扱いたいmime typeに対応するDOMString
のsequenceです。
unsanitized
オプションはUAによってサポートされない場合があります。ウェブ著者は、unsanitized
に記載したMIME型の内容が必ず未サニタイズであると仮定してはいけません。プライバシーモードによってはこのオプションが許可されないことがあります。
クリップボードタスクソース は、システムクリップボードデータの読み書きに応じてトリガーされます。
7.3.1. read(formats)
read(formats)
メソッドは以下の手順を実行する:
-
pをrealm内の新しいPromiseとする。
-
formatsが空でない場合:
-
formats["
unsanitized
"]の各formatについて:-
formatが任意未サニタイズデータ型に含まれていない場合、pをrejectし、formatと
"NotAllowedError"
DOMException
をrealmで返す。
-
-
-
以下の手順を並列で実行する:
-
rをクリップボード読み取り権限の確認の結果とする。
-
rがfalseの場合:
-
グローバルタスクをキューに追加し、permission task source上で realmのglobal objectに対し pをrejectし
"NotAllowedError"
DOMException
をrealmで返す。 -
この手順を中断する。
-
-
dataをシステムクリップボードデータのコピーとする。
-
itemsをsequence<クリップボードアイテム>として作成する。
-
dataの各systemClipboardItemについて:
-
itemを新しいクリップボードアイテムとして作成する。
-
systemClipboardItem内の各systemClipboardRepresentationについて:
-
mimeTypeをsystemClipboardRepresentationのnameを使ってOS固有形式からよく知られたMIME型アルゴリズムの結果とする。
-
mimeTypeがnullの場合、このループを継続する。
-
representationを新しいrepresentationとして作成する。
-
representationのMIME typeをmimeTypeで設定する。
-
isUnsanitizedをfalseとする。
-
formatsが空でない場合:
-
formats["
unsanitized
"]の各formatについて:-
formatがMIME typeと等しい場合、isUnsanitizedをtrueにする。
-
-
-
representationのdataをsystemClipboardRepresentationのdataでresolveする。
著者がgetTypeを呼び出した後に、システムクリップボードから非同期でデータを取得できるようにすべきですが、この手順だとread時点でデータが提供されることを示唆しています。
-
UAは、representationのdataをサニタイズしてもよいですが、representationのMIME typeの本質が"image/png"の場合は、メタデータ保持のためサニタイズしてはなりません。また、以下条件を満たす場合も除外します:
-
representationのMIME typeが未サニタイズデータ型リストに含まれる。
-
isUnsanitizedがtrueである。
-
-
representationをitemのlist of representationsに追加する。
-
isUnsanitizedをfalseにする。
-
-
itemのlist of representationsのサイズが0より大きければ、itemをitemsに追加する。
-
-
itemsのサイズが0より大きい場合:
-
firstItemをitems[0]とする。
-
Webカスタム形式の読み取りアルゴリズムをfirstItemに対して実行する。
-
-
そうでなければ:
-
customItemを新しいクリップボードアイテムとする。
-
Webカスタム形式の読み取りアルゴリズムをcustomItemに対して実行する。
-
customItemのlist of representationsのサイズが0より大きければ、customItemをitemsに追加する。
-
-
グローバルタスクをキューに追加し、クリップボードタスクソース上で realmのglobal objectに対し、以下の手順を実行する:
-
clipboardItemsをsequence<
ClipboardItem
>として作成する。 -
itemsの各クリップボードアイテム underlyingItemについて:
-
clipboardItemを、ClipboardItemオブジェクトの生成手順に従いunderlyingItemとrealmで生成する。
-
clipboardItemをclipboardItemsに追加する。
-
-
pをclipboardItemsでresolveする。
-
-
-
pを返す。
const items= await navigator. clipboard. read(); 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の場合:
-
グローバルタスクをキューに追加し、permission task source上で realmのglobal objectに対し pをrejectし
"NotAllowedError"
DOMException
をrealmで返す。 -
この手順を中断する。
-
-
dataをシステムクリップボードデータのコピーとする。
一部のOSには複数のクリップボード(例: Linuxの"primary"、"secondary"、"selection")が存在します。どのクリップボードからデータを読み取るか定義してください。
-
グローバルタスクをキューに追加し、クリップボードタスクソース上で realmのglobal objectに対し、以下の手順を実行する:
-
dataの各systemClipboardItemについて:
-
systemClipboardItem内の各systemClipboardRepresentationについて:
-
mimeTypeをsystemClipboardRepresentationのnameを使ってOS固有形式からよく知られたMIME型アルゴリズムの結果とする。
-
mimeTypeがnullの場合、このループを継続する。
-
representationを新しいrepresentationとして作成する。
-
representationのMIME typeの本質が"text/plain"の場合:
-
representationのMIME typeをmimeTypeで設定する。
-
representationDataPromiseをrepresentationのdataとする。
-
-
representationDataPromiseが値vでfulfilledされた場合:
-
representationDataPromiseがrejectされた場合:
-
pをrejectし、
"NotFoundError"
DOMException
をrealmで返す。 -
pを返す。
-
-
-
-
-
-
pをrejectし、
"NotFoundError"
DOMException
をrealmで返す。 -
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の場合:
-
グローバルタスクをキューに追加し、permission task source上で realmのglobal objectに対し pをrejectし
"NotAllowedError"
DOMException
をrealmで返す。 -
この手順を中断する。
-
-
グローバルタスクをキューに追加し、クリップボードタスクソース上で realmのglobal objectに対し、以下の手順を実行する:
-
dataListをsequence<
ClipboardItem
>として作成する。 -
dataのsizeが1より大きく、かつ現在のOSがシステムクリップボードで複数のネイティブクリップボードアイテムをサポートしていない場合は、data[0]をdataListに追加し、そうでなければdataListをdataとする。
dataに複数アイテムが含まれ、OSが複数のネイティブクリップボードアイテムをサポートしている場合、現行アルゴリズムは各アイテムを順に書き込むが、本来はまとめて書き込むべきです。
-
dataListの各clipboardItemについて:
-
clipboardItemのclipboard itemのlist of representationsの各representationについて:
-
representationDataPromiseをrepresentationのdataとする。
-
-
representationDataPromiseが値vでfulfilledされた場合:
-
representationDataPromiseがrejectされた場合:
-
pをrejectし、
"NotAllowedError"
DOMException
をrealmで返す。 -
この手順を中断する。
-
-
-
-
itemListの各blobについて:
-
typeをblobの
type
とする。 -
typeが必須データ型または任意データ型リストに含まれていない場合、pをrejectし、
"NotAllowedError"
DOMException
をrealmで返し、この手順を中断する。 -
cleanItemをblobの(オプションでサニタイズされた)コピーとする。
-
サニタイズ処理が試みられたが正常に完了しなかった場合、以下の手順を実行する:
-
pをrejectし、
"NotAllowedError"
DOMExceptionをrealmで返す。 -
この手順を中断する。
-
-
cleanItemをcleanItemListに追加する。
-
-
optionをclipboardItemのclipboard itemのpresentation styleとする。
-
blobとoptionをクリップボードへ書き込む(cleanItemListとoptionを使用)。
-
-
pをresolveする。
-
-
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の場合:
-
グローバルタスクをキューに追加し、permission task source上で realmのglobal objectに対し pをrejectし
"NotAllowedError"
DOMExceptionをrealmで返す。 -
この手順を中断する。
-
-
グローバルタスクをキューに追加し、クリップボードタスクソース上で realmのglobal objectに対し、以下の手順を実行する:
-
textBlobを新しい
Blob
(type
属性は"text/plain;charset=utf-8
"、バイト列はdataのUTF-8エンコード)で作成する。注: Windowsではdata内の`\n`を`\r\n`に置換してからtextBlobを作成してください。
-
textBlobをitemListに追加する。
-
optionを"unspecified"に設定する。
-
blobとoptionをクリップボードへ書き込む(itemListとoptionを使用)。
-
pをresolveする。
-
-
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という名前のクリップボードイベントを発火する
-
-
イベントがキャンセルされた場合、
-
write content to the clipboardアルゴリズムを呼び出し、
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を返す
-
-
-
イベントがキャンセルされた場合、
-
write content to the clipboardアルゴリズムを呼び出し、
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を、関連グローバルオブジェクトが一時的なアクティベーションを持つ場合true、そうでなければfalseとする。
-
もしhasGestureなら、
-
現在のスクリプトがユーザーエージェントまたはOSが作成した「貼り付け」要素のユーザー操作により実行されている場合trueを返す。
-
-
falseを返す。
9.2. クリップボード書き込み権限
9.2.1. クリップボード書き込み権限の確認
-
writeWithoutGestureを
{ name: "clipboard-write", allowWithoutGesture: true }
権限の権限状態とする。 -
writeWithoutGestureが
granted
ならtrueを返す。 -
hasGestureを、関連グローバルオブジェクトが一時的なアクティベーションを持つ場合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とオプションをクリップボードに書き込む
- 入力
-
presentationStyle: クリップボードアイテムのpresentation style
- 出力
-
なし
-
itemsの各itemについて:
-
formatStringをitemの
type
に対してOS固有のよく知られたフォーマットを実行した結果とする。 -
formatStringが空の場合、以下の手順を実行:
-
webCustomFormatStringをitemの
type
とする。 -
webCustomFormatを空の
type
として作成する。 -
もしwebCustomFormatStringが"web "で始まる場合、"web "を除去し残りの文字列をwebMimeTypeStringに保存する。
-
webMimeTypeをwebMimeTypeStringに対してMIME型のパースを実行した結果とする。
-
もしwebMimeTypeが失敗なら、すべての手順を中断する。
-
itemの
type
をwebCustomFormatに設定する。 -
webCustomFormatをwebCustomFormatsに追加する。
-
-
payloadをitemのバイト列をUTF-8デコードした結果とする。
-
payloadとpresentationStyleをformatStringをネイティブクリップボードフォーマットとして使い、システムクリップボードに挿入する。
一部のOSには複数のクリップボード(例: Linuxの"primary"、"secondary"、"selection")が存在します。どのクリップボードに書き込むか定義してください。
-
-
Webカスタムフォーマットの書き込みを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の本質が"text/plain"の場合、
Windowsの場合:
-
CF_UNICODETEXTをwellKnownFormatに代入する。
MacOSの場合:
-
NSPasteboardTypeStringをwellKnownFormatに代入する。
Linux・ChromeOS・Androidの場合:
-
"text/plain"をwellKnownFormatに代入する。
-
-
それ以外でmimeTypeの本質が"text/html"の場合、
Windowsの場合:
-
CF_HTMLをwellKnownFormatに代入する。
MacOSの場合:
-
NSPasteboardTypeHTMLをwellKnownFormatに代入する。
Linux・ChromeOS・Androidの場合:
-
"text/html"をwellKnownFormatに代入する。
-
-
それ以外でmimeTypeの本質が"image/png"の場合、
Windowsの場合:
-
"PNG"をwellKnownFormatに代入する。
MacOSの場合:
-
NSPasteboardTypePNGをwellKnownFormatに代入する。
Linux・ChromeOS・Androidの場合:
-
"image/png"をwellKnownFormatに代入する。
-
-
それ以外でmimeTypeの本質が"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文字列とする。
注: webCustomFormatMapの内容デシリアライズにはJSONリーダーが必要。
-
webCustomFormatMapString内の各(key, value)について:
-
mimeTypeをkeyに対してMIME型のパースの結果とする。
-
mimeTypeが失敗なら、ループを継続する。
-
representationを新しいrepresentationとして作成する。
-
representationのMIME typeをmimeTypeに設定する。
-
representationのisCustomフラグをtrueに設定する。
-
webCustomFormatをvalueを使ってシステムクリップボードから読み取る。
-
読み取りが成功した場合、representationのdataをシステムクリップボードの取得データに設定し、失敗ならループを継続する。
-
representationをitemのlist of representationsに追加する。
-
Webカスタムフォーマットの書き込み
-
idxを0で初期化する。
-
webCustomFormatMapをOS固有のカスタムマップ名とする。
-
webCustomFormatMapStringを空のJSON文字列とする。
-
itemsの各itemについて:
-
webCustomFormatをOS固有のカスタム名とする。
-
webCustomFormatIdxをwebCustomFormatにidxを結合した結果とする。
-
itemの
type
をキー、webCustomFormatIdxを値として webCustomFormatMapStringにJSONシリアライザーで追加する。注: webCustomFormatMapStringへのシリアライズにはJSONライターが必要。
-
itemをwebCustomFormatIdxをフォーマットとしてシステムクリップボードに挿入する。
-
idxをインクリメントする。
-
idxが100を超えたら、このループを終了する。
-
-
webCustomFormatMapStringをwebCustomFormatMapをフォーマットとしてシステムクリップボードに挿入する。
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
に追加する。