diff options
Diffstat (limited to 'src/zen/frontend/html/trace.js')
| -rw-r--r-- | src/zen/frontend/html/trace.js | 40 |
1 files changed, 28 insertions, 12 deletions
diff --git a/src/zen/frontend/html/trace.js b/src/zen/frontend/html/trace.js index 2910da15d..2c0b7a3bd 100644 --- a/src/zen/frontend/html/trace.js +++ b/src/zen/frontend/html/trace.js @@ -8,16 +8,8 @@ import { StatsView } from "./stats.js"; import { MemoryView } from "./memory.js"; import { LogsView } from "./logs.js"; import { CsvStatsView } from "./csvstats.js"; - -function escapeHtml(s) { - return String(s).replace(/[&<>"']/g, (c) => ({ - "&": "&", - "<": "<", - ">": ">", - "\"": """, - "'": "'", - }[c])); -} +import { CountersView } from "./counters.js"; +import { escapeHtml } from "./util.js"; function formatTimeMs(us) { if (us < 1000) return `${us} µs`; @@ -157,10 +149,11 @@ async function main() { const memoryView = new MemoryView(model, document.getElementById("memory-content")); const logsView = new LogsView(model, document.getElementById("logs-content")); const csvView = new CsvStatsView(model, document.getElementById("csv-content")); + const countersView = new CountersView(model, document.getElementById("counters-content")); const threadsListApi = renderThreadsList(model, timeline); renderRegionCategories(model, timeline); - setupTabs(memoryView, logsView, csvView); + setupTabs(memoryView, logsView, csvView, countersView); setupSearch(model, timeline, stats); const bookmarksToggle = document.getElementById("bookmarks-toggle"); @@ -173,6 +166,26 @@ async function main() { timeline.setLodEnabled(lodToggle.checked); }); + const compactToggle = document.getElementById("compact-toggle"); + compactToggle.addEventListener("change", () => { + timeline.setCompact(compactToggle.checked); + }); + + // 'c' toggles compact mode while the timeline tab is active. Skipped + // when focus is in a text input so typing 'c' in the search box still + // works normally. + document.addEventListener("keydown", (e) => { + if (e.key !== "c" && e.key !== "C") return; + if (e.ctrlKey || e.metaKey || e.altKey) return; + const target = e.target; + if (target && (target.tagName === "INPUT" || target.tagName === "TEXTAREA" || target.isContentEditable)) return; + const timelineTab = document.querySelector(".tab[data-tab='timeline']"); + if (!timelineTab || !timelineTab.classList.contains("active")) return; + e.preventDefault(); + compactToggle.checked = !compactToggle.checked; + timeline.setCompact(compactToggle.checked); + }); + // Enable all threads that actually have captured scopes by default; if // none do, enable every thread so the swimlanes still show up empty. const withScopes = model.threads.filter((t) => t.scope_count > 0).map((t) => t.thread_id); @@ -492,7 +505,7 @@ function renderRegionCategories(model, timeline) { timeline.setEnabledRegionCategories(allIndices); } -function setupTabs(memoryView, logsView, csvView) { +function setupTabs(memoryView, logsView, csvView, countersView) { const tabs = document.querySelectorAll(".tab"); const views = document.querySelectorAll(".view"); const validTabs = new Set(Array.from(tabs, (tab) => tab.dataset.tab)); @@ -518,6 +531,9 @@ function setupTabs(memoryView, logsView, csvView) { if (key === "csv" && csvView) { csvView.ensureLoaded(); } + if (key === "counters" && countersView) { + countersView.ensureLoaded(); + } } for (const tab of tabs) { |