DevTools Sidebar — HTML

HTML template builders for DevTools Sidebar

بۇ قوليازمىنى بىۋاسىتە قاچىلاشقا بولمايدۇ. بۇ باشقا قوليازمىلارنىڭ ئىشلىتىشى ئۈچۈن تەمىنلەنگەن ئامبار بولۇپ، ئىشلىتىش ئۈچۈن مېتا كۆرسەتمىسىگە قىستۇرىدىغان كود: // @require https://update.greasyfork.org/scripts/580257/1837616/DevTools%20Sidebar%20%E2%80%94%20HTML.js

You will need to install an extension such as Tampermonkey, Greasemonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

You will need to install an extension such as Tampermonkey or Userscripts to install this script.

You will need to install an extension such as Tampermonkey to install this script.

You will need to install a user script manager extension to install this script.

(I already have a user script manager, let me install it!)

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install an extension such as Stylus to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

You will need to install a user style manager extension to install this style.

(I already have a user style manager, let me install it!)

// ==UserScript==
// @name         DevTools Sidebar — HTML
// @namespace    http://tampermonkey.net/
// @version      7.1.0
// @description  HTML template builders for DevTools Sidebar
// @author       MrNosferatu
// ==/UserScript==

// ─── Build sidebar interceptor panel ─────────────────────────────────────────
function buildInterceptorPanel(ns) {
  const isRes = ns === 'res';
  return `
    <div class="dt-section">
      <div class="dt-slabel">Status</div>
      <div class="dt-row">
        <div class="dt-row-info">
          <div class="dt-row-label">Enable ${isRes?'Response':'Request'} Interceptor</div>
          <div class="dt-row-sub">${isRes?'Edit API responses before the page receives them':'Halt & inspect outgoing requests'}</div>
        </div>
        <label class="dt-toggle"><input type="checkbox" id="dt-${ns}-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-${ns}-qdot"></div><span class="dt-queue-text" id="dt-${ns}-qtext">No ${isRes?'responses':'requests'} waiting</span></div>
    </div>
    <div class="dt-section">
      <div class="dt-slabel">Intercept Methods</div>
      <div class="dt-row-sub" style="margin-bottom:10px;font-size:11px;color:var(--mu)">${isRes?'Intercept responses for these methods.':'GET edits URL params; others edit body.'}</div>
      <div class="dt-method-grid">${ALL_METHODS.map(m=>`<input type="checkbox" class="dt-method-check" id="dt-${ns}-m-${m}" data-m="${m}"><label class="dt-method-pill" for="dt-${ns}-m-${m}">${m}</label>`).join('')}</div>
    </div>
    <div class="dt-section">
      <div class="dt-slabel">Persistence</div>
      <div class="dt-row">
        <div class="dt-row-info">
          <div class="dt-row-label">Stay enabled on reload</div>
          <div class="dt-row-sub">Remember state across page refreshes</div>
        </div>
        <label class="dt-toggle"><input type="checkbox" id="dt-${ns}-persist"><div class="dt-toggle-track"><div class="dt-toggle-thumb"></div></div></label>
      </div>
      <div class="dt-persist-note" id="dt-${ns}-pnote">Resets on each page load by default.</div>
    </div>
    <div class="dt-section">
      <div class="dt-slabel">Capture Mode</div>
      <div class="dt-row" style="margin-bottom:0">
        <div class="dt-row-info"><div class="dt-row-label">URL Matching</div><div class="dt-row-sub">Auto captures all; Manual filters by regex</div></div>
        <div class="dt-chip" id="dt-${ns}-chip">Auto</div>
      </div>
      <div class="dt-mode-group">
        <button class="dt-mode-btn active" data-mode="auto" data-ns="${ns}">Auto — All</button>
        <button class="dt-mode-btn" data-mode="manual" data-ns="${ns}">Manual — Regex</button>
      </div>
      <div class="dt-regex-wrap" id="dt-${ns}-rwrap">
        <div class="dt-flabel" style="margin-top:12px">URL Pattern</div>
        <div class="dt-regex-field">
          <span class="dt-regex-delim">/</span>
          <input class="dt-regex-input" id="dt-${ns}-regex" type="text" placeholder="api\\/v\\d+\\/.*" spellcheck="false">
          <span class="dt-regex-delim">/</span>
          <div class="dt-regex-dot" id="dt-${ns}-rdot"></div>
        </div>
      </div>
    </div>
  `;
}

// ─── Sidebar settings panel HTML ──────────────────────────────────────────────
function buildSidebarSettingsPanel() {
  return `
    <div class="dt-section">
      <div class="dt-slabel">Theme</div>
      <div class="dt-theme-grid" id="dt-sb-theme-grid"></div>
    </div>
    <div class="dt-section">
      <div class="dt-slabel">Font</div>
      <div class="dt-font-list" id="dt-sb-font-list"></div>
    </div>
    <div class="dt-section">
      <div class="dt-slabel">Font Size</div>
      <div class="dt-size-row">
        <input type="range" class="dt-size-slider" id="dt-sb-size-slider" min="9" max="18" step="1">
        <span class="dt-size-val" id="dt-sb-size-val">12px</span>
      </div>
    </div>
    <div class="dt-section">
      <div class="dt-slabel">Custom Colors</div>
      <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 class="dt-section">
      <div class="dt-slabel">Preview</div>
      <div class="dt-ed-preview" id="dt-sb-preview">
        <div class="dt-ed-preview-inner" id="dt-sb-preview-inner">{"message": "Hello, DevTools!",\n "status": 200,\n "data": [1, 2, 3]}</div>
      </div>
    </div>
    <div class="dt-section">
      <div class="dt-settings-apply-row">
        <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>
    </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>
  `;
}

// ─── Full HTML ────────────────────────────────────────────────────────────────
const HTML = `
  <div id="dt-tab" title="DevTools Sidebar">
    <div id="dt-tab-inner">
      <div id="dt-tab-dot"></div><div id="dt-tab-label">DevTools</div><div id="dt-tab-chevron">‹</div>
    </div>
  </div>

  <div id="dt-sidebar">
    <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="req">Request</button>
      <button class="dt-nav-btn" data-panel="res">Response</button>
      <button class="dt-nav-btn" data-panel="settings">Settings</button>
      <button class="dt-nav-btn" data-panel="about">About</button>
    </div>
    <div class="dt-scroll">
      <div class="dt-panel active" id="dt-panel-req">${buildInterceptorPanel('req')}</div>
      <div class="dt-panel" id="dt-panel-res">${buildInterceptorPanel('res')}</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 class="dt-flabel">Request Payload</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>
            </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">✎ Manual Edit</button>
            <button class="dt-res-tab" data-restab="gui">⊞ GUI Extract</button>
            <button class="dt-res-tab" data-restab="code">⌨ JS Transform</button>
          </div>
          <div id="dt-res-manual" class="dt-payload-section">
            <div class="dt-flabel">Response Body</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&#10;// res = { url, method, status }&#10;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">▶ Run Transform</button>
              <div class="dt-transform-err" id="dt-res-transform-err"></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>
            </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>
`;