105 lines
No EOL
3.7 KiB
HTML
105 lines
No EOL
3.7 KiB
HTML
<div class="markdown-editor">
|
|
<div class="card">
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="editor-toolbar">
|
|
<button type="button" data-action="bold" class="btn btn-sm btn-outline-secondary">
|
|
<i class="ti ti-bold"></i>
|
|
</button>
|
|
<button type="button" data-action="italic" class="btn btn-sm btn-outline-secondary">
|
|
<i class="ti ti-italic"></i>
|
|
</button>
|
|
<button type="button" data-action="heading" class="btn btn-sm btn-outline-secondary">
|
|
<i class="ti ti-h-1"></i>
|
|
</button>
|
|
<button type="button" data-action="bulletList" class="btn btn-sm btn-outline-secondary">
|
|
<i class="ti ti-list"></i>
|
|
</button>
|
|
<button type="button" data-action="orderedList" class="btn btn-sm btn-outline-secondary">
|
|
<i class="ti ti-list-numbers"></i>
|
|
</button>
|
|
<button type="button" data-action="link" class="btn btn-sm btn-outline-secondary">
|
|
<i class="ti ti-link"></i>
|
|
</button>
|
|
<button type="button" data-action="code" class="btn btn-sm btn-outline-secondary">
|
|
<i class="ti ti-code"></i>
|
|
</button>
|
|
</div>
|
|
<div id="editor-container" class="mt-2">
|
|
<div id="editor"></div>
|
|
</div>
|
|
<input type="hidden" name="{{ field_name }}" id="markdown-content" value="{{ content }}">
|
|
</div>
|
|
<div class="col-md-6">
|
|
<div class="card">
|
|
<div class="card-header">
|
|
<h3 class="card-title">Preview</h3>
|
|
</div>
|
|
<div class="card-body p-0">
|
|
<div id="markdown-preview" class="markdown-body p-3"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function () {
|
|
// Initialize Tiptap editor
|
|
const editor = new window.tiptap.Editor({
|
|
element: document.getElementById('editor'),
|
|
extensions: [
|
|
window.tiptapStarterKit.StarterKit,
|
|
window.tiptapLink.Link,
|
|
window.tiptapCodeBlock.CodeBlock,
|
|
window.tiptapImage.Image
|
|
],
|
|
content: document.getElementById('markdown-content').value || '',
|
|
onUpdate: ({ editor }) => {
|
|
// Update the hidden input with the markdown content
|
|
const markdown = editor.storage.markdown.getMarkdown();
|
|
document.getElementById('markdown-content').value = markdown;
|
|
|
|
// Update preview
|
|
updatePreview(markdown);
|
|
}
|
|
});
|
|
|
|
// Initialize the preview with the current content
|
|
updatePreview(editor.storage.markdown.getMarkdown());
|
|
|
|
// Initialize the toolbar buttons
|
|
document.querySelectorAll('.editor-toolbar button').forEach(button => {
|
|
button.addEventListener('click', () => {
|
|
const action = button.dataset.action;
|
|
|
|
if (action === 'link') {
|
|
const url = prompt('URL');
|
|
if (url) {
|
|
editor.chain().focus().setLink({ href: url }).run();
|
|
}
|
|
} else if (action === 'heading') {
|
|
editor.chain().focus().toggleHeading({ level: 1 }).run();
|
|
} else {
|
|
editor.chain().focus()[`toggle${action.charAt(0).toUpperCase() + action.slice(1)}`]().run();
|
|
}
|
|
});
|
|
});
|
|
|
|
// Function to update preview
|
|
function updatePreview(markdown) {
|
|
const converter = new showdown.Converter({
|
|
tables: true,
|
|
tasklists: true,
|
|
strikethrough: true,
|
|
ghCodeBlocks: true
|
|
});
|
|
|
|
const html = converter.makeHtml(markdown);
|
|
document.getElementById('markdown-preview').innerHTML = html;
|
|
}
|
|
});
|
|
</script> |