diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index 1b7cd30c3..667846cdc 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -216,4 +216,4 @@ jobs:
python -m pip install --upgrade tox
- name: Test with tox
- run: tox -e docs,style,readme
+ run: tox -e docs,style,packaging
diff --git a/.gitignore b/.gitignore
index 564e7b8cc..df5a2d10c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
*.pyc
*.DS_Store
*~
+.idea
build
.coverage
dist
diff --git a/README.rst b/README.rst
index 3a3304780..8bea757ad 100644
--- a/README.rst
+++ b/README.rst
@@ -34,7 +34,7 @@ Here's a screenshot of the toolbar in action:
In addition to the built-in panels, a number of third-party panels are
contributed by the community.
-The current stable version of the Debug Toolbar is 3.2.1. It works on
+The current stable version of the Debug Toolbar is 3.2.2. It works on
Django ≥ 2.2.
Documentation, including installation and configuration instructions, is
diff --git a/debug_toolbar/__init__.py b/debug_toolbar/__init__.py
index 84eea7d7a..93c78c7f0 100644
--- a/debug_toolbar/__init__.py
+++ b/debug_toolbar/__init__.py
@@ -1,12 +1,15 @@
+import django
+
__all__ = ["VERSION"]
# Do not use pkg_resources to find the version but set it here directly!
# see issue #1446
-VERSION = "3.2.1"
+VERSION = "3.2.2"
# Code that discovers files or modules in INSTALLED_APPS imports this module.
urls = "debug_toolbar.toolbar", "djdt"
-default_app_config = "debug_toolbar.apps.DebugToolbarConfig"
+if django.VERSION < (3, 2):
+ default_app_config = "debug_toolbar.apps.DebugToolbarConfig"
diff --git a/debug_toolbar/locale/sk/LC_MESSAGES/django.mo b/debug_toolbar/locale/sk/LC_MESSAGES/django.mo
index a26e3cc7b..e6af7c505 100644
Binary files a/debug_toolbar/locale/sk/LC_MESSAGES/django.mo and b/debug_toolbar/locale/sk/LC_MESSAGES/django.mo differ
diff --git a/debug_toolbar/locale/sk/LC_MESSAGES/django.po b/debug_toolbar/locale/sk/LC_MESSAGES/django.po
index 2c8a9c7e3..ef6657953 100644
--- a/debug_toolbar/locale/sk/LC_MESSAGES/django.po
+++ b/debug_toolbar/locale/sk/LC_MESSAGES/django.po
@@ -1,7 +1,7 @@
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
-#
-#
+#
+#
# Translators:
# Juraj Bubniak {{ store_context.toolbar.stats.HistoryPanel.status_code|escape }}%s
"
msgid "%(num_receivers)d receiver of 1 signal"
msgid_plural "%(num_receivers)d receivers of 1 signal"
msgstr[0] "%(num_receivers)d príjemca 1 signálu"
-msgstr[1] "%(num_receivers)d príjemcov 1 signálu"
+msgstr[1] "%(num_receivers)d príjemcovia 1 signálu"
msgstr[2] "%(num_receivers)d príjemcov 1 signálu"
+msgstr[3] "%(num_receivers)d príjemcov 1 signálu"
#: panels/signals.py:48
#, python-format
msgid "%(num_receivers)d receiver of %(num_signals)d signals"
msgid_plural "%(num_receivers)d receivers of %(num_signals)d signals"
-msgstr[0] "%(num_receivers)d príjemca %(num_signals)d signálov"
+msgstr[0] "%(num_receivers)d príjemca %(num_signals)d signálu"
msgstr[1] "%(num_receivers)d príjemcov %(num_signals)d signálov"
-msgstr[2] "%(num_receivers)d príjemcov %(num_signals)d signálov"
+msgstr[2] "%(num_receivers)d príjemcu %(num_signals)d signálu"
+msgstr[3] "%(num_receivers)d príjemcov %(num_signals)d signálov"
#: panels/signals.py:53
msgid "Signals"
@@ -133,8 +137,9 @@ msgstr "Statické súbory"
msgid "%(num_used)s file used"
msgid_plural "%(num_used)s files used"
msgstr[0] "%(num_used)s použitý súbor"
-msgstr[1] "%(num_used)s použitých súborov"
+msgstr[1] "%(num_used)s použité súbory"
msgstr[2] "%(num_used)s použitých súborov"
+msgstr[3] "%(num_used)s použitých súborov"
#: panels/timer.py:23
#, python-format
@@ -146,10 +151,8 @@ msgstr "CPU: %(cum)0.2fms (%(total)0.2fms)"
msgid "Total: %0.2fms"
msgstr "Celkovo: %0.2fms"
-#: panels/timer.py:34 templates/debug_toolbar/panels/logging.html:7
-#: templates/debug_toolbar/panels/sql_explain.html:11
-#: templates/debug_toolbar/panels/sql_profile.html:12
-#: templates/debug_toolbar/panels/sql_select.html:11
+#: panels/timer.py:34 templates/debug_toolbar/panels/logging.html:7 templates/debug_toolbar/panels/sql_explain.html:11
+#: templates/debug_toolbar/panels/sql_profile.html:12 templates/debug_toolbar/panels/sql_select.html:11
msgid "Time"
msgstr "Čas"
@@ -228,11 +231,11 @@ msgstr "Nečinný"
#: panels/sql/panel.py:38
msgid "Active"
-msgstr "Akcia"
+msgstr "Aktívne"
#: panels/sql/panel.py:39
msgid "In transaction"
-msgstr "Stav transakcie:"
+msgstr "V transakcii"
#: panels/sql/panel.py:40
msgid "In error"
@@ -285,9 +288,8 @@ msgstr "Poloha:"
#: templates/debug_toolbar/redirect.html:10
msgid ""
-"The Django Debug Toolbar has intercepted a redirect to the above URL for "
-"debug viewing purposes. You can click the above link to continue with the "
-"redirect as normal."
+"The Django Debug Toolbar has intercepted a redirect to the above URL for debug viewing purposes. You can click the above link to continue with the redirect "
+"as normal."
msgstr "Django Debug Toolbar zachytil presmerovanie na vyššie uvedenú URL pre účely ladenia. Pre normálne presmerovanie môžete kliknúť na vyššie uvedený odkaz."
#: templates/debug_toolbar/panels/cache.html:2
@@ -318,8 +320,7 @@ msgstr "Príkazy"
msgid "Calls"
msgstr "Volania"
-#: templates/debug_toolbar/panels/cache.html:43
-#: templates/debug_toolbar/panels/sql.html:20
+#: templates/debug_toolbar/panels/cache.html:43 templates/debug_toolbar/panels/sql.html:20
msgid "Time (ms)"
msgstr "Čas (ms)"
@@ -327,13 +328,11 @@ msgstr "Čas (ms)"
msgid "Type"
msgstr "Typ"
-#: templates/debug_toolbar/panels/cache.html:45
-#: templates/debug_toolbar/panels/request.html:8
+#: templates/debug_toolbar/panels/cache.html:45 templates/debug_toolbar/panels/request.html:8
msgid "Arguments"
msgstr "Argumenty"
-#: templates/debug_toolbar/panels/cache.html:46
-#: templates/debug_toolbar/panels/request.html:9
+#: templates/debug_toolbar/panels/cache.html:46 templates/debug_toolbar/panels/request.html:9
msgid "Keyword arguments"
msgstr "Kľúčové argumenty"
@@ -345,21 +344,13 @@ msgstr "Backend"
msgid "Request headers"
msgstr "Hlavičky požiadavky"
-#: templates/debug_toolbar/panels/headers.html:8
-#: templates/debug_toolbar/panels/headers.html:27
-#: templates/debug_toolbar/panels/headers.html:48
+#: templates/debug_toolbar/panels/headers.html:8 templates/debug_toolbar/panels/headers.html:27 templates/debug_toolbar/panels/headers.html:48
msgid "Key"
msgstr "Kľúč"
-#: templates/debug_toolbar/panels/headers.html:9
-#: templates/debug_toolbar/panels/headers.html:28
-#: templates/debug_toolbar/panels/headers.html:49
-#: templates/debug_toolbar/panels/request.html:33
-#: templates/debug_toolbar/panels/request.html:59
-#: templates/debug_toolbar/panels/request.html:85
-#: templates/debug_toolbar/panels/request.html:110
-#: templates/debug_toolbar/panels/settings.html:6
-#: templates/debug_toolbar/panels/timer.html:11
+#: templates/debug_toolbar/panels/headers.html:9 templates/debug_toolbar/panels/headers.html:28 templates/debug_toolbar/panels/headers.html:49
+#: templates/debug_toolbar/panels/request.html:33 templates/debug_toolbar/panels/request.html:59 templates/debug_toolbar/panels/request.html:85
+#: templates/debug_toolbar/panels/request.html:110 templates/debug_toolbar/panels/settings.html:6 templates/debug_toolbar/panels/timer.html:11
msgid "Value"
msgstr "Hodnota"
@@ -372,9 +363,7 @@ msgid "WSGI environ"
msgstr "WSGI prostredie"
#: templates/debug_toolbar/panels/headers.html:43
-msgid ""
-"Since the WSGI environ inherits the environment of the server, only a "
-"significant subset is shown below."
+msgid "Since the WSGI environ inherits the environment of the server, only a significant subset is shown below."
msgstr "Keďže WSGI prostredie dedí z prostredia servera, je nižšie zobrazená iba významná podmnožina."
#: templates/debug_toolbar/panels/logging.html:6
@@ -389,8 +378,7 @@ msgstr "Kanál"
msgid "Message"
msgstr "Správa"
-#: templates/debug_toolbar/panels/logging.html:10
-#: templates/debug_toolbar/panels/staticfiles.html:45
+#: templates/debug_toolbar/panels/logging.html:10 templates/debug_toolbar/panels/staticfiles.html:45
msgid "Location"
msgstr "Poloha"
@@ -406,8 +394,7 @@ msgstr "Volanie"
msgid "CumTime"
msgstr "CumTime"
-#: templates/debug_toolbar/panels/profiling.html:7
-#: templates/debug_toolbar/panels/profiling.html:9
+#: templates/debug_toolbar/panels/profiling.html:7 templates/debug_toolbar/panels/profiling.html:9
msgid "Per"
msgstr "Za"
@@ -435,9 +422,7 @@ msgstr "URL meno"
msgid "Cookies"
msgstr "Cookies"
-#: templates/debug_toolbar/panels/request.html:32
-#: templates/debug_toolbar/panels/request.html:58
-#: templates/debug_toolbar/panels/request.html:84
+#: templates/debug_toolbar/panels/request.html:32 templates/debug_toolbar/panels/request.html:58 templates/debug_toolbar/panels/request.html:84
#: templates/debug_toolbar/panels/request.html:109
msgid "Variable"
msgstr "Premenná"
@@ -491,15 +476,15 @@ msgstr "Príjemcovia"
msgid "%(num)s query"
msgid_plural "%(num)s queries"
msgstr[0] "%(num)s dopyt"
-msgstr[1] "%(num)s dopytov"
-msgstr[2] "%(num)s dopytov"
+msgstr[1] "%(num)s dopyty"
+msgstr[2] "%(num)s dopytu"
+msgstr[3] "%(num)s dopytov"
#: templates/debug_toolbar/panels/sql.html:18
msgid "Query"
msgstr "Dopyt"
-#: templates/debug_toolbar/panels/sql.html:19
-#: templates/debug_toolbar/panels/timer.html:36
+#: templates/debug_toolbar/panels/sql.html:19 templates/debug_toolbar/panels/timer.html:36
msgid "Timeline"
msgstr "Časová os"
@@ -527,9 +512,7 @@ msgstr "(neznámy)"
msgid "No SQL queries were recorded during this request."
msgstr "V priebehu tejto požiadavky neboli zaznamenané žiadne SQL dopyty."
-#: templates/debug_toolbar/panels/sql_explain.html:3
-#: templates/debug_toolbar/panels/sql_profile.html:3
-#: templates/debug_toolbar/panels/sql_select.html:3
+#: templates/debug_toolbar/panels/sql_explain.html:3 templates/debug_toolbar/panels/sql_profile.html:3 templates/debug_toolbar/panels/sql_select.html:3
#: templates/debug_toolbar/panels/template_source.html:3
msgid "Back"
msgstr "Späť"
@@ -538,15 +521,11 @@ msgstr "Späť"
msgid "SQL explained"
msgstr "SQL vysvetlené"
-#: templates/debug_toolbar/panels/sql_explain.html:9
-#: templates/debug_toolbar/panels/sql_profile.html:10
-#: templates/debug_toolbar/panels/sql_select.html:9
+#: templates/debug_toolbar/panels/sql_explain.html:9 templates/debug_toolbar/panels/sql_profile.html:10 templates/debug_toolbar/panels/sql_select.html:9
msgid "Executed SQL"
msgstr "Vykonané SQL"
-#: templates/debug_toolbar/panels/sql_explain.html:13
-#: templates/debug_toolbar/panels/sql_profile.html:14
-#: templates/debug_toolbar/panels/sql_select.html:13
+#: templates/debug_toolbar/panels/sql_explain.html:13 templates/debug_toolbar/panels/sql_profile.html:14 templates/debug_toolbar/panels/sql_select.html:13
msgid "Database"
msgstr "Databáza"
@@ -572,18 +551,15 @@ msgid_plural "Static file paths"
msgstr[0] "Cesta k statickému súboru"
msgstr[1] "Cesty k statickým súborom"
msgstr[2] "Cesty k statickým súborom"
+msgstr[3] "Ciest k statickým súborom"
#: templates/debug_toolbar/panels/staticfiles.html:8
#, python-format
msgid "(prefix %(prefix)s)"
msgstr "(prefix %(prefix)s)"
-#: templates/debug_toolbar/panels/staticfiles.html:12
-#: templates/debug_toolbar/panels/staticfiles.html:23
-#: templates/debug_toolbar/panels/staticfiles.html:35
-#: templates/debug_toolbar/panels/templates.html:10
-#: templates/debug_toolbar/panels/templates.html:28
-#: templates/debug_toolbar/panels/templates.html:43
+#: templates/debug_toolbar/panels/staticfiles.html:12 templates/debug_toolbar/panels/staticfiles.html:23 templates/debug_toolbar/panels/staticfiles.html:35
+#: templates/debug_toolbar/panels/templates.html:10 templates/debug_toolbar/panels/templates.html:28 templates/debug_toolbar/panels/templates.html:43
msgid "None"
msgstr "Žiadny"
@@ -593,21 +569,24 @@ msgid_plural "Static file apps"
msgstr[0] "Aplikácia pre statické súbory"
msgstr[1] "Aplikácie pre statické súbory"
msgstr[2] "Aplikácie pre statické súbory"
+msgstr[3] "Aplikácií pre statické súbory"
#: templates/debug_toolbar/panels/staticfiles.html:26
msgid "Static file"
msgid_plural "Static files"
-msgstr[0] ""
-msgstr[1] ""
-msgstr[2] "Statické súbory"
+msgstr[0] "Statický súbor"
+msgstr[1] "Statické súbory"
+msgstr[2] "Statického súbora"
+msgstr[3] "Statických súborov"
#: templates/debug_toolbar/panels/staticfiles.html:40
#, python-format
msgid "%(payload_count)s file"
msgid_plural "%(payload_count)s files"
msgstr[0] "%(payload_count)s súbor"
-msgstr[1] "%(payload_count)s súborov"
-msgstr[2] "%(payload_count)s súborov"
+msgstr[1] "%(payload_count)s súbory"
+msgstr[2] "%(payload_count)s súbora"
+msgstr[3] "%(payload_count)s súborov"
#: templates/debug_toolbar/panels/staticfiles.html:44
msgid "Path"
@@ -621,18 +600,19 @@ msgstr "Zdrojový kód šablóny:"
msgid "Template path"
msgid_plural "Template paths"
msgstr[0] "Cesta k šablóne"
-msgstr[1] "Cesta k šablóne"
-msgstr[2] "Cesta k šablóne"
+msgstr[1] "Cesty k šablóne"
+msgstr[2] "Cesty k šablóne"
+msgstr[3] "Ciest k šablóne"
#: templates/debug_toolbar/panels/templates.html:13
msgid "Template"
msgid_plural "Templates"
msgstr[0] "Šablóna"
-msgstr[1] "Šablóna"
-msgstr[2] "Šablóna"
+msgstr[1] "Šablóny"
+msgstr[2] "Šablóny"
+msgstr[3] "Šablón"
-#: templates/debug_toolbar/panels/templates.html:21
-#: templates/debug_toolbar/panels/templates.html:37
+#: templates/debug_toolbar/panels/templates.html:21 templates/debug_toolbar/panels/templates.html:37
msgid "Toggle context"
msgstr "Prepnúť kontext"
@@ -640,8 +620,9 @@ msgstr "Prepnúť kontext"
msgid "Context processor"
msgid_plural "Context processors"
msgstr[0] "Spracovateľ kontextu"
-msgstr[1] "Spracovateľ kontextu"
-msgstr[2] "Spracovateľ kontextu"
+msgstr[1] "Spracovatelia kontextu"
+msgstr[2] "Spracovateľa kontextu"
+msgstr[3] "Spracovateľov kontextu"
#: templates/debug_toolbar/panels/timer.html:2
msgid "Resource usage"
diff --git a/debug_toolbar/panels/__init__.py b/debug_toolbar/panels/__init__.py
index ec3445c1e..8fd433c63 100644
--- a/debug_toolbar/panels/__init__.py
+++ b/debug_toolbar/panels/__init__.py
@@ -107,6 +107,10 @@ def content(self):
def scripts(self):
"""
Scripts used by the HTML content of the panel when it's displayed.
+
+ When a panel is rendered on the frontend, the ``djdt.panel.render``
+ JavaScript event will be dispatched. The scripts can listen for
+ this event to support dynamic functionality.
"""
return []
diff --git a/debug_toolbar/panels/history/panel.py b/debug_toolbar/panels/history/panel.py
index 4494bbfcd..541c59136 100644
--- a/debug_toolbar/panels/history/panel.py
+++ b/debug_toolbar/panels/history/panel.py
@@ -15,12 +15,18 @@
class HistoryPanel(Panel):
- """ A panel to display History """
+ """A panel to display History"""
title = _("History")
nav_title = _("History")
template = "debug_toolbar/panels/history.html"
+ @property
+ def enabled(self):
+ # Do not show the history panel if the panels are rendered on request
+ # rather than loaded via ajax.
+ return super().enabled and not self.toolbar.should_render_panels()
+
@property
def is_historical(self):
"""The HistoryPanel should not be included in the historical panels."""
@@ -62,6 +68,7 @@ def generate_stats(self, request, response):
{
"request_url": request.get_full_path(),
"request_method": request.method,
+ "status_code": response.status_code,
"data": data,
"time": timezone.now(),
}
diff --git a/debug_toolbar/panels/history/views.py b/debug_toolbar/panels/history/views.py
index b4cf8c835..10b4dcc1a 100644
--- a/debug_toolbar/panels/history/views.py
+++ b/debug_toolbar/panels/history/views.py
@@ -2,6 +2,7 @@
from django.template.loader import render_to_string
from debug_toolbar.decorators import require_show_toolbar, signed_data_view
+from debug_toolbar.forms import SignedDataForm
from debug_toolbar.panels.history.forms import HistoryStoreForm
from debug_toolbar.toolbar import DebugToolbar
@@ -16,6 +17,10 @@ def history_sidebar(request, verified_data):
store_id = form.cleaned_data["store_id"]
toolbar = DebugToolbar.fetch(store_id)
context = {}
+ if toolbar is None:
+ # When the store_id has been popped already due to
+ # RESULTS_CACHE_SIZE
+ return JsonResponse(context)
for panel in toolbar.panels:
if not panel.is_historical:
continue
@@ -40,7 +45,8 @@ def history_refresh(request, verified_data):
if form.is_valid():
requests = []
- for id, toolbar in reversed(DebugToolbar._store.items()):
+ # Convert to list to handle mutations happenening in parallel
+ for id, toolbar in list(DebugToolbar._store.items())[::-1]:
requests.append(
{
"id": id,
@@ -50,7 +56,11 @@ def history_refresh(request, verified_data):
"id": id,
"store_context": {
"toolbar": toolbar,
- "form": HistoryStoreForm(initial={"store_id": id}),
+ "form": SignedDataForm(
+ initial=HistoryStoreForm(
+ initial={"store_id": id}
+ ).initial
+ ),
},
},
),
diff --git a/debug_toolbar/panels/logging.py b/debug_toolbar/panels/logging.py
index f296fc882..a7252c2bb 100644
--- a/debug_toolbar/panels/logging.py
+++ b/debug_toolbar/panels/logging.py
@@ -78,6 +78,6 @@ def process_request(self, request):
def generate_stats(self, request, response):
records = collector.get_collection()
- self._records[threading.currentThread()] = records
+ self._records[threading.current_thread()] = records
collector.clear_collection()
self.record_stats({"records": records})
diff --git a/debug_toolbar/panels/sql/tracking.py b/debug_toolbar/panels/sql/tracking.py
index 75366802c..2ed691344 100644
--- a/debug_toolbar/panels/sql/tracking.py
+++ b/debug_toolbar/panels/sql/tracking.py
@@ -55,9 +55,12 @@ def cursor(*args, **kwargs):
)
def chunked_cursor(*args, **kwargs):
- return state.Wrapper(
- connection._djdt_chunked_cursor(*args, **kwargs), connection, panel
- )
+ # prevent double wrapping
+ # solves https://github.com/jazzband/django-debug-toolbar/issues/1239
+ cursor = connection._djdt_chunked_cursor(*args, **kwargs)
+ if not isinstance(cursor, BaseCursorWrapper):
+ return state.Wrapper(cursor, connection, panel)
+ return cursor
connection.cursor = cursor
connection.chunked_cursor = chunked_cursor
@@ -71,7 +74,11 @@ def unwrap_cursor(connection):
del connection.chunked_cursor
-class ExceptionCursorWrapper:
+class BaseCursorWrapper:
+ pass
+
+
+class ExceptionCursorWrapper(BaseCursorWrapper):
"""
Wraps a cursor and raises an exception on any operation.
Used in Templates panel.
@@ -84,7 +91,7 @@ def __getattr__(self, attr):
raise SQLQueryTriggered()
-class NormalCursorWrapper:
+class NormalCursorWrapper(BaseCursorWrapper):
"""
Wraps a cursor and logs queries.
"""
diff --git a/debug_toolbar/panels/staticfiles.py b/debug_toolbar/panels/staticfiles.py
index 9a15c0f28..ef6af5d3e 100644
--- a/debug_toolbar/panels/staticfiles.py
+++ b/debug_toolbar/panels/staticfiles.py
@@ -118,7 +118,7 @@ def process_request(self, request):
def generate_stats(self, request, response):
used_paths = collector.get_collection()
- self._paths[threading.currentThread()] = used_paths
+ self._paths[threading.current_thread()] = used_paths
self.record_stats(
{
diff --git a/debug_toolbar/static/debug_toolbar/css/toolbar.css b/debug_toolbar/static/debug_toolbar/css/toolbar.css
index 6bbfd3d73..13fbbed0a 100644
--- a/debug_toolbar/static/debug_toolbar/css/toolbar.css
+++ b/debug_toolbar/static/debug_toolbar/css/toolbar.css
@@ -198,7 +198,7 @@
#djDebug #djDebugToolbarHandle {
position: fixed;
- transform: rotate(-90deg);
+ transform: translateY(-100%) rotate(-90deg);
transform-origin: right bottom;
background-color: #fff;
border: 1px solid #111;
diff --git a/debug_toolbar/static/debug_toolbar/js/history.js b/debug_toolbar/static/debug_toolbar/js/history.js
index e20c85438..cc14b2e4f 100644
--- a/debug_toolbar/static/debug_toolbar/js/history.js
+++ b/debug_toolbar/static/debug_toolbar/js/history.js
@@ -7,21 +7,30 @@ $$.on(djDebug, "click", ".switchHistory", function (event) {
const newStoreId = this.dataset.storeId;
const tbody = this.closest("tbody");
- tbody
- .querySelector(".djdt-highlighted")
- .classList.remove("djdt-highlighted");
+ const highlighted = tbody.querySelector(".djdt-highlighted");
+ if (highlighted) {
+ highlighted.classList.remove("djdt-highlighted");
+ }
this.closest("tr").classList.add("djdt-highlighted");
ajaxForm(this).then(function (data) {
djDebug.setAttribute("data-store-id", newStoreId);
- Object.keys(data).forEach(function (panelId) {
- const panel = document.getElementById(panelId);
- if (panel) {
- panel.outerHTML = data[panelId].content;
- document.getElementById("djdt-" + panelId).outerHTML =
- data[panelId].button;
- }
- });
+ // Check if response is empty, it could be due to an expired store_id.
+ if (Object.keys(data).length === 0) {
+ const container = document.getElementById("djdtHistoryRequests");
+ container.querySelector(
+ 'button[data-store-id="' + newStoreId + '"]'
+ ).innerHTML = "Switch [EXPIRED]";
+ } else {
+ Object.keys(data).forEach(function (panelId) {
+ const panel = document.getElementById(panelId);
+ if (panel) {
+ panel.outerHTML = data[panelId].content;
+ document.getElementById("djdt-" + panelId).outerHTML =
+ data[panelId].button;
+ }
+ });
+ }
});
});
@@ -29,12 +38,14 @@ $$.on(djDebug, "click", ".refreshHistory", function (event) {
event.preventDefault();
const container = document.getElementById("djdtHistoryRequests");
ajaxForm(this).then(function (data) {
+ // Remove existing rows first then re-populate with new data
+ container
+ .querySelectorAll("tr[data-store-id]")
+ .forEach(function (node) {
+ node.remove();
+ });
data.requests.forEach(function (request) {
- if (
- !container.querySelector('[data-store-id="' + request.id + '"]')
- ) {
- container.innerHTML = request.content + container.innerHTML;
- }
+ container.innerHTML = request.content + container.innerHTML;
});
});
});
diff --git a/debug_toolbar/static/debug_toolbar/js/timer.js b/debug_toolbar/static/debug_toolbar/js/timer.js
index 1d4ac19d8..70d3fe5a2 100644
--- a/debug_toolbar/static/debug_toolbar/js/timer.js
+++ b/debug_toolbar/static/debug_toolbar/js/timer.js
@@ -1,59 +1,75 @@
-const timingOffset = performance.timing.navigationStart,
- timingEnd = performance.timing.loadEventEnd,
- totalTime = timingEnd - timingOffset;
-function getLeft(stat) {
- return ((performance.timing[stat] - timingOffset) / totalTime) * 100.0;
-}
-function getCSSWidth(stat, endStat) {
- let width =
- ((performance.timing[endStat] - performance.timing[stat]) / totalTime) *
- 100.0;
- // Calculate relative percent (same as sql panel logic)
- width = (100.0 * width) / (100.0 - getLeft(stat));
- return width < 1 ? "2px" : width + "%";
-}
-function addRow(tbody, stat, endStat) {
- const row = document.createElement("tr");
- if (endStat) {
- // Render a start through end bar
- row.innerHTML =
- "" +
- stat.replace("Start", "") +
- " " +
- '' +
- " " +
- (performance.timing[stat] - timingOffset) +
- " (+" +
- (performance.timing[endStat] - performance.timing[stat]) +
- ") ";
- row.querySelector("rect").setAttribute(
- "width",
- getCSSWidth(stat, endStat)
- );
- } else {
- // Render a point in time
- row.innerHTML =
- "" +
- stat +
- " " +
- '' +
- " " +
- (performance.timing[stat] - timingOffset) +
- " ";
- row.querySelector("rect").setAttribute("width", 2);
+import { $$ } from "./utils.js";
+
+function insertBrowserTiming() {
+ console.log(["inserted"]);
+ const timingOffset = performance.timing.navigationStart,
+ timingEnd = performance.timing.loadEventEnd,
+ totalTime = timingEnd - timingOffset;
+ function getLeft(stat) {
+ return ((performance.timing[stat] - timingOffset) / totalTime) * 100.0;
+ }
+ function getCSSWidth(stat, endStat) {
+ let width =
+ ((performance.timing[endStat] - performance.timing[stat]) /
+ totalTime) *
+ 100.0;
+ // Calculate relative percent (same as sql panel logic)
+ width = (100.0 * width) / (100.0 - getLeft(stat));
+ return width < 1 ? "2px" : width + "%";
+ }
+ function addRow(tbody, stat, endStat) {
+ const row = document.createElement("tr");
+ if (endStat) {
+ // Render a start through end bar
+ row.innerHTML =
+ "" +
+ stat.replace("Start", "") +
+ " " +
+ '' +
+ " " +
+ (performance.timing[stat] - timingOffset) +
+ " (+" +
+ (performance.timing[endStat] - performance.timing[stat]) +
+ ") ";
+ row.querySelector("rect").setAttribute(
+ "width",
+ getCSSWidth(stat, endStat)
+ );
+ } else {
+ // Render a point in time
+ row.innerHTML =
+ "" +
+ stat +
+ " " +
+ '' +
+ " " +
+ (performance.timing[stat] - timingOffset) +
+ " ";
+ row.querySelector("rect").setAttribute("width", 2);
+ }
+ row.querySelector("rect").setAttribute("x", getLeft(stat));
+ tbody.appendChild(row);
+ }
+
+ const browserTiming = document.getElementById("djDebugBrowserTiming");
+ // Determine if the browser timing section has already been rendered.
+ if (browserTiming.classList.contains("djdt-hidden")) {
+ const tbody = document.getElementById("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");
+ addRow(tbody, "requestStart", "responseEnd"); // There is no requestEnd
+ addRow(tbody, "responseStart", "responseEnd");
+ addRow(tbody, "domLoading", "domComplete"); // Spans the events below
+ addRow(tbody, "domInteractive");
+ addRow(tbody, "domContentLoadedEventStart", "domContentLoadedEventEnd");
+ addRow(tbody, "loadEventStart", "loadEventEnd");
+ browserTiming.classList.remove("djdt-hidden");
}
- row.querySelector("rect").setAttribute("x", getLeft(stat));
- tbody.appendChild(row);
}
-const tbody = document.getElementById("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");
-addRow(tbody, "requestStart", "responseEnd"); // There is no requestEnd
-addRow(tbody, "responseStart", "responseEnd");
-addRow(tbody, "domLoading", "domComplete"); // Spans the events below
-addRow(tbody, "domInteractive");
-addRow(tbody, "domContentLoadedEventStart", "domContentLoadedEventEnd");
-addRow(tbody, "loadEventStart", "loadEventEnd");
-document.getElementById("djDebugBrowserTiming").classList.remove("djdt-hidden");
+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();
+$$.onPanelRender(djDebug, "TimerPanel", insertBrowserTiming);
diff --git a/debug_toolbar/static/debug_toolbar/js/toolbar.js b/debug_toolbar/static/debug_toolbar/js/toolbar.js
index d739cbdb3..c17ee3ea2 100644
--- a/debug_toolbar/static/debug_toolbar/js/toolbar.js
+++ b/debug_toolbar/static/debug_toolbar/js/toolbar.js
@@ -20,7 +20,8 @@ const djdt = {
if (!this.className) {
return;
}
- const current = document.getElementById(this.className);
+ const panelId = this.className;
+ const current = document.getElementById(panelId);
if ($$.visible(current)) {
djdt.hide_panels();
} else {
@@ -39,13 +40,24 @@ const djdt = {
window.location
);
url.searchParams.append("store_id", store_id);
- url.searchParams.append("panel_id", this.className);
+ url.searchParams.append("panel_id", panelId);
ajax(url).then(function (data) {
inner.previousElementSibling.remove(); // Remove AJAX loader
inner.innerHTML = data.content;
$$.executeScripts(data.scripts);
$$.applyStyles(inner);
+ djDebug.dispatchEvent(
+ new CustomEvent("djdt.panel.render", {
+ detail: { panelId: panelId },
+ })
+ );
});
+ } else {
+ djDebug.dispatchEvent(
+ new CustomEvent("djdt.panel.render", {
+ detail: { panelId: panelId },
+ })
+ );
}
}
}
@@ -178,6 +190,7 @@ const djdt = {
requestAnimationFrame(function () {
djdt.handleDragged = false;
});
+ djdt.ensure_handle_visibility();
}
});
const show =
@@ -198,6 +211,15 @@ const djdt = {
e.classList.remove("djdt-active");
});
},
+ ensure_handle_visibility() {
+ const handle = document.getElementById("djDebugToolbarHandle");
+ // set handle position
+ const handleTop = Math.min(
+ localStorage.getItem("djdt.top") || 0,
+ window.innerHeight - handle.offsetWidth
+ );
+ handle.style.top = handleTop + "px";
+ },
hide_toolbar() {
djdt.hide_panels();
@@ -205,16 +227,8 @@ const djdt = {
const handle = document.getElementById("djDebugToolbarHandle");
$$.show(handle);
- // set handle position
- let handleTop = localStorage.getItem("djdt.top");
- if (handleTop) {
- handleTop = Math.min(
- handleTop,
- window.innerHeight - handle.offsetHeight
- );
- handle.style.top = handleTop + "px";
- }
-
+ djdt.ensure_handle_visibility();
+ window.addEventListener("resize", djdt.ensure_handle_visibility);
document.removeEventListener("keydown", onKeyDown);
localStorage.setItem("djdt.show", "false");
@@ -237,6 +251,7 @@ const djdt = {
$$.hide(document.getElementById("djDebugToolbarHandle"));
$$.show(document.getElementById("djDebugToolbar"));
localStorage.setItem("djdt.show", "true");
+ window.removeEventListener("resize", djdt.ensure_handle_visibility);
},
cookie: {
get(key) {
diff --git a/debug_toolbar/static/debug_toolbar/js/utils.js b/debug_toolbar/static/debug_toolbar/js/utils.js
index 4683b319f..da810aad0 100644
--- a/debug_toolbar/static/debug_toolbar/js/utils.js
+++ b/debug_toolbar/static/debug_toolbar/js/utils.js
@@ -7,6 +7,21 @@ const $$ = {
}
});
},
+ onPanelRender(root, panelId, fn) {
+ /*
+ This is a helper function to attach a handler for a `djdt.panel.render`
+ event of a specific panel.
+
+ root: The container element that the listener should be attached to.
+ panelId: The Id of the panel.
+ fn: A function to execute when the event is triggered.
+ */
+ root.addEventListener("djdt.panel.render", function (event) {
+ if (event.detail.panelId === panelId) {
+ fn.call(event);
+ }
+ });
+ },
show(element) {
element.classList.remove("djdt-hidden");
},
diff --git a/debug_toolbar/templates/debug_toolbar/base.html b/debug_toolbar/templates/debug_toolbar/base.html
index 78b9b7fe2..7abc5476f 100644
--- a/debug_toolbar/templates/debug_toolbar/base.html
+++ b/debug_toolbar/templates/debug_toolbar/base.html
@@ -7,7 +7,10 @@
{% endblock %}
{{ panel.title }}
{% trans "Method" %}
{% trans "Path" %}
{% trans "Request Variables" %}
+ {% trans "Status" %}
{% trans "Action" %}
diff --git a/debug_toolbar/templates/debug_toolbar/panels/history_tr.html b/debug_toolbar/templates/debug_toolbar/panels/history_tr.html
index 9ce984396..31793472a 100644
--- a/debug_toolbar/templates/debug_toolbar/panels/history_tr.html
+++ b/debug_toolbar/templates/debug_toolbar/panels/history_tr.html
@@ -38,6 +38,9 @@
+
+