Greasy Fork

Feedly 优化

一些优化

// ==UserScript==
// @name         Feedly 优化
// @homepage     https://greasyfork.org/zh-CN/scripts/488038-feedly-%E4%BC%98%E5%8C%96
// @namespace    https://feedly.com
// @version      2025.03.06.2
// @description  一些优化
// @author       Ejin
// @match        https://feedly.com/*
// @grant        none
// ==/UserScript==

// 2025.03.06 屏蔽某些关键词的内容。
// 2025.02.25 消灭新特性提醒窗口(What's new,并且为漂浮状态)
// 2024.08.10 优化左侧UI,将上方无用导航链接移至下方
// 2024.07.14 弱化存档分类的加粗,隐藏未读数。
// 2024.02.23 First-read,跳转到第一个已读项
(function () {
    'use strict';

    setInterval(() => {//1.route 持续重复运行

        // 1.1 First-read
        if (location.href.indexOf("feedly.com/i/subscription/feed") != -1) {
            if (document.querySelector(".count-followers") != null
                && document.querySelector(".count-followers").parentElement.parentElement.innerHTML.indexOf("First-read") == -1) {
                //开始匿名函数,一次性增加First-read链接并设置事件。
                (() => {
                    document.querySelector(".count-followers").parentElement.parentElement.innerHTML
                        += "<span class='detail'> <a href='javascript:;' id='First-read' style='color:#9e9e9e;'>First-read</a></span>";
                    document.getElementById("First-read").parentElement.setAttribute(
                        "class",document.querySelector('#First-read').parentElement.parentElement.children[0].className);// 修正class统一格式
                    //增加First-read链接后,为它赋予事件。
                    document.getElementById("First-read").addEventListener('click', () => {
                        //事件开始,隐藏First-read链接,设置工作标志。
                        document.getElementById("First-read").style.display = "none";
                        document.querySelector("article").setAttribute("auto_roll_page","1");//正在自动滚动标志,切换其他RSS会自动消失
                        //隐藏链接后,开始自动滚动页面,开启计时器函数
                        ((/*setInterval*/ timeindex)=>{timeindex=setInterval(()=>{
                            if(document.querySelector("article[auto_roll_page]") == null){
                                //标志消失则停止滚动操作并退出
                                clearInterval(timeindex);
                                return;
                            }
                            //操作页面
                            if (document.querySelectorAll(".EntryTitleLink").length > 0 || document.querySelectorAll(".entry--read").length > 0) {
                                if (!document.querySelector(".entry--read")) {
                                    //未发现已读的内容,继续滚动页面
                                    document.querySelectorAll(".EntryTitleLink")[document.querySelectorAll(".EntryTitleLink").length - 1].scrollIntoView();
                                } else {
                                    //发现已读内容,停止滚动。并将未读内容放在合适位置
                                    document.querySelector('#feedlyFrame').scrollBy(0, -1000);//向上滚动
                                    document.querySelector(".entry--read").scrollIntoView();//滚动到第一个已读内容
                                    document.querySelector('#feedlyFrame').scrollBy(0,
                                        200 - document.querySelector('#feedlyFrame').clientHeight
                                    );//再往回滚动一点,即能看到一部分未读内容
                                    document.querySelector("article[auto_roll_page]").removeAttribute("auto_roll_page");//清理
                                    clearInterval(timeindex);//清理
                                }
                            }//结束页面操作
                        },1000);})();//滚动计时器函数结束
                    });//事件定义结束
                })();//整体匿名函数结束
            }//判断是否需要增加First-read链接,并确认页面是否准备好
        } //end First-read

        // 1.2 待增加

    }, 500);//end 1.route

    // 2 重复运行
    // 2.1.点击、标记已读自动跳到returnALL后返回ALL页面
    setInterval(() => {
        if (document.querySelector("#header-title") && document.querySelector("#header-title").innerText == "returnALL") {
            //文件夹和RSS有区别,如果进的是RSS会有一个链接,所以用innerText获取是通用的
            document.querySelectorAll("span").forEach(ele => {
                if (ele.innerHTML == "All") {
                    ele.click();
                }
            });
        }
    }, 1500);// end 跳到returnALL后返回ALL页面

    // 2.2 清理右侧内容标题列表中绿色的广告
	setInterval(() => {
		//删除广告
		if(document.querySelector('.InterestingMetadataWrapper--separator-right')){
			document.querySelector('.InterestingMetadataWrapper--separator-right').remove();
		}
		//删除跟随在广告后的小圆点
		if(document.querySelector('.EntryMetadataSeparator')){
			document.querySelector('.EntryMetadataSeparator').remove();
		}
	}, 4000);//end 右侧标题中的绿色广告
	//清理右侧顶栏的升级按钮。
	((/*setInterval*/ timeindex,timecount=1)=>{timeindex=setInterval(()=>{
		if(document.querySelector("#topHeaderBarFX")){
			if(document.querySelector("#topHeaderBarFX").querySelector("button").innerHTML.indexOf("Upgrade") != -1){
				document.querySelector("#topHeaderBarFX").querySelector("button").remove();
				clearInterval(timeindex);
			}
		}

		if(timecount==30){clearInterval(timeindex);}timecount++;
	},2000);})(); //end 内容标题广告和顶部升级按钮

    // 2.3 屏蔽某些关键词的内容。
    var ADKeywords=['[推广]','[VXNA]', '万 0.85 免 5', '万 0.85 免五', '万 0.5 免五'];
    setInterval(() => {
        if(location.href.indexOf("v2ex") == -1){
            return;
        }

        document.querySelectorAll('article:not([scriptcheck="1"])').forEach(article => {
            var articleContent = article.textContent;
            // 检查是否包含关键词
            var hasKeyword = ADKeywords.some(keyword => articleContent.includes(keyword));
            // 如果包含关键词,则隐藏并添加属性
            if (hasKeyword) {
                //article.style.display = 'none';
                //article.setAttribute('scriptcheck', '1');
                article.remove();//删除掉,否则可能影响其他脚本
            }
        });
    }, 3000);

    // 2.4 待增加

    // 3 不重复运行
    // 3.1 弱化存档分类,隐藏未读数。
    ((/*setInterval*/ timeindex,timecount=1)=>{timeindex=setInterval(()=>{
        if (document.querySelector('button[aria-label^="Mark 存档"')) {
            if (document.querySelector('button[aria-label^="Mark 存档"').style.opacity == "") {
                // 寻找存档文件夹的最上层元素,目的是设置透明,鼠标移动过去时取消透明
                var parEle = document.querySelector('button[aria-label^="Mark 存档"]');
                while (parEle.parentElement.querySelectorAll('button').length <= 3) {
                    // length可能性:1=没找到未读数本身(是个按钮),3=找到了本栏所有按钮,4+=找到了4+个(超过本文件夹最上层DOM)
                    parEle = parEle.parentElement;
                }

                //通过透明隐藏未读数
                parEle.onmouseover = () => {
                    document.querySelector('button[aria-label^="Mark 存档"').style.opacity = "1";
                };
                parEle.onmouseout = () => {
                    document.querySelector('button[aria-label^="Mark 存档"').style.opacity = "0.2";
                };
                parEle.onmouseout();

                // 顺便帮忙处理returnALL类别的加粗和未读数
                document.querySelectorAll(".LeftnavListRow__text--bold").forEach(item => {
                    if (item.innerHTML == "returnALL") {
                        item.className = item.className.replace("LeftnavListRow__text--bold", "");
                    }
                });
                document.querySelector('button[aria-label^="Mark returnALL"').style.display = "none";

				clearInterval(timeindex);
            }
        }

		if(timecount==30){clearInterval(timeindex);}timecount++;
    },2000);})(); //end 弱化存档分类

    // 3.2 优化左侧 UI,将上方无用导航链接移至下方
    ((/*setInterval*/ timeindex,timecount=1)=>{timeindex=setInterval(()=>{
        // 检查必要的导航元素是否存在
        if (document.querySelector('div[title="Today"]') && document.querySelector('div[title="Integrations & API"]')) {
            const navTitles = ["Today", "Read Later", "Recently Read"]; // 需要移动的导航标题列表
            const navFoot = document.querySelector('div[title="Integrations & API"]').parentElement; // 定位左边栏下方
            let insertIndex = 0; // 记录插入位置
            navFoot.children[0].style.borderTop = '1px solid #ccc'; // 原下方导航栏最上面加一个横线

            navTitles.forEach(title => {
                const navTop = document.querySelector(`div[title="${title}"]`).parentElement; // 定位左边栏上方

                // 将上方导航元素移动到下方
                while (navTop.children.length > 0) {
                    navFoot.insertBefore(navTop.children[0], navFoot.children[insertIndex]);
                    insertIndex++;
                }

                // 清理空父元素
                let parent = navTop.parentElement;
                while (parent && parent.innerText.trim() === "") {
                    const temp = parent.parentElement;
                    parent.remove();
                    parent = temp;
                }
            });//forEach

            clearInterval(timeindex);
        }
		if (timecount == 120) { clearInterval(timeindex); } timecount++;
    },300);})();//end 优化左侧 UI

    //3.3 消灭新特性提醒窗口(What's new,并且为漂浮状态)
    ((/*setInterval*/ timeindex, timecount = 1) => {timeindex = setInterval(() => {
            if (document.querySelector(".AppDockedPopups")) {
                if (document.querySelector(".AppDockedPopups").innerHTML.indexOf("What's new") != -1) {
                    document.querySelector(".AppDockedPopups").querySelector("button").click();
                }
            }

            if (timecount == 200) { clearInterval(timeindex); } timecount++;
        }, 300);
    })(); //end

    // 3.4 待增加

})(); //end all