Skip to content

chore(ui): move to Font Awesome 7, with no v4 shims - #1336

Merged
mastacontrola merged 2 commits into
working-1.6from
chore-fontawesome7
Aug 24, 2026
Merged

chore(ui): move to Font Awesome 7, with no v4 shims#1336
mastacontrola merged 2 commits into
working-1.6from
chore-fontawesome7

Conversation

@mastacontrola

@mastacontrola mastacontrola commented Aug 24, 2026

Copy link
Copy Markdown
Member

FOG shipped Font Awesome 4.7.0 — nine years old. This vendors 7.3.1 and migrates every call site, deliberately without v4-shims.css.

A shim layer is one you can never remove, because nothing ever tells you when its last consumer goes away. Dropping it is only safe if something checks the call sites, so this adds that check instead of the shims.

What the FA4 names actually do under FA7

I initially described all 26 as blank boxes. That was measured wrong — a ::before with content set is not proof of a glyph. Rasterising each against the shipped build and counting non-transparent pixels splits them three ways:

behaviour count which
render nothing 8 check-square-o, circle-o, file-excel-o, hdd-o, money, moon-o, square-o, sun-o — all the FA4 -o outline variants, whose glyphs moved to the regular family without the old names being kept
render the wrong glyph 2 windows, slack — brand codepoints while .fa selects the solid font, so they draw a tofu box
render correctly today 16 refresh, magic, warning, dashboard, globe, … — FA7 kept the old name as an alias

The tell on the tofu pair: both measured ink=1452, identical to each other. Two different icons can't have the same pixel count.

So this is worth less as a bug fix than I first claimed, and more as maintenance: two thirds of these look fine in a browser right now and break whenever FontAwesome drops the aliases. That's exactly the change nobody catches by looking — which is the argument for the test, not against the work.

What changed

68 call sites across core. 26 FA4-only names, 11 FA5-era aliases (fa-times-circlefa-circle-xmark, fa-cogsfa-gears), and 46 canonical names still on the bare fa prefix — .fa resolves to solid in FA7 so those rendered either way, but leaving part of the codebase on the old prefix is the inconsistency this pass exists to remove.

Payload

6 font formats (~500KB) → 3 woff2 (~254KB). Costs IE11 and pre-2014 browsers, already unusable on this Bootstrap 5 UI. The vendored CSS is byte-identical to upstream all.min.css so the next upgrade is a straight file swap; fa-v4compatibility.woff2 ships only because that CSS references it, and an unused @font-face is never fetched.

Menu icons fixed while the names were changing anyway

item was now why
Storagenodes box-archive server an archive box is not a storage node
Roles key user-shield roles are permissions, not credentials
Audit Log shield clipboard-list a shield is protection; a log is a record
iPXE Menu bars list-ol fa-bars is the hamburger glyph
User Groups address-book people-group collided with the LDAP plugin
Sites location-dot building collided with the Location plugin
Modules gears sliders collided with Client Settings

Checking these against fog-plugins found five icons serving two different menu items each. Core and plugins now use 38 distinct icons with none shared — an icon that means two things is the same navigation problem as a wrong one.

Bonus fix: toasts have had no icon since Bootstrap 5

PNotify was left on its bootstrap3 styling, which emits glyphicon classes — dropped in Bootstrap 4. Every notice has been rendering content: none at zero width ever since. Its fontawesome preset is FA4, so switching alone would have traded one blank box for another; the names are overridden at our call site in fog.common.js, not in the vendored pnotify.min.js, because editing that means the next upgrade silently reverts the fix.

Verified on the lab

All three font families load, brands woff2 serves 200, zero blank glyphs across 45 distinct icon classes, every sidebar entry renders, and both toast types now draw a 20px icon.

Tests

tests/fontawesome7-icon-names.test.php — 14 checks, 9 mutants killed: an FA4 name creeping back, a bare fa prefix, a pro-only name (absent from the free build and just as blank), the shims returning, a missing webfont, and the PNotify override being undone.

Downstream

