Skip to content

Instantly share code, notes, and snippets.

@sounisi5011
Last active February 10, 2023 16:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sounisi5011/311bf1167515584a64cf6402646cbc6b to your computer and use it in GitHub Desktop.
Save sounisi5011/311bf1167515584a64cf6402646cbc6b to your computer and use it in GitHub Desktop.
[Tampermonkey] アカウント切替時にTwitterのホーム画面へ移動するのを防ぐTampermonkeyスクリプト

Do not jump to Twitter home!

アカウントを切り替えた直後に、Twitterのホーム画面へ勝手に移動するのを防ぐTampermonkeyスクリプト。 ここをクリックしてインストールします

機能

  • アカウントを切り替えた直後に、自動的にホーム画面へ移動しそうな場合は、強制的にブラウザバックします。
// ==UserScript==
// @name Do not jump to Twitter home!
// @namespace https://gist.github.com/sounisi5011/311bf1167515584a64cf6402646cbc6b
// @version 0.9.4
// @description アカウント切替時にTwitterのホーム画面へ移動するのを防ぎます。
// @author sounisi5011
// @match https://twitter.com/*
// @grant none
// ==/UserScript==
const STORAGE_KEY =
"https://gist.github.com/sounisi5011/311bf1167515584a64cf6402646cbc6b";
/**
* フラグを破棄するタイムアウト時間
* Note: 稀に、クリックしてもアカウントが切り替わらない場合が存在するため、一定以上の時間が経過したフラグは破棄する
* Note: ブラウザが重い場合は、ページ切り替えに時間がかかりすぎてタイムアウトする恐れがある。
* タブを138個開いているChrome 109.0.5414.119では、おおよそ5秒。
* 長すぎても本来の動作に支障が出るため、7秒に設定する。
*/
const STORAGE_TIMEOUT_MSEC = 7 * 1000;
const HOME_URL_REGEXP = /^https:\/\/twitter\.com\/home\/*(?=[?#]|$)/i;
function loadData() {
const dataText = sessionStorage.getItem(STORAGE_KEY);
if (dataText) {
try {
return JSON.parse(dataText);
} catch (error) {
if (!(error instanceof SyntaxError)) throw error;
}
}
return null;
}
function setData(object) {
const newData = { ...loadData(), ...object };
const dataText = JSON.stringify(newData);
sessionStorage.setItem(STORAGE_KEY, dataText);
}
function isTimeout(lastUpdatedMSec, limitMSec) {
return lastUpdatedMSec + limitMSec < Date.now();
}
/*
* 初回ロード時、および、URLが変更された場合に実行する処理
*/
function main(url) {
/*
* URLがTwitterのホーム画面ではない場合は、処理を中断
*/
if (!HOME_URL_REGEXP.test(url)) return;
/*
* 保存済みのデータが存在しない場合は、処理を中断
*/
const data = loadData();
if (!data) return;
/*
* disallowVisitHomeフラグがfalseの場合は、処理を中断
*/
if (!data.disallowVisitHome) return;
/*
* disallowVisitHomeをfalseに設定する
*/
setData({ disallowVisitHome: false });
/*
* updateプロパティがデータに存在し、かつ、更新時刻からSTORAGE_TIMEOUT_MSECミリ秒以上経過した場合は、処理を中断
* Note: 稀に、クリックしてもアカウントが切り替わらない場合が存在するため、一定以上の時間が経過したフラグは破棄する
*/
if (
typeof data.update === "number" &&
isTimeout(data.update, STORAGE_TIMEOUT_MSEC)
) {
return;
}
/*
* ページの移動をキャンセルする
*/
history.back();
}
/*
* クリックを検知する
* Note: Chrome 99.0.4844.74において、captureフラグをtrueにしないとSession Storageが更新されない。ページ移動までに間に合っていない可能性がある
*/
document.addEventListener("click", (event) => {
/*
* クリックされた要素がアカウントを切り替えるボタンだった場合は、以降の処理に進む
*/
if (!event.target.closest('[aria-label$="に切り替える"]')) return;
/*
* disallowVisitHomeフラグをtrueに設定し、ホーム画面への移動を禁止
*/
setData({
disallowVisitHome: true,
update: Date.now(),
});
}, { capture: true, passive: true });
/*
* ページのURLの変更を検知する
*/
{
let prevURL, rerunId;
function navigate(callback = () => {}) {
const url = location.href;
if (prevURL !== url) {
prevURL = url;
main(url);
callback();
}
}
if ('navigation' in window && 'onnavigate' in window.navigation) {
/**
* navigateイベントをサポートしている場合は、navigateイベントでURLの変更を監視する
*/
window.navigation.addEventListener('navigate', () => navigate(), { passive: true });
// navigateイベントは初回読み込み時には実行されないため、一回だけ実行する
navigate();
} else {
/**
* navigateイベントをサポートしていない場合は、タイマー処理でURLの変更を監視する
* Note: navigateイベントを除き、history.pushState()メソッドを実行したページ移動を検知するイベントは存在しない
*/
(function pageMoveObserver() {
navigate(() => {
// たまに実行されない場合があるため、0.5秒後に再実行する
if (typeof rerunId === 'number') clearTimeout(rerunId);
rerunId = setTimeout(() => {
rerunId = null;
main(location.href);
}, 500);
});
requestAnimationFrame(pageMoveObserver);
})();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment