Skip to content

Commit

Permalink
🐛 修复GM_xhr unsafeHeader 发送错误、popup支持运行
Browse files Browse the repository at this point in the history
  • Loading branch information
CodFrm committed Nov 2, 2022
1 parent fe96990 commit 02d1a45
Show file tree
Hide file tree
Showing 21 changed files with 377 additions and 42 deletions.
16 changes: 16 additions & 0 deletions example/cloudcat.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// ==UserScript==
// @name cloudscript
// @namespace https://bbs.tampermonkey.net.cn/
// @version 0.1.0
// @description 可以导出成nodejs可执行的包,在云端执行
// @author You
// @crontab * * once * *
// @cloudCat
// @exportCookie domain=.scriptscat.org
// ==/UserScript==

return new Promise((resolve, reject) => {
// Your code here...
resolve();
});

3 changes: 3 additions & 0 deletions pkg/cloudscript/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# 脚本上云


17 changes: 17 additions & 0 deletions pkg/cloudscript/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export interface CloudScriptParams {
[key: string]: {
title: string;
type?: "select";
options?: string[];
};
}

export default class CloudScriptFactory {
static create() {}

static params(): { [key: string]: CloudScriptParams } {
return {
local: {},
};
}
}
6 changes: 6 additions & 0 deletions pkg/filesystem/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# 文件系统

用于同步和备份至云端

- zip
- webdav
9 changes: 6 additions & 3 deletions src/app/message/internal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,17 @@ export default class MessageInternal

onDisconnect?: () => void;

tag: TargetTag;

constructor(tag: TargetTag) {
super();
this.reconnect(tag);
this.tag = tag;
this.reconnect();
}

