Skip to content

Instantly share code, notes, and snippets.

@unarist
Last active September 6, 2018 04:53
Show Gist options
  • Save unarist/ce93c77eee6ff9bf51491ff06a3109d3 to your computer and use it in GitHub Desktop.
Save unarist/ce93c77eee6ff9bf51491ff06a3109d3 to your computer and use it in GitHub Desktop.
:don: - スラングにabbrつけるやつ
// ==UserScript==
// @name :don: - スラングにabbrつけるやつ
// @namespace https://github.com/unarist/
// @version 0.21.1
// @author unarist
// @match https://mstdn.maud.io/*
// @grant none
// @downloadURL https://gist.github.com/unarist/ce93c77eee6ff9bf51491ff06a3109d3/raw/mastodon-add-abbr.user.js
// @noframes
// ==/UserScript==
/*
0.21: v1.5.0対応(遅い)
0.16: 1カラムとの間で切り替えてもいいように
0.14: v1.4.0対応な気がする
0.11: href内で誤爆しないように、正規表現一本にまとめて高速化?
*/
(function() {
'use strict';
if (!document.querySelector('.app-holder[data-react-class="Mastodon"], #mastodon')) return;
const patterns = [
[/ほ0た/g, 'もしかして: ほた'],
[/ほ[55]ん|例の七文字/g, 'ほたはろりこん'],
[/ほ[33]り/g, 'ほたはろり'],
[/ろ2ん/g, 'ろりこん'],
[/CM3D2/g, 'カスタムメイド3D2'],
[/激30ド/g, '激カワ猫耳ダウナー系フリルふりふりツインテールあざと美少女メイド'],
[/末代/g, '/about/moreを参照。辞書的には死んだ後の世、末の世といった意味。'],
[/(?:藍川)? ?茜|茜ちゃん/g, 'mstdn.maud.ioの看板娘。青髪赤目キャラ。グッズもある → https://akane.blue/'],
// https://mstdn.maud.io/about/more
[/:don:/g, 'mstdn.maud.io。深く考えずにEmojiっぽく :don: にしてたらみんなそれでいいというので続投した。謎。'],
[/:realtek:/gi, '蟹'],
[/キラキラッター|kirakiratter|kkt/gi, 'アイカツ!に登場するSNS。をモチーフにしたMastodonインスタンス。ついにテーマ機能を実装した。'],
[/i18n/gi, 'Internationalization。国際化。そもそも日本語を扱えるようにとか日本語化できるようにとかそういう。'],
[/l10n/gi, 'Localization。地域化。地域に応じた表示言語とか通貨形式とか追加する感じ。'],
[/o\.p(?!\w|-)|o4o\.p2n|omanko\.porn/, 'ykzts氏が運営するインスタンス、omanko.porn。'],
[/肘確/g, '「まずい、肘が確定するっ!」ノラとと#4より'],
[/ノラとと/g, 'いわゆる美少女ゲーム「ノラと皇女と野良猫ハート」、およびそれを原作にしたアニメ。肘が確定する。'],
[/かぼるー??/g, 'かぼらないで!'],
[/うけるー??/g, 'うけないで!'],
[/ましまろです/g, 'ま〜まれぇど制作のえっちげ「お家に帰るまでがましまろです」好評発売中です'],
[/canned mackerel/gi, '鯖缶'],
[/\bSKK\b/gi, '独特な入力方式がクセになる、かな漢字変換システム。元々はEmacs向けだが、各種環境に互換実装が存在する。'],
[/山田うどん(?:OS)?/g, '関東圏のうどんチェーン、もしくはロゴが似ているLineageOS。'],
[/立川/g, '1. 東京都立川市 2. マイクラ鯖 3. その中央都市 4. そこからワールド各地へ飛ぶゲート'],
[/IKEA/g, '1. スウェーデン発祥の家具量販店 2. マイクラ立川鯖の巨大共有倉庫'],
[/ひなビタ(?!♪)/g, 'ひなビタ♪'],
[/erait(!?!)/g, 'eraitt (えらいっt) + ^H = erait (えらいっ)'],
];
const combined_regex = new RegExp('(' + patterns.map(pattern => pattern[0].source).join(')|(') + ')', 'gi');
const observe_root = document.querySelector('.app-holder[data-react-class="Mastodon"], #mastodon');
const applyAbbr = node => {
for (const elem of document.querySelectorAll('.status__content p:only-child, .status__content p > span')) {
if (elem.querySelector('abbr') !== null) continue;
for (const node of elem.childNodes) {
if (node.nodeType !== Node.TEXT_NODE) continue;
let cur = node, match;
while ((match = combined_regex.exec(cur.textContent)) !== null) {
const pattern_idx = match.findIndex((e,i) => e && i) - 1;
const abbr_elem = Object.assign(document.createElement('abbr'), { title: patterns[pattern_idx][1], textContent: match[0] });
cur = cur.splitText(match.index);
cur.textContent = cur.textContent.slice(match[0].length);
cur.parentNode.insertBefore(abbr_elem, cur);
combined_regex.lastIndex = 0;
}
}
}
};
new MutationObserver(mutations => {
for (const mutation of mutations) {
for (const node of mutation.addedNodes) {
if (node.nodeName === 'ARTICLE' || node.className && node.className.match(/^status|^notification|^column$/)) {
applyAbbr(node);
}
}
}
}).observe(observe_root, {childList: true, subtree: true});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment