Skip to content

Instantly share code, notes, and snippets.

@khsk
Last active September 26, 2017 01:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save khsk/e4c10a98889a0a7e5ce5 to your computer and use it in GitHub Desktop.
Save khsk/e4c10a98889a0a7e5ce5 to your computer and use it in GitHub Desktop.
Qiitaのコードにコピーボタンを追加するユーザースクリプト ref: http://qiita.com/khsk/items/27a80755d883521ecd73
// ==UserScript==
// @name Qiita code copy button
// @namespace khsk
// @description コードをコピーするボタンを追加する
// @include http://qiita.com/*/items/*
// @version 1
// @grant none
// ==/UserScript==
const OFF = 0
const ON = 1
// マウスオーバー時のみボタンを表示 ただし表示時にアイコン分下にずれる(OFFなら常にずれている)
var enable_mouseover = ON
// インターフェース作成
var i = document.createElement('i')
i.className = 'fa fa-clipboard'
var div = document.createElement('div')
div.appendChild(i)
// クラスによるfloatを解除
div.style.float = 'none'
// クラスによるフォントの拡大を解除
div.style.fontSize = 'initial'
// コード内かつコード名の右側へ
div.style.display = 'inline-block'
// 上に張り付いているので少し離す(本来よりn pxだけ長くなる)
div.style.marginTop = '3px'
// 「書き方」のマウスオーバーを拝借
div.className = 'editorMarkdown_help'
// notice 解除するぐらいなら必要なcssのみ手動でコピーした方が安心しそう
if (enable_mouseover) {
// displayではボタン分のスペースを確保しないのでvisibilityで。
// displayではマウスオーバー・アウトでガタガタになる。(marginを設定しないならば名前付きはずれない)
//div.style.display = 'none'
div.style.visibility = 'hidden'
}
div.addEventListener('click', copy_code)
// 先に宣言しないと登録できないので、関数定義
// コピー関数
var copy_code = function() {
if (!document.queryCommandSupported('copy')) {
// Firefox40までは未実装でもtrueが来てしまう
alert('copyに対応していません')
return
}
// コピー対象を選択状態にする
var range = document.createRange();
range.selectNode(get_last_html_node(this.parentNode));
window.getSelection().addRange(range);
try {
document.execCommand('copy')
} catch (e) {
// 非対応なら例外が出る Firefox40までなど
alert('copyに失敗しました')
}
// 選択を解除する
window.getSelection().removeAllRanges();
}
// 空のテキストノードを含まないchildrenからラストノードを取得するヘルパー
var get_last_html_node = function (node) {
return node.children[node.children.length - 1]
}
// マウスオーバー処理有効時のみ宣言
if (enable_mouseover) {
var show_button = function() {
//get_last_html_node(this).previousSibling.style.display = 'inline-block'
get_last_html_node(this).previousSibling.style.visibility = ''
}
var hide_button = function() {
//get_last_html_node(this).previousSibling.style.display = 'none'
get_last_html_node(this).previousSibling.style.visibility = 'hidden'
}
}
// 全 ``` 記法にコピーボタンをつける(``は対象外)
var code_frames = document.getElementsByClassName('code-frame')
/* Chromeでは Array.forEachに対応していない http://ptech.g.hatena.ne.jp/noromanba/20120521/1337639496
Array.forEach(code_frames, function(item) {
// クローンしないと最後のitemにしか追加されない。trueでアイコンまでクローン
var div_clone = div.cloneNode(true)
// cloneしたものにイベントを登録する必要がある
div_clone.addEventListener('click', copy_code)
// childNodes first・lastChildはtextノードも含み、挿入場所が末尾になる場合があるので、childrenから取得
item.insertBefore(div_clone, get_last_html_node(item))
if(enable_mouseover) {
item.addEventListener('mouseover', show_button)
item.addEventListener('mouseout', hide_button)
}
})
*/
Array.prototype.forEach.call(code_frames, function(item) {
// クローンしないと最後のitemにしか追加されない。trueでアイコンまでクローン
var div_clone = div.cloneNode(true)
// cloneしたものにイベントを登録する必要がある
div_clone.addEventListener('click', copy_code)
// childNodes first・lastChildはtextノードも含み、挿入場所が末尾になる場合があるので、childrenから取得
item.insertBefore(div_clone, get_last_html_node(item))
if(enable_mouseover) {
item.addEventListener('mouseover', show_button)
item.addEventListener('mouseout', hide_button)
}
})
// ==UserScript==
// @name Qiita code copy button
// @namespace khsk
// @description コードをコピーするボタンを追加する
// @include http://qiita.com/*/items/*
// @include https://qiita.com/*/items/*
// @version 1
// @grant none
// ==/UserScript==
const OFF = 0
const ON = 1
// マウスオーバー時のみボタンを表示 ただし、ボタン分の領域は常に確保
var enable_mouseover = ON
// インターフェース作成
var i = document.createElement('i')
i.className = 'fa fa-clipboard'
var div = document.createElement('div')
div.appendChild(i)
// クラスによるfloatを解除
div.style.float = 'none'
// クラスによるフォントの拡大を解除
div.style.fontSize = 'initial'
// コード内かつコード名の右側へ
div.style.display = 'inline-block'
// 上に張り付いているので少し離す(本来よりn pxだけ長くなる)
div.style.marginTop = '3px'
// 「書き方」のマウスオーバーを拝借
div.className = 'editorMarkdown_help'
if (enable_mouseover) {
div.style.visibility = 'hidden'
}
div.addEventListener('click', copy_code)
// 先に宣言しないと登録できないので、関数定義
// コピー関数
var copy_code = function() {
if (!document.queryCommandSupported('copy')) {
// Firefox40までは未実装でもtrueが来てしまう
alert('copyに対応していません')
return
}
// コピー対象を選択状態にする
var range = document.createRange();
range.selectNode(get_last_html_node(this.parentNode));
window.getSelection().addRange(range);
try {
document.execCommand('copy')
} catch (e) {
// 非対応なら例外が出る Firefox40までなど
alert('copyに失敗しました')
}
// 選択を解除する
window.getSelection().removeAllRanges();
}
// 空のテキストノードを含まないchildrenからラストノードを取得するヘルパー
var get_last_html_node = function (node) {
return node.children[node.children.length - 1]
}
// マウスオーバー処理有効時のみ宣言
if (enable_mouseover) {
var show_button = function() {
get_last_html_node(this).previousSibling.style.visibility = ''
}
var hide_button = function() {
get_last_html_node(this).previousSibling.style.visibility = 'hidden'
}
}
// 全 ``` 記法にコピーボタンをつける(``は対象外)
var code_frames = document.getElementsByClassName('code-frame')
Array.prototype.forEach.call(code_frames, function(item) {
// クローンしないと最後のitemにしか追加されない。trueでアイコンまでクローン
var div_clone = div.cloneNode(true)
// cloneしたものにイベントを登録する必要がある
div_clone.addEventListener('click', copy_code)
// childNodes first・lastChildはtextノードも含み、挿入場所が末尾になる場合があるので、childrenから取得
item.insertBefore(div_clone, get_last_html_node(item))
if(enable_mouseover) {
item.addEventListener('mouseover', show_button)
item.addEventListener('mouseout', hide_button)
}
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment