HTML template builders for DevTools Sidebar
Este script no debería instalarse directamente. Es una biblioteca que utilizan otros scripts mediante la meta-directiva de inclusión // @require https://update.greasyfork.org/scripts/580257/1839659/DevTools%20Sidebar%20%E2%80%94%20HTML.js
// ==UserScript==
// @name DevTools Sidebar — HTML
// @namespace http://tampermonkey.net/
// @version 7.2.3
// @description HTML template builders for DevTools Sidebar
// @author MrNosferatu
// ==/UserScript==
// ─── Build merged Network panel ───────────────────────────────────────────────
function buildNetworkPanel() {
function tip(text) {
return `<span class="dt-tip"><span class="dt-tip-icon">?</span><span class="dt-tip-text">${text}</span></span>`;
}
return `
<div class="dt-section">
<div class="dt-slabel">Filter</div>
<div class="dt-row" style="margin-bottom:8px">
<div class="dt-row-label" style="display:flex;align-items:center;gap:5px">Methods ${tip('Applies to both request and response interceptors, and benchmark capture.')}</div>
</div>
<div class="dt-method-grid">${ALL_METHODS.map(m=>`<input type="checkbox" class="dt-method-check" id="dt-net-m-${m}" data-m="${m}"><label class="dt-method-pill" for="dt-net-m-${m}">${m}</label>`).join('')}</div>
<div style="margin-top:14px">
<div class="dt-row" style="margin-bottom:6px">
<div class="dt-row-label" style="display:flex;align-items:center;gap:5px">URL Mode ${tip('Auto intercepts every URL. Manual filters by the regex pattern below.')}</div>
<div class="dt-chip" id="dt-net-chip">Auto</div>
</div>
<div class="dt-mode-group">
<button class="dt-mode-btn active" data-mode="auto" data-ns="net">Auto</button>
<button class="dt-mode-btn" data-mode="manual" data-ns="net">Regex</button>
</div>
<div class="dt-regex-wrap" id="dt-net-rwrap">
<div class="dt-regex-field" style="margin-top:8px">
<span class="dt-regex-delim">/</span>
<input class="dt-regex-input" id="dt-net-regex" type="text" placeholder="api\\/v\\d+\\/.*" spellcheck="false">
<span class="dt-regex-delim">/</span>
<div class="dt-regex-dot" id="dt-net-rdot"></div>
</div>
</div>
</div>
</div>
<div class="dt-section">
<div class="dt-slabel">Request</div>
<div class="dt-row" style="margin-bottom:10px">
<div class="dt-row-label" style="display:flex;align-items:center;gap:5px">Intercept ${tip('Halt outgoing requests before they are sent. GET requests show URL params editor; others show body editor.')}</div>
<label class="dt-toggle"><input type="checkbox" id="dt-req-enabled"><div class="dt-toggle-track"><div class="dt-toggle-thumb"></div></div></label>
</div>
<div class="dt-queue"><div class="dt-queue-dot" id="dt-req-qdot"></div><span class="dt-queue-text" id="dt-req-qtext">No requests queued</span></div>
<div class="dt-row" id="dt-req-persist-row" style="margin-top:10px;margin-bottom:0">
<div class="dt-row-label" style="display:flex;align-items:center;gap:5px">Persist ${tip('Keep intercept enabled across page reloads.')}</div>
<label class="dt-toggle"><input type="checkbox" id="dt-req-persist"><div class="dt-toggle-track"><div class="dt-toggle-thumb"></div></div></label>
</div>
</div>
<div class="dt-section">
<div class="dt-slabel">Response</div>
<div class="dt-row" style="margin-bottom:10px">
<div class="dt-row-label" style="display:flex;align-items:center;gap:5px">Intercept ${tip('Hold API responses and allow editing the body and headers before the page receives them.')}</div>
<label class="dt-toggle"><input type="checkbox" id="dt-res-enabled"><div class="dt-toggle-track"><div class="dt-toggle-thumb"></div></div></label>
</div>
<div class="dt-queue"><div class="dt-queue-dot" id="dt-res-qdot"></div><span class="dt-queue-text" id="dt-res-qtext">No responses queued</span></div>
<div class="dt-row" id="dt-res-persist-row" style="margin-top:10px;margin-bottom:0">
<div class="dt-row-label" style="display:flex;align-items:center;gap:5px">Persist ${tip('Keep intercept enabled across page reloads.')}</div>
<label class="dt-toggle"><input type="checkbox" id="dt-res-persist"><div class="dt-toggle-track"><div class="dt-toggle-thumb"></div></div></label>
</div>
</div>
<div class="dt-section">
<div class="dt-slabel">Transforms</div>
<div class="dt-row" style="margin-bottom:10px">
<div class="dt-row-label" style="display:flex;align-items:center;gap:5px">Auto-apply ${tip('Automatically apply a matching enabled preset to responses — no modal shown.')}</div>
<label class="dt-toggle"><input type="checkbox" id="dt-res-auto-transform"><div class="dt-toggle-track"><div class="dt-toggle-thumb"></div></div></label>
</div>
<div class="dt-at-hint" id="dt-res-auto-transform-hint" style="font-size:11px;color:var(--mu);margin-bottom:10px"></div>
<button class="dt-btn-presets" id="dt-res-presets-btn">
<svg width="13" height="13" viewBox="0 0 13 13" fill="none" stroke="currentColor" stroke-width="1.5"><circle cx="6.5" cy="6.5" r="2"/><path d="M6.5 1v1.5M6.5 10.5V12M1 6.5h1.5M10.5 6.5H12M2.6 2.6l1.1 1.1M9.3 9.3l1.1 1.1M9.3 2.6l-1.1 1.1M3.7 9.3l-1.1 1.1"/></svg>
Manage Presets
</button>
</div>
`;
}
// ─── Keep buildInterceptorPanel as alias for nothing (no longer used directly)
function buildInterceptorPanel(ns) { return ''; }
// ─── Sidebar settings panel HTML ──────────────────────────────────────────────
// ─── Sidebar settings panel HTML ──────────────────────────────────────────────
function buildSidebarSettingsPanel() {
return `
<div class="dt-section">
<div class="dt-slabel">Layout</div>
<div class="dt-row" style="margin-bottom:10px">
<div class="dt-row-label">Position</div>
<div class="dt-side-toggle" id="dt-sb-side-toggle">
<button class="dt-side-btn" data-side="left">Left</button>
<button class="dt-side-btn active" data-side="right">Right</button>
</div>
</div>
<div class="dt-row" style="margin-bottom:6px"><div class="dt-row-label">Width</div></div>
<div class="dt-slider-row">
<button class="dt-slider-step" id="dt-sb-width-dec">−</button>
<input type="range" class="dt-size-slider" id="dt-sb-width-slider" min="280" max="720" step="4" style="flex:1">
<button class="dt-slider-step" id="dt-sb-width-inc">+</button>
<input type="text" class="dt-slider-val-input" id="dt-sb-width-val" value="360">
</div>
</div>
<div class="dt-section">
<div class="dt-slabel">Appearance</div>
<div class="dt-appearance-tabs">
<button class="dt-appearance-tab" data-sbmode="light">Light</button>
<button class="dt-appearance-tab" data-sbmode="dark">Dark</button>
<button class="dt-appearance-tab" data-sbmode="auto">Auto</button>
<button class="dt-appearance-tab" data-sbmode="custom">Custom</button>
</div>
<div id="dt-sb-custom-colors" style="display:none">
<div class="dt-custom-colors">
<div class="dt-color-group"><div class="dt-color-label">Background</div><div class="dt-color-input-row"><input type="color" class="dt-color-picker" id="dt-sb-sbg-picker"><input type="text" class="dt-color-hex" id="dt-sb-sbg-hex" placeholder="#1a1b1e" maxlength="9"><button class="dt-color-clear" id="dt-sb-sbg-clear">✕</button></div></div>
<div class="dt-color-group"><div class="dt-color-label">Surface</div><div class="dt-color-input-row"><input type="color" class="dt-color-picker" id="dt-sb-ssf-picker"><input type="text" class="dt-color-hex" id="dt-sb-ssf-hex" placeholder="#222327" maxlength="9"><button class="dt-color-clear" id="dt-sb-ssf-clear">✕</button></div></div>
<div class="dt-color-group"><div class="dt-color-label">Text</div><div class="dt-color-input-row"><input type="color" class="dt-color-picker" id="dt-sb-stx-picker"><input type="text" class="dt-color-hex" id="dt-sb-stx-hex" placeholder="#e4e6f0" maxlength="9"><button class="dt-color-clear" id="dt-sb-stx-clear">✕</button></div></div>
<div class="dt-color-group"><div class="dt-color-label">Border</div><div class="dt-color-input-row"><input type="color" class="dt-color-picker" id="dt-sb-sbd-picker"><input type="text" class="dt-color-hex" id="dt-sb-sbd-hex" placeholder="#333540" maxlength="9"><button class="dt-color-clear" id="dt-sb-sbd-clear">✕</button></div></div>
</div>
</div>
</div>
<div class="dt-section">
<div class="dt-slabel">Editor Theme</div>
<div class="dt-theme-grid" id="dt-sb-theme-grid"></div>
<div id="dt-sb-editor-custom-colors" style="display:none;margin-top:12px">
<div class="dt-custom-colors">
<div class="dt-color-group"><div class="dt-color-label">Background</div><div class="dt-color-input-row"><input type="color" class="dt-color-picker" id="dt-sb-bg-picker"><input type="text" class="dt-color-hex" id="dt-sb-bg-hex" placeholder="#1e1e2e" maxlength="9"><button class="dt-color-clear" id="dt-sb-bg-clear">✕</button></div></div>
<div class="dt-color-group"><div class="dt-color-label">Text</div><div class="dt-color-input-row"><input type="color" class="dt-color-picker" id="dt-sb-text-picker"><input type="text" class="dt-color-hex" id="dt-sb-text-hex" placeholder="#cdd6f4" maxlength="9"><button class="dt-color-clear" id="dt-sb-text-clear">✕</button></div></div>
</div>
</div>
</div>
<div class="dt-section">
<div class="dt-slabel">Editor Font</div>
<div class="dt-font-list" id="dt-sb-font-list"></div>
</div>
<div class="dt-section">
<div class="dt-row" style="margin-bottom:6px"><div class="dt-row-label">Font Size</div></div>
<div class="dt-slider-row">
<button class="dt-slider-step" id="dt-sb-size-dec">−</button>
<input type="range" class="dt-size-slider" id="dt-sb-size-slider" min="9" max="18" step="1" style="flex:1">
<button class="dt-slider-step" id="dt-sb-size-inc">+</button>
<input type="text" class="dt-slider-val-input" id="dt-sb-size-val" value="12">
</div>
<div style="margin-top:12px;border-radius:8px;overflow:hidden" id="dt-sb-preview">
<div class="dt-editor-wrap" style="border-radius:6px;margin:0">
<div style="padding:10px 12px" id="dt-sb-preview-inner">const greeting = "Hello, DevTools!";</div>
</div>
</div>
</div>
<div class="dt-section" style="display:flex;gap:8px">
<button class="dt-btn-reset" id="dt-sb-settings-reset">Reset</button>
<button class="dt-btn-apply" id="dt-sb-settings-apply">Apply</button>
</div>
`;
}
// ─── Editor HTML ──────────────────────────────────────────────────────────────
// The cURL copy button lives here in the editor bar — a secondary utility
// action, consistent with Format/Minify. Only rendered for the request editor.
function buildEditorHTML(id) {
const isCurlEditor = id === 'dt-req-ed';
return `
<div class="dt-editor-wrap" id="${id}-wrap">
<div class="dt-editor-outer">
<div class="dt-hl-overlay" id="${id}-hl" aria-hidden="true"></div>
<textarea class="dt-editor" id="${id}" spellcheck="false"></textarea>
</div>
<div class="dt-editor-bar" id="${id}-bar">
<button class="dt-editor-btn" id="${id}-fmt">Format</button>
<button class="dt-editor-btn" id="${id}-min">Minify</button>
<span class="dt-json-badge" id="${id}-badge">—</span>
${isCurlEditor ? `<button class="dt-editor-btn" id="dt-req-copy-curl">Copy as cURL</button>` : ''}
<button class="dt-editor-btn dt-search-toggle-btn" id="${id}-stoggle" title="Find (Ctrl+F)">⌕ Find</button>
</div>
<div class="dt-search-bar hidden" id="${id}-sbar">
<div class="dt-search-wrap" id="${id}-swrap">
<span class="dt-search-icon">⌕</span>
<input class="dt-search-input" id="${id}-sinput" type="text" placeholder="Search…" spellcheck="false">
</div>
<span class="dt-search-count" id="${id}-scount">—</span>
<button class="dt-snav" id="${id}-sprev" title="Prev (Shift+Enter)">↑</button>
<button class="dt-snav" id="${id}-snext" title="Next (Enter)">↓</button>
<button class="dt-sclose" id="${id}-sclose">✕</button>
</div>
</div>
`;
}
// ─── Benchmark panel HTML ─────────────────────────────────────────────────────
function buildBenchPanel() {
return `
<!-- Mode selector: Off / Manual / Capture -->
<div class="dt-section">
<div class="dt-slabel">Mode</div>
<div class="dt-mode-group" style="margin-top:0">
<button class="dt-mode-btn active" id="dt-bench-mode-off">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.6" style="vertical-align:middle;margin-right:4px"><circle cx="5.5" cy="5.5" r="4.5"/><line x1="3.3" y1="3.3" x2="7.7" y2="7.7"/></svg>Off
</button>
<button class="dt-mode-btn" id="dt-bench-mode-manual">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.6" style="vertical-align:middle;margin-right:4px"><path d="M2 2h7M2 5.5h5M2 9h6"/></svg>Manual
</button>
<button class="dt-mode-btn" id="dt-bench-mode-capture">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.6" style="vertical-align:middle;margin-right:4px"><circle cx="5.5" cy="5.5" r="4"/><circle cx="5.5" cy="5.5" r="1.5" fill="currentColor" stroke="none"/></svg>Capture
</button>
</div>
</div>
<!-- Manual URL input -->
<div class="dt-section" id="dt-bench-manual-section" style="display:none">
<div class="dt-slabel">Request</div>
<!-- cURL paste area -->
<div id="dt-bench-curl-wrap" style="margin-bottom:10px">
<div class="dt-flabel" style="margin-bottom:5px">
Paste cURL
<span style="font-weight:400;color:var(--mu);margin-left:4px">— or fill the fields below</span>
</div>
<textarea class="dt-bench-body-ed" id="dt-bench-curl-input" spellcheck="false" rows="2"
placeholder="curl 'https://api.example.com/data' -H 'Authorization: Bearer token' -d '{}'"></textarea>
<button class="dt-pe-add-pattern" id="dt-bench-curl-parse" style="margin-top:6px">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.8"><polyline points="2,3 5.5,6.5 9,3"/><line x1="5.5" y1="6.5" x2="5.5" y2="1"/><line x1="1" y1="9" x2="10" y2="9"/></svg>
Parse cURL into fields
</button>
</div>
<div style="display:flex;gap:6px;margin-bottom:10px">
<select class="dt-bench-method-sel" id="dt-bench-method">
${['GET','POST','PUT','PATCH','DELETE'].map(m=>`<option value="${m}">${m}</option>`).join('')}
</select>
<input class="dt-bench-url-input" id="dt-bench-url" type="text" placeholder="https://api.example.com/endpoint" spellcheck="false">
</div>
<div class="dt-flabel" style="margin-bottom:6px">Headers <span style="font-weight:400;color:var(--mu)">(optional)</span></div>
<div class="dt-pe-patterns-list" id="dt-bench-headers-list"></div>
<button class="dt-pe-add-pattern" id="dt-bench-add-header">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.8"><line x1="5.5" y1="1" x2="5.5" y2="10"/><line x1="1" y1="5.5" x2="10" y2="5.5"/></svg>
Add header
</button>
<div id="dt-bench-body-wrap" style="display:none;margin-top:12px">
<div class="dt-flabel" style="margin-bottom:6px">Body</div>
<textarea class="dt-bench-body-ed" id="dt-bench-body" spellcheck="false" placeholder='{"key": "value"}'></textarea>
</div>
</div>
<!-- Capture mode -->
<div class="dt-section" id="dt-bench-capture-section" style="display:none">
<div id="dt-bench-cap-persist-row" class="dt-row" style="margin-bottom:12px">
<div class="dt-row-info">
<div class="dt-row-label">Persist</div>
<div class="dt-row-sub">Keep capture mode enabled across reloads</div>
</div>
<label class="dt-toggle"><input type="checkbox" id="dt-bench-cap-persist"><div class="dt-toggle-track"><div class="dt-toggle-thumb"></div></div></label>
</div>
<div class="dt-flabel" style="margin-bottom:6px">Capture Methods</div>
<div class="dt-method-grid" style="margin-bottom:12px">${ALL_METHODS.map(m=>`<input type="checkbox" class="dt-method-check" id="dt-bench-cap-m-${m}" data-m="${m}" checked><label class="dt-method-pill" for="dt-bench-cap-m-${m}">${m}</label>`).join('')}</div>
<div class="dt-flabel" style="margin-bottom:4px">URL Filter</div>
<div class="dt-mode-group" style="margin-bottom:8px">
<button class="dt-mode-btn active" data-mode="auto" data-ns="bench-cap">Auto — All</button>
<button class="dt-mode-btn" data-mode="manual" data-ns="bench-cap">Manual — Regex</button>
</div>
<div class="dt-regex-wrap" id="dt-bench-cap-rwrap">
<div class="dt-regex-field">
<span class="dt-regex-delim">/</span>
<input class="dt-regex-input" id="dt-bench-cap-regex" type="text" placeholder="api\\/v\\d+\\/.*" spellcheck="false">
<span class="dt-regex-delim">/</span>
<div class="dt-regex-dot" id="dt-bench-cap-rdot"></div>
</div>
</div>
<div class="dt-bench-capture-list" id="dt-bench-capture-list" style="margin-top:10px">
<div class="dt-bench-capture-empty" id="dt-bench-capture-empty">Enable capture, then browse the page — requests will appear here.</div>
</div>
</div>
<!-- Selected request preview (shared between modes) -->
<div class="dt-section" id="dt-bench-selected-section" style="display:none">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
<div class="dt-slabel" style="margin-bottom:0">Selected Request</div>
<button class="dt-bench-clear-sel" id="dt-bench-clear-sel">Clear</button>
</div>
<div class="dt-bench-sel-pill" id="dt-bench-sel-pill"></div>
</div>
<!-- Run config -->
<div class="dt-section" id="dt-bench-config-section">
<div class="dt-slabel">Run Config</div>
<div class="dt-bench-config-grid">
<div class="dt-bench-config-item">
<div class="dt-flabel">Iterations</div>
<input class="dt-bench-num-input" id="dt-bench-iters" type="number" min="1" max="500" value="10">
</div>
<div class="dt-bench-config-item">
<div class="dt-flabel">Concurrency</div>
<input class="dt-bench-num-input" id="dt-bench-concurrency" type="number" min="1" max="20" value="1">
</div>
<div class="dt-bench-config-item">
<div class="dt-flabel">Delay (ms)</div>
<input class="dt-bench-num-input" id="dt-bench-delay" type="number" min="0" max="5000" value="0">
</div>
<div class="dt-bench-config-item">
<div class="dt-flabel">Warmup</div>
<label class="dt-toggle" style="margin-top:4px"><input type="checkbox" id="dt-bench-warmup" checked><div class="dt-toggle-track"><div class="dt-toggle-thumb"></div></div></label>
</div>
</div>
<button class="dt-bench-run-btn" id="dt-bench-run">
<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor"><polygon points="2,1 11,6 2,11"/></svg>
Run Benchmark
</button>
</div>
<!-- Results -->
<div class="dt-section" id="dt-bench-results-section" style="display:none">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px">
<div class="dt-slabel" style="margin-bottom:0">Results</div>
<div style="display:flex;gap:6px">
<button class="dt-bench-copy-btn" id="dt-bench-copy-results">Copy</button>
<button class="dt-bench-copy-btn dt-bench-clear-results-btn" id="dt-bench-clear-results">Clear</button>
</div>
</div>
<!-- Last result accordion — sits at top, expands downward -->
<div class="dt-bench-accordion" id="dt-bench-last-result" style="display:none;margin-bottom:12px">
<button class="dt-bench-accordion-hd" id="dt-bench-last-result-toggle">
<span class="dt-bench-accordion-label">Last Request</span>
<span class="dt-bench-accordion-pill" id="dt-bench-last-result-pill"></span>
<svg class="dt-bench-accordion-arrow" width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.8"><polyline points="2,3.5 5,6.5 8,3.5"/></svg>
</button>
<div class="dt-bench-accordion-body" id="dt-bench-last-result-body" style="display:none">
<div class="dt-bench-accordion-row" id="dt-bench-last-url-row">
<div class="dt-bench-accordion-key">URL</div>
<div class="dt-bench-accordion-val" id="dt-bench-last-url"></div>
</div>
<div class="dt-bench-accordion-row" id="dt-bench-last-params-row" style="display:none">
<div class="dt-bench-accordion-key">Params</div>
<div class="dt-bench-accordion-val" id="dt-bench-last-params"></div>
</div>
<div class="dt-bench-accordion-row" id="dt-bench-last-headers-row" style="display:none">
<div class="dt-bench-accordion-key">Headers</div>
<div class="dt-bench-accordion-val" id="dt-bench-last-headers"></div>
</div>
<div class="dt-bench-accordion-row" id="dt-bench-last-body-row" style="display:none">
<div class="dt-bench-accordion-key">Body</div>
<div class="dt-bench-accordion-val" id="dt-bench-last-body"></div>
</div>
</div>
</div>
<div class="dt-bench-progress" id="dt-bench-progress" style="display:none">
<div class="dt-bench-progress-bar"><div class="dt-bench-progress-fill" id="dt-bench-progress-fill"></div></div>
<div class="dt-bench-progress-label" id="dt-bench-progress-label">Running…</div>
</div>
<div class="dt-bench-stats" id="dt-bench-stats"></div>
<canvas class="dt-bench-chart" id="dt-bench-chart" height="54"></canvas>
<div class="dt-bench-run-list" id="dt-bench-run-list"></div>
</div>
`;
}
// ─── Full HTML ────────────────────────────────────────────────────────────────
const HTML = `
<div id="dt-tab" title="DevTools Sidebar">
<div id="dt-tab-inner">
<div id="dt-tab-label">DevTools</div><div id="dt-tab-chevron">‹</div>
</div>
</div>
<div id="dt-sidebar">
<div id="dt-sb-drag-handle"></div>
<div class="dt-head">
<div class="dt-head-icon">🛠</div>
<div class="dt-head-text"><div class="dt-head-title">DevTools</div><div class="dt-head-sub">Developer Utilities</div></div>
<button class="dt-head-close" id="dt-close-btn">✕</button>
</div>
<div class="dt-nav">
<button class="dt-nav-btn active" data-panel="network">Network</button>
<button class="dt-nav-btn" data-panel="bench">Bench</button>
<button class="dt-nav-btn" data-panel="settings">Settings</button>
</div>
<div class="dt-scroll">
<div class="dt-panel active" id="dt-panel-network">${buildNetworkPanel()}</div>
<div class="dt-panel" id="dt-panel-bench">${buildBenchPanel()}</div>
<div class="dt-panel" id="dt-panel-settings">${buildSidebarSettingsPanel()}</div>
<div class="dt-panel" id="dt-panel-about">
<div class="dt-about-hero"><div class="dt-about-icon">🛠</div><div class="dt-about-title">DevTools Sidebar</div><div class="dt-about-version">v7.0.0 · Tampermonkey</div></div>
<div class="dt-feature-list">
<div class="dt-feature-item"><div class="dt-feature-ico"></div><div><div class="dt-feature-name">Request Interceptor</div><div class="dt-feature-desc">Edit request body or URL params before sending. Supports GET/POST/PUT/PATCH/DELETE.</div></div></div>
<div class="dt-feature-item"><div class="dt-feature-ico"></div><div><div class="dt-feature-name">Response Interceptor</div><div class="dt-feature-desc">Capture & transform responses. Manual edit, GUI path extractor, or custom JS transform.</div></div></div>
<div class="dt-feature-item"><div class="dt-feature-ico"></div><div><div class="dt-feature-name">Editor Theming</div><div class="dt-feature-desc">Catppuccin, Monokai, Nord, Dracula, VS Light presets + custom background & text colors, font, and size. Edit live from the Settings tab.</div></div></div>
</div>
</div>
</div>
</div>
<!-- Request Modal -->
<div id="dt-req-overlay" class="dt-overlay">
<div id="dt-req-modal" class="dt-modal">
<div class="dt-modal-head">
<div class="dt-modal-icon req">⚡</div>
<div class="dt-modal-meta"><div class="dt-modal-title">Request Intercepted</div><div class="dt-modal-url" id="dt-req-url"></div></div>
<div class="dt-method-tag POST" id="dt-req-method">POST</div>
</div>
<div class="dt-modal-body" id="dt-req-body">
<div class="dt-modal-inner">
<div id="dt-req-editor-section" class="dt-payload-section">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">
<div class="dt-flabel" style="margin-bottom:0">Request Payload</div>
<button class="dt-revert-btn" id="dt-req-ed-revert" title="Revert to original">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M1.5 5.5A4 4 0 1 1 3 8.5"/><polyline points="1,3 1.5,5.5 4,5"/></svg>
Revert
</button>
</div>
${buildEditorHTML('dt-req-ed')}
</div>
<div id="dt-req-params-section" class="dt-params-section" style="display:none">
<div class="dt-flabel">URL Parameters</div>
<div class="dt-params-list" id="dt-req-params-list"></div>
<button class="dt-add-param" id="dt-req-add-param">+ Add Parameter</button>
</div>
<div class="dt-headers-section">
<div class="dt-headers-toggle" id="dt-req-htoggle">
<span class="dt-headers-arrow">›</span>
<span class="dt-headers-label">Request Headers</span>
<span class="dt-headers-count" id="dt-req-hcount"></span>
<button class="dt-hrevert-btn" id="dt-req-hrevert" title="Revert headers to original" style="display:none">
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M1 4.5A3.5 3.5 0 1 1 2.5 7.8"/><polyline points="1,2.5 1,4.5 3,4.5"/></svg>
Revert
</button>
</div>
<div class="dt-headers-body" id="dt-req-hbody"><div class="dt-headers-inner" id="dt-req-hinner"></div></div>
</div>
</div>
</div>
<div class="dt-modal-foot">
<button class="dt-foot-btn dt-foot-btn-abort" id="dt-req-abort">Abort</button>
<span class="dt-modal-count" id="dt-req-count"></span>
<button class="dt-foot-btn dt-foot-btn-send" id="dt-req-send">Send Request →</button>
</div>
</div>
</div>
<!-- Response Modal -->
<div id="dt-res-overlay" class="dt-overlay">
<div id="dt-res-modal" class="dt-modal">
<div class="dt-modal-head">
<div class="dt-modal-icon res">↩</div>
<div class="dt-modal-meta"><div class="dt-modal-title">Response Intercepted</div><div class="dt-modal-url" id="dt-res-url"></div></div>
<div class="dt-method-tag GET" id="dt-res-method">GET</div>
</div>
<div class="dt-modal-body" id="dt-res-body">
<div class="dt-modal-inner">
<div id="dt-res-status-bar"></div>
<div class="dt-res-tabs">
<button class="dt-res-tab active" data-restab="manual"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" style="vertical-align:middle;margin-right:4px"><path d="M2 3h8M2 6h5M2 9h6"/></svg>Manual Edit</button>
<button class="dt-res-tab" data-restab="gui"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" style="vertical-align:middle;margin-right:4px"><rect x="1" y="1" width="4" height="4" rx="0.5"/><rect x="7" y="1" width="4" height="4" rx="0.5"/><rect x="1" y="7" width="4" height="4" rx="0.5"/><rect x="7" y="7" width="4" height="4" rx="0.5"/></svg>GUI Extract</button>
<button class="dt-res-tab" data-restab="code"><svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5" style="vertical-align:middle;margin-right:4px"><polyline points="3,4 1,6 3,8"/><polyline points="9,4 11,6 9,8"/><line x1="7" y1="2" x2="5" y2="10"/></svg>JS Transform</button>
</div>
<div id="dt-res-manual" class="dt-payload-section">
<div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:4px">
<div class="dt-flabel" style="margin-bottom:0">Response Body</div>
<button class="dt-revert-btn" id="dt-res-ed-revert" title="Revert to original">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.6"><path d="M1.5 5.5A4 4 0 1 1 3 8.5"/><polyline points="1,3 1.5,5.5 4,5"/></svg>
Revert
</button>
</div>
${buildEditorHTML('dt-res-ed')}
</div>
<div id="dt-res-gui" class="dt-transform-section" style="display:none">
<div class="dt-transform-note">Click a key in the tree to select a path. Then choose an action to apply to the response.</div>
<div class="dt-transform-cols">
<div class="dt-transform-pane">
<div class="dt-transform-pane-label">Response Tree</div>
<div class="dt-tree" id="dt-res-tree"></div>
</div>
<div class="dt-transform-pane" style="max-width:200px;flex-shrink:0">
<div class="dt-transform-pane-label">Actions</div>
<div class="dt-path-builder">
<div class="dt-transform-pane-label" style="color:var(--vi);margin-bottom:4px">Selected path:</div>
<div class="dt-path-display" id="dt-res-path-display">—</div>
<div class="dt-path-actions">
<button class="dt-path-btn dt-path-btn-extract" id="dt-res-extract-btn">Extract value</button>
<button class="dt-path-btn dt-path-btn-wrap" id="dt-res-wrap-btn">Wrap in key</button>
</div>
<input class="dt-custom-wrap-input" id="dt-res-wrap-key" type="text" placeholder='wrap key name e.g. "data"' style="display:none">
</div>
</div>
</div>
</div>
<div id="dt-res-code" class="dt-code-section" style="display:none">
<div class="dt-code-note">
Write a JS function body. You receive <code>data</code> (parsed JSON or raw string) and <code>res</code> (metadata).<br>
Return the value that should replace the response. Example:<br>
<code>return data.res.data;</code> or <code>return { items: data.items, total: data.meta.total };</code>
</div>
<textarea class="dt-transform-editor" id="dt-res-code-editor" spellcheck="false" placeholder="// data = parsed response JSON // res = { url, method, status } return data;"></textarea>
<div style="display:flex;gap:8px;align-items:center;flex-shrink:0">
<button class="dt-transform-run-btn" id="dt-res-run-btn">
<svg width="12" height="12" viewBox="0 0 12 12" fill="currentColor"><polygon points="2,1 11,6 2,11"/></svg>
Run Transform
</button>
<button class="dt-transform-save-btn" id="dt-res-save-preset" title="Save this transform as a preset">
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" stroke="currentColor" stroke-width="1.5"><rect x="1" y="1" width="10" height="10" rx="1"/><rect x="3.5" y="1" width="5" height="3.5" rx="0.5"/><rect x="3" y="6.5" width="6" height="4" rx="0.5"/></svg>
Save Preset
</button>
<div class="dt-transform-err" id="dt-res-transform-err"></div>
</div>
<div id="dt-res-preview" class="dt-res-preview-section">
<div class="dt-flabel" style="margin-bottom:8px">Preview (Before → After)</div>
<div class="dt-preview-container">
<div class="dt-preview-pane">
<div class="dt-preview-label">Original</div>
<div class="dt-preview-content dt-editor-themed" id="dt-res-preview-original"></div>
</div>
<div class="dt-preview-arrow">→</div>
<div class="dt-preview-pane">
<div class="dt-preview-label">Transformed</div>
<div class="dt-preview-content dt-editor-themed" id="dt-res-preview-transformed"></div>
</div>
</div>
</div>
</div>
<div class="dt-headers-section">
<div class="dt-headers-toggle" id="dt-res-htoggle">
<span class="dt-headers-arrow">›</span>
<span class="dt-headers-label">Response Headers</span>
<span class="dt-headers-count" id="dt-res-hcount"></span>
<button class="dt-hrevert-btn" id="dt-res-hrevert" title="Revert headers to original" style="display:none">
<svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M1 4.5A3.5 3.5 0 1 1 2.5 7.8"/><polyline points="1,2.5 1,4.5 3,4.5"/></svg>
Revert
</button>
</div>
<div class="dt-headers-body" id="dt-res-hbody"><div class="dt-headers-inner" id="dt-res-hinner"></div></div>
</div>
</div>
</div>
<div class="dt-modal-foot">
<button class="dt-foot-btn dt-foot-btn-abort" id="dt-res-abort">Passthrough (Original)</button>
<span class="dt-modal-count" id="dt-res-count"></span>
<button class="dt-foot-btn dt-foot-btn-send res-send" id="dt-res-send">Apply Response →</button>
</div>
</div>
</div>
<!-- Presets Modal — must be after dt-res-overlay in DOM so it stacks on top -->
<div id="dt-presets-overlay" class="dt-overlay">
<div id="dt-presets-modal" class="dt-modal" style="max-width:560px;width:90%;height:auto;min-height:300px;max-height:80vh">
<div class="dt-modal-head">
<div class="dt-modal-icon res">
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="2" y="2" width="5" height="5" rx="1"/><rect x="9" y="2" width="5" height="5" rx="1"/><rect x="2" y="9" width="5" height="5" rx="1"/><rect x="9" y="9" width="5" height="5" rx="1"/></svg>
</div>
<div class="dt-modal-meta">
<div class="dt-modal-title" id="dt-presets-modal-title">Response Transform Presets</div>
<div class="dt-modal-url">Save & manage transform presets</div>
</div>
</div>
<div class="dt-modal-body" id="dt-presets-body">
<!-- List view -->
<div id="dt-presets-list-view" class="dt-modal-inner" style="gap:10px">
<div class="dt-presets-list" id="dt-presets-list"></div>
<div class="dt-presets-empty" id="dt-presets-empty" style="text-align:center;color:var(--mu);padding:32px 20px;display:none">No presets saved yet.</div>
<div class="dt-preset-load-hint" id="dt-preset-load-hint" style="display:none;font-size:11px;color:var(--mu);background:var(--am-bg);border:1px solid var(--am-bd);border-radius:6px;padding:8px 12px;line-height:1.5">
<strong style="color:var(--am)">Load</strong> puts the preset's JS code into the transform editor — it only takes effect once you're in the response intercept modal and click Run or Apply.
</div>
</div>
<!-- Editor view (save / edit) -->
<div id="dt-preset-editor-view" class="dt-modal-inner" style="display:none;gap:14px">
<div>
<div class="dt-flabel" style="margin-bottom:6px">Preset Name</div>
<input class="dt-preset-name-input" id="dt-pe-name" type="text" placeholder="My Transform" spellcheck="false">
</div>
<div>
<div class="dt-flabel" style="margin-bottom:4px">URL Patterns <span style="font-weight:400;color:var(--mu)">(regex — leave empty to match all)</span></div>
<div class="dt-pe-patterns-list" id="dt-pe-patterns"></div>
<button class="dt-pe-add-pattern" id="dt-pe-add-pattern">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.8"><line x1="5.5" y1="1" x2="5.5" y2="10"/><line x1="1" y1="5.5" x2="10" y2="5.5"/></svg>
Add pattern
</button>
</div>
</div>
</div>
<div class="dt-modal-foot" id="dt-presets-foot-list">
<button class="dt-foot-btn dt-foot-btn-abort" id="dt-presets-close" style="flex:1">Close</button>
</div>
<div class="dt-modal-foot" id="dt-presets-foot-editor" style="display:none">
<button class="dt-foot-btn dt-foot-btn-abort" id="dt-pe-cancel">Cancel</button>
<button class="dt-foot-btn dt-foot-btn-send" id="dt-pe-save">Save Preset</button>
</div>
</div>
</div>
<!-- Mini Save Preset — last in DOM, always on top -->
<div id="dt-save-preset-overlay" class="dt-overlay dt-mini-overlay">
<div class="dt-mini-modal">
<div class="dt-mini-modal-head">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" stroke="currentColor" stroke-width="1.6"><rect x="1" y="1" width="12" height="12" rx="1.5"/><rect x="4" y="1" width="6" height="4" rx="0.5"/><rect x="3.5" y="7.5" width="7" height="4.5" rx="0.5"/></svg>
Save Preset
</div>
<div class="dt-mini-modal-body">
<div class="dt-flabel" style="margin-bottom:5px">Preset Name</div>
<input class="dt-preset-name-input" id="dt-spe-name" type="text" placeholder="My Transform" spellcheck="false" style="margin-bottom:12px">
<div class="dt-flabel" style="margin-bottom:4px">URL Patterns <span style="font-weight:400;color:var(--mu)">(regex — empty = match all)</span></div>
<div class="dt-pe-patterns-list" id="dt-spe-patterns"></div>
<button class="dt-pe-add-pattern" id="dt-spe-add-pattern">
<svg width="11" height="11" viewBox="0 0 11 11" fill="none" stroke="currentColor" stroke-width="1.8"><line x1="5.5" y1="1" x2="5.5" y2="10"/><line x1="1" y1="5.5" x2="10" y2="5.5"/></svg>
Add pattern
</button>
</div>
<div class="dt-modal-foot" style="padding:12px 16px;gap:8px">
<button class="dt-foot-btn dt-foot-btn-abort" id="dt-spe-cancel">Cancel</button>
<button class="dt-foot-btn dt-foot-btn-send" id="dt-spe-save">Save</button>
</div>
</div>
</div>
`;