CNVD_Modify

CNVD添加复制漏洞列表页面单个或所有漏洞标题、优化用户中心已提交漏洞展示和复制漏洞编号

// ==UserScript==
// @name         CNVD_Modify
// @namespace    http://tampermonkey.net/
// @version      0.3
// @description  CNVD添加复制漏洞列表页面单个或所有漏洞标题、优化用户中心已提交漏洞展示和复制漏洞编号
// @author       Mrxn
// @homepage     https://mrxn.net/
// @supportURL   https://github.com/Mr-xn/CNVD_Modify
// @license      MIT
// @run-at       document-end
// @match        https://www.cnvd.org.cn/*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=cnvd.org.cn
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // Your code here...

    function copy_all_vuln_title(){
        // 获取表格元素
        const table = document.querySelector('.tlist');

        // 获取表格中的thead和tbody元素
        const thead = table.querySelector('thead');
        const tbody = table.querySelector('tbody');

        // 获取所有的tr元素
        const trList = tbody.querySelectorAll('tr');

        // 获取表格中的第一个th元素
        const th = thead.querySelector('th:first-child');

        // 创建复制按钮
        const btn = document.createElement('button');
        btn.textContent = '复制所有标题';

        // 给复制按钮设置样式
        btn.style.position = 'relative';
        btn.style.top = 0;
        btn.style.right = 0;
        btn.style.paddingLeft = '10px';

        // 给复制按钮添加点击事件
        btn.addEventListener('click', () => {
            // 创建一个数组,用于保存所有的title属性值
            const titles = [];
            // 遍历所有的tr元素
            trList.forEach(tr => {
                // 获取当前tr元素下的第一个td元素
                const td = tr.querySelector('td:first-child');
                // 如果当前td元素下有a标签
                const a = td.querySelector('a');
                if (a) {
                    // 将a标签的title属性值添加到数组中
                    titles.push(a.getAttribute('title') || a.outerText);
                }
            });
            // 将title属性值以换行符为分隔符合并为一个字符串
            const text = titles.join('\n');
            // 创建一个临时的textarea元素
            const textarea = document.createElement('textarea');
            // 将合并后的字符串赋值给textarea元素的value属性
            textarea.value = text;
            // 将textarea元素添加到页面中
            document.body.appendChild(textarea);
            // 选中textarea元素中的文本
            textarea.select();
            // 复制选中的文本
            document.execCommand('copy');
            // 删除临时的textarea元素
            document.body.removeChild(textarea);
        });

        // 将复制按钮添加到th元素中
        th.appendChild(btn);
    }

    function user_copy(){
        // 判断当前页面是否为 https://www.cnvd.org.cn/
        if (window.location.href.startsWith('https://www.cnvd.org.cn/')) {
            //优化用户中心的已提交漏洞列表展示
            var elements = document.querySelectorAll('.tlist th, .tlist td');
            for (var i = 0; i < elements.length; i++) {
                elements[i].style.padding = '0';
            }

            //优化漏洞列表页面给每条漏洞前面添加复制按钮
            // 获取所有的td元素
            const tdList = document.querySelectorAll('tbody td');

            // 遍历所有的td元素
            tdList.forEach(td => {
                // 获取a标签元素
                const a = td.querySelector('a');
                if (!a) {
                    return;
                }
                // 创建复制按钮
                const btn = document.createElement('button');
                btn.textContent = '复制';

                // 给复制按钮设置样式
                btn.style.position = 'relative';
                btn.style.top = 0;
                btn.style.right = 0;

                // 根据a标签的href属性判断复制的内容
                if (a.getAttribute('href').startsWith('/flaw/show/')) {
                    //复制单独的每一条漏洞标题
                    // 复制a标签的title属性
                    btn.addEventListener('click', () => {
                        // 创建一个临时的textarea元素
                        const textarea = document.createElement('textarea');
                        // 将a标签的title属性赋值给textarea元素的value属性
                        textarea.value = a.getAttribute('title') || a.outerText;
                        // 将textarea元素添加到页面中
                        document.body.appendChild(textarea);
                        // 选中textarea元素中的文本
                        textarea.select();
                        // 复制选中的文本
                        document.execCommand('copy');
                        // 删除临时的textarea元素
                        document.body.removeChild(textarea);
                    });
                } else if (a.getAttribute('href').startsWith('/user/myreport/')) {
                    // 复制a标签的文本内容
                    btn.addEventListener('click', () => {
                        // 创建一个临时的textarea元素
                        const textarea = document.createElement('textarea');
                        // 将a标签的文本内容赋值给textarea元素的value属性
                        textarea.value = a.textContent;
                        // 将textarea元素添加到页面中
                        document.body.appendChild(textarea);
                        // 选中textarea元素中的文本
                        textarea.select();
                        // 复制选中的文本
                        document.execCommand('copy');
                        // 删除临时的textarea元素
                        document.body.removeChild(textarea);
                    });
                } else {
                    // 如果a标签的href属性既不以/flaw/show/开头,也不以/user/myreport/开头,则不添加复制按钮
                    return;
                }

                // 将复制按钮添加到td元素中
                td.appendChild(btn);
            });
        }
    }
    function run(){
        if (window.location.href.startsWith('https://www.cnvd.org.cn/')){
            user_copy();
        }
        if (window.location.href.includes('/flaw/list') || window.location.href.includes('/flaw/flawListByManu')) {
            //添加复制所有漏洞标题按钮
            copy_all_vuln_title();
        }
    }
    function Surveillance(){
        // 监视 table 内容的变化
        const observer = new MutationObserver(function(mutationsList, observer) {
            // 遍历每一个变化
            for (let mutation of mutationsList) {
                // 如果变化发生在 table 中,则执行某个函数
                if (mutation.target.nodeName === 'TABLE') {
                    return true;
                }
            }
        });

        // 配置 MutationObserver 监听 table 内容的变化
        const config = { childList: true, subtree: true };
        observer.observe(document.body, config);

    }

    //开始运行
    run();

})();