Skip to content

Commit 3f06fda

Browse files
committed
Merge branch 'release/v1.4' into develop/add-no-csp-option
2 parents 25dcdfb + 3e975c0 commit 3f06fda

55 files changed

Lines changed: 2358 additions & 528 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/pull_request_template.md

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
1-
## 概述 Descriptions
1+
## Checklist / 检查清单
22

3-
<!-- 如果有关联的 issue,请在下面记载 -->
4-
<!-- Describe related issue(s) if any. -->
5-
<!-- close #xxx -->
3+
- [ ] Fixes mentioned issues / 修复已提及的问题
4+
- [ ] Code reviewed by human / 代码通过人工检查
5+
- [ ] Changes tested / 已完成测试
66

7-
## 变更内容 Changes
7+
## Description / 描述
88

9-
<!-- - 这个 PR 做了什么? -->
10-
<!-- - What does this PR do? -->
9+
<!-- Description / PR 描述 -->
1110

12-
### 截图 Screenshots
11+
## Screenshots / 截图
1312

14-
<!-- 如果可以展示页面,请务必附上截图 -->
15-
<!-- If it can be illustrated, please provide a screenshot. -->
13+
<!-- Screenshots / 截图-->

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,5 @@ CLAUDE.md
3939

4040
test-results
4141
playwright-report
42+
43+
superpowers

.husky/pre-commit

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,35 @@
11
#!/bin/sh
22

3-
pnpm run lint-fix
3+
# Skip checks: SKIP_PRE_PUSH=1 git push or git push --no-verify
4+
if [ "$SKIP_PRE_PUSH" = "1" ]; then
5+
echo "⏭ SKIP_PRE_PUSH=1, skipping pre-push checks"
6+
exit 0
7+
fi
48

5-
# 将已暂存且被 lint-fix 修改过的文件重新加入暂存区
6-
STAGED=$(git diff --cached --name-only --diff-filter=d)
7-
CHANGED=$(git diff --name-only)
9+
# Only run checks when pushing to main or release/* branches
10+
remote="$1"
11+
need_check=0
812

9-
for file in $CHANGED; do
10-
case "$STAGED" in
11-
*"$file"*) git add "$file" ;;
12-
esac
13+
while read local_ref local_sha remote_ref remote_sha; do
14+
branch=$(echo "$remote_ref" | sed 's|refs/heads/||')
15+
16+
if [ "$branch" = "main" ] || echo "$branch" | grep -q "^release/"; then
17+
need_check=1
18+
echo "🔍 Detected push target: $branch"
19+
fi
1320
done
21+
22+
if [ "$need_check" = "0" ]; then
23+
exit 0
24+
fi
25+
26+
echo ""
27+
echo "▶ Running lint..."
28+
pnpm run lint || exit 1
29+
30+
echo ""
31+
echo "▶ Running tests..."
32+
pnpm run test:ci || exit 1
33+
34+
echo ""
35+
echo "✅ All checks passed! (build and e2e tests will run in CI)"

.husky/pre-push

Lines changed: 0 additions & 35 deletions
This file was deleted.

e2e/vscode-connect.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ async function openToolsPage(context: Parameters<typeof openOptionsPage>[0], ext
1515
return page;
1616
}
1717

18-
/** 获取「开发调试」卡片区域的定位器 */
18+
/** 获取「开发工具」卡片区域的定位器 */
1919
function getDevCard(page: Page) {
20-
// 开发调试 / Development Debugging 卡片是页面上第二个 Card
20+
// 开发工具 / Development Tool 卡片是页面上第二个 Card
2121
return page.locator(".arco-card").nth(1);
2222
}
2323

