您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
Reply to messages on HF Convo with formatted text
- // ==UserScript==
- // @name HFReply
- // @version 2025-02-15
- // @description Reply to messages on HF Convo with formatted text
- // @author NovoDev
- // @match https://hackforums.net/*
- // @grant none
- // @license MIT
- // @namespace https://greasyfork.org/users/1435467
- // ==/UserScript==
- (function () {
- 'use strict';
- function addReplyButtons() {
- const messageContainerXPath = "/html/body/div[3]/div[3]/div/div[3]/div[3]/div/div[2]/div[3]";
- const commentBox = document.evaluate("//*[@id='comment']", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
- if (!commentBox) {
- console.error("Comment box not found");
- return;
- }
- const container = document.evaluate(messageContainerXPath, document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
- if (!container) {
- console.error("Message container not found");
- return;
- }
- const observer = new MutationObserver(() => {
- const messages = container.querySelectorAll(".message-convo-left, .message-convo-right, .message-convo-follow");
- messages.forEach((msg) => {
- if (msg.dataset.replyAdded) return;
- const isOwnMessage = msg.classList.contains("message-convo-right");
- if (isOwnMessage) return;
- const messageText = msg.textContent.trim().toLowerCase();
- if (messageText.includes("/flip") || messageText.includes("/jackpot")) {
- return;
- }
- msg.dataset.replyAdded = "true";
- let nameElement = msg.querySelector("[data-profile-username] a strong");
- if (!nameElement) {
- let prevMsg = msg.previousElementSibling;
- while (prevMsg) {
- nameElement = prevMsg.querySelector("[data-profile-username] a strong");
- if (nameElement) break;
- prevMsg = prevMsg.previousElementSibling;
- }
- }
- const textContainers = msg.querySelectorAll(".message-bubble-message");
- if (nameElement && textContainers.length > 0) {
- let replyText = `@${nameElement.textContent.trim()}@ : ***"`;
- textContainers.forEach(container => {
- const textSpans = container.querySelectorAll("span");
- textSpans.forEach(span => {
- replyText += `${span.textContent.trim()} `;
- });
- });
- replyText = replyText.trim() + `"***`;
- const replyButton = document.createElement("span");
- replyButton.innerHTML = `
- <span style="
- cursor: pointer;
- color: #fff;
- background: #2563eb;
- padding: 4px 8px;
- margin-left: 10px;
- font-size: 12px;
- border-radius: 6px;
- display: inline-flex;
- align-items: center;
- gap: 4px;
- transition: filter 0.2s;
- ">
- <svg viewBox="0 0 24 24" width="12" height="12" fill="currentColor">
- <path d="M10 9V5l-7 7 7 7v-4.1c5 0 8.5 1.6 11 5.1-1-5-4-10-11-11z"/>
- </svg>
- Reply
- </span>
- `;
- replyButton.onmouseenter = () => {
- replyButton.firstElementChild.style.filter = "brightness(0.9)";
- };
- replyButton.onmouseleave = () => {
- replyButton.firstElementChild.style.filter = "none";
- };
- replyButton.onclick = () => {
- commentBox.value = `${replyText}\n${commentBox.value}`;
- commentBox.focus();
- commentBox.scrollIntoView();
- };
- textContainers[textContainers.length - 1].appendChild(replyButton);
- }
- });
- });
- observer.observe(container, { childList: true, subtree: true });
- }
- window.addEventListener("load", addReplyButtons);
- })();