mirror of
https://github.com/DarrenOfficial/dpaste.git
synced 2024-11-15 08:02:54 +11:00
Raw view improvements, copy snippet button, hide edit panel. #120
This commit is contained in:
parent
2666c90400
commit
8825ef0930
9 changed files with 97 additions and 8 deletions
|
@ -1,6 +1,14 @@
|
||||||
Changelog
|
Changelog
|
||||||
=========
|
=========
|
||||||
|
|
||||||
|
(development)
|
||||||
|
-------------
|
||||||
|
|
||||||
|
- "Edit Snippet" panel is now hidden by default to remove visual noise.
|
||||||
|
- Added a dedicated "Copy Snippet" button to copy the content to the clipboard.
|
||||||
|
- Added "View Raw" option to optionally render the 'raw' snippet content with a
|
||||||
|
template rather served as plain text. This was added to hinder abuse.
|
||||||
|
|
||||||
3.1 (2019-05-16)
|
3.1 (2019-05-16)
|
||||||
----------------
|
----------------
|
||||||
|
|
||||||
|
|
|
@ -102,12 +102,43 @@ lines.forEach(function(el) {
|
||||||
// Copy URL to Clipboard
|
// Copy URL to Clipboard
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
const clipboardLink = document.getElementById('copyToClipboard');
|
const clipboardLink = document.getElementById('copyToClipboard');
|
||||||
const copyToClipboardField = document.getElementById('copyToClipboardField');
|
const clipboardField = document.getElementById('copyToClipboardField');
|
||||||
|
|
||||||
if (clipboardLink && copyToClipboardField) {
|
if (clipboardLink && clipboardField) {
|
||||||
clipboardLink.onclick = function(e) {
|
clipboardLink.onclick = function(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
copyToClipboardField.select();
|
clipboardField.select();
|
||||||
document.execCommand('Copy');
|
document.execCommand('Copy');
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// Copy Snippet content to Clipboard
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
const snippetClipboardLink = document.getElementById('copySnippetToClipboard');
|
||||||
|
const snippetClipboardField = document.getElementById('copySnippetSource');
|
||||||
|
const snippetClipboardConfirm = document.getElementById('copy');
|
||||||
|
|
||||||
|
if (snippetClipboardLink && snippetClipboardField) {
|
||||||
|
snippetClipboardLink.onclick = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
snippetClipboardField.select();
|
||||||
|
document.execCommand('Copy');
|
||||||
|
snippetClipboardConfirm.style.maxHeight = '80px';
|
||||||
|
window.scrollTo(0, 0);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const editSnippetLink = document.getElementById('editSnippet');
|
||||||
|
const editSnippetForm = document.getElementById('edit');
|
||||||
|
|
||||||
|
if (editSnippetLink && editSnippetForm) {
|
||||||
|
editSnippetLink.onclick = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
editSnippetForm.style.display = 'block';
|
||||||
|
window.scrollTo(
|
||||||
|
editSnippetForm.getBoundingClientRect().x,
|
||||||
|
editSnippetForm.getBoundingClientRect().y
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
|
@ -5,6 +5,11 @@
|
||||||
line-height: 17px;
|
line-height: 17px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Edit panel in details view, not shown by default.
|
||||||
|
#edit {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
.snippet-form {
|
.snippet-form {
|
||||||
background-color: $bgColor;
|
background-color: $bgColor;
|
||||||
|
|
||||||
|
|
|
@ -133,3 +133,10 @@ ul#snippetOptions {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: $baseFontDemiBold;
|
font-weight: $baseFontDemiBold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Textarea that holds the unaltered snippet content to be copied to clipboard
|
||||||
|
#copySnippetSource {
|
||||||
|
width: 0;
|
||||||
|
position: absolute;
|
||||||
|
left: -9999px;
|
||||||
|
}
|
||||||
|
|
|
@ -77,6 +77,10 @@ class dpasteAppConfig(AppConfig):
|
||||||
# Disable "view Raw" mode.
|
# Disable "view Raw" mode.
|
||||||
RAW_MODE_ENABLED = True
|
RAW_MODE_ENABLED = True
|
||||||
|
|
||||||
|
# If enabled, the "raw View" mode will display the snippet content as
|
||||||
|
# plain text rather rendered in a template.
|
||||||
|
RAW_MODE_PLAIN_TEXT = True
|
||||||
|
|
||||||
# Lexers which have wordwrap enabled by default
|
# Lexers which have wordwrap enabled by default
|
||||||
LEXER_WORDWRAP = ('rst',)
|
LEXER_WORDWRAP = ('rst',)
|
||||||
|
|
||||||
|
|
|
@ -36,6 +36,9 @@
|
||||||
{% if raw_mode and snippet.expire_type != 3 %}
|
{% if raw_mode and snippet.expire_type != 3 %}
|
||||||
<li><a href="{% url "snippet_details_raw" snippet.secret_id %}">{% trans "View Raw" %}</a></li>
|
<li><a href="{% url "snippet_details_raw" snippet.secret_id %}">{% trans "View Raw" %}</a></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<textarea id="copySnippetSource">{{ snippet.content }}</textarea>
|
||||||
|
<li><a href="#copy" id="copySnippetToClipboard">{% trans "Copy Snippet" %}</a></li>
|
||||||
|
<li><a href="#edit" id="editSnippet">{% trans "Edit Snippet" %}</a></li>
|
||||||
{% if snippet.lexer != 'text' %}
|
{% if snippet.lexer != 'text' %}
|
||||||
<li>
|
<li>
|
||||||
<label for="wordwrap">
|
<label for="wordwrap">
|
||||||
|
@ -45,6 +48,12 @@
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
<div id="copy" class="confirm-modal">
|
||||||
|
<form method="POST" action="">
|
||||||
|
{% trans "Snippet content copied to clipboard." %}
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="delete" class="confirm-modal">
|
<div id="delete" class="confirm-modal">
|
||||||
<form method="POST" action="">
|
<form method="POST" action="">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
|
@ -77,9 +86,11 @@
|
||||||
|
|
||||||
{{ snippet.highlight }}
|
{{ snippet.highlight }}
|
||||||
|
|
||||||
<header class="sub">
|
<div id="edit">
|
||||||
<h2>{% trans "Edit this Snippet" %}</h2>
|
<header class="sub">
|
||||||
</header>
|
<h2>{% trans "Edit this Snippet" %}</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
{% include "dpaste/includes/form.html" %}
|
{% include "dpaste/includes/form.html" %}
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
|
@ -37,3 +37,4 @@
|
||||||
{{ form.content }}
|
{{ form.content }}
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
13
dpaste/templates/dpaste/raw.html
Normal file
13
dpaste/templates/dpaste/raw.html
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>{{ snippet.secret_id }}</title>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||||
|
<meta name="robots" content="noindex, nofollow"/>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<pre>{{ object.content }}</pre>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -152,6 +152,8 @@ class SnippetRawView(SnippetDetailView):
|
||||||
Display the raw content of a snippet
|
Display the raw content of a snippet
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
template_name = 'dpaste/raw.html'
|
||||||
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not config.RAW_MODE_ENABLED:
|
if not config.RAW_MODE_ENABLED:
|
||||||
return HttpResponseForbidden(
|
return HttpResponseForbidden(
|
||||||
|
@ -161,13 +163,20 @@ class SnippetRawView(SnippetDetailView):
|
||||||
)
|
)
|
||||||
return super(SnippetRawView, self).dispatch(request, *args, **kwargs)
|
return super(SnippetRawView, self).dispatch(request, *args, **kwargs)
|
||||||
|
|
||||||
def render_to_response(self, context, **response_kwargs):
|
def render_plain_text(self, context, **response_kwargs):
|
||||||
snippet = self.get_object()
|
snippet = self.get_object()
|
||||||
response = HttpResponse(snippet.content)
|
response = HttpResponse(snippet.content)
|
||||||
response['Content-Type'] = 'text/plain;charset=UTF-8'
|
response['Content-Type'] = 'text/plain;charset=UTF-8'
|
||||||
response['X-Content-Type-Options'] = 'nosniff'
|
response['X-Content-Type-Options'] = 'nosniff'
|
||||||
return response
|
return response
|
||||||
|
|
||||||
|
def render_to_response(self, context, **response_kwargs):
|
||||||
|
if config.RAW_MODE_PLAIN_TEXT:
|
||||||
|
return self.render_plain_text(config, **response_kwargs)
|
||||||
|
return super(SnippetRawView, self).render_to_response(
|
||||||
|
context, **response_kwargs
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class SnippetHistory(TemplateView):
|
class SnippetHistory(TemplateView):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in a new issue