185 lines
6.6 KiB
HTML
185 lines
6.6 KiB
HTML
{{ template "base.html" . }}
|
|
|
|
{{ define "extrahead" }}
|
|
{{/* TODO: These are no longer useful? */}}
|
|
<link rel="stylesheet" href="{{ static "editor.css" }}" />
|
|
<script src="{{ static "util.js" }}"></script>
|
|
<script src="{{ static "editor.js" }}"></script>
|
|
|
|
<script src="{{ static "go_wasm_exec.js" }}"></script>
|
|
<script>
|
|
const previewWorker = new Worker('/assets/editorpreviews.js');
|
|
</script>
|
|
|
|
<style>
|
|
#editor {
|
|
resize: vertical;
|
|
}
|
|
</style>
|
|
{{ end }}
|
|
|
|
{{ define "content" }}
|
|
<div class="content-block ph3 ph0-ns">
|
|
{{ if not .CanEditTitle }}
|
|
<h2>{{ .Title }}</h2>
|
|
{{ end }}
|
|
<div class="flex flex-column flex-row-ns">
|
|
<form id="form" action="{{ .SubmitUrl }}" method="post" class="flex-fair-ns">
|
|
{{ csrftoken .Session }}
|
|
|
|
{{ if .CanEditTitle }}
|
|
<input id="title" class="b w-100 mb1" name="title" type="text" placeholder="Post title..." value="{{ .Title }}" />
|
|
{{ end }}
|
|
{{/* TODO: Reintroduce the toolbar in a way that makes sense for Markdown */}}
|
|
{{/*
|
|
<div class="toolbar" id="toolbar">
|
|
<input type="button" id="bold" value="B" />
|
|
<input type="button" id="italic" value="I" />
|
|
<input type="button" id="underline" value="U" />
|
|
<input type="button" id="monospace" value="monospace" />
|
|
<input type="button" id="url" value="url" />
|
|
<input type="button" id="img" value="img" />
|
|
<input type="button" id="code" value="code" />
|
|
<input type="button" id="quote_simple" value="quote (anon)" />
|
|
<input type="button" id="quote_member" value="quote (member)" />
|
|
<input type="button" id="spoiler" value="spoiler" />
|
|
<input type="button" id="lalign" value="Left" />
|
|
<input type="button" id="calign" value="Center" />
|
|
<input type="button" id="ralign" value="Right" />
|
|
<input type="button" id="ulist" value="ul" />
|
|
<input type="button" id="olist" value="ol" />
|
|
<input type="button" id="litem" value="li" />
|
|
<input type="button" id="youtube" value="youtube" />
|
|
</div>
|
|
*/}}
|
|
<textarea id="editor" class="w-100 h6 minh-6 pa2 mono lh-copy" name="body">{{ .EditInitialContents }}</textarea>
|
|
|
|
<div class="flex flex-row-reverse justify-start mt2">
|
|
<input type="submit" class="button ml2" name="submit" value="{{ .SubmitLabel }}" />
|
|
</div>
|
|
|
|
{{ if .IsEditing }}
|
|
<span class="editreason">
|
|
<label for="editreason">Edit reason:</label>
|
|
<input name="editreason" maxlength="255" type="text" id="editreason" />
|
|
</span>
|
|
{{ end }}
|
|
|
|
{{/* TODO: Sticky threads
|
|
{% if user.is_staff and post and post.depth == 0 %}
|
|
<div class="checkbox sticky">
|
|
<input type="checkbox" name="sticky" id="sticky" {% if thread.sticky %}checked{% endif%} />
|
|
<label for="sticky">Sticky thread</label>
|
|
</div>
|
|
{% endif %}
|
|
*/}}
|
|
|
|
{{ with .PostReplyingTo }}
|
|
<h4 class="mt3">The post you're replying to:</h4>
|
|
{{ template "forum_post_standalone.html" . }}
|
|
{{ end }}
|
|
|
|
{{/*
|
|
|
|
{% if context_newer %}
|
|
<h4>Replies since then:</h4>
|
|
<div class="recent-posts">
|
|
{% for post in posts_newer %}
|
|
{% include "forum_thread_single_post.html" %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
|
|
{% if context_older %}
|
|
<h4>Replies before then:</h4>
|
|
<div class="recent-posts">
|
|
{% for post in posts_older %}
|
|
{% include "forum_thread_single_post.html" %}
|
|
{% endfor %}
|
|
</div>
|
|
{% endif %}
|
|
*/}}
|
|
</form>
|
|
<div id="preview-container" class="post post-preview mv3 mathjax flex-fair-ns mv0-ns ml3-ns overflow-auto">
|
|
<div id="preview" class="body contents"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
const form = document.querySelector('#form');
|
|
const titleField = document.querySelector('#title'); // may be undefined, be careful!
|
|
const textField = document.querySelector('#editor');
|
|
const preview = document.querySelector('#preview');
|
|
|
|
const storagePrefix = 'post-contents';
|
|
|
|
// Delete old irrelevant local post contents
|
|
const aWeekAgo = new Date().getTime() - (7 * 24 * 60 * 60 * 1000);
|
|
for (const key in window.localStorage) {
|
|
if (!window.localStorage.hasOwnProperty(key)) {
|
|
continue;
|
|
}
|
|
|
|
if (key.startsWith(storagePrefix)) {
|
|
try {
|
|
const { when } = JSON.parse(window.localStorage.getItem(key));
|
|
if (when <= aWeekAgo) {
|
|
window.localStorage.removeItem(key);
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
}
|
|
}
|
|
|
|
// Load any stored content from localStorage
|
|
const storageKey = `${storagePrefix}/${window.location.host}${window.location.pathname}`;
|
|
const storedContents = window.localStorage.getItem(storageKey);
|
|
if (storedContents && !textField.value) {
|
|
try {
|
|
const { title, contents } = JSON.parse(storedContents);
|
|
if (titleField) {
|
|
titleField.value = title;
|
|
}
|
|
textField.value = contents;
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
}
|
|
|
|
function updatePreview(previewHtml) {
|
|
preview.innerHTML = previewHtml;
|
|
MathJax.typeset();
|
|
}
|
|
|
|
previewWorker.onmessage = ({ data }) => {
|
|
updatePreview(data);
|
|
};
|
|
|
|
function doMarkdown() {
|
|
const md = textField.value;
|
|
previewWorker.postMessage(md);
|
|
updateContentCache();
|
|
}
|
|
|
|
function updateContentCache() {
|
|
window.localStorage.setItem(storageKey, JSON.stringify({
|
|
when: new Date().getTime(),
|
|
title: titleField ? titleField.value : '',
|
|
contents: textField.value,
|
|
}));
|
|
}
|
|
|
|
doMarkdown();
|
|
textField.addEventListener('input', () => doMarkdown());
|
|
if (titleField) {
|
|
titleField.addEventListener('input', () => updateContentCache());
|
|
}
|
|
|
|
form.addEventListener('submit', e => {
|
|
window.localStorage.removeItem(storageKey);
|
|
});
|
|
</script>
|
|
{{ end }}
|