Greasy Fork

Greasy Fork is available in English.

Twitter - 为用户添加备注(别名/标签)

为用户添加备注(别名/标签)功能,以帮助识别和搜索

目前为 2023-01-12 提交的版本,查看 最新版本

// ==UserScript==
// @name                Twitter - Add notes to the user
// @name:zh-CN          Twitter - 为用户添加备注(别名/标签)
// @name:zh-TW          Twitter - 為用戶添加備註(別名/標籤)
// @name:ja             Twitter - ユーザーへのメモの追加(エイリアス/ラベル)
// @name:ko             Twitter - 사용자에게 메모 추가 (별칭/라벨)
// @name:fr             Twitter - ajouter des notes aux utilisateurs (alias/tag)
// @namespace           http://greasyfork.icu/zh-CN/users/193133-pana
// @homepage            http://greasyfork.icu/zh-CN/users/193133-pana
// @icon                data:image/svg+xml;base64,PHN2ZyByb2xlPSJpbWciIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgd2lkdGg9IjI0cHgiIGhlaWdodD0iMjRweCIgdmlld0JveD0iMCAwIDI0IDI0IiBhcmlhLWxhYmVsbGVkYnk9Im5ld0ljb25UaXRsZSIgc3Ryb2tlPSJyZ2JhKDI5LDE2MSwyNDIsMS4wMCkiIHN0cm9rZS13aWR0aD0iMiIgc3Ryb2tlLWxpbmVjYXA9InNxdWFyZSIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgZmlsbD0ibm9uZSIgY29sb3I9InJnYmEoMjksMTYxLDI0MiwxLjAwKSI+IDx0aXRsZSBpZD0ibmV3SWNvblRpdGxlIj5OZXc8L3RpdGxlPiA8cGF0aCBkPSJNMTkgMTRWMjJIMi45OTk5N1Y0SDEzIi8+IDxwYXRoIGQ9Ik0xNy40NjA4IDQuMDM5MjFDMTguMjQxOCAzLjI1ODE3IDE5LjUwODIgMy4yNTgxNiAyMC4yODkyIDQuMDM5MjFMMjAuOTYwOCA0LjcxMDc5QzIxLjc0MTggNS40OTE4NCAyMS43NDE4IDYuNzU4MTcgMjAuOTYwOCA3LjUzOTIxTDExLjU4NTggMTYuOTE0MkMxMS4yMTA3IDE3LjI4OTMgMTAuNzAyIDE3LjUgMTAuMTcxNiAxNy41TDcuNSAxNy41TDcuNSAxNC44Mjg0QzcuNSAxNC4yOTggNy43MTA3MSAxMy43ODkzIDguMDg1NzkgMTMuNDE0MkwxNy40NjA4IDQuMDM5MjFaIi8+IDxwYXRoIGQ9Ik0xNi4yNSA1LjI1TDE5Ljc1IDguNzUiLz4gPC9zdmc+
// @version             4.4.2
// @description         Add a note(alias/tag) for users to help identify and search
// @description:zh-CN   为用户添加备注(别名/标签)功能,以帮助识别和搜索
// @description:zh-TW   為用戶添加備註(別名/標籤)功能,以幫助識別和搜尋
// @description:ja      ユーザーが識別と検索に役立つメモ(エイリアス/タグ)機能を追加する
// @description:ko      사용자 식별 및 검색에 도움이되는 메모 (별칭/태그) 기능 추가
// @description:fr      Ajouter une fonction de notes (alias/tag) pour les utilisateurs pour aider à identifier et rechercher
// @author              pana
// @license             GNU General Public License v3.0 or later
// @compatible          chrome
// @compatible          firefox
// @match               *://*twitter.com/*
// @require             https://gcore.jsdelivr.net/npm/[email protected]/minified/arrive.min.js
// @require             https://gcore.jsdelivr.net/npm/[email protected]/dist/vue.min.js
// @require             https://gcore.jsdelivr.net/gh/LightAPIs/greasy-fork-library@59abf2b972ae76013a5bb936a11bbf72869785e0/Note_Obj.js
// @noframes
// @grant               GM_info
// @grant               GM.info
// @grant               GM_getValue
// @grant               GM.getValue
// @grant               GM_setValue
// @grant               GM.setValue
// @grant               GM_deleteValue
// @grant               GM.deleteValue
// @grant               GM_listValues
// @grant               GM.listValues
// @grant               GM_openInTab
// @grant               GM.openInTab
// @grant               GM_registerMenuCommand
// @grant               GM_unregisterMenuCommand
// @grant               GM_addValueChangeListener
// @grant               GM_removeValueChangeListener
// ==/UserScript==

