您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
用于检验Via的Adblock规则中的Css隐藏规则是否有错误的规则,支持自动运行和菜单操作。
当前为
- // ==UserScript==
- // @name Via Css 检验
- // @namespace https://viayoo.com/
- // @version 2.6
- // @license MIT
- // @description 用于检验Via的Adblock规则中的Css隐藏规则是否有错误的规则,支持自动运行和菜单操作。
- // @author Copilot
- // @run-at document-end
- // @match *://*/*
- // @grant GM_registerMenuCommand
- // @require https://cdn.jsdelivr.net/npm/js-beautify@1.14.0/js/lib/beautify-css.js
- // @require https://cdn.jsdelivr.net/npm/css-tree@2.3.1/dist/csstree.min.js
- // ==/UserScript==
- (function() {
- 'use strict';
- // 获取CSS文件URL
- function getCssFileUrl() {
- const currentHost = window.location.hostname;
- return `https://${currentHost}/via_inject_blocker.css`;
- }
- // 使用 js-beautify 格式化CSS内容
- function formatCssWithJsBeautify(rawCss) {
- try {
- return css_beautify(rawCss, {
- indent_size: 2,
- selector_separator_newline: true
- });
- } catch (error) {
- console.error(`CSS格式化失败:${error.message}`);
- return null;
- }
- }
- // 截断错误行以限制字符数
- function truncateErrorLine(errorLine, maxLength = 150) {
- if (errorLine.length > maxLength) {
- return errorLine.substring(0, maxLength) + "..."; // 添加省略号表示截断
- }
- return errorLine;
- }
- // 读取并格式化CSS内容
- async function fetchAndFormatCss() {
- const url = getCssFileUrl();
- try {
- const response = await fetch(url);
- if (!response.ok) {
- throw new Error(`无法获取CSS文件:${response.statusText}`);
- }
- const rawCss = await response.text();
- return formatCssWithJsBeautify(rawCss);
- } catch (error) {
- console.error(`无法获取或格式化CSS文件:${error.message}`);
- return null;
- }
- }
- // 翻译错误信息为中文
- function translateErrorMessage(englishMessage) {
- const translations = {
- "Identifier is expected": "需要标识符",
- "Unexpected end of input": "输入意外结束",
- "Selector is expected": "需要选择器",
- "Invalid character": "无效字符",
- "Unexpected token": "意外的标记",
- '"]" is expected': '需要 "]"',
- '"{" is expected': '需要 "{"',
- 'Unclosed block': '未闭合的块',
- 'Unclosed string': '未闭合的字符串',
- 'Property is expected': '需要属性名',
- 'Value is expected': '需要属性值',
- "Percent sign is expected": "需要百分号 (%)",
- 'Attribute selector (=, ~=, ^=, $=, *=, |=) is expected': '需要属性选择器运算符(=、~=、^=、$=、*=、|=)',
- 'Semicolon is expected': '需要分号 ";"',
- 'Number is expected': '需要数字',
- 'Colon is expected': '需要冒号 ":"'
- };
- return translations[englishMessage] || `${englishMessage}`;
- }
- // 验证格式化后的CSS内容
- function validateCss(formattedCss, isAutoRun = false) {
- if (!formattedCss) return;
- let hasError = false;
- const errors = [];
- const lines = formattedCss.split('\n'); // 将格式化的CSS按行分割
- try {
- csstree.parse(formattedCss, {
- onParseError(error) {
- hasError = true;
- // 获取并截断错误的具体片段
- const errorLine = lines[error.line - 1] || "无法提取错误行";
- const truncatedErrorLine = truncateErrorLine(errorLine);
- // 翻译错误信息
- const translatedMessage = translateErrorMessage(error.message);
- const errorMessage = `
- CSS 解析错误:
- - 位置:第 ${error.line} 行
- - 错误信息:${translatedMessage}
- - 错误片段:${truncatedErrorLine}
- `.trim();
- errors.push(errorMessage);
- }
- });
- if (hasError) {
- if (isAutoRun) {
- alert(errors.join('\n\n'));
- }
- } else if (!isAutoRun) {
- alert("CSS验证通过:未发现错误。");
- }
- } catch (error) {
- const translatedMessage = translateErrorMessage(error.message);
- if (isAutoRun) {
- console.error(`自动运行时CSS验证失败:${translatedMessage}`);
- } else {
- alert(`CSS验证失败:${translatedMessage}`);
- }
- }
- }
- // 自动运行逻辑
- async function autoRunCssValidation() {
- const formattedCss = await fetchAndFormatCss();
- if (formattedCss) {
- validateCss(formattedCss, true); // 自动运行时传递 true
- }
- }
- // 注册菜单
- GM_registerMenuCommand("验证CSS文件", async () => {
- const formattedCss = await fetchAndFormatCss();
- if (formattedCss) {
- validateCss(formattedCss, false); // 手动运行时传递 false
- }
- });
- // 触发自动运行
- autoRunCssValidation();
- })();