From 386d596b499fa240060fa3ed98c2328a7471238f Mon Sep 17 00:00:00 2001 From: tophf Date: Sat, 2 Sep 2023 14:55:45 +0300 Subject: [PATCH] fix #1881: GM_log in Chrome 109+ --- src/injected/content/index.js | 1 + src/injected/content/inject.js | 6 +++--- src/injected/util/index.js | 2 ++ src/injected/web/index.js | 17 +++++++++++++++-- src/types.d.ts | 2 +- 5 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/injected/content/index.js b/src/injected/content/index.js index 060591e709..854d8bad6c 100644 --- a/src/injected/content/index.js +++ b/src/injected/content/index.js @@ -67,6 +67,7 @@ addBackgroundHandlers({ }); addHandlers({ + Log: data => safeApply(logging[data[0]], logging, data[1]), TabFocus: REIFY, UpdateValue: REIFY, }); diff --git a/src/injected/content/inject.js b/src/injected/content/inject.js index f7e1b79bb5..bd6c3bff2a 100644 --- a/src/injected/content/inject.js +++ b/src/injected/content/inject.js @@ -1,6 +1,6 @@ import bridge, { addHandlers } from './bridge'; import { elemByTag, makeElem, nextTask, onElement, sendCmd } from './util'; -import { bindEvents, fireBridgeEvent, META_STR } from '../util'; +import { bindEvents, CONSOLE_METHODS, fireBridgeEvent, META_STR } from '../util'; import { Run } from './cmd-run'; const bridgeIds = bridge[IDS]; @@ -308,7 +308,7 @@ async function injectPageList(runAt) { } function setupContentInvoker() { - const invokeContent = VMInitInjection(IS_FIREFOX)(bridge.onHandle); + const invokeContent = VMInitInjection(IS_FIREFOX)(bridge.onHandle, logging); const postViaBridge = bridge.post; bridge.post = (cmd, params, realm, node) => { const fn = realm === CONTENT @@ -348,7 +348,7 @@ function addVaultExports(vaultSrc) { const exports = cloneInto(createNullObj(), document); // In FF a detached iframe's `console` doesn't print anything, we'll export it from content const exportedConsole = cloneInto(createNullObj(), document); - ['log', 'info', 'warn', 'error', 'debug']::forEach(k => { + CONSOLE_METHODS::forEach(k => { exportedConsole[k] = exportFunction(logging[k], document); /* global exportFunction */ }); diff --git a/src/injected/util/index.js b/src/injected/util/index.js index da70b27130..c1a5637550 100644 --- a/src/injected/util/index.js +++ b/src/injected/util/index.js @@ -11,6 +11,8 @@ export { } from '@/common'; export * from '@/common/consts'; +export const CONSOLE_METHODS = ['log', 'info', 'warn', 'error', 'debug']; + export const fireBridgeEvent = (eventId, msg) => { const detail = cloneInto ? cloneInto(msg, document) : msg; const evtMain = new SafeCustomEvent(eventId, { __proto__: null, detail }); diff --git a/src/injected/web/index.js b/src/injected/web/index.js index c3f9aad61d..c090c2ce49 100644 --- a/src/injected/web/index.js +++ b/src/injected/web/index.js @@ -1,17 +1,19 @@ import bridge, { addHandlers } from './bridge'; import store from './store'; +import { GM_API } from './gm-api'; import { makeGmApiWrapper } from './gm-api-wrapper'; import './gm-values'; import './notifications'; import './requests'; import './tabs'; -import { bindEvents } from '../util'; +import { bindEvents, CONSOLE_METHODS } from '../util'; +import { safeConcat } from './util'; // Make sure to call safe::methods() in code that may run after userscripts const toRun = createNullObj(); -export default function initialize(invokeHost) { +export default function initialize(invokeHost, console) { if (PAGE_MODE_HANDSHAKE) { window::on(PAGE_MODE_HANDSHAKE + '*', e => { e = e::getDetail(); @@ -25,6 +27,16 @@ export default function initialize(invokeHost) { this[id] = VAULT; }, }); + /* Can't use a detached `console` in Chrome 109+ due to https://crrev.com/1063194 */ + if (!IS_FIREFOX) { + for (const m of CONSOLE_METHODS) { + logging[m] = (...args) => bridge.post('Log', [m, args]); + } + /** @this {GMContext} */ + GM_API.bound.GM_log = function (...args) { + bridge.post('Log', ['log', safeConcat([`[${this.script.displayName}]`], args)]); + }; + } } else { bridge.mode = CONTENT; bridge.post = (cmd, data, node) => { @@ -32,6 +44,7 @@ export default function initialize(invokeHost) { }; global.chrome = undefined; global.browser = undefined; + logging = console; // eslint-disable-line no-global-assign return (cmd, data, realm, node) => { if (process.env.DEBUG) console.info('[bridge.guest.content] received', { cmd, data, node }); bridge.onHandle({ cmd, data, node }); diff --git a/src/types.d.ts b/src/types.d.ts index 10068c9330..0ebdb5f1b1 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -18,7 +18,7 @@ declare interface GMContext { id: number; resCache: StringMap; resources: StringMap; - script: VMScript; + script: VMInjection.Script; } /**