誕生日

greasemonkeyスクリプトの新ネタが思いつかないので、日記を書くことでお茶を濁しておきたい。テーマはランダムで決めるものとした。自分で決めたところで、私の力量ではどうなるものでもない。ならば運を天に任せてみようという趣向である。フォロワーのツイートから選ぼうと思ったのだが、API制限のせいかどうもそういうwebサービスが見当たらなかった。どのみち私がフォローしているアカウントは既に3000を超え、カオスの一言に尽きる。ならば完全に無作為のアカウントから選んでも変わりないだろうと思い、以下のサイトを使用した。
random tweet -- see what the world is thinking

結果選ばれたツイートがこれである。モニターの向こう側とテンションの落差がすごいな

テーマは誕生日としたが、あまりいい思い出はない。学生時代から社会性を置き去りにした私では既に限界を迎えつつある。毎日が誕生日というのはその時点で矛盾を抱えているのではないだろうか。水商売で働く女性の一部は誕生日が複数あるという話を聞いたことがあるが、流石に毎日というわけではあるまい。そもそもとみーさんが誰か知らない。実在人物かどうかさえ知らない人間の誕生日を祝うのはいささか辛いものがある。その上でなお、素直に祝うべきだろうか。親の誕生日だってろくに祝ったことのない人間がここだけ祝うというのもおかしな話ではないだろうか。祝えと言われれば祝うが、心の奥底における煩悶がどこか消えない。しかしやはり、ここは祝うべきだろう。すべて私の個人的な事情なのだから。おめでとうございます。

ここまで読まれた方は意外に思われるかもしれないが、クリスマスというイベントを否定する気はない。祝いたい人間は素直に祝えばいいだけの話だ。ケーキも嫌いではない。むしろ成人男性としては好きな部類に入る。性行為をしたい人間はすればいい。ほんの一瞬その手のイベント行為の際に流れに乗れない、私のような不器用な人間もいるという事実を頭の片隅においていただければ幸いです。構わず放置しておけばただ一人、静かに歳を重ねるだけの話である。

Twitterで今日の予定をメモ

このスクリプトFirefoxで動作を保証しないものとします
let.hatelabo.jp

// ==UserScript==
// @name         twitter_date
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://twitter.com/*
// @grant        none
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
// @require      http://momentjs.com/downloads/moment.js
// ==/UserScript==
var result2 = document.evaluate('id("global-new-tweet-button")', document, null, 7, null);
result2.snapshotItem(0).insertAdjacentHTML('afterend', '<input type="button" value="メモ" id="task_list">');
var result3 = document.evaluate('id("task_list")', document, null, 7, null);
result3.snapshotItem(0).addEventListener('click', sample, false);

function sample() {
  localStorage.setItem("n_url", location.href);
  history.pushState(null, null, "/koko_nanimo_naidesuyo4");
  window.addEventListener('beforeunload', function (e) {
    e.returnValue = '本当に移動してよろしいですか?';
  }, false);
  var now = moment();
  var d_week = now.format("ddd");
  d_week = d_week.replace("Sun", "日");
  d_week = d_week.replace("Mon", "月");
  d_week = d_week.replace("Tue", "火");
  d_week = d_week.replace("Wed", "水");
  d_week = d_week.replace("Thu", "木");
  d_week = d_week.replace("Fri", "金");
  d_week = d_week.replace("Sat", "土");
  document.body.innerHTML = "<div><span>" + now.format("M月D日") + "</span><span>(" + d_week + ")</span></div>";
  if (!('draft2' in localStorage)) {
    document.body.insertAdjacentHTML("beforeend", "<textarea>戻るボタンなどのブラウザバックで元のページに戻ります</textarea><br>");
  } else {
    document.body.insertAdjacentHTML("beforeend", "<textarea>" + localStorage.getItem('draft2') + "</textarea><br>");
  }
  document.body.insertAdjacentHTML("beforeend", "<div><div><input type='button' value='save'><input type='button' value='load'><a href='https://www.jma.go.jp/jp/yoho/'>天気</a><a href='https://tv.so-net.ne.jp/'>TV</a></div></div>");
  var result = document.evaluate('//input', document, null, 7, null);
  result.snapshotItem(0).addEventListener('click', sample2, false);
  result.snapshotItem(1).addEventListener('click', sample3, false);

  function sample2() {
    var result4 = document.evaluate('//textarea', document, null, 7, null);
    localStorage.setItem('draft2', result4.snapshotItem(0).value);
  }

  function sample3() {
    var result4 = document.evaluate('//textarea', document, null, 7, null);
    var draft2 = localStorage.getItem('draft2');
    result4.snapshotItem(0).value = draft2;
  }
  var result5 = document.evaluate('//textarea/following-sibling::div', document, null, 7, null);
  result5.snapshotItem(0).style.width = "15%";
  result5.snapshotItem(0).classList.add("t_after");
  $('.t_after>div').css({
    "display": "flex",
    "justify-content": "space-between"
  });
  window.addEventListener('popstate', function (event) {
    location.href = localStorage.getItem("n_url");
  });
}

