D1 Part 3 leftovers: remove 8 residual emoji + Python emoji gate
- The D0 grep gate false-negatived multibyte emoji on Windows (its zero was wrong). scripts/emoji_gate.py scans by Unicode codepoint; it found 8 survivors: backups.html (📁→file-text icon, 🔄 restore-info text), debug.html (🔄→'fut', 🔒→'titkosított'), deploy.html (📦→upload icon, ★ default-marker → '(alapértelmezett)'), storage.html (📦→upload icon, 📦 in the migrate-target option → plain text). All → sprite icons or plain words. - Gates: scripts/emoji_gate.py = 0; new Go TestNoEmojiInTemplates codepoint scan keeps it enforced (allowlist: ✓✗✔✘•●○■▶ monochrome text marks). go build/vet/test ./... green (18 pkgs).
This commit is contained in:
@@ -252,3 +252,41 @@ func TestStorageAgentDownNote(t *testing.T) {
|
||||
t.Error("enrichment JS lacks the warn-note error path")
|
||||
}
|
||||
}
|
||||
|
||||
// TestNoEmojiInTemplates (D1 §10, Group G): no emoji/pictographs in web templates. Go-side
|
||||
// codepoint scan (the D0 grep-based gate false-negatived multibyte emoji on Windows).
|
||||
func TestNoEmojiInTemplates(t *testing.T) {
|
||||
allow := map[rune]bool{}
|
||||
for _, r := range "✓✗✔✘•●○■▶" {
|
||||
allow[r] = true
|
||||
}
|
||||
isEmoji := func(r rune) bool {
|
||||
if allow[r] {
|
||||
return false
|
||||
}
|
||||
switch {
|
||||
case r >= 0x1F300 && r <= 0x1FAFF,
|
||||
r >= 0x2600 && r <= 0x26FF,
|
||||
r >= 0x2700 && r <= 0x27BF,
|
||||
r >= 0xFE00 && r <= 0xFE0F,
|
||||
r >= 0x1F1E6 && r <= 0x1F1FF:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
entries, _ := templateFS.ReadDir("templates")
|
||||
for _, e := range entries {
|
||||
if !strings.HasSuffix(e.Name(), ".html") {
|
||||
continue
|
||||
}
|
||||
b, err := templateFS.ReadFile("templates/" + e.Name())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, r := range string(b) {
|
||||
if isEmoji(r) {
|
||||
t.Errorf("%s contains emoji %q (U+%04X)", e.Name(), r, r)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@
|
||||
{{end}}
|
||||
{{if .Tier2SizeHuman}}<span class="tier-size">{{.Tier2SizeHuman}}</span>{{end}}
|
||||
<span class="tier-contents">{{.BackupContents}}</span>
|
||||
<span class="tier-browsable" title="A mentés böngészhető fájlrendszerben">📁</span>
|
||||
<span class="tier-browsable" title="A mentés böngészhető fájlrendszerben"><svg class="ico ico-sm"><use href="#i-file-text"/></svg></span>
|
||||
<div class="layer-actions">
|
||||
<a href="/stacks/{{.StackName}}/backup" class="btn btn-xs btn-outline">Beállítás</a>
|
||||
</div>
|
||||
@@ -743,7 +743,7 @@ function onRestoreAppChange() {
|
||||
var hasVolumes = opt.getAttribute('data-has-volumes') === 'true';
|
||||
|
||||
if (hasHDD || hasVolumes) {
|
||||
typeInfo.innerHTML = '🔄 Teljes visszaállítás: adatbázis + konfiguráció + felhasználói adatok a kiválasztott pillanatképből.';
|
||||
typeInfo.innerHTML = 'Teljes visszaállítás: adatbázis + konfiguráció + felhasználói adatok a kiválasztott pillanatképből.';
|
||||
typeInfo.className = 'restore-info';
|
||||
} else if (hasDB) {
|
||||
typeInfo.innerHTML = 'Adatbázis és konfiguráció visszaállítása — az alkalmazásnak nincs külön felhasználói adata.';
|
||||
|
||||
@@ -362,7 +362,7 @@ function renderDiagnostic(d) {
|
||||
html += '<h4 style="margin-top:.75rem">Ütemező</h4><table class="info-table debug-table"><tr><th>Név</th><th>Típus</th><th>Utolsó futás</th><th>Fut</th></tr>';
|
||||
d.scheduler.forEach(function(j) {
|
||||
var type = j.type === 'daily' ? j.schedule : (j.interval || '-');
|
||||
html += '<tr><td>' + j.name + '</td><td>' + type + '</td><td>' + (j.last_run ? fmtTime(j.last_run) : '-') + '</td><td>' + (j.running ? '🔄' : '-') + '</td></tr>';
|
||||
html += '<tr><td>' + j.name + '</td><td>' + type + '</td><td>' + (j.last_run ? fmtTime(j.last_run) : '-') + '</td><td>' + (j.running ? 'fut' : '-') + '</td></tr>';
|
||||
});
|
||||
html += '</table>';
|
||||
}
|
||||
@@ -835,7 +835,7 @@ function renderAppBundles(bundles) {
|
||||
html += '<td>' + (b.exported_at || '-') + '</td>';
|
||||
html += '<td>' + (b.size_human || '-') + '</td>';
|
||||
html += '<td>' + escapeHtml(b.drive_label || b.drive_path) + '</td>';
|
||||
html += '<td>' + (b.encrypted ? '🔒' : '-') + '</td>';
|
||||
html += '<td>' + (b.encrypted ? 'titkosított' : '-') + '</td>';
|
||||
html += '<td>' + (b.has_db ? 'igen' : '-') + '</td>';
|
||||
html += '<td>' + (b.needs_hdd ? 'igen' : '-') + '</td>';
|
||||
html += '<td class="mono" style="font-size:.7rem;max-width:200px;overflow:hidden;text-overflow:ellipsis">' + escapeHtml(b.path) + '</td>';
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
</div>
|
||||
{{if .OtherStoragePaths}}
|
||||
<span class="btn btn-sm btn-outline" style="margin-top:.75rem;opacity:.45;cursor:not-allowed" title="Hamarosan">
|
||||
📦 Mozgatás másik tárolóra
|
||||
<svg class="ico ico-sm"><use href="#i-upload"/></svg> Mozgatás másik tárolóra
|
||||
</span>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -565,7 +565,7 @@
|
||||
{{range $.StoragePaths}}
|
||||
<option value="{{.Path}}" data-free-percent="{{printf "%.0f" .FreePercent}}"
|
||||
{{if .IsDefault}}selected{{end}}>
|
||||
{{.Label}} — {{.FreeHuman}} szabad{{if .IsDefault}} ★{{end}}
|
||||
{{.Label}} — {{.FreeHuman}} szabad{{if .IsDefault}} (alapértelmezett){{end}}
|
||||
</option>
|
||||
{{end}}
|
||||
</select>
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
<div class="storage-app-row">
|
||||
<a href="/apps/{{.Stack}}" class="storage-app-link">{{.Name}}</a>
|
||||
{{if .SizeHuman}}<span class="mono form-hint">{{.SizeHuman}}</span>{{end}}
|
||||
<span class="btn btn-xs btn-outline" style="opacity:.45;cursor:not-allowed" title="Hamarosan">📦 Mozgatás</span>
|
||||
<span class="btn btn-xs btn-outline" style="opacity:.45;cursor:not-allowed" title="Hamarosan"><svg class="ico ico-sm"><use href="#i-upload"/></svg> Mozgatás</span>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
@@ -151,7 +151,7 @@
|
||||
{{$src := .Path}}
|
||||
<span class="migrate-inline" style="display:inline-flex;gap:.35rem;align-items:center">
|
||||
<select id="migrate-target-{{.Path}}" class="btn btn-xs btn-outline">
|
||||
<option value="">📦 Áthelyezés ide…</option>
|
||||
<option value="">Áthelyezés ide…</option>
|
||||
{{range $.StoragePaths}}{{if and (ne .Path $src) .Schedulable (not .Disconnected) (not .Decommissioned)}}<option value="{{.Path}}">{{.Label}} ({{.Path}})</option>{{end}}{{end}}
|
||||
</select>
|
||||
<button class="btn btn-xs btn-outline" onclick="storageMigrateAll('{{.Path}}','{{.Label}}')">Összes adat áthelyezése</button>
|
||||
|
||||
Reference in New Issue
Block a user