From 3d8642db52fa1c37ea33611b01081cb3d3c7e0c2 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 2 Apr 2026 13:19:14 +0000 Subject: [PATCH] Fix whitespace-only mappings highlighting every space on the page A mapping imported with real: " " (single space) passed the !m.real guard (space is truthy), producing new RegExp(" ", "gi") which matched every space character in the DOM and highlighted them all. - Added .trim() to all real/substitute guard conditions in content.js (inline substitute, reveal functions) and substitution-engine.js so whitespace-only values are treated as empty and skipped - Added the same guard in highlightMatches so the CSS Highlight API never creates ranges for blank search terms - Added trim + blank-check to the bulk import path in options.js so whitespace-only real values are dropped at import time rather than saved to storage https://claude.ai/code/session_01CwcZK8nqL8pyBH9AxDs9qo --- src/content/content.js | 5 +++-- src/lib/substitution-engine.js | 8 ++++---- src/options/options.js | 7 ++++--- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/content/content.js b/src/content/content.js index 552fd65..c71ec63 100644 --- a/src/content/content.js +++ b/src/content/content.js @@ -50,7 +50,7 @@ const sorted = [...maps].sort((a, b) => b.real.length - a.real.length); for (const m of sorted) { - if (!m.enabled || !m.real || !m.substitute) continue; + if (!m.enabled || !m.real?.trim() || !m.substitute?.trim()) continue; const escaped = esc(m.real); const regex = new RegExp(escaped, m.caseSensitive ? 'g' : 'gi'); let match; @@ -70,7 +70,7 @@ let result = text; const sorted = [...maps].sort((a, b) => b.substitute.length - a.substitute.length); for (const m of sorted) { - if (!m.enabled || !m.real || !m.substitute) continue; + if (!m.enabled || !m.real?.trim() || !m.substitute?.trim()) continue; const escaped = esc(m.substitute); const regex = new RegExp(escaped, m.caseSensitive ? 'g' : 'gi'); result = result.replace(regex, m.real); @@ -1130,6 +1130,7 @@ for (const p of pairs) { const searchTerm = settings.revealMode ? p.to : p.from; + if (!searchTerm?.trim()) continue; const escaped = esc(searchTerm); // Add word boundaries when the term starts/ends with word chars to // prevent partial-word matches (e.g. "aud" inside "Claude") diff --git a/src/lib/substitution-engine.js b/src/lib/substitution-engine.js index f7e5fd9..d0e64ec 100644 --- a/src/lib/substitution-engine.js +++ b/src/lib/substitution-engine.js @@ -21,7 +21,7 @@ const SubstitutionEngine = { ); for (const mapping of sorted) { - if (!mapping.enabled || !mapping.real || !mapping.substitute) continue; + if (!mapping.enabled || !mapping.real?.trim() || !mapping.substitute?.trim()) continue; const escaped = this._escapeRegex(mapping.real); const regex = new RegExp(escaped, mapping.caseSensitive ? 'g' : 'gi'); @@ -54,7 +54,7 @@ const SubstitutionEngine = { ); for (const mapping of sorted) { - if (!mapping.enabled || !mapping.real || !mapping.substitute) continue; + if (!mapping.enabled || !mapping.real?.trim() || !mapping.substitute?.trim()) continue; const escaped = this._escapeRegex(mapping.substitute); const regex = new RegExp(escaped, mapping.caseSensitive ? 'g' : 'gi'); @@ -71,7 +71,7 @@ const SubstitutionEngine = { const found = []; for (const mapping of mappings) { - if (!mapping.enabled || !mapping.real) continue; + if (!mapping.enabled || !mapping.real?.trim()) continue; const escaped = this._escapeRegex(mapping.real); const regex = new RegExp(escaped, mapping.caseSensitive ? 'g' : 'gi'); @@ -103,7 +103,7 @@ const SubstitutionEngine = { // Collect all match positions in the original text const matches = []; for (const mapping of sorted) { - if (!mapping.enabled || !mapping.real || !mapping.substitute) continue; + if (!mapping.enabled || !mapping.real?.trim() || !mapping.substitute?.trim()) continue; const escaped = this._escapeRegex(mapping.real); const regex = new RegExp(escaped, mapping.caseSensitive ? 'g' : 'gi'); diff --git a/src/options/options.js b/src/options/options.js index 313aedf..f78374a 100644 --- a/src/options/options.js +++ b/src/options/options.js @@ -1814,11 +1814,12 @@ async function applyBulkImport() { await Storage.updateProfile(profile.id, profile); } - // Add mappings + // Add mappings — skip any with blank/whitespace-only real values for (const m of result.mappings) { + if (!m.real?.trim()) continue; await Storage.addMapping({ - real: m.real, - substitute: m.substitute || '', + real: m.real.trim(), + substitute: m.substitute?.trim() || '', category: m.category || 'general', caseSensitive: false, });