diff --git a/manifest.json b/manifest.json index b5633fa..9843c62 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ -{ +{ "manifest_version": 3, "name": "Mailsuite Signature Stripper", - "version": "0.1.0", + "version": "0.2.0", "description": "Removes the Mailsuite/Mailtrack promotional signature from your outgoing Gmail messages. Read tracking keeps working.", "permissions": ["storage"], "host_permissions": ["https://mail.google.com/*"], diff --git a/src/detect.js b/src/detect.js index 536188e..76f1112 100644 --- a/src/detect.js +++ b/src/detect.js @@ -29,6 +29,10 @@ */ const SIGNATURE_MARKERS = [ '#mt-signature', + /* Gmail rewrites ids when it quotes or renders a message, turning + id="mt-signature" into id="m_-1234...mt-signature", which is why + Mailsuite ships its own un-prefixing helper. Match on contains. */ + '[id*="mt-signature"]', '[data-signature-template]', '[class*="mt-signature"]', '[class*="mt-old-signature"]', diff --git a/src/strip.js b/src/strip.js index aa0daa7..9857ce1 100644 --- a/src/strip.js +++ b/src/strip.js @@ -10,14 +10,23 @@ const detect = globalThis.MailSuiteFreeDetect; if (!detect) return; - /* Gmail's compose body, across layouts and locales. */ - const COMPOSE = [ - 'div[g_editable="true"]', - 'div.Am.Al.editable', - 'div[contenteditable="true"][role="textbox"]', - 'div[aria-label="Message Body"]', - ].join(','); - + /* + * Scan the whole page, not a list of guessed compose selectors. + * + * The first version scoped every scan to div[g_editable="true"] and friends. + * That put a guess about Gmail's internal class names on the critical path: + * if the compose root did not match, nothing was ever examined and the + * extension silently did nothing. + * + * It does not need to be that fragile. #mt-signature and + * data-signature-template are Mailsuite's own labels and appear on nothing + * else, so if one is in the page it is theirs and it can go. Scanning from + * document.body removes an entire class of failure. + * + * Side effect worth knowing: this also hides the signature on Mailtrack mail + * you receive. Purely visual, in your browser, and it changes nothing about + * what anybody sent. + */ const settings = { enabled: true, keepUnsubscribe: true, removed: 0 }; chrome.storage.local.get(settings).then((stored) => Object.assign(settings, stored)); @@ -26,14 +35,14 @@ }); const scrubAll = () => { - if (!settings.enabled) return 0; - let removed = 0; - for (const root of document.querySelectorAll(COMPOSE)) { - removed += detect.scrubRoot(root, { keepUnsubscribe: settings.keepUnsubscribe }); - } + if (!settings.enabled || !document.body) return 0; + const removed = detect.scrubRoot(document.body, { + keepUnsubscribe: settings.keepUnsubscribe, + }); if (removed) { settings.removed += removed; chrome.storage.local.set({ removed: settings.removed }); + console.log(`[MailSuiteFree] removed ${removed} signature block(s)`); } return removed; }; @@ -81,5 +90,9 @@ true, ); + /* Says the content script is alive. If this line is missing from the Gmail + console, the extension is not loaded, which is a different problem from the + extension not working. */ + console.log('[MailSuiteFree] active on', location.host); scrubAll(); })(); diff --git a/test/detect.test.js b/test/detect.test.js index ba0effa..2b03665 100644 --- a/test/detect.test.js +++ b/test/detect.test.js @@ -187,6 +187,17 @@ test('a beacon inside the real signature survives it', () => { assert.equal(root.querySelectorAll('img[src*="/trace/mail/"]').length, 1); }); +test('catches the signature after Gmail has prefixed the id', () => { + /* Gmail rewrites ids when it renders or quotes a message, which is why + Mailsuite ships its own un-prefixing helper. */ + const root = compose( + '