popup细节
Some checks failed
test / Run tests (push) Failing after 3s
build / Build (push) Failing after 5s
Some checks failed
test / Run tests (push) Failing after 3s
build / Build (push) Failing after 5s
This commit is contained in:
@ -48,6 +48,10 @@ export class ScriptClient extends Client {
|
||||
getScriptRunResource(script: Script): Promise<ScriptRunResouce> {
|
||||
return this.do("getScriptRunResource", script);
|
||||
}
|
||||
|
||||
excludeUrl(uuid: string, url: string, remove: boolean) {
|
||||
return this.do("excludeUrl", { uuid, url, remove });
|
||||
}
|
||||
}
|
||||
|
||||
export class ResourceClient extends Client {
|
||||
|
@ -10,6 +10,7 @@ import {
|
||||
Script,
|
||||
ScriptDAO,
|
||||
SCRIPT_TYPE_NORMAL,
|
||||
SCRIPT_RUN_STATUS_RUNNING,
|
||||
} from "@App/app/repo/scripts";
|
||||
import {
|
||||
ScriptMenuRegisterCallbackValue,
|
||||
@ -54,9 +55,11 @@ export class PopupService {
|
||||
) {}
|
||||
|
||||
genScriptMenuByTabMap(menu: ScriptMenu[]) {
|
||||
let n = 0;
|
||||
menu.forEach((script) => {
|
||||
// 创建脚本菜单
|
||||
if (script.menus.length) {
|
||||
n += script.menus.length;
|
||||
chrome.contextMenus.create({
|
||||
id: `scriptMenu_` + script.uuid,
|
||||
title: script.name,
|
||||
@ -65,7 +68,6 @@ export class PopupService {
|
||||
});
|
||||
script.menus.forEach((menu) => {
|
||||
// 创建菜单
|
||||
console.log("create menu", menu);
|
||||
chrome.contextMenus.create({
|
||||
id: `scriptMenu_menu_${script.uuid}_${menu.id}`,
|
||||
title: menu.name,
|
||||
@ -75,6 +77,7 @@ export class PopupService {
|
||||
});
|
||||
}
|
||||
});
|
||||
return n;
|
||||
}
|
||||
|
||||
// 生成chrome菜单
|
||||
@ -86,6 +89,7 @@ export class PopupService {
|
||||
if (!menu.length && !backgroundMenu.length) {
|
||||
return;
|
||||
}
|
||||
let n = 0;
|
||||
// 创建根菜单
|
||||
chrome.contextMenus.create({
|
||||
id: "scriptMenu",
|
||||
@ -93,18 +97,21 @@ export class PopupService {
|
||||
contexts: ["all"],
|
||||
});
|
||||
if (menu) {
|
||||
this.genScriptMenuByTabMap(menu);
|
||||
n += this.genScriptMenuByTabMap(menu);
|
||||
}
|
||||
// 后台脚本的菜单
|
||||
if (backgroundMenu) {
|
||||
this.genScriptMenuByTabMap(backgroundMenu);
|
||||
n += this.genScriptMenuByTabMap(backgroundMenu);
|
||||
}
|
||||
if (n === 0) {
|
||||
// 如果没有菜单,删除菜单
|
||||
chrome.contextMenus.remove("scriptMenu");
|
||||
}
|
||||
}
|
||||
|
||||
async registerMenuCommand(message: ScriptMenuRegisterCallbackValue) {
|
||||
// 给脚本添加菜单
|
||||
return this.txUpdateScriptMenu(message.tabId, async (data) => {
|
||||
console.log("register menu", message, data);
|
||||
const script = data.find((item) => item.uuid === message.uuid);
|
||||
if (script) {
|
||||
const menu = script.menus.find((item) => item.id === message.id);
|
||||
@ -165,7 +172,7 @@ export class PopupService {
|
||||
hasUserConfig: !!script.config,
|
||||
metadata: script.metadata,
|
||||
runStatus: script.runStatus,
|
||||
runNum: 0,
|
||||
runNum: script.type === SCRIPT_TYPE_NORMAL ? 0 : script.runStatus === SCRIPT_RUN_STATUS_RUNNING ? 1 : 0,
|
||||
runNumByIframe: 0,
|
||||
menus: [],
|
||||
customExclude: (script as ScriptMatchInfo).customizeExcludeMatches || [],
|
||||
@ -175,21 +182,21 @@ export class PopupService {
|
||||
// 获取popup页面数据
|
||||
async getPopupData(req: GetPopupDataReq): Promise<GetPopupDataRes> {
|
||||
// 获取当前tabId
|
||||
const scriptUuid = await this.runtime.getPageScriptByUrl(req.url);
|
||||
const script = await this.runtime.getPageScriptByUrl(req.url, true);
|
||||
// 与运行时脚本进行合并
|
||||
const runScript = await this.getScriptMenu(req.tabId);
|
||||
// 筛选出未运行的脚本
|
||||
const notRunScript = scriptUuid.filter((script) => {
|
||||
return !runScript.find((item) => item.uuid === script.uuid);
|
||||
});
|
||||
// 将未运行的脚本转换为菜单
|
||||
const scriptList = notRunScript.map((script): ScriptMenu => {
|
||||
// 合并数据
|
||||
const scriptMenu = script.map((script) => {
|
||||
const run = runScript.find((item) => item.uuid === script.uuid);
|
||||
if (run) {
|
||||
// 如果脚本已经存在,则不添加,赋值状态
|
||||
run.enable = script.status === SCRIPT_STATUS_ENABLE;
|
||||
return run;
|
||||
}
|
||||
return this.scriptToMenu(script);
|
||||
});
|
||||
runScript.push(...scriptList);
|
||||
// 后台脚本只显示开启或者运行中的脚本
|
||||
|
||||
return { scriptList: runScript, backScriptList: await this.getScriptMenu(-1) };
|
||||
return { scriptList: scriptMenu, backScriptList: await this.getScriptMenu(-1) };
|
||||
}
|
||||
|
||||
async getScriptMenu(tabId: number) {
|
||||
@ -263,17 +270,17 @@ export class PopupService {
|
||||
return;
|
||||
}
|
||||
return this.txUpdateScriptMenu(-1, async (menu) => {
|
||||
const scriptMenu = menu.find((item) => item.uuid === uuid);
|
||||
const index = menu.findIndex((item) => item.uuid === uuid);
|
||||
if (script.status === SCRIPT_STATUS_ENABLE) {
|
||||
// 加入菜单
|
||||
if (!scriptMenu) {
|
||||
if (index === -1) {
|
||||
const item = this.scriptToMenu(script);
|
||||
menu.push(item);
|
||||
}
|
||||
} else {
|
||||
// 移出菜单
|
||||
if (scriptMenu) {
|
||||
menu.splice(menu.indexOf(scriptMenu), 1);
|
||||
if (index !== -1) {
|
||||
menu.splice(index, 1);
|
||||
}
|
||||
}
|
||||
return menu;
|
||||
@ -281,9 +288,9 @@ export class PopupService {
|
||||
});
|
||||
subscribeScriptDelete(this.mq, async ({ uuid }) => {
|
||||
return this.txUpdateScriptMenu(-1, async (menu) => {
|
||||
const scriptMenu = menu.find((item) => item.uuid === uuid);
|
||||
if (scriptMenu) {
|
||||
menu.splice(menu.indexOf(scriptMenu), 1);
|
||||
const index = menu.findIndex((item) => item.uuid === uuid);
|
||||
if (index !== -1) {
|
||||
menu.splice(index, 1);
|
||||
return menu;
|
||||
}
|
||||
return null;
|
||||
@ -293,6 +300,7 @@ export class PopupService {
|
||||
return this.txUpdateScriptMenu(-1, async (menu) => {
|
||||
const scriptMenu = menu.find((item) => item.uuid === uuid);
|
||||
if (scriptMenu) {
|
||||
scriptMenu.runNum = 1;
|
||||
scriptMenu.runStatus = runStatus;
|
||||
return menu;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ export class RuntimeService {
|
||||
// 加载页面脚本
|
||||
await this.loadPageScript(script);
|
||||
if (!data.enable) {
|
||||
await this.unregistryPageScript(script);
|
||||
await this.unregistryPageScript(script.uuid);
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -82,15 +82,9 @@ export class RuntimeService {
|
||||
}
|
||||
});
|
||||
// 监听脚本删除
|
||||
subscribeScriptDelete(this.mq, async (data) => {
|
||||
const script = await this.scriptDAO.get(data.uuid);
|
||||
if (!script) {
|
||||
return;
|
||||
}
|
||||
if (script.type === SCRIPT_TYPE_NORMAL) {
|
||||
await this.unregistryPageScript(script);
|
||||
this.deleteScriptMatch(script.uuid);
|
||||
}
|
||||
subscribeScriptDelete(this.mq, async ({ uuid }) => {
|
||||
await this.unregistryPageScript(uuid);
|
||||
this.deleteScriptMatch(uuid);
|
||||
});
|
||||
|
||||
// 将开启的脚本发送一次enable消息
|
||||
@ -138,24 +132,29 @@ export class RuntimeService {
|
||||
return sendMessage(new ExtensionContentMessageSend(tabId, options), "content/runtime/" + action, data);
|
||||
}
|
||||
|
||||
async getPageScriptUuidByUrl(url: string) {
|
||||
async getPageScriptUuidByUrl(url: string, includeCustomize?: boolean) {
|
||||
const match = await this.loadScriptMatchInfo();
|
||||
// 匹配当前页面的脚本
|
||||
const matchScriptUuid = match.match(url!);
|
||||
// 排除自定义匹配
|
||||
const excludeScriptUuid = this.scriptCustomizeMatch.match(url!);
|
||||
const excludeMatch = new Set<string>();
|
||||
excludeScriptUuid.forEach((uuid) => {
|
||||
excludeMatch.add(uuid);
|
||||
});
|
||||
return matchScriptUuid.filter((value) => {
|
||||
// 过滤掉自定义排除的脚本
|
||||
return !excludeMatch.has(value);
|
||||
});
|
||||
// 包含自定义排除的脚本
|
||||
if (includeCustomize) {
|
||||
const excludeScriptUuid = this.scriptCustomizeMatch.match(url!);
|
||||
const match = new Set<string>();
|
||||
excludeScriptUuid.forEach((uuid) => {
|
||||
match.add(uuid);
|
||||
});
|
||||
matchScriptUuid.forEach((uuid) => {
|
||||
match.add(uuid);
|
||||
});
|
||||
// 转化为数组
|
||||
console.log("matchScriptUuid", matchScriptUuid);
|
||||
return Array.from(match);
|
||||
}
|
||||
return matchScriptUuid;
|
||||
}
|
||||
|
||||
async getPageScriptByUrl(url: string) {
|
||||
const matchScriptUuid = await this.getPageScriptUuidByUrl(url);
|
||||
async getPageScriptByUrl(url: string, includeCustomize?: boolean) {
|
||||
const matchScriptUuid = await this.getPageScriptUuidByUrl(url, includeCustomize);
|
||||
return matchScriptUuid.map((uuid) => {
|
||||
return Object.assign({}, this.scriptMatchCache?.get(uuid));
|
||||
});
|
||||
@ -266,15 +265,7 @@ export class RuntimeService {
|
||||
Object.keys(data).forEach((key) => {
|
||||
const item = data[key];
|
||||
cache.set(item.uuid, item);
|
||||
item.matches.forEach((match) => {
|
||||
this.scriptMatch.add(match, item.uuid);
|
||||
});
|
||||
item.excludeMatches.forEach((match) => {
|
||||
this.scriptMatch.exclude(match, item.uuid);
|
||||
});
|
||||
item.customizeExcludeMatches.forEach((match) => {
|
||||
this.scriptCustomizeMatch.exclude(match, item.uuid);
|
||||
});
|
||||
this.syncAddScriptMatch(item);
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -305,6 +296,11 @@ export class RuntimeService {
|
||||
await this.loadScriptMatchInfo();
|
||||
}
|
||||
this.scriptMatchCache!.set(item.uuid, item);
|
||||
this.syncAddScriptMatch(item);
|
||||
this.saveScriptMatchInfo();
|
||||
}
|
||||
|
||||
syncAddScriptMatch(item: ScriptMatchInfo) {
|
||||
// 清理一下老数据
|
||||
this.scriptMatch.del(item.uuid);
|
||||
this.scriptCustomizeMatch.del(item.uuid);
|
||||
@ -316,9 +312,8 @@ export class RuntimeService {
|
||||
this.scriptMatch.exclude(match, item.uuid);
|
||||
});
|
||||
item.customizeExcludeMatches.forEach((match) => {
|
||||
this.scriptCustomizeMatch.exclude(match, item.uuid);
|
||||
this.scriptCustomizeMatch.add(match, item.uuid);
|
||||
});
|
||||
this.saveScriptMatchInfo();
|
||||
}
|
||||
|
||||
async updateScriptStatus(uuid: string, status: SCRIPT_STATUS) {
|
||||
@ -329,11 +324,11 @@ export class RuntimeService {
|
||||
this.saveScriptMatchInfo();
|
||||
}
|
||||
|
||||
deleteScriptMatch(uuid: string) {
|
||||
async deleteScriptMatch(uuid: string) {
|
||||
if (!this.scriptMatchCache) {
|
||||
return;
|
||||
await this.loadScriptMatchInfo();
|
||||
}
|
||||
this.scriptMatchCache.delete(uuid);
|
||||
this.scriptMatchCache!.delete(uuid);
|
||||
this.scriptMatch.del(uuid);
|
||||
this.scriptCustomizeMatch.del(uuid);
|
||||
this.saveScriptMatchInfo();
|
||||
@ -394,24 +389,28 @@ export class RuntimeService {
|
||||
if (script.metadata["run-at"]) {
|
||||
registerScript.runAt = getRunAt(script.metadata["run-at"]);
|
||||
}
|
||||
await chrome.userScripts.register([registerScript]);
|
||||
if (await Cache.getInstance().get("registryScript:" + script.uuid)) {
|
||||
await chrome.userScripts.update([registerScript]);
|
||||
} else {
|
||||
await chrome.userScripts.register([registerScript]);
|
||||
}
|
||||
await Cache.getInstance().set("registryScript:" + script.uuid, true);
|
||||
}
|
||||
}
|
||||
|
||||
async unregistryPageScript(script: Script) {
|
||||
if (!(await Cache.getInstance().get("registryScript:" + script.uuid))) {
|
||||
async unregistryPageScript(uuid: string) {
|
||||
if (!(await Cache.getInstance().get("registryScript:" + uuid))) {
|
||||
return;
|
||||
}
|
||||
chrome.userScripts.unregister(
|
||||
{
|
||||
ids: [script.uuid],
|
||||
ids: [uuid],
|
||||
},
|
||||
() => {
|
||||
// 删除缓存
|
||||
Cache.getInstance().del("registryScript:" + script.uuid);
|
||||
Cache.getInstance().del("registryScript:" + uuid);
|
||||
// 修改脚本状态为disable
|
||||
this.updateScriptStatus(script.uuid, SCRIPT_STATUS_DISABLE);
|
||||
this.updateScriptStatus(uuid, SCRIPT_STATUS_DISABLE);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ export class ScriptService {
|
||||
.then(() => {
|
||||
logger.info("delete success");
|
||||
this.mq.publish("deleteScript", { uuid });
|
||||
return {};
|
||||
return true;
|
||||
})
|
||||
.catch((e) => {
|
||||
logger.error("delete error", Logger.E(e));
|
||||
@ -279,6 +279,32 @@ export class ScriptService {
|
||||
return Promise.resolve(ret);
|
||||
}
|
||||
|
||||
async excludeUrl({ uuid, url, remove }: { uuid: string; url: string; remove: boolean }) {
|
||||
const script = await this.scriptDAO.get(uuid);
|
||||
if (!script) {
|
||||
throw new Error("script not found");
|
||||
}
|
||||
script.selfMetadata = script.selfMetadata || {};
|
||||
let excludes = script.selfMetadata.exclude || script.metadata.exclude || [];
|
||||
if (remove) {
|
||||
excludes = excludes.filter((item) => item !== url);
|
||||
} else {
|
||||
excludes.push(url);
|
||||
}
|
||||
script.selfMetadata.exclude = excludes;
|
||||
return this.scriptDAO
|
||||
.update(uuid, script)
|
||||
.then(() => {
|
||||
// 广播一下
|
||||
this.mq.publish("installScript", { script, update: true });
|
||||
return true;
|
||||
})
|
||||
.catch((e) => {
|
||||
this.logger.error("exclude url error", Logger.E(e));
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
init() {
|
||||
this.listenerScriptInstall();
|
||||
|
||||
@ -290,5 +316,6 @@ export class ScriptService {
|
||||
this.group.on("updateRunStatus", this.updateRunStatus.bind(this));
|
||||
this.group.on("getCode", this.getCode.bind(this));
|
||||
this.group.on("getScriptRunResource", this.buildScriptRunResource.bind(this));
|
||||
this.group.on("excludeUrl", this.excludeUrl.bind(this));
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user