Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ All historical references to "CFWheels" in this changelog have been preserved fo

- Debug bar Tools → Packages page now lists packages available from the `wheels-dev/wheels-packages` registry in fresh apps generated with `wheels new`. The previous gate (`FileExists("/cli/lucli/services/packages/Registry.cfc")`) silently returned an empty list because user apps don't ship the CLI alongside the framework. The registry reader now lives at `vendor/wheels/services/packages/{Registry,HttpClient,ManifestCache}.cfc` and ships with every generated app. The registry list stays scoped to the standalone Tools → Packages page; the inline debug-bar Environment panel shows installed packages only, so the bar stays compact and doesn't trigger a registry walk on every dev-mode page load. (#2530)
- `Registry.fetchManifest()` now validates that a manifest contains a non-empty `versions` array before returning, throwing `Wheels.Packages.RegistryMalformed` instead of letting a downstream `local.m.versions[ArrayLen(...)]` access crash with an unhandled `Expression` error. The per-package skip-on-malformed catch in `listAll()` now actually catches every malformed shape, so the Tools → Packages page degrades gracefully when the registry serves a partial manifest. Mirrored into the CLI's `cli/lucli/services/packages/Registry.cfc` to keep both copies in sync. (#2530)
- Installed-package indicator on the Tools → Packages page now renders correctly. The badge previously used Semantic UI's icon-font `<i class="check icon">`, which the bundled `semantic.min.css` declares only with `.eot` and `.svg` font sources (no `.woff`/`.woff2`) and is referenced via relative URLs broken by the page's inlined-CSS approach — so the glyph never loaded in modern browsers. Replaced with an inline SVG checkmark, matching the pattern used by every other icon in the same view. (#2423)
- Snapshot pre-releases on `develop` now publish the full artifact set (`wheels-core-*.zip`, `wheels-base-template-*.zip`, `wheels-cli-*.zip`, `wheels-starter-app-*.zip`) alongside `wheels-module-*`. Previously only the module tarball was attached, which broke Homebrew/Chocolatey distributions that depend on fetching `wheels-core-*.zip` as a companion artifact: users scaffolded a new app and hit "Could not locate the Wheels framework source" at chapter 1 of the tutorial. Snapshots now mirror the main-branch release contents exactly, flagged as pre-release.
- `wheels doctor` now detects when the installed CLI module has no companion framework source (vendor/wheels/) on disk — catches broken package distributions before they surface as a cryptic scaffold error. Previously `doctor` would report missing project directories and recommend `wheels new`, but `wheels new` would then fail with "Could not locate the Wheels framework source." The new `checkFrameworkSourceBundled` check walks the same search paths as `Module.cfc`'s `resolveFrameworkSource()` and reports a CRITICAL issue when none resolve, replacing the misleading `wheels new` recommendation with guidance to reinstall or set `WHEELS_FRAMEWORK_PATH`.
- `wheels new` framework-not-found error now links to the real guides page (`/v4-0-0-snapshot/start-here/installing/`) instead of a 404 (`/docs/getting-started`), and mentions Homebrew/Chocolatey packaging explicitly so users can tell the difference between "I'm in the wrong directory" and "my install is incomplete."
Expand Down
2 changes: 1 addition & 1 deletion vendor/wheels/public/views/packagelist.cfm
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ for (local.key in packageMeta) {
<td>#HTMLEditFormat(local.rp.latestVersion)#</td>
<td>
<cfif local.isInstalled>
<span class="ui label"><i class="check icon"></i> Installed</span>
<span class="ui label"><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 512 512" fill="currentColor" style="vertical-align: middle; margin-right: 4px;"><path d="M438.6 105.4c12.5 12.5 12.5 32.8 0 45.3l-256 256c-12.5 12.5-32.8 12.5-45.3 0l-128-128c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L160 338.7 393.4 105.4c12.5-12.5 32.8-12.5 45.3 0z"/></svg>Installed</span>
<cfelse>
<!--- rp.name is registry-schema-constrained to ^[a-z0-9][a-z0-9-]*$, so both id and JS string are already safe.
JSStringFormat() is applied in the onclick defensively in case that invariant ever loosens.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
/**
* Tools > Packages page (#2423): the "Installed" badge on registry rows must
* use an inline SVG checkmark, not Semantic UI's icon font.
*
* The bundled `vendor/wheels/public/assets/css/semantic.min.css` is inlined
* into the page via a script-side include inside a style block in
* `_header.cfm`, which breaks the @font-face `url(themes/default/assets/`
* `fonts/icons.*)` relative paths (they resolve against the page URL, not
* the CSS file location). Additionally the `Icons` font-face declaration
* in that bundle only references `.eot` and `.svg` formats — no `.woff` or
* `.woff2` — so even with working URLs no modern browser can load the
* glyph. Every other icon in the same view uses inline SVG; the Installed
* badge must do the same.
*/
component extends="wheels.WheelsTest" {

function run() {
describe("packagelist.cfm Installed badge (##2423)", () => {

it("does not use Semantic UI's icon font for the Installed badge", () => {
var source = FileRead(ExpandPath("/wheels/public/views/packagelist.cfm"));

expect(FindNoCase("<i class=""check icon"">", source) GT 0).toBeFalse(
"packagelist.cfm must not use <i class=""check icon""></i> for "
& "the Installed badge — the Semantic UI icon font is not "
& "loadable in this view (CSS is inlined, breaking relative "
& "@font-face URLs, and the bundle omits .woff/.woff2 for the "
& "Icons family). Use an inline <svg> checkmark instead."
);
});

it("renders the Installed badge with an inline SVG checkmark", () => {
var source = FileRead(ExpandPath("/wheels/public/views/packagelist.cfm"));

// The Installed badge block: a <span class="ui label"> that
// contains an <svg>...</svg> followed by the word "Installed".
// Tolerate whitespace and arbitrary svg attributes/contents.
var pattern = "<span[^>]*class=""[^""]*ui[^""]*label[^""]*""[^>]*>\s*<svg[\s\S]*?</svg>\s*Installed";

expect(REFindNoCase(pattern, source) GT 0).toBeTrue(
"Expected a <span class=""ui label""> containing an inline "
& "<svg>...</svg> immediately before the text 'Installed'. "
& "See issue ##2423."
);
});

});
}

}
Loading