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 @@ -83,6 +83,7 @@ All notable changes to `phalcon/debugbar` are documented here. The format is bas
- Explain in `Provider` why the boot request uses `get()` and the history request uses `getShared()`. [#98](https://github.com/phalcon/debugbar/issues/98)
- Show `true` and `false` for booleans in messages, show `[]`, `null` and the class name of an object in the grid, and time each query from its own start (0 when there is no start). [#99](https://github.com/phalcon/debugbar/issues/99)
- Debug page: show the previous exceptions, fix the API links, read each file one time, drop the arguments from the `debugVar()` backtrace, match `\vendor\`, and end the line of a skipped `Dump` key. [#100](https://github.com/phalcon/debugbar/issues/100)
- Debug page: copy on `http://` pages, show "Copy failed" when a copy fails, and encode the paths in the PhpStorm and VS Code links. [#101](https://github.com/phalcon/debugbar/issues/101)
- Test HTML writes, the collapse state and `localStorage` errors in the JS tests, and keep every listener in the fake DOM. [#103](https://github.com/phalcon/debugbar/issues/103)

## [0.4.0](https://github.com/phalcon/debugbar/releases/tag/v0.4.0) (2026-07-14)
Expand Down
35 changes: 30 additions & 5 deletions resources/assets/debug.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@
}

function escAttr(s) {
return String(s).replace(/"/g, """);
return String(s).replace(/[&"]/g, function (c) {
return { "&": "&", "\"": """ }[c];
});
}

/* ---- PHP syntax highlighter (no dependencies) ---- */
Expand Down Expand Up @@ -88,10 +90,30 @@
toastTimer = setTimeout(function () { toastEl.classList.remove("show"); }, 1400);
}

/* The clipboard API is only in secure contexts (https, localhost). */
function copyWithTextarea(text) {
var area = document.createElement("textarea");
var copied = false;
area.value = text;
area.setAttribute("readonly", "");
area.style.position = "fixed";
area.style.opacity = "0";
document.body.appendChild(area);
area.select();
try { copied = document.execCommand("copy"); } catch (e) {}
document.body.removeChild(area);
return copied;
}

function copy(text, msg) {
if (navigator.clipboard && navigator.clipboard.writeText) {
navigator.clipboard.writeText(text).then(function () { toast(msg); });
navigator.clipboard.writeText(text).then(
function () { toast(msg); },
function () { toast("Copy failed"); }
);
return;
}
toast(copyWithTextarea(text) ? msg : "Copy failed");
}

/* ---- theme ---- */
Expand Down Expand Up @@ -127,13 +149,16 @@
if (el.querySelector(".mini")) { continue; }
var file = el.getAttribute("data-file");
var line = el.getAttribute("data-line") || "";
var enc = encodeURI(file);
/* PhpStorm takes the path as one query value; VS Code takes a path, so encode each segment. */
var phpstorm = "phpstorm://open?file=" + encodeURIComponent(file) + "&line=" + encodeURIComponent(line);
var vscode = "vscode://file" + file.split("/").map(encodeURIComponent).join("/") +
(line ? ":" + encodeURIComponent(line) : "");
var mini = document.createElement("span");
mini.className = "mini";
mini.innerHTML =
'<button class="icon-btn" data-copy="' + escAttr(file) + '">Copy path</button>' +
'<a class="icon-btn" href="phpstorm://open?file=' + enc + "&line=" + line + '">PhpStorm</a>' +
'<a class="icon-btn" href="vscode://file' + enc + (line ? ":" + line : "") + '">VS Code</a>';
'<a class="icon-btn" href="' + escAttr(phpstorm) + '">PhpStorm</a>' +
'<a class="icon-btn" href="' + escAttr(vscode) + '">VS Code</a>';
el.appendChild(mini);
}
}
Expand Down
Loading