Twitter - 為使用者新增備註

為使用者新增備註功能,以幫助識別和搜尋; 滑鼠移至網頁右下角彈出搜尋按鈕

目前為 2020-06-05 提交的版本,檢視 最新版本

// ==UserScript==
// @name                Twitter - Add notes to the user
// @name:zh-CN          Twitter - 为用户添加备注
// @name:zh-TW          Twitter - 為使用者新增備註
// @namespace           https://gf.qytechs.cn/zh-CN/users/193133-pana
// @homepage            https://www.sailboatweb.com
// @version             1.1.7
// @description         Add a note for users to help identify and search; the search button pops up in the lower right corner
// @description:zh-CN   为用户添加备注功能,以帮助识别和搜索; 鼠标移至网页右下角弹出搜索按钮
// @description:zh-TW   為使用者新增備註功能,以幫助識別和搜尋; 滑鼠移至網頁右下角彈出搜尋按鈕
// @author              pana
// @license             GNU General Public License v3.0 or later
// @include             http*://*twitter.com/*
// @require             https://cdnjs.cloudflare.com/ajax/libs/arrive/2.4.1/arrive.min.js
// @grant               GM_getValue
// @grant               GM_setValue
// ==/UserScript==

(function() {
    'use strict';
    const LANG = {
        'EN': {
            'title': 'Note',
            'add_button_text': 'Add note',
            'add_button_title': 'Add notes to the user',
            'modify_button_text': 'Modify note',
            'modify_button_title': 'Modify notes for the user',
            'input_placeholder': '(Enter a note, delete it when blanked; press Enter to save)',
            'save_button_text': 'Save',
            'clear_button_text': 'Clear',
            'cancel_button_text': 'Cancel',
            'search_placeholder': 'Search notes',
            'user_id': 'User ID: ',
            'user_name': 'User Name: '
        },
        'ZH_CN': {
            'title': '备注',
            'add_button_text': '添加备注',
            'add_button_title': '为用户添加备注',
            'modify_button_text': '修改备注',
            'modify_button_title': '为用户修改备注',
            'input_placeholder': '(请输入备注,置空时删除;按下Enter键保存)',
            'save_button_text': '保存',
            'clear_button_text': '清除',
            'cancel_button_text': '取消',
            'search_placeholder': '搜索备注',
            'user_id': '用户 ID: ',
            'user_name': '用户名: '
        },
        'ZH_TW': {
            'title': '備註',
            'add_button_text': '新增備註',
            'add_button_title': '為使用者新增備註',
            'modify_button_text': '修改備註',
            'modify_button_title': '為使用者修改備註',
            'input_placeholder': '(請輸入備註,置空時刪除;按下Enter鍵儲存)',
            'save_button_text': '儲存',
            'clear_button_text': '清除',
            'cancel_button_text': '取消',
            'search_placeholder': '搜尋備註',
            'user_id': '使用者 ID: ',
            'user_name': '使用者名稱: '
        }
    };
    const ICON = {
        'NOTE_GRAY': 'url(data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBhcmlhLWxhYmVsbGVkYnk9Im5ld0ljb25UaXRsZSIgc3Ryb2tlPSJyZ2IoMTAxLCAxMTksIDEzNCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgZmlsbD0ibm9uZSIgY29sb3I9InJnYigxMDEsIDExOSwgMTM0KSI+IDx0aXRsZSBpZD0ibmV3SWNvblRpdGxlIj5OZXc8L3RpdGxlPiA8cGF0aCBkPSJNMTkgMTRWMjJIMi45OTk5N1Y0SDEzIi8+IDxwYXRoIGQ9Ik0xNy40NjA4IDQuMDM5MjFDMTguMjQxOCAzLjI1ODE3IDE5LjUwODIgMy4yNTgxNiAyMC4yODkyIDQuMDM5MjFMMjAuOTYwOCA0LjcxMDc5QzIxLjc0MTggNS40OTE4NCAyMS43NDE4IDYuNzU4MTcgMjAuOTYwOCA3LjUzOTIxTDExLjU4NTggMTYuOTE0MkMxMS4yMTA3IDE3LjI4OTMgMTAuNzAyIDE3LjUgMTAuMTcxNiAxNy41TDcuNSAxNy41TDcuNSAxNC44Mjg0QzcuNSAxNC4yOTggNy43MTA3MSAxMy43ODkzIDguMDg1NzkgMTMuNDE0MkwxNy40NjA4IDQuMDM5MjFaIi8+IDxwYXRoIGQ9Ik0xNi4yNSA1LjI1TDE5Ljc1IDguNzUiLz4gPC9zdmc+)',
        'NOTE_BLUE': 'url(data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBhcmlhLWxhYmVsbGVkYnk9Im5ld0ljb25UaXRsZSIgc3Ryb2tlPSJyZ2JhKDI5LDE2MSwyNDIsMS4wMCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgZmlsbD0ibm9uZSIgY29sb3I9InJnYmEoMjksMTYxLDI0MiwxLjAwKSI+IDx0aXRsZSBpZD0ibmV3SWNvblRpdGxlIj5OZXc8L3RpdGxlPiA8cGF0aCBkPSJNMTkgMTRWMjJIMi45OTk5N1Y0SDEzIi8+IDxwYXRoIGQ9Ik0xNy40NjA4IDQuMDM5MjFDMTguMjQxOCAzLjI1ODE3IDE5LjUwODIgMy4yNTgxNiAyMC4yODkyIDQuMDM5MjFMMjAuOTYwOCA0LjcxMDc5QzIxLjc0MTggNS40OTE4NCAyMS43NDE4IDYuNzU4MTcgMjAuOTYwOCA3LjUzOTIxTDExLjU4NTggMTYuOTE0MkMxMS4yMTA3IDE3LjI4OTMgMTAuNzAyIDE3LjUgMTAuMTcxNiAxNy41TDcuNSAxNy41TDcuNSAxNC44Mjg0QzcuNSAxNC4yOTggNy43MTA3MSAxMy43ODkzIDguMDg1NzkgMTMuNDE0MkwxNy40NjA4IDQuMDM5MjFaIi8+IDxwYXRoIGQ9Ik0xNi4yNSA1LjI1TDE5Ljc1IDguNzUiLz4gPC9zdmc+)',
        'SEARCH': 'url(data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBhcmlhLWxhYmVsbGVkYnk9InNlYXJjaEljb25UaXRsZSIgc3Ryb2tlPSJyZ2JhKDI5LDE2MSwyNDIsMS4wMCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgZmlsbD0ibm9uZSIgY29sb3I9InJnYmEoMjksMTYxLDI0MiwxLjAwKSI+IDx0aXRsZSBpZD0ic2VhcmNoSWNvblRpdGxlIj5TZWFyY2g8L3RpdGxlPiA8cGF0aCBkPSJNMTQuNDEyMTEyMiwxNC40MTIxMTIyIEwyMCwyMCIvPiA8Y2lyY2xlIGN4PSIxMCIgY3k9IjEwIiByPSI2Ii8+IDwvc3ZnPg==)'
    };
    const STYLE_VALUE = `
        .my_twitter_note_btn {
            background-image: ${ICON.NOTE_GRAY};
            background-repeat: no-repeat;
            background-position: center;
            background-color: rgba(0, 0, 0, 0);
            border-bottom-left-radius: 9999px;
            border-bottom-right-radius: 9999px;
            border-top-left-radius: 9999px;
            border-top-right-radius: 9999px;
            transition-property: background-color, box-shadow;
            transition-duration: 0.2s;
        }
        .my_twitter_note_btn:hover {
            background-image: ${ICON.NOTE_BLUE};
            background-color: rgba(29, 161, 242, 0.1);
        }
        .base_tool_bar_btn {
            height: 32px;
            width: 32px;
            margin: -8px -45px -8px 70px;
            background-size: 18px auto;
        }
        .comment_tool_bar_btn {
            height: 42px;
            width: 42px;
            margin: 2px 0px 0px -15px;
            background-size: 22px auto;
            cursor: pointer;
        }
        .my_before_follow_note_btn {
            height: 39px;
            width: 39px;
            background-image: ${ICON.NOTE_BLUE};
            background-repeat: no-repeat;
            background-size: 19px auto;
            background-position: center;
            margin-bottom: 10px;
            margin-right: 10px;
            cursor: pointer;
            border: 1px solid rgba(29,161,242,1.00);
            border-bottom-left-radius: 9999px;
            border-bottom-right-radius: 9999px;
            border-top-left-radius: 9999px;
            border-top-right-radius: 9999px;
            background-color: rgba(0, 0, 0, 0);
            transition-property: background-color, box-shadow;
            transition-duration: 0.2s;
        }
        .my_before_follow_note_btn:hover {
            background-color: rgba(29, 161, 242, 0.1);
        }
        .list_show, .show_separator {
            display: block !important;
        }
        #presentation_div_for_user {
            display: flex;
            position: fixed;
            background-color: rgba(0, 0, 0, .5);
            top: 0;
            bottom: 0;
            left: 0;
            right: 0;
            z-index: 101;
            align-items: center;
            justify-content: center;
        }
        .dialog_div_for_user {
            position: relative;
            width: 400px;
            background-color: rgb(21, 32, 43);
            border: 0 solid #000;
            border-radius: 12px;
            display: flex;
            flex-direction: column;
        }
        .user_title_span_for_user {
            min-height: 48px;
            text-align: center;
            border: 1px solid rgba(0, 0, 0, .5);
            color: #1da1f2;
            font-weight: bold;
            background-color: rgba(0, 0, 0, 0);
            border-top-left-radius: 12px;
            border-top-right-radius: 12px;
            white-space: pre-wrap;
            cursor: text;
            user-select: text;
            line-height: 24px;
        }
        .tag_input_for_user {
            min-height: 32px;
            margin: 5px;
            border: 1px solid rgba(29, 161, 242, 0.1);
            padding-left: 5px;
            background-color: #253341;
            color: #fff;
        }
        .button_for_user {
            min-height: 48px;
            cursor: pointer;
            border: 1px solid rgba(0, 0, 0, .5);
            background-color: rgba(0, 0, 0, 0);
            color: #fff;
        }
        .button_for_user:hover {
            color: #1da1f2;
        }
        .cancel_button_for_user {
            border-bottom-left-radius: 12px;
            border-bottom-right-radius: 12px;
        }
        #searchFrame {
            position: relative;
        }
        #myInputSearch {
            width: 350px;
            height: 40px;
            border: 2px solid #000;
            border-radius: 40px;
            padding: 0 20px;
            position: relative;
            background-color: rgb(37, 51, 65);
            color: #fff;
            outline: none;
        }
        #tagsList {
            width: 350px;
            height: 250px;
            overflow-y: scroll;
            text-align: left;
            display: none;
            position: absolute;
            margin: 0 20px;
            z-index: 100;
            background-color: rgb(37, 51, 65);
            border: 1px solid rgba(29, 161, 242, 0.1);
        }
        .ins_list_item {
            cursor: pointer;
            color: #fff;
            padding-left: 5px;
            height: 25px;
            line-height: 25px;
        }
        .ins_highlight {
            background-color: #6699cc;
        }
        .ins_hide {
            display: none;
        }
        .ins_tag_span {
            color: #336699;
        }
        .my_note_btn_hide {
            display: none;
        }
        ol.script-list li:hover .my_twitter_note_btn {
            display: inline !important;
        }
        .expand_box {
            bottom: 0px;
            height: 50px;
            position: fixed;
            right: -50px;
            transition: 0.5s;
            width: 100px;
            z-index: 99;
        }
        .show_expand_box {
            right: 0;
            width: 50px;
        }
        #expandSpan {
            border-radius: 99px;
            border: 1px solid #00A1D6;
            bottom: 1vh;
            color: #FFF;
            cursor: pointer;
            display: block;
            font-size: 13px;
            height: 38px;
            line-height: 38px;
            position: absolute;
            right: 1vw;
            text-align: center;
            width: 38px;
            z-index: 98;
            background-image: ${ICON.SEARCH};
            background-repeat: no-repeat;
            background-size: 24px auto;
            background-position: center;
        }
        #my_search_bottom_layer_div {
            display: flex;
            position: fixed;
            background-color: rgba(0, 0, 0, .5);
            top: -50vh;
            bottom: 0;
            left: 0;
            right: 0;
            z-index: 100;
            align-items: center;
            justify-content: center;
        }
    `;
    var selector = {
        'body': 'body',
        'root': '#react-root div .r-13awgt0.r-12vffkv',
        'homepage': {
            'article': 'article',
            'tool_bar': '.css-1dbjc4n.r-18u37iz.r-1wtj0ep.r-156q2ks.r-1mdbhws',
            'show_name': '.css-901oao.css-bfa6kz.r-1qd0xha.r-a023e6.r-vw2c0b.r-ad9z0x.r-bcqeeo.r-3s2u2q.r-qvutc0 > span',
            'id': '.css-901oao.css-bfa6kz.r-18u37iz.r-1qd0xha.r-a023e6.r-16dba41.r-ad9z0x.r-bcqeeo.r-qvutc0 > span',
            'reprint_a': '.css-1dbjc4n.r-1iusvr4.r-16y2uox.r-5f2r5o.r-m611by a',
            'reprint_name': '.css-1dbjc4n.r-1iusvr4.r-16y2uox.r-5f2r5o.r-m611by a > span > span',
            'at': 'a.css-4rbku5.css-18t94o4.css-901oao.css-16my406.r-1loqt21.r-1qd0xha.r-ad9z0x.r-bcqeeo.r-qvutc0',
            'user_frame': '.css-18t94o4.css-1dbjc4n.r-1ny4l3l.r-1j3t67a.r-1w50u8q.r-o7ynqc.r-6416eg',
            'blockquote': 'div[role="blockquote"]'
        },
        'userpage': {
            'main_user_id': '.css-1dbjc4n.r-15d164r.r-1g94qm0 .css-1dbjc4n.r-18u37iz.r-1wbh5a2 > div > span',
            'main': '.css-1dbjc4n.r-ku1wi2.r-1j3t67a.r-m611by',
            'id': '.css-1dbjc4n.r-18u37iz.r-1wbh5a2 > div > span',
            'follow': '.css-1dbjc4n.r-obd0qt.r-18u37iz.r-1w6e6rj.r-1h0z5md.r-dnmrzs',
            'show_name': '.css-901oao.r-1qd0xha.r-1b6yd1w.r-1vr29t4.r-ad9z0x.r-bcqeeo.r-qvutc0 > span'
        },
        'comment': {
            'tool_bar': '.css-1dbjc4n.r-1oszu61.r-1efd50x.r-5kkj8d.r-18u37iz.r-ahm1il.r-a2tzq0'
        }
    };
    var modify_style = selector.homepage.show_name + ' { white-space: normal; }\n';
    class Twitter_Note {
        constructor(config, lang, show_list = []) {
            this.config = config;
            this.lang = lang;
            this.showList = show_list;
        }
        createNoteBtn(user_id, user_name, callback, class_name = "my_twitter_note_btn") {
            let btn = document.createElement('div');
            btn.className = class_name;
            if (this.judgeUsers(user_id)) {
                btn.title = this.lang.modify_button_title;
            } else {
                btn.title = this.lang.add_button_title;
            }
            btn.addEventListener('click', (event) => {
                event.stopPropagation();
                document.body.appendChild(this.createNoteFrame(user_id, user_name, () => {    
                    if (this.judgeUsers(user_id)) {
                        btn.title = this.lang.modify_button_title;
                    } else {
                        btn.title = this.lang.add_button_title;
                    }
                    if (typeof(callback) == 'function') {
                        callback();
                    }
                }));
            });
            return btn;
        }
        doneHandle(user_id, ele, path_name, w = false) {
            if (w) {
                if (path_name) {
                    if (ele.querySelector(path_name)) {
                        let source_dom = ele.querySelector(path_name);
                        if (this.judgeUsers(user_id)) {
                            source_dom.textContent = this.getUserAtTag(user_id);
                        } else {
                            source_dom.textContent = user_id;
                        }
                    }
                } else {
                    if (this.judgeUsers(user_id)) {
                        ele.textContent = this.getUserAtTag(user_id);
                    } else {
                        ele.textContent = user_id;
                    }
                }
            } else {
                if (path_name) {
                    if (ele.querySelector(path_name + ' .ins_tag_span')) {
                        let tag_dom = ele.querySelector(path_name + ' .ins_tag_span');
                        if (this.judgeUsers(user_id)) {
                            tag_dom.textContent = this.getUserFormatTag(user_id);
                        } else {
                            ele.querySelector(path_name).removeChild(tag_dom);
                        }
                    } else {
                        if (this.judgeUsers(user_id)) {
                            ele.querySelector(path_name).appendChild(this.createNoteSpan(user_id));
                        }
                    }
                } else {
                    if (ele.querySelector('.ins_tag_span')) {
                        let an_tag_dom = ele.querySelector('.ins_tag_span');
                        if (this.judgeUsers(user_id)) {
                            an_tag_dom.textContent = this.getUserFormatTag(user_id);
                        } else {
                            ele.removeChild(an_tag_dom);
                        }
                    } else {
                        if (this.judgeUsers(user_id)) {
                            ele.appendChild(this.createNoteSpan(user_id));
                        }
                    }
                }
            }
        }
        isUsersFromLink(link) {
            return /^\/[^/]+$/i.test(link.replace(location.origin, ""));
        }
        getUserIdFromLink(link) {
            return link.replace(location.origin + '/', '@');
        }
        judgeUsers(user_id) {
            if (this.getUserIndex(user_id) == -1) {
                return false;
            }
            return true;
        }
        getUserIndex(user_id) {
            for (let i in this.config.users_array) {
                if (user_id == this.config.users_array[i].id) {
                    return i;
                }
            }
            return -1;
        }
        getUserTag(user_id) {
            if (this.judgeUsers(user_id)) {
                return this.config.users_array[this.getUserIndex(user_id)].tag;
            }
            return '';
        }
        getUserFormatTag(user_id) {
            if (this.judgeUsers(user_id)) {
                return '[' + this.getUserTag(user_id) + ']';
            }
            return '';
        }
        getUserAtTag(user_id) {
            if (this.judgeUsers(user_id)) {
                return '@' + this.getUserTag(user_id);
            }
            return '';
        }
        writeUsers(user_id, tag_value) {
            if (this.judgeUsers(user_id)) {
                let index = this.getUserIndex(user_id);
                if (tag_value) {
                    this.config.users_array[index].tag = tag_value;
                } else {
                    this.config.users_array.splice(index, 1);
                }
            } else {
                if (tag_value) {
                    let temp_scripts_obj = {
                        'id': user_id,
                        'tag': tag_value
                    };
                    this.config.users_array.push(temp_scripts_obj);
                }
            }
            GM_setValue('twitter_config', this.config);
        }
        removeNoteFrame(frame_id = 'presentation_div_for_user') {
            let temp_ele = document.getElementById(frame_id);
            if (temp_ele) {
                temp_ele.parentNode.removeChild(temp_ele);
            }
        }
        createNoteFrame(user_id, user_name, callback) {
            let that = this;
            let presentation_div = document.createElement('div');
            presentation_div.id = 'presentation_div_for_user';
            presentation_div.addEventListener('click', function (event) {
                if (event.target === this) {
                    that.removeNoteFrame();
                }
            });
            let dialog_div = document.createElement('div');
            dialog_div.className = 'dialog_div_for_user';
            let user_title_p = document.createElement('button');
            user_title_p.className = 'user_title_span_for_user';
            user_title_p.textContent = this.lang.user_id + user_id + '\n' + this.lang.user_name + user_name;
            let tag_input = document.createElement('input');
            tag_input.className = 'tag_input_for_user';
            tag_input.type = 'text';
            tag_input.placeholder = this.lang.input_placeholder;
            if (this.judgeUsers(user_id)) {
                tag_input.value = this.config.users_array[this.getUserIndex(user_id)].tag;
            } else {
                tag_input.value = '';
            }
            tag_input.addEventListener('keyup', (e) => {
                if (e.keyCode === 13) {
                    this.writeUsers(user_id, tag_input.value);
                    this.resetSearchFrame();
                    if (typeof(callback) == 'function') {
                        callback();
                    }
                    this.removeNoteFrame();
                }
            });
            setTimeout(function() {
                try {
                    tag_input.focus();
                    tag_input.select();
                } catch(e) {
                    console.error(e);
                }
            }, 200);
            let save_button = document.createElement('button');
            save_button.className = 'button_for_user';
            save_button.type = 'button';
            save_button.innerText = this.lang.save_button_text;
            save_button.addEventListener('click', () => {
                this.writeUsers(user_id, tag_input.value);
                this.resetSearchFrame();
                if (typeof(callback) == 'function') {
                    callback();
                }
                this.removeNoteFrame();
            });
            let clear_button = document.createElement('button');
            clear_button.className = 'button_for_user';
            clear_button.type = 'button';
            clear_button.innerText = this.lang.clear_button_text;
            clear_button.addEventListener('click', () => {
                this.writeUsers(user_id, '');
                this.resetSearchFrame();
                if (typeof(callback) == 'function') {
                    callback();
                }
                this.removeNoteFrame();
            });
            let cancel_button = document.createElement('button');
            cancel_button.className = 'button_for_user cancel_button_for_user';
            cancel_button.type = 'button';
            cancel_button.innerText = this.lang.cancel_button_text;
            cancel_button.addEventListener('click', () => {
                this.removeNoteFrame();
            });
            dialog_div.appendChild(user_title_p);
            dialog_div.appendChild(tag_input);
            dialog_div.appendChild(save_button);
            dialog_div.appendChild(clear_button);
            dialog_div.appendChild(cancel_button);
            presentation_div.appendChild(dialog_div);
            return presentation_div;
        }
        resetSearchFrame() {
            let tags_list = document.getElementById('tagsList');
            if (tags_list) {
                tags_list.innerHTML = "";
                this.config.users_array.forEach((item, index) => {
                    tags_list.appendChild(this.createListDiv(index, item));
                });
            }
        }
        removeSearchFrame(frame_id = 'my_search_bottom_layer_div') {
            let search_frame = document.getElementById(frame_id);
            if (search_frame) {
                search_frame.parentNode.removeChild(search_frame);
            }
        }
        cretaeSearchFrame() {
            let that = this;
            let bottom_layer_div = document.createElement('div');
            bottom_layer_div.id = 'my_search_bottom_layer_div';
            bottom_layer_div.addEventListener('click', function(event) {
                if (event.target === this) {
                    that.removeSearchFrame();
                }
            });
            let search_frame = document.createElement('div');
            search_frame.id = 'searchFrame';
            bottom_layer_div.appendChild(search_frame);
            let search_input = document.createElement('input');
            search_input.id = 'myInputSearch';
            search_input.type = 'text';
            search_input.placeholder = this.lang.search_placeholder;
            search_input.value = "";
            search_input.addEventListener('focusin', () => {
                document.getElementById('tagsList').classList.add('list_show');
                this.searchEvent(search_input);
            });
            setTimeout(function() {
                try {
                    search_input.focus();
                    search_input.select();
                } catch(e) {
                    console.error(e);
                }
            }, 200);
            search_frame.appendChild(search_input);
            let tags_list = document.createElement('div');
            tags_list.id = 'tagsList';
            for (let i = 0; i < this.config.users_array.length; i ++) {
                tags_list.appendChild(this.createListDiv(i, this.config.users_array[i]));
            }
            search_frame.appendChild(tags_list);
            return bottom_layer_div;
        }
        createListDiv(id_number, users_obj) {
            let list_div = document.createElement('div');
            list_div.id = 'tags_' + id_number;
            list_div.className = 'ins_list_item';
            list_div.textContent = users_obj.tag;
            list_div.addEventListener('mouseenter', function() {
                for (let ele of document.querySelectorAll('#tagsList div')) {
                    ele.classList.remove('ins_highlight');
                }
                this.classList.add('ins_highlight');
            });
            list_div.addEventListener('click', function() {
                location.pathname = users_obj.id.replace(/^@/, '/');
            });
            return list_div;
        }
        searchEvent(input_dom) {
            let list_arr = [];
            for (let ele of document.querySelectorAll('#tagsList div')) {
                let arr_obj = {
                    'eleContainer': ele.textContent,
                    'ele': ele
                };
                list_arr.push(arr_obj);
            }
            let current_index = 0;
            input_dom.addEventListener('keyup', (event) => {
                document.getElementById('tagsList').classList.add('list_show');
                let search_val;
                switch (event.keyCode) {
                    case 38:
                    case 40:
                    case 37:
                    case 39:
                        event.returnValue = false;
                        break;
                    case 13:
                        this.showList[current_index].click();
                        break;
                    default:
                        search_val = input_dom.value;
                        this.showList = [];
                        list_arr.forEach((item) => {
                            if (item.eleContainer.indexOf(search_val) !== -1) {
                                item.ele.classList.remove('ins_hide');
                                this.showList.push(item.ele);
                            } else {
                                item.ele.classList.add('ins_hide');
                            }
                        });
                        current_index = 0;
                        break;
                }
                this.showList.forEach(function(item, index) {
                    if (index === current_index) {
                        item.classList.add('ins_highlight');
                        document.getElementById('tagsList').scrollTop = item.offsetTop;
                    } else {
                        item.classList.remove('ins_highlight');
                    }
                });
                let list_height = 25 * this.showList.length;
                if (list_height < 250) {
                    document.getElementById('tagsList').style.height = list_height + 'px';
                } else {
                    document.getElementById('tagsList').style.height = '250px';
                }
            });
            input_dom.addEventListener('keydown', (event) => {
                if (event.keyCode === 38) {
                    current_index --;
                    if (current_index < 0) {
                        current_index = 0;
                    }
                } else if (event.keyCode === 40) {
                    current_index ++;
                    if (current_index >= this.showList.length) {
                        current_index = this.showList.length - 1;
                    }
                }
                this.showList.forEach(function(item, index) {
                    if (index === current_index) {
                        item.classList.add('ins_highlight');
                        document.getElementById('tagsList').scrollTop = item.offsetTop;
                    } else {
                        item.classList.remove('ins_highlight');
                    }
                });
            });
        }
        createNoteSpan(user_id, an_class_name = "") {
            let note_span = document.createElement('span');
            note_span.className = 'ins_tag_span';
            if (an_class_name) {
                note_span.classList.add(an_class_name);
            }
            note_span.textContent = this.getUserFormatTag(user_id);
            return note_span;
        }
    }
    function save_Event(user_id, note_obj) {
        for (let ele of document.querySelectorAll(selector.homepage.article)) {
            let ele_id = "";
            if (ele.querySelector(selector.homepage.id)) {
                ele_id = ele.querySelector(selector.homepage.id).textContent;
            }
            let ele_reprint_id = "";
            if (ele.querySelector(selector.homepage.reprint_a)) {
                ele_reprint_id = note_obj.getUserIdFromLink(ele.querySelector(selector.homepage.reprint_a).href);
            }
            if (ele_id == user_id) {
                note_obj.doneHandle(user_id, ele, selector.homepage.show_name);
            }
            if (ele_reprint_id == user_id) {
                note_obj.doneHandle(user_id, ele, selector.homepage.reprint_name);
            }
            for (let ele_at_user of ele.querySelectorAll(selector.homepage.at)) {
                if (note_obj.isUsersFromLink(ele_at_user.href)) {
                    let ele_at_user_id = note_obj.getUserIdFromLink(ele_at_user.href);
                    if (ele_at_user_id == user_id) {
                        note_obj.doneHandle(user_id, ele_at_user, "", true);
                    }
                }
            }
        }
        for (let user_ele of document.querySelectorAll(selector.userpage.main)) {
            let user_ele_id = user_ele.querySelector(selector.userpage.id).textContent;
            if (user_ele_id == user_id) {
                note_obj.doneHandle(user_id, user_ele, selector.userpage.show_name);
            }
        }
        for (let user_frame_ele of document.querySelectorAll(selector.homepage.user_frame)) {
            let user_frame_ele_id = user_frame_ele.querySelector(selector.userpage.id).textContent;
            if (user_frame_ele_id == user_id) {
                note_obj.doneHandle(user_id, user_frame_ele, selector.homepage.show_name);
            }
        }
        for (let blockquote_ele of document.querySelectorAll(selector.homepage.blockquote)) {
            let blockquote_ele_id = blockquote_ele.querySelector(selector.homepage.id).textContent;
            if (blockquote_ele_id == user_id) {
                note_obj.doneHandle(user_id, blockquote_ele, selector.homepage.show_name);
            }
        }
    }
    function init(twitter_config) {
        let style_dom = document.createElement('style');
        style_dom.type = 'text/css';
        style_dom.innerHTML = STYLE_VALUE;
        document.body.appendChild(style_dom);
        let modify_style_dom = document.createElement('style');
        modify_style_dom.type = 'text/css';
        modify_style_dom.innerHTML = modify_style;
        document.body.appendChild(modify_style_dom);
        let lang_str = document.documentElement.lang;
        let lang_value;
        switch (lang_str) {
            case 'zh':
            case 'zh-cn':
            case 'zh-CN':
                lang_value = LANG.ZH_CN;
                break;
            case 'zh-hk':
            case 'zh-HK':
            case 'zh-tw':
            case 'zh-TW':
            case 'zh-Hant':
                lang_value = LANG.ZH_TW;
                break;
            case 'en':
            default:
                lang_value = LANG.EN;
                break;
        }
        let note_obj = new Twitter_Note(twitter_config, lang_value);
        let expand_box = document.createElement('div');
        expand_box.className = 'expand_box';
        expand_box.onmouseenter = function() {
            this.classList.add('show_expand_box');
        };
        expand_box.onmouseleave = function() {
            this.classList.remove('show_expand_box');
        };
        let search_btn = document.createElement('span');
        search_btn.id = 'expandSpan';
        search_btn.title = note_obj.lang.search_placeholder;
        search_btn.addEventListener('click', function(event) {
            event.stopPropagation();
            document.body.appendChild(note_obj.cretaeSearchFrame());
        });
        expand_box.appendChild(search_btn);
        document.body.appendChild(expand_box);
        document.querySelector(selector.root).arrive(selector.homepage.article, {fireOnAttributesModification: true, existing: true}, function() {
            if (this.querySelector(selector.homepage.id)) {
                let user_id = this.querySelector(selector.homepage.id).textContent;
                let user_name = this.querySelector(selector.homepage.show_name).textContent;
                if (this.querySelector(selector.homepage.tool_bar)) {
                    this.querySelector(selector.homepage.tool_bar).appendChild(note_obj.createNoteBtn(user_id, user_name, function() {
                        save_Event(user_id, note_obj);
                    }, 'my_twitter_note_btn base_tool_bar_btn css-1dbjc4n'));
                }
                if (this.querySelector(selector.comment.tool_bar)) {
                    this.querySelector(selector.comment.tool_bar).appendChild(note_obj.createNoteBtn(user_id, user_name, function() {
                        save_Event(user_id, note_obj);
                    }, 'my_twitter_note_btn comment_tool_bar_btn css-1dbjc4n'));
                }
                note_obj.doneHandle(user_id, this, selector.homepage.show_name);
            }
            if (this.querySelector(selector.homepage.reprint_a)) {
                let reprint_id = note_obj.getUserIdFromLink(this.querySelector(selector.homepage.reprint_a).href);
                note_obj.doneHandle(reprint_id, this, selector.homepage.reprint_name);
            }
            if (this.querySelector(selector.homepage.blockquote)) {
                let blockquote_user = this.querySelector(selector.homepage.blockquote);
                let blockquote_user_id = blockquote_user.querySelector(selector.homepage.id).textContent;
                note_obj.doneHandle(blockquote_user_id, blockquote_user, selector.homepage.show_name);
            }
            for (let at_user of this.querySelectorAll(selector.homepage.at)) {
                if (note_obj.isUsersFromLink(at_user.href)) {
                    let at_user_id = note_obj.getUserIdFromLink(at_user.href);
                    note_obj.doneHandle(at_user_id, at_user, "", true);
                }
            }
        });
        document.querySelector(selector.root).arrive(selector.userpage.main, {fireOnAttributesModification: true, existing: true}, function() {
            let user_id = this.querySelector(selector.userpage.id).textContent;
            let user_name = this.querySelector(selector.userpage.show_name).textContent;
            var follow_note_btn;
            if (this.querySelector(selector.userpage.follow)) {
                follow_note_btn = note_obj.createNoteBtn(user_id, user_name, function() {
                    save_Event(user_id, note_obj);
                }, 'my_before_follow_note_btn css-901oao');
                this.querySelector(selector.userpage.follow).insertAdjacentElement('afterbegin', follow_note_btn);
            }
            note_obj.doneHandle(user_id, this, selector.userpage.show_name);
            let user_id_change = new MutationObserver(() => {
                let new_user_id = this.querySelector(selector.userpage.id).textContent;
                note_obj.doneHandle("", this, selector.userpage.show_name);
                let new_user_name = this.querySelector(selector.userpage.show_name).textContent;
                if (follow_note_btn) {
                    follow_note_btn.parentNode.removeChild(follow_note_btn);
                    follow_note_btn = note_obj.createNoteBtn(new_user_id, new_user_name, function() {
                        save_Event(new_user_id, note_obj);
                    }, 'my_before_follow_note_btn css-901oao');
                    this.querySelector(selector.userpage.follow).insertAdjacentElement('afterbegin', follow_note_btn);
                }
                note_obj.doneHandle(new_user_id, this, selector.userpage.show_name);
            });
            let user_id_change_container = this.querySelector(selector.userpage.main_user_id);
            let user_id_change_option = {
                'subtree': true,
                'characterData': true
            };
            user_id_change.observe(user_id_change_container, user_id_change_option);
        });
        document.querySelector(selector.root).arrive(selector.homepage.user_frame, {fireOnAttributesModification: true, existing: true}, function() {
            let user_id = this.querySelector(selector.userpage.id).textContent;
            note_obj.doneHandle(user_id, this, selector.homepage.show_name);
        });
    }
    Promise.all([GM_getValue('twitter_config')]).then(function(data) {
        let twitter_config = {
            users_array: []
        };
        if (data[0] !== undefined) {
            twitter_config = data[0];
        }
        init(twitter_config);
    }).catch(function(e) {
        console.error('Script error.');
        console.error(e);
    });
})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址