2018/02 : 更新
1) 行番号部分をクリックするとソースを選択するようにしました。
2) 表示時にテキストエリアにフォーカスを移すようにしました。
3) コピー操作をしやすいように、テキストエリア内に padding-left を入れました。
4) ツールバーの不透明度を 0.5 => 0.8 に変更しました。
5) ツールバーに対する border の CSS を変更して見えやすくしました。
そもそも、SyntaxHighlighter を配布していたサイトが GitHub に移った上、バージョン4 になってるけれど、いろいろ一般的には面倒な事になってるので、古いバージョンを一生懸命使って来た... というのが現実でした。
しかし、ここに来て行単位を取り出す『ソースの表示』がしょぼい事や、クリップボードへコピーするのが Flash だったとか、印刷表示ができていない(理由は解ったので対応済み)とか、about のリンク先が終わってるとか、ロクでも無い現状を打破しました。
これらは、オリジナルの処理を書き換えるという方法で行ってます。マイナーバージョンが上がった際にあった shLegacy.js というスクリプトで実装できます。解る人はこのサイトのソースを見てもらってコピーすれば使えます。但し、ウチのバージョンは 2.0.296 なんで、世の中的には難しいでしょうけれど。
ありがたいことに、WEB アーカイブからダウンロードできました。
※ 他のバージョンも可能です。
※ ライセンスは GNU Lesser General Public License
ソースの表示
行番号対応しました。これは、JQuery Lined TextArea plugin というプラグイン使ってます。行番号だけあれば十分なので、既に開発も終わってる古いソフトですが、 MIT License だしソースは短いし、自分でどうにでもアップグレードできそうなので使う事にしました。
▼ ウインドウを最大化した時に行番号を表示するという処理を、jquery-linedtextarea.js の中に追加しています( ソースはこれです )
$(window).resize( function(){
var domTextArea = textarea[0];
var scrollTop = domTextArea.scrollTop;
var clientHeight = domTextArea.clientHeight;
codeLinesDiv.css( {'margin-top': (-1*scrollTop) + "px"} );
lineNo = fillOutLines( codeLinesDiv, scrollTop + clientHeight, lineNo );
});
ただ、textarea を使うので、ウインドウを最大化した時の幅や高さの調整は自分で外から追加する必要がありました。
▼ 組み込んだ内容
SyntaxHighlighter.toolbar.items.viewSource = function(highlighter)
{
this.create = function()
{
return "\u884c\u756a\u53f7\u4ed8\u304d\u30c6\u30ad\u30b9\u30c8\u30a8\u30ea\u30a2\u3067\u30bd\u30fc\u30b9\u3092\u8868\u793a\u3057\u307e\u3059";
};
this.execute = function(sender, event, args)
{
var wnd = SyntaxHighlighter.utils.popup('', '_blank', 750, 400, 'location=0, resizable=1, menubar=0, scrollbars=1')
;
var code = SyntaxHighlighter.utils.unindent(
SyntaxHighlighter.utils.fixForBlogger(highlighter.originalCode)
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/&/g, '&')
.replace(/\n/g, '\n')
);
code = SyntaxHighlighter.utils.unindent(code);
var str="";
str+="<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> ";
str+="<"+"script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js\"></"+"script> \n";
str+="<"+"script src=\"https://lightbox.sakura.ne.jp/homepage/jquery/plugins/jquery-linedtextarea.js\"></"+"script> \n";
str+="<link id=\"link\" rel=\"stylesheet\" href=\"https://lightbox.sakura.ne.jp/homepage/jquery/plugins/jquery-linedtextarea.css\"> \n";
wnd.document.write(str);
wnd.document.write('<t'+ 'extarea readonly style="width:100%;height:350px">' + code + '</' + 'textarea>');
str="";
str+="<"+"script> \n";
str+="$(function() { \n";
str+=" $(\"textarea\").linedtextarea(); \n";
str+=" $(\".linedwrap\").css({\"width\":\"calc(100% - 20px\"}); \n";
str+=" $(\".lines\").css({\"height\":\"calc(100% - 20px)\"}); \n";
str+=" $(\"textarea\").css({\"width\":\"calc(100% - 80px)\", \"padding-left\":\"10px\"}); \n";
str+=" $(\"textarea\").css({\"height\":\"calc(100% - 20px)\"}); \n";
str+=" $(\"head\").append($(\"<title>\").text(\"\u30bd\u30fc\u30b9\u306e\u8868\u793a\")); \n";
str+=" $(\".codelines\").on(\"click\", function(){ $(\"textarea\").select() } ); \n";
str+=" $(\"textarea\").focus(); \n";
str+="}); \n";
str+="</"+"script> ";
wnd.document.write(str);
wnd.document.close();
};
};
何も無いところに動的にいろいろやる必要があるので、document.write は仕方無いので使っています。
document.write だけに関して言えば、将来性はそのへん疑問はありますが、当面しばらく大丈夫だと思ってます。
内容としては、動的に jQuery を書き出して、さらに jQuery のコードも書き出す事になってます。
高さと幅の調整は jQuery の部分の、本体とその親要素に対して calc を使って 100% から補正するというテクニックでやっています。
▼ 補正部分のみ取り出すとこうなります
<script>
$(function() {
$("textarea").linedtextarea();
$(".linedwrap").css({"width":"calc(100% - 20px"});
$(".lines").css({"height":"calc(100% - 20px)"});
$("textarea").css({"width":"calc(100% - 80px)"});
$("textarea").css({"height":"calc(100% - 20px)"});
$("head").append($("<title>").text("ソースの表示"));
$(".codelines").on("click", function(){ $("textarea").select() } );
$("textarea").focus();
});
</script>
次は、クリップボードのお話です
自サイト(logical error を含む)で使用している SyntaxHighlighter のツールバーの問題点をごっそり自前で修正・カスタマイズしました。( その2 / ソースをクリップボードにコピー )
以下は、一般的なコードサンプルになります
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script>
$(function(){
$("#open_window").on("click", function(){
code = $("#code").val();
var wnd = win_open("","_blank",750, 400, "location=0,resizable=1,menubar=0,scrollbars=1");
var str="";
str+="<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"> ";
str+="<"+"script src=\"https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js\"></"+"script> \n";
str+="<"+"script src=\"https://lightbox.sakura.ne.jp/homepage/jquery/plugins/jquery-linedtextarea.js\"></"+"script> \n";
str+="<link id=\"link\" rel=\"stylesheet\" href=\"https://lightbox.sakura.ne.jp/homepage/jquery/plugins/jquery-linedtextarea.css\"> \n";
wnd.document.write(str);
wnd.document.write('<t'+ 'extarea readonly style="width:100%;height:350px">' + code + '</' + 'textarea>');
str="";
str+="<"+"script> \n";
str+="$(function() { \n";
str+=" $(\"textarea\").linedtextarea(); \n";
str+=" $(\".linedwrap\").css({\"width\":\"calc(100% - 20px\"}); \n";
str+=" $(\".lines\").css({\"height\":\"calc(100% - 20px)\"}); \n";
str+=" $(\"textarea\").css({\"width\":\"calc(100% - 80px)\", \"padding-left\":\"10px\"}); \n";
str+=" $(\"textarea\").css({\"height\":\"calc(100% - 20px)\"}); \n";
str+=" $(\"head\").append($(\"<title>\").text(\"\u30bd\u30fc\u30b9\u306e\u8868\u793a\")); \n";
str+=" $(\".codelines\").on(\"click\", function(){ $(\"textarea\").select() } ); \n";
str+=" $(\"textarea\").focus(); \n";
str+=" $(\"body\").css({\"overflow-y\":\"y:hidden\"}); \n";
str+="}); \n";
str+="</"+"script> ";
wnd.document.write(str);
wnd.document.close();
});
});
function win_open(url, name, width, height, options) {
var x = (screen.width - width) / 2;
var y = (screen.height - height) / 2;
options +=
', left=' + x +
', top=' + y +
', width=' + width +
', height=' + height
;
// 先頭のカンマを取り除く
options = options.replace(/^,/, '');
var win = window.open(url, name, options);
win.focus();
return win;
}
</script>
<input id="open_window" type="button" value="window を開く">
<br>
<textarea id="code" style='width:400px;height:300px'></textarea>