-
+
-
diff --git a/emhttp/plugins/dynamix/Vars.page b/emhttp/plugins/dynamix/Vars.page
index 55b9d5c21..7fce7fb4f 100644
--- a/emhttp/plugins/dynamix/Vars.page
+++ b/emhttp/plugins/dynamix/Vars.page
@@ -15,23 +15,28 @@ Tag="code"
* all copies or substantial portions of the Software.
*/
?>
-
-
-
$globals = [];
$names = ['_SERVER','devs','disks','sec','sec_nfs','shares','users','var'];
foreach ($names as $name) $globals[$name] = $$name;
// show outgoing proxy information, is in the environment but not a superglobal
$globals['environment'] = ['http_proxy' => getenv('http_proxy'), 'no_proxy' => getenv('no_proxy')];
-echo "
",htmlspecialchars(print_r($globals,true)),"
";
?>
-
+
+
+
+
+
= htmlspecialchars(print_r($globals,true));?>
+
+
+
+
diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout/BodyInlineJS.php b/emhttp/plugins/dynamix/include/DefaultPageLayout/BodyInlineJS.php
index 4215ffc51..8b14cbf57 100644
--- a/emhttp/plugins/dynamix/include/DefaultPageLayout/BodyInlineJS.php
+++ b/emhttp/plugins/dynamix/include/DefaultPageLayout/BodyInlineJS.php
@@ -446,4 +446,128 @@ function nchanFocusStop(banner=true) {
}
}
+
+/**
+ * Calculates and sets the height of a target element to fill the available viewport space.
+ *
+ * This function dynamically resizes an element to occupy the remaining vertical space
+ * after accounting for other page elements like headers, footers, controls, and their
+ * margins/padding. Useful for creating full-height scrollable content areas.
+ *
+ * The function includes default elements that are commonly present on pages:
+ * - elementsForHeight: '#header', '#menu', '#footer' (plus any additional provided)
+ * - elementsForSpacing: '.displaybox' (plus any additional provided)
+ *
+ * @param {Object} params - Configuration object for height calculation
+ * @param {string} [params.targetElementSelector='.js-fill-available-height'] - CSS selector for the element to resize
+ * @param {string[]} [params.elementSelectorsForHeight=[]] - Additional CSS selectors for elements
+ * whose full height (including margins) should be subtracted from available space.
+ * These are added to the default selectors: '#header', '#menu', '#footer'
+ * @param {string[]} [params.elementSelectorsForSpacing=[]] - Additional CSS selectors for elements
+ * whose spacing (margins and padding only) should be subtracted from available space.
+ * These are added to the default selector: '.displaybox'
+ * @param {number} [params.minHeight=330] - Minimum height in pixels for the target element
+ * @param {number} [params.manualSpacingOffset=10] - Additional pixels to subtract for manual spacing
+ *
+ * @example
+ * // Use with default parameters - targets '.js-fill-available-height'
+ * fillAvailableHeight();
+ *
+ * @example
+ * // Custom configuration with additional elements
+ * // MUST BE USED IN JQUERY ON READY
+ * $(function() { // or $(document).ready(function() {
+ * fillAvailableHeight({
+ * targetElementSelector: '.my-content',
+ * elementSelectorsForHeight: ['.my-controls', '.my-actions'],
+ * elementSelectorsForSpacing: ['.my-content'],
+ * minHeight: 500,
+ * manualSpacingOffset: 20
+ * });
+ * });
+ */
+function fillAvailableHeight(params = { // default params
+ targetElementSelector: '.js-fill-available-height',
+ elementSelectorsForHeight: [],
+ elementSelectorsForSpacing: [],
+ minHeight: 330,
+ manualSpacingOffset: 10,
+}) {
+ const minHeight = params.minHeight || 330;
+
+ // default elementsForHeight
+ const elementsForHeight = [
+ '#header',
+ '#menu',
+ '#footer',
+ '.title',
+ ...(params.elementSelectorsForHeight ? params.elementSelectorsForHeight : []),
+ ];
+
+ // elements with a height and margin we want to subtract from the target height
+ let targetHeight = window.innerHeight - elementsForHeight.reduce((acc, selector) => {
+ const element = document.querySelector(selector);
+
+ if (!element) {
+ return acc;
+ }
+
+ const computedStyle = getComputedStyle(element);
+ const height = element.offsetHeight;
+ const marginTop = parseFloat(computedStyle.marginTop) || 0;
+ const marginBottom = parseFloat(computedStyle.marginBottom) || 0;
+ // we don't need to calculate padding because it's already included in the height
+ const totalForElement = height + marginTop + marginBottom;
+
+ return acc + totalForElement;
+ }, 0);
+
+ // elements with spacing that we want to subtract from the target height, but not their actual height.
+ const elementsForSpacing = [
+ '#displaybox',
+ ...(params.targetElementSelector ? [params.targetElementSelector] : []),
+ ...(params.elementSelectorsForSpacing ? params.elementSelectorsForSpacing : []),
+ ];
+
+ targetHeight -= elementsForSpacing.reduce((acc, selector) => {
+ const element = document.querySelector(selector);
+
+ if (!element) {
+ return acc;
+ }
+
+ const computedStyle = getComputedStyle(element);
+ const marginTop = parseFloat(computedStyle.marginTop) || 0;
+ const marginBottom = selector !== '#displaybox' ? parseFloat(computedStyle.marginBottom) || 0 : 0;
+ const paddingTop = parseFloat(computedStyle.paddingTop) || 0;
+ const paddingBottom = selector !== '#displaybox' ? parseFloat(computedStyle.paddingBottom) || 0 : 0;
+ // we don't want to subtract paddingBottom or marginBottom for #displaybox b/c it adds unnecessary spacing in the calculations
+ // b/c the paddingBottom is accounting for the fixed footer.
+
+ const totalForElement = marginTop + marginBottom + paddingTop + paddingBottom;
+
+ return acc + totalForElement;
+ }, 0);
+
+ // subtract addtional spacing from the target height to provide spacing between the actions & the footer
+ targetHeight -= params.manualSpacingOffset || 10;
+
+ const finalHeight = Math.max(targetHeight, minHeight);
+
+ $(params.targetElementSelector).height(finalHeight);
+
+ // Set up resize listener to call itself with same params
+ // Remove existing listener first to avoid duplicates
+ if (window.fillAvailableHeightResizeHandler) {
+ window.removeEventListener('resize', window.fillAvailableHeightResizeHandler);
+ }
+
+ // Create debounced handler that calls this function with same params
+ window.fillAvailableHeightResizeHandler = debounce(function() {
+ fillAvailableHeight(params);
+ }, 150);
+
+ // Add the new listener
+ window.addEventListener('resize', window.fillAvailableHeightResizeHandler);
+}
diff --git a/emhttp/plugins/dynamix/include/DefaultPageLayout/HeadInlineJS.php b/emhttp/plugins/dynamix/include/DefaultPageLayout/HeadInlineJS.php
index 3a7c5e185..5a7f2bd89 100644
--- a/emhttp/plugins/dynamix/include/DefaultPageLayout/HeadInlineJS.php
+++ b/emhttp/plugins/dynamix/include/DefaultPageLayout/HeadInlineJS.php
@@ -562,4 +562,12 @@ $.ajaxPrefilter(function(s, orig, xhr){
}
setTimerReload();
+
+function debounce(func, wait = 300) {
+ let timeout;
+ return function(...args) {
+ clearTimeout(timeout);
+ timeout = setTimeout(() => func.apply(this, args), wait);
+ };
+}
diff --git a/emhttp/plugins/dynamix/sheets/Syslog.css b/emhttp/plugins/dynamix/sheets/Syslog.css
index a418409f7..11ce7c2b8 100644
--- a/emhttp/plugins/dynamix/sheets/Syslog.css
+++ b/emhttp/plugins/dynamix/sheets/Syslog.css
@@ -6,8 +6,6 @@ input#max {
display: flex;
justify-content: space-between;
align-items: center;
- gap: 10px;
- margin-bottom: 10px;
box-sizing: border-box;
* {