General source code refactoring
This commit is contained in:
174
src/features/debug/content-view.js
Normal file
174
src/features/debug/content-view.js
Normal file
@@ -0,0 +1,174 @@
|
||||
function createDebugContentView({
|
||||
DEBUG_PANEL_ID,
|
||||
MODAL_ID,
|
||||
debugState,
|
||||
formatDebugBody,
|
||||
formatHeaderBlock,
|
||||
formatMetadataBlock,
|
||||
environment
|
||||
}) {
|
||||
const { document } = environment;
|
||||
function toggleDebugPanel() {
|
||||
const modal = document.getElementById(MODAL_ID);
|
||||
|
||||
if (!modal || modal.hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
const panel = document.getElementById(DEBUG_PANEL_ID);
|
||||
|
||||
if (!panel) {
|
||||
return;
|
||||
}
|
||||
|
||||
panel.hidden = !panel.hidden;
|
||||
renderDebugPanel();
|
||||
}
|
||||
|
||||
function renderDebugPanel() {
|
||||
const panel = document.getElementById(DEBUG_PANEL_ID);
|
||||
|
||||
if (!panel || panel.hidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
panel.textContent = "";
|
||||
|
||||
const panelHeader = document.createElement("header");
|
||||
panelHeader.className = "opportunities-extension-debug-panel-header";
|
||||
|
||||
const heading = document.createElement("div");
|
||||
const title = document.createElement("h2");
|
||||
title.textContent = "Debug Requests";
|
||||
|
||||
const summary = document.createElement("p");
|
||||
summary.textContent = `${debugState.requestLog.length} request${debugState.requestLog.length === 1 ? "" : "s"} since modal opened.`;
|
||||
heading.append(title, summary);
|
||||
|
||||
const visibilityButton = document.createElement("button");
|
||||
visibilityButton.type = "button";
|
||||
visibilityButton.className = "opportunities-extension-icon-button opportunities-extension-debug-visibility-button";
|
||||
visibilityButton.setAttribute("aria-pressed", String(debugState.debugSecretsVisible));
|
||||
visibilityButton.setAttribute("aria-label", debugState.debugSecretsVisible ? "Hide sensitive values" : "Show sensitive values");
|
||||
visibilityButton.title = debugState.debugSecretsVisible ? "Hide sensitive values" : "Show sensitive values";
|
||||
visibilityButton.append(createDebugVisibilityIcon(debugState.debugSecretsVisible));
|
||||
visibilityButton.addEventListener("click", () => {
|
||||
debugState.debugSecretsVisible = !debugState.debugSecretsVisible;
|
||||
renderDebugPanel();
|
||||
});
|
||||
panelHeader.append(heading, visibilityButton);
|
||||
|
||||
const list = document.createElement("div");
|
||||
list.className = "opportunities-extension-debug-list";
|
||||
|
||||
if (debugState.requestLog.length === 0) {
|
||||
const empty = document.createElement("div");
|
||||
empty.className = "opportunities-extension-debug-empty";
|
||||
empty.textContent = "No requests recorded yet.";
|
||||
list.append(empty);
|
||||
}
|
||||
|
||||
debugState.requestLog.forEach((entry) => {
|
||||
const item = document.createElement("details");
|
||||
item.className = `opportunities-extension-debug-item opportunities-extension-debug-item-${entry.status}`;
|
||||
|
||||
const heading = document.createElement("summary");
|
||||
heading.className = "opportunities-extension-debug-heading";
|
||||
|
||||
const name = document.createElement("strong");
|
||||
name.textContent = `${entry.id}. ${entry.name}`;
|
||||
|
||||
const httpStatus = document.createElement("span");
|
||||
httpStatus.className = "opportunities-extension-debug-http-status";
|
||||
httpStatus.textContent = entry.httpStatus ? String(entry.httpStatus) : "pending";
|
||||
|
||||
const status = document.createElement("span");
|
||||
status.className = "opportunities-extension-debug-status";
|
||||
status.textContent = entry.status;
|
||||
|
||||
const summaryMeta = document.createElement("span");
|
||||
summaryMeta.className = "opportunities-extension-debug-summary-meta";
|
||||
summaryMeta.append(httpStatus, status);
|
||||
|
||||
heading.append(name, summaryMeta);
|
||||
|
||||
const lines = [
|
||||
`${entry.method} ${entry.url}`,
|
||||
`Started: ${formatDebugTime(entry.startedAt)}`,
|
||||
entry.completedAt ? `Completed: ${formatDebugTime(entry.completedAt)} (${entry.durationMs}ms)` : "Completed: pending",
|
||||
entry.httpStatus ? `HTTP: ${entry.httpStatus} ${entry.statusText}`.trim() : "",
|
||||
entry.error ? `Error: ${entry.error}` : "",
|
||||
`Response body truncated: ${entry.responseBodyTruncated ? "yes" : "no"}`
|
||||
].filter(Boolean);
|
||||
|
||||
const details = document.createElement("div");
|
||||
details.className = "opportunities-extension-debug-details";
|
||||
appendDebugBlock(details, "Request", lines.join("\n"));
|
||||
appendDebugBlock(details, "Request Metadata", formatMetadataBlock(entry.metadata));
|
||||
appendDebugBlock(details, "Request Headers", formatHeaderBlock(entry.requestHeaders));
|
||||
appendDebugBlock(details, "Request Body", formatDebugBody(entry.requestBody));
|
||||
appendDebugBlock(details, "Response Headers", formatHeaderBlock(entry.responseHeaders));
|
||||
appendDebugBlock(details, "Response Body", formatDebugBody(entry.responseBody));
|
||||
|
||||
item.append(heading, details);
|
||||
list.append(item);
|
||||
});
|
||||
|
||||
panel.append(panelHeader, list);
|
||||
}
|
||||
|
||||
function createDebugVisibilityIcon(secretsVisible) {
|
||||
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
|
||||
const eye = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||
const pupil = document.createElementNS("http://www.w3.org/2000/svg", "circle");
|
||||
|
||||
svg.setAttribute("viewBox", "0 0 24 24");
|
||||
svg.setAttribute("aria-hidden", "true");
|
||||
svg.setAttribute("focusable", "false");
|
||||
eye.setAttribute("d", "M2.5 12s3.5-6.5 9.5-6.5 9.5 6.5 9.5 6.5-3.5 6.5-9.5 6.5S2.5 12 2.5 12Z");
|
||||
pupil.setAttribute("cx", "12");
|
||||
pupil.setAttribute("cy", "12");
|
||||
pupil.setAttribute("r", "2.75");
|
||||
[eye, pupil].forEach((shape) => {
|
||||
shape.setAttribute("fill", "none");
|
||||
shape.setAttribute("stroke", "currentColor");
|
||||
shape.setAttribute("stroke-linecap", "round");
|
||||
shape.setAttribute("stroke-linejoin", "round");
|
||||
shape.setAttribute("stroke-width", "1.7");
|
||||
});
|
||||
svg.append(eye, pupil);
|
||||
|
||||
if (secretsVisible) {
|
||||
const slash = document.createElementNS("http://www.w3.org/2000/svg", "path");
|
||||
slash.setAttribute("d", "M4 4l16 16");
|
||||
slash.setAttribute("fill", "none");
|
||||
slash.setAttribute("stroke", "currentColor");
|
||||
slash.setAttribute("stroke-linecap", "round");
|
||||
slash.setAttribute("stroke-width", "1.9");
|
||||
svg.append(slash);
|
||||
}
|
||||
|
||||
return svg;
|
||||
}
|
||||
|
||||
function appendDebugBlock(container, label, value) {
|
||||
const block = document.createElement("section");
|
||||
const heading = document.createElement("h3");
|
||||
const content = document.createElement("pre");
|
||||
|
||||
heading.textContent = label;
|
||||
content.textContent = value;
|
||||
block.append(heading, content);
|
||||
container.append(block);
|
||||
}
|
||||
|
||||
function formatDebugTime(date) {
|
||||
return date.toLocaleTimeString(undefined, {
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit"
|
||||
});
|
||||
}
|
||||
|
||||
return { toggleDebugPanel, renderDebugPanel, createDebugVisibilityIcon, appendDebugBlock, formatDebugTime };
|
||||
}
|
||||
Reference in New Issue
Block a user