match
Some checks failed
build / Build (push) Failing after 6s
test / Run tests (push) Failing after 8s
Some checks failed
build / Build (push) Failing after 6s
test / Run tests (push) Failing after 8s
This commit is contained in:
parent
fc69019877
commit
eea3b43e0b
@ -39,9 +39,7 @@ export class Server {
|
||||
private logger = LoggerCore.getInstance().logger({ service: "messageServer" });
|
||||
|
||||
constructor(prefix: string, message: Message) {
|
||||
console.log("constructor", prefix, message);
|
||||
message.onConnect((msg: any, con: MessageConnect) => {
|
||||
console.log("onConnect", this.apiFunctionMap, this.apiFunctionMap.size);
|
||||
this.logger.trace("server onConnect", { msg });
|
||||
if (msg.action.startsWith(prefix)) {
|
||||
return this.connectHandle(msg.action.slice(prefix.length + 1), msg.data, con);
|
||||
@ -50,7 +48,6 @@ export class Server {
|
||||
});
|
||||
|
||||
message.onMessage((msg: { action: string; data: any }, sendResponse, sender) => {
|
||||
console.log("onConnect", this.apiFunctionMap, this.apiFunctionMap.size);
|
||||
this.logger.trace("server onMessage", { msg: msg as any });
|
||||
if (msg.action.startsWith(prefix)) {
|
||||
return this.messageHandle(msg.action.slice(prefix.length + 1), msg.data, sendResponse, sender);
|
||||
|
@ -12,6 +12,10 @@ export interface Writer {
|
||||
write(level: LogLevel, message: string, label: LogLabel): void;
|
||||
}
|
||||
|
||||
export class EmptyWriter implements Writer {
|
||||
write(): void {}
|
||||
}
|
||||
|
||||
export default class LoggerCore {
|
||||
static instance: LoggerCore;
|
||||
|
||||
|
@ -85,4 +85,8 @@ export class RuntimeClient extends Client {
|
||||
pageLoad(): Promise<{ flag: string; scripts: ScriptRunResouce[] }> {
|
||||
return this.do("pageLoad");
|
||||
}
|
||||
|
||||
scriptLoad(flag: string, uuid: string) {
|
||||
return this.do("scriptLoad", { flag, uuid });
|
||||
}
|
||||
}
|
||||
|
@ -8,9 +8,9 @@ import { ScriptService } from "./script";
|
||||
import { runScript, stopScript } from "../offscreen/client";
|
||||
import { getRunAt } from "./utils";
|
||||
import { randomString } from "@App/pkg/utils/utils";
|
||||
import { compileInjectScript, compileScriptCode } from "@App/runtime/content/utils";
|
||||
import { compileInjectScript, compileInjectScriptInfo, compileScriptCode } from "@App/runtime/content/utils";
|
||||
import Cache from "@App/app/cache";
|
||||
import { dealMatches } from "@App/pkg/utils/match";
|
||||
import { dealPatternMatches } from "@App/pkg/utils/match";
|
||||
|
||||
export class RuntimeService {
|
||||
scriptDAO: ScriptDAO = new ScriptDAO();
|
||||
@ -92,16 +92,17 @@ export class RuntimeService {
|
||||
});
|
||||
}
|
||||
|
||||
scriptFlag() {
|
||||
return Cache.getInstance().getOrSet("scriptInjectFlag", () => {
|
||||
messageFlag() {
|
||||
return Cache.getInstance().getOrSet("scriptInjectMessageFlag", () => {
|
||||
return Promise.resolve(randomString(16));
|
||||
});
|
||||
}
|
||||
|
||||
async pageLoad(_, sender: GetSender) {
|
||||
const scriptFlag = await this.scriptFlag();
|
||||
const scriptFlag = await this.messageFlag();
|
||||
const chromeSender = sender.getSender() as chrome.runtime.MessageSender;
|
||||
// 匹配当前页面的脚本
|
||||
console.log("pageLoad");
|
||||
|
||||
return Promise.resolve({ flag: scriptFlag });
|
||||
}
|
||||
@ -128,7 +129,7 @@ export class RuntimeService {
|
||||
.then((res) => res.text())
|
||||
.then(async (injectJs) => {
|
||||
// 替换ScriptFlag
|
||||
const code = `(function (ScriptFlag) {\n${injectJs}\n})('${await this.scriptFlag()}')`;
|
||||
const code = `(function (MessageFlag) {\n${injectJs}\n})('${await this.messageFlag()}')`;
|
||||
chrome.userScripts.register([
|
||||
{
|
||||
id: "scriptcat-inject",
|
||||
@ -168,19 +169,23 @@ export class RuntimeService {
|
||||
scriptRes.code = compileInjectScript(scriptRes);
|
||||
|
||||
matches.push(...(script.metadata["include"] || []));
|
||||
const patternMatches = dealPatternMatches(matches);
|
||||
const registerScript: chrome.userScripts.RegisteredUserScript = {
|
||||
id: scriptRes.uuid,
|
||||
js: [{ code: scriptRes.code }],
|
||||
matches: dealMatches(matches),
|
||||
matches: patternMatches.patternResult,
|
||||
world: "MAIN",
|
||||
};
|
||||
if (!script.metadata["noframes"]) {
|
||||
registerScript.allFrames = true;
|
||||
}
|
||||
|
||||
if (script.metadata["exclude-match"]) {
|
||||
const excludeMatches = script.metadata["exclude-match"];
|
||||
excludeMatches.push(...(script.metadata["exclude"] || []));
|
||||
registerScript.excludeMatches = dealMatches(excludeMatches);
|
||||
const result= dealPatternMatches(excludeMatches);
|
||||
|
||||
registerScript.excludeMatches =result.patternResult;
|
||||
}
|
||||
if (script.metadata["run-at"]) {
|
||||
registerScript.runAt = getRunAt(script.metadata["run-at"]);
|
||||
@ -190,13 +195,22 @@ export class RuntimeService {
|
||||
Cache.getInstance().set("registryScript:" + script.uuid, true);
|
||||
});
|
||||
console.log(registerScript);
|
||||
// 把脚本uuid注册到content页面
|
||||
// 把脚本信息注入到USER_SCRIPT环境中
|
||||
chrome.userScripts.register([
|
||||
{
|
||||
id: "content-" + scriptRes.uuid,
|
||||
js: [{ code: "window.a=1;console.log('window.a',window,window.b)" }],
|
||||
matches: dealMatches(matches),
|
||||
id: "scriptinfo-" + scriptRes.uuid,
|
||||
js: [
|
||||
{
|
||||
code: compileInjectScriptInfo(
|
||||
await this.messageFlag(),
|
||||
scriptRes,
|
||||
await (await fetch("inject_script_info.js")).text()
|
||||
),
|
||||
},
|
||||
],
|
||||
matches: dealPatternMatches(matches),
|
||||
runAt: "document_start",
|
||||
world: "USER_SCRIPT",
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
@ -23,7 +23,3 @@ client.pageLoad().then((data) => {
|
||||
const runtime = new ContentRuntime(send, msg);
|
||||
runtime.start(data.scripts);
|
||||
});
|
||||
|
||||
chrome.storage.local.get((data) => {
|
||||
console.log(data);
|
||||
});
|
||||
|
@ -5,10 +5,7 @@ import { Server } from "@Packages/message/server";
|
||||
import { InjectRuntime } from "./runtime/content/inject";
|
||||
import { ScriptRunResouce } from "./app/repo/scripts";
|
||||
|
||||
// 通过flag与content建立通讯,这个ScriptFlag是后端注入时候生成的
|
||||
const flag = ScriptFlag;
|
||||
|
||||
const msg = new CustomEventMessage(flag, false);
|
||||
const msg = new CustomEventMessage(MessageFlag, false);
|
||||
|
||||
// 加载logger组件
|
||||
const logger = new LoggerCore({
|
||||
|
@ -1,10 +1,157 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { dealMatches } from "./match";
|
||||
import { dealPatternMatches, parsePatternMatchesURL, UrlMatch } from "./match";
|
||||
|
||||
// https://developer.chrome.com/docs/extensions/mv3/match_patterns/
|
||||
describe("dealMatches", () => {
|
||||
it("*://link.17173.com*", () => {
|
||||
const matches = dealMatches(["*://link.17173.com*"]);
|
||||
expect(matches).toEqual(["*://link.17173.com/*"]);
|
||||
describe("UrlMatch-google", () => {
|
||||
const url = new UrlMatch<string>();
|
||||
url.add("https://*/*", "ok1");
|
||||
url.add("https://*/foo*", "ok2");
|
||||
url.add("https://*.google.com/foo*bar", "ok3");
|
||||
url.add("https://example.org/foo/bar.html", "ok4");
|
||||
url.add("http://127.0.0.1/*", "ok5");
|
||||
url.add("*://mail.google.com/*", "ok6");
|
||||
it("match1", () => {
|
||||
expect(url.match("https://www.google.com/")).toEqual(["ok1"]);
|
||||
expect(url.match("https://example.org/foo/bar.html")).toEqual(["ok1", "ok2", "ok4"]);
|
||||
});
|
||||
it("match2", () => {
|
||||
expect(url.match("https://example.com/foo/bar.html")).toEqual(["ok1", "ok2"]);
|
||||
expect(url.match("https://www.google.com/foo")).toEqual(["ok1", "ok2"]);
|
||||
expect(url.match("https://www.google.com/foo2")).toEqual(["ok1", "ok2"]);
|
||||
});
|
||||
it("match3", () => {
|
||||
expect(url.match("https://www.google.com/foo/baz/bar")).toEqual(["ok1", "ok2", "ok3"]);
|
||||
expect(url.match("https://docs.google.com/foobar")).toEqual(["ok1", "ok2", "ok3"]);
|
||||
});
|
||||
it("match4", () => {
|
||||
expect(url.match("https://example.org/foo/bar.html")).toEqual(["ok1", "ok2", "ok4"]);
|
||||
});
|
||||
it("match5", () => {
|
||||
expect(url.match("http://127.0.0.1/")).toEqual(["ok5"]);
|
||||
expect(url.match("http://127.0.0.1/foo/bar.html")).toEqual(["ok5"]);
|
||||
});
|
||||
it("match6", () => {
|
||||
expect(url.match("http://mail.google.com/foo/baz/bar")).toEqual(["ok6"]);
|
||||
expect(url.match("https://mail.google.com/foobar")).toEqual(["ok1", "ok2", "ok3", "ok6"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("UrlMatch-google-error", () => {
|
||||
const url = new UrlMatch<string>();
|
||||
it("error-1", () => {
|
||||
expect(() => {
|
||||
url.add("https://*foo/bar", "ok1");
|
||||
}).toThrow(Error);
|
||||
});
|
||||
it("error-2", () => {
|
||||
expect(() => {
|
||||
url.add("https://foo.*.bar/baz", "ok1");
|
||||
}).toThrow(Error);
|
||||
});
|
||||
it("error-3", () => {
|
||||
expect(() => {
|
||||
url.add("http:/bar", "ok1");
|
||||
}).toThrow(Error);
|
||||
});
|
||||
});
|
||||
|
||||
// 从tm找的一些特殊的匹配规则
|
||||
describe("UrlMatch-search", () => {
|
||||
const url = new UrlMatch<string>();
|
||||
url.add("https://www.google.com/search?q=*", "ok1");
|
||||
it("match1", () => {
|
||||
expect(url.match("https://www.google.com/search?q=foo")).toEqual(["ok1"]);
|
||||
expect(url.match("https://www.google.com/search?q1=foo")).toEqual([]);
|
||||
});
|
||||
|
||||
url.add("https://bbs.tampermonkey.net.cn", "ok2");
|
||||
it("match2", () => {
|
||||
expect(url.match("https://bbs.tampermonkey.net.cn")).toEqual(["ok2"]);
|
||||
expect(url.match("https://bbs.tampermonkey.net.cn/")).toEqual(["ok2"]);
|
||||
expect(url.match("https://bbs.tampermonkey.net.cn/foo/bar.html")).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("UrlMatch-port1", () => {
|
||||
const url = new UrlMatch<string>();
|
||||
url.add("http://test.list.ggnb.top/search", "ok1");
|
||||
it("match1", () => {
|
||||
expect(url.match("http://test.list.ggnb.top/search")).toEqual(["ok1"]);
|
||||
expect(url.match("http://test.list.ggnb.top/search?")).toEqual([]);
|
||||
expect(url.match("http://test.list.ggnb.top/search?foo=bar")).toEqual([]);
|
||||
});
|
||||
|
||||
it("port", () => {
|
||||
expect(url.match("http://test.list.ggnb.top:80/search")).toEqual(["ok1"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("UrlMatch-port2", () => {
|
||||
const url = new UrlMatch<string>();
|
||||
url.add("http://test.list.ggnb.top:80/search", "ok1");
|
||||
url.add("http://test.list.ggnb.top*/search", "ok2");
|
||||
url.add("http://test.list.ggnb.top:*/search", "ok3");
|
||||
url.add("http://localhost:3000/", "ok4");
|
||||
it("match1", () => {
|
||||
expect(url.match("http://test.list.ggnb.top:80/search")).toEqual(["ok1", "ok2", "ok3"]);
|
||||
expect(url.match("http://test.list.ggnb.top:81/search")).toEqual(["ok2", "ok3"]);
|
||||
expect(url.match("http://test.list.ggnb.top/search")).toEqual(["ok1", "ok2", "ok3"]);
|
||||
});
|
||||
it("case2", () => {
|
||||
expect(url.match("http://localhost:3000/")).toEqual(["ok4"]);
|
||||
expect(url.match("http://localhost:8000/")).toEqual([]);
|
||||
});
|
||||
});
|
||||
|
||||
// https://developer.chrome.com/docs/extensions/mv3/match_patterns/
|
||||
describe("dealPatternMatches", () => {
|
||||
it("https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns?hl=zh-cn#examples", () => {
|
||||
const matches = dealPatternMatches(["https://*/*", "http://127.0.0.1/*", "http://127.0.0.1/"]);
|
||||
expect(matches.patternResult).toEqual(["https://*/*", "http://127.0.0.1/*", "http://127.0.0.1/"]);
|
||||
});
|
||||
// 处理一些特殊情况
|
||||
it("*://link.17173.com*", () => {
|
||||
const matches = dealPatternMatches(["*://link.17173.com*"]);
|
||||
expect(matches.patternResult).toEqual(["*://link.17173.com/*"]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("parsePatternMatchesURL", () => {
|
||||
it("https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns?hl=zh-cn#examples", () => {
|
||||
const matches = parsePatternMatchesURL("https://*/*");
|
||||
expect(matches).toEqual({
|
||||
scheme: "https",
|
||||
host: "*",
|
||||
path: "*",
|
||||
});
|
||||
const matches2 = parsePatternMatchesURL("https://*/foo*");
|
||||
expect(matches2).toEqual({
|
||||
scheme: "https",
|
||||
host: "*",
|
||||
path: "foo*",
|
||||
});
|
||||
const matches3 = parsePatternMatchesURL("http://127.0.0.1/");
|
||||
expect(matches3).toEqual({
|
||||
scheme: "http",
|
||||
host: "127.0.0.1",
|
||||
path: "",
|
||||
});
|
||||
});
|
||||
it("search", () => {
|
||||
// 会忽略掉search部分
|
||||
const matches = parsePatternMatchesURL("https://*/*?search");
|
||||
expect(matches).toEqual({
|
||||
scheme: "https",
|
||||
host: "*",
|
||||
path: "*",
|
||||
});
|
||||
});
|
||||
it("*://link.17173.com*", () => {
|
||||
const matches = parsePatternMatchesURL("*://link.17173.com*");
|
||||
expect(matches).toEqual({
|
||||
scheme: "*",
|
||||
host: "link.17173.com",
|
||||
path: "*",
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -1,3 +1,5 @@
|
||||
import Logger from "@App/app/logger/logger";
|
||||
|
||||
export interface Url {
|
||||
scheme: string;
|
||||
host: string;
|
||||
@ -5,10 +7,15 @@ export interface Url {
|
||||
search: string;
|
||||
}
|
||||
|
||||
// 根据https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns?hl=zh-cn进行匹配
|
||||
export class Match {}
|
||||
export default class Match<T> {
|
||||
protected cache = new Map<string, T[]>();
|
||||
|
||||
export function parseURL(url: string): Url | undefined {
|
||||
protected rule = new Map<string, T[]>();
|
||||
|
||||
protected parseURL(url: string): Url | undefined {
|
||||
if (url.indexOf("*http") === 0) {
|
||||
url = url.substring(1);
|
||||
}
|
||||
const match = /^(.+?):\/\/(.*?)((\/.*?)(\?.*?|)|)$/.exec(url);
|
||||
if (match) {
|
||||
return {
|
||||
@ -30,25 +37,239 @@ export function parseURL(url: string): Url | undefined {
|
||||
default:
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
protected compileRe(url: string): string {
|
||||
const u = this.parseURL(url);
|
||||
if (!u) {
|
||||
return "";
|
||||
}
|
||||
switch (u.scheme) {
|
||||
case "*":
|
||||
u.scheme = ".+?";
|
||||
break;
|
||||
case "http*":
|
||||
u.scheme = "http[s]?";
|
||||
break;
|
||||
default:
|
||||
}
|
||||
let pos = u.host.indexOf("*");
|
||||
if (u.host === "*" || u.host === "**") {
|
||||
pos = -1;
|
||||
} else if (u.host.endsWith("*")) {
|
||||
// 处理*结尾
|
||||
if (!u.host.endsWith(":*")) {
|
||||
u.host = u.host.substring(0, u.host.length - 1);
|
||||
}
|
||||
} else if (pos !== -1 && pos !== 0) {
|
||||
return "";
|
||||
}
|
||||
u.host = u.host.replace(/\*/g, "[^/]*?");
|
||||
// 处理 *.开头
|
||||
if (u.host.startsWith("[^/]*?.")) {
|
||||
u.host = `([^/]*?\\.?)${u.host.substring(7)}`;
|
||||
} else if (pos !== -1) {
|
||||
if (u.host.indexOf(".") === -1) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
// 处理顶域
|
||||
if (u.host.endsWith("tld")) {
|
||||
u.host = `${u.host.substr(0, u.host.length - 3)}.*?`;
|
||||
}
|
||||
// 处理端口
|
||||
const pos2 = u.host.indexOf(":");
|
||||
if (pos2 === -1) {
|
||||
u.host = `${u.host}(:\\d+)?`;
|
||||
} else {
|
||||
const port = u.host.substring(pos2 + 1);
|
||||
if (port === "*") {
|
||||
u.host = `${u.host.substring(0, pos2)}(:\\d+)?`;
|
||||
} else {
|
||||
u.host = `${u.host.substring(0, pos2)}(:${port})?`;
|
||||
}
|
||||
}
|
||||
let re = `^${u.scheme}://${u.host}`;
|
||||
if (u.path === "/") {
|
||||
re += "[/]?";
|
||||
} else {
|
||||
re += u.path.replace(/\*/g, ".*?");
|
||||
}
|
||||
if (u.search) {
|
||||
re += u.search.replace(/([\\?])/g, "\\$1").replace(/\*/g, ".*?");
|
||||
}
|
||||
return `${re.replace(/\//g, "/")}$`;
|
||||
}
|
||||
|
||||
public add(url: string, val: T) {
|
||||
const re = this.compileRe(url);
|
||||
if (!re) {
|
||||
throw new Error(`invalid url: ${url}`);
|
||||
}
|
||||
let rule = this.rule.get(re);
|
||||
if (!rule) {
|
||||
rule = [];
|
||||
this.rule.set(re, rule);
|
||||
}
|
||||
rule.push(val);
|
||||
this.delCache();
|
||||
}
|
||||
|
||||
public match(url: string): T[] {
|
||||
let ret = this.cache.get(url);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
ret = [];
|
||||
try {
|
||||
this.rule.forEach((val, key) => {
|
||||
const re = new RegExp(key);
|
||||
if (re.test(url) && ret) {
|
||||
ret.push(...val);
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.warn("bad match rule", Logger.E(e));
|
||||
// LoggerCore.getLogger({ component: "match" }).warn(
|
||||
// "bad match rule",
|
||||
// Logger.E(e)
|
||||
// );
|
||||
}
|
||||
this.cache.set(url, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected static getId(val: any): string {
|
||||
if (typeof val === "object") {
|
||||
return (<{ uuid: string }>(<unknown>val)).uuid;
|
||||
}
|
||||
return <string>(<unknown>val);
|
||||
}
|
||||
|
||||
public del(val: T) {
|
||||
const id = Match.getId(val);
|
||||
this.rule.forEach((rules, key) => {
|
||||
const tmp: T[] = [];
|
||||
rules.forEach((rule) => {
|
||||
if (Match.getId(rule) !== id) {
|
||||
tmp.push(rule);
|
||||
}
|
||||
});
|
||||
if (tmp) {
|
||||
this.rule.set(key, tmp);
|
||||
} else {
|
||||
this.rule.delete(key);
|
||||
}
|
||||
});
|
||||
this.delCache();
|
||||
}
|
||||
|
||||
protected delCache() {
|
||||
this.cache.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// 处理油猴的match和include为chrome的matches
|
||||
export function dealMatches(matches: string[]) {
|
||||
const result: string[] = [];
|
||||
for (let i = 0; i < matches.length; i++) {
|
||||
const url = parseURL(matches[i]);
|
||||
if (url) {
|
||||
export class UrlMatch<T> extends Match<T> {
|
||||
protected excludeMatch = new Match<T>();
|
||||
|
||||
public exclude(url: string, val: T) {
|
||||
this.excludeMatch.add(url, val);
|
||||
}
|
||||
|
||||
public del(val: T): void {
|
||||
super.del(val);
|
||||
this.excludeMatch.del(val);
|
||||
this.cache.clear();
|
||||
}
|
||||
|
||||
public match(url: string): T[] {
|
||||
const cache = this.cache.get(url);
|
||||
if (cache) {
|
||||
return cache;
|
||||
}
|
||||
let ret = super.match(url);
|
||||
// 排除
|
||||
const includeMap = new Map();
|
||||
ret.forEach((val) => {
|
||||
includeMap.set(Match.getId(val), val);
|
||||
});
|
||||
const exclude = this.excludeMatch.match(url);
|
||||
const excludeMap = new Map();
|
||||
exclude.forEach((val) => {
|
||||
excludeMap.set(Match.getId(val), 1);
|
||||
});
|
||||
ret = [];
|
||||
includeMap.forEach((val: T, key) => {
|
||||
if (!excludeMap.has(key)) {
|
||||
ret.push(val);
|
||||
}
|
||||
});
|
||||
this.cache.set(url, ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
export interface PatternMatchesUrl {
|
||||
scheme: string;
|
||||
host: string;
|
||||
path: string;
|
||||
}
|
||||
|
||||
// 解析URL, 根据https://developer.chrome.com/docs/extensions/develop/concepts/match-patterns?hl=zh-cn进行处理
|
||||
export function parsePatternMatchesURL(url: string): PatternMatchesUrl | undefined {
|
||||
let result: PatternMatchesUrl | undefined;
|
||||
const match = /^(.+?):\/\/(.*?)(\/(.*?)(\?.*?|)|)$/.exec(url);
|
||||
if (match) {
|
||||
result = {
|
||||
scheme: match[1],
|
||||
host: match[2],
|
||||
path: match[4] || (url[url.length - 1] === "*" ? "*" : ""),
|
||||
};
|
||||
} else {
|
||||
// 处理一些特殊情况
|
||||
switch (url) {
|
||||
case "*":
|
||||
result = {
|
||||
scheme: "*",
|
||||
host: "*",
|
||||
path: "*",
|
||||
};
|
||||
break;
|
||||
default:
|
||||
}
|
||||
}
|
||||
if (result) {
|
||||
if (result.host !== "*") {
|
||||
// *开头但是不是*.的情况
|
||||
if (url.host.startsWith("*")) {
|
||||
if (!url.host.startsWith("*.")) {
|
||||
if (result.host.startsWith("*")) {
|
||||
if (!result.host.startsWith("*.")) {
|
||||
// 删除开头的*号
|
||||
url.host = url.host.slice(1);
|
||||
result.host = result.host.slice(1);
|
||||
}
|
||||
} else if (url.host.endsWith("*")) {
|
||||
url.host = url.host.slice(0, -1);
|
||||
}
|
||||
result.push(`${url.scheme}://${url.host}/${url.path}` + (url.search ? "?" + url.search : ""));
|
||||
// 结尾是*的情况
|
||||
if (result.host.endsWith("*")) {
|
||||
result.host = result.host.slice(0, -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// 处理油猴的match和include为chrome的pattern-matche
|
||||
export function dealPatternMatches(matches: string[]) {
|
||||
const patternResult: string[] = [];
|
||||
const result: string[] = [];
|
||||
for (let i = 0; i < matches.length; i++) {
|
||||
const url = parsePatternMatchesURL(matches[i]);
|
||||
if (url) {
|
||||
patternResult.push(`${url.scheme}://${url.host}/${url.path}`);
|
||||
result.push(matches[i]);
|
||||
}
|
||||
}
|
||||
return {
|
||||
patternResult,
|
||||
result,
|
||||
};
|
||||
}
|
||||
|
@ -10,6 +10,10 @@ export default class ContentRuntime {
|
||||
) {}
|
||||
|
||||
start(scripts: ScriptRunResouce[]) {
|
||||
console.log("onMessage");
|
||||
this.msg.onMessage((msg, sendResponse) => {
|
||||
console.log("content onMessage", msg);
|
||||
});
|
||||
// 由content到background
|
||||
// 转发gmApi消息
|
||||
// this.contentMessage.setHandler("gmApi", (action, data) => {
|
||||
|
@ -29,8 +29,18 @@ export function compileScript(code: string): ScriptFunc {
|
||||
}
|
||||
|
||||
export function compileInjectScript(script: ScriptRunResouce): string {
|
||||
return `window['${script.flag}']=function(context,GM_info){\n${script.code}\n}`;
|
||||
}
|
||||
|
||||
// 编译注入脚本信息
|
||||
export function compileInjectScriptInfo(
|
||||
messageFlag: string,
|
||||
script: ScriptRunResouce,
|
||||
injectScriptInfoCode: string
|
||||
): string {
|
||||
return (
|
||||
`console.log(window,'` + script.flag + `');window['${script.flag}']=function(context,GM_info){\n${script.code}\n}`
|
||||
`(function (MessageFlag, ScriptFlag, ScriptUuid) {\n${injectScriptInfoCode}\n})` +
|
||||
`('${messageFlag}', '${script.flag}', '${script.uuid}');`
|
||||
);
|
||||
}
|
||||
|
||||
|
2
src/types/main.d.ts
vendored
2
src/types/main.d.ts
vendored
@ -7,7 +7,7 @@ declare const sandbox: Window;
|
||||
|
||||
declare const self: ServiceWorkerGlobalScope;
|
||||
|
||||
declare const ScriptFlag: string;
|
||||
declare const MessageFlag: string;
|
||||
|
||||
// 可以让content与inject环境交换携带dom的对象
|
||||
declare let cloneInto: ((detail: any, view: any) => any) | undefined;
|
||||
|
Loading…
x
Reference in New Issue
Block a user