Skip to content

Commit 66b1128

Browse files
committed
move the popup script out of the html, 1.1.1
MV3 serves extension pages under script-src 'self', which refuses an inline <script> outright. The popup's entire controller was inline, so it never ran in any build: the panel rendered, the textarea accepted input, and nothing was wired to it. Loading the folder unpacked and pasting a string with one U+200B and one U+00A0 now reports 2 hidden characters and enables the button.
1 parent 267c418 commit 66b1128

3 files changed

Lines changed: 60 additions & 50 deletions

File tree

extension/manifest.json

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
11
{
22
"manifest_version": 3,
33
"name": "Invisibles — hidden character cleaner",
4-
"version": "1.1.0",
4+
"version": "1.1.1",
55
"description": "See the invisible characters hiding in your text, then strip them. Runs in your browser, no permissions, nothing uploaded.",
6-
"icons": { "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" },
6+
"icons": {
7+
"16": "icons/icon16.png",
8+
"48": "icons/icon48.png",
9+
"128": "icons/icon128.png"
10+
},
711
"action": {
812
"default_popup": "popup.html",
913
"default_title": "Invisibles — clean hidden characters",
10-
"default_icon": { "16": "icons/icon16.png", "48": "icons/icon48.png", "128": "icons/icon128.png" }
14+
"default_icon": {
15+
"16": "icons/icon16.png",
16+
"48": "icons/icon48.png",
17+
"128": "icons/icon128.png"
18+
}
1119
}
1220
}

extension/popup.html

Lines changed: 1 addition & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -98,52 +98,6 @@ <h1>Invisibles</h1>
9898
</div>
9999

100100
<script src="core.js"></script>
101-
<script>
102-
(function(){
103-
var I=window.Invisibles;
104-
var inEl=document.getElementById('in'),cleanBtn=document.getElementById('clean'),
105-
copyBtn=document.getElementById('copy'),norm=document.getElementById('norm'),
106-
summary=document.getElementById('summary'),chips=document.getElementById('chips'),
107-
out=document.getElementById('out'),delta=document.getElementById('delta');
108-
109-
function render(){
110-
var text=inEl.value, r=I.scan(text);
111-
cleanBtn.disabled=!text||(r.total===0&&!norm.checked);
112-
if(!text){summary.innerHTML='';chips.innerHTML='';return;}
113-
if(r.total===0){
114-
summary.innerHTML='<span class="verdict clean">Clean.</span> No hidden characters.'+(norm.checked?' Punctuation will still be normalized.':'');
115-
chips.innerHTML='';return;
116-
}
117-
summary.innerHTML='<span class="verdict dirty">'+r.total+' hidden character'+(r.total>1?'s':'')+'</span> found.';
118-
var cats=Object.keys(r.counts).sort();
119-
chips.innerHTML=cats.map(function(c){
120-
var label=(I.CATEGORIES[c]||c).split(': ')[0];
121-
return '<span class="chip"><b>'+r.counts[c]+'</b> '+label+'</span>';
122-
}).join('');
123-
}
124-
function doClean(){
125-
var before=inEl.value, t=I.clean(before);
126-
if(norm.checked) t=I.normalizePunctuation(t);
127-
out.value=t; out.hidden=false; copyBtn.hidden=false;
128-
// A look-alike space becomes a real space, so it never shows up in a length
129-
// difference. Reporting only that difference read as "found 4, removed 2",
130-
// which looks like it missed two.
131-
var r=I.scan(before), swapped=r.counts.space||0, deleted=r.total-swapped, parts=[];
132-
if(deleted) parts.push(deleted+' removed');
133-
if(swapped) parts.push(swapped+' turned into a normal space');
134-
if(!parts.length) delta.textContent=norm.checked?'Punctuation normalized.':'Nothing to change.';
135-
else delta.textContent=parts.join(', ')+'.'+(norm.checked?' Punctuation normalized.':'');
136-
}
137-
copyBtn.addEventListener('click',function(){
138-
navigator.clipboard.writeText(out.value).then(function(){
139-
var o=copyBtn.textContent;copyBtn.textContent='Copied ✓';setTimeout(function(){copyBtn.textContent=o;},1300);
140-
}).catch(function(){out.select();document.execCommand('copy');});
141-
});
142-
inEl.addEventListener('input',render);
143-
norm.addEventListener('change',render);
144-
cleanBtn.addEventListener('click',doClean);
145-
render();
146-
})();
147-
</script>
101+
<script src="popup.js"></script>
148102
</body>
149103
</html>

extension/popup.js

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// Lives in its own file because MV3's default extension-page CSP is
2+
// script-src 'self', which refuses an inline <script> outright. Inlined, none of
3+
// this ran: the popup rendered and every control was dead.
4+
(function(){
5+
var I=window.Invisibles;
6+
var inEl=document.getElementById('in'),cleanBtn=document.getElementById('clean'),
7+
copyBtn=document.getElementById('copy'),norm=document.getElementById('norm'),
8+
summary=document.getElementById('summary'),chips=document.getElementById('chips'),
9+
out=document.getElementById('out'),delta=document.getElementById('delta');
10+
11+
function render(){
12+
var text=inEl.value, r=I.scan(text);
13+
cleanBtn.disabled=!text||(r.total===0&&!norm.checked);
14+
if(!text){summary.innerHTML='';chips.innerHTML='';return;}
15+
if(r.total===0){
16+
summary.innerHTML='<span class="verdict clean">Clean.</span> No hidden characters.'+(norm.checked?' Punctuation will still be normalized.':'');
17+
chips.innerHTML='';return;
18+
}
19+
summary.innerHTML='<span class="verdict dirty">'+r.total+' hidden character'+(r.total>1?'s':'')+'</span> found.';
20+
var cats=Object.keys(r.counts).sort();
21+
chips.innerHTML=cats.map(function(c){
22+
var label=(I.CATEGORIES[c]||c).split(': ')[0];
23+
return '<span class="chip"><b>'+r.counts[c]+'</b> '+label+'</span>';
24+
}).join('');
25+
}
26+
function doClean(){
27+
var before=inEl.value, t=I.clean(before);
28+
if(norm.checked) t=I.normalizePunctuation(t);
29+
out.value=t; out.hidden=false; copyBtn.hidden=false;
30+
// A look-alike space becomes a real space, so it never shows up in a length
31+
// difference. Reporting only that difference read as "found 4, removed 2",
32+
// which looks like it missed two.
33+
var r=I.scan(before), swapped=r.counts.space||0, deleted=r.total-swapped, parts=[];
34+
if(deleted) parts.push(deleted+' removed');
35+
if(swapped) parts.push(swapped+' turned into a normal space');
36+
if(!parts.length) delta.textContent=norm.checked?'Punctuation normalized.':'Nothing to change.';
37+
else delta.textContent=parts.join(', ')+'.'+(norm.checked?' Punctuation normalized.':'');
38+
}
39+
copyBtn.addEventListener('click',function(){
40+
navigator.clipboard.writeText(out.value).then(function(){
41+
var o=copyBtn.textContent;copyBtn.textContent='Copied ✓';setTimeout(function(){copyBtn.textContent=o;},1300);
42+
}).catch(function(){out.select();document.execCommand('copy');});
43+
});
44+
inEl.addEventListener('input',render);
45+
norm.addEventListener('change',render);
46+
cleanBtn.addEventListener('click',doClean);
47+
render();
48+
})();

0 commit comments

Comments
 (0)