TampermonkeyでTwitterの画像URLを元に戻した

技術

この記事は2019年1月24日に書かれたものです。ご注意ください。

ある日のこと…
      
      

      
      

      
      

      
      

      
      
キレそう

はい。ということでね、Twitterのデザインを新しくしたら、今まで

https://pbs.twimg.com/media/DxrfR_RVsAA05-e.jpg:orig

という画像URLが

https://pbs.twimg.com/media/DxrfR_RVsAA05-e?format=jpg&name=small:orig

に変わっていたので、Tampermonkeyで修正してきました。結構無理矢理です。

コード

// ==UserScript==
// @name         Twitterの画像URLを変える
// @namespace    https://twitter.com/
// @version      1.0.0
// @description  media/334?format=jpg&name=900x900 => media/334.jpg:orig
// @author       micelle
// @match        https://twitter.com/*
// @require      https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// @grant        none
// ==/UserScript==
(function() {
  const observer = new MutationObserver(records => {
    $('div[aria-label^="タイムライン"] > div > div > div, div[aria-label^="Timeline"] > div > div > div').each((divIndex, divElm) => {
      $(divElm).find('img[alt="画像"], img[alt="Image"]').each((imgIndex, imgElm) => {
        const src = $(imgElm).attr('src');
        const rep = src.replace(/\?format=/, '.').replace(/&name=.+/, ':orig');
        $(imgElm).attr('src', rep);
      });
    });
  });
  const target = $('#react-root').get(0);
  const option = {
    childList: true,
    subtree: true
  }
  observer.observe(target, option);
})();

解説

今回はMutationObserverでDOMの変化を取得しています。TLを下にスクロールしたり上にスクロールしたり、動かすとDOMが変化するので利用しています。setTimeoutとか使うヤツはダサダサだぞ!!(,, ՞ਊ ՞)=☞)՞ਊ ՞)
MutationObserverについては下の記事をコピペしてきました。とてもわかりやすい(昔は理解できなかったゾ)。

監視の停止とか今回は不要なので削除(してよかったのかな?)。
監視オプションは孫まで見たいのでsubtree: trueを設定。
ターゲットは適当に$('#react-root').get(0);を設定。ちなみに.get(0)を使わないと(たしか)jQueryのオブジェクトになっちゃうので注意!今回はDOM欲しいからね。

const observer = new MutationObserver(records => {
  // なにか処理
});
const target = $('#react-root').get(0);
const option = {
  childList: true,
  subtree: true
}
observer.observe(target, option);

↑これでDOMが変化したら=ツイートが読み込まれたり表示されたら諸々処理できるようになったよ。

各ツイートの要素は

$('div[aria-label^="タイムライン"] > div > div > div, div[aria-label^="Timeline"] > div > div > div').each((divIndex, divElm) => {
  // なにか処理
});

で1つ1つ取得できます。セレクタがちょっとアホみたいだけど許してヒヤシンス ʅ(;◔౪◔)ʃ
ちなみにaria-labelの中身はTLだとタイムライン: ホームタイムラインで、ユーザーのプロフィールではタイムライン: (ᐛ)みせる?バーチャル鹿erさんのツイートだよ。
なお英語だとTimeline: Your Home TimelineTimeline: (ᐛ)みせる?バーチャル鹿er’s Tweetsになっちゃうので、日英以外の言語使ってたらココ変えてね?(セレクタとしては完全にダメじゃん…w)(ある程度網羅させて現在の言語設定をみてからココを設定…とかでもいいかもだけど面倒だし、みりあやんないよ)

まぁそんなこんなで各ツイートの要素を取ってきたら

$(divElm).find('img[alt="画像"], img[alt="Image"]').each((imgIndex, imgElm) => {
  const src = $(imgElm).attr('src');
  const rep = src.replace(/\?format=/, '.').replace(/&name=.+/, ':orig');
  $(imgElm).attr('src', rep);
});

srcの中身を書き換えてあげます。

いじょう!!!!!

最後にやさしく無名関数で囲ってあげておきました。意味ないかも。

Twitter新しくなってからClassバカじゃないです??????
気持ち悪くて仕方が無いです。(たぶんシステムのせい。きっとせいのみだれ。ごまだれ^-^)

(あ、これシラフで書きました。わけわかんねえ…)