Skip to content
Open
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
4 changes: 2 additions & 2 deletions debug_toolbar/static/debug_toolbar/css/toolbar.css
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/* Variable definitions */
:root {
:host {
/* Font families are the same as in Django admin/css/base.css */
--djdt-font-family-primary:
"Segoe UI", system-ui, Roboto, "Helvetica Neue", Arial, sans-serif,
Expand All @@ -13,7 +13,7 @@
"Noto Color Emoji";
}

:root,
:host,
#djDebug[data-theme="light"] {
--djdt-font-color: black;
--djdt-background-color: white;
Expand Down
8 changes: 4 additions & 4 deletions debug_toolbar/static/debug_toolbar/js/history.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { $$, ajaxForm, replaceToolbarState } from "./utils.js";
import { $$, ajaxForm, getDebugElement, replaceToolbarState } from "./utils.js";

const djDebug = document.getElementById("djDebug");
const djDebug = getDebugElement();

function difference(setA, setB) {
const _difference = new Set(setA);
Expand All @@ -19,7 +19,7 @@ function pluckData(nodes, key) {

function refreshHistory() {
const formTarget = djDebug.querySelector(".refreshHistory");
const container = document.getElementById("djdtHistoryRequests");
const container = djDebug.querySelector("#djdtHistoryRequests");
const oldIds = new Set(
pluckData(
container.querySelectorAll("tr[data-request-id]"),
Expand Down Expand Up @@ -85,7 +85,7 @@ function switchHistory(newRequestId) {

ajaxForm(formTarget).then((data) => {
if (Object.keys(data).length === 0) {
const container = document.getElementById("djdtHistoryRequests");
const container = djDebug.querySelector("#djdtHistoryRequests");
container.querySelector(
`button[data-request-id="${newRequestId}"]`
).innerHTML = "Switch [EXPIRED]";
Expand Down
9 changes: 5 additions & 4 deletions debug_toolbar/static/debug_toolbar/js/timer.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { $$ } from "./utils.js";
import { $$, getDebugElement } from "./utils.js";

const djDebug = getDebugElement();

function insertBrowserTiming() {
const timingOffset = performance.timing.navigationStart;
Expand Down Expand Up @@ -58,10 +60,10 @@ function insertBrowserTiming() {
tbody.appendChild(row);
}

const browserTiming = document.getElementById("djDebugBrowserTiming");
const browserTiming = djDebug.querySelector("#djDebugBrowserTiming");
// Determine if the browser timing section has already been rendered.
if (browserTiming.classList.contains("djdt-hidden")) {
const tbody = document.getElementById("djDebugBrowserTimingTableBody");
const tbody = djDebug.querySelector("#djDebugBrowserTimingTableBody");
// This is a reasonably complete and ordered set of timing periods (2 params) and events (1 param)
addRow(tbody, "domainLookupStart", "domainLookupEnd");
addRow(tbody, "connectStart", "connectEnd");
Expand All @@ -75,7 +77,6 @@ function insertBrowserTiming() {
}
}

const djDebug = document.getElementById("djDebug");
// Insert the browser timing now since it's possible for this
// script to miss the initial panel load event.
insertBrowserTiming();
Expand Down
52 changes: 26 additions & 26 deletions debug_toolbar/static/debug_toolbar/js/toolbar.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
import { $$, ajax, debounce, replaceToolbarState } from "./utils.js";
import {
$$,
ajax,
debounce,
getDebugElement,
replaceToolbarState,
} from "./utils.js";

function onKeyDown(event) {
if (event.keyCode === 27) {
djdt.hideOneLevel();
}
}

function getDebugElement() {
// Fetch the debug element from the DOM.
// This is used to avoid writing the element's id
// everywhere the element is being selected. A fixed reference
// to the element should be avoided because the entire DOM could
// be reloaded such as via HTMX boosting.
return document.getElementById("djDebug");
}

const djdt = {
handleDragged: false,
needUpdateOnFetch: false,
Expand All @@ -27,7 +24,7 @@ const djdt = {
return;
}
const panelId = this.className;
const current = document.getElementById(panelId);
const current = djDebug.querySelector(`#${panelId}`);
if ($$.visible(current)) {
djdt.hidePanels();
} else {
Expand Down Expand Up @@ -103,7 +100,7 @@ const djdt = {
}

ajax(url, ajaxData).then((data) => {
const win = document.getElementById("djDebugWindow");
const win = djDebug.querySelector("#djDebugWindow");
win.innerHTML = data.content;
$$.show(win);
});
Expand All @@ -116,7 +113,7 @@ const djdt = {
const toggleClose = "-";
const openMe = this.textContent === toggleOpen;
const name = this.dataset.toggleName;
const container = document.getElementById(`${name}_${id}`);
const container = djDebug.querySelector(`#${name}_${id}`);
for (const el of container.querySelectorAll(".djDebugCollapsed")) {
$$.toggle(el, openMe);
}
Expand Down Expand Up @@ -156,7 +153,7 @@ const djdt = {
});
let startPageY;
let baseY;
const handle = document.getElementById("djDebugToolbarHandle");
const handle = djDebug.querySelector("#djDebugToolbarHandle");
function onHandleMove(event) {
// Chrome can send spurious mousemove events, so don't do anything unless the
// cursor really moved. Otherwise, it will be impossible to expand the toolbar
Expand Down Expand Up @@ -240,16 +237,17 @@ const djdt = {
},
hidePanels() {
const djDebug = getDebugElement();
$$.hide(document.getElementById("djDebugWindow"));
$$.hide(djDebug.querySelector("#djDebugWindow"));
for (const el of djDebug.querySelectorAll(".djdt-panelContent")) {
$$.hide(el);
}
for (const el of document.querySelectorAll("#djDebugToolbar li")) {
for (const el of djDebug.querySelectorAll("#djDebugToolbar li")) {
el.classList.remove("djdt-active");
}
},
ensureHandleVisibility() {
const handle = document.getElementById("djDebugToolbarHandle");
const djDebug = getDebugElement();
const handle = djDebug.querySelector("#djDebugToolbarHandle");
// set handle position
const handleTop = Math.min(
localStorage.getItem("djdt.top") || 265,
Expand All @@ -258,11 +256,12 @@ const djdt = {
handle.style.top = `${handleTop}px`;
},
hideToolbar() {
const djDebug = getDebugElement();
djdt.hidePanels();

$$.hide(document.getElementById("djDebugToolbar"));
$$.hide(djDebug.querySelector("#djDebugToolbar"));

const handle = document.getElementById("djDebugToolbarHandle");
const handle = djDebug.querySelector("#djDebugToolbarHandle");
$$.show(handle);
djdt.ensureHandleVisibility();
window.addEventListener("resize", djdt.ensureHandleVisibility);
Expand All @@ -271,11 +270,12 @@ const djdt = {
localStorage.setItem("djdt.show", "false");
},
hideOneLevel() {
const win = document.getElementById("djDebugWindow");
const djDebug = getDebugElement();
const win = djDebug.querySelector("#djDebugWindow");
if ($$.visible(win)) {
$$.hide(win);
} else {
const toolbar = document.getElementById("djDebugToolbar");
const toolbar = djDebug.querySelector("#djDebugToolbar");
if (toolbar.querySelector("li.djdt-active")) {
djdt.hidePanels();
} else {
Expand All @@ -284,16 +284,16 @@ const djdt = {
}
},
showToolbar() {
const djDebug = getDebugElement();
document.addEventListener("keydown", onKeyDown);
$$.show(document.getElementById("djDebug"));
$$.hide(document.getElementById("djDebugToolbarHandle"));
$$.show(document.getElementById("djDebugToolbar"));
$$.show(djDebug);
$$.hide(djDebug.querySelector("#djDebugToolbarHandle"));
$$.show(djDebug.querySelector("#djDebugToolbar"));
localStorage.setItem("djdt.show", "true");
window.removeEventListener("resize", djdt.ensureHandleVisibility);
},
updateOnAjax() {
const sidebarUrl =
document.getElementById("djDebug").dataset.sidebarUrl;
const sidebarUrl = getDebugElement().dataset.sidebarUrl;
const slowjax = debounce(ajax, 200);

function handleAjaxResponse(requestId) {
Expand Down
21 changes: 16 additions & 5 deletions debug_toolbar/static/debug_toolbar/js/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ const $$ = {
},
};

function getDebugElement() {
// Fetch the debug element from the DOM.
// This is used to avoid writing the element's id
// everywhere the element is being selected. A fixed reference
// to the element should be avoided because the entire DOM could
// be reloaded such as via HTMX boosting.
const root = document.getElementById("djDebugRoot").shadowRoot;
return root.querySelector("#djDebug");
}

function ajax(url, init) {
return fetch(url, Object.assign({ credentials: "same-origin" }, init))
.then((response) => {
Expand All @@ -89,7 +99,8 @@ function ajax(url, init) {
);
})
.catch((error) => {
const win = document.getElementById("djDebugWindow");
const djDebug = getDebugElement();
const win = djDebug.querySelector("#djDebugWindow");
win.innerHTML = `<div class="djDebugPanelTitle"><h3>${error.message}</h3><button type="button" class="djDebugClose">»</button></div>`;
$$.show(win);
throw error;
Expand All @@ -110,14 +121,14 @@ function ajaxForm(element) {
}

function replaceToolbarState(newRequestId, data) {
const djDebug = document.getElementById("djDebug");
const djDebug = getDebugElement();
djDebug.setAttribute("data-request-id", newRequestId);
// Check if response is empty, it could be due to an expired requestId.
for (const panelId of Object.keys(data)) {
const panel = document.getElementById(panelId);
const panel = djDebug.querySelector(`#${panelId}`);
if (panel) {
panel.outerHTML = data[panelId].content;
document.getElementById(`djdt-${panelId}`).outerHTML =
djDebug.querySelector(`#djdt-${panelId}`).outerHTML =
data[panelId].button;
}
}
Expand All @@ -141,4 +152,4 @@ function debounce(func, delay) {
};
}

export { $$, ajax, ajaxForm, replaceToolbarState, debounce };
export { $$, getDebugElement, ajax, ajaxForm, replaceToolbarState, debounce };
81 changes: 43 additions & 38 deletions debug_toolbar/templates/debug_toolbar/base.html
Original file line number Diff line number Diff line change
@@ -1,43 +1,48 @@
{% load i18n static %}
{% block css %}
<link{% if toolbar.csp_nonce %} nonce="{{ toolbar.csp_nonce }}"{% endif %} rel="stylesheet" href="{% static 'debug_toolbar/css/print.css' %}" media="print">
<link{% if toolbar.csp_nonce %} nonce="{{ toolbar.csp_nonce }}"{% endif %} rel="stylesheet" href="{% static 'debug_toolbar/css/toolbar.css' %}">
{% endblock css %}
{% block js %}
<script{% if toolbar.csp_nonce %} nonce="{{ toolbar.csp_nonce }}"{% endif %} type="module" src="{% static 'debug_toolbar/js/toolbar.js' %}" async></script>
{% endblock js %}
<div id="djDebug" class="djdt-hidden" dir="ltr"
{% if not toolbar.should_render_panels %}
data-request-id="{{ toolbar.request_id }}"
data-render-panel-url="{% url 'djdt:render_panel' %}"
{% endif %}
{% url 'djdt:history_sidebar' as history_url %}
{% if history_url %}
data-sidebar-url="{{ history_url }}"
{% endif %}
data-default-show="{% if toolbar.config.SHOW_COLLAPSED %}false{% else %}true{% endif %}"
{{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }} data-update-on-fetch="{{ toolbar.config.UPDATE_ON_FETCH }}">
<div class="djdt-hidden" id="djDebugToolbar">
<ul id="djDebugPanelList">
<li><a id="djHideToolBarButton" href="#" title="{% translate 'Hide toolbar' %}">{% translate "Hide" %} »</a></li>
<li>
<a id="djToggleThemeButton" href="#" title="{% translate 'Toggle Theme' %}">
{% translate "Toggle Theme" %} {% include "debug_toolbar/includes/theme_selector.html" %}
</a>
</li>
<div id="djDebugRoot" {{ toolbar.config.ROOT_TAG_EXTRA_ATTRS|safe }}>
<template shadowrootmode="open">
{% block css %}
<link{% if toolbar.csp_nonce %} nonce="{{ toolbar.csp_nonce }}"{% endif %} rel="stylesheet" href="{% static 'debug_toolbar/css/print.css' %}" media="print">
<link{% if toolbar.csp_nonce %} nonce="{{ toolbar.csp_nonce }}"{% endif %} rel="stylesheet" href="{% static 'debug_toolbar/css/toolbar.css' %}">
{% endblock css %}
{% block js %}
<script{% if toolbar.csp_nonce %} nonce="{{ toolbar.csp_nonce }}"{% endif %} type="module" src="{% static 'debug_toolbar/js/toolbar.js' %}" async></script>
{% endblock js %}
<div id="djDebug" class="djdt-hidden" dir="ltr"
{% if not toolbar.should_render_panels %}
data-request-id="{{ toolbar.request_id }}"
data-render-panel-url="{% url 'djdt:render_panel' %}"
{% endif %}
{% url 'djdt:history_sidebar' as history_url %}
{% if history_url %}
data-sidebar-url="{{ history_url }}"
{% endif %}
data-default-show="{% if toolbar.config.SHOW_COLLAPSED %}false{% else %}true{% endif %}"
data-update-on-fetch="{{ toolbar.config.UPDATE_ON_FETCH }}">
<link{% if toolbar.csp_nonce %} nonce="{{ toolbar.csp_nonce }}"{% endif %} rel="stylesheet" href="{% static 'debug_toolbar/css/toolbar.css' %}">

<div class="djdt-hidden" id="djDebugToolbarHandle">
<div title="{% translate 'Show toolbar' %}" id="djShowToolBarButton">
<span id="djShowToolBarD">D</span><span id="djShowToolBarJ">J</span>DT
</div>
</div>
<div class="djdt-hidden" id="djDebugToolbar">
<ul id="djDebugPanelList">
<li><a id="djHideToolBarButton" href="#" title="{% translate 'Hide toolbar' %}">{% translate "Hide" %} »</a></li>
<li>
<a id="djToggleThemeButton" href="#" title="{% translate 'Toggle Theme' %}">
{% translate "Toggle Theme" %} {% include "debug_toolbar/includes/theme_selector.html" %}
</a>
</li>
{% for panel in toolbar.panels %}
{% include "debug_toolbar/includes/panel_button.html" %}
{% endfor %}
</ul>
</div>
{% for panel in toolbar.panels %}
{% include "debug_toolbar/includes/panel_button.html" %}
{% include "debug_toolbar/includes/panel_content.html" %}
{% endfor %}
</ul>
</div>
<div class="djdt-hidden" id="djDebugToolbarHandle">
<div title="{% translate 'Show toolbar' %}" id="djShowToolBarButton">
<span id="djShowToolBarD">D</span><span id="djShowToolBarJ">J</span>DT
<div id="djDebugWindow" class="djdt-panelContent djdt-hidden"></div>
</div>
</div>

{% for panel in toolbar.panels %}
{% include "debug_toolbar/includes/panel_content.html" %}
{% endfor %}
<div id="djDebugWindow" class="djdt-panelContent djdt-hidden"></div>
</template>
</div>
2 changes: 1 addition & 1 deletion docs/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,7 @@ could add a **debug_toolbar/base.html** template override to your project:

{% block css %}{{ block.super }}
<style>
:root {
:host {
--djdt-font-family-primary: 'Roboto', sans-serif;
}
</style>
Expand Down
4 changes: 2 additions & 2 deletions docs/panels.rst
Original file line number Diff line number Diff line change
Expand Up @@ -444,14 +444,14 @@ Events

.. code-block:: javascript
import { $$ } from "./utils.js";
import { $$, getDebugElement } from "./utils.js";
function addCustomMetrics() {
// Logic to process/add custom metrics here.
// Be sure to cover the case of this function being called twice
// due to file being loaded asynchronously.
}
const djDebug = document.getElementById("djDebug");
const djDebug = getDebugElement();
$$.onPanelRender(djDebug, "CustomPanel", addCustomMetrics);
// Since a panel's scripts are loaded asynchronously, it's possible that
// the above statement would occur after the djdt.panel.render event has
Expand Down
Loading