Twitter Middle Clicks

This script makes it possible to open a quoted tweet, a trend, a link in tweet input form, or an input complement into a new tab by middle click.

От 10.10.2021. Виж последната версия.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name        Twitter Middle Clicks
// @name:ja     Twitter 中クリック
// @description This script makes it possible to open a quoted tweet, a trend, a link in tweet input form, or an input complement into a new tab by middle click.
// @description:ja 引用されたツイート、トレンド、ツイート入力欄のリンク、入力補完を中クリックして新規タブで開けるようにします。
// @namespace   https://greatest.deepsurf.us/users/137
// @version     1.3.0
// @match       https://twitter.com/*
// @exclude     https://twitter.com/settings*
// @exclude     https://twitter.com/tos*
// @exclude     https://twitter.com/privacy*
// @exclude     https://twitter.com/jobs*
// @exclude     https://twitter.com/account/*
// @exclude     https://twitter.com/intent/*
// @exclude     https://twitter.com/i/cards/*
// @license     MPL-2.0
// @contributionURL https://www.amazon.co.jp/registry/wishlist/E7PJ5C3K7AM2
// @compatible  Edge
// @compatible  Firefox Firefoxを推奨 / Firefox is recommended
// @compatible  Opera
// @compatible  Chrome
// @grant       dummy
// @run-at      document-start
// @icon        https://abs.twimg.com/favicons/twitter.ico
// @author      100の人
// @homepageURL https://greatest.deepsurf.us/scripts/392927
// ==/UserScript==

'use strict';

addEventListener('mouseup', function (event) { // Firefox、Google Chromeは、auxclickがリンク上でしか動作しない不具合がある
	if (event.button !== 1 || event.detail !== 0 || event.target.closest('a')) {
		// 中クリックでない、ダブルクリック、またはリンクのクリックなら
		return;
	}
	
	if (event.target.dataset.text) {
		if (!event.target.parentElement.parentElement.style.color) {
			return;
		}

		// ツイート入力欄のリンク
		let url;
		const content = event.target.textContent;
		if (content.startsWith('@')) {
			url = '/' + content.replace('@', '');
		} else if (content.startsWith('#')) {
			// ハッシュタグ
			url = '/hashtag/' + encodeURIComponent(content.replace('#', ''));
		} else if (content.startsWith('$')) {
			// キャッシュタグ
			url = '/search?q=' + encodeURIComponent(content);
		} else {
			try {
				new URL(content);
			} catch (exception) {
				if (exception.name !== 'TypeError') {
					throw exception;
				}
				// ドメイン
				url = 'http://' + content;
			}

			if (!url) {
				// URL
				url = content;
			}
		}
		open(url);
		return;
	}
	
	const option = event.target.closest('[role="option"]');
	if (option) {
		// ツイート入力欄、または検索窓の入力補完
		let url;
		if (option.querySelector('[data-testid="TypeaheadUser"]')) {
			// ユーザー
			url = '/' + option.querySelector('[dir="ltr"]').textContent.replace('@', '');
		} else {
			let content = event.target.textContent;
			const searchForm = option.closest('[role="search"]');
			if (searchForm) {
				// 検索窓
				const searchTerms = searchForm.querySelector('[role="combobox"]').value;
				switch (content) {
					case `「${searchTerms}」を検索`:
						content = searchTerms;
						break;
					case `@${searchTerms}さんのプロフィール`:
						url = '/' + searchTerms.replace('@', '');
						break;
				}
			}
			if (!url) {
				url = content.startsWith('#')
					? '/hashtag/' + encodeURIComponent(content.replace('#', '')) // ハッシュタグ
					: '/search?q=' + encodeURIComponent(content); // Twitterの検索窓では空白が「+」ではなく「%20」に置き換わる
			}
		}
		open(url);
		return;
	}
	
	// Ctrl + 主クリック
	const init = {};
	for (const key in event) {
		init[key] = event[key];
	}
	init.button = 0;
	init.ctrlKey = true;
	if (!event.target.dispatchEvent(new MouseEvent('click', init))) {
		event.preventDefault();
		event.stopImmediatePropagation();
	}
}, true);