* fix(ci): pin htmx.org back to 2.0.10 to match vendored asset and SRI
The npm group bump #8085 raised htmx.org to 4.0.0, but the vendored
include/js/htmx.js, the HTMX_2_0_10_SRI integrity constant, and the
htmx.js.version file were not regenerated. CI's 'Build managed JavaScript'
step (build/sync-js.mjs) copies node_modules/htmx.org/dist/htmx.js, so it
shipped 4.0.0 while htmx_script_tag() still emitted the 2.0.10 SRI, failing
tests/Unit/Ui/Html/HtmxTest. Revert htmx.org to the vendored/pinned 2.0.10;
a real htmx 4.x upgrade should be a separate, tested PR.
* fix(htmx): sync version file, tests and docs to vendored 2.0.10
* feat: add select2 for enhanced/searchable dropdowns
Vendors select2 4.1.0 (MIT, https://select2.org) as a new front-end
dependency, following this branch's existing npm-synced-to-include/js
convention:
- package.json: added "select2": "4.1.0" to dependencies (alongside the
other npm-tracked front-end libs, so Dependabot can track it).
- build/sync-js.mjs: added node_modules/select2/dist/js/select2.full.js ->
include/js/select2.js to the asset map (the "full" build bundles its
jquery-mousewheel dependency, so no extra package is needed).
- include/js/select2.js: the synced output (select2.full.js, unminified,
matching this repo's "vendor unminified where possible" convention).
CSS, following the existing per-theme vendor-CSS convention (jquery-ui.css,
jquery.multiselect.css, etc. - none of which are npm-synced either):
- include/themes/<theme>/select2.css: the upstream select2.css (structural/
functional rules), copied unmodified into all 10 themes.
- lib/html.php: wired both the JS and (per-theme) CSS into the page header,
next to the other jQuery UI plugin includes.
- include/themes/<theme>/main.css: since Select2 4.x publishes no jQuery UI
theme/adapter, appended a small override block per theme (widget border/
background/text, hover, and active/highlighted colors) reusing each
theme's own jquery-ui.css/.ui-state-active colors, so Select2 dropdowns
match that theme's native jQuery UI look instead of Select2's generic
default styling.
* feat: initialize select2() widgets in applySkin()
Wires up the select2/select2-nosearch/select2-tags/select2-multi/
select2-multi-tags/select2-callback marker classes so pages can opt in
to a Select2-enhanced dropdown just by adding the class, matching the
existing markup-driven convention used by other jQuery UI widget
setup in this function.
Dialog-hosted selects pass dropdownParent so the dropdown attaches to
the ui-dialog widget instead of escaping under it (a well-known
Select2 + jQuery UI dialog z-index/stacking issue).
* fix: remove accidental theme:'bootstrap' from select2-multi init
* fix: address Copilot review findings on the select2 PR
- package-lock.json: added the select2@4.1.0 entry (registry resolved URL +
integrity hash) so `npm ci` no longer rejects the package.json/lockfile
mismatch.
- .gitignore / include/js/select2.js: select2.js is a generated npm-synced
build output like the other managed libraries, so it belongs in the
generated-asset ignore list, not committed. Untracked the copy that had
been committed; `npm run build:js` regenerates it locally.
- build/README.md: documented select2 among the npm-managed libraries, and
clarified that the per-theme select2.css copies are committed unmodified
upstream CSS (unlike jquery-ui/jstree's Cacti-owned theme CSS).
- include/themes/paper-plane/main.css: highlighted/focused Select2 options
were the same white as the dropdown background, giving no visible focus
indicator; changed to the theme's own hover color (#dadada / #212121).
- include/themes/sunrise/main.css: same issue; changed to this theme's
established menu focus color (#3C8A3C, matching .ui-menu .ui-state-focus)
with white text.
* fix: address 3 material Copilot review findings on select2 init
- Exclude the select2/select2-nosearch/select2-tags/select2-multi/
select2-multi-tags/select2-callback marker classes from
setSelectMenus()'s generic $('select')... loop, so Select2-marked
single-selects are no longer first hidden/wrapped by jQuery UI
Selectmenu before Select2 wraps them again.
- select2-callback: Select2 calls the ajax.url callback with a context
that is not the original <select>, so $(this).data('callback') read
undefined inside it. Capture the element's callback URL into a local
variable before calling .select2() and use that instead.
- select2-callback: it was the only initializer that never checked for a
jQuery UI dialog ancestor, so its dropdown always appended to body and
could be hidden behind a dialog's overlay. Set dropdownParent the same
way the other five initializers do.
* fix: proactively apply 2 material findings from the 1.2.x PR review
Copilot's review of the companion 1.2.x PR (#8052) found 2 bugs in this
same select2-init code that also apply here unchanged:
- Select2 renders its replacement as <span class="select2 select2-container">,
so the plain class selectors (.select2, .select2-nosearch, etc.) also
matched Select2's own generated wrappers on every later applySkin() call
(e.g. during AJAX navigation), re-initializing and nesting wrappers.
Scoped all six selectors to `select.<marker-class>` so only the original
<select> elements are ever matched.
- select2-callback's ajax response was never normalized: Cacti's existing
callback endpoints (e.g. lib/auth.php) return a plain array of
{label, value, id} objects, but Select2 requires {results: [{id, text}]}.
Added a processResults mapping so callback-backed dropdowns actually
populate.
- select2-callback now also sets dropdownParent unconditionally (dialog
ancestor, or document.body otherwise) instead of leaving it unset outside
dialogs.
* chore: manage front-end JavaScript libraries with npm and Dependabot
Move all third-party front-end JavaScript to npm so Dependabot tracks it, and
drop the committed copies in favour of a build. package.json pins jquery,
jquery-ui, jstree (3.3.12 -> 3.3.17), billboard.js, pace-js, tablesorter and
jquery-validation; build/sync-js.mjs copies their dist files into include/js/
and runs on npm install via postinstall.
pace-js carries a one-line local fix (a stray regex alternation that made it
match the empty string) applied through patch-package
(patches/pace-js+1.2.4.patch); the fix should be sent upstream so the patch can
be dropped. Only Cacti's own themed jquery-ui/jstree CSS stays committed.
An npm ecosystem is added to dependabot.yml for develop. The release pipeline
and any workflow that serves Cacti pages must run 'npm ci' (which builds via
postinstall) before use, since the generated files are no longer in the tree.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* hardening: remove vendored development artifacts
* feat(release): attach the built artifact to the release
The workflow already builds an attested, checksummed archive carrying the
Composer dependencies, then discards it after thirty days.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: fail the publish step when the bundle is empty
An unmatched glob would otherwise reach gh as a literal path.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: treat the maintenance lock notice as expected log output
The line records the lock working, so a second maintenance run overlapping
in CI failed unrelated pull requests.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: consolidate release dependency changelog
* ci: build managed JavaScript in release artifacts
* test: cover managed JavaScript build end to end
* deps: complete phpseclib 4 migration
* deps: update patch-package to audited release
* ci: satisfy workflow shell policy
* chore: source DOMPurify from npm and update it to 3.4.14
Add dompurify to the npm-managed set (was committed at 3.4.7) and bump to 3.4.14.
DOMPurify is the client-side XSS sanitizer used on tree labels, device tooltips
and plugin messages; keeping it current with upstream bypass fixes matters more
than for the UI libraries.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: preserve release changelog ordering
* test: preserve DOMPurify source map in npm build
* chore: source htmx, d3, big.js, lzjs and screenfull from npm
Add the remaining unmodified third-party libraries to the npm-managed build:
htmx.org 2.0.6, d3 7.8.2, big.js 6.2.2, lzjs 1.3.1 and screenfull 3.3.3. Each
was verified byte-identical (lzjs differs only in a JSDoc comment) to the copies
being removed. htmx in particular moves from a hand-tracked SHA pin to npm with
lockfile integrity.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover phpseclib 4 integration
* ci: build managed assets before htmx tests
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>