(async function () {
  'use strict';
  if (typeof Note_Obj !== 'function') {
    alert('Note_Obj.js was not loaded successfully!');
  }
  const UPDATED = '2023-01-12';
  const TWITTER_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+)',
  };
  const TWITTER_STYLE = `
    .note-obj-twitter-blue-tag {
        background-color: #3c81df;
        color: #fff;
        display: inline-flex;
        align-items: center;
        padding: 2px 10px;
        line-height: 100%;
        border-radius: 50px;
    }
    .note-obj-twitter-note-btn {
        background-image: ${TWITTER_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;
    }
    .note-obj-twitter-note-btn:hover {
        background-image: ${TWITTER_ICON.NOTE_BLUE};
        background-color: rgba(29, 161, 242, .1);
    }
    .note-obj-twitter-panel-btn {
        height: 32px;
        width: 32px;
        margin: 5px 0px 0px 0px;
        background-size: 28px auto;
        cursor: pointer !important;
        border-radius: 0px;
    }
    .note-obj-twitter-panel-btn:hover::after {
        content: "";
        display: flex;
        position: relative;
        background-color: rgba(29, 161, 242, .1);
        width: 48px;
        height: 48px;
        top: -8px;
        left: -8px;
        border-radius: 99px;
    }
    .note-obj-twitter-before-follow-note-btn {
        height: 36px;
        width: 36px;
        background-image: ${TWITTER_ICON.NOTE_BLUE};
        background-repeat: no-repeat;
        background-size: 19px auto;
        background-position: center;
        margin-bottom: 12px;
        margin-right: 12px;
        cursor: pointer;
        border: 1px solid rgba(29, 161, 242, 1);
        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;
    }
    .note-obj-twitter-before-follow-note-btn:hover {
        background-color: rgba(29, 161, 242, .1);
    }
    .note-obj-twitter-base-tool-bar-btn {
        height: 18px;
        width: 18px;
        margin: 0px -40px 0px 0px;
        background-size: 20px auto;
        border-radius: 0px;
    }
    .note-obj-twitter-base-tool-bar-btn:hover::after {
        content: "";
        position: absolute;
        background-color: rgba(29, 161, 242, .1);
        width: 34px;
        height: 34px;
        top: -8px;
        left: -8px;
        border-radius: 99px;
    }
    .note-obj-twitter-comment-tool-bar-btn {
        height: 24px;
        width: 24px;
        margin: 12px 0px 0px 0px;
        background-size: 24px auto;
        border-radius: 0px;
        cursor: pointer;
    }
    .note-obj-twitter-comment-tool-bar-btn:hover::after {
        content: "";
        position: absolute;
        background-color: rgba(29, 161, 242, .1);
        width: 38px;
        height: 38px;
        top: -8px;
        left: -8px;
        border-radius: 99px;
    }
    .note-obj-twitter-left-box {
        height: 50%;
    }`;
  const selector = {
    root: '#react-root div .r-13awgt0.r-12vffkv',
    homepage: {
      id: 'div[data-testid="User-Names"] a[role="link"] > div[dir] > span',
      article: 'article',
      toolBar: '.css-1dbjc4n.r-18u37iz.r-1wtj0ep.r-1mdbhws',
      showName: 'div[data-testid="User-Names"] a[role="link"] > div > div[dir] > span',
      reprintA: '.css-1dbjc4n.r-1habvwh.r-16y2uox a',
      reprintName: ':scope > span:first-of-type > span',
      at: 'a.css-4rbku5.css-18t94o4.css-901oao.css-16my406.r-1loqt21.r-bcqeeo.r-qvutc0',
      userFrame: '.css-18t94o4.css-1dbjc4n.r-1loqt21.r-1wbh5a2.r-dnmrzs.r-1ny4l3l',
      blockquote: 'div[aria-labelledby][id] > .css-1dbjc4n > div[role="link"]',
      blockquoteId: ':scope div[tabindex] .css-1dbjc4n > div[dir] > span',
      blockquoteShowName: 'div[data-testid="UserAvatar-Container-unknown"]',
    },
    userpage: {
      main: '.css-1dbjc4n.r-1ifxtd0.r-ymttw5.r-ttdzmv',
      id: '[data-testid="UserName"] .css-1dbjc4n.r-18u37iz.r-1wbh5a2 span',
      showName: '[data-testid="UserName"] .css-901oao.r-1vr29t4.r-bcqeeo.r-qvutc0 > span',
      follow: '.css-1dbjc4n.r-obd0qt.r-18u37iz.r-1w6e6rj.r-1h0z5md.r-dnmrzs',
    },
    comment: {
      toolBar: '.css-1dbjc4n.r-1oszu61.r-1efd50x.r-5kkj8d.r-18u37iz.r-a2tzq0',
    },
    hover: {
      panel: 'div[data-testid="HoverCard"] .r-nsbfu8',
      followBtn: '.css-1dbjc4n.r-bcqeeo',
      id: 'a[role="link"]',
      showName: 'a[role="link"] > div > [dir] > span',
    },
    modal: {
      cell: '[aria-labelledby="modal-header"] [data-testid="UserCell"]',
      id: 'a[role="link"]',
      showName: 'a[role="link"] > div > [dir] > span',
    },
    follow: {
      cell: '[data-testid="cellInnerDiv"] [data-testid="UserCell"]',
      id: 'a[role="link"]',
      showName: 'a[role="link"] > div > [dir] > span',
    },
    rightRecommended: {
      cell: '[role="complementary"] [data-testid="UserCell"]',
      id: 'a[role="link"]',
      showName: 'a[role="link"] > div > [dir]',
    },
    note: {
      button: '.note-obj-add-note-btn',
    },
  };
  const noteObj = new Note_Obj('myTwitterNote');
  await noteObj.init({
    style: selector.homepage.showName + ', ' + selector.modal.showName + ' { white-space: normal; }\n' + TWITTER_STYLE,
    changeEvent: changeEvent,
    settings: {
      showToolbarButton: {
        type: 'checkbox',
        lang: {
          en: 'Display the "Add Note" button in the toolbar below each tweet (if there is no such button in the user\'s hover information panel, this option can be turned on)',
          zh_cn: '在每条推特下方的工具栏里显示"添加备注"按钮 (如果在用户的悬停信息面板里没有此按钮时,可以打开此选项)',
          zh_tw: '在每條推特下方的工具欄裡顯示"添加備註"按鈕 (如果在用戶的懸停資訊面板裡沒有此按鈕時,可以打開此選項)',
          ja: '各Twitterの下のツールバーに“備考追加”ボタンが表示されます(ユーザのホバリング情報パネルにこのボタンがない場合は、このオプションを開くことができます)',
          ko: '각 트위터 아래의 도구 모음에 "메모 추가" 단추가 표시됩니다(사용자의 롤오버 정보 패널에 이 단추가 없는 경우 이 옵션을 설정할 수 있음)',
          fr: "Afficher le bouton \"Ajouter une note\" dans la barre d'outils sous chaque tweet (S'il n'y a pas de bouton de ce type dans le panneau d'informations de survol de l'utilisateur, vous pouvez activer cette option)",
        },
        default: false,
        event: insertToolbarButtonEvent,
      },
      disableInTweets: {
        type: 'checkbox',
        lang: {
          en: 'Disable replaces peoples @username to @note in tweets',
          zh_cn: '禁止将推文中的用户 @username 替换为 @note',
          zh_tw: '禁止將推文中的使用者 @username 替换为 @note',
          ja: '無効にすると、ツイート内のユーザーの@usernameが@noteに置き換えられます',
          ko: '비활성화는 트윗에서 @username을 @note로 대체합니다',
          fr: "Désactiver remplace le @nom d'utilisateur par @note dans les tweets",
        },
        default: false,
        event: disableInTweetsEvent,
      },
    },
    script: {
      author: {
        name: 'pana',
        homepage: 'http://greasyfork.icu/zh-CN/users/193133-pana',
      },
      address: 'http://greasyfork.icu/scripts/404587',
      updated: UPDATED,
      library: [
        {
          name: 'arrive.js',
          version: '2.4.1',
          url: 'https://github.com/uzairfarooq/arrive',
        },
      ],
    },
    leftBtnBoxClassName: 'note-obj-twitter-left-box',
  });
  function atFilter(text) {
    return text.replace(/^@/, '');
  }
  function hrefComparator(href) {
    return /^[^/]+$/i.test(href);
  }
  function toolBarNoteButton(ele, state) {
    const eleId = Note_Obj.fn.getTextContent(ele, selector.homepage.id, atFilter);
    if (eleId) {
      const eleName = Note_Obj.fn.getTextContent(ele, selector.homepage.showName, undefined, 'info');
      const homepageToolBar = Note_Obj.fn.query(ele, selector.homepage.toolBar, 'info');
      const commentToolBar = Note_Obj.fn.query(ele, selector.comment.toolBar, 'info');
      if (homepageToolBar) {
        const homepageToolBarBtn = Note_Obj.fn.querySelector(homepageToolBar, selector.note.button);
        if (state) {
          !homepageToolBarBtn &&
            homepageToolBar.appendChild(
              noteObj.createNoteBtn(eleId, eleName, ['note-obj-twitter-note-btn', 'note-obj-twitter-base-tool-bar-btn', 'css-1dbjc4n'])
            );
        } else {
          homepageToolBarBtn && homepageToolBarBtn.remove();
        }
      }
      if (commentToolBar) {
        const commentToolBarBtn = Note_Obj.fn.querySelector(commentToolBar, selector.note.button);
        if (state) {
          !commentToolBarBtn &&
            commentToolBar.appendChild(
              noteObj.createNoteBtn(eleId, eleName, ['note-obj-twitter-note-btn', 'note-obj-twitter-comment-tool-bar-btn', 'css-1dbjc4n'])
            );
        } else {
          commentToolBarBtn && commentToolBarBtn.remove();
        }
      }
    }
  }
  function homepageNote(ele, curId = undefined) {
    const eleId = Note_Obj.fn.getTextContent(ele, selector.homepage.id, atFilter);
    if (eleId) {
      if (curId) {
        curId == eleId &&
          noteObj.handler(eleId, ele, selector.homepage.showName, {
            add: 'span',
            classname: 'note-obj-twitter-blue-tag',
          });
      } else {
        const eleName = Note_Obj.fn.getTextContent(ele, selector.homepage.showName, undefined, 'info');
        noteObj.judgeUsers(eleId) &&
          noteObj.handler(
            eleId,
            ele,
            selector.homepage.showName,
            {
              add: 'span',
              classname: 'note-obj-twitter-blue-tag',
            },
            eleName
          );
      }
    }
  }
  function reprintANote(ele, curId = undefined) {
    const reprintA = Note_Obj.fn.queryA(ele, selector.homepage.reprintA, 'info');
    if (reprintA) {
      const eleId = Note_Obj.fn.getUserIdFromLink(reprintA.href);
      if ((curId && curId == eleId) || (!curId && noteObj.judgeUsers(eleId))) {
        noteObj.handler(eleId, reprintA, selector.homepage.reprintName, {
          add: 'span',
          classname: 'note-obj-twitter-blue-tag',
          symbol: {
            offsetWidth: 30,
          },
        });
      }
    }
  }
  function blockquoteNote(ele, curId = undefined) {
    const blockquote = Note_Obj.fn.query(ele, selector.homepage.blockquote, 'info');
    if (blockquote) {
      const blockquoteUser = Note_Obj.fn.query(blockquote, selector.homepage.blockquoteShowName);
      if (blockquoteUser) {
        const bn = blockquoteUser.nextElementSibling;
        if (bn) {
          const eleId = Note_Obj.fn.getTextContent(blockquote, selector.homepage.blockquoteId, atFilter);
          if ((curId && curId == eleId) || (!curId && noteObj.judgeUsers(eleId))) {
            noteObj.handler(eleId, bn, null, {
              add: 'span',
              classname: 'note-obj-twitter-blue-tag',
            });
          }
        }
      }
    }
  }
  function homepageAtNote(ele, state, userId = undefined) {
    for (const atUser of Note_Obj.fn.qAllA(ele, selector.homepage.at, 'info')) {
      const atUserId = Note_Obj.fn.getUserIdFromLink(atUser.href, hrefComparator);
      if ((userId && userId == atUserId) || (!userId && noteObj.judgeUsers(atUserId))) {
        noteObj.handler(atUserId, atUser, null, {
          symbol: {
            prefix: '@',
          },
          restore: state,
        });
      }
    }
  }
  function userpageNote(ele, userId = undefined) {
    const eleId = Note_Obj.fn.getTextContent(ele, selector.userpage.id, atFilter);
    if (userId) {
      userId == eleId &&
        noteObj.handler(eleId, ele, selector.userpage.showName, {
          add: 'span',
          classname: 'note-obj-twitter-blue-tag',
        });
    } else {
      const eleName = Note_Obj.fn.getTextContent(ele, selector.userpage.showName, undefined, 'info');
      noteObj.judgeUsers(eleId) &&
        noteObj.handler(
          eleId,
          ele,
          selector.userpage.showName,
          {
            add: 'span',
            classname: 'note-obj-twitter-blue-tag',
          },
          eleName
        );
    }
  }
  function followNote(ele, userId = undefined) {
    spanItemNote(ele, selector.follow.id, selector.follow.showName, userId);
  }
  function rightRecommendedNote(ele, userId = undefined) {
    spanItemNote(ele, selector.rightRecommended.id, selector.rightRecommended.showName, userId);
  }
  function modalNote(ele, userId = undefined) {
    spanItemNote(ele, selector.modal.id, selector.modal.showName, userId);
  }
  function spanItemNote(ele, idSelector, nameSelector, userId = undefined) {
    const eleId = Note_Obj.fn.getHrefUserId(ele, idSelector);
    if ((userId && userId == eleId) || (!userId && noteObj.judgeUsers(eleId))) {
      noteObj.handler(eleId, ele, nameSelector, {
        add: 'span',
        class: 'note-obj-twitter-blue-tag',
      });
    }
  }
  function disableInTweetsEvent(status) {
    for (const ele of document.querySelectorAll(selector.homepage.article)) {
      homepageAtNote(ele, status);
    }
  }
  function insertToolbarButtonEvent(status) {
    document.querySelectorAll(selector.homepage.article).forEach(ele => {
      toolBarNoteButton(ele, status);
    });
  }
  function changeEvent(noteObj, userId = undefined) {
    for (const ele of document.querySelectorAll(selector.homepage.article)) {
      homepageNote(ele, userId);
      reprintANote(ele, userId);
      blockquoteNote(ele, userId);
      homepageAtNote(ele, noteObj.getConfig().other.disableInTweets == true, userId);
    }
    for (const ele of document.querySelectorAll(selector.userpage.main)) {
      userpageNote(ele, userId);
    }
    for (const ele of document.querySelectorAll(selector.follow.cell)) {
      followNote(ele, userId);
    }
    for (const ele of document.querySelectorAll(selector.rightRecommended.cell)) {
      rightRecommendedNote(ele, userId);
    }
    for (const ele of document.querySelectorAll(selector.modal.cell)) {
      modalNote(ele, userId);
    }
  }
  function init() {
    const arriveOption = {
      fireOnAttributesModification: true,
      existing: true,
    };
    const rootDom = document.querySelector(selector.root);
    if (rootDom === null) {
      return;
    }
    rootDom.arrive(selector.homepage.article, arriveOption, ele => {
      toolBarNoteButton(ele, noteObj.getConfig().other.showToolbarButton == true);
      homepageNote(ele);
      reprintANote(ele);
      blockquoteNote(ele);
      const disableInTweets = noteObj.getConfig().other.disableInTweets == true;
      if (!disableInTweets) {
        homepageAtNote(ele, disableInTweets);
      }
    });
    rootDom.arrive(selector.userpage.main, arriveOption, ele => {
      const eleId = Note_Obj.fn.getTextContent(ele, selector.userpage.id, atFilter);
      if (eleId) {
        const eleName = Note_Obj.fn.getTextContent(ele, selector.userpage.showName, undefined, 'info');
        let followNoteBtn;
        const userpageFollow = Note_Obj.fn.query(ele, selector.userpage.follow);
        if (userpageFollow) {
          followNoteBtn = noteObj.createNoteBtn(eleId, eleName, ['note-obj-twitter-before-follow-note-btn', 'css-901oao']);
          userpageFollow.insertAdjacentElement('afterbegin', followNoteBtn);
        }
        const userIdChange = new MutationObserver(() => {
          const newUserId = Note_Obj.fn.getTextContent(ele, selector.userpage.id, atFilter);
          if (newUserId) {
            noteObj.handler('', ele, selector.userpage.showName, {
              add: 'span',
              classname: 'note-obj-twitter-blue-tag',
            });
            const newUserName = Note_Obj.fn.getTextContent(ele, selector.userpage.showName, undefined, 'info');
            if (followNoteBtn) {
              followNoteBtn.remove();
              followNoteBtn = noteObj.createNoteBtn(newUserId, newUserName, ['note-obj-twitter-before-follow-note-btn', 'css-901oao']);
              userpageFollow && userpageFollow.insertAdjacentElement('afterbegin', followNoteBtn);
            }
            noteObj.judgeUsers(newUserId) &&
              noteObj.handler(
                newUserId,
                ele,
                selector.userpage.showName,
                {
                  add: 'span',
                  classname: 'note-obj-twitter-blue-tag',
                },
                newUserName
              );
          }
        });
        const obId = Note_Obj.fn.query(ele, selector.userpage.id);
        obId &&
          userIdChange.observe(obId, {
            subtree: true,
            characterData: true,
          });
      }
      userpageNote(ele);
    });
    rootDom.arrive(selector.follow.cell, arriveOption, ele => {
      followNote(ele);
    });
    rootDom.arrive(selector.rightRecommended.cell, arriveOption, ele => {
      rightRecommendedNote(ele);
    });
    rootDom.arrive(selector.modal.cell, arriveOption, ele => {
      modalNote(ele);
    });
    rootDom.arrive(selector.hover.panel, arriveOption, ele => {
      const eleId = Note_Obj.fn.getHrefUserId(ele, selector.hover.id);
      if (eleId) {
        const userShowNameText = Note_Obj.fn.getTextContent(ele, selector.hover.showName, undefined, 'info');
        const hoverFollowBtn = Note_Obj.fn.query(ele, selector.hover.followBtn);
        hoverFollowBtn &&
          hoverFollowBtn.insertAdjacentElement(
            'beforebegin',
            noteObj.createNoteBtn(eleId, userShowNameText, ['note-obj-twitter-note-btn', 'note-obj-twitter-panel-btn'])
          );
        noteObj.judgeUsers(eleId) &&
          noteObj.handler(
            eleId,
            ele,
            selector.hover.showName,
            {
              add: 'span',
              class: 'note-obj-twitter-blue-tag',
            },
            userShowNameText
          );
      }
    });
  }
  init();
})();