* refactor(themes): remove the Carrot and Hollyberry themes
Both were near-copies of the classic stylesheet kept as examples; the 1.3.0 upgrade prunes their directories and moves anyone who selected them to Modern instead of the alphabetical fallback.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs(changelog): add fragment for #8526
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover retired theme cleanup and handle deleted coverage files
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(a11y): [develop] correct labels, document semantics and duplicate IDs
Associates form controls with their labels, replaces obsolete tt markup, removes duplicate element IDs, and adds a native accessibility browser suite with its database fixture.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(a11y): validate label IDs and recognize attribute escaping
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Preserve package and inline JavaScript coverage safeguards. Retain SpikeKill last-value repair with boundary and zero samples, and the updated PHP action pin. Apply required formatting to incoming test fixtures.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Commit 8471 bumped dompurify from 3.4.16 to 3.4.17 in package.json but left
the JavaScript contract test and the vendored include/js/purify.js at 3.4.16,
breaking the "JavaScript contracts" CI job on develop (test "DOMPurify is
pinned and generated from the matching npm release").
- Update tests/js/sync_js.test.mjs to expect dompurify 3.4.17 in both the
package.json pin assertion and the purify.js license-header match.
- Regenerate include/js/purify.js and include/js/purify.js.map from the
dompurify 3.4.17 npm release via build/sync-js.mjs (npm install postinstall).
All 78 JavaScript contract tests pass locally.
Co-authored-by: TheWitness <copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(themes): skin jQuery multiselect in Deepness and the 3.x markup in four themes
Deepness: main.css repainted select2 onto its --dp-* palette but never
the jQuery multiselect button or popup menu, so those fell through to the
jquery-ui.css textured surfaces and the generic uppercase button rule and
looked like the Dark theme. Repaint them to match the select2 controls.
Cacti, Carrot, Hollyberry, Raspberry: these themes ship the old 1.x
jquery.multiselect.css while include/js/jquery.multiselect.js is 3.x, so
optgroup menus showed list bullets, a nested indent, compounded 0.9em
option text and an unstyled group label. Add the missing 3.x rules.
All changes extend each theme's main.css; the stock
jquery.multiselect.css files are left untouched.
Reported in Cacti/plugin_flowview#298.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix(themes): satisfy the develop CHANGELOG and theme coverage gates
- Move the CHANGELOG entries into changelog.d/8443.issue, as develop
expects fragments rather than direct CHANGELOG edits.
- Drop the Deepness multiselect border-radius; .ui-corner-all forces
border-radius with !important in this theme, so it never applied.
- Add Chromium computed-style tests for the new multiselect rules in
Deepness, Cacti, Carrot, Hollyberry and Raspberry so the changed CSS
lines are exercised by the theme correctness suite.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: TheWitness <copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: Update the deepness favicon
(cherry picked from commit 3a59295162)
* QA: If the SVG is present, it's all we need.
(cherry picked from commit ee0b4c84ed)
* fix: Update such that the modern svg favicon can render
.cactiConsoleContentArea scrolls vertically, and with no right padding the
scrollbar sat flush against the right-aligned cells (for example the Data
Source Info values on data_sources.php), hiding the last digits. Give it a
15px right gutter in every legacy theme (cacti, carrot, dark, deepness,
hollyberry, modern, paper-plane, paw, raspberry, sunrise). midwinter already
reserves a scrollbar gutter and is unchanged.
Cover each changed rule with a develop-theme-correctness targeted test.
The page_filter_format setting is meant to be either/or: Modern shows the
Layouts selector with its Edit dialog, Legacy shows the classic inline
filter. Legacy also rendered the Layouts selector row (and its JavaScript),
so the new and the classic filters appeared together.
Stop rendering the Layouts selector in Legacy mode: create_filter() no
longer appends create_layouts(), and create_javascript() only emits the
layouts script in modern mode. The now-unused create_layouts() and
create_layouts_javascript() helpers are removed, and the setting help text
is updated to say the Layouts selector is available in Modern only.
* Add one-click RRDfile repair to Data Source Info mode
The Data Source Info mode already compares the RRDfile against the Cacti
definition and prints the rrdtool tune recommendations (add a missing Data
Source with DS:name:type:heartbeat:min:max, remove an extra one with DEL:name,
and correct the type, heartbeat, minimum and maximum). It did not, however,
offer a way to apply them from the page the way data_debug.php does.
- Add an "Apply Suggested Fixes" link to the "RRDtool Tune Info" box header when
the web server can write the RRDfile; when it cannot, the header falls back to
"Run Fix from Command Line" and the commands remain listed for manual use.
- Add a ds_repair action that runs the same tune recommendations server-side
(gated on data_source_authorized() and on the RRDfile being writable, and
skipping any recommendation carrying control characters), logs each command to
DSDEBUG, then reloads the Data Source so the result is visible. This mirrors
data_debug.php's run_repair / "Apply Suggested Fixes".
- Harden the Info-mode guard so a missing/unreadable RRDfile (rrdtool info
returning false) no longer triggers an array-offset warning.
* Address review: POST-guard ds_repair and harden repair result check
- Route the "Apply Suggested Fixes" action through a CSRF-protected POST: the
link now uses the cactiPostAction handler (href="#", data-url) instead of a
GET navigation, and ds_repair is added to the $bad_actions guard in
include/global.php so a tokenless request fails closed with 405. ds_repair is
added to the curated CSRF action test for regression coverage.
- Use a strict comparison on the rrdtool_execute() result: it can return null
on a failed exec/proxy connection, and null == '' would have reported a failed
repair as "All RRDfile repairs succeeded."
- Refresh the sink inventory baseline for the new header redirects in ds_repair.
* Add request-coverage probe for the ds_repair RRDfile repair handler
The Data Source Info mode repair handler ds_repair() is a POST action that the
page-level e2e suites do not drive (it needs a Data Source whose RRDfile
mismatches its Cacti definition). Add a request-coverage fixture that loads the
handler in isolation via cacti_fixture_source_function(), stubs its I/O
boundaries, and drives every branch (unauthorized, unreadable RRDfile, no RRA,
nothing to tune, not writable, a control-character recommendation that is
skipped, and both tune success and failure). Register it in
run_request_coverage.sh for data_sources.php changes so the changed-line
coverage gate sees the handler exercised.
* Address review: use defined helpers and boolean repair result
- Replace the undefined cacti_has_control_chars() check with a comparison
against rrd_strip_control_chars() (loaded from lib/rrd.php) to skip any
tune recommendation that carries control characters.
- Execute each tune with RRDTOOL_OUTPUT_BOOLEAN and treat a strict true as
success so proxy storage (which returns the raw 'OK u:...' status under
RRDTOOL_OUTPUT_RETURN_STDERR) is not misreported as a failure.
- Add the new translatable strings to locales/po/cacti.pot and reuse the
existing failure msgid.
- Update the request-coverage fixture to the new boundary contract.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* deepness: make search-result highlight readable and on-theme
The .filteredValue search highlight set a neon yellow (#F8D93D) background
with no text color, so the emerald link text (--dp-link) rendered on bright
yellow was effectively unreadable and clashed with the dark emerald theme.
Use a warm gold background that complements the emerald palette and a
near-black (--dp-page) text color for high-contrast, readable matches.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* tests: cover deepness .filteredValue highlight computed styles
Assert the deepness search-highlight background and text colors in the
theme-correctness suite so the changed .filteredValue CSS lines are
exercised and meet the changed-CSS coverage gate.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The install, enable, remote enable, load and dialog-confirmed actions on
plugins.php are guarded by csrf_require_post() on the server. The anchors
were still activated by the generic GET anchor handler, so clicking them
returned a 405 on the develop branch. Submit these actions over POST:
- The dialog Continue button and the Check Latest control now post.
- A capture-phase document click listener intercepts the install, enable,
remote enable and load icons before the bubble-phase generic handler, so
they post, keep working after Ajax table refreshes, and bind only once.
Tabler (i.ti) icons rendered smaller than the FontAwesome glyphs used on
the 1.2.x branch, so give them an explicit 16px rule matching the fa
layout in each bundled theme, and cover the new rule with
develop-theme-correctness targeted tests.
* fix(themes): correct CSS cascade, font fallbacks and responsive selectors
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(themes): remove validated empty and redundant CSS rules
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style(css): remove reviewed inactive rules and redundant separators
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style(themes): consolidate two reviewed duplicate selectors
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(themes): remove identical whitespace declaration after consolidation
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(theme): keep context menu fallbacks in Cacti overrides
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(theme): measure native CSS and header coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: retain bootstrap coverage and validate request dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: cover Midwinter and graph heading CSS repairs in Chromium
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: take the theme coverage base from the merge commit parent
- github.event.pull_request.base.sha can predate the develop tip the checkout was merged onto, which counted develop's own CSS lines as the PR's.
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(graphs): reveal graph content area after tree branch loads
The jstree select_node handler hides .cactiGraphContentArea (#navigation_right) before loading a branch's graphs via AJAX to avoid flashing the previous branch, but the only re-show was coupled to a window resize event that does not fire after the AJAX load. On themes that hide .cactiGraphContentArea by default (e.g. Deepness) the content area stayed display:none and the graphs/filters were invisible. Re-show it on loadUrl completion.
* fix(filter): keep the Edit Filter dialog columns from collapsing
The modern filter Edit dialog is created with jQuery UI width:'auto'. Its body is a table-based label/field grid, which jQuery UI measures at min-content, collapsing the dialog content to a sliver and pushing the fields off to the right. Floor the content min-width so the columns lay out. Validated in Deepness and Dark.
* fix(graphs): centre single-column graphs in the graph view
graphWrapperOuter > div:first-child is width:fit-content inside a (full-width for one column) flex wrapper, so the graph rendered flush-left. Add auto horizontal margins so it centres; the absolutely-positioned drilldown toggle continues to track the graph.
* fix(graphs): don't re-show content area on aborted branch load
A superseding tree branch click aborts the in-flight loadUrl; its .always() must not re-show the content area the new selection just hid, or stale graphs flash while the new branch loads. Skip completions whose textStatus is 'abort'.
* feat: expose RRDtool 1.11 graph axis controls
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: constrain axis template inheritance checkboxes
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(rrd): exercise native aggregate validation and enforce coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: share changed-code coverage contracts and enforce shell policy
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(ci): run request coverage with portable path matching
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: retain bootstrap coverage and validate request dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: synchronize native coverage fixture dispatch
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: measure coverage at the exact PR revision
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Label the open graph drilldown strip (layout.js labelGraphDrilldownIcons), shorten the action titles, and restyle the strip as a table menu. Each theme's main.css declares the --cacti-dd-* custom properties (foreground, hamburger/panel backgrounds, hairline border, hover accent) that include/css/graph_drilldown.css consumes via var() with a dark fallback, so each theme gets an appropriate light or dark look with its own accent and the hamburger reads correctly on light themes. Themes without a block (e.g. midwinter) use the dark fallback. Regenerates the affected locales/po/cacti.pot entries for the shortened titles.
Co-authored-by: TheWitness <1439914+TheWitness@users.noreply.github.com>
* security: require CSRF-protected POST for link and plugin reordering (#7454)
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(csrf): share POST and token guards for reorder actions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(auth): preserve SAML POST callback sessions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(auth): filter SAML inputs before bootstrap
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(csrf): require POST for administrative mutation endpoints
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(csrf): support token-checking mutation helper
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(theme): enable graph opacity without selectmenu
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs(changelog): describe theme fix
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(graph): restore redraw URLs and retry realtime failures
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(theme): restore Midwinter navigation and kiosk controls
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs(changelog): describe theme fix
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(navigation): preserve filters and restore search and keyboard controls
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(theme): preserve Midwinter authentication controls
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs(changelog): describe theme fix
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(ui): preserve form state and notification lifecycles
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix: replace the blinking timer during skin setup
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Graph drilldown: keep hamburger fixed, icons reachable, hide on graph leave
The action-icon strip now slides down below the hamburger (flex column) instead
of the hamburger dropping to the bottom of the icons. Closing is driven by
leaving the whole graph rather than the small icon strip, so the mouse can move
from the hamburger onto the icons without the strip closing. Leaving the graph
also blurs the hamburger so it no longer lingers after interacting with it.
* changelog: graph drilldown interaction fixes (#8315)
* Graph drilldown: tolerate tooltip-induced mouseleave, drop hamburger title
A native tooltip appearing over a drilldown icon fires a spurious mouseleave on
the graph (relatedTarget null), which closed the strip. Defer the close and
re-check the graph is genuinely not hovered first, so the icon tooltips no longer
destabilize it. Also drop the hamburger's redundant title (its aria-label stays).
* Graph drilldown: widen the close grace period to 500ms
* Graph drilldown: tie hamburger visibility to the graph image
Reveal the hamburger while the pointer is over the graph image (or the toggle
overlaid on it) rather than anywhere in the graph cell, so moving off the image
hides it after the grace period. Entering a different graph now immediately
hides and closes any other graph's open strip.
* Graph drilldown: lift the open graph so its strip clears thumbnails below
With thumbnails a short graph's open icon strip overflows onto the graph below;
sibling graphs paint in DOM order, so that graph rendered on top of the strip,
making the icons unclickable and stealing the hover (which closed the strip).
Raise the open graph (.graphDrillActive, position:relative; z-index) so its
overflowing strip stays on top and the graph beneath is not hovered.
* Graph drilldown: reveal via :focus-visible and stop blurring to preserve keyboard focus
* fix(ui): preserve graph action focus during pointer navigation
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(ui): cover graph drilldown interactions and gate PR coverage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: measure committed PR changes on a policy-compliant runner
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Thomas Vincent <thomasvincent@gmail.com>
* Filter dialog: theme-aware close glyph, titlebar height matches tableHeader, Deepness input theming
- Replace the non-theme-aware inverted sprite close icon with a theme-coloured x glyph (color: inherit) across all 10 themes that style cactiFilterDialog.
- Set the titlebar height/line-height to match each theme's cactiTableTitleRow height instead of 10px padding that made the dialog header taller than table headers.
- Deepness: re-apply theme field colours to dialog inputs/selects/textareas with higher specificity so jQuery UI .ui-widget-content .ui-state-default no longer overrides them.
* changelog: filter dialog theme consistency (#8312)
* Filter dialog: theme select focus border; raspberry titlebar 28px to match table header box
* test(ui): cover filter dialogs across all changed themes
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: measure committed PR changes on a policy-compliant runner
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: Thomas Vincent <thomasvincent@gmail.com>
* security: harden browser history and dependency option merging
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* docs: record CodeQL triage decisions and follow-up scope
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: wait for history reload before inspecting browser storage
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* security: isolate HTMX history from the legacy navigation handler
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* ci: build CodeQL assets through controlled dependency installs
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* security: render form validation messages as plain text
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: verify drag rows and color input security boundaries
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: verify tree navigation rename and datetime input boundaries
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* security: harden menu rendering and complete CodeQL caller review
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* security: centralize menu rendering and stabilize certificate CI
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test: align certificate expectation with parallel web PR
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
Co-authored-by: TheWitness <thewitness@cacti.net>
* fix(core): correct client state and declare public method contracts
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(security): isolate Midwinter external homepage popup
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(client): isolate menu state and simplify validated JavaScript guards
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(auth): use certificate expiry truth in rendering assertions
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* refactor(js): remove unused local storage while retaining initializer calls
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(js): encode inline translated values through the shared JSON boundary
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* style(js): wrap encoded translation literals without changing messages
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* fix(client): remove unused checkbox reads from graph resizing
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* refactor(client): declare repeated function locals once
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* test(ui): run column width regression in browser CI
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
---------
Signed-off-by: Thomas Vincent <thomasvincent@gmail.com>
* Persist table column widths across request actions
Column widths are stored in localStorage keyed by the table id, but
html_start_box() derives that id from the request action/report/tab, so a
filter refresh (action change/go) reloads the same table under a different
id and the saved widths are not restored. Emit a stable, action-independent
data-colsizing key on each cactiTable and use it in saveTableWidths(), while
keeping the DOM id unchanged.
* changelog: 8309 table column width persistence
* Column width persist: keep per-view key, normalize only filter-refresh actions
The previous key dropped the action/report/tab entirely, so distinct table schemas at the same page+ordinal (e.g. support.php processes vs background tabs, utilities.php view_snmp_cache vs view_poller_cache) collapsed into one localStorage entry and applied widths from the wrong schema.
Retain the stable logical-view discriminator (tab/report, or a non-transient action) in the data-colsizing key and normalize only the transient filter-refresh actions (go/change/clear/reset), so widths still survive a filter change but never cross unrelated schemas.
* Use short array syntax for the colsizing normalization list (php-cs-fixer)
* Graph drilldown: common hamburger toggle across all themes
The graph action icons were revealed by hovering to the right of the graph, implemented per-theme (dark/midwinter/sunrise main.js) and always-on elsewhere.
Hide the icons by default behind a small fa-bars hamburger overlaid on the graph's top-right. Clicking it opens the icon strip, which stays until a second click, leaving the strip, or an outside click. The behaviour is now centralized in include/layout.js (initGraphDrilldown) and include/css/graph_drilldown.css, and the per-theme hover JS is removed.
* changelog: 8308 feature fragment
* Graph drilldown: address review (a11y, positioning, spikekill, POT)
- Anchor the toggle to the shrink-wrapped graph holder (width:fit-content) so the hamburger sits on the graph's top-right, not the full-width column edge.
- Keep the hamburger focusable while visually hidden (opacity instead of display:none); reveal on hover, keyboard focus, open, and hover-less devices.
- Expose aria-expanded on the toggle and update it in every open/close path; add aria-haspopup/aria-label.
- Close any open SpikeKill submenu (spikeKillClose) when the strip closes or switches, matching the removed per-theme handlers.
- Remove the now-duplicate Midwinter top-right ellipsis pseudo-element.
- Add the new 'Graph Actions' msgid to locales/po/cacti.pot.
* Harmonize DateTimePicker styling with each theme palette
The jQuery UI datepicker and timepicker addon rendered with the stock ThemeRoller texture-image backgrounds and a generic gray/green look that did not match any theme (most visible in the deepness dark theme). Add per-theme, picker-scoped overrides to every theme's jquery.timepicker.css so the popup surface, header, weekday labels, day cells, selected/hover/today states, Now/Done buttons, and the time sliders use each theme's own accent and content colors. Rules are scoped to .ui-datepicker so other jQuery UI widgets are unaffected.
* Address DateTimePicker a11y review (develop)
- Reset the nav-icon filter on prev/next hover (cacti, paw, raspberry) so the dark jQuery UI sprite stays visible on the pale hover tint.
- Give carrot and hollyberry a dark header title + dark nav icons so the month/year text clears AA on the light-ish accent header.
- Carrot: move to the theme's darker orange (#d2691e) for the today outline and sliders, and use a dark foreground on the orange selected-day/button fills.
- cacti and hollyberry: dark foreground on the accent selected-day/button fills to clear 4.5:1.
- paper-plane and sunrise: invert the icon sprite to white so the arrows are visible on their dark headers.
- dark and modern: add an explicit focus outline on the time-slider handles (both themes suppress the browser outline globally).
- midwinter: rebuild the override on the theme palette variables so the picker follows dark/light mode, with the theme blue as a fixed AA accent.
* Add a jQuery rebind() helper and roll it out across the core UI
Add $.fn.rebind(events[, selector], handler...) to include/layout.js as a
shorthand for the common off(events).on(events, ...) re-attach idiom, then
convert the matching chained calls across the core JavaScript and inline
PHP handlers to use it. Only pairs whose off() and on() events (and
delegated selector) match are converted; off() with no arguments is left
as-is since it intentionally clears every handler.
* changelog: add 8279.feature fragment
* tests: update layout.js JS tests for the rebind() helper
* tests: assert the cactiPostAction handler via rebind()
* rebind: preserve the delegated selector for the two-argument event-map overload; add helper tests
* themes(deepness): harmonize all greens to the emerald palette
* docs: changelog.d/8234.issue (deepness green harmonization)
* themes(deepness): distinct active-state green + sync themeroller url
Address review: give .ui-state-active a darker emerald (#083f2e) so persistent selection stays distinct from the #0c5f44 hover/focus state, and update the themeroller URL's hover/active colors and textures (flat) to match the de-olived declarations.
* themes: use a clean green for .deviceUp instead of muddy olive
The device-status/good-message color .deviceUp was rgba(148,179,107,0.8), a desaturated olive that reads as a muddy warm tone (easily confused with warning/bad) - most visibly on the jQuery UI message dialog, where core wraps MESSAGE_LEVEL_INFO text in <span class=deviceUp>. Align these themes with the clean green rgba(40,180,40) already used by the deepness, modern and paw themes. Applies to device-status text everywhere the class is used.
* changelog: add fragment for .deviceUp green recolor (#8231)
* themes: unify login page styling across all core themes
Flatten the dark themes' login page/card gradients (dark, paper-plane) to flat surfaces, give every theme a clean bordered login card, and add a browser -webkit-autofill override per theme so saved credentials keep the theme's input colors instead of the browser's olive tint. Re-point the Deepness and MidWinter themes' login styling from the legacy .login*/.cactiLogin* classes to develop's .cactiAuth* markup (including .cactiAuthLeft, which auth_login.php targets) so their login pages render correctly. Light themes keep their signature login backdrops.
* changelog: add fragment for login page theme unification (#8230)
* deepness: deep-dark login background with a bordered, slightly-greyer login box
Drop the emerald loginBody gradient for a flat deep-dark page (var(--dp-page)), give the login box a flat slightly-greyer tint (var(--dp-panel-alt)) with a thin var(--dp-border) border, and override -webkit-autofill so the username/password fields no longer show the olive autofill tint.
* docs: add CHANGELOG entry for #8224 (Deepness login restyle)
* deepness: use input surface for login autofill override
The -webkit-autofill inset box-shadow used var(--dp-panel-alt) (the login card surface) instead of var(--dp-panel) used by the standard text/password inputs. Autofilled credentials therefore took on the card color rather than the normal input appearance. Use var(--dp-panel) so the override only removes Chrome's autofill tint.
* dark theme: add theme-appropriate host status pills
Port the translucent host status pills (.deviceStatus) to develop's Dark theme with colors anchored to the theme's olive/sage palette: Up olive rgba(148,179,107)/rgba(167,217,134), Down muted brick red, Recovering theme orange #ff8f1e, Error theme purple #750F7D, Unknown theme blue #0072B5, Disabled theme grey #a1a1a1. The deviceStatus hook already ships in get_colored_device_status() on develop.
* changelog: 8223.feature dark theme host status pills
* dark: opaque dark backing for status pills on selected/hover rows
On tr.selected (opaque light-olive gradient) and tr.selectable:hover the translucent .deviceStatus pills let the bright row show through, dropping the light !important status text below WCAG contrast. Back the pills with the theme base (#161616) in those states; per-state border/text colors still convey status.
---------
Co-authored-by: TheWitness <larry@thewitness.org>
* deepness: match modern console icon sizing/alignment and drop sub-menu indent
Port modern's .menu_glyph size/alignment (18px, 22px width, padding-right:0, inline-block), add line-height:20px to .menuitem span, bump legacy i.fa to 15px with text-align:left, and remove the 32px sub-menu indent (#nav li ul li a now flush at 5px like the top-level items).
* docs: add CHANGELOG entry for #8221 (Deepness console icon alignment)
* issue: skin the modern filter Edit dialog for the Deepness theme
The Deepness theme received the modern filter *bar* rules (#8219) but not
the .ui-dialog.cactiFilterDialog skin the other themes carry, so the filter
Edit dialog fell back to the default jQuery UI themeroller look (mismatched
titlebar gradient, unstyled buttonpane). Port the scoped dialog block used
by the other themes, using Deepness's emerald palette variables
(--dp-accent-deep titlebar/primary button, --dp-border buttonpane divider).
* issue#8220: reference PR number in CHANGELOG entry to satisfy the format gate
* issue: fix Deepness theme modern filter bar stacking vertically
The Deepness theme (added in #8206) shipped include/themes/deepness/main.css without the modern filter-bar display rules the other themes carry, so .filterColumn/.filterColumnButton divs fell back to display:block and the Layouts/Search/Rows controls and action buttons stacked vertically. Port the .filterRow/.filterColumn/.filterColumnButton table-display rules and the .cactiFilterModernBar rules from the modern theme.
* docs: add CHANGELOG entry for #8219 (Deepness filter bar fix)
* issue#8219: port icon-rotate and barSep modern-bar rules to Deepness
html_filter.php adds icon-rotate to the Refresh glyph and emits empty barSep separator spans. Deepness lacked both rules, so the refresh action had no spin feedback and the separators were invisible. Add .icon-rotate and .cactiFilterModernBar .barSep (using the dark-theme rgba(128,128,128,0.45) separator colour, matching the dark/carrot/paper-plane themes).
The .menu_parent fa/fas/fab/far/fal icons used var(--dp-accent) (emerald). Switch to var(--dp-text) so the console navigation glyphs stay light in every state.