fix: terminal font dont always load#2155
Conversation
Greptile SummaryThis PR fixes intermittent terminal font loading by splitting the process into two phases:
Confidence Score: 5/5Safe to merge; the font loading fix is well-structured and all previously flagged null-guard issues are addressed The core logic change — eager injection followed by local-URI replacement — is correct for all built-in fonts. The only gap is that custom fonts with regex metacharacters in their name would silently skip the local-URI replacement, but this doesn't affect any currently shipped font and the font still loads (just from the remote URL). The cordova.js additions are standard Cordova runtime files and don't introduce logic risk. src/lib/fonts.js — the regex replacement in Important Files Changed
Sequence DiagramsequenceDiagram
participant App as main.js (onDeviceReady)
participant TC as TerminalComponent.init()
participant LTF as loadTerminalFont()
participant Fonts as fonts.js
participant Style as DOM style
participant Browser as document.fonts
App->>Fonts: injectFontFace("MesloLGS NF Regular")
Fonts->>Style: "append @font-face (bundled data URI)"
Fonts->>Browser: document.fonts.load() no-await
Note over TC: Terminal opened
TC->>LTF: loadTerminalFont() async non-blocking
LTF->>Fonts: injectFontFace(fontFamily)
Fonts->>Style: "append @font-face remote URL if not present"
Fonts->>Browser: document.fonts.load() no-await
LTF->>Fonts: await loadFont(fontFamily)
Fonts->>Fonts: download remote font file to local URI
Fonts->>Style: "replace remote @font-face with local-URI version"
Fonts->>Browser: await document.fonts.load()
LTF-->>TC: resolved
TC->>TC: _fontReady.then terminal.options.fontFamily
TC->>TC: terminal.refresh(0, rows-1)
Note over TC: openTerminal() mount()
TC->>TC: rAF 1 fitAddon.fit() terminal.focus()
TC->>TC: rAF 2 safety re-apply fontFamily and refresh
Reviews (2): Last reviewed commit: "fix: replace pre-injected font-face with..." | Re-trigger Greptile |
| function injectFontFace(name) { | ||
| const $style = ensureStyleElement(FONT_FACE_STYLE_ID); | ||
| const css = get(name); | ||
|
|
||
| if (!css) return; | ||
|
|
||
| // Inject CSS if not already present (skip remote URL downloads - loadFont handles those) | ||
| if (!$style.textContent.includes(`font-family: '${name}'`)) { | ||
| $style.textContent = `${$style.textContent}\n${css}`; | ||
| } | ||
|
|
||
| // Kick off browser font loading without blocking | ||
| if (document.fonts?.load) { | ||
| document.fonts.load(`12px '${name}'`).catch(() => {}); | ||
| } | ||
| } |
There was a problem hiding this comment.
Remote fonts bypass local caching when
injectFontFace is called before loadFont
injectFontFace injects the raw @font-face CSS (containing the original https://acode.app/… URL) into the style element. When loadFont is subsequently called in loadTerminalFont() or terminalSettings.js, it downloads the font file to local storage and replaces the remote URL with an internal URI (content://…) — but then the "already present" guard ($style.textContent.includes(...)) is true, so the locally-URI'd CSS is never injected. The browser is left with the remote URL and the locally cached copy is never served.
For locally bundled fonts (like MesloLGS NF Regular) this is harmless, but for any remote font (e.g., JetBrains Mono Regular, Cascadia Code) this breaks offline/cached font loading — a regression from the pre-PR behaviour where only loadFont ran and always replaced the URL before injecting.
Co-authored-by: greptile-apps[bot] <165735046+greptile-apps[bot]@users.noreply.github.com>
…n terminal mount - loadFont now replaces stale @font-face blocks (pre-injected by injectFontFace with remote URLs) with locally-cached URIs, fixing offline loading regression for remote fonts like JetBrains Mono and Cascadia Code - add if (!this.terminal) null guard to mount()'s first rAF and setTimeout callbacks to prevent crashes on early terminal dispose
|
@greptile_apps review again |
No description provided.