6.6 クリップボード

(1/1)
クリップボードに書き込む人のイラスト(女性)
プログラムの処理結果を他システムに渡すとき、インターフェースを介して渡すのが理想だが、開発にコストがかることが多い。そこで次善の策として、クリップボードを介して手動でデータを渡す運用にすることがある。
今回は、「5.4 正規表現」で作ったハイパーリンク変換プログラムを改良し、変換結果をクリップボードにコピーできることを目指す。

サンプル・プログラムの実行例

テキスト中のURLをハイパーリンクに変換

目次

サンプル・プログラム

圧縮ファイルの内容
url2link2.htmlテキスト中のURLをハイパーリンクに変換
pahooClipboard.jsクリップボード・クラス
url2link2.html 更新履歴
バージョン 更新日 内容
1.1.0 2023/08/16 制御構造を見直した
1.0 2021/08/14 初版
pahooClipboard.js 更新履歴
バージョン 更新日 内容
1.0 2021/08/31 初版

クリップボードとセキュリティ

JavaScriptからクリップボードにアクセスする方法は、過去に何度か変わっている。
2010年代までは、ZeroClipboard というオープンソースのライブラリがよく使われた。これは、Flashを利用していたため、その後、ブラウザのFlashサポートとともに使えなくなった。

document.execCommand メソッドを使う方法があったが、これもセキュリティ上望ましくないということで、機能が廃止された。

2021年8月現在、navigator.clipboard オブジェクトの利用が推奨されているが、IE11ではこの機能が実装されていない。
そこで、
  1. navigator.clipboardが実装されているブラウザ
  2. IE11の場合
  3. 上記2つのいずれでもない場合
の3つに場合分けして、クリップボードへデータをコピーするクラス pahooClipboard を作ることにする。クラスは "pahooClipboard.js" としてファイルを分け、他のプログラムでも流用できるようにする。

pahooClipboard――クリップボード・クラス

   9: 
  10: /**
  11:  * クリップボード・クラス
  12:  *    IE11対応のため無名関数で記述
  13:  * @param   String idname コピー・ボタン名(ID名)
  14:  * @return  なし
  15: */
  16: pahooClipboard = function(idname) {
  17:     let elem = document.getElementById(idname);
  18: 
  19:     //ボタン押下:クリップボードへコピー
  20:     elem.addEventListener('click', function() {
  21:         let target = elem.getAttribute('data-clipboard-target');    //コピー対象
  22:         let elem2  = document.getElementById(target);
  23:         let text   = elem2.value;
  24: 
  25:         //IE以外(navigator.clipboard 実装済)
  26:         if (navigator.clipboard) {
  27:             navigator.clipboard.writeText(text);
  28:             console.log('navigator.clipboard');
  29:         //IE
  30:         } else if (window.clipboardData) {
  31:             window.clipboardData.setData('Text', text);
  32:             console.log('window.clipboardData');
  33:         //それ以外:execCommand('Copy')実行(ただし非推奨機能)
  34:         } else {
  35:             elem2.select();
  36:             document.execCommand('Copy');
  37:             console.log('execCommand');
  38:         }
  39:     }, false);
  40: }

 115: 変換後テキスト<br />
 116: <textarea name="dest" id="dest" rows="10" style="width:600px;"></textarea>
 117: </p>
 118: <input type="submit" name="exec" id="exec" value="変換" onClick="url2link()" />&nbsp;
 119: <input type="submit" name="reset" id="reset" value="リセット" onClick="reset()" />&nbsp;
 120: <input type="button" id="btncopy" name="btncopy" value="コピー" data-clipboard-target="dest" />
 121: 

クラス pahooClipboard は、IEでも動作することを目指し、無名関数を使って定義した。詳しくは、「5.5 クラス」をご覧いただきたい。

引数はコピー・ボタンのID名である。
addEventListener メソッドは、このオブジェクト(コピー・ボタン)で何かイベントが起きたときに実行する処理を登録する。ここでは、cliskイベントが起きたときに、それ以降の関数を実行するようにしている。

コピー対象は、コピー・ボタンに data-clipboard-target 属性で指定したオブジェクトである。上述のHTML部分を合わせてご覧いただきたい。
コピー対象が特定できたら、クリップボードへのコピー処理を行う。

まず、navigator.clipboard が存在する場合だが、これは clipboard.writeText メソッドを使ってクリップボードに書き込む。

次にIEの場合だが、IEには window.clipboardData という navigator.clipboard と同機能のメソッドがあり、これを使う。

最後に、navigator.clipboardwindow.clipboardData も無い場合だが、非推奨の execCommand('Copy') を使うことにした。この場合、事前に select メソッドを使ってコピーする範囲を選択しておく必要がある。
また、どの方式が実行されたか、console.log に出力するようにした。

コラム:同期と非同期

いろいろなクリップボードのイラスト
Windowsの Win32:クリップボードAPIはかなり古く、少なくともWindows 2000の時代から存在する。「PHPでクリップボードにテキスト貼り付け(Windowsアプリ版)」で紹介したように、この機能は "User32.dll" に実装されている。
今日ではセキュリティが不十分なAPIとして知られており、このため、JavaScript側でもクリップボードへのアクセス方式を見直していると思われる。
クリップボードのセキュリティ問題は、コピーされたデータが容易に他のプログラムによって読み取られる恐れがあることだ。
また、格納するデータ量に応じてメモリ領域を確保しているため、画像など極端に大きなデータをコピーしようとして、メモリ確保・解放が正しく行われていないと、システムにダメージを与える恐れがある。

一方、マイクロソフトは、2021年のWindows 10の機能改良の中で、クリップボードの履歴機能を付加したり、他のデバイス(Androidスマホやタブレット)でもクリップボードの内容を共有できるようにした。セキュリティ的にどうなのだろうか🤔

参考サイト

(この項おわり)
header