@@ -106,7 +106,7 @@ test.describe("VSCode 连接", () => {
106106
const card = getDevCard(page);
107107

108108
// 卡片标题
109-
await expect(card.getByText(/development debugging|/i)).toBeVisible();
109+
await expect(card.getByText(/development tool|/i)).toBeVisible();
110110

111111
// VSCode URL 输入框
112112
const urlInput = card.locator(".arco-input");
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
// ==UserScript==
2+
// @name once(...) 示例 - 工作时间内每小时执行一次
3+
// @namespace https://bbs.tampermonkey.net.cn/
4+
// @version 0.1.0
5+
// @description 演示 once(...) 语法:每天 9 时至 17 时期间,每小时执行一次
6+
// @author You
7+
// @crontab * once(9-17) * * *
8+
// @grant GM_log
9+
// @grant GM_xmlhttpRequest
10+
// @connect httpbin.org
11+
// ==/UserScript==
12+
13+
/**
14+
* `once(expr)` 语法说明:
15+
*
16+
* * once(9-17) * * *
17+
* ↑ ↑
18+
* 分 时位
19+
*
20+
* - `once(9-17)` 写在时位:
21+
* - 括号内 `9-17` 是时位的候选值,即只有 9 时至 17 时才会触发
22+
* - `once` 锁定"每小时"这个周期,每小时重置一次
23+
*
24+
* 效果:每天 9:00–17:59,每小时在当小时内第一次命中时执行,共执行 9 次/天。
25+
* 18 时起不再触发,次日 9 时重新开始。
26+
*
27+
* 与 `* 9-17 * * *` 的区别:
28+
* - `* 9-17 * * *` 每小时的每一分钟都执行(共 60×9 = 540 次/天)
29+
* - `* once(9-17) * * *` 每小时只执行一次(共 9 次/天)
30+
*
31+
* 常见用途:工作时间内定期轮询、状态检查、数据同步等。
32+
*/
33+
return new Promise((resolve, reject) => {
34+
const hour = new Date().getHours();
35+
GM_log(`当前时间:${hour} 时,本小时内第一次触发,开始执行……`);
36+
37+
GM_xmlhttpRequest({
38+
url: "https://httpbin.org/get",
39+
method: "GET",
40+
responseType: "json",
41+
anonymous: true,
42+
43+
onload(resp) {
44+
if (resp.status === 200) {
45+
GM_log(`${hour} 时执行成功,本小时内不再重复。`);
46+
resolve("ok");
47+
} else {
48+
reject(`请求失败,状态码:${resp.status}`);
49+
}
50+
},
51+
onerror() {
52+
reject("网络错误,请求失败。");
53+
},
54+
});
55+
});

example/crontab/crontab-once.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// ==UserScript==
2+
// @name once 示例 - 每天只执行一次
3+
// @namespace https://bbs.tampermonkey.net.cn/
4+
// @version 0.1.0
5+
// @description 演示 once 语法:每天在工作时间(9-18点)内第一次触发时执行,当天不再重复
6+
// @author You
7+
// @crontab * 9-18 once * *
8+
// @grant GM_log
9+
// @grant GM_xmlhttpRequest
10+
// @connect httpbin.org
11+
// ==/UserScript==
12+
13+
/**
14+
* `once` 语法说明:
15+
*
16+
* * 9-18 once * *
17+
* ↑ ↑ ↑
18+
* 分 时 日位的 once
19+
*
20+
* - 分位 `*`、时位 `9-18`:每天 9:00–18:59 的每分钟都是候选时间
21+
* - 日位 `once`:在"每天"这个周期内,只允许执行一次
22+
*
23+
* 效果:每天工作时间内,第一次触发时执行;执行成功后,当天剩余时间不再执行。
24+
* 次日 9 点起重置,重新等待第一次触发。
25+
*
26+
* 常见用途:每天定时同步、上报、检查类任务。
27+
*/
28+
return new Promise((resolve, reject) => {
29+
GM_log("今天还没执行过,开始执行……");
30+
31+
GM_xmlhttpRequest({
32+
url: "https://httpbin.org/get",
33+
method: "GET",
34+
responseType: "json",
35+
anonymous: true,
36+
37+
onload(resp) {
38+
if (resp.status === 200) {
39+
GM_log("执行成功,今天不会再运行。");
40+
resolve("ok");
41+
} else {
42+
reject(`请求失败,状态码:${resp.status}`);
43+
}
44+
},
45+
onerror() {
46+
reject("网络错误,请求失败。");
47+
},
48+
});
49+
});

example/window_onurlchange.js

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// ==UserScript==
2+
// @name window.onurlchange 示例
3+
// @namespace https://bbs.tampermonkey.net.cn/
4+
// @version 0.1.0
5+
// @description 监听页面 URL 变化(兼容 Tampermonkey)
6+
// @author You
7+
// @match *://*/*
8+
// @grant window.onurlchange
9+
// ==/UserScript==
10+
11+
if (window.onurlchange === null) {
12+
// feature is supported
13+
14+
// 方式一:使用 window.onurlchange 赋值
15+
window.onurlchange = function (e) {
16+
console.log("URL changed to:", e.url);
17+
};
18+
19+
// 方式二:使用 addEventListener
20+
window.addEventListener("urlchange", function (e) {
21+
console.log("URL changed (addEventListener):", e.url);
22+
});
23+
}

package.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "scriptcat",
3-
"version": "1.4.0-beta",
3+
"version": "1.4.0-beta.1",
44
"description": "脚本猫,一个可以执行用户脚本的浏览器扩展,万物皆可脚本化,让你的浏览器可以做更多的事情!",
55
"author": "CodFrm",
66
"license": "GPLv3",
@@ -55,7 +55,7 @@
5555
"string-similarity-js": "^2.1.4",
5656
"uuid": "^11.1.0",
5757
"webdav": "^5.9.0",
58-
"yaml": "^2.8.1"
58+
"yaml": "^2.8.3"
5959
},
6060
"devDependencies": {
6161
"@eslint/compat": "^1.4.1",
@@ -75,6 +75,8 @@
7575
"@types/serviceworker": "^0.0.120",
7676
"@unocss/postcss": "66.5.4",
7777
"@vitest/coverage-v8": "^4.0.18",
78+
"acorn": "^8.16.0",
79+
"uglify-js":"^3.19.3",
7880
"autoprefixer": "^10.4.21",
7981
"cross-env": "^10.1.0",
8082
"crx": "^5.0.1",
@@ -89,6 +91,7 @@
8991
"iconv-lite": "^0.7.2",
9092
"jsdom": "^26.1.0",
9193
"jszip": "^3.10.1",
94+
"magic-string": "^0.30.21",
9295
"mock-xmlhttprequest": "^8.4.1",
9396
"postcss": "^8.5.6",
9497
"postcss-loader": "^8.2.0",

0 commit comments

Comments
 (0)