Skip to content

[Feature] [Chrome >= 127] Userscript 借助 ScriptCat Extension Popup 订制弹窗 #1117

@cyfung1031

Description

@cyfung1031

功能描述

请清晰描述你想要的功能:

FF (2023?):
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/browserAction/openPopup

說明 (2022):
https://oliverdunk.com/2022/11/13/extensions-open-popup

Chrome (2024):
https://developer.chrome.com/docs/extensions/reference/api/action?hl=en#method-openPopup

Chrome 在 127 终于引入了 chrome.action.openPopup();

也就是可以用 JavaScript 打开 popup 的 弹窗

userscript 很多时都需要有一个弹窗的东西
以往都只能在页面做
现在可以在Popup搞

为了不被滥用,建议只能用 node 的 click / pointerdown / pointerup / mouseup / mousedown / keydown / keyup / keypress 这 8个事件触发 (context-menu 對手機使用者不友善,有 PointerEvent 即不需要 TouchEvent )
也就是避免 setInterval(()=>{ chrome.action.openPopup(); }, 1000); 這種惡意濫用

CAT_POPUP({ node: Node, id: string | number, trigger: "click" | "_pointer" | "^pointer" | "^mouse" | "_mouse" | ShortCut, html: string, width: number = 320, height: number = 500 });
  • 回传:自动 id / 自定义id

  • click, ctrl-click, alt-click, ...

  • _pointer, ^pointer, _ctrl-pointer, ^ctrl-pointer, _alt-pointer, ^alt-pointer ....

  • _mouse, ^mouse, _ctrl-mouse, ^ctrl-mouse, _alt-mouse, ^alt-mouse ....

  • ShortCut 是 string (不包含 mouse, click, pointer ), 格式定义参考: https://github.com/violentmonkey/vm-shortcut?tab=readme-ov-file#key-definition. 引伸 keypress, keyup(^), keydown(_)

  • node 可指定為 document.documentElement / document.body ,實現全局 hook

  • 實際使用上,CAT會做一個沙盒popup頁面,避免惡意操作 extension APIs

<!doctype html>
<html>
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title></title>
    <style>
      html,
      body {
        margin: 0;
        padding: 0;
        border: 0;
      }
      div {width: {{ width }}px; height: {{ height }}px;}
      iframe {position: fixed; top: 0; bottom: 0; left: 0; right: 0;}
    </style>
    <script src="popup-api-message.js"></script>
  </head>

  <body>
<iframe src="data:text/html;base64,PHN0cmljdD48aDE+SGVsbG8sIFdvcmxkISBGaWxsZWQgZnJvbSBCYXNlNjQgZGF0YSE8L2gxPjwvc3RyaWN0Pg==" width="100%" height="100%" frameborder="0"></iframe>
<div></div>
  </body>
</html>
  • PHN0cmljdD48aDE+SGVsbG8sIFdvcmxkISBGaWxsZWQgZnJvbSBCYXNlNjQgZGF0YSE8L2gxPjwvc3RyaWN0Pg== 會換成 html 的 base64
  • 可通過 top.postMessage 呼叫特定 API 操作 (popup-api-message.js). Iframe 內可以提供一些簡單封裝實現指定 API, 例如 GM.setValue, GM.getValue , GM.deleteValue 等
  • 用户可指定 width 和 height (预设 width=320px height=500px ), 但过大的话浏览器会自行调整大小

例子:

左键click

// 新增Popup动作
let popupId = CAT_POPUP({ node: button1, trigger: "click", html: "<ul><li>option1</li><li>option2</li></ul>"});
// 修改Popup动作 ( 先清除舊注冊 )
CAT_POPUP({ node: button1, id: popupId, trigger: "click", html: "<ul><li>Apple</li><li>Orange</li></ul>"});
// 删掉Popup动作 ( trigger 或 html 为空值 )
CAT_POPUP({ id: popupId });

左键mousedown

// 新增Popup动作 (mousedown)
CAT_POPUP({ node: button2, trigger: "_mouse", html: "<ul><li>option1</li><li>option2</li></ul>"});

ctrl+左键mouseup

// 新增Popup动作 (ctrl + mousedown)
CAT_POPUP({ node: button2, trigger: "^ctrl-mouse", html: "<ul><li>option1</li><li>option2</li></ul>"});
// 新增Popup动作 (keypress: ctrl-alt-h)
CAT_POPUP({ node: button2, trigger: "ctrl-alt-h", html: "<ul><li>Keypress1</li><li>Keypress2</li></ul>"});
// 新增Popup动作 (keyup: ctrl-alt-t)
CAT_POPUP({ node: button2, trigger: "^ctrl-alt-t", html: "<ul><li>Keyup1</li><li>Keyup2</li></ul>"});
// 新增Popup动作 (keydown: ctrl-alt-n)
CAT_POPUP({ node: button2, trigger: "_ctrl-alt-n", html: "<ul><li>Keydown1</li><li>Keydown2</li></ul>"});
  • ※ 如重复Popup动作(该main frame/sub frame的当前脚本&所有脚本),在第一个动作执行后已经是 openPopup 状态,后续不执行

使用场景

在什么情况下需要这个功能?(例如:处理特定网站时,提升操作效率等)

让脚本有一个像样的弹窗

附加说明

(可选)补充截图、示例代码或其他参考信息

Image
// ==UserScript==
// @name         Popup Action Demo
// @namespace    https://docs.scriptcat.org/
// @version      0.1.0
// @description  try to take over the world!
// @author       You
// @match        https://example.com/
// @grant        CAT_POPUP
// @noframes
// ==/UserScript==

(function() {
    'use strict';

   CAT_POPUP({ node: document.querySelector("h1"), trigger: "click", html: "<h1>Hello World!</h1>"});
})();

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions