V2EX增强插件

一些增强功能

// ==UserScript==
// @name          V2EX增强插件
// @description   一些增强功能
// @homepage      https://greasyfork.org/zh-CN/scripts/3452-v2ex%E5%A2%9E%E5%BC%BA%E6%8F%92%E4%BB%B6
// @namespace     yfmx746qpx8vhhmrgzt9s4cijmejj3tn
// @icon          http://ww1.sinaimg.cn/large/4ec98f50jw1e85azvlnh9j206y06y3ye.jpg
// @author        me
// @match         https://*.v2ex.com/*
// @match         https://v2ex.com/*
// @version       2025.03.13
// @grant         none
// ==/UserScript==

// 2024.03.08 新消息界面,回复提醒对比感谢提醒更加醒目
// 2024.02.27 回复框增加快捷回复,建议广告贴发在推广节点
// 2024.01.16 新消息界面,显示消息序号,页码链接显示序号范围
// 2024.01.08 更新管理员列表,标记回帖中漏标记的管理员
// 2023.12.27 避免链接转图片的大小超出布局
// 2021.11.26 账户余额页面增加签到页面链接
// 2020.10.19 首页增加全文搜索链接
// 2020.10.10 解决由于改版导致的定位错误导致无法签到问题
// 2019.10.25 解决Safari不能重加载新浪图片
// 2019.08.01 修正帖子tag区域的链接转图片误判
// 2019.05.12 新浪的图片反防盗链
// 2017.05.16 由于存储数据出错,改变存储数据的方式
// 2016.09.21 修复发帖页面判断用户名出错的情况
// 2016.09.14 修正判断登录状态逻辑
// 2016.05.25 链接自动转图片
// 2016.05.21 新增召唤/呼叫管理员
// 2016.05.09 Webkit内核允许修改回复框高度
// 2016.04.12 在回复时可@所有人
// 2015.10.16 新增在回复中标记楼主
// 2015.03.22 尝试修正未知原因情况下导致的签到失败。
// 2015.02.07 解决JQuery库在某种情况可能会无法载入
// 2014.10.07 某种情况下会产生cookie重复赋值,增加清理补丁。
// 2014.10.06 cookie信息过期时间改为3天


setTimeout(function(){
    // 签到
    (()=>{
        if (typeof jQuery !== 'undefined') {
            qiandao();
        } else {
            loadAndExecute("https://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.0.0.min.js", qiandao() );
        } //加载jQuery库

        //定义过程
        function qiandao() {
            if ( $("a[class='balance_area']").length > 0 && $("a[href='/settings']").length > 0 ) {
                var uid=$.find('a[href^="/member/"]')[0].innerHTML;//用户名
                var dateinfo=new Date().getUTCDate();//获得GMT时间今天几号
                var SigninInfo=uid + ":" + dateinfo + "";
                var daily = $('input[id="search"]');
                if (daily.length && localStorage.SigninInfo != SigninInfo ) {
                    $.ajax({url:"/"});
                    daily.val("正在检测每日签到状态...");
                    $.ajax({
                        url: "/mission/daily",
                        success: function(data) {
                            var awards = $(data).find('input[value^="领取"]');
                            if (awards.length) {
                                // daily.val("正在" + awards.attr("value") + "...");
                                daily.val("正在领取今日的登录奖励......");
                                $.ajax({
                                    url: awards.attr('onclick').match(/(?=\/).+?(?=\')/),
                                    success: function(data) {
                                        daily.val("正在提交...");
                                        var days=data.split("已连续登")[1].split(" ")[1];
                                        if ( $('a[href="/mission/daily"]').length==1 ) {$('a[href="/mission/daily"]').parent().parent().fadeOut(3000);}
                                        $.ajax({
                                            url: "/balance",
                                            success: function(data) {
                                                function p(s) {return s < 10 ? '0' + s: s;} //自动补0
                                                var date2="" + new Date().getUTCFullYear() + p(new Date().getUTCMonth()+1) +p(new Date().getUTCDate());
                                                if (data.indexOf(date2+" 的每日登录奖励")!="-1") {
                                                        daily.val( "已连续领取" + days + "天,本次领到" + data.split("每日登录")[2].split(" ")[1] + "铜币" );
                                                        localStorage.SigninInfo = SigninInfo;
                                                } else {
                                                        daily.val( "自动领取遇到意外,你可以试试手动领。" );
                                                }
                                            }
                                        });
                                    },
                                    error: function() {
                                            daily.val("网络异常 :(");
                                    }
                                });
                            }else{
                                    if (data.indexOf("已领取") != -1) {
                                            daily.val("今日奖励领取过了");
                                            localStorage.SigninInfo = SigninInfo;
                                    } else {
                                            daily.val("无法辩识领奖按钮 :(");
                                    }

                            }
                        },
                        error: function() {
                                daily.val("请手动领取今日的登录奖励!");
                        }
                    });
                }
            }
        }// end qiandao

        function loadAndExecute(jsurl, fun, errfun) {
            // jsurl:js文件地址;fun:js成功加载文件执行脚本/函数;errfun:js文件加载失败执行脚本/函数
            if(jsurl==null){return;}

            var jsele= document.createElement("script");
            jsele.setAttribute("src", jsurl);

            if(fun != null) {jsele.setAttribute("onload",funtostring(fun))};
            if(errfun != null) {jsele.setAttribute("onerror", funtostring(errfun))};
            document.head.appendChild(jsele);

            //传入脚本字符串直接返回,传入函数则转换为字符串。
            function funtostring(fun){
                if(typeof fun == "function"){
                    return "("+fun+")()";
                } else {
                    return fun;
                }
            }
        } //end loadAndExecute
    })(); //end 签到

    //帖子标记个别没有自动标记的管理员,回复所有人
    if (location.href.indexOf("/t/") != -1) {
    (function (){
        var modarr=["Livid","Kai","Olivia","GordianZ","sparanoid","Tink"];
        var modlist="@"+modarr.join(" @");//生成@所有管理员的列表
        var uname=document.getElementById("Rightbar").getElementsByTagName("a")[0].href.split("/member/")[1];//自己用户名
        //标记管理员,预存回复用户名列表
        var lzname=document.getElementById("Main").getElementsByClassName("avatar")[0].parentNode.href.split("/member/")[1];
        var allname='@'+lzname+' ';
        var all_elem = document.querySelectorAll('a[href^="/member"].dark');
        for(var i=0; i<all_elem.length; i++) {
            if (modlist.indexOf(all_elem[i].innerHTML)!= -1){
                if (document.getElementsByClassName("badges")[i].innerHTML.indexOf("mod") == -1){
                    document.getElementsByClassName("badges")[i].innerHTML+='<div class="badge mod">MOD</div>';
                }
            }
            //为回复所有人做准备
            if ( uname != all_elem[i].innerHTML && all_elem[i].href.indexOf("/member/") != -1
            && all_elem[i].innerText == all_elem[i].innerHTML && allname.indexOf('@'+all_elem[i].innerHTML+' ') == -1 ) {
                allname+='@'+ all_elem[i].innerHTML+' ';
            }
        }


        if ( document.getElementById("reply_content") ) {
            document.getElementById("reply_content").parentNode.innerHTML
                +="&nbsp;&nbsp;&nbsp;&nbsp;<a href='javascript:;' onclick='if ( document.getElementById(\"reply_content\").value.indexOf(\""
                +allname+"\") == -1 ) {document.getElementById(\"reply_content\").value+=\"\\r\\n"+allname+"\"}'>@所有人</a>";
            if ( document.body.style.WebkitBoxShadow !== undefined ) {
                //允许调整回复框高度
                document.getElementById("reply_content").style.resize="vertical";
            }
            document.getElementById("reply_content").style.overflow="auto";

            document.getElementById("reply_content").parentNode.innerHTML
                +="&nbsp;&nbsp;&nbsp;&nbsp;<a href='javascript:;' onclick='if ( document.getElementById(\"reply_content\").value.indexOf(\""
                +modlist+"\") == -1 ) {document.getElementById(\"reply_content\").value+=\"\\r\\n"+modlist+"\"}'>@管理员</a>";
        }
    })();
    }// end 回复所有人,@管理员

    // 帖子回复框增加快捷回复,提示广告贴应发在推广节点
    if (location.href.indexOf("/t/") != -1) {
    (function(){
        document.getElementById("reply_content").parentNode.innerHTML
            +="&nbsp;&nbsp;&nbsp;&nbsp;<a href='javascript:;' onclick='document.getElementById(\"reply_content\").value+=\"\\r\\n"+"@Livid 这贴明显是推广贴,却没有发在推广节点。"+"\"'>报告广告贴</a>";
    })()
    }// end 举报广告贴链接

    // 图片链接自动转换成图片 代码来自caoyue@v2ex
    (function (){
        var links = document.links;
        for (var i=0;i<links.length;i++){
            var link = links[i];
            if (/^http.*\.(?:jpg|jpeg|jpe|bmp|png|gif)/i.test(link.href)
                && !/<img\s/i.test(link.innerHTML) && link.href.indexOf("v2ex.com/tag")==-1){
                link.innerHTML = "<img title='" + link.href + "' src='" + link.href + "' style='max-width:98%' decoding='async' loading='lazy' />";
                // decoding='async'异步解析图像,加快显示其他内容。loading='lazy'懒加载。
            }
        }
    })();// end 图片链接自动转换成图片

    //新浪图床的图片反防盗链
    (function (){
        var images = document.images;
        for (var i=0;i<images.length;i++){
            var image = images[i];
            if ( image.src && image.src.indexOf(".sinaimg.cn")!=-1 &&image.src.indexOf(".sinaimg.cn")<13 ) {
                image.setAttribute("referrerPolicy","no-referrer");
                image.src=image.src + "?";
            }
        }
    })();// end 新浪图床的图片反防盗链

    // 首页增加全文搜索链接
    if ( location.href.split("v2ex.com")[1] == "/" && $('div[id="SecondaryTabs"]').length > 0 ) {
        document.getElementById("SecondaryTabs").innerHTML+='&nbsp;&nbsp;&nbsp;&nbsp;<a href="https://www.sov2ex.com/" title="第三方全文搜索">全文搜索</a>'
        document.getElementById("SecondaryTabs").innerHTML+='&nbsp;&nbsp;&nbsp;&nbsp;<a href="/changes" title="所有节点最新100帖">最新</a>'
    }// end 首页增加全文搜索链接

    // 在账户余额界面/明细界面的上方增加签到页面链接
    if ( location.href.indexOf("/balance") != -1 && document.getElementsByClassName("tab").length > 0) {
        document.getElementsByClassName("tab")[0].parentNode.innerHTML+='<a class="tab" href="/mission/daily" >签到</a>'
    }
    //

    // 新消息界面,显示消息序号,页码链接显示序号范围
    if (location.href.indexOf("/notifications") != -1){
    (function(){
        var page_index=new URL(window.location.href).searchParams.get('p');
        var before_index=0;
        if(page_index!=null){
            before_index=(page_index-1)*50;
        }
        document.querySelectorAll("a[onclick^=delete]").forEach((ele,i)=>{
            var index_ele=document.createElement("span");
            index_ele.innerText=(i+1+before_index)+". ";
            ele.parentElement.insertBefore(index_ele,ele.parentElement.firstElementChild)
        })
        var allmsgcount=document.querySelectorAll(".header .gray")[0].innerText;//消息总数
        document.querySelectorAll(".page_current,.page_normal").forEach((ele)=>{
            var index_a=(ele.innerText-1)*50+1;
            var index_b=(ele.innerText-1)*50+50;
            var title_str=index_a+"-"+index_b;
            if(allmsgcount-index_a<50){
                title_str=index_a+"-"+allmsgcount;
            }
            ele.setAttribute("title",title_str)
        })
    })();
    }// end 新消息界面,序号和翻页按钮优化

    // 新消息界面,回复提醒对比感谢提醒更加醒目
    if (location.href.indexOf("/notifications") != -1){
    (function(){
        if(document.querySelectorAll(".payload").length > 0){
            document.querySelectorAll(".payload").forEach((ele) => {
                if(ele.parentElement.innerText.indexOf("时提到了你") != -1
                || ele.parentElement.innerText.indexOf("里回复了你") != -1 ){
                    //1、被人@提醒。2、回复我的主题提醒。
                    ele.style.backgroundColor="#F9EA9A";
                }
            })
        }
    })();
    }// end 新消息界面优化

},0);// end