setupToggleCommands

Library that creates toggleable menu commands for userscript managers

当前为 2024-06-17 提交的版本,查看 最新版本

此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.org/scripts/498119/1395863/setupToggleCommands.js

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name        setupToggleCommands
// @license     MIT
// @namespace   rtonne
// @match       *://*/*
// @version     1.0
// @author      Rtonne
// @description Library that creates toggleable menu commands for userscript managers
// @grant       GM.registerMenuCommand
// @grant       GM.unregisterMenuCommand
// @grant       GM.getValue
// @grant       GM.setValue
// ==/UserScript==

/**
 * Can be the only function of this library used externally.
 * @param {_Command[]} command_list The list of all toggle commands that are to be added.
 */
async function setupToggleCommands(command_list) {
  for (const command of command_list) {
    _runCommandFunction(command);
  }
  for (const command of command_list) {
    await _registerCommand(command_list, command);
  }
}

/**
 * @typedef {Object} _Command
 * @property {string} id The id of the menu command and the key for the value.
 * @property {string} off_text The text displayed when the last function ran was toggleOffFunction.
 * @property {string} on_text The text displayed when the last function ran was toggleOnFunction.
 * @property {string} [off_tooltip] The tooltip shown while hovering the command when the last function ran was toggleOffFunction.
 * @property {string} [on_tooltip] The tooltip shown while hovering the command when the last function ran was toggleOnFunction.
 * @property {boolean} [default_value] The default value. Its "false" by default.
 * @property {boolean} [auto_close] If the userscript manager popup closes when the command is clicked. Its "false" by default.
 * @property {() => void} [toggleOffFunction] A function to be run then toggling off the command.
 * @property {() => void} [toggleOnFunction] A function to be run then toggling on the command.
 */

// To check if in place command replacement is supported
// https://violentmonkey.github.io/api/gm/#gm_registermenucommand
const _can_replace_in_place =
  "test" === GM.registerMenuCommand("test", () => {}, { id: "test" });
GM.unregisterMenuCommand("test");

/**
 * Runs the correct command function, and toggles the command text.
 * @param {_Command[]} command_list The list of all commands (may be used to replace old commands).
 * @param {_Command} command The command being toggled.
 */
async function _toggleCommand(command_list, command) {
  await GM.setValue(
    command.id,
    !(await GM.getValue(command.id, command.default_value))
  );
  _runCommandFunction(command);
  if (_can_replace_in_place) {
    await _registerCommand(command_list, command);
  } else {
    // If we can't replace commands, we need to remove them all, then re-add them
    for (const command of command_list) {
      GM.unregisterMenuCommand(command.id);
    }
    for (const command of command_list) {
      await _registerCommand(command_list, command);
    }
  }
}

/**
 * Registers the command with the correct text.
 * @param {_Command[]} command_list The list of all commands (may be used to replace old commands).
 * @param {_Command} command
 */
async function _registerCommand(command_list, command) {
  let text = command.on_text;
  let tooltip = command.on_tooltip;
  if (!(await GM.getValue(command.id, command.default_value))) {
    text = command.off_text;
    tooltip = command.off_tooltip;
  }

  GM.registerMenuCommand(text, () => _toggleCommand(command_list, command), {
    id: command.id,
    title: tooltip,
    autoClose: command.auto_close !== undefined && command.auto_close,
  });
}

/**
 * Runs the correct command function.
 * @param {_Command} command
 */
async function _runCommandFunction(command) {
  if (await GM.getValue(command.id, command.default_value)) {
    if (command.toggleOnFunction) {
      command.toggleOnFunction();
    }
  } else {
    if (command.toggleOffFunction) {
      command.toggleOffFunction();
    }
  }
}