GitHub の Markdown に TOC (目次) を付けるブックマークレット (vanilla JS 編)

# はじめに
皆さん、GitHub で Markdown 読む機会、意外と多いですよね。長い README とか、目次が欲しくなってきます。
そで、kobake@github さんによる [GitHub の Markdown に TOC (目次) を付けるブックマークレット](http://qiita.com/kobake@github/items/3f29a0e20ae4c49e0c81) という記事を以前見つけてありがたく利用していたのですが、どうやら最近 GitHub の各ページから jQuery にアクセスできなくなったようでした。なので、こちらのブックマークレットを vanilla JS で書き直してみました。何か問題・ご意見・ご指摘等があればコメントお願いします！

# Bookmarklet

a. 適当なページをブックマークします
b. URL を以下に変更（コピペ）します

```js:bookmarklet
javascript:(function(){var e=(function(){/*.toc{border: 1px solid #aaa;padding: 4px 12px;margin-bottom: 12px;position: relative;padding-top: 30px;}.toc-title{display: inline-block;width: auto;background-color: #ccc;position: absolute;left: 0px;top: 0px;font-size: 8pt;padding: 2px 4px;padding-right: 8px;color: #666;}.toc-h{font-size: 11pt;}.toc-h1{}.toc-h2{margin-left: 20px;}.toc-h3{margin-left: 40px;}*/}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];var f=document.createElement('style');f.classList.add("toc-style");f.innerHTML='\n'+e+'\n';document.head.appendChild(f);var g=document.createElement('div');g.classList.add('toc');var i=document.createElement('div');i.classList.add('toc-title');i.innerHTML='TOC';g.appendChild(i);var j=document.querySelectorAll('.markdown-body')[0];j.insertBefore(g,j.firstChild);document.querySelectorAll('.markdown-body h1, .markdown-body h2, .markdown-body h3').forEach(function(a){var b=a.tagName.toLowerCase();var c=document.createElement("div");c.classList.add("toc-h");c.classList.add("toc-"+b);var d=document.createElement("a");c.appendChild(d);d.innerHTML="- "+a.childNodes[1].textContent;d.href=a.querySelectorAll('a')[0].href;g.appendChild(c)})})();
```
c. お好みの GitHub の markdown でブックマークを開きます（実行します）
d. ご覧あれ（例は facebook/react の README）

![github-toc.gif](https://qiita-image-store.s3.amazonaws.com/0/103206/aedc8004-4a42-22f0-1628-f622669262e2.gif)


# 圧縮前コード
```js
javascript: (function() {
    var style = (function () {/*
        .toc{
            border: 1px solid #aaa;
            padding: 4px 12px;
            margin-bottom: 12px;
            position: relative;
            padding-top: 30px;
        }
        .toc-title{
            display: inline-block;
            width: auto;
            background-color: #ccc;
            position: absolute;
            left: 0px;
            top: 0px;
            font-size: 8pt;
            padding: 2px 4px;
            padding-right: 8px;
            color: #666;
        }
        .toc-h{
            font-size: 11pt;
        }
        .toc-h1{
        }
        .toc-h2{
            margin-left: 20px;
        }
        .toc-h3{
            margin-left: 40px;
        }
    */}).toString().match(/[^]*\/\*([^]*)\*\/\}$/)[1];

    var styleEl = document.createElement('style');
    styleEl.classList.add('toc-style');
    styleEl.innerHTML = '\n' + style + '\n';
    document.head.appendChild(styleEl);

    var tocDiv = document.createElement('div');
    tocDiv.classList.add('toc');
    var tocTitleDiv = document.createElement('div');
    tocTitleDiv.classList.add('toc-title');
    tocTitleDiv.innerHTML = 'TOC';
    tocDiv.appendChild(tocTitleDiv);

    var markdownBody = document.querySelector('.markdown-body');
    markdownBody.insertBefore(tocDiv, markdownBody.firstChild);

    Array.prototype.forEach.call(document.querySelectorAll('.markdown-body h1, .markdown-body h2, .markdown-body h3'), function(node){
        // level
        var tagName = node.tagName.toLowerCase();

        // link div
        var linkDiv = document.createElement('div');
        linkDiv.classList.add('toc-h');
        linkDiv.classList.add('toc-' + tagName);

        // link
        var aEl = document.createElement('a');
        aEl.innerHTML = '- ' + node.childNodes[1].textContent;
        aEl.href = node.querySelector('a').href;
        linkDiv.appendChild(aEl);

        // append
        tocDiv.appendChild(linkDiv);
    });
})();
```

# 備考
- style はkobake@githubさんのものを流用させていただきました。問題あればコメントお願いします。
- `aEl.innerHTML = "- " + node.childNodes[1].textContent` の部分を調整すれば各見出しの見た目をいじれます。
- querySelectorAll は比較的新しいですが、IE8以上で動くと思います（確認はしてない）
- 動作確認は Chrome だけ行ってます。
- 今後また GitHub 上の構造変化がある可能性もありますので、その際はまたコメント等でお知らせください。

# TODO
- jQuery の remove の部分は条件分岐面倒だったのでスキップしてる。必要なら書く。
- 圧縮前コードを GitHub or Gist に移動します

# history
- querySelectorAll である必要がない部分を querySelector に変更した
- quotation の種類を統一した
- Array.prototype.forEach
- Minify の方法少し変更