fix: in-player adblocker inject timing issue

- fix #1478
This commit is contained in:
JellyBrick
2023-12-11 07:45:43 +09:00
parent d0ca10e1a1
commit abf2a52b46
3 changed files with 41 additions and 19 deletions

View File

@ -1,3 +1,5 @@
import { contextBridge, webFrame } from 'electron';
import { blockers } from './types'; import { blockers } from './types';
import { createPlugin } from '@/utils'; import { createPlugin } from '@/utils';
import { import {
@ -107,31 +109,25 @@ export default createPlugin({
}, },
}, },
preload: { preload: {
script: 'window.JSON = window._proxyJson; window._proxyJson = undefined; window.Response = window._proxyResponse; window._proxyResponse = undefined; 0',
async start({ getConfig }) { async start({ getConfig }) {
const config = await getConfig(); const config = await getConfig();
if (config.blocker === blockers.WithBlocklists) { if (config.blocker === blockers.WithBlocklists) {
// Preload adblocker to inject scripts/styles // Preload adblocker to inject scripts/styles
await injectCliqzPreload(); await injectCliqzPreload();
} else if (config.blocker === blockers.InPlayer && !isInjected()) {
inject(contextBridge);
await webFrame.executeJavaScript(this.script);
} }
}, },
async onConfigChange(newConfig) { async onConfigChange(newConfig) {
if (newConfig.blocker === blockers.WithBlocklists) { if (newConfig.blocker === blockers.WithBlocklists) {
await injectCliqzPreload(); await injectCliqzPreload();
} else if (newConfig.blocker === blockers.InPlayer && !isInjected()) {
inject(contextBridge);
await webFrame.executeJavaScript(this.script);
} }
}, },
}, },
renderer: {
async start({ getConfig }) {
const config = await getConfig();
if (config.blocker === blockers.InPlayer && !isInjected()) {
inject();
}
},
onConfigChange(newConfig) {
if (newConfig.blocker === blockers.InPlayer && !isInjected()) {
inject();
}
},
}
}); });

View File

@ -1,3 +1,5 @@
export const inject: () => void; import type { ContextBridge } from 'electron';
export const inject: (contextBridge: ContextBridge) => void;
export const isInjected: () => boolean; export const isInjected: () => boolean;

View File

@ -12,7 +12,11 @@ let injected = false;
export const isInjected = () => injected; export const isInjected = () => injected;
export const inject = () => { /**
* @param {Electron.ContextBridge} contextBridge
* @returns {*}
*/
export const inject = (contextBridge) => {
injected = true; injected = true;
{ {
const pruner = function (o) { const pruner = function (o) {
@ -28,17 +32,37 @@ export const inject = () => {
return o; return o;
}; };
JSON.parse = new Proxy(JSON.parse, { contextBridge.exposeInMainWorld('_proxyJson', {
apply() { parse: new Proxy(JSON.parse, {
return pruner(Reflect.apply(...arguments)); apply() {
}, return pruner(Reflect.apply(...arguments));
},
}),
stringify: JSON.stringify,
[Symbol.toStringTag]: JSON[Symbol.toStringTag],
}); });
const withPrototype = (obj) => {
const protos = Object.getPrototypeOf(obj);
for (const [key, value] of Object.entries(protos)) {
if (Object.prototype.hasOwnProperty.call(obj, key)) continue;
if (typeof value === 'function') {
obj[key] = function (...args) {
return value.call(obj, ...args);
}
} else {
obj[key] = value;
}
}
return obj;
};
Response.prototype.json = new Proxy(Response.prototype.json, { Response.prototype.json = new Proxy(Response.prototype.json, {
apply() { apply() {
return Reflect.apply(...arguments).then((o) => pruner(o)); return Reflect.apply(...arguments).then((o) => pruner(o));
}, },
}); });
contextBridge.exposeInMainWorld('_proxyResponse', withPrototype(Response));
} }
(function () { (function () {