日本ではBlogerが不人気なようです。
完全無料、広告表示なし、https標準対応、25年以上継続的に運用されてきたサービスなんですが、日本では使っている人が少ないようです。
とりあえず始めるのは簡単で、カスタマイズしようと思えば知識は必要ですが可能という強力なサービスだと思うのですが利用者は増えていないようです。
カスタマイズも最近でしたら生成AIがあるのでHTMLやCSS、Javascriptもあまり知識がない私のような者でもそこそ出来るようになってきました。
という事で、今回コードブロックの右側にコピーボタンを配置し、クリックするとコードをコピーできる機能を実装してみました。ただし、execCommand については非推奨になりましたので代替案であるHTML5のClipboard API を使用した形で実装したいと思います。
まずはGoogleさんで検索をして幾つかのサイトを参考に実装してみました。
私のサイトではソースの表示にはprettyprintを使っているのですが、linenumsを指定するとうまくコピーできない(1行目だけコピーされる)ようです。
原因は、linenumsを指定するとol、liダグを使って行番号を表示させているのですがこれが原因のようです。
という事でCopilotに指導を仰ぎながら修正したのが以下のコードとなります。
CSS
Blogerのテーマ > マイテーマの「HTML編集」で「]]></b:skin>」の前に以下のCSSを追加して下さい。
pre.prettyprint {
overflow: auto;
word-wrap: normal;
text-align: left;
margin: 0;
}
pre.prettyprint > ol.linenums > li
{
list-style-type: decimal;
margin: 0;
padding: 0;
}
.code-container {
text-align: right;
margin: 0;
}
.copy-button{
font-size: 12px;
padding: 2px 10px;
color: #fff;
background-color: #444;
border: none;
cursor: pointer;
transition: background-color 0.3s ease;
}
.copy-button:hover{
background: #999
}
pre code{
display: block;
margin: 0;
padding: 2px 5px;
line-height: 1;
overflow: auto;
color: #f8f8f8;
}
Javascript
同じく、「/body」の直前に以下のコードを追加して下さい。
<script>//<![CDATA[
// コピーボタン作成用コード
(function(d){
const pres = d.querySelectorAll('pre.prettyprint');
if(pres.length == 0){
return;
}
pres.forEach(function(pre) {
// コード(pre)とCopyボタンを収容するdiv作成(Copyボタンにprettyprintの影響が及ばないようにする為)
const div = d.createElement("div");
div.className = "code-container";
// Copyボタンを生成してdivに追加(子の先頭)
const btn = d.createElement('button');
btn.className = 'copy-button';
btn.textContent = 'copy';
div.appendChild(btn);
btn.addEventListener('click', copy_code, false);
// コード(pre)の親にdivを追加
pre.parentNode.insertBefore(div, pre);
// コード(pre)を現在の親からdivの子の末尾へ移動)
div.appendChild(pre);
});
})(document);
// コピー機能用コード
function copy_code(){
const pre = this.nextElementSibling;
let code;
if(pre.classList.contains('linenums')){
code = [ ... pre.querySelectorAll('li')]
.map(li => li.textContent)
.join('\n');
} else{
code = pre.textContent;
}
if(navigator.clipboard){
navigator.clipboard.writeText(code).then(() => {
this.textContent = 'Copied';
setTimeout(() => {
this.textContent = 'Copy';
}, 500);
}).catch(e => {
alert('コピーできませんでした\nお手数ですが手動でコピーしてください\n\n' + e.message);
});
} else{
alert('このブラウザは Clipboard API 非対応です\nお手数ですが手動でコピーしてください');
}
}
//]]></script>
あとはprettyprintを使ってコードを埋め込めば、自動的にCopyボタンが追加されます。
今回参考にさせていただいたサイト
・コードブロックにコピーボタンを実装する(Clipboard API 対応版)
・Bloggerでコードをきれいに表示する方法-copy機能の追加