Skip to content

Commit 2cf8141

Browse files
committed
Merge branch 'main' into release/v1.3
2 parents 2af2845 + 0892fcd commit 2cf8141

File tree

2 files changed

+176
-16
lines changed

2 files changed

+176
-16
lines changed

src/app/service/content/gm_api/gm_api.test.ts

Lines changed: 158 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,158 @@ describe.concurrent("GM_value", () => {
461461
expect(ret).toEqual({ ret1: 123, ret2: 456 });
462462
});
463463

464+
it.concurrent("value引用问题 #1141", async () => {
465+
const script = Object.assign({}, scriptRes) as ScriptLoadInfo;
466+
script.metadata.grant = ["GM_getValue", "GM_setValue", "GM_getValues"];
467+
script.code = `
468+
const value1 = {
469+
arr: [1],
470+
obj: {
471+
a: "1"
472+
},
473+
str: "123",
474+
}
475+
GM_setValue("abc", value1);
476+
477+
const allValues1 = GM_getValues();
478+
479+
allValues1.abc.arr.push(8);
480+
allValues1.n1 = 5;
481+
allValues1.n2 = {c: 8};
482+
delete allValues1.abc.obj.a;
483+
allValues1.abc.str = "0";
484+
485+
const value2 = GM_getValue("abc");
486+
487+
value2.arr.push(2);
488+
value2.obj.b = 2;
489+
value2.str = "456";
490+
491+
value1.arr.push(3);
492+
value1.obj.b = 3;
493+
value1.str = "789";
494+
495+
const value3 = GM_getValue("abc");
496+
497+
const values1 = GM_getValues(["abc", "n3"]);
498+
499+
const values2 = GM_getValues({"abc":{}, "n4":{}, "n5":"hi"});
500+
501+
values2.abc.arr.push(2);
502+
values2.abc.obj.b = 2;
503+
values2.abc.str = "456";
504+
505+
const allValues2 = GM_getValues();
506+
507+
508+
const value4 = GM_getValue("abc");
509+
const value5 = GM_getValue("abc");
510+
value5.arr[0] = 9;
511+
GM_setValue("abc", value5);
512+
513+
const value6 = GM_getValue("abc");
514+
515+
return { value1, value2, value3, values1,values2, allValues1, allValues2, value4, value5, value6 };
516+
`;
517+
const mockSendMessage = vi.fn().mockResolvedValue({ code: 0 });
518+
const mockMessage = {
519+
sendMessage: mockSendMessage,
520+
} as unknown as Message;
521+
// @ts-ignore
522+
const exec = new ExecScript(script, "content", mockMessage, nilFn, envInfo);
523+
exec.scriptFunc = compileScript(compileScriptCode(script));
524+
const ret = await exec.exec();
525+
526+
expect(mockSendMessage).toHaveBeenCalled();
527+
expect(mockSendMessage).toHaveBeenCalledTimes(2);
528+
529+
expect(ret).toEqual({
530+
value1: {
531+
arr: [1, 3],
532+
obj: {
533+
a: "1",
534+
b: 3,
535+
},
536+
str: "789",
537+
},
538+
value2: {
539+
arr: [1, 2],
540+
obj: {
541+
a: "1",
542+
b: 2,
543+
},
544+
str: "456",
545+
},
546+
value3: {
547+
arr: [1],
548+
obj: {
549+
a: "1",
550+
},
551+
str: "123",
552+
},
553+
values1: {
554+
abc: {
555+
arr: [1],
556+
obj: {
557+
a: "1",
558+
},
559+
str: "123",
560+
},
561+
},
562+
values2: {
563+
abc: {
564+
arr: [1, 2],
565+
obj: {
566+
a: "1",
567+
b: 2,
568+
},
569+
str: "456",
570+
},
571+
n4: {},
572+
n5: "hi",
573+
},
574+
allValues1: {
575+
abc: {
576+
arr: [1, 8],
577+
obj: {},
578+
str: "0",
579+
},
580+
n1: 5,
581+
n2: { c: 8 },
582+
},
583+
allValues2: {
584+
abc: {
585+
arr: [1],
586+
obj: {
587+
a: "1",
588+
},
589+
str: "123",
590+
},
591+
},
592+
value4: {
593+
arr: [1],
594+
obj: {
595+
a: "1",
596+
},
597+
str: "123",
598+
},
599+
value5: {
600+
arr: [9],
601+
obj: {
602+
a: "1",
603+
},
604+
str: "123",
605+
},
606+
value6: {
607+
arr: [9],
608+
obj: {
609+
a: "1",
610+
},
611+
str: "123",
612+
},
613+
});
614+
});
615+
464616
it.concurrent("GM_setValues", async () => {
465617
const script = Object.assign({}, scriptRes) as ScriptLoadInfo;
466618
script.metadata.grant = ["GM_getValues", "GM_setValues"];
@@ -499,7 +651,7 @@ describe.concurrent("GM_value", () => {
499651
api: "GM_setValues",
500652
params: [
501653
// event id
502-
expect.stringMatching(/^.+::\d$/),
654+
expect.stringMatching(/^.+::\d+$/),
503655
// the object payload
504656
keyValuePairs1,
505657
],
@@ -523,7 +675,7 @@ describe.concurrent("GM_value", () => {
523675
api: "GM_setValues",
524676
params: [
525677
// event id
526-
expect.stringMatching(/^.+::\d$/),
678+
expect.stringMatching(/^.+::\d+$/),
527679
// the object payload
528680
keyValuePairs2,
529681
],
@@ -573,7 +725,7 @@ describe.concurrent("GM_value", () => {
573725
api: "GM_setValues",
574726
params: [
575727
// event id
576-
expect.stringMatching(/^.+::\d$/),
728+
expect.stringMatching(/^.+::\d+$/),
577729
// the object payload
578730
keyValuePairs1,
579731
],
@@ -592,7 +744,7 @@ describe.concurrent("GM_value", () => {
592744
api: "GM_setValue",
593745
params: [
594746
// event id
595-
expect.stringMatching(/^.+::\d$/),
747+
expect.stringMatching(/^.+::\d+$/),
596748
// the string payload
597749
"b",
598750
],
@@ -643,7 +795,7 @@ describe.concurrent("GM_value", () => {
643795
api: "GM_setValues",
644796
params: [
645797
// event id
646-
expect.stringMatching(/^.+::\d$/),
798+
expect.stringMatching(/^.+::\d+$/),
647799
// the object payload
648800
keyValuePairs1,
649801
],
@@ -667,7 +819,7 @@ describe.concurrent("GM_value", () => {
667819
api: "GM_setValues",
668820
params: [
669821
// event id
670-
expect.stringMatching(/^.+::\d$/),
822+
expect.stringMatching(/^.+::\d+$/),
671823
// the string payload
672824
keyValuePairs2,
673825
],

src/app/service/content/gm_api/gm_api.ts

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,9 @@ export default class GMApi extends GM_Base {
237237
if (!a.scriptRes) return undefined;
238238
const ret = a.scriptRes.value[key];
239239
if (ret !== undefined) {
240+
if (ret && typeof ret === "object") {
241+
return structuredClone(ret);
242+
}
240243
return ret;
241244
}
242245
return defaultValue;
@@ -268,14 +271,14 @@ export default class GMApi extends GM_Base {
268271
if (promise) {
269272
valueChangePromiseMap.set(id, promise);
270273
}
271-
// 对object的value进行一次转化
272-
if (value && typeof value === "object") {
273-
value = JSON.parse(JSON.stringify(value));
274-
}
275274
if (value === undefined) {
276275
delete a.scriptRes.value[key];
277276
a.sendMessage("GM_setValue", [id, key]);
278277
} else {
278+
// 对object的value进行一次转化
279+
if (value && typeof value === "object") {
280+
value = structuredClone(value);
281+
}
279282
a.scriptRes.value[key] = value;
280283
a.sendMessage("GM_setValue", [id, key, value]);
281284
}
@@ -297,13 +300,13 @@ export default class GMApi extends GM_Base {
297300
const keyValuePairs = [] as [string, REncoded<unknown>][];
298301
for (const [key, value] of Object.entries(values)) {
299302
let value_ = value;
300-
// 对object的value进行一次转化
301-
if (value_ && typeof value_ === "object") {
302-
value_ = JSON.parse(JSON.stringify(value_));
303-
}
304303
if (value_ === undefined) {
305304
if (valueStore[key]) delete valueStore[key];
306305
} else {
306+
// 对object的value进行一次转化
307+
if (value_ && typeof value_ === "object") {
308+
value_ = structuredClone(value_);
309+
}
307310
valueStore[key] = value_;
308311
}
309312
// 避免undefined 等空值流失,先进行映射处理
@@ -369,7 +372,7 @@ export default class GMApi extends GM_Base {
369372
if (!this.scriptRes) return {};
370373
if (!keysOrDefaults) {
371374
// Returns all values
372-
return this.scriptRes.value;
375+
return structuredClone(this.scriptRes.value);
373376
}
374377
const result: TGMKeyValue = {};
375378
if (Array.isArray(keysOrDefaults)) {
@@ -378,7 +381,12 @@ export default class GMApi extends GM_Base {
378381
for (let index = 0; index < keysOrDefaults.length; index++) {
379382
const key = keysOrDefaults[index];
380383
if (key in this.scriptRes.value) {
381-
result[key] = this.scriptRes.value[key];
384+
// 对object的value进行一次转化
385+
let value = this.scriptRes.value[key];
386+
if (value && typeof value === "object") {
387+
value = structuredClone(value);
388+
}
389+
result[key] = value;
382390
}
383391
}
384392
} else {

0 commit comments

Comments
 (0)