FOG_PLUGINS_VERSION bumped to v1.6.15 in this PR, which is the matching plugin migration (FOGProject/fog-plugins#25, released). Pinned here rather than as a follow-up so no install lands between new core and FA4 plugin icons.

mastacontrola and others added 2 commits August 23, 2026 20:58
FOG shipped Font Awesome 4.7.0, which is nine years old. This vendors 7.3.1 and
migrates every call site, deliberately WITHOUT v4-shims.css: a shim layer is one
you can never remove, because nothing ever tells you when its last consumer goes
away. Dropping it is only safe if something checks the call sites, so this adds
that check rather than the shims.

The failure mode is why this is a scripted pass with a test, not hand edits. An
FA4 name under FA7 is not an error: the element renders, the stylesheet loads,
the console stays clean, and the user gets an empty gap. Nothing 404s and nothing
throws -- the only signal is somebody looking at the page.

68 call sites rewritten across core, in two groups with different risk:

  MUST   26 names FA7 dropped outright (fa-refresh -> fa-arrows-rotate,
         fa-warning -> fa-triangle-exclamation, fa-dashboard -> fa-gauge-high,
         fa-hdd-o -> far fa-hard-drive, ...). Each one is a blank box.
  LEGACY 11 FA5-era aliases FA7 still emits as working classes
         (fa-times-circle -> fa-circle-xmark, fa-cogs -> fa-gears). Renaming
         these is modernisation; nothing depended on it.

The remaining 46 sites were canonical names still on the bare `fa` prefix. `.fa`
resolves to solid in FA7 so they rendered either way, but leaving part of the
codebase on the old prefix is the inconsistency this pass exists to remove.

Payload roughly halves: 6 font formats (~500KB) become 3 woff2 (~254KB), which
costs IE11 and pre-2014 browsers -- already unusable on this Bootstrap 5 UI. The
vendored CSS is byte-identical to upstream all.min.css so the next upgrade is a
straight file swap; fa-v4compatibility.woff2 is shipped only because that CSS
references it, and an unused @font-face is never fetched.

Menu icons that were wrong or ambiguous are fixed while we are here, since the
names were changing anyway:

  Storagenodes  box-archive   -> server            an archive box is not a node
  Roles         key           -> user-shield       roles are permissions
  Audit Log     shield        -> clipboard-list    a shield is protection
  iPXE Menu     bars          -> list-ol           fa-bars is the hamburger
  User Groups   address-book  -> people-group      collided with the LDAP plugin
  Sites         location-dot  -> building          collided with Location plugin
  Modules       gears         -> sliders           collided with Client Settings

Checking those against fog-plugins found five icons serving two different menu
items each; core and plugins now use 38 distinct icons with none shared. An icon
that means two things is the same navigation problem as a wrong one.

Also fixes toasts having had NO icon since the Bootstrap 3 -> 5 move. PNotify was
left on its "bootstrap3" styling, which emits glyphicon classes, and glyphicons
went away in Bootstrap 4 -- every notice has been rendering `content: none` at
zero width ever since. Its "fontawesome" preset is FA4, so switching alone would
have swapped one blank box for another; the names are overridden at our call site
in fog.common.js rather than in the vendored pnotify.min.js, because editing that
means the next upgrade of it silently reverts the fix.

FOG_PLUGINS_VERSION is NOT bumped here. The matching plugin migration is
fog-plugins#25; core pins the release it produces in a follow-up so an install
never lands between new core and FA4 plugin icons.

Verified on the lab: all three font families load, the brands woff2 serves 200,
zero blank glyphs across 45 distinct icon classes, every sidebar entry renders,
and both toast types now draw a 20px icon.

Tests: fontawesome7-icon-names.test.php, 14 checks, 9 mutants killed -- covering
an FA4 name creeping back, a bare `fa` prefix, a pro-only name (absent from the
free build and just as blank), the shims returning, a missing webfont, and the
PNotify override being undone.

Co-Authored-By: Claude <noreply@anthropic.com>
…ames

Core now ships Font Awesome 7 with no v4 shims, so a plugin release still using
FA4 class names renders its menu entries wrongly -- and mostly silently, since
an unknown icon class is not an error. v1.6.15 is the matching plugin migration
(fog-plugins#25).

Pinned in the same PR as the core migration rather than as a follow-up: an
install that picked up new core against the old pin would get exactly that
broken state, and the window would be however long the second PR took to merge.

Also corrects the previous commit's characterisation of the FA4 names, which
was measured wrong. Rasterising each one against the shipped build on the lab
(count the non-transparent pixels, rather than trusting that a ::before with
content is a glyph) splits the 26 three ways:

   8 render NOTHING -- no class in the stylesheet at all. All are the FA4 "-o"
     outline variants, whose glyphs moved to the regular family without the old
     names being kept: check-square-o, circle-o, file-excel-o, hdd-o, money,
     moon-o, square-o, sun-o.
   2 render the WRONG glyph: fa-windows and fa-slack resolve to a codepoint in
     the brands font while `.fa` selects the solid one, so they draw a tofu box.
     Both measured ink=1452, identical to each other, which is what gave it
     away -- two different icons cannot have the same pixel count.
  16 render CORRECTLY today, because FA7 kept the old name as an alias
     (refresh, magic, warning, dashboard, globe, ...).

So the migration is worth less as a bug fix than the previous message claimed
and more as maintenance: two thirds of these look fine in a browser right now
and break whenever FontAwesome drops the aliases. That is precisely the change
nobody would catch by looking, which is the argument for the test rather than
against the work.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant