Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added clipboard copy button #2051

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
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
7 changes: 7 additions & 0 deletions debug_toolbar/panels/templates/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from django.core import signing
from django.db.models.query import QuerySet, RawQuerySet
from django.template import RequestContext, Template
from django.templatetags.static import static
from django.test.signals import template_rendered
from django.test.utils import instrumented_test_render
from django.urls import path
Expand Down Expand Up @@ -225,3 +226,9 @@ def generate_stats(self, request, response):
"context_processors": context_processors,
}
)

@property
def scripts(self):
scripts = super().scripts
scripts.append(static("debug_toolbar/js/copy_context.js"))
return scripts
50 changes: 50 additions & 0 deletions debug_toolbar/static/debug_toolbar/js/copy_context.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
document.addEventListener("click", (event) => {
if (event.target.classList.contains("copy-context")) {
const context = event.target.getAttribute("data-context");

if (context) {
try {
const decodedContext = decodeUnicode(context);
const listContext = makeList(decodedContext);

navigator.clipboard
.writeText(listContext)
.then(() => {
const originalText = event.target.textContent;
event.target.textContent = "Copied!";

setTimeout(() => {
event.target.textContent = originalText;
}, 2000);
})
.catch((error) => {
console.error("Failed to copy context:", error);
});
} catch (error) {
console.error("Error processing context:", error);
}
}
}
});

/**
* Decodes escaped Unicode characters in a string.
*
* @param {string} text - The text containing escaped Unicode characters.
* @returns {string} - Decoded text.
*/
function decodeUnicode(text) {
return text.replace(/\\u[\dA-Fa-f]{4}/g, (match) => {
return String.fromCharCode(parseInt(match.replace("\\u", ""), 16));
});
}

/**
* Wraps multiple JSON objects into a list format.
*
* @param {string} text - The raw text containing multiple JSON objects.
* @returns {string} - Properly formatted JSON array string.
*/
function makeList(text) {
return `[${text.replace(/\n(?=\{)/g, ',')}]`;
}
3 changes: 3 additions & 0 deletions debug_toolbar/templates/debug_toolbar/panels/templates.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ <h4>{% blocktrans count templates|length as template_count %}Template{% plural %
<dd>
<details>
<summary>{% trans "Toggle context" %}</summary>
<button class="copy-context" data-context="{{ template.context|escapejs }}">
{% trans "Copy" %}
</button>
<code class="djTemplateContext">{{ template.context }}</code>
</details>
</dd>
Expand Down