Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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.d/debugbar-restore-button.fixed.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Debug bar: the minimized "Debug" restore button now renders after clicking the X. The `#wdb-minimized` button was nested inside the `#wheels-debugbar` container that `wdbMinimize()` hides with `display:none`, so it could never appear and the bar stayed gone for the whole browser session (manual `sessionStorage` cleanup was the only recovery). It is now a sibling of the container, so minimizing shows the restore button bottom-right and clicking it brings the bar back ([#3345](https://github.com/wheels-dev/wheels/issues/3345)).
4 changes: 3 additions & 1 deletion vendor/wheels/events/onrequestend/debug.cfm
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,10 @@ OR (StructKeyExists(url, "format") AND ListFindNoCase("json,xml,csv,pdf", url.fo
</div>
</cfif>

</div>

<!--- ============ MINIMIZED BUTTON ============ --->
<!--- Sibling of ##wheels-debugbar on purpose: wdbMinimize() sets the container to display:none, and a descendant of a display:none element can never render, so nesting this inside the container makes the restore button unreachable (issue ##3345). It is independently position:fixed. The script include stays below so both elements exist when debugbar.js's load-time wdbMinimize() re-invocation runs. --->
<div id="wdb-minimized" style="display:none;position:fixed;bottom:8px;right:8px;z-index:99999;">
<button onclick="wdbRestore()" style="background:##1e1e2e;border:1px solid ##45475a;border-radius:8px;padding:6px 10px;cursor:pointer;color:##89b4fa;font-size:12px;font-family:inherit;display:flex;align-items:center;gap:4px;box-shadow:0 2px 8px rgba(0,0,0,.3);">
<svg viewBox="0 0 153 18" xmlns="http://www.w3.org/2000/svg" style="width:20px;height:5px;"><path d="M15.71 12c1.65 0 2.99 1.34 2.99 3s-1.34 3-2.99 3-2.99-1.34-2.99-3v-1.27c0-.42-.15-.79-.45-1.09L6.1 6.45c-.3-.3-.66-.45-1.09-.45H3.75c-1.65 0-2.99-1.34-2.99-3S2.09 0 3.74 0s2.99 1.34 2.99 3v1.27c0 .42.15.79.45 1.09l6.17 6.19c.3.3.66.45 1.09.45z" fill="##f38ba8"/></svg>
Expand All @@ -498,6 +501,5 @@ OR (StructKeyExists(url, "format") AND ListFindNoCase("json,xml,csv,pdf", url.fo
</div>

<script><cfinclude template="/wheels/public/assets/js/debugbar.js"></script>
</div>
</cfoutput></cfsavecontent><cfoutput>#ReReplace(local.wdbHtml, "(?m)>\s+<", "><", "all")#</cfoutput>
<!--- cfformat-ignore-end --->
81 changes: 81 additions & 0 deletions vendor/wheels/tests/specs/events/DebugBarMinimizedButtonSpec.cfc
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
component extends="wheels.WheelsTest" {

function run() {
describe("debug bar minimized restore button placement", () => {
// wdbMinimize() (public/assets/js/debugbar.js) sets #wheels-debugbar to
// display:none and #wdb-minimized to display:block. A descendant of a
// display:none element is never rendered regardless of its own display
// value, so the "Debug" restore button must be a SIBLING of the
// container, not a child — otherwise clicking the X hides the bar for
// the whole browser session with no visible recovery (issue #3345).
// This spec renders debug.cfm and asserts structurally that
// id="wdb-minimized" appears only after the div balance for
// #wheels-debugbar has returned to zero (sibling, not descendant).
it("renders the wdb-minimized button as a sibling of the debug bar container", () => {
var priorReqWheels = StructKeyExists(request, "wheels") ? Duplicate(request.wheels) : {};

try {
if (!StructKeyExists(request, "wheels")) {
request.wheels = {};
}
request.wheels.execution = {total = 0};
request.wheels.params = {controller = "wheels", action = "tests", route = ""};

// debug.cfm bails out (cfexit) when url.format is one of
// json/xml/csv/pdf so it never breaks an API response. The
// test runner is hit with format=json — clear it for the
// duration of the include so the template renders.
var hadUrlFormat = StructKeyExists(url, "format");
var priorUrlFormat = hadUrlFormat ? url.format : "";
if (hadUrlFormat) {
StructDelete(url, "format");
}

var output = "";
try {
output = application.wo.$includeAndReturnOutput($template = "/wheels/events/onrequestend/debug.cfm");
} finally {
if (hadUrlFormat) {
url.format = priorUrlFormat;
}
}

var containerPos = FindNoCase('id="wheels-debugbar"', output);
expect(containerPos).toBeGT(0, "the ##wheels-debugbar container should render");

var minimizedPos = FindNoCase('id="wdb-minimized"', output);
expect(minimizedPos).toBeGT(0, "the ##wdb-minimized restore button should render");

// Walk <div / </div tokens starting just inside the container's
// opening tag and find where its balance returns to zero (the
// position of the container's own closing tag).
var depth = 1;
var pos = containerPos;
var containerClosePos = 0;
while (depth > 0) {
var nextOpen = FindNoCase("<div", output, pos + 1);
var nextClose = FindNoCase("</div", output, pos + 1);
expect(nextClose).toBeGT(0, "unbalanced markup: ##wheels-debugbar never closes");
if (nextOpen > 0 && nextOpen < nextClose) {
depth += 1;
pos = nextOpen;
} else {
depth -= 1;
pos = nextClose;
containerClosePos = nextClose;
}
}

expect(minimizedPos).toBeGT(
containerClosePos,
"##wdb-minimized must render AFTER ##wheels-debugbar closes (sibling, not descendant) — " &
"nested inside the container, wdbMinimize()'s display:none makes the restore button unreachable (##3345)"
);
} finally {
request.wheels = priorReqWheels;
}
});
});
}

}
Loading