LoginSignup
13
6

More than 5 years have passed since last update.

Qiita スライドを Chrome 拡張で改善してみる

Last updated at Posted at 2017-06-29
1 / 11

Qiita のスライド

Qiita にはスライドビュー機能があります。
これを使えば Qiita の記事書きと、LTなどの発表で同じものが使えて非常に効率が良いですが、実際には機能が足りず、本番で使うには辛いものがあります。
そこで、足りない機能を全て Chrome 拡張で作ってみましたので、その作り方とともに公開します。

Chrome 拡張を通じてどのような修正を行うことで、改善が達成されるものなのか、参考にしてください。
また、この Chrome拡張も、そのソースも一般公開します。

なお、この Chrome 拡張では、jQuery v2 にくわえ、 ChEx.js という自作の秘伝のタレを使ってます。


Chrome拡張の置き場所

とりあえず入れて試したい方はこちらから入れてみてください。
https://chrome.google.com/webstore/detail/qiita-slide-%E6%94%B9/cgnhlhefahcojhfdoobggpdhpjcgfodc

(ソースコード全体は現在準備中です。近々公開します。)


1. で強調したい

image.png

Qiita のスライドでは強調部分が単色で、強調が伝わりづらいですね。
そこで、**~***~* の部分に色がつくようにします。

$('body').append(`<style>
    .slide_preview.markdownContent strong { color: red; }
    .slide_preview.markdownContent em { color: blue; font-style: normal; font-weight: bold; }
</style>`);
  • body<style>~</style> を足すことで全体的に効くスタイルを追加してます。
  • この追加では既存の DOM のスタイルは変わってくれませんが、今後、新規に追加される DOM はすべてこの影響を受けることになります。
  • .slide_preview.markdownContent は Slide の外枠で、この中にある strongem の色を変えています。

2. カーソルを大きくしたい

image.png

カーソルつかって「ここです」と示しても、カーソル小さすぎて伝わりません。
そこで、 B キーで、カーソルを巨大化したり、もとに戻したりできるようにしましょう。

$('body').append(`<style>
    .slide_preview.markdownContent.chex-big-cursor,
    .slide_preview.markdownContent.chex-big-cursor pre {
        cursor: url(https://waterada.github.io/chrome-ex-qiita/big-cursor.png), auto;
    }
</style>`);
ChEx.keydown('B', '大きなカーソル', () => {
    $('.slide_preview.markdownContent').toggleClass('chex-big-cursor');
});
  • ChEx.keydown() という秘伝のタレを使っています。これで B を押した場合に chex-big-cursor がトグルするようにしてます。
  • ChEx.keydown() の中では色々やってるのですが、要するに下記をやりたいのです。
$(document).keydown(function (e) {
    if (e.which === 'B') {
        $('.slide_preview.markdownContent').toggleClass('chex-big-cursor');
    }
});
  • cursor というスタイルを使ってカーソルを変えることができますが、普通大きさは変えられません。ですが画像は指定できますので、大きな画像を指定することで大きくしています。

3. 行番号オン/オフ

image.png

コードの説明の際に行番号が欲しくなるときがあります。
L キーで行番号のオン/オフできるようにしましょう。

ChEx.keydown('L', '行番号オン/オフ', () => {
    let $preList = $('.slide_preview.markdownContent').find('pre');
    ChEx.toggle('lineNum', () => {
        $preList.each(function () {
            let $pre = $(this);
            let html = $pre.html();
            let i = 1;
            html = html.trim().replace(/^/gm, () => {
                return `<span class="chex-line-num">${ChEx.padding(i++, 3)}| </span>`;
            });
            $pre.html(html);
        });
    }, () => {
        $preList.find('.chex-line-num').remove();
    });
});
  • ChEx.toggle() は2つのコールバックを呼び出すたびに交互に実行してくれる便利関数です。
  • ChEx.padding() は数値のパディングをする便利関数です。
  • 置換正規表現 /^/gmm フラグは見慣れないかもしれません。m があると、^ は各行の先頭にヒットするようになります。
  • 現状、各行ごとに実際に改行されているので、先頭に連番の HTML を差し込んでいます。

