Greasy Fork

Greasy Fork is available in English.

keyToShowClass | 快捷键启动自定义样式

Press a shortcut key to activate the specified host's custom styling. | 点击某个快捷键,来启动你指定的host的自定义的样式

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        keyToShowClass | 快捷键启动自定义样式
// @namespace   https://leizingyiu.net
// @match       http*://*/*
// @grant       none
// @version     20250309
// @author      leizingyiu
// @description Press a shortcut key to activate the specified host's custom styling. | 点击某个快捷键,来启动你指定的host的自定义的样式
// @license     GNU AGPLv3

// ==/UserScript==

prefix = "yiu_lib_show_info_";
// 定义样式模板字典
const dict = {
  "example":"⬇️",
  "liblib.art": {
    KeyC: `
      .${prefix}$/{code/} [class^=ImageCard_mask],
      .${prefix}$/{code/} [class^=ImageCard_imageCard] {
        opacity: 1 !important;
        background: #00000000 !important;
        color: #000 !important;
      }

      .${prefix}$/{code/} [class^=ImageCard_nickName],
      .${prefix}$/{code/} [class^=ImageGenerateInfoPopover_generateBtn] {
        color: #fff !important;
        text-shadow: unset !important;
        mix-blend-mode: difference;
      }

      .${prefix}$/{code/} [class^=ImageCard_drawBtn],
      .${prefix}$/{code/} .opacity-0 {
        opacity: 1 !important;
      }

      [class^=ImageCard_mask],
      [class^=ImageCard_imageCard] {
        transition: opacity 0.2s ease, background 0.2s ease, color 0.2s ease !important;
      }

      [class^=ImageCard_nickName],
      [class^=ImageGenerateInfoPopover_generateBtn] {
        transition: text-shadow 0.2s ease, color 0.2s ease !important;
      }

      [class^=ImageCard_drawBtn], .opacity-0 {
        transition: opacity 0.2s ease;
      }
    `,
  },
  // 可以扩展其他主机和按键
};

// 获取当前主机名
const currentHost = window.location.host;

function hasSetting(host) {
  for (const [hostKey, styles] of Object.entries(dict)) {
    if (host.includes(hostKey)) {
      return true; // 如果当前主机包含字典中的主机名,则返回对应的样式模板
    }
  }
  return false; // 如果没有匹配的主机名,返回 null
}

// 根据主机名获取对应的样式模板
function getHostStyles(host) {
  for (const [hostKey, styles] of Object.entries(dict)) {
    if (host.includes(hostKey)) {
      return styles; // 如果当前主机包含字典中的主机名,则返回对应的样式模板
    }
  }
  return null; // 如果没有匹配的主机名,返回 null
}

// 动态生成样式内容
function generateStyleContent(template, code) {
  return template.replace(/\$\/\{code\/\}/g, code); // 替换所有 $/{code/} 占位符
}

// 初始化样式
function initializeStyles() {
  const hostStyles = getHostStyles(currentHost); // 获取当前主机的样式模板

  if (!hostStyles) {
    console.error(`未找到与主机 ${currentHost} 匹配的样式模板`);
    return;
  }

  // 遍历主机的所有按键样式模板
  for (const [key, styleTemplate] of Object.entries(hostStyles)) {
    const styleContent = generateStyleContent(styleTemplate, key); // 替换占位符

    const styleElement = document.createElement("style");
    styleElement.textContent = styleContent; // 设置样式内容
    document.head.appendChild(styleElement); // 添加到 <head>
  }
}

// 初始化事件监听器
function initializeEventListeners() {
  const hostStyles = getHostStyles(currentHost); // 获取当前主机的样式模板

  if (!hostStyles) {
    console.error(`未找到与主机 ${currentHost} 匹配的样式模板`);
    return;
  }

  const toggleClass = (e) => {
    const key = e.code; // 获取按键代码
    console.log("key to show class : toggleClass : start");

    const isKeySupported = hostStyles.hasOwnProperty(key); // 检查按键是否在样式模板中

    if (isKeySupported) {
      console.log("key to show class : toggleClass : KeySupported");

      if (e.type === "keydown") {
        document.body.classList.add(`${prefix}${key}`); // 添加动态类名
      } else if (e.type === "keyup") {
        document.body.classList.remove(`${prefix}${key}`); // 移除动态类名
      }
    }
  };

  window.addEventListener("keydown", toggleClass);
  window.addEventListener("keyup", toggleClass);
}

// 主函数:初始化样式和事件监听器
function main() {
  console.log("key to show class : main : start");

  initializeStyles(); // 初始化样式
  initializeEventListeners(); // 初始化事件监听器

  console.log("key to show class : main : end ");
}

// window.addEventListener('load',function(){
//   if(hasSetting(currentHost)==true){
//     main();
//   }
// })

/**
 * 监听页面状态变化的函数
 * @param {Object} options - 配置对象,用于启用或禁用特定事件监听
 * @param {boolean} options.onUrlChange - 是否监听地址栏变化(hashchange 和 popstate)
 * @param {boolean} options.onPageNavigation - 是否监听页面前进或后退(popstate)
 * @param {boolean} options.onPageLoad - 是否监听页面加载完成(DOMContentLoaded 和 load)
 * @param {Function} [options.commonCallback] - 通用回调函数,适用于所有事件
 * @param {Object} callbacks - 回调函数对象(可选)
 * @param {Function} callbacks.onUrlChangeCallback - 地址栏变化时的回调
 * @param {Function} callbacks.onPageNavigationCallback - 页面前进或后退时的回调
 * @param {Function} callbacks.onPageLoadCallback - 页面加载完成时的回调
 */
function listenPageStateChanges(options = {}, callbacks = {}) {
  const {
    onUrlChange = false,
    onPageNavigation = false,
    onPageLoad = false,
    commonCallback, // 通用回调函数
  } = options;

  const {
    onUrlChangeCallback = commonCallback,
    onPageNavigationCallback = commonCallback,
    onPageLoadCallback = commonCallback,
  } = callbacks;

  // 1. 地址栏变化(hashchange 和 popstate)
  if (onUrlChange && typeof onUrlChangeCallback === "function") {
    window.addEventListener("hashchange", () => {
       onUrlChangeCallback(window.location.href);
    });

    window.addEventListener("popstate", () => {
       onUrlChangeCallback(window.location.href);
    });
  }

  // 2. 页面前进或后退(popstate)
  if (onPageNavigation && typeof onPageNavigationCallback === "function") {
    window.addEventListener("popstate", () => {
       onPageNavigationCallback(window.location.href);
    });
  }

  // 3. 页面加载完成(DOMContentLoaded 和 load)
  if (onPageLoad && typeof onPageLoadCallback === "function") {
    document.addEventListener("DOMContentLoaded", () => {
       onPageLoadCallback("DOMContentLoaded");
    });

    window.addEventListener("load", () => {
       onPageLoadCallback("load");
    });
  }
}

console.log("key to show class", hasSetting(currentHost));

if (hasSetting(currentHost) == true) {
  listenPageStateChanges(
    {
      onUrlChange: true, // 启用地址栏变化监听
      onPageNavigation: true, // 启用页面导航监听
      onPageLoad: true, // 启用页面加载完成监听
      commonCallback: (data) => {
        main(data);
      },
    },
    {
      // 如果需要单独定义某个事件的回调,可以在这里覆盖 commonCallback
      // 例如:
      // onUrlChangeCallback: (newUrl) => {
      //   console.log('单独处理地址栏变化:', newUrl);
      // },
    },
  );
}