From b88a978843d350b35e2d8d44c18497e301bd2a67 Mon Sep 17 00:00:00 2001 From: tophf Date: Wed, 3 Aug 2022 23:58:55 +0300 Subject: [PATCH] improve orphan check + cosmetics --- content/apply.js | 2 +- content/install-hook-userstyles.js | 44 ++++++++++++++++-------------- 2 files changed, 25 insertions(+), 21 deletions(-) diff --git a/content/apply.js b/content/apply.js index 2146b18c..a3a0ee19 100644 --- a/content/apply.js +++ b/content/apply.js @@ -259,7 +259,7 @@ } function orphanCheck() { - if (tryCatch(() => chrome.i18n.getUILanguage())) return; + if (chrome.runtime.id) return; // In Chrome content script is orphaned on an extension update/reload // so we need to detach event listeners window.removeEventListener(orphanEventId, orphanCheck, true); diff --git a/content/install-hook-userstyles.js b/content/install-hook-userstyles.js index 786e7ce4..082e7581 100644 --- a/content/install-hook-userstyles.js +++ b/content/install-hook-userstyles.js @@ -94,8 +94,8 @@ function onMutation(mutations) { for (const {target: el} of mutations) { if (el.style.display === 'none' && - /^ik-/.test(el.name) && - /^#[\da-f]{6}$/.test(el.value)) { + /^ik-/.test(el.name) && + /^#[\da-f]{6}$/.test(el.value)) { onChange({target: el}); } } @@ -174,7 +174,7 @@ } function orphanCheck() { - if (chrome.i18n) return true; + if (chrome.runtime.id) return true; removeEventListener(orphanEventId, orphanCheck, true); removeEventListener('click', onClick, true); removeEventListener('change', onChange); @@ -185,42 +185,46 @@ })(); function inPageContext(eventId, eventIdHost, styleId, apiUrl) { - window.isInstalled = true; const {dispatchEvent, CustomEvent, removeEventListener} = window; const apply = Map.call.bind(Map.apply); const CR = chrome.runtime; - const {sendMessage} = CR; + const SEND = 'sendMessage'; const RP = Response.prototype; - const origJson = RP.json; - let done, vars; - CR.sendMessage = function (id, msg, opts, cb = opts) { - if (id === 'fjnbnpbmkenffdnngjfgmeleoegfcffe' && + const ORIG = {json: RP.json, [SEND]: CR[SEND]}; + let done, orphaned, vars; + CR[SEND] = ovrSend; + RP.json = ovrJson; + window.isInstalled = true; + addEventListener(eventId, onCommand, true); + function ovrSend(id, msg, opts, cb = opts) { + if (!orphaned && + id === 'fjnbnpbmkenffdnngjfgmeleoegfcffe' && msg && msg.type === 'deleteStyle' && typeof cb === 'function') { cb(true); } else { - return sendMessage(...arguments); + return ORIG[SEND](...arguments); } - }; - RP.json = async function () { - const res = await apply(origJson, this, arguments); + } + async function ovrJson() { + const res = await apply(ORIG.json, this, arguments); try { if (!done && this.url === apiUrl) { - RP.json = origJson; - done = true; // will be used if called by another script that saved our RP.json hook + if (RP.json === ovrJson) RP.json = ORIG.json; + done = true; send(res); setVars(res); } } catch (e) {} return res; - }; - addEventListener(eventId, onCommand, true); + } function onCommand(e) { if (e.detail === 'quit') { removeEventListener(eventId, onCommand, true); - CR.sendMessage = sendMessage; - RP.json = origJson; - done = true; + // We can restore the hooks only if another script didn't modify them + if (CR[SEND] === ovrSend) CR[SEND] = ovrSend; + if (RP.json === ovrJson) RP.json = ORIG.json; + done = orphaned = true; } else if (/^vars:/.test(e.detail)) { vars = JSON.parse(e.detail.slice(5)); } else if (e.relatedTarget) {