4. 範囲選択エリアを黄色に

image.png

範囲選択して示してみても、デフォルトの色ではあまり目立ちません。
色を黄色マーカーっぽくしましょう。

$('body').append(`<style>
    .slide_preview.markdownContent ::selection { background: yellow; color: black; }
    .slide_preview.markdownContent .chex-line-num::selection { background: #f7f7f7; color: black; }
</style>`);
  • ::selection というセレクタを指定することで色を変えられます。
  • .chex-line-num::selection も指定しているのは、上記で行番号を表示してる場合、番号部分は色を変えたくなかったからです。

5. スライドコントローラのオン/オフ

image.png
↑スライドコントローラ

消して画面大きく見せたいとき、ありますね。

ChEx.keydown('Q', 'スライドコントローラのオン/オフ', () => {
    $('.slide_controller').toggle();
});

6. keydown のヘルプ表示

image.png

keydown で仕込んだキー、忘れてしまうことがあるので、H キーでヘルプがでるようにしましょう。

ChEx.keydownHelp('H', $('.slide_preview.markdownContent').position());
  • ChEx.keydown() を使っていれば、勝手にヘルプ用のテキストを作り上げてくれます。
  • $('.slide_preview.markdownContent').position() はヘルプ枠の表示位置を決める際の基準となる位置です。

7. h1で改行する

ページ内に h1 しかない場合、スライドだと、大きな文字で中央寄せで表示されるのですが、改行はできません。
そこで、半角スペース2つを書くことで改行されるようにします。

//h1で半角スペース2つなら改行
$('body').append(`<style>
    /* チラツキ防止のため初め非表示 */
    .slide_preview.markdownContent h1 { display: none; }
    .slide_preview.markdownContent .slide_preview_firstSlide h1 { display: block; }
</style>`);
ChEx.onChangeDom($('.slide_preview.markdownContent'), function () {
    $('.slide_preview.markdownContent').find('h1').each(function () {
        let $h1 = $(this);
        $h1.html($h1.html().replace(/ {2}/g, '<br/>')).show();
    });
});
  • ChEx.onChangeDom() は特定の DOM ノード以下で DOM の変更があった場合にイベントが発火するという便利関数です。
  • 実際にやってることを簡潔に書くと次のようになります。
ChEx.onChangeDom = function ($root, callback) {
    let timeoutId = 0;
    $root.on("DOMNodeInserted DOMSubtreeModified", function () {
        if (timeoutId) return true; //動いていたらやらない
        timeoutId = setTimeout(function () {
            try {
                callback();
            } finally {
                timeoutId = 0;
            }
            return true;
        }, 100);
    });
};
  • DOMNodeInsertedDOMSubtreeModified というイベントにハンドラを設定しているのがわかると思います。
  • このイベントは連続的に発生することが多いので、0.1秒ほど落ち着くのを待ってから発火させてます。待ってる間に発生するイベントは全て捨てちゃいます。最後の状態で1回だけ発火すれば良いので。
  • なぜ DOM の変更を監視してるのかというと、スライドの各ページは表示時に毎回、メモリ上に持っている情報をベースに生成されているためです。onLoad 完了後に DOM にあるものを書き換えても、ページに表示されるものは書き換わらないのです。
  • replace(/ {2}/g, '<br/>') で空白2個を改行に変えてます。
  • 最初に display: none; してるのは、表示後に書き換えることになるので、改行前の文字列が一瞬表示されて美しくないからです。

最後に

2017-08-05(土) に builderscon tokyo というイベントで 「Chrome拡張を使って様々なWebサービスをハックする」 というネタで登壇します。
https://builderscon.io/tokyo/2017/session/9e8711fb-7f56-44ea-b550-0d48ff756e1d

image.png

ご興味ある方がいらっしゃいましたら、ぜひとも聞きにきてください。

13
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
6