2018年12月2日日曜日

Chrome拡張でコピペ禁止を禁止

結構大きなサイトでなぜかコピペが禁止されていて辛みがあり、Chrome拡張でコピペ禁止を禁止する事にしました。 よほど重要なサイトならともかく「なぜここで?」というところはたまにある。

コピペ禁止は例えば以下のような実装パターンがあるけど、JavaScript/CSSの両方を弄らないと対処できない。 以下の4例以外にマウス/タッチイベントをキャプチャするみたいな方法もありそうだけど、実装は見た事がないし作るのは面倒そうなので割愛した。


JavaScriptによるコピペ禁止例

:

JavaScriptによる選択禁止例

:

CSSによる選択禁止例

:

JavaScriptによるキーボード禁止例

:


Chrome拡張での対応は、以前紹介した Minimal User CSS & JavaScript なChrome拡張を作った を拡張する事を前提として話を進める。 ただし "run_at": "document_start" で実行しないといけない点だけは注意して欲しい (参考)。

user.jsに以下を書き加える。
// コピペの禁止を禁止
document.addEventListener('cut', event => event.stopImmediatePropagation(), true);
document.addEventListener('copy', event => event.stopImmediatePropagation(), true);
document.addEventListener('paste', event => event.stopImmediatePropagation(), true);
// 選択の禁止を禁止 (user.cssも変更が必要)
document.addEventListener('selectstart', event => event.stopImmediatePropagation(), true);
// キーボード/マウス/タッチイベントの変更を禁止
// document.addEventListener('keydown', event => event.stopImmediatePropagation(), true);
// document.addEventListener('mousedown', event => event.stopImmediatePropagation(), true);
// document.addEventListener('dragstart', event => event.stopImmediatePropagation(), true);
// document.addEventListener('touchstart', event => event.stopImmediatePropagation(), true);
// document.addEventListener('touchmove', event => event.stopImmediatePropagation(), true);
キーボード/マウス/タッチイベントの変更禁止はリッチUIサイトでは不都合が生じる可能性がある。 普段はこれらをOFFにしておいて、いざ面倒なサイトに遭遇した時だけONにしたほうが良いかも知れない。 逆にサイト管理者がユーザに多少の不都合があったとしてもコピペを禁止したい場合、この辺を弄ると良いと思われる。
その他の指定に関しては常時ONにしておいても良いと思う。 選択の禁止はゲームサイトだと問題になる事はあるかもだけど、せいぜいそれくらいだろう。


user.cssは以下のようにする。
* {
  user-select: auto !important;
  user-drag: auto !important;
}

user-select/user-dragプロパティにはブラウザ特有の値として、-moz-, -webkit-, -khtml-, -ms- などの追加プロパティがある。 様々なブラウザの利用を考えると一番最初に書いたコピペ禁止の実装例のようにすべて指定する必要がある。 ソースを見るのが面倒な人のために書き出すと、以下のように値を指定するべきだ。
-webkit-user-select: text !important;
-webkit-user-drag: auto !important;
:
ただuser-select/user-dragさえ指定しておけばChrome拡張ではきちんと動作する事を確認しているし、 ブラウザ毎に動作が微妙に異なる部分をわざわざ指定するのは面倒なだけだ。 最も簡単な指定さえしておけば (たぶん) 十分だろう。

0 件のコメント: