From 490b2ebf33758c1d726b34f32657c9773840a28f Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 29 Mar 2026 19:56:57 +0000 Subject: [PATCH] Fix reveal mode not restoring substitute values on toggle off MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old unrevealInElement relied on a WeakMap (originalTexts) to restore text nodes to their pre-reveal state. This broke when SPA frameworks (React) re-rendered the DOM while reveal was active — new text nodes containing real values had no WeakMap entry to restore from, so real data stayed visible after turning reveal off. Fix: unrevealInElement now actively reverse-replaces real values back to their substitute counterparts using the reveal pairs, matching the same approach revealText uses in the forward direction. This works regardless of DOM re-renders or streaming content changes. https://claude.ai/code/session_01NNBEPuXMFGWezJb1f958nL --- src/content/content.js | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/content/content.js b/src/content/content.js index 7f35276..407e6cf 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -1035,15 +1035,37 @@ } } + function unrevealText(text) { + const pairs = getRevealPairs(); + let result = text; + for (const p of pairs) { + const escaped = esc(p.to); // p.to is the real value + const regex = new RegExp(escaped, p.caseSensitive ? 'g' : 'gi'); + result = result.replace(regex, p.from); // p.from is the substitute + } + return result; + } + function unrevealInElement(el) { if (SKIP_REVEAL_TAGS.has(el.tagName)) return; - const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT); + const walker = document.createTreeWalker(el, NodeFilter.SHOW_TEXT, { + acceptNode(node) { + const parent = node.parentElement; + if (parent && SKIP_REVEAL_TAGS.has(parent.tagName)) return NodeFilter.FILTER_REJECT; + if (parent?.closest?.('.ss-autodetect-warning, .ss-presend-warning, .ss-reveal-badge')) return NodeFilter.FILTER_REJECT; + return NodeFilter.FILTER_ACCEPT; + } + }); let textNode; while ((textNode = walker.nextNode())) { - const original = originalTexts.get(textNode); - if (original && textNode.textContent !== original) { - textNode.textContent = original; + const text = textNode.textContent; + if (!text || text.length < MIN_STRING_LENGTH) continue; + const unrevealed = unrevealText(text); + if (unrevealed !== text) { + textNode.textContent = unrevealed; + // Update saved original so future reveals start from the right state + originalTexts.set(textNode, unrevealed); } } }