Compare commits

...
2 Commits
Author SHA1 Message Date
marc b46b699576 Schublade in der HoneyBar: Kacheln trugen das Polster der Listenpunkte
.menu a ist spezifischer als .d-app — die Kacheln bekamen dadurch
padding 6px 8px und text-align left statt ihrer eigenen Werte. Das faellt
in der HoneyBar auf, nicht auf dem Schreibtisch: dort steht die
Schublade in .startmenu und wird spezifisch genug angesprochen.
Reihenfolge half nicht, nur Spezifitaet.

Dazu ein Waechter: Ein Backtick in einem Kommentar von honeybar.js
beendet die Vorlagenzeichenkette mitten im CSS und zerlegt die Datei —
zweimal passiert, jetzt bricht der Test.
2026-08-29 23:58:07 +02:00
marc c070f301bb 1.3b als gebaut markiert 2026-08-29 23:50:32 +02:00
3 changed files with 64 additions and 14 deletions

No files matched your search

+2 -2
View File
@@ -92,7 +92,7 @@ Kacheln und beantwortet genau die Frage, die ein generisches Symbol offenlässt.
Hochladen (siehe „Eigene App-Logos" in Teil 2). Sie hängen an derselben Ablage Hochladen (siehe „Eigene App-Logos" in Teil 2). Sie hängen an derselben Ablage
wie das Bild-Widget und gehören deshalb dorthin, nicht mehr ins Fundament. wie das Bild-Widget und gehören deshalb dorthin, nicht mehr ins Fundament.
### 1.3b Reihenfolge der Apps — geplant (29.08.2026) ### 1.3b Reihenfolge der Apps — ✅ gebaut (29.08.2026)
Heute stehen die Apps so, wie sie eingetragen wurden. Ab vier, fünf Stück ist Heute stehen die Apps so, wie sie eingetragen wurden. Ab vier, fünf Stück ist
das eine Frage — in der HoneyBar zuerst, weil dort der Platz am knappsten ist das eine Frage — in der HoneyBar zuerst, weil dort der Platz am knappsten ist
@@ -127,7 +127,7 @@ Sortieren dieselbe Frage aufgeworfen: mitwandern oder stehenbleiben? Beides
falsch. Neue Apps hängen sich jetzt einfach hinten an, die Reihenfolge macht man falsch. Neue Apps hängen sich jetzt einfach hinten an, die Reihenfolge macht man
mit den Pfeilen. mit den Pfeilen.
Beim Bauen zu beachten: Beim Bauen aufgetreten:
- Der Klick auf einen Pfeil sitzt in einem `<summary>` — ohne `preventDefault` - Der Klick auf einen Pfeil sitzt in einem `<summary>` — ohne `preventDefault`
klappt jeder Sortierklick die Zeile auf. klappt jeder Sortierklick die Zeile auf.
+20 -12
View File
@@ -188,6 +188,12 @@
color: var(--p); text-shadow: var(--glow); color: var(--p); text-shadow: var(--glow);
} }
.menu[data-open="1"] { display: flex; } .menu[data-open="1"] { display: flex; }
/* Die Listenpunkte des Systemmenues. Sie stehen VOR der Schublade:
Die Regel "menu a" ist spezifischer als die Klasse der Kachel, und
danach gewaehlt haetten die Kacheln Polster und Ausrichtung der Liste
geerbt statt ihrer eigenen. Genau das war passiert. */
.menu a, .menu button { text-align: left; padding: 6px 8px; color: var(--p-mid); }
.menu a:hover, .menu button:hover { background: var(--p-faint); color: var(--p); }
/* Die Schublade: Symbol, Name, Untertitel. Sie wird absichtlich /* Die Schublade: Symbol, Name, Untertitel. Sie wird absichtlich
aufgemacht, weil man etwas sucht — also wird gelesen, nicht nur aufgemacht, weil man etwas sucht — also wird gelesen, nicht nur
wiedererkannt. Deshalb stehen hier immer Namen, anders als im wiedererkannt. Deshalb stehen hier immer Namen, anders als im
@@ -196,7 +202,11 @@
/* minmax(0, 1fr): Ohne das darf eine lange Beschreibung ihre Spalte /* minmax(0, 1fr): Ohne das darf eine lange Beschreibung ihre Spalte
auseinanderdruecken, und die Schublade wird breiter als der Schirm. */ auseinanderdruecken, und die Schublade wird breiter als der Schirm. */
.drawer { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; } .drawer { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 2px; }
.d-app { /* .menu .d-app, nicht .d-app: Die Kachel ist ein <a> im Menue, und
"menu a" oben ist spezifischer als eine einzelne Klasse — die
Kacheln trugen dadurch Polster und Ausrichtung der Listenpunkte.
Reihenfolge hilft dagegen nicht, nur Spezifitaet. */
.menu .d-app {
display: flex; flex-direction: column; align-items: center; gap: 5px; display: flex; flex-direction: column; align-items: center; gap: 5px;
padding: 9px 4px; text-align: center; color: var(--p-mid); padding: 9px 4px; text-align: center; color: var(--p-mid);
border: 1px solid transparent; min-width: 0; border: 1px solid transparent; min-width: 0;
@@ -204,23 +214,21 @@
/* Die Regel fuer a und button oben setzt nowrap — richtig fuer den /* Die Regel fuer a und button oben setzt nowrap — richtig fuer den
Streifen, falsch Streifen, falsch
hier: Der Untertitel soll umbrechen statt abgeschnitten zu werden. */ hier: Der Untertitel soll umbrechen statt abgeschnitten zu werden. */
.d-name, .d-sub { max-width: 100%; } .menu .d-name, .menu .d-sub { max-width: 100%; }
.d-sub { white-space: normal; } .menu .d-sub { white-space: normal; }
.d-name { overflow: hidden; text-overflow: ellipsis; } .menu .d-name { overflow: hidden; text-overflow: ellipsis; }
.d-app:hover { border-color: var(--p-dim); color: var(--p); } .menu .d-app:hover { background: none; border-color: var(--p-dim); color: var(--p); }
.d-app[aria-current="page"] { border-color: var(--p); color: var(--p); } .menu .d-app[aria-current="page"] { border-color: var(--p); color: var(--p); }
.d-app .ico { width: 24px; height: 24px; } .menu .d-app .ico { width: 24px; height: 24px; }
.d-app .ico svg { width: 24px; height: 24px; } .menu .d-app .ico svg { width: 24px; height: 24px; }
.d-name { letter-spacing: .08em; } .menu .d-name { letter-spacing: .08em; }
/* Der Untertitel darf umbrechen, aber nicht wachsen — sonst stehen die /* Der Untertitel darf umbrechen, aber nicht wachsen — sonst stehen die
Kacheln unterschiedlich hoch. */ Kacheln unterschiedlich hoch. */
.d-sub { .menu .d-sub {
font-size: 10px; line-height: 1.25; color: var(--p-dim); font-size: 10px; line-height: 1.25; color: var(--p-dim);
display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
} }
.menu a, .menu button { text-align: left; padding: 6px 8px; color: var(--p-mid); }
.menu a:hover, .menu button:hover { background: var(--p-faint); color: var(--p); }
.menu hr { border: 0; border-top: 1px solid var(--p-faint); margin: 3px 0; } .menu hr { border: 0; border-top: 1px solid var(--p-faint); margin: 3px 0; }
.menu .head { .menu .head {
padding: 4px 8px; font-size: 10px; letter-spacing: .18em; padding: 4px 8px; font-size: 10px; letter-spacing: .18em;
+42
View File
@@ -4,6 +4,8 @@ import (
"encoding/json" "encoding/json"
"net/http" "net/http"
"net/http/httptest" "net/http/httptest"
"os"
"strings"
"testing" "testing"
"honeyos/internal/store" "honeyos/internal/store"
@@ -43,3 +45,43 @@ func TestMitOrtKommtDasWetter(t *testing.T) {
t.Fatalf("falsches Wetter: %+v", w) t.Fatalf("falsches Wetter: %+v", w)
} }
} }
// Die HoneyBar bringt ihr CSS und ihr Markup in Vorlagenzeichenketten mit.
// Ein Backtick in einem Kommentar beendet die Zeichenkette mittendrin — die
// Datei ist dann kaputt, und zwar nur in der HoneyBar, nicht auf dem
// Schreibtisch. Genau das ist zweimal passiert; deshalb dieser Wächter.
func TestHoneyBarOhneBacktickInKommentaren(t *testing.T) {
b, err := os.ReadFile("web/honeybar/honeybar.js")
if err != nil {
t.Fatal(err)
}
src := string(b)
imBlock := false
for nr, zeile := range strings.Split(src, "\n") {
rest := zeile
for {
if imBlock {
ende := strings.Index(rest, "*/")
if ende < 0 {
if strings.Contains(rest, "`") {
t.Errorf("Zeile %d: Backtick in einem Kommentar — das beendet die Vorlagenzeichenkette:\n %s", nr+1, strings.TrimSpace(zeile))
}
break
}
if strings.Contains(rest[:ende], "`") {
t.Errorf("Zeile %d: Backtick in einem Kommentar — das beendet die Vorlagenzeichenkette:\n %s", nr+1, strings.TrimSpace(zeile))
}
rest = rest[ende+2:]
imBlock = false
continue
}
start := strings.Index(rest, "/*")
if start < 0 {
break
}
rest = rest[start+2:]
imBlock = true
}
}
}