Qiitaのフィードに記事投稿者の名前を表示するユーザースクリプト

# <i class="fa fa-cubes"></i> 概要

Qiitaのフィード画面で直接には見えない投稿者の名前を表示する。

# <i class="fa fa-cogs"></i> 検証環境

* Firefox 51
* Greasemonkey

# <i class="fa fa-camera"></i> スクリーンショット

![mienai.JPG](https://qiita-image-store.s3.amazonaws.com/0/62354/85b72325-8426-ba90-9533-0ffd006b5024.jpeg)

これが

![mieru.JPG](https://qiita-image-store.s3.amazonaws.com/0/62354/1ef73005-69a7-ba95-560c-430d6ccae29c.jpeg)

こうなる。
タグ名がリンクになるように、ユーザー名もユーザーページのリンクになっている。

![iine.JPG](https://qiita-image-store.s3.amazonaws.com/0/62354/3b6d1010-c92f-8dd3-7eaf-75ca8a679353.jpeg)

![come.JPG](https://qiita-image-store.s3.amazonaws.com/0/62354/82e0cc55-e872-a8da-0df3-ea8d1736a6c1.jpeg)

フォローしている人のいいねとコメントにも対応している。
他に何かあったかな？

# <i class="fa fa-code"></i> コード

Gistスクリプトリンク<i class="fa fa-external-link"></i>[Qiita_show_username_to_feed.user.js]

```js:Qiita_show_username_to_feed.user.js
// ==UserScript==
// @name        Qiita show username to feed
// @namespace   khsk
// @description フィードに投稿者の名前を追加する
// @include     http://qiita.com/
// @include     https://qiita.com/
// @include     http://qiita.com/items
// @include     https://qiita.com/items
// @include     http://qiita.com/stock
// @include     https://qiita.com/stock
// @include     http://qiita.com/mine
// @include     https://qiita.com/mine
// @version     1
// @grant       none
// ==/UserScript==

console.time('show name');
//const FEED_ITEMS = 20; // 一度に読み込むフィード数
const ITEN_CLASS = 'item-box track' // 'item-box track hidden'はおそらく投稿のタグを複数フォローしていたとき、ひとつ以外につけられる。だから、見るたびに同じ記事でもタグ表記が異なるフィードになることがあると思う。

const getUserName = node => {
    const link =  node.querySelector('div.item-box-title > h1 > a');
    return link.href.match(/https?:\/\/qiita.com\/([^/]+)/)[1];
};

const createUserNameNode = parentNode => {

  const userName = getUserName(parentNode);

  const a = document.createElement('a');
  a.href = 'https://qiita.com/' + userName;
  a.innerHTML = ' ' + userName + ' ';

  const span = document.createElement('span');
  // タグ名みたいに太文字にするよ
  span.className = 'user';
  // insertBeforeが面倒くさい
  span.innerHTML = ' ' + a.outerHTML + ' ';

  return span;
}

const insertUserNameNode = (parentNode) => {

  const userNameNode = createUserNameNode(parentNode);
  // 語尾変化 : 挿入前 + 挿入後
  const insertPattarn = {
    'の' : /(に)(新しい投稿がありました)/,
    // いいねと！コメントが！なぜか！spanに！囲まれている！！
    'の投稿に' : /(が)(<span>(?:コメント|いいね)<\/span>しました)/,
    // フォロイーの投稿は別にいいよね。
  };
  const action = parentNode.querySelector('div.item-box-header > div.action');
  if (action == null) {
    return;
  }
  let html = action.innerHTML;
  // ここわかりにくい
  for (let suffix in insertPattarn) {
    let newHtml = html.replace(insertPattarn[suffix], '$1' + userNameNode.outerHTML + suffix + '$2');
    if (newHtml != html) {
      action.innerHTML = newHtml;
      break;
    }
  }
}

const mo = new MutationObserver((mutationRecords, data2) => {

  mutationRecords.forEach(mutationRecord =>{
    if (mutationRecord.addedNodes == null) {
      return;
    }

    // 追加だけでもいろいろ引っかかるので、1フィード読み込み件数をひとつのフィルターにする
    // が、表示後の「n件の新しいアクティビティ」に対応できないと思う。気にしないってときは使う
//     if (mutationRecord.addedNodes.length != FEED_ITEMS) {
//       return;
//     }
    
    mutationRecord.addedNodes.forEach(node => {
      // フィードであることをクラス名でチェック
      if(node.className != ITEN_CLASS) {
        return;
      }
      insertUserNameNode(node);
    });
  });
});

const items = document.getElementsByClassName('col-sm-9')[0];
const options = {childList: true, subtree:true};
mo.observe(items, options);

console.timeEnd('show name');

```

いつも通りですが、成長としては`MutationObserver`で追加されたDOMにだけ処理ができるようになった。

# <i class="fa fa-info-circle" aria-hidden="true"></i> 元ネタ

[Qiita のフィードは投稿者の存在を蔑ろにしていると思うんだ… - Qiita]

## 元記事やスクリプト感想

>僕の Qiita 記事をクリックする人がクリックする前に見ているのは僕の名前やアイコンではなく有名なユーザさんやタグの名前とロゴなのだ。タイトルだけは自分のものだけど。

フィードを漁る身としてはいいね数と有名ユーザーさんを指標にしてたけど、投稿者としてはタイトル勝負と思ってたので自己矛盾に気づいた感じ。

[Qiita のフィードは投稿者の存在を蔑ろにしていると思うんだ… - Qiita コメント:#comment-08b8fd5a940c8926f8c7]

>「誰が書いたか」で記事を取捨選択してほしくないという意図からあのような仕様にしているんだと思っていました。

そうなのかなーと思っていた。
知名度も実績も無い自分のような人の記事は名前で足切りされそうで、名前が出ないからタイトル勝負で開く所まではもって行けるのでは！？と思っていました。

でも単純接触効果ってものもあるし、ちらとでも名前が写らないと無い知名度も高まりませんし。
よく見る名前を覚える覚えもありますし。頑張って投稿していっぱい名前が映れば人の頭の片隅に残るんじゃないかな。
自分は週一投稿で露出しないんですが。

タイトル芸といえば、観測範囲外なのですが@harapeko_wktk のタイトルが印象に残るしちょっと楽しくなるしで、そういったアピールもありなのかなと。

***

今までのフィードに慣れていると投稿者名がでるだけでもごちゃっと感じて、慣れの問題だろうけど、UIのスマートさというか取捨選択もやっぱり大事だなと思いました。

だから、投稿者が(開く前に)分かることの良し悪しはまだわからないので、使っていくかは悩んでるんですけど、選択肢はあってもいいよねって。

# <i class="fa fa-question-circle"></i> ユーザーのアイコンは出ないの？

出ません。
`qiita/ユーザー名/ユーザー名.icon`とかがユーザー画像のaliasとかになってくれていたらよかったんですけど、
現在のイマジネーションではユーザー情報取得→画像URL取得をしなければならず、
APIはリクエスト数制限あるし、
一度に`20(フィード数)*(1(ユーザー情報取得) + 1(アイコン表示))`の40リクエストが読み込むたびに発生するのはダメだろうと。

ただ、一回ずつなら大丈夫だと思うので、タグアイコンにマウスを載せるとユーザーアイコンに切り替わるスクリプトも書いています。
async使っちゃったので、順調なら明日の3/7のFirefox 52で対応されるので来週ぐらいに完成できたらいいなって。

# <i class="fa fa-book"></i> 参考

手前味噌

* [Qiitaのフィードから特定ユーザーの投稿を非表示にするユーザースクリプト - Qiita]
* [MutationRecord - Web API インターフェイス | MDN]


[Qiita のフィードは投稿者の存在を蔑ろにしていると思うんだ… - Qiita]:http://qiita.com/kobake@github/items/9f3406bed89c08052107

[Qiita のフィードは投稿者の存在を蔑ろにしていると思うんだ… - Qiita コメント:#comment-08b8fd5a940c8926f8c7]:http://qiita.com/kobake@github/items/9f3406bed89c08052107#comment-08b8fd5a940c8926f8c7

[Qiitaのフィードから特定ユーザーの投稿を非表示にするユーザースクリプト - Qiita]:http://qiita.com/khsk/items/392ec147c4962caed9ca

[MutationRecord - Web API インターフェイス | MDN]:https://developer.mozilla.org/ja/docs/Web/API/MutationRecord

[Qiita_show_username_to_feed.user.js]:https://gist.github.com/khsk/08b545586899ce263b7eea87986bc764/raw/a01d4bcbae37e14112811578e3a094ed35419f0f/Qiita_show_username_to_feed.user.js