reconnect(tag: TargetTag) {
reconnect() {
this.port = chrome.runtime.connect({
name: tag,
name: this.tag,
});
this.channelManager = new WarpChannelManager((data) => {
this.nativeSend(data);
Expand Down
6 changes: 2 additions & 4 deletions src/app/migrate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
import { db } from "./repo/dao";
import { Script } from "./repo/scripts";

// 重命名字段,统一使用小峰驼
// 0.10.0重构,重命名字段,统一使用小峰驼
function renameField(): void {
db.version(16)
.stores({
scripts:
"++id,&uuid,name,namespace,author,originDomain,subscribeUrl,type,sort,status," +
"runStatus,createtime,updatetime,checktime",
logger: "++id,level,createtime",
export: "++id,&scriptId",
})
.upgrade(async (tx) => {
await tx
Expand All @@ -18,15 +19,12 @@ function renameField(): void {
.modify((script: { [key: string]: any }) => {
if (script.origin_domain) {
script.originDomain = script.origin_domain;
delete script.origin_domain;
}
if (script.checkupdate_url) {
script.checkUpdateUrl = script.checkupdate_url;
delete script.checkupdate_url;
}
if (script.download_url) {
script.downloadUrl = script.download_url;
delete script.download_url;
}
});
});
Expand Down
25 changes: 25 additions & 0 deletions src/app/repo/export.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { DAO, db } from "./dao";

export type ExportTarget = "local" | "tencentCloud" | "";

// 导出与本地脚本关联记录
export interface Export {
id: number;
scriptId: number;
params?: {
[key: string]: {
[key: string]: any;
};
};
// 导出目标
target: ExportTarget;
}

export class ExportDAO extends DAO<Export> {
public tableName = "export";

constructor() {
super();
this.table = db.table(this.tableName);
}
}
10 changes: 5 additions & 5 deletions src/app/service/script/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,13 @@ export class ScriptManager extends Manager {
}
} catch (e) {
logger.error("prepare script failed", Logger.E(e));
return;
}
} else {
Cache.getInstance().set(CacheKey.scriptInfo(info.uuid), info);
chrome.tabs.create({
url: `src/install.html?uuid=${info.uuid}`,
});
}
Cache.getInstance().set(CacheKey.scriptInfo(info.uuid), info);
chrome.tabs.create({
url: `src/install.html?uuid=${info.uuid}`,
});
})
.catch((e) => {
logger.error("fetch script info failed", Logger.E(e));
Expand Down
20 changes: 16 additions & 4 deletions src/app/service/system/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import IoC from "@App/app/ioc";
import { MessageHander } from "@App/app/message/message";
import { ScriptDAO } from "@App/app/repo/scripts";
import { SystemConfig } from "@App/pkg/config/config";
import semver from "semver";
import Manager from "../manager";

// value管理器,负责value等更新获取等操作
Expand Down Expand Up @@ -47,13 +48,24 @@ export class SystemManager extends Manager {
if (details.reason === "install") {
chrome.tabs.create({ url: "https://docs.scriptcat.org/" });
} else if (details.reason === "update") {
chrome.tabs.create({
url: "https://docs.scriptcat.org/docs/change/",
});
const version = semver.parse(ExtVersion);
if (version && version.prerelease) {
chrome.tabs.create({
url: "https://docs.scriptcat.org/docs/change/",
});
} else {
chrome.tabs.create({
url: "https://docs.scriptcat.org/docs/change/pre-release",
});
}
}
});
}
// 处理
// 处理pingpong
this.message.setHandler("ping", () => {
return Promise.resolve("pong");
});
// 处理外部网站调用
this.message.setHandler(
ExternalMessage,
async (
Expand Down
117 changes: 117 additions & 0 deletions src/pages/components/CloudScript/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { Script } from "@App/app/repo/scripts";
import {
Button,
Checkbox,
Form,
Input,
Modal,
Select,
} from "@arco-design/web-react";
import FormItem from "@arco-design/web-react/es/Form/form-item";
import { IconQuestionCircleFill } from "@arco-design/web-react/icon";
import CloudScriptFactory from "@Pkg/cloudscript/factory";
import React, { useEffect } from "react";

const cloudScriptParams = CloudScriptFactory.params();

const CloudScriptList = [
{
key: "local",
name: "本地",
},
];

const CloudScript: React.FC<{
// eslint-disable-next-line react/require-default-props
script?: Script;
onClose: () => void;
}> = ({ script, onClose }) => {
const [visible, setVisible] = React.useState(false);
const [cloudScriptType, setCloudScriptType] = React.useState("local");

useEffect(() => {
if (script) {
setVisible(true);
}
}, [script]);
return (
<Modal
title={
<div>
<span
style={{
height: "32px",
lineHeight: "32px",
}}
>
{script?.name} 上传至云
</span>
<Button
type="text"
icon={
<IconQuestionCircleFill
style={{
margin: 0,
}}
/>
}
href="https://docs.scriptcat.org/docs/dev/cloudcat/"
target="_blank"
iconOnly
/>
</div>
}
visible={visible}
onCancel={() => {
setVisible(false);
onClose();
}}
>
<Form
autoComplete="off"
style={{
width: "100%",
}}
layout="vertical"
>
<FormItem label="上传至">
<Select
value={cloudScriptType}
onChange={(value) => {
setCloudScriptType(value);
}}
>
{CloudScriptList.map((item) => (
<Select.Option key={item.key} value={item.key}>
{item.name}
</Select.Option>
))}
</Select>
</FormItem>
{Object.keys(cloudScriptParams[cloudScriptType]).map((key) => {
const item = cloudScriptParams[cloudScriptType][key];
return (
<FormItem key={key} label={item.title}>
<Input />
</FormItem>
);
})}
<FormItem label="值导出表达式">
<Input.TextArea />
</FormItem>
<FormItem label="">
<Checkbox>导入时覆盖原值</Checkbox>
</FormItem>
<FormItem label="cookie导出表达式">
<Input.TextArea />
</FormItem>
<FormItem label="">
<Checkbox>导入时覆盖原值</Checkbox>
</FormItem>
<Button type="primary">恢复默认值</Button>
</Form>
</Modal>
);
};

export default CloudScript;
1 change: 0 additions & 1 deletion src/pages/components/FileSystemParams/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ const fileSystemList = [
{
key: "webdav",
name: "WebDAV",
params: fsParams.webdav,
},
];
const FileSystemParams: React.FC<{
Expand Down
49 changes: 48 additions & 1 deletion src/pages/components/ScriptMenuList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,42 @@ import {
import IoC from "@App/app/ioc";
import ScriptController from "@App/app/service/script/controller";
import { SCRIPT_RUN_STATUS_RUNNING } from "@App/app/repo/scripts";
import { RiPlayFill, RiStopFill } from "react-icons/ri";
import RuntimeController from "@App/runtime/content/runtime";

const CollapseItem = Collapse.Item;

// 用于popup页的脚本操作列表
const ScriptMenuList: React.FC<{
script: ScriptMenu[];
}> = ({ script }) => {
isBackscript: boolean;
}> = ({ script, isBackscript }) => {
const [list, setList] = useState([] as ScriptMenu[]);
const message = IoC.instance(MessageInternal) as MessageInternal;
const scriptCtrl = IoC.instance(ScriptController) as ScriptController;
const runtimeCtrl = IoC.instance(RuntimeController) as RuntimeController;
useEffect(() => {
setList(script);
}, [script]);

useEffect(() => {
// 监听脚本运行状态
const channel = runtimeCtrl.watchRunStatus();
channel.setHandler(([id, status]: any) => {
setList((prev) => {
const newList = [...prev];
const index = newList.findIndex((item) => item.id === id);
if (index !== -1) {
newList[index].runStatus = status;
}
return newList;
});
});
return () => {
channel.disChannel();
};
}, []);

const sendMenuAction = (sender: MessageSender, channelFlag: string) => {
let id = sender.tabId;
if (sender.frameId) {
Expand Down Expand Up @@ -106,6 +129,30 @@ const ScriptMenuList: React.FC<{
contentStyle={{ padding: "0 0 0 40px" }}
>
<div className="flex flex-col">
{isBackscript && (
<Button
className="text-left"
type="secondary"
icon={
item.runStatus !== SCRIPT_RUN_STATUS_RUNNING ? (
<RiPlayFill />
) : (
<RiStopFill />
)
}
onClick={() => {
if (item.runStatus !== SCRIPT_RUN_STATUS_RUNNING) {
runtimeCtrl.startScript(item.id);
} else {
runtimeCtrl.stopScript(item.id);
}
}}
>
{item.runStatus !== SCRIPT_RUN_STATUS_RUNNING
? "运行一次"
: "停止"}
</Button>
)}
<Button
className="text-left"
type="secondary"
Expand Down
3 changes: 2 additions & 1 deletion src/pages/components/layout/Sider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ if (!hash.length) {

const Sider: React.FC = () => {
const [menuSelect, setMenuSelect] = useState(hash);
const [collapsed, setCollapsed] = useState(false);
const [collapsed, setCollapsed] = useState(localStorage.collapsed === "true");

return (
<HashRouter>
Expand All @@ -36,6 +36,7 @@ const Sider: React.FC = () => {
collapsed={collapsed}
width={200}
onCollapse={(c) => {
localStorage.collapsed = c;
setCollapsed(c);
}}
>
Expand Down
Loading

0 comments on commit 02d1a45

Please sign in to comment.