Fucking with people

inserts random hair spaces into your toots to fuck with people

您需要先安裝使用者腳本管理器擴展,如 TampermonkeyGreasemonkeyViolentmonkey 之後才能安裝該腳本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyViolentmonkey 後才能安裝該腳本。

您需要先安裝使用者腳本管理器擴充功能,如 TampermonkeyUserscripts 後才能安裝該腳本。

你需要先安裝一款使用者腳本管理器擴展,比如 Tampermonkey,才能安裝此腳本

您需要先安裝使用者腳本管理器擴充功能後才能安裝該腳本。

(我已經安裝了使用者腳本管理器,讓我安裝!)

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展,比如 Stylus,才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

你需要先安裝一款使用者樣式管理器擴展後才能安裝此樣式

(我已經安裝了使用者樣式管理器,讓我安裝!)

// ==UserScript==
// @name         Fucking with people
// @namespace    https://github.com/ashkitten
// @version      1.1.0
// @description  inserts random hair spaces into your toots to fuck with people
// @author       ashkitten
// @match        https://sleeping.town/*
// @grant        none
// ==/UserScript==

/* jshint esversion: 6 */

// checks if we're in the process of typing a mention or emoji
// mostly stolen from my girlfriend: https://github.com/rustodon/rustodon/blob/master/lib/posticle/src/regexes.rs
// this is needlessly overcomplicated but it was fun so yeah
const PARTIAL_MENTION_OR_EMOJI = /(?:@(?:[a-zA-Z0-9_]{1,32})?(?:[@](?:(?:(?:(?:[^-_!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000](?:[^!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]*[^-_!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000])?)\.)*(?:[^-_!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000](?:[^!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]*[^-_!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000])?)\.(?:[^-_!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]?[^-_!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\d](?:[^!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]{1,60}[^-_!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]|[^-_!\"#$%&\'()*+,./:;<=>?@\[\]^`{|}~\x00-\x1F\x7F\ufffe\ufeff\uffff\u202a-\u202e\t-\r \u0085\u00a0\u1680\u180e\u2000-\u200a\u2028\u2029\u202f\u205f\u3000])?))))?|(?<=[^:]|\n|^):[a-zA-Z0-9_]*:?)$/;

(function() {
    'use strict';

    // callback function to execute when mutations are observed
    // we can't use an arrow function here because we need the `this` object
    new MutationObserver(function(mutations) {
        // target the composer textarea
        let textarea = document.querySelector(".composer--textarea .textarea");
        // check if it exists
        if (textarea) {
            textarea.addEventListener("input", e => {
                // check if we're inserting a single character
                if (e.data && e.data.length === 1) {
                    // check that we're not @mentioning someone or typing out an :emoji:
                    if (textarea.value.slice(0, textarea.selectionStart).search(PARTIAL_MENTION_OR_EMOJI) === -1) {
                        // a 1 in 5 chance works pretty well
                        if (Math.random() < 0.2) {
                            // insert a hair space
                            textarea.value = `${textarea.value.slice(0, textarea.selectionStart)}\u200a${textarea.value.slice(textarea.selectionStart)}`;
                            textarea.setSelectionRange(textarea.selectionStart + 1, textarea.selectionStart + 1);
                        }
                    }
                }
            });
            // disconnect the MutationObserver so it won't get called again
            this.disconnect();
        }
    }).observe(document.body, { childList: true, subtree: true });
})();