新・日々の暮らしに疲れてない?

一人バンド、火頭工房

【Chrome拡張機能】文字をドラッグでオートコピー&右クリックでペースト

久しぶりにクローム拡張機能を作ろうと思います。

 

どこかで見かけた便利機能で「文字をハイライトしたらコピーする」というもの。その後、右クリックでペースト出来るようにしたらもう1つ便利だろう、ということでパパっと作ってみることに。

 

これが意外と苦労したんですよね、しかも現状使い物になっていない。

 

そもそも文字のコピー(右クリックでメニューからコピー、あるいはCtrl + cでコピーする機能)って別にブラウザだけで行うものでもないですよね、メモ帳に書いたものをコピーしたり、ブラウザ上のアドレスバーのURLをコピーしたり。

 

これらはクローム拡張機能でどうこうできる範疇を超えているわけで、ここに目をつけるのは筋違いと言うわけですね。

 

とにかく実装した範囲を記します。

 

「左クリックでドラッグした範囲をコピー」

これはすんなり行きました。

onmouseupイベントというのがあり、マウスボタンを離した時に発火してくれます。その中で、window.getSelection(); をすれば選択範囲の要素が取得できます。ここから選択範囲の文字列を取得するには更に、toString(); をします。

 

こんな感じ↓

let _selected = window.getSelection();

let selected = _selected.toString();

 

これでドラッグで選択した範囲の文字列が取得できます。

 

次、コピー。

document.execCommand('copy');

これだけ。ちょっと良く分かっていないのですが、何をコピーするか渡していなくてもonmouseupイベントの中で行えば、選択範囲をクリップボードにコピーしてくれます、ちょっと気持ち悪いですね。

 

とにかく、これでコピーは作動します。

ただし、これだとコピーするつもりがなくてもクリックするたびにコピーしようとするので、文字数制限や空文字対策をする必要があります。

 

クリップボードにコピーしたものを右クリックでペーストする」

こっちが問題でした。

コピーが簡単だったもんで、document.execCommand('paste'); とでもすればペーストしてくれるだろうと踏んでいましたが間違いでした。

こっちはどこにペーストするのか、指定をしないと作動しない感じでしょうか(まぁそりゃそうだわな)。

 

調べてみると、ペースト先の要素を取得し、.focus()したりしているコードを見つけました。でも、私が試してもうまく動作しないんですよね。falseが返って来てしまいます。←返ってくるだけマシです。

 

ちなみに、右クリックで何かを作動させるには、contextmenuに機能を追加する、ということになります。document.addEventListener()でcontextmenuを指定し、その中にコードを書いていくのですが、navigator.clipboard.readText(); を試してみるとうまく行きました。

 

でもね、ネットで拾ってきたコードを適当に試してるので何かわかってないんですよ。navigatorって何?って感じです。

 

とにかく動いたので気を良くしてテストしてたら、navigatorの意味がわかりました。

 

f:id:hiatama:20181231162126p:plain

どーん。これです、最悪。

 

サイトによってこの許可を求められます、これは致命的。

というわけでクロームの設定をいじってユーザーが常時クリップボードへのアクセスを許可しないとこの機能自体が無駄になります(そういう設定フラグがあるのかも知りません)。

 

やる気がなくなりました。

 

後は考えたことや気づいたことを箇条書きしておきます。

 

・調べていると、コピペはセキュリティの観点から許可に対して慎重らしい。拡張機能側で許可を書いている例も発見。

 

・document.execCommand('copy'); では許可を求められなかったのだから、ペーストも

許可なし? もしそうなら、狙った要素に作動させることが出来れば全て解決。

 

クリップボードに頼らず、変数に文字列を格納して擬似コピーペースト機能を作ればいいじゃん → クリップボードを通さない以上、ブラウザ外でコピーしたものはペースト出来ないのでイマイチ。

 

クリップボードを通さない場合、同じタブの中だけしかコピーペーストができないのでそれでは無意味、変数の中味を共有するには、ストレージとかバックグラウンドページを使う必要がありちょい面倒、だけどやる価値あり。

 

・それでも最初に書いたように、アドレスバーなどは拡張機能でいじれない範囲なので(たぶん)機能として中途半端だと気づく。

 

・ペーストする時に、消したい文字を範囲選択してそこにペーストして上書きすることってありません? あれが出来なくなります。ドラッグを解除した瞬間に消したいはずの文字が新たにコピーされてしまうからです。選択範囲をした状態で左マウスボタンを離さず右クリックしたら回避できましたが...ちょっとなぁ。

 

以上。

まぁいつも通り、自分だけで使えばいいや。

許可が求められる navigatorは論外だけど、変数を使った擬似コピーペースト機能でも使い道ある。

 

少なくともdocument.execCommand('copy') の方に問題はない、ちゃんとクリップボードにコピーされるので、同時に内容を変数に確保、右クリックでのペーストはnavigatorを通さず、変数の内容を 要素.target.value で直接入力する仕組みにします。

もちろん Ctrl + v でもペーストが出来るので問題なし。

 

あとはdocument.execCommand('paste'); の方をもう少し調べてみるのと、バックグラウンドページを使った方法も完成させよう。

 

それでは2018年も終わり。良いお年を。 

 

追記:

調べて色々試したところ、ストレージと変数を使って擬似コピペ機能を使うのが手軽でした。ブラウザ以外からコピーしたものには対応できていませんが、これもタブ機能を調べれば対処できそうです。あとはアドレスバーへのアクセスだけど...これはたぶん無理。