diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 09e7036af..a15d59279 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,11 +51,6 @@ jobs: restore-keys: | ${{ matrix.python-version }}-v1- - - name: Install enchant (only for docs) - run: | - sudo apt-get -qq update - sudo apt-get -y install enchant - - name: Install dependencies run: | python -m pip install --upgrade pip @@ -122,10 +117,10 @@ jobs: restore-keys: | ${{ matrix.python-version }}-v1- - - name: Install enchant (only for docs) and gdal-bin (for postgis) + - name: Install gdal-bin (for postgis) run: | sudo apt-get -qq update - sudo apt-get -y install enchant gdal-bin + sudo apt-get -y install gdal-bin - name: Install dependencies run: | diff --git a/debug_toolbar/static/debug_toolbar/js/toolbar.js b/debug_toolbar/static/debug_toolbar/js/toolbar.js index 0f62be894..ef2e617f9 100644 --- a/debug_toolbar/static/debug_toolbar/js/toolbar.js +++ b/debug_toolbar/static/debug_toolbar/js/toolbar.js @@ -18,65 +18,60 @@ function getDebugElement() { const djdt = { handleDragged: false, init() { - $$.on( - document.body, - "click", - "#djDebugPanelList li a", - function (event) { - event.preventDefault(); - if (!this.className) { - return; - } - const panelId = this.className; - const current = document.getElementById(panelId); - if ($$.visible(current)) { - djdt.hidePanels(); - } else { - djdt.hidePanels(); + const djDebug = getDebugElement(); + $$.on(djDebug, "click", "#djDebugPanelList li a", function (event) { + event.preventDefault(); + if (!this.className) { + return; + } + const panelId = this.className; + const current = document.getElementById(panelId); + if ($$.visible(current)) { + djdt.hidePanels(); + } else { + djdt.hidePanels(); - $$.show(current); - this.parentElement.classList.add("djdt-active"); + $$.show(current); + this.parentElement.classList.add("djdt-active"); - const djDebug = getDebugElement(); - const inner = current.querySelector( - ".djDebugPanelContent .djdt-scroll" - ), - storeId = djDebug.dataset.storeId; - if (storeId && inner.children.length === 0) { - const url = new URL( - djDebug.dataset.renderPanelUrl, - window.location - ); - url.searchParams.append("store_id", storeId); - 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 { + const inner = current.querySelector( + ".djDebugPanelContent .djdt-scroll" + ), + storeId = djDebug.dataset.storeId; + if (storeId && inner.children.length === 0) { + const url = new URL( + djDebug.dataset.renderPanelUrl, + window.location + ); + url.searchParams.append("store_id", storeId); + 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 }, + }) + ); } } - ); - $$.on(document.body, "click", "#djDebug .djDebugClose", function () { + }); + $$.on(djDebug, "click", ".djDebugClose", function () { djdt.hideOneLevel(); }); $$.on( - document.body, + djDebug, "click", - "#djDebug .djDebugPanelButton input[type=checkbox]", + ".djDebugPanelButton input[type=checkbox]", function () { djdt.cookie.set( this.dataset.cookie, @@ -90,7 +85,7 @@ const djdt = { ); // Used by the SQL and template panels - $$.on(document.body, "click", "#djDebug .remoteCall", function (event) { + $$.on(djDebug, "click", ".remoteCall", function (event) { event.preventDefault(); let url; @@ -113,7 +108,7 @@ const djdt = { }); // Used by the cache, profiling and SQL panels - $$.on(document.body, "click", "#djDebug .djToggleSwitch", function () { + $$.on(djDebug, "click", ".djToggleSwitch", function () { const id = this.dataset.toggleId; const toggleOpen = "+"; const toggleClose = "-"; @@ -150,12 +145,12 @@ const djdt = { }); }); - $$.on(document.body, "click", "#djHideToolBarButton", function (event) { + $$.on(djDebug, "click", "#djHideToolBarButton", function (event) { event.preventDefault(); djdt.hideToolbar(); }); - $$.on(document.body, "click", "#djShowToolBarButton", function () { + $$.on(djDebug, "click", "#djShowToolBarButton", function () { if (!djdt.handleDragged) { djdt.showToolbar(); } @@ -179,35 +174,29 @@ const djdt = { djdt.handleDragged = true; } } - $$.on( - document.body, - "mousedown", - "#djShowToolBarButton", - function (event) { - event.preventDefault(); - startPageY = event.pageY; - baseY = handle.offsetTop - startPageY; - document.addEventListener("mousemove", onHandleMove); + $$.on(djDebug, "mousedown", "#djShowToolBarButton", function (event) { + event.preventDefault(); + startPageY = event.pageY; + baseY = handle.offsetTop - startPageY; + document.addEventListener("mousemove", onHandleMove); - document.addEventListener( - "mouseup", - function (event) { - document.removeEventListener("mousemove", onHandleMove); - if (djdt.handleDragged) { - event.preventDefault(); - localStorage.setItem("djdt.top", handle.offsetTop); - requestAnimationFrame(function () { - djdt.handleDragged = false; - }); - djdt.ensureHandleVisibility(); - } - }, - { once: true } - ); - } - ); + document.addEventListener( + "mouseup", + function (event) { + document.removeEventListener("mousemove", onHandleMove); + if (djdt.handleDragged) { + event.preventDefault(); + localStorage.setItem("djdt.top", handle.offsetTop); + requestAnimationFrame(function () { + djdt.handleDragged = false; + }); + djdt.ensureHandleVisibility(); + } + }, + { once: true } + ); + }); - const djDebug = getDebugElement(); // Make sure the debug element is rendered at least once. // showToolbar will continue to show it in the future if the // entire DOM is reloaded. diff --git a/docs/configuration.rst b/docs/configuration.rst index 2e20c454c..7949ae501 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -98,6 +98,8 @@ Toolbar options The toolbar keeps up to this many results in memory. +.. _ROOT_TAG_EXTRA_ATTRS: + * ``ROOT_TAG_EXTRA_ATTRS`` Default: ``''`` diff --git a/docs/spelling_wordlist.txt b/docs/spelling_wordlist.txt index 5e3a7f64b..5103a6466 100644 --- a/docs/spelling_wordlist.txt +++ b/docs/spelling_wordlist.txt @@ -8,6 +8,8 @@ fallbacks flamegraph flatpages frontend +Hotwire +htmx inlining isort Jazzband diff --git a/docs/tips.rst b/docs/tips.rst index d5d160fb3..c79d12523 100644 --- a/docs/tips.rst +++ b/docs/tips.rst @@ -20,6 +20,44 @@ Browsers have become more aggressive with caching static assets, such as JavaScript and CSS files. Check your browser's development console, and if you see errors, try a hard browser refresh or clearing your cache. +Working with htmx and Turbo +---------------------------- + +Libraries such as `htmx `_ and +`Turbo `_ need additional configuration to retain +the toolbar handle element through page renders. This can be done by +configuring the :ref:`ROOT_TAG_EXTRA_ATTRS ` to include +the relevant JavaScript library's attribute. + +htmx +~~~~ + +The attribute `htmx `_ uses is +`hx-preserve `_. + +Update your settings to include: + +.. code-block:: python + + DEBUG_TOOLBAR_CONFIG = { + "ROOT_TAG_EXTRA_ATTRS": "hx-preserve" + } + +Hotwire Turbo +~~~~~~~~~~~~~ + +The attribute `Turbo `_ uses is +`data-turbo-permanent `_ + +Update your settings to include: + +.. code-block:: python + + DEBUG_TOOLBAR_CONFIG = { + "ROOT_TAG_EXTRA_ATTRS": "data-turbo-permanent" + } + + Performance considerations -------------------------- diff --git a/example/settings.py b/example/settings.py index 1b8216b71..d2bd57387 100644 --- a/example/settings.py +++ b/example/settings.py @@ -61,6 +61,7 @@ WSGI_APPLICATION = "example.wsgi.application" +DEBUG_TOOLBAR_CONFIG = {"ROOT_TAG_EXTRA_ATTRS": "data-turbo-permanent hx-preserve"} # Cache and database diff --git a/example/templates/htmx/boost.html b/example/templates/htmx/boost.html index f6c2c9749..782303b4e 100644 --- a/example/templates/htmx/boost.html +++ b/example/templates/htmx/boost.html @@ -3,25 +3,28 @@ - Index of Tests - + Index of Tests (htmx) + -

Index of Tests

+

Index of Tests (htmx) - Page {{page_num|default:"1"}}

+ +

+ For the debug panel to remain through page navigation, add the setting: +

+DEBUG_TOOLBAR_CONFIG = {
+  "ROOT_TAG_EXTRA_ATTRS": "hx-preserve"
+}
+      
+

+ -

Django Admin

- + + Home + diff --git a/example/templates/index.html b/example/templates/index.html index fad2fc4ae..382bfb0e9 100644 --- a/example/templates/index.html +++ b/example/templates/index.html @@ -12,6 +12,8 @@

Index of Tests

  • jQuery 3.3.1
  • MooTools 1.6.0
  • Prototype 1.7.3.0
  • +
  • Hotwire Turbo
  • +
  • htmx
  • Django Admin

    {% endcache %} diff --git a/example/templates/turbo/index.html b/example/templates/turbo/index.html new file mode 100644 index 000000000..143054e37 --- /dev/null +++ b/example/templates/turbo/index.html @@ -0,0 +1,56 @@ +{% load cache %} + + + + + Index of Tests + + + +

    Turbo Index - Page {{page_num|default:"1"}}

    + +

    + For the debug panel to remain through page navigation, add the setting: +

    +DEBUG_TOOLBAR_CONFIG = {
    +  "ROOT_TAG_EXTRA_ATTRS": "data-turbo-permanent"
    +}
    +      
    +

    + + +

    + Value + {{ request.session.value|default:0 }} + + +

    + + Home + + diff --git a/example/urls.py b/example/urls.py index d609035df..da52601f8 100644 --- a/example/urls.py +++ b/example/urls.py @@ -5,11 +5,32 @@ from example.views import increment urlpatterns = [ - path("", TemplateView.as_view(template_name="index.html")), + path("", TemplateView.as_view(template_name="index.html"), name="home"), path("jquery/", TemplateView.as_view(template_name="jquery/index.html")), path("mootools/", TemplateView.as_view(template_name="mootools/index.html")), path("prototype/", TemplateView.as_view(template_name="prototype/index.html")), - path("htmx/boost/", TemplateView.as_view(template_name="htmx/boost.html")), + path( + "htmx/boost/", + TemplateView.as_view(template_name="htmx/boost.html"), + name="htmx", + ), + path( + "htmx/boost/2", + TemplateView.as_view( + template_name="htmx/boost.html", extra_context={"page_num": "2"} + ), + name="htmx2", + ), + path( + "turbo/", TemplateView.as_view(template_name="turbo/index.html"), name="turbo" + ), + path( + "turbo/2", + TemplateView.as_view( + template_name="turbo/index.html", extra_context={"page_num": "2"} + ), + name="turbo2", + ), path("admin/", admin.site.urls), path("ajax/increment", increment, name="ajax_increment"), path("__debug__/", include("debug_toolbar.urls")),