Greasy Fork

Greasy Fork is available in English.

妖火网增强插件

获得焦点时回复框自动停靠、加载更多楼层、回复任意楼层、异步评论、双击定位评论区、发帖增强、图床直达、超链图片回复

当前为 2022-09-27 提交的版本,查看 最新版本

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         妖火网增强插件
// @namespace    https://yaohuo.me/
// @version      0.45
// @description  获得焦点时回复框自动停靠、加载更多楼层、回复任意楼层、异步评论、双击定位评论区、发帖增强、图床直达、超链图片回复
// @author       外卖不用券(id:23825)
// @match        https://*.yaohuo.me/*
// @icon         https://yaohuo.me/css/favicon.ico
// @license      MIT
// ==/UserScript==

if (
    /^\/bbs-.*\.html$/.test(window.location.pathname) ||
    "/bbs/book_view.aspx" === window.location.pathname
) {
    // 回复框停靠
    let content = document.getElementsByClassName("content")[1];
    let form = document.getElementsByName("f")[0];
    content.removeChild(form);
    let newDiv = document.createElement("div");
    let clazz = document.createAttribute("class");
    clazz.value = "sticky";
    newDiv.setAttributeNode(clazz);
    newDiv.style.cssText = "padding: 7px; background-color: #fff";
    newDiv.innerHTML = form.outerHTML;
    document.body.insertBefore(newDiv, content);
    let sticky = false;
    newDiv.onclick = () => {
        let form = document.getElementsByName("f")[0];
        let sendmsg = document.getElementsByName("sendmsg")[0];
        let span = document.createElement("span");
        let textNode = document.createTextNode("取消回复停靠");
        span.appendChild(textNode);
        span.style.cssText = "float: right";
        span.onclick = (e) => {
            e.cancelBubble = true;
            newDiv.style.cssText = "padding: 7px; background-color: #fff";
            form.removeChild(span);
            sticky = false;
        };
        if (!sticky) {
            newDiv.style.cssText =
                "position: sticky; top: 0; bottom: 0; padding: 7px; background-color: #fff";
            form.insertBefore(span, sendmsg);
            sticky = true;
        }
    };
    // 加载更多回复
    let more = document.getElementsByClassName("more")[0];
    if (more) {
        let moreLink = more.getElementsByTagName("a")[0];
        let totalpage = Math.ceil(
            /getTotal=\d+/.exec(moreLink.href)[0].slice(9) / 15
        );
        let currpage = 1;
        // let topage = parseInt(/&page=\d+/.exec(moreLink.href)[0].slice(6));
        let topage = 2;
        let tourl = moreLink.href.replace("&page=" + topage, "");
        //   more.removeChild(moreLink);
        let newMoreLink = document.createElement("a");
        let span1 = document.createElement("span");
        let span1_id = document.createAttribute("id");
        span1_id.value = "YH_show_loadimg";
        span1.setAttributeNode(span1_id);
        newMoreLink.appendChild(span1);
        let span2 = document.createElement("span");
        let span2_id = document.createAttribute("id");
        span2_id.value = "YH_show_tip";
        span2.setAttributeNode(span2_id);
        span2.appendChild(
            document.createTextNode("加载更多(" + currpage + "/" + totalpage + ")")
        );
        newMoreLink.appendChild(span2);
        newMoreLink.style.width = "50%";
        more.appendChild(newMoreLink);
        moreLink.style.width = "50%";
        more.appendChild(moreLink);
        newMoreLink.onclick = () =>
            YH_show_next(totalpage, 15, currpage, tourl, "page");
    }
    // 回复任意楼层
    replyAny();
    // 双击定位评论区
    let bbscontent = document.getElementsByClassName("bbscontent")[0];
    bbscontent.ondblclick = () =>
        document.getElementsByClassName("sticky")[0].scrollIntoView(true);
    // 妖火图床、超链接、图片
    form = document.getElementsByName("f")[0];
    form.removeChild(form.lastChild);
    form.insertAdjacentHTML(
        "beforeend",
        `<span style='float: right; padding-right: 10px'>
          <span id='ubb_url' style='font-size:14px; margin-left: 10px'>超链</span>
        <span id='ubb_img' style='font-size:14px; margin-left: 10px'>图片</span>
        <a href='https://yh-pic.ihcloud.net/' style='font-size:14px; margin-left: 10px'>图床</a>
        </span><br>`
    );
    // 超链接
    const textarea = document.querySelector(
        "body > div.sticky > form > textarea"
    );
    document.getElementById("ubb_url").addEventListener("click", (e) => {
        e.preventDefault();
        insertText(textarea, "[url][/url]", 6);
    });
    document.getElementById("ubb_img").addEventListener("click", (e) => {
        e.preventDefault();
        insertText(textarea, "[img][/img]", 6);
    });
    // 异步评论
    let submitBtn = document.getElementsByName('g')[0];
    submitBtn.onclick = function(e) {
        const formData = new FormData(document.forms[0]);
        const entries = formData.entries();
        const data = Object.fromEntries(entries);
        data.g = '快速回复';
        if (data.content.length > 0) {
            e.preventDefault(); // 阻止表单提交事件
            // console.log(data);
            fetch('/bbs/book_re.aspx', { // 异步POST请求表单
                method: 'POST',
                headers: {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                },
                body: new URLSearchParams(data)
            }).then(res => {
                return res.text(); // 回复成功
            }).then(html => {
                let recontenttip = /class="tip">(.*?)<\/div>/.exec(html)[1]; // 回复提示
                // console.log(recontenttip)
                let tip = '';
                if (recontenttip.includes('回复成功')) {
                    tip = '<div class="ui__alert" style="z-index: 9999;"><div class="ui__alert_bg in"></div> <div class="ui__alert_content in"> <div class="ui__content_body"><h4 class="ui__title">回复成功</h4><div>获得妖晶' + /\d+/.exec(recontenttip)[0] + ',经验10</div> </div></div></div>';
                } else {
                    tip = '<div class="ui__alert" style="z-index: 9999;"><div class="ui__alert_bg in"></div> <div class="ui__alert_content in"> <div class="ui__content_body"><h4 class="ui__title">请不要发重复内容!</h4> </div></div></div>';
                }
                document.getElementsByName("content")[0].value = '';
                let recontent = document.getElementsByClassName('recontent')[0];
                fetch('/bbs-' + data.id + '.html').then(res => res.text()).then(html => { // 异步GET请求页面
                    // 重新渲染评论区
                    let newcontent = /recontent">(.*?)<div.class="more"/.exec(html)[1];
                    recontent.innerHTML = '<div id="retip">' + tip + '</div>' + newcontent;
                });
                setTimeout(() => {
                    document.getElementById('retip').style.display = 'none';
                }, 2000); // 2s后提示自动消失
            })
        }
    }
} else if (
    "/bbs/book_re.aspx" === window.location.pathname &&
    !window.location.search
) {
    // 回复后快速返回
    // window.location.href = document
    //     .getElementsByClassName("tip")[0]
    //     .getElementsByTagName("a")[0].href;  // 2022/09/27 论坛已自动跳转
} else if (
    [
        "/bbs/book_view_add.aspx",
        "/bbs/book_view_sendmoney.aspx",
        "/bbs/book_view_addvote.aspx",
        "/bbs/book_view_addfile.aspx",
        "/bbs/book_view_mod.aspx",
    ].includes(window.location.pathname)
) {
    let bookContent = document.getElementsByName("book_content")[0];
    bookContent.insertAdjacentHTML(
        "beforebegin",
        `<div class='btBox'>
          <div class='bt2'>
              <a style='width:25%' id='ubb_a'>超链接</a>
              <a style='width:25%' id='ubb_img'>图片</a>
              <a style='width:25%' id='ubb_movie'>视频</a>
              <a style='width:25%' id='ubb_more'">更多...</a>
          </div>
      </div>
      <div class='more_ubb_tools' style='display: none'>
          <div class='btBox'>
              <div class='bt2'>
                  <a style='width:25%' id='ubb_f'>颜色</a>
                  <a style='width:25%' id='ubb_b'">加粗</a>
                  <a style='width:25%' id='ubb_s'>删除</a>
                  <a style='width:25%' id='ubb_audio'>音频</a>
              </div>
          </div>
          <div class='btBox'>
              <div class='bt2'>
                  <a href='https://yaohuo.me/tuchuang/'>妖火图床</a>
                  <a href='https://aapi.eu.org/dy'>好记解析</a>
              </div>
          </div>
      </div>`
    );
    document.getElementById("ubb_a").addEventListener("click", () => {
        insertText(bookContent, "[url][/url]", 6);
    });
    document.getElementById("ubb_f").addEventListener("click", () => {
        insertText(bookContent, "[forecolor=#FF0000][/forecolor]", 12);
    });
    document.getElementById("ubb_b").addEventListener("click", () => {
        insertText(bookContent, "[b][/b]", 4);
    });
    document.getElementById("ubb_s").addEventListener("click", () => {
        insertText(bookContent, "[strike][/strike]", 9);
    });
    document.getElementById("ubb_img").addEventListener("click", () => {
        insertText(bookContent, "[img][/img]", 6);
    });
    document.getElementById("ubb_movie").addEventListener("click", () => {
        insertText(bookContent, "[movie=100%*100%][/movie]", 8);
    });
    document.getElementById("ubb_audio").addEventListener("click", () => {
        insertText(bookContent, "[audio=X][/audio]", 8);
    });
    document.getElementById("ubb_more").addEventListener("click", () => {
        let ubb_tool = document.getElementsByClassName("more_ubb_tools")[0];
        ubb_tool.style.display =
            ubb_tool.style.display === "none" ? "block" : "none";
    });
}

function insertText(obj, str, offset) {
    if (document.selection) {
        var sel = document.selection.createRange();
        sel.text = str;
    } else if (
        typeof obj.selectionStart === "number" &&
        typeof obj.selectionEnd === "number"
    ) {
        var startPos = obj.selectionStart,
            endPos = obj.selectionEnd,
            cursorPos = startPos,
            tmpStr = obj.value;
        obj.value =
            tmpStr.substring(0, startPos) +
            str +
            tmpStr.substring(endPos, tmpStr.length);
        cursorPos += str.length;
        obj.selectionStart = obj.selectionEnd = cursorPos - offset;
    } else {
        console.log("///");
        console.log(obj.value);
        obj.value += str;
    }
    obj.focus();
}

function replyAny() {
    let sticky = document.getElementsByClassName("sticky")[0];
    let recontent = document.getElementsByClassName("recontent")[0].childNodes;
    for (let i = 0; i < recontent.length; i++) {
        try {
            let replyLink = recontent[i].getElementsByTagName("a")[0].href;
            recontent[i].onclick = () => {
                let reply = /reply=\d+/.exec(replyLink)[0].slice(6);
                let touserid = /touserid=\d+/.exec(replyLink)[0].slice(9);
                sticky.style.cssText =
                    "position: sticky; top: 0; bottom: 0; padding: 7px; background-color: #fff";
                sticky.click();
                let form = document.getElementsByName("f")[0];
                if (form.firstChild.tagName === "B") {
                    form.removeChild(form.firstChild);
                    form.removeChild(form.firstChild);
                    form.removeChild(form.firstChild);
                    form.removeChild(form.firstChild);
                }
                form.insertAdjacentHTML(
                    "afterbegin",
                    "<b>回复" +
                    reply +
                    '楼</b><select name="sendmsg2"><option value="1">通知对方</option><option value="0">不予通知</option></select><span class="noreply" style="float: right">取消回复楼层</span><br>'
                );
                if (form.lastChild.tagName === "INPUT") {
                    form.removeChild(form.lastChild);
                    form.removeChild(form.lastChild);
                }
                form.insertAdjacentHTML(
                    "beforeend",
                    '<input type="hidden" name="reply" value="' + reply + '">'
                );
                form.insertAdjacentHTML(
                    "beforeend",
                    '<input type="hidden" name="touserid" value="' + touserid + '">'
                );
                document.getElementsByClassName("noreply")[0].onclick = () => {
                    form.removeChild(form.firstChild);
                    form.removeChild(form.firstChild);
                    form.removeChild(form.firstChild);
                    form.removeChild(form.firstChild);
                    form.removeChild(form.lastChild);
                    form.removeChild(form.lastChild);
                };
            };
        } catch (error) {}
    }
}

// YH_common.js
var xmlhttp = null;
var YH_now_currpage = 0;
var YH_page_total = 0;
var YH_scoll_downEnd = 0;

function YH_show_next(YH_total, YH_pagesize, YH_currpage, tourl, pagetype) {
    YH_page_total = parseInt(YH_total);
    var pagesize = parseInt(YH_pagesize);
    var currpage = parseInt(YH_currpage);
    if (YH_now_currpage == 0) {
        YH_now_currpage = currpage + 1;
    } else {
        YH_now_currpage = YH_now_currpage + 1;
    }
    document.getElementById("YH_show_loadimg").innerHTML =
        '<span id="loadimg">&nbsp;</span>';
    document.getElementById("YH_show_tip").innerHTML =
        "正在努力加载(" + YH_now_currpage + "/" + YH_page_total + ")中";
    if (YH_now_currpage > YH_page_total) {
        document.getElementById("YH_show_loadimg").innerHTML = "";
        document.getElementById("YH_show_tip").innerHTML = "没有更多了";
    } else {
        tourl = tourl + "&" + pagetype + "=" + YH_now_currpage;
        LoadXML_Async(tourl);
    }
}

function LoadXML_Async(tourl) {
    try {
        if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
            if (xmlhttp.overrideMimeType) {
                xmlhttp.overrideMimeType("text/xml");
            }
        } else if (window.ActiveXObject) {
            var activexName = ["MSXML2.XMLHTTP", "Microsoft.XMLHTTP", ""];
            for (var i = 0; i < activexName.length; i++) {
                try {
                    xmlhttp = new ActiveXObject(activexName[i]);
                    break;
                } catch (e) {}
            }
        }
        xmlhttp.onreadystatechange = YH_CallBack;
        xmlhttp.open("GET", tourl, true);
        xmlhttp.send(null);
    } catch (e) {
        document.getElementById("YH_show_loadimg").innerHTML =
            '<span id="loadimg">&nbsp;</span>';
        document.getElementById("YH_show_tip").innerHTML = "加载出错了!";
    }
}

function YH_CallBack() {
    if (xmlhttp == null) {
        return;
    }
    if (xmlhttp.readyState == 4) {
        if (xmlhttp.status == 200) {
            var responseText = xmlhttp.responseText;
            var st = responseText.indexOf("<!--listS-->");
            var et = responseText.indexOf("<!--listE-->");
            if (st < 0 || et < 0) {
                document.getElementById("YH_show_loadimg").innerHTML = "";
                document.getElementById("YH_show_tip").innerHTML = "加载完全部了!";
            } else {
                responseText = responseText.substring(st + 12, et);
                document.getElementsByClassName("recontent")[0].style.display = "block";
                document.getElementsByClassName("recontent")[0].innerHTML +=
                    responseText;
                replyAny();
                if (YH_now_currpage == YH_page_total) {
                    document.getElementById("YH_show_loadimg").innerHTML = "";
                    document.getElementById("YH_show_tip").innerHTML = "没有更多了";
                } else {
                    document.getElementById("YH_show_loadimg").innerHTML = "";
                    document.getElementById("YH_show_tip").innerHTML =
                        "加载更多(" + YH_now_currpage + "/" + YH_page_total + ")";
                }
            }
        }
    }
}