YoutubeでURLメモ用のテキストエリアを表示

このスクリプトFirefoxで動作を保証しないものとします
let.hatelabo.jp

// ==UserScript==
// @name         youtube2hatena
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.youtube.com/*
// @grant        none
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
// ==/UserScript==
var result2 = document.evaluate('id("search-form")', document, null, 7, null);
result2.snapshotItem(0).insertAdjacentHTML('afterend', '<input type="button" value="メモ" id="draft">');
$(function () {
  $('#draft').click(function () {
    localStorage.setItem("n_url", location.href);
    history.pushState(null, null, "/channel/");
    document.body.innerHTML = "";
    if (!('draft' in localStorage)) {
      document.body.insertAdjacentHTML("beforeend", "<textarea>戻るボタンなどのブラウザバックで元のページに戻ります</textarea><br><input type='button' value='save'><input type='button' value='load'><input type='button' value='hatena'>");
    } else {
      document.body.insertAdjacentHTML("beforeend", "<textarea>" + localStorage.getItem('draft') + "</textarea><br><input type='button' value='save'><input type='button' value='load'><input type='button' value='hatena'>");
    }
    var result2 = document.evaluate('//input', document, null, 7, null);
    result2.snapshotItem(0).addEventListener('click', sample, false);
    result2.snapshotItem(1).addEventListener('click', sample2, false);
    result2.snapshotItem(2).addEventListener('click', sample3, false);

    function sample() {
      var result3 = document.evaluate('//textarea', document, null, 7, null);
      localStorage.setItem('draft', result3.snapshotItem(0).value);
      alert("保存しました");
    }

    function sample2() {
      var result3 = document.evaluate('//textarea', document, null, 7, null);
      var draft = localStorage.getItem('draft');
      result3.snapshotItem(0).value = draft;
      alert("ロードしました");
    }

    function sample3() {
      var result3 = document.evaluate('//textarea', document, null, 7, null);
      var r1 = /https\:\/\//gi;
      var r2 = /(\[.+)\n/gi;
      var r3 = /\&t\=\d+s/gi;
      result3.snapshotItem(0).value = result3.snapshotItem(0).value.replace(r1, '[https://');
      result3.snapshotItem(0).value = result3.snapshotItem(0).value.replace(r2, '$1:embed:cite]\n');
      result3.snapshotItem(0).value = result3.snapshotItem(0).value.replace(r3, '');
      alert("はてな記法に置き換えました");
    }
    window.addEventListener('popstate', function (event) {
      location.href = localStorage.getItem("n_url");
    });
  }, );
});

Twitterのツイートをはてなブログに埋め込む形式でリストを表示

このスクリプトFirefoxで動作を保証しないものとします
let.hatelabo.jp

// ==UserScript==
// @name         twitter2hatena
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://twitter.com/*/status/*
// @grant        none
// ==/UserScript==
var result = document.evaluate('//div[@class="ProfileTweet-actionList js-actions"]', document, null, 7, null);
result.snapshotItem(0).insertAdjacentHTML('beforeend', '<input type="button" value="登録" id="regist2">');
var result2 = document.evaluate('id("regist2")', document, null, 7, null);
result2.snapshotItem(0).addEventListener('click', sample, false);

function sample() {
  for (var i = 0; i < 128; i++) {
    if (!('tweet' + (i + 1) in localStorage)) {
      if (i == 127) {
        alert("保存できるURLの数は128までに制限しています。\nローカルストレージから登録したキーを削除してください");
        break;
      }
      var cb = list_check(i + 1, location.href);
      if (cb != 1) {
        localStorage.setItem('tweet' + (i + 1), location.href);
        alert("登録しました");
        break;
      } else {
        break;
      }
    }
  }
  //重複削除
  function list_check(lp, n_name) {
    var flag = 0;
    for (var i = 0; i < lp; i++) {
      if (localStorage.getItem('tweet' + (i + 1)) == n_name) {
        alert("このツイートは既に登録されています");
        flag = 1;
        break;
      }
    }
    return flag;
  }
}
//リスト表示処理
var result4 = document.evaluate('//div[@class="ProfileTweet-actionList js-actions"]', document, null, 7, null);
result4.snapshotItem(0).insertAdjacentHTML('beforeend', '<input type="button" value="リスト" id="list2">');
var result5 = document.evaluate('id("list2")', document, null, 7, null);
result5.snapshotItem(0).addEventListener('click', sample2, false);

function sample2() {
  localStorage.setItem("n_url", location.href);
  history.pushState(null, null, "/koko_nanimo_naidesuyo3");
  document.body.innerHTML = "";
  for (var i = 0; i < 128; i++) {
    if ('tweet' + (i + 1) in localStorage) {
      document.body.insertAdjacentHTML('beforeend', '<div>[' + localStorage.getItem('tweet' + (i + 1)) + ':embed]</div>');
    } else {
      break;
    }
  }
  window.addEventListener('popstate', function (event) {
    location.href = localStorage.getItem("n_url");
  });
}

SPOTで記事を探しやすくする

let.hatelabo.jp

// ==UserScript==
// @name         spot_search
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://travel.spot-app.jp/*
// @grant        none
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
// @require      http://momentjs.com/downloads/moment.js
// ==/UserScript==
var result6 = document.evaluate('//ul[@class="nav_list"]', document, null, 7, null);
result6.snapshotItem(0).insertAdjacentHTML('beforeend', '<input type="button" id="last_visit" value="訪問確認">');
var result8 = document.evaluate('id("last_visit")', document, null, 7, null);
result8.snapshotItem(0).addEventListener('click', function () {
  var now = moment();
  if (!('last_visit' in localStorage)) {
    localStorage.setItem('last_visit', now);
    alert("現在の時刻をローカルストレージに書き込みました");
  } else {
    if (now.diff(localStorage.getItem('last_visit'), 'days') != 0) {
      alert(now.diff(localStorage.getItem('last_visit'), 'days') + "日前に訪れています");
      localStorage.setItem('last_visit', now);
    } else {
      alert("今日訪れました");
      localStorage.setItem('last_visit', now);
    }
  }
});
result6.snapshotItem(0).insertAdjacentHTML('beforeend', '<select id="pref_name"><option value="">都道府県</option><option value="北海道">北海道</option><option value="青森県">青森県</option><option value="岩手県">岩手県</option><option value="宮城県">宮城県</option><option value="秋田県">秋田県</option><option value="山形県">山形県</option><option value="福島県">福島県</option><option value="茨城県">茨城県</option><option value="栃木県">栃木県</option><option value="群馬県">群馬県</option><option value="埼玉県">埼玉県</option><option value="千葉県">千葉県</option><option value="東京都">東京都</option><option value="神奈川県">神奈川県</option><option value="新潟県">新潟県</option><option value="富山県">富山県</option><option value="石川県">石川県</option><option value="福井県">福井県</option><option value="山梨県">山梨県</option><option value="長野県">長野県</option><option value="岐阜県">岐阜県</option><option value="静岡県">静岡県</option><option value="愛知県">愛知県</option><option value="三重県">三重県</option><option value="滋賀県">滋賀県</option><option value="京都府">京都府</option><option value="大阪府">大阪府</option><option value="兵庫県">兵庫県</option><option value="奈良県">奈良県</option><option value="和歌山県">和歌山県</option><option value="鳥取県">鳥取県</option><option value="島根県">島根県</option><option value="岡山県">岡山県</option><option value="広島県">広島県</option><option value="山口県">山口県</option><option value="徳島県">徳島県</option><option value="香川県">香川県</option><option value="愛媛県">愛媛県</option><option value="高知県">高知県</option><option value="福岡県">福岡県</option><option value="佐賀県">佐賀県</option><option value="長崎県">長崎県</option><option value="熊本県">熊本県</option><option value="大分県">大分県</option><option value="宮崎県">宮崎県</option><option value="鹿児島県">鹿児島県</option><option value="沖縄県">沖縄県</option></select> ');
var result7 = document.evaluate('id("pref_name")', document, null, 7, null);
result7.snapshotItem(0).addEventListener('change', function () {
  var selectedValue = $("#pref_name").val();
  location.href = "https://travel.spot-app.jp/category/" + selectedValue + "/";
});
result6.snapshotItem(0).insertAdjacentHTML('beforeend', '<input type="button" id="sub_search" value="記事検索">');
document.getElementById("sub_search").addEventListener('click', function () {
  var s_word = window.prompt("検索ワードを入力してください", "");
  if (s_word != null) {
    location.href = "https://travel.spot-app.jp/?s=" + s_word;
  }
});
.n_author a {
  font-size: 12px !important;
  color: #444444;
}

#header .header_nav {
  letter-spacing: 0;
}

.header_nav .nav_item a {
  margin: 0 10px;
}

#header .header_nav .nav_list {
  max-width: none;
}

.loop-content-frame {
  opacity: 1;
}

登録したTwitterのアカウントをリストで表示

このスクリプトFirefoxで動作を保証しないものとします
let.hatelabo.jp

// ==UserScript==
// @name         twitter_acc_list
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://twitter.com/*
// @grant        none
// @require      http://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js
// ==/UserScript==
//登録処理
var result2 = document.evaluate('id("global-new-tweet-button")', document, null, 7, null);
result2.snapshotItem(0).insertAdjacentHTML('afterend', '<input type="button" value="登録" id="regist">');
var result3 = document.evaluate('id("regist")', document, null, 7, null);
result3.snapshotItem(0).addEventListener('click', sample, false);

function sample() {
  var result = document.evaluate('//link[@rel="canonical"]', document, null, 7, null);
  var n_str = result.snapshotItem(0).href + "/";
  var n_arr = n_str.split("/");
  var acc = n_arr[3];
  if (acc.length == 0) {
    acc = "home_kokokara_hajimaruyo";
  }
  for (var i = 0; i < 128; i++) {
    if (!('user' + (i + 1) in localStorage)) {
      if (i == 127) {
        alert("保存できるURLの数は128までに制限しています。\nローカルストレージから登録したキーを削除してください");
        break;
      }
      var cb = list_check(i + 1, acc);
      if (cb != 1) {
        localStorage.setItem('user' + (i + 1), acc);
        var memo_ran = window.prompt("コメントは何かありますか?", "");
        localStorage.setItem(acc, memo_ran);
        alert("登録しました");
        break;
      } else {
        break;
      }
    }
  }
  //重複チェック
  function list_check(lp, n_name) {
    var flag = 0;
    for (var i = 0; i < lp; i++) {
      if (localStorage.getItem('user' + (i + 1)) == n_name) {
        alert("このページは既に登録されています");
        flag = 1;
        break;
      }
    }
    return flag;
  }
}
//リスト表示処理
var result4 = document.evaluate('id("global-new-tweet-button")', document, null, 7, null);
result4.snapshotItem(0).insertAdjacentHTML('afterend', '<input type="button" value="リスト" id="list">');
var result5 = document.evaluate('id("list")', document, null, 7, null);
result5.snapshotItem(0).addEventListener('click', sample2, false);

function sample2() {
  localStorage.setItem("n_url", location.href);
  history.pushState(null, null, "/koko_nanimo_naidesuyo2");
  document.body.innerHTML = "<ol type=1></ol>";
  var result6 = document.evaluate('//ol', document, null, 7, null);
  for (var i = 0; i < 128; i++) {
    if ('user' + (i + 1) in localStorage) {
      if (localStorage.getItem('user' + (i + 1)) != "home_kokokara_hajimaruyo") {
        if (localStorage.getItem(localStorage.getItem('user' + (i + 1))) != null) {
          result6.snapshotItem(0).insertAdjacentHTML('beforeend', '<li class=line' + (i + 1) + '><img src=https://twitter.com/' + localStorage.getItem('user' + (i + 1)) + '/profile_image?size=mini><a href=https://twitter.com/' + localStorage.getItem('user' + (i + 1)) + '>@' + localStorage.getItem('user' + (i + 1)) + '</a><div>' + localStorage.getItem(localStorage.getItem('user' + (i + 1))) + '</div></li>');
        } else {
          result6.snapshotItem(0).insertAdjacentHTML('beforeend', '<li class=line' + (i + 1) + '><img src=https://twitter.com/' + localStorage.getItem('user' + (i + 1)) + '/profile_image?size=mini><a href=https://twitter.com/' + localStorage.getItem('user' + (i + 1)) + '>@' + localStorage.getItem('user' + (i + 1)) + '</a></li>');
        }
      } else {
        result6.snapshotItem(0).insertAdjacentHTML('beforeend', '<li class=line' + (i + 1) + '>home</li><br>');
      }
    } else {
      document.body.insertAdjacentHTML('beforeend', '<input type=button id=remove value=削除>');
      break;
    }
  }
  var listArray = document.querySelectorAll('li+li');
  for (var a = 0; a < listArray.length; a++) {
    listArray[a].style.marginTop = "1em";
  }
  $(function () {
    $('#remove').click(function () {
      var j = window.prompt("何番目のアカウントを削除しますか?\n半角英数で入力してください。\n入力例は1番から3番を消す場合です", "1-3");
      if (/\-/g.test(j)) {
        var j_sp = j.split("-");
        var j_begin = j_sp[0];
        var j_end = j_sp[1];
        while (j_begin <= j_end) {
          $('.line' + j_begin).css({
            "display": "none"
          });
          j_begin++;
        }
      } else {
        $('.line' + j).css({
          "display": "none"
        });
      }
    }, );
  });
  window.addEventListener('popstate', function (event) {
    location.href = localStorage.getItem("n_url");
  });
}

Youtubeで音量調整が必要そうな場合に警告を表示

// ==UserScript==
// @name         youtube_volume_alert
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  try to take over the world!
// @author       You
// @match        https://www.youtube.com/watch?v=*
// @grant        none
// ==/UserScript==
var result = document.evaluate('//video', document, null, 7, null);
result.snapshotItem(0).addEventListener('play', function () {
  if (result.snapshotItem(0).volume >= 0.9) {
    alert("音量が90%以上に設定されています");
  } else if (result.snapshotItem(0).volume <= 0.1) {
    alert("音量が10%以下に設定されています");
  }
});