From 300900c54d3d59ad850d68275b35514cea69fae3 Mon Sep 17 00:00:00 2001
From: agusmakmun
Date: Thu, 28 Aug 2025 23:00:17 +0700
Subject: [PATCH 1/3] feat: support tailwind ui
---
README.md | 90 +-
martor/static/martor/css/martor.tailwind.css | 476 ++++++
.../static/martor/css/martor.tailwind.min.css | 401 +++++
martor/static/martor/js/martor.tailwind.js | 659 +++++++++
.../static/martor/js/martor.tailwind.min.js | 5 +
martor/static/plugins/css/tailwind.min.css | 1289 +++++++++++++++++
martor/templates/martor/tailwind/editor.html | 57 +
martor/templates/martor/tailwind/emoji.html | 184 +++
martor/templates/martor/tailwind/guide.html | 228 +++
martor/templates/martor/tailwind/toolbar.html | 150 ++
martor/widgets.py | 2 +-
martor_demo/app/templates/tailwind/base.html | 110 ++
martor_demo/app/templates/tailwind/form.html | 228 +++
.../templates/tailwind/test_markdownify.html | 251 ++++
martor_demo/martor_demo/settings.py | 2 +-
15 files changed, 4127 insertions(+), 5 deletions(-)
create mode 100644 martor/static/martor/css/martor.tailwind.css
create mode 100644 martor/static/martor/css/martor.tailwind.min.css
create mode 100644 martor/static/martor/js/martor.tailwind.js
create mode 100644 martor/static/martor/js/martor.tailwind.min.js
create mode 100644 martor/static/plugins/css/tailwind.min.css
create mode 100644 martor/templates/martor/tailwind/editor.html
create mode 100644 martor/templates/martor/tailwind/emoji.html
create mode 100644 martor/templates/martor/tailwind/guide.html
create mode 100644 martor/templates/martor/tailwind/toolbar.html
create mode 100644 martor_demo/app/templates/tailwind/base.html
create mode 100644 martor_demo/app/templates/tailwind/form.html
create mode 100644 martor_demo/app/templates/tailwind/test_markdownify.html
diff --git a/README.md b/README.md
index 1ef32e74..2ce20346 100644
--- a/README.md
+++ b/README.md
@@ -4,14 +4,14 @@
📖 **Documentation:** https://django-markdown-editor.readthedocs.io
-**Martor** is a Markdown Editor plugin for Django, supported for _Bootstrap_ & _Semantic-UI_.
+**Martor** is a Markdown Editor plugin for Django, supported for _Bootstrap_, _Semantic-UI_ & _Tailwind CSS_.
### Features
* Live Preview
* Integrated with [_Ace Editor_](https://ace.c9.io)
-* Supported with [_Bootstrap_](https://getbootstrap.com) and [_Semantic-UI_](https://semantic-ui.com)
+* Supported with [_Bootstrap_](https://getbootstrap.com), [_Semantic-UI_](https://semantic-ui.com) and [_Tailwind CSS_](https://tailwindcss.com)
* Supported Multiple Fields [_fixed this issue_](https://github.com/agusmakmun/django-markdown-editor/issues/3)
* Upload Images to imgur.com _(via API)_ and [custom uploader][13]
* Direct Mention users `@[username]` - _(requires user to logged in)_.
@@ -86,7 +86,7 @@ Please register your application at https://api.imgur.com/oauth2/addclient
to get `IMGUR_CLIENT_ID` and `IMGUR_API_KEY`.
```python
-# Choices are: "semantic", "bootstrap"
+# Choices are: "semantic", "bootstrap", "tailwind"
MARTOR_THEME = 'bootstrap'
# Global martor settings
@@ -335,6 +335,90 @@ Different with *Template Renderer*, the *Template Editor Form* have more css & j
```
+#### Tailwind CSS Theme
+
+When using `MARTOR_THEME = 'tailwind'`, include the required CSS and JavaScript files:
+
+**Template Renderer (Tailwind):**
+
+```html
+{% extends "base.html" %}
+{% load static %}
+{% load martortags %}
+
+{% block css %}
+
+
+
+{% endblock %}
+
+{% block content %}
+
+
+
{{ post.title }}
+
+ {{ post.description|safe_markdown }}
+
+
+
+{% endblock %}
+
+{% block js %}
+
+
+{% endblock %}
+```
+
+**Template Editor Form (Tailwind):**
+
+```html
+{% extends "base.html" %}
+{% load static %}
+
+{% block css %}
+
+
+
+{% endblock %}
+
+{% block content %}
+
+{% endblock %}
+
+{% block js %}
+
+
+
+
+
+
+
+
+
+{% endblock %}
+```
+
+
### Custom Uploader
If you want to save the images uploaded to your storage,
diff --git a/martor/static/martor/css/martor.tailwind.css b/martor/static/martor/css/martor.tailwind.css
new file mode 100644
index 00000000..1d2bfef4
--- /dev/null
+++ b/martor/static/martor/css/martor.tailwind.css
@@ -0,0 +1,476 @@
+/**
+ * Martor Tailwind CSS Theme
+ * This file provides Tailwind CSS-based styling for the Martor markdown editor
+ * Use with Tailwind CSS framework
+ */
+
+/* Global Body Overflow Control */
+body.overflow {
+ overflow: hidden !important;
+}
+
+/* Main Editor Container */
+.martor {
+ @apply h-[500px] max-h-[500px];
+}
+
+.martor-field {
+ @apply w-full h-64 min-h-[100px] resize-y border-r border-b border-gray-300;
+}
+
+.main-martor {
+ @apply my-4 relative;
+}
+
+/* Modal Styles */
+.main-martor .modal-header {
+ @apply p-2 px-4;
+}
+
+.main-martor .modal-header h5 {
+ @apply text-base;
+}
+
+/* Upload Progress Overlay */
+.main-martor .upload-progress {
+ @apply absolute z-[100] w-full h-full pt-20 bg-black bg-opacity-85 text-white text-center;
+}
+
+/* Toolbar Styles */
+.martor-toolbar {
+ @apply z-[100];
+}
+
+.enable-living .martor-toolbar {
+ @apply relative;
+}
+
+.martor-toolbar .markdown-image-upload {
+ @apply relative overflow-hidden;
+}
+
+.martor-toolbar .markdown-image-upload input[type=file] {
+ @apply absolute top-0 right-0 w-full h-full text-2xl p-0 pl-9 text-right opacity-0 outline-none cursor-pointer block;
+ min-width: 100%;
+ min-height: 100%;
+ filter: alpha(opacity=0);
+}
+
+/* Emoji Styles */
+.emoji-loader-init {
+ min-height: 200px !important;
+ @apply pt-16;
+}
+
+.emoji-content-body {
+ @apply text-xs;
+}
+
+.insert-emoji {
+ @apply cursor-pointer no-underline;
+}
+
+/* Reference Table */
+.table.markdown-reference {
+ @apply text-xs;
+}
+
+.table.markdown-reference h1 {
+ @apply text-2xl;
+}
+
+.table.markdown-reference h2 {
+ @apply text-xl;
+}
+
+.table.markdown-reference ul,
+.table.markdown-reference ol {
+ @apply pl-4;
+}
+
+/* Preview Styles */
+div.martor-preview {
+ @apply p-4 overflow-auto bg-gray-50;
+}
+
+div.martor-preview-stale {
+ background: repeating-linear-gradient(-45deg, #fff, #fff 10px, #f8f8f8 10px, #f8f8f8 20px) !important;
+}
+
+/* Tab Navigation Styles */
+.main-martor .nav-tabs {
+ @apply border-b-2 border-gray-200;
+}
+
+.main-martor .nav-tabs .nav-link:hover,
+.main-martor .nav-tabs .nav-link:focus {
+ @apply border-transparent;
+}
+
+.main-martor .nav-tabs .nav-item.show .nav-link,
+.main-martor .nav-tabs .nav-link.active,
+.main-martor .nav-tabs .nav-link.active:hover {
+ @apply border-transparent border-b-2 border-gray-800 text-gray-700;
+}
+
+.main-martor .tab-pane {
+ @apply relative;
+}
+
+.icon.expand-editor {
+ @apply absolute -bottom-2 right-2 z-[100];
+}
+
+.no-border {
+ @apply border-0;
+}
+
+/* Live Preview Mode */
+div.enable-living .martor-preview {
+ @apply block opacity-100 mt-4 border border-gray-200 rounded-md;
+}
+
+div.enable-living .tab-martor-menu a.nav-link {
+ @apply hidden;
+}
+
+/* Custom Scrollbar Styles */
+.section-martor ::-webkit-scrollbar-track {
+ -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+ @apply rounded-lg bg-gray-100;
+}
+
+.section-martor ::-webkit-scrollbar {
+ @apply h-1.5 w-1.5 bg-gray-100;
+}
+
+.section-martor ::-webkit-scrollbar-thumb {
+ @apply rounded-lg bg-gray-600;
+ -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3);
+}
+
+.ace_scrollbar-v {
+ cursor: ns-resize;
+}
+
+/* Fullscreen Mode */
+.main-martor-fullscreen {
+ @apply bg-white fixed z-[9999] max-h-full h-full w-full m-0 left-0 top-0;
+}
+
+.main-martor-fullscreen .fields.martor-toolbar {
+ @apply border-b border-gray-300 m-0;
+}
+
+.main-martor-fullscreen .section-martor {
+ @apply h-[90%] relative;
+}
+
+.main-martor-fullscreen .martor-field,
+.main-martor-fullscreen div.martor-preview {
+ min-height: 95vh;
+}
+
+/* Preview Content Styling */
+.marked-emoji,
+div.martor-preview .marked-emoji {
+ @apply max-w-5;
+}
+
+div.martor-preview {
+ @apply text-sm leading-relaxed;
+}
+
+div.martor-preview>*:first-child {
+ @apply mt-0;
+}
+
+div.martor-preview>*:last-child {
+ @apply mb-5;
+}
+
+div.martor-preview a.absent {
+ @apply text-red-600;
+}
+
+div.martor-preview a.anchor {
+ @apply block pl-8 -ml-8 cursor-pointer absolute top-0 left-0 bottom-0;
+}
+
+/* Heading Styles */
+div.martor-preview h1,
+div.martor-preview h2,
+div.martor-preview h3,
+div.martor-preview h4,
+div.martor-preview h5,
+div.martor-preview h6 {
+ @apply my-5 mb-2 p-0 font-bold cursor-text relative;
+ -webkit-font-smoothing: antialiased;
+ background: none;
+}
+
+div.martor-preview h1:hover a.anchor,
+div.martor-preview h2:hover a.anchor,
+div.martor-preview h3:hover a.anchor,
+div.martor-preview h4:hover a.anchor,
+div.martor-preview h5:hover a.anchor,
+div.martor-preview h6:hover a.anchor {
+ @apply no-underline leading-none pl-0 -ml-6;
+ top: 15%;
+}
+
+div.martor-preview h1 {
+ @apply text-3xl text-black;
+}
+
+div.martor-preview h2 {
+ @apply text-2xl text-black;
+}
+
+div.martor-preview h3 {
+ @apply text-lg;
+}
+
+div.martor-preview h4 {
+ @apply text-base;
+}
+
+div.martor-preview h5 {
+ @apply text-sm;
+}
+
+div.martor-preview h6 {
+ @apply text-gray-500 text-sm;
+}
+
+/* Content Elements */
+div.martor-preview p,
+div.martor-preview blockquote,
+div.martor-preview ul,
+div.martor-preview ol,
+div.martor-preview dl,
+div.martor-preview table,
+div.martor-preview pre {
+ @apply my-4;
+}
+
+div.martor-preview hr {
+ background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxBEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;
+ @apply border-0 text-gray-300 h-1 p-0;
+}
+
+/* First Child Margin Reset */
+div.martor-preview>h2:first-child,
+div.martor-preview>h1:first-child,
+div.martor-preview>h1:first-child+h2,
+div.martor-preview>h3:first-child,
+div.martor-preview>h4:first-child,
+div.martor-preview>h5:first-child,
+div.martor-preview>h6:first-child {
+ @apply mt-0 pt-0;
+}
+
+div.martor-preview a:first-child h1,
+div.martor-preview a:first-child h2,
+div.martor-preview a:first-child h3,
+div.martor-preview a:first-child h4,
+div.martor-preview a:first-child h5,
+div.martor-preview a:first-child h6 {
+ @apply mt-0 pt-0;
+}
+
+div.martor-preview h1+p,
+div.martor-preview h2+p,
+div.martor-preview h3+p,
+div.martor-preview h4+p,
+div.martor-preview h5+p,
+div.martor-preview h6+p {
+ @apply mt-0;
+}
+
+/* List Styles */
+div.martor-preview li p.first {
+ @apply inline-block;
+}
+
+div.martor-preview ul li {
+ @apply list-disc;
+}
+
+div.martor-preview ul,
+div.martor-preview ol {
+ @apply pl-8;
+}
+
+div.martor-preview ul.no-list,
+div.martor-preview ol.no-list {
+ @apply list-none p-0;
+}
+
+div.martor-preview ul li> :first-child,
+div.martor-preview ul li ul:first-of-type,
+div.martor-preview ol li> :first-child,
+div.martor-preview ol li ul:first-of-type {
+ @apply mt-0;
+}
+
+div.martor-preview ul ul,
+div.martor-preview ul ol,
+div.martor-preview ol ol,
+div.martor-preview ol ul {
+ @apply mb-0;
+}
+
+/* Definition Lists */
+div.martor-preview dl {
+ @apply p-0;
+}
+
+div.martor-preview dl dt {
+ @apply text-sm font-bold italic p-0 my-4 mt-0;
+}
+
+div.martor-preview dl dt:first-child {
+ @apply p-0;
+}
+
+div.martor-preview dl dt> :first-child {
+ @apply mt-0;
+}
+
+div.martor-preview dl dt> :last-child {
+ @apply mb-0;
+}
+
+div.martor-preview dl dd {
+ @apply m-0 mb-4 pl-4;
+}
+
+div.martor-preview dl dd> :first-child {
+ @apply mt-0;
+}
+
+div.martor-preview dl dd> :last-child {
+ @apply mb-0;
+}
+
+/* Blockquotes */
+div.martor-preview blockquote {
+ @apply border-l-4 border-gray-300 py-1 px-4 text-gray-500 bg-white;
+}
+
+div.martor-preview blockquote> :first-child {
+ @apply mt-0;
+}
+
+div.martor-preview blockquote> :last-child {
+ @apply mb-0;
+}
+
+/* Tables */
+div.martor-preview table th {
+ @apply font-bold;
+}
+
+div.martor-preview table th,
+div.martor-preview table td {
+ @apply border border-gray-300 py-1.5 px-3;
+}
+
+div.martor-preview table tr {
+ @apply border-t border-gray-300 bg-white;
+}
+
+div.martor-preview table tr:nth-child(2n) {
+ @apply bg-gray-50;
+}
+
+/* Images */
+div.martor-preview img,
+div.martor-preview p img {
+ @apply max-w-full;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+/* Image Frames */
+div.martor-preview span.frame {
+ @apply block overflow-hidden;
+}
+
+div.martor-preview span.frame>span {
+ @apply border border-gray-300 block float-left overflow-hidden my-3 mt-0 p-2 w-auto;
+}
+
+div.martor-preview span.frame span img {
+ @apply block float-left;
+}
+
+div.martor-preview span.frame span span {
+ @apply clear-both text-gray-800 block pt-1 pb-0;
+}
+
+/* Image Alignment */
+div.martor-preview span.align-center {
+ @apply block overflow-hidden clear-both;
+}
+
+div.martor-preview span.align-center>span {
+ @apply block overflow-hidden my-3 mt-0 mx-auto text-center;
+}
+
+div.martor-preview span.align-center span img {
+ @apply mx-auto text-center;
+}
+
+div.martor-preview span.align-right {
+ @apply block overflow-hidden clear-both;
+}
+
+div.martor-preview span.align-right>span {
+ @apply block overflow-hidden my-3 mt-0 text-right;
+}
+
+div.martor-preview span.align-right span img {
+ @apply m-0 text-right;
+}
+
+div.martor-preview span.float-left {
+ @apply block mr-3 overflow-hidden float-left;
+}
+
+div.martor-preview span.float-left span {
+ @apply my-3 mt-0;
+}
+
+div.martor-preview span.float-right {
+ @apply block ml-3 overflow-hidden float-right;
+}
+
+div.martor-preview span.float-right>span {
+ @apply block overflow-hidden my-3 mt-0 mx-auto text-right;
+}
+
+/* Code Styles */
+div.martor-preview code,
+div.martor-preview tt {
+ @apply mx-0.5 py-0 px-1 border border-gray-200 bg-gray-100 rounded;
+}
+
+div.martor-preview code {
+ @apply whitespace-nowrap;
+}
+
+div.martor-preview pre>code {
+ @apply m-0 p-0 whitespace-pre border-0 bg-transparent;
+}
+
+div.martor-preview .highlight pre,
+div.martor-preview pre {
+ @apply border border-gray-200 p-4 overflow-auto text-sm leading-normal bg-gray-50 rounded;
+}
+
+div.martor-preview pre code,
+div.martor-preview pre tt {
+ @apply m-0 p-0 bg-transparent border-0;
+}
diff --git a/martor/static/martor/css/martor.tailwind.min.css b/martor/static/martor/css/martor.tailwind.min.css
new file mode 100644
index 00000000..f7fa99c6
--- /dev/null
+++ b/martor/static/martor/css/martor.tailwind.min.css
@@ -0,0 +1,401 @@
+body.overflow {
+ overflow: hidden !important
+}
+
+.martor {
+ @apply h-[500px] max-h-[500px]
+}
+
+.martor-field {
+ @apply w-full h-64 min-h-[100px] resize-y border-r border-b border-gray-300
+}
+
+.main-martor {
+ @apply my-4 relative
+}
+
+.main-martor .modal-header {
+ @apply p-2 px-4
+}
+
+.main-martor .modal-header h5 {
+ @apply text-base
+}
+
+.main-martor .upload-progress {
+ @apply absolute z-[100] w-full h-full pt-20 bg-black bg-opacity-85 text-white text-center
+}
+
+.martor-toolbar {
+ @apply z-[100]
+}
+
+.enable-living .martor-toolbar {
+ @apply relative
+}
+
+.martor-toolbar .markdown-image-upload {
+ @apply relative overflow-hidden
+}
+
+.martor-toolbar .markdown-image-upload input[type=file] {
+ @apply absolute top-0 right-0 w-full h-full text-2xl p-0 pl-9 text-right opacity-0 outline-none cursor-pointer block;
+ min-width: 100%;
+ min-height: 100%;
+ filter: alpha(opacity=0)
+}
+
+.emoji-loader-init {
+ min-height: 200px !important;
+ @apply pt-16
+}
+
+.emoji-content-body {
+ @apply text-xs
+}
+
+.insert-emoji {
+ @apply cursor-pointer no-underline
+}
+
+.table.markdown-reference {
+ @apply text-xs
+}
+
+.table.markdown-reference h1 {
+ @apply text-2xl
+}
+
+.table.markdown-reference h2 {
+ @apply text-xl
+}
+
+.table.markdown-reference ul, .table.markdown-reference ol {
+ @apply pl-4
+}
+
+div.martor-preview {
+ @apply p-4 overflow-auto bg-gray-50
+}
+
+div.martor-preview-stale {
+ background: repeating-linear-gradient(-45deg, #fff, #fff 10px, #f8f8f8 10px, #f8f8f8 20px) !important
+}
+
+.main-martor .nav-tabs {
+ @apply border-b-2 border-gray-200
+}
+
+.main-martor .nav-tabs .nav-link:hover, .main-martor .nav-tabs .nav-link:focus {
+ @apply border-transparent
+}
+
+.main-martor .nav-tabs .nav-item.show .nav-link, .main-martor .nav-tabs .nav-link.active, .main-martor .nav-tabs .nav-link.active:hover {
+ @apply border-transparent border-b-2 border-gray-800 text-gray-700
+}
+
+.main-martor .tab-pane {
+ @apply relative
+}
+
+.icon.expand-editor {
+ @apply absolute -bottom-2 right-2 z-[100]
+}
+
+.no-border {
+ @apply border-0
+}
+
+div.enable-living .martor-preview {
+ @apply block opacity-100 mt-4 border border-gray-200 rounded-md
+}
+
+div.enable-living .tab-martor-menu a.nav-link {
+ @apply hidden
+}
+
+.section-martor ::-webkit-scrollbar-track {
+ -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
+ @apply rounded-lg bg-gray-100
+}
+
+.section-martor ::-webkit-scrollbar {
+ @apply h-1.5 w-1.5 bg-gray-100
+}
+
+.section-martor ::-webkit-scrollbar-thumb {
+ @apply rounded-lg bg-gray-600;
+ -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3)
+}
+
+.ace_scrollbar-v {
+ cursor: ns-resize
+}
+
+.main-martor-fullscreen {
+ @apply bg-white fixed z-[9999] max-h-full h-full w-full m-0 left-0 top-0
+}
+
+.main-martor-fullscreen .fields.martor-toolbar {
+ @apply border-b border-gray-300 m-0
+}
+
+.main-martor-fullscreen .section-martor {
+ @apply h-[90%] relative
+}
+
+.main-martor-fullscreen .martor-field, .main-martor-fullscreen div.martor-preview {
+ min-height: 95vh
+}
+
+.marked-emoji,
+div.martor-preview .marked-emoji {
+ @apply max-w-5
+}
+
+div.martor-preview {
+ @apply text-sm leading-relaxed
+}
+
+div.martor-preview>*:first-child {
+ @apply mt-0
+}
+
+div.martor-preview>*:last-child {
+ @apply mb-5
+}
+
+div.martor-preview a.absent {
+ @apply text-red-600
+}
+
+div.martor-preview a.anchor {
+ @apply block pl-8 -ml-8 cursor-pointer absolute top-0 left-0 bottom-0
+}
+
+div.martor-preview h1, div.martor-preview h2, div.martor-preview h3, div.martor-preview h4, div.martor-preview h5, div.martor-preview h6 {
+ @apply my-5 mb-2 p-0 font-bold cursor-text relative;
+ -webkit-font-smoothing: antialiased;
+ background: none
+}
+
+div.martor-preview h1:hover a.anchor,
+div.martor-preview h2:hover a.anchor,
+div.martor-preview h3:hover a.anchor,
+div.martor-preview h4:hover a.anchor,
+div.martor-preview h5:hover a.anchor,
+div.martor-preview h6:hover a.anchor {
+ @apply no-underline leading-none pl-0 -ml-6;
+ top: 15%
+}
+
+div.martor-preview h1 {
+ @apply text-3xl text-black
+}
+
+div.martor-preview h2 {
+ @apply text-2xl text-black
+}
+
+div.martor-preview h3 {
+ @apply text-lg
+}
+
+div.martor-preview h4 {
+ @apply text-base
+}
+
+div.martor-preview h5 {
+ @apply text-sm
+}
+
+div.martor-preview h6 {
+ @apply text-gray-500 text-sm
+}
+
+div.martor-preview p, div.martor-preview blockquote, div.martor-preview ul, div.martor-preview ol, div.martor-preview dl, div.martor-preview table, div.martor-preview pre {
+ @apply my-4
+}
+
+div.martor-preview hr {
+ background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxBEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;
+ @apply border-0 text-gray-300 h-1 p-0
+}
+
+div.martor-preview>h2:first-child, div.martor-preview>h1:first-child, div.martor-preview>h1:first-child+h2, div.martor-preview>h3:first-child, div.martor-preview>h4:first-child, div.martor-preview>h5:first-child, div.martor-preview>h6:first-child {
+ @apply mt-0 pt-0
+}
+
+div.martor-preview a:first-child h1, div.martor-preview a:first-child h2, div.martor-preview a:first-child h3, div.martor-preview a:first-child h4, div.martor-preview a:first-child h5, div.martor-preview a:first-child h6 {
+ @apply mt-0 pt-0
+}
+
+div.martor-preview h1+p, div.martor-preview h2+p, div.martor-preview h3+p, div.martor-preview h4+p, div.martor-preview h5+p, div.martor-preview h6+p {
+ @apply mt-0
+}
+
+div.martor-preview li p.first {
+ @apply inline-block
+}
+
+div.martor-preview ul li {
+ @apply list-disc
+}
+
+div.martor-preview ul, div.martor-preview ol {
+ @apply pl-8
+}
+
+div.martor-preview ul.no-list, div.martor-preview ol.no-list {
+ @apply list-none p-0
+}
+
+div.martor-preview ul li>:first-child, div.martor-preview ul li ul:first-of-type, div.martor-preview ol li>:first-child, div.martor-preview ol li ul:first-of-type {
+ @apply mt-0
+}
+
+div.martor-preview ul ul, div.martor-preview ul ol, div.martor-preview ol ol, div.martor-preview ol ul {
+ @apply mb-0
+}
+
+div.martor-preview dl {
+ @apply p-0
+}
+
+div.martor-preview dl dt {
+ @apply text-sm font-bold italic p-0 my-4 mt-0
+}
+
+div.martor-preview dl dt:first-child {
+ @apply p-0
+}
+
+div.martor-preview dl dt>:first-child {
+ @apply mt-0
+}
+
+div.martor-preview dl dt>:last-child {
+ @apply mb-0
+}
+
+div.martor-preview dl dd {
+ @apply m-0 mb-4 pl-4
+}
+
+div.martor-preview dl dd>:first-child {
+ @apply mt-0
+}
+
+div.martor-preview dl dd>:last-child {
+ @apply mb-0
+}
+
+div.martor-preview blockquote {
+ @apply border-l-4 border-gray-300 py-1 px-4 text-gray-500 bg-white
+}
+
+div.martor-preview blockquote>:first-child {
+ @apply mt-0
+}
+
+div.martor-preview blockquote>:last-child {
+ @apply mb-0
+}
+
+div.martor-preview table th {
+ @apply font-bold
+}
+
+div.martor-preview table th, div.martor-preview table td {
+ @apply border border-gray-300 py-1.5 px-3
+}
+
+div.martor-preview table tr {
+ @apply border-t border-gray-300 bg-white
+}
+
+div.martor-preview table tr:nth-child(2n) {
+ @apply bg-gray-50
+}
+
+div.martor-preview img, div.martor-preview p img {
+ @apply max-w-full;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box
+}
+
+div.martor-preview span.frame {
+ @apply block overflow-hidden
+}
+
+div.martor-preview span.frame>span {
+ @apply border border-gray-300 block float-left overflow-hidden my-3 mt-0 p-2 w-auto
+}
+
+div.martor-preview span.frame span img {
+ @apply block float-left
+}
+
+div.martor-preview span.frame span span {
+ @apply clear-both text-gray-800 block pt-1 pb-0
+}
+
+div.martor-preview span.align-center {
+ @apply block overflow-hidden clear-both
+}
+
+div.martor-preview span.align-center>span {
+ @apply block overflow-hidden my-3 mt-0 mx-auto text-center
+}
+
+div.martor-preview span.align-center span img {
+ @apply mx-auto text-center
+}
+
+div.martor-preview span.align-right {
+ @apply block overflow-hidden clear-both
+}
+
+div.martor-preview span.align-right>span {
+ @apply block overflow-hidden my-3 mt-0 text-right
+}
+
+div.martor-preview span.align-right span img {
+ @apply m-0 text-right
+}
+
+div.martor-preview span.float-left {
+ @apply block mr-3 overflow-hidden float-left
+}
+
+div.martor-preview span.float-left span {
+ @apply my-3 mt-0
+}
+
+div.martor-preview span.float-right {
+ @apply block ml-3 overflow-hidden float-right
+}
+
+div.martor-preview span.float-right>span {
+ @apply block overflow-hidden my-3 mt-0 mx-auto text-right
+}
+
+div.martor-preview code, div.martor-preview tt {
+ @apply mx-0.5 py-0 px-1 border border-gray-200 bg-gray-100 rounded
+}
+
+div.martor-preview code {
+ @apply whitespace-nowrap
+}
+
+div.martor-preview pre>code {
+ @apply m-0 p-0 whitespace-pre border-0 bg-transparent
+}
+
+div.martor-preview .highlight pre, div.martor-preview pre {
+ @apply border border-gray-200 p-4 overflow-auto text-sm leading-normal bg-gray-50 rounded
+}
+
+div.martor-preview pre code, div.martor-preview pre tt {
+ @apply m-0 p-0 bg-transparent border-0
+}
diff --git a/martor/static/martor/js/martor.tailwind.js b/martor/static/martor/js/martor.tailwind.js
new file mode 100644
index 00000000..9b1642e8
--- /dev/null
+++ b/martor/static/martor/js/martor.tailwind.js
@@ -0,0 +1,659 @@
+/**
+ * Name : Martor v1.6.45 (Tailwind CSS Version)
+ * Created by : Agus Makmun (Summon Agus)
+ * Release date : 15-Nov-2024
+ * License : GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
+ * Repository : https://github.com/agusmakmun/django-markdown-editor
+ * Theme : Tailwind CSS
+**/
+
+(function ($) {
+ if (!$) {
+ $ = django.jQuery;
+ }
+ $.fn.martor = function () {
+ $('.martor').trigger('martor.init');
+
+ // Tailwind-specific utility functions
+ var TailwindUtils = {
+ showElement: function(element) {
+ $(element).removeClass('hidden').addClass('block');
+ },
+ hideElement: function(element) {
+ $(element).removeClass('block').addClass('hidden');
+ },
+ showModal: function(element) {
+ $(element).removeClass('hidden').addClass('flex');
+ $('body').addClass('overflow-hidden');
+ },
+ hideModal: function(element) {
+ $(element).removeClass('flex').addClass('hidden');
+ $('body').removeClass('overflow-hidden');
+ },
+ toggleTab: function(activeTab, activeContent, inactiveTabs, inactiveContents) {
+ // Hide all tabs and contents
+ $(inactiveTabs).removeClass('border-b-2 border-gray-800 text-gray-700').addClass('text-gray-500');
+ $(inactiveContents).removeClass('block').addClass('hidden');
+
+ // Show active tab and content
+ $(activeTab).removeClass('text-gray-500').addClass('border-b-2 border-gray-800 text-gray-700');
+ $(activeContent).removeClass('hidden').addClass('block');
+ }
+ };
+
+ // CSRF code
+ var getCookie = function (name) {
+ var cookieValue = null;
+ var i = 0;
+ if (document.cookie && document.cookie !== '') {
+ var cookies = document.cookie.split(';');
+ for (i; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) === (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+ };
+
+ // Each multiple editor fields
+ this.each(function (i, obj) {
+ var mainMartor = $(obj);
+ var field_name = mainMartor.data('field-name');
+ var textareaId = $('#id_' + field_name);
+ var editorId = 'martor-' + field_name;
+ var editor = ace.edit(editorId);
+ var editorConfig = JSON.parse(textareaId.data('enable-configs').replace(/'/g, '"'));
+
+ editor.setTheme('ace/theme/github');
+ editor.getSession().setMode('ace/mode/markdown');
+ editor.getSession().setUseWrapMode(true);
+ editor.$blockScrolling = Infinity; // prevents ace from logging annoying warnings
+ editor.renderer.setScrollMargin(10, 10); // set padding
+ editor.setAutoScrollEditorIntoView(true);
+ editor.setShowPrintMargin(false);
+ editor.setOptions({
+ enableBasicAutocompletion: true,
+ enableSnippets: true,
+ enableLiveAutocompletion: true,
+ enableMultiselect: false
+ });
+
+ if (editorConfig.living == 'true') {
+ $(obj).addClass('enable-living');
+ }
+
+ var emojiWordCompleter = {
+ getCompletions: function (editor, session, pos, prefix, callback) {
+ var wordList = typeof (emojis) != "undefined" ? emojis : []; // from `atwho/emojis.min.js`
+ var obj = editor.getSession().getTokenAt(pos.row, pos.column.count);
+ if (typeof (obj.value) != "undefined") {
+ var curTokens = obj.value.split(/\s+/);
+ var lastToken = curTokens[curTokens.length - 1];
+
+ if (lastToken[0] == ':') {
+ callback(null, wordList.map(function (word) {
+ return {
+ caption: word,
+ value: word.replace(':', '') + ' ',
+ meta: 'emoji' // this should return as text only.
+ };
+ }));
+ }
+ }
+ }
+ }
+ var mentionWordCompleter = {
+ getCompletions: function (editor, session, pos, prefix, callback) {
+ var obj = editor.getSession().getTokenAt(pos.row, pos.column.count);
+ if (typeof (obj.value) != "undefined") {
+ var curTokens = obj.value.split(/\s+/);
+ var lastToken = curTokens[curTokens.length - 1];
+
+ if (lastToken[0] == '@' && lastToken[1] == '[') {
+ username = lastToken.replace(/([\@\[/\]/])/g, '');
+ $.ajax({
+ url: textareaId.data('search-users-url'),
+ data: {
+ 'username': username,
+ 'csrfmiddlewaretoken': getCookie('csrftoken')
+ },
+ success: function (data) {
+ if (data['status'] == 200) {
+ var wordList = [];
+ for (var i = 0; i < data['data'].length; i++) {
+ wordList.push('@[' + data['data'][i] + ']')
+ }
+ callback(null, wordList.map(function (word) {
+ return {
+ caption: word,
+ value: word + ' ',
+ meta: 'users'
+ };
+ }));
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+
+ // assign all `field_name`, uses for a per-single editor.
+ $(obj).find('.martor-toolbar').find('.markdown-selector').attr({ 'data-field-name': field_name });
+ $(obj).find('.upload-progress').attr({ 'data-field-name': field_name });
+ $(obj).find('.modal-help-guide').attr({ 'data-field-name': field_name });
+ $(obj).find('.modal-emoji').attr({ 'data-field-name': field_name });
+
+ // Set if editor has changed.
+ editor.on('change', function (evt) {
+ var content = editor.getSession().getValue();
+ textareaId.val(content);
+
+ // for validate markdown
+ textareaId.parent().find('.invalid-feedback').remove();
+ textareaId.parent().removeClass('has-error');
+
+ // Auto update preview in realtime when editor activated
+ if (editorConfig.living == 'true' && content.length > 0) {
+ var preview_tab = $('.tab-preview-' + field_name);
+ markdownfy(textareaId, preview_tab, false);
+ }
+ });
+
+ // spellcheck
+ if (editorConfig.spellcheck == 'true') {
+ langTools = ace.require("ace/ext/language_tools");
+ // NOTE: install typo.js first. https://github.com/cfinke/Typo.js
+ // use `pip install typojs`
+ var spellcheck = function (content) {
+ var us_dict = new Typo("en_US", false, false, { dictionaryPath: "dicts" });
+ var wordList = content.split(/\s+/);
+ var suggestions = [];
+
+ for (var i in wordList) {
+ var word = wordList[i];
+
+ // Check if our word contains a character that isn't a letter or an apostrophe.
+ var nonWord = word.match(/[^a-zA-Z']/);
+ if (!nonWord && word && !us_dict.check(word)) {
+ var sugg = us_dict.suggest(word);
+
+ if (sugg.length > 0) {
+ suggestions.push({
+ word: word,
+ suggestions: sugg
+ });
+ }
+ }
+ }
+
+ return suggestions;
+ };
+
+ var spellcheckCompleter = {
+ getCompletions: function (editor, session, pos, prefix, callback) {
+ var content = session.getValue();
+ var suggestions = spellcheck(content);
+ var wordList = [];
+
+ suggestions.forEach(function (suggestion) {
+ suggestion.suggestions.forEach(function (word) {
+ wordList.push(word);
+ });
+ });
+
+ callback(null, wordList.map(function (word) {
+ return {
+ caption: word,
+ value: word,
+ meta: 'spell'
+ };
+ }));
+ }
+ };
+ langTools.addCompleter(spellcheckCompleter);
+ }
+
+ var editorTabButton = $('.tab-editor-' + field_name);
+ editorTabButton.click(function () {
+ // show the `.martor-toolbar` for this current editor if under preview.
+ $(this).closest('.tab-martor-menu').find('.martor-toolbar').show();
+ });
+
+ // Tailwind-specific tab handling
+ $('.tab-editor-' + field_name).click(function() {
+ var editorContent = $('#editor-content-' + field_name);
+ var previewContent = $('#preview-content-' + field_name);
+ var previewTab = $('.tab-preview-' + field_name);
+
+ TailwindUtils.toggleTab(
+ this,
+ editorContent,
+ previewTab,
+ previewContent
+ );
+ });
+
+ $('.tab-preview-' + field_name).click(function() {
+ var editorContent = $('#editor-content-' + field_name);
+ var previewContent = '#preview-content-' + field_name;
+ var editorTab = $('.tab-editor-' + field_name);
+
+ TailwindUtils.toggleTab(
+ this,
+ previewContent,
+ editorTab,
+ editorContent
+ );
+
+ // hide the `.martor-toolbar` when activating tab preview.
+ $(this).closest('.tab-martor-menu').find('.martor-toolbar').hide();
+ markdownfy(textareaId, $(previewContent), true);
+ });
+
+ if (editorConfig.emoji == 'true') {
+ langTools = ace.require("ace/ext/language_tools");
+ langTools.addCompleter(emojiWordCompleter);
+ }
+
+ if (editorConfig.mention == 'true') {
+ langTools = ace.require("ace/ext/language_tools");
+ langTools.addCompleter(mentionWordCompleter);
+ }
+
+ // The Markdown function.
+ function markdownfy(textareaId, previewBox, isTabPreview) {
+ var text = textareaId.val();
+ var isLivePreview = editorConfig.living == 'true';
+
+ if (text.length > 0) {
+ var timeout = textareaId.data('save-timeout');
+ var markdownfyUrl = textareaId.data('markdownfy-url');
+
+ if (!isLivePreview && isTabPreview) {
+ previewBox.html('Processing...
');
+ }
+
+ setTimeout(function () {
+ $.ajax({
+ url: markdownfyUrl,
+ type: 'POST',
+ data: {
+ 'content': text,
+ 'csrfmiddlewaretoken': getCookie('csrftoken')
+ },
+ success: function (data) {
+ var content = data['content'];
+ previewBox.html(content);
+
+ // add class `.martor-preview` to applying the css.
+ previewBox.addClass('martor-preview');
+
+ // Scroll into bottom of preview only for non-living mode
+ if (!isLivePreview && isTabPreview) {
+ previewBox.animate({ scrollTop: previewBox[0].scrollHeight }, 800);
+ }
+
+ // Re-parse highlight on preview pane again.
+ if (typeof (hljs) !== "undefined") {
+ previewBox.find('pre code').each(function (i, block) {
+ hljs.highlightBlock(block);
+ });
+ }
+ }
+ });
+ }, timeout);
+ } else {
+ previewBox.html('Nothing to preview
');
+ }
+ }
+
+ // Handle toolbar dropdowns for Tailwind
+ $('.martor-toolbar .dropdown').each(function() {
+ var dropdown = $(this);
+ var toggle = dropdown.find('.dropdown-toggle');
+ var menu = dropdown.find('.dropdown-menu');
+
+ toggle.click(function(e) {
+ e.preventDefault();
+ e.stopPropagation();
+
+ // Close other dropdowns
+ $('.martor-toolbar .dropdown-menu').not(menu).addClass('hidden');
+
+ // Toggle current dropdown
+ menu.toggleClass('hidden');
+ });
+
+ // Close dropdown when clicking outside
+ $(document).click(function(e) {
+ if (!dropdown.is(e.target) && dropdown.has(e.target).length === 0) {
+ menu.addClass('hidden');
+ }
+ });
+ });
+
+ // Modal Popup for Help Guide & Emoji Cheat Sheet
+ $('.markdown-help[data-field-name=' + field_name + ']').click(function () {
+ TailwindUtils.showModal('.modal-help-guide[data-field-name=' + field_name + ']');
+ });
+
+ // Close modal functionality
+ $('.modal-help-guide[data-field-name=' + field_name + '] .modal-close').click(function () {
+ TailwindUtils.hideModal('.modal-help-guide[data-field-name=' + field_name + ']');
+ });
+
+ // Toggle editor, preview, maximize
+ $('.markdown-toggle-maximize[data-field-name=' + field_name + ']').click(function () {
+ if ($(obj).hasClass('main-martor-fullscreen')) {
+ $(obj).removeClass('main-martor-fullscreen');
+ $('body').removeClass('overflow-hidden');
+ } else {
+ $(obj).addClass('main-martor-fullscreen');
+ $('body').addClass('overflow-hidden');
+ }
+ });
+
+ // markdown insert emoji from the modal
+ $('.markdown-emoji[data-field-name=' + field_name + ']').click(function () {
+ var modalEmoji = $('.modal-emoji[data-field-name=' + field_name + ']');
+ var emojiList = typeof (emojis) != "undefined" ? emojis : []; // from `plugins/js/emojis.min.js`
+ var segmentEmoji = modalEmoji.find('.emoji-content-body');
+ var loaderInit = modalEmoji.find('.emoji-loader-init');
+
+ // setup initial loader
+ segmentEmoji.html('');
+ TailwindUtils.showElement(loaderInit);
+ TailwindUtils.showModal(modalEmoji);
+
+ setTimeout(function() {
+ for (var i = 0; i < emojiList.length; i++) {
+ var linkEmoji = textareaId.data('base-emoji-url') + emojiList[i].replace(/:/g, '') + '.png';
+ segmentEmoji.append('');
+ $('a[data-emoji-target="' + emojiList[i] + '"]').click(function () {
+ markdownToEmoji(editor, $(this).data('emoji-target'));
+ TailwindUtils.hideModal(modalEmoji);
+ });
+ }
+ TailwindUtils.hideElement(loaderInit);
+ TailwindUtils.showElement(segmentEmoji);
+ }, 100);
+ });
+
+ // Close emoji modal
+ $('.modal-emoji[data-field-name=' + field_name + '] .modal-close').click(function () {
+ TailwindUtils.hideModal('.modal-emoji[data-field-name=' + field_name + ']');
+ });
+
+ // Set initial value if has the content before.
+ editor.setValue(textareaId.val(), -1);
+
+ // Upload Image
+ // reference: https://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously
+ var uploadProgress = $('.upload-progress[data-field-name=' + field_name + ']');
+ $(obj).find('input[name=markdown-image-upload]').change(function () {
+ if ($(this).val() === '') {
+ return;
+ }
+
+ var formData = new FormData();
+ var imageName = $(this)[0].files[0].name;
+ var imageFile = $(this)[0].files[0];
+ var imageSize = $(this)[0].files[0].size;
+ var maxFileSize = 1024 * 1024 * 10; // 10MB
+
+ if (imageSize > maxFileSize) {
+ alert('Image size too large. Maximum file size is 10MB.');
+ return;
+ }
+
+ formData.append('markdown-image-upload', imageFile);
+ formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
+
+ TailwindUtils.showElement(uploadProgress);
+
+ $.ajax({
+ url: textareaId.data('upload-url'),
+ type: 'POST',
+ data: formData,
+ processData: false,
+ contentType: false,
+ beforeSend: function () {
+ uploadProgress.find('.spinner').removeClass('hidden');
+ },
+ success: function (data) {
+ if (data['status'] == 200) {
+ var imageUrl = data['image_url'];
+ markdownToImageLink(editor, imageName, imageUrl);
+ } else {
+ alert(data['error']);
+ }
+ TailwindUtils.hideElement(uploadProgress);
+ },
+ error: function (xhr, textStatus, errorThrown) {
+ alert('Image upload failed: ' + errorThrown);
+ TailwindUtils.hideElement(uploadProgress);
+ }
+ });
+ });
+
+ // All the markdowns selector object
+ var MarkdownSelectors = {
+ bold: function () {
+ markdownSyntaxWrap(editor, '**', '**', 'Bolded text');
+ },
+ italic: function () {
+ markdownSyntaxWrap(editor, '*', '*', 'Italicized text');
+ },
+ horizontal: function () {
+ markdownSyntaxWrap(editor, '', '\n***\n', '');
+ },
+ h1: function () {
+ markdownSyntaxWrap(editor, '# ', '', 'Heading 1');
+ },
+ h2: function () {
+ markdownSyntaxWrap(editor, '## ', '', 'Heading 2');
+ },
+ h3: function () {
+ markdownSyntaxWrap(editor, '### ', '', 'Heading 3');
+ },
+ pre: function () {
+ markdownSyntaxWrap(editor, '```\n', '\n```\n', 'Code goes here...');
+ },
+ code: function () {
+ markdownSyntaxWrap(editor, '`', '`', 'Code goes here...');
+ },
+ quote: function () {
+ markdownSyntaxWrap(editor, '> ', '', 'Quoted text');
+ },
+ ul: function () {
+ markdownSyntaxWrap(editor, '* ', '', 'List item');
+ },
+ ol: function () {
+ markdownSyntaxWrap(editor, '1. ', '', 'List item');
+ },
+ link: function () {
+ markdownSyntaxWrap(editor, '[', '](http://)', 'link text');
+ },
+ image: function () {
+ markdownSyntaxWrap(editor, '', 'image text');
+ },
+ mention: function () {
+ markdownToDirectMention(editor);
+ },
+ emoji: function () {
+ $('.markdown-emoji[data-field-name=' + field_name + ']').trigger('click');
+ },
+ toggle: function () {
+ $('.markdown-toggle-maximize[data-field-name=' + field_name + ']').trigger('click');
+ },
+ help: function () {
+ $('.markdown-help[data-field-name=' + field_name + ']').trigger('click');
+ }
+ };
+
+ // Markdowns selectors click events
+ $(obj).find('.markdown-bold').click(function () { MarkdownSelectors.bold(); });
+ $(obj).find('.markdown-italic').click(function () { MarkdownSelectors.italic(); });
+ $(obj).find('.markdown-horizontal').click(function () { MarkdownSelectors.horizontal(); });
+ $(obj).find('.markdown-h1').click(function () { MarkdownSelectors.h1(); });
+ $(obj).find('.markdown-h2').click(function () { MarkdownSelectors.h2(); });
+ $(obj).find('.markdown-h3').click(function () { MarkdownSelectors.h3(); });
+ $(obj).find('.markdown-pre').click(function () { MarkdownSelectors.pre(); });
+ $(obj).find('.markdown-code').click(function () { MarkdownSelectors.code(); });
+ $(obj).find('.markdown-blockquote').click(function () { MarkdownSelectors.quote(); });
+ $(obj).find('.markdown-unordered-list').click(function () { MarkdownSelectors.ul(); });
+ $(obj).find('.markdown-ordered-list').click(function () { MarkdownSelectors.ol(); });
+ $(obj).find('.markdown-link').click(function () { MarkdownSelectors.link(); });
+ $(obj).find('.markdown-image-link').click(function () { MarkdownSelectors.image(); });
+ $(obj).find('.markdown-direct-mention').click(function () { MarkdownSelectors.mention(); });
+ $(obj).find('.markdown-emoji').click(function () { MarkdownSelectors.emoji(); });
+ $(obj).find('.markdown-toggle-maximize').click(function () { MarkdownSelectors.toggle(); });
+ $(obj).find('.markdown-help').click(function () { MarkdownSelectors.help(); });
+
+ // Markdowns shorcuts key
+ editor.commands.addCommand({
+ name: 'bold',
+ bindKey: { win: 'Ctrl-B', mac: 'Command-B' },
+ exec: function (editor) { MarkdownSelectors.bold(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'italic',
+ bindKey: { win: 'Ctrl-I', mac: 'Command-I' },
+ exec: function (editor) { MarkdownSelectors.italic(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'horizontal',
+ bindKey: { win: 'Ctrl-H', mac: 'Command-H' },
+ exec: function (editor) { MarkdownSelectors.horizontal(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'h1',
+ bindKey: { win: 'Ctrl-Alt-1', mac: 'Command-Alt-1' },
+ exec: function (editor) { MarkdownSelectors.h1(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'h2',
+ bindKey: { win: 'Ctrl-Alt-2', mac: 'Command-Alt-2' },
+ exec: function (editor) { MarkdownSelectors.h2(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'h3',
+ bindKey: { win: 'Ctrl-Alt-3', mac: 'Command-Alt-3' },
+ exec: function (editor) { MarkdownSelectors.h3(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'pre',
+ bindKey: { win: 'Ctrl-Alt-P', mac: 'Command-Alt-P' },
+ exec: function (editor) { MarkdownSelectors.pre(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'code',
+ bindKey: { win: 'Ctrl-Alt-C', mac: 'Command-Alt-C' },
+ exec: function (editor) { MarkdownSelectors.code(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'quote',
+ bindKey: { win: 'Ctrl-Q', mac: 'Command-Q' },
+ exec: function (editor) { MarkdownSelectors.quote(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'ul',
+ bindKey: { win: 'Ctrl-U', mac: 'Command-U' },
+ exec: function (editor) { MarkdownSelectors.ul(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'ol',
+ bindKey: { win: 'Ctrl-Shift-O', mac: 'Command-Shift-O' },
+ exec: function (editor) { MarkdownSelectors.ol(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'link',
+ bindKey: { win: 'Ctrl-L', mac: 'Command-L' },
+ exec: function (editor) { MarkdownSelectors.link(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'image',
+ bindKey: { win: 'Ctrl-Shift-I', mac: 'Command-Shift-I' },
+ exec: function (editor) { MarkdownSelectors.image(); },
+ readOnly: false
+ });
+ editor.commands.addCommand({
+ name: 'mention',
+ bindKey: { win: 'Ctrl-M', mac: 'Command-M' },
+ exec: function (editor) { MarkdownSelectors.mention(); },
+ readOnly: false
+ });
+ });
+
+ // Global function for markdown syntax wrapping
+ function markdownSyntaxWrap(editor, startTag, endTag, defaultText) {
+ var selectedText = editor.getSelectedText();
+ var text = selectedText || defaultText;
+ var range = editor.getSelectionRange();
+
+ if (selectedText.length === 0) {
+ // If no selection, place cursor between tags
+ editor.session.replace(range, startTag + text + endTag);
+ var newPos = range.start;
+ newPos.column += startTag.length;
+ editor.moveCursorToPosition(newPos);
+ editor.clearSelection();
+ } else {
+ // If text is selected, wrap it with tags
+ editor.session.replace(range, startTag + text + endTag);
+ }
+ editor.focus();
+ }
+
+ // markdown to image link
+ function markdownToImageLink(editor, imageName, imageUrl) {
+ var text = '';
+ var range = editor.getSelectionRange();
+ editor.session.replace(range, text);
+ editor.focus();
+ }
+
+ // markdown to emoji
+ function markdownToEmoji(editor, emojiName) {
+ var text = emojiName + ' ';
+ var range = editor.getSelectionRange();
+ editor.session.replace(range, text);
+ editor.focus();
+ }
+
+ // markdown to direct mention
+ function markdownToDirectMention(editor) {
+ var text = '@[username] ';
+ var range = editor.getSelectionRange();
+ editor.session.replace(range, text);
+
+ // Select the "username" part for easy replacement
+ var newRange = range;
+ newRange.start.column += 2; // position after @[
+ newRange.end.column += 10; // position before ]
+ editor.selection.setRange(newRange);
+ editor.focus();
+ }
+ };
+})(jQuery);
diff --git a/martor/static/martor/js/martor.tailwind.min.js b/martor/static/martor/js/martor.tailwind.min.js
new file mode 100644
index 00000000..d6d34d1b
--- /dev/null
+++ b/martor/static/martor/js/martor.tailwind.min.js
@@ -0,0 +1,5 @@
+/**
+ * Martor v1.6.45 (Tailwind CSS Version) - Minified
+ * License: GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
+**/
+!function(e){e=e||django.jQuery,e.fn.martor=function(){e(".martor").trigger("martor.init");var t={showElement:function(t){e(t).removeClass("hidden").addClass("block")},hideElement:function(t){e(t).removeClass("block").addClass("hidden")},showModal:function(t){e(t).removeClass("hidden").addClass("flex"),e("body").addClass("overflow-hidden")},hideModal:function(t){e(t).removeClass("flex").addClass("hidden"),e("body").removeClass("overflow-hidden")},toggleTab:function(t,n,o,r){e(o).removeClass("border-b-2 border-gray-800 text-gray-700").addClass("text-gray-500"),e(r).removeClass("block").addClass("hidden"),e(t).removeClass("text-gray-500").addClass("border-b-2 border-gray-800 text-gray-700"),e(n).removeClass("hidden").addClass("block")}},n=function(e){var t=null,n=0;if(document.cookie&&""!==document.cookie)for(var o=document.cookie.split(";");n0){var s=o.data("save-timeout"),d=o.data("markdownfy-url");l||!r||r.html('Processing...
'),setTimeout(function(){e.ajax({url:d,type:"POST",data:{content:c,csrfmiddlewaretoken:n("csrftoken")},success:function(e){var n=e.content;r.html(n),r.addClass("martor-preview"),l||!r||r.animate({scrollTop:r[0].scrollHeight},800),"undefined"!=typeof hljs&&r.find("pre code").each(function(e,t){hljs.highlightBlock(t)})}})},s)}else r.html('Nothing to preview
')}this.each(function(l,s){var d=e(s),u=d.data("field-name"),m=e("#id_"+u),f="martor-"+u,h=ace.edit(f),g=JSON.parse(m.data("enable-configs").replace(/'/g,'"'));h.setTheme("ace/theme/github"),h.getSession().setMode("ace/mode/markdown"),h.getSession().setUseWrapMode(!0),h.$blockScrolling=1/0,h.renderer.setScrollMargin(10,10),h.setAutoScrollEditorIntoView(!0),h.setShowPrintMargin(!1),h.setOptions({enableBasicAutocompletion:!0,enableSnippets:!0,enableLiveAutocompletion:!0,enableMultiselect:!1}),"true"==g.living&&e(s).addClass("enable-living");var p={getCompletions:function(e,t,n,o,r){var a="undefined"!=typeof emojis?emojis:[],i=e.getSession().getTokenAt(n.row,n.column.count);if("undefined"!=typeof i.value){var c=i.value.split(/\s+/);c[c.length-1][0]==":"&&r(null,a.map(function(e){return{caption:e,value:e.replace(":","")+" ",meta:"emoji"}}))}}},v={getCompletions:function(t,o,r,a,i){var c=t.getSession().getTokenAt(r.row,r.column.count);if("undefined"!=typeof c.value){var l=c.value.split(/\s+/),s=l[l.length-1];if("@"==s[0]&&"["==s[1]){username=s.replace(/([\@\[\/\]/])/g,""),e.ajax({url:m.data("search-users-url"),data:{username:username,csrfmiddlewaretoken:n("csrftoken")},success:function(e){if(200==e.status){for(var t=[],n=0;n0&&c(m,e(".tab-preview-"+u),!1)});var b=e(".tab-editor-"+u);b.click(function(){e(this).closest(".tab-martor-menu").find(".martor-toolbar").show()}),e(".tab-editor-"+u).click(function(){var n=e("#editor-content-"+u),o=e("#preview-content-"+u),r=e(".tab-preview-"+u);t.toggleTab(this,n,r,o)}),e(".tab-preview-"+u).click(function(){var n=e("#editor-content-"+u),o="#preview-content-"+u,r=e(".tab-editor-"+u);t.toggleTab(this,o,r,n),e(this).closest(".tab-martor-menu").find(".martor-toolbar").hide(),c(m,e(o),!0)}),"true"==g.emoji&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(p)),"true"==g.mention&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(v)),e(".martor-toolbar .dropdown").each(function(){var t=e(this),n=t.find(".dropdown-toggle"),o=t.find(".dropdown-menu");n.click(function(n){n.preventDefault(),n.stopPropagation(),e(".martor-toolbar .dropdown-menu").not(o).addClass("hidden"),o.toggleClass("hidden")}),e(document).click(function(e){t.is(e.target)||0!==t.has(e.target).length||o.addClass("hidden")})}),e(".markdown-help[data-field-name="+u+"]").click(function(){t.showModal(".modal-help-guide[data-field-name="+u+"]")}),e(".modal-help-guide[data-field-name="+u+"] .modal-close").click(function(){t.hideModal(".modal-help-guide[data-field-name="+u+"]")}),e(".markdown-toggle-maximize[data-field-name="+u+"]").click(function(){e(s).hasClass("main-martor-fullscreen")?(e(s).removeClass("main-martor-fullscreen"),e("body").removeClass("overflow-hidden")):(e(s).addClass("main-martor-fullscreen"),e("body").addClass("overflow-hidden"))}),e(".markdown-emoji[data-field-name="+u+"]").click(function(){var n=e(".modal-emoji[data-field-name="+u+"]"),o="undefined"!=typeof emojis?emojis:[],r=n.find(".emoji-content-body"),i=n.find(".emoji-loader-init");r.html(""),t.showElement(i),t.showModal(n),setTimeout(function(){for(var c=0;c '),e('a[data-emoji-target="'+o[c]+'"]').click(function(){a(h,e(this).data("emoji-target")),t.hideModal(n)})}t.hideElement(i),t.showElement(r)},100)}),e(".modal-emoji[data-field-name="+u+"] .modal-close").click(function(){t.hideModal(".modal-emoji[data-field-name="+u+"]")}),h.setValue(m.val(),-1);var y=e(".upload-progress[data-field-name="+u+"]");e(s).find("input[name=markdown-image-upload]").change(function(){if(""!==e(this).val()){var o=new FormData,a=e(this)[0].files[0].name,i=e(this)[0].files[0],c=e(this)[0].files[0].size;if(c>10485760)return void alert("Image size too large. Maximum file size is 10MB.");o.append("markdown-image-upload",i),o.append("csrfmiddlewaretoken",n("csrftoken")),t.showElement(y),e.ajax({url:m.data("upload-url"),type:"POST",data:o,processData:!1,contentType:!1,beforeSend:function(){y.find(".spinner").removeClass("hidden")},success:function(e){200==e.status?r(h,a,e.image_url):alert(e.error),t.hideElement(y)},error:function(e,n,o){alert("Image upload failed: "+o),t.hideElement(y)}})}});var k={bold:function(){o(h,"**","**","Bolded text")},italic:function(){o(h,"*","*","Italicized text")},horizontal:function(){o(h,"","\n***\n","")},h1:function(){o(h,"# ","","Heading 1")},h2:function(){o(h,"## ","","Heading 2")},h3:function(){o(h,"### ","","Heading 3")},pre:function(){o(h,"```\n","\n```\n","Code goes here...")},code:function(){o(h,"`","`","Code goes here...")},quote:function(){o(h,"> ","","Quoted text")},ul:function(){o(h,"* ","","List item")},ol:function(){o(h,"1. ","","List item")},link:function(){o(h,"[","](http://)","link text")},image:function(){o(h,"","image text")},mention:function(){i(h)},emoji:function(){e(".markdown-emoji[data-field-name="+u+"]").trigger("click")},toggle:function(){e(".markdown-toggle-maximize[data-field-name="+u+"]").trigger("click")},help:function(){e(".markdown-help[data-field-name="+u+"]").trigger("click")}};e(s).find(".markdown-bold").click(function(){k.bold()}),e(s).find(".markdown-italic").click(function(){k.italic()}),e(s).find(".markdown-horizontal").click(function(){k.horizontal()}),e(s).find(".markdown-h1").click(function(){k.h1()}),e(s).find(".markdown-h2").click(function(){k.h2()}),e(s).find(".markdown-h3").click(function(){k.h3()}),e(s).find(".markdown-pre").click(function(){k.pre()}),e(s).find(".markdown-code").click(function(){k.code()}),e(s).find(".markdown-blockquote").click(function(){k.quote()}),e(s).find(".markdown-unordered-list").click(function(){k.ul()}),e(s).find(".markdown-ordered-list").click(function(){k.ol()}),e(s).find(".markdown-link").click(function(){k.link()}),e(s).find(".markdown-image-link").click(function(){k.image()}),e(s).find(".markdown-direct-mention").click(function(){k.mention()}),e(s).find(".markdown-emoji").click(function(){k.emoji()}),e(s).find(".markdown-toggle-maximize").click(function(){k.toggle()}),e(s).find(".markdown-help").click(function(){k.help()}),h.commands.addCommand({name:"bold",bindKey:{win:"Ctrl-B",mac:"Command-B"},exec:function(e){k.bold()},readOnly:!1}),h.commands.addCommand({name:"italic",bindKey:{win:"Ctrl-I",mac:"Command-I"},exec:function(e){k.italic()},readOnly:!1}),h.commands.addCommand({name:"horizontal",bindKey:{win:"Ctrl-H",mac:"Command-H"},exec:function(e){k.horizontal()},readOnly:!1}),h.commands.addCommand({name:"h1",bindKey:{win:"Ctrl-Alt-1",mac:"Command-Alt-1"},exec:function(e){k.h1()},readOnly:!1}),h.commands.addCommand({name:"h2",bindKey:{win:"Ctrl-Alt-2",mac:"Command-Alt-2"},exec:function(e){k.h2()},readOnly:!1}),h.commands.addCommand({name:"h3",bindKey:{win:"Ctrl-Alt-3",mac:"Command-Alt-3"},exec:function(e){k.h3()},readOnly:!1}),h.commands.addCommand({name:"pre",bindKey:{win:"Ctrl-Alt-P",mac:"Command-Alt-P"},exec:function(e){k.pre()},readOnly:!1}),h.commands.addCommand({name:"code",bindKey:{win:"Ctrl-Alt-C",mac:"Command-Alt-C"},exec:function(e){k.code()},readOnly:!1}),h.commands.addCommand({name:"quote",bindKey:{win:"Ctrl-Q",mac:"Command-Q"},exec:function(e){k.quote()},readOnly:!1}),h.commands.addCommand({name:"ul",bindKey:{win:"Ctrl-U",mac:"Command-U"},exec:function(e){k.ul()},readOnly:!1}),h.commands.addCommand({name:"ol",bindKey:{win:"Ctrl-Shift-O",mac:"Command-Shift-O"},exec:function(e){k.ol()},readOnly:!1}),h.commands.addCommand({name:"link",bindKey:{win:"Ctrl-L",mac:"Command-L"},exec:function(e){k.link()},readOnly:!1}),h.commands.addCommand({name:"image",bindKey:{win:"Ctrl-Shift-I",mac:"Command-Shift-I"},exec:function(e){k.image()},readOnly:!1}),h.commands.addCommand({name:"mention",bindKey:{win:"Ctrl-M",mac:"Command-M"},exec:function(e){k.mention()},readOnly:!1})})}}(jQuery);
diff --git a/martor/static/plugins/css/tailwind.min.css b/martor/static/plugins/css/tailwind.min.css
new file mode 100644
index 00000000..9a318403
--- /dev/null
+++ b/martor/static/plugins/css/tailwind.min.css
@@ -0,0 +1,1289 @@
+/**
+ * Tailwind CSS Base Components for Martor
+ * This file provides minimal Tailwind CSS base styles for environments that don't have Tailwind CSS configured
+ * For production use, it's recommended to use a full Tailwind CSS build
+ */
+
+/* Base Reset and Normalization */
+*,
+::before,
+::after {
+ box-sizing: border-box;
+ border-width: 0;
+ border-style: solid;
+ border-color: #e5e7eb
+}
+
+::before,
+::after {
+ --tw-content: ''
+}
+
+html {
+ line-height: 1.5;
+ -webkit-text-size-adjust: 100%;
+ -moz-tab-size: 4;
+ tab-size: 4;
+ font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"
+}
+
+body {
+ margin: 0;
+ line-height: inherit
+}
+
+hr {
+ height: 0;
+ color: inherit;
+ border-top-width: 1px
+}
+
+abbr:where([title]) {
+ text-decoration: underline dotted
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ font-size: inherit;
+ font-weight: inherit
+}
+
+a {
+ color: inherit;
+ text-decoration: inherit
+}
+
+b,
+strong {
+ font-weight: bolder
+}
+
+code,
+kbd,
+samp,
+pre {
+ font-family: ui-monospace, SFMono-Regular, "Menlo", "Monaco", "Consolas", "Liberation Mono", "Courier New", monospace;
+ font-size: 1em
+}
+
+small {
+ font-size: 80%
+}
+
+sub,
+sup {
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline
+}
+
+sub {
+ bottom: -.25em
+}
+
+sup {
+ top: -.5em
+}
+
+table {
+ text-indent: 0;
+ border-color: inherit;
+ border-collapse: collapse
+}
+
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: inherit;
+ font-size: 100%;
+ font-weight: inherit;
+ line-height: inherit;
+ color: inherit;
+ margin: 0;
+ padding: 0
+}
+
+button,
+select {
+ text-transform: none
+}
+
+button,
+[type='button'],
+[type='reset'],
+[type='submit'] {
+ -webkit-appearance: button;
+ background-color: transparent;
+ background-image: none
+}
+
+:-moz-focusring {
+ outline: auto
+}
+
+:-moz-ui-invalid {
+ box-shadow: none
+}
+
+progress {
+ vertical-align: baseline
+}
+
+::-webkit-inner-spin-button,
+::-webkit-outer-spin-button {
+ height: auto
+}
+
+[type='search'] {
+ -webkit-appearance: textfield;
+ outline-offset: -2px
+}
+
+::-webkit-search-decoration {
+ -webkit-appearance: none
+}
+
+::-webkit-file-upload-button {
+ -webkit-appearance: button;
+ font: inherit
+}
+
+summary {
+ display: list-item
+}
+
+blockquote,
+dl,
+dd,
+h1,
+h2,
+h3,
+h4,
+h5,
+h6,
+hr,
+figure,
+p,
+pre {
+ margin: 0
+}
+
+fieldset {
+ margin: 0;
+ padding: 0
+}
+
+legend {
+ padding: 0
+}
+
+ol,
+ul,
+menu {
+ list-style: none;
+ margin: 0;
+ padding: 0
+}
+
+textarea {
+ resize: vertical
+}
+
+input::placeholder,
+textarea::placeholder {
+ opacity: 1;
+ color: #9ca3af
+}
+
+button,
+[role="button"] {
+ cursor: pointer
+}
+
+:disabled {
+ cursor: default
+}
+
+img,
+svg,
+video,
+canvas,
+audio,
+iframe,
+embed,
+object {
+ display: block;
+ vertical-align: middle
+}
+
+img,
+video {
+ max-width: 100%;
+ height: auto
+}
+
+/* Utility Classes for Martor */
+.hidden {
+ display: none
+}
+
+.block {
+ display: block
+}
+
+.inline-block {
+ display: inline-block
+}
+
+.flex {
+ display: flex
+}
+
+.inline-flex {
+ display: inline-flex
+}
+
+.grid {
+ display: grid
+}
+
+.absolute {
+ position: absolute
+}
+
+.relative {
+ position: relative
+}
+
+.fixed {
+ position: fixed
+}
+
+.inset-0 {
+ top: 0px;
+ right: 0px;
+ bottom: 0px;
+ left: 0px
+}
+
+.left-0 {
+ left: 0px
+}
+
+.right-0 {
+ right: 0px
+}
+
+.top-0 {
+ top: 0px
+}
+
+.bottom-0 {
+ bottom: 0px
+}
+
+.-bottom-2 {
+ bottom: -0.5rem
+}
+
+.right-2 {
+ right: 0.5rem
+}
+
+.z-50 {
+ z-index: 50
+}
+
+.z-\[100\] {
+ z-index: 100
+}
+
+.z-\[9999\] {
+ z-index: 9999
+}
+
+.m-0 {
+ margin: 0
+}
+
+.mx-auto {
+ margin-left: auto;
+ margin-right: auto
+}
+
+.my-4 {
+ margin-top: 1rem;
+ margin-bottom: 1rem
+}
+
+.my-5 {
+ margin-top: 1.25rem;
+ margin-bottom: 1.25rem
+}
+
+.mb-2 {
+ margin-bottom: 0.5rem
+}
+
+.mb-4 {
+ margin-bottom: 1rem
+}
+
+.mb-5 {
+ margin-bottom: 1.25rem
+}
+
+.ml-2 {
+ margin-left: 0.5rem
+}
+
+.ml-3 {
+ margin-left: 0.75rem
+}
+
+.mr-2 {
+ margin-right: 0.5rem
+}
+
+.mr-3 {
+ margin-right: 0.75rem
+}
+
+.mt-0 {
+ margin-top: 0px
+}
+
+.mt-4 {
+ margin-top: 1rem
+}
+
+.-ml-6 {
+ margin-left: -1.5rem
+}
+
+.-ml-8 {
+ margin-left: -2rem
+}
+
+.h-1 {
+ height: 0.25rem
+}
+
+.h-1\.5 {
+ height: 0.375rem
+}
+
+.h-4 {
+ height: 1rem
+}
+
+.h-5 {
+ height: 1rem
+}
+
+.h-6 {
+ height: 1.5rem
+}
+
+.h-8 {
+ height: 2rem
+}
+
+.h-10 {
+ height: 2.5rem
+}
+
+.h-12 {
+ height: 3rem
+}
+
+.h-64 {
+ height: 16rem
+}
+
+.h-\[90\%\] {
+ height: 90%
+}
+
+.h-\[500px\] {
+ height: 500px
+}
+
+.h-full {
+ height: 100%
+}
+
+.max-h-\[500px\] {
+ max-height: 500px
+}
+
+.max-h-64 {
+ max-height: 16rem
+}
+
+.max-h-96 {
+ max-height: 24rem
+}
+
+.max-h-full {
+ max-height: 100%
+}
+
+.min-h-\[100px\] {
+ min-height: 100px
+}
+
+.min-h-64 {
+ min-height: 16rem
+}
+
+.min-h-screen {
+ min-height: 100vh
+}
+
+.w-1\.5 {
+ width: 0.375rem
+}
+
+.w-3 {
+ width: 0.75rem
+}
+
+.w-4 {
+ width: 1rem
+}
+
+.w-5 {
+ width: 1.25rem
+}
+
+.w-6 {
+ width: 1.5rem
+}
+
+.w-8 {
+ width: 2rem
+}
+
+.w-10 {
+ width: 2.5rem
+}
+
+.w-12 {
+ width: 3rem
+}
+
+.w-48 {
+ width: 12rem
+}
+
+.w-auto {
+ width: auto
+}
+
+.w-full {
+ width: 100%
+}
+
+.max-w-2xl {
+ max-width: 42rem
+}
+
+.max-w-4xl {
+ max-width: 56rem
+}
+
+.max-w-5 {
+ max-width: 1.25rem
+}
+
+.max-w-full {
+ max-width: 100%
+}
+
+.flex-shrink-0 {
+ flex-shrink: 0
+}
+
+.resize-y {
+ resize: vertical
+}
+
+.grid-cols-1 {
+ grid-template-columns: repeat(1, minmax(0, 1fr))
+}
+
+.grid-cols-2 {
+ grid-template-columns: repeat(2, minmax(0, 1fr))
+}
+
+.grid-cols-8 {
+ grid-template-columns: repeat(8, minmax(0, 1fr))
+}
+
+.flex-col {
+ flex-direction: column
+}
+
+.flex-wrap {
+ flex-wrap: wrap
+}
+
+.items-center {
+ align-items: center
+}
+
+.items-end {
+ align-items: flex-end
+}
+
+.items-start {
+ align-items: flex-start
+}
+
+.justify-center {
+ justify-content: center
+}
+
+.justify-between {
+ justify-content: space-between
+}
+
+.gap-1 {
+ gap: 0.25rem
+}
+
+.gap-2 {
+ gap: 0.5rem
+}
+
+.gap-4 {
+ gap: 1rem
+}
+
+.gap-6 {
+ gap: 1.5rem
+}
+
+.space-x-1>:not([hidden])~:not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(0.25rem*var(--tw-space-x-reverse));
+ margin-left: calc(0.25rem*calc(1-var(--tw-space-x-reverse)))
+}
+
+.space-x-8>:not([hidden])~:not([hidden]) {
+ --tw-space-x-reverse: 0;
+ margin-right: calc(2rem*var(--tw-space-x-reverse));
+ margin-left: calc(2rem*calc(1-var(--tw-space-x-reverse)))
+}
+
+.space-y-1>:not([hidden])~:not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.25rem*calc(1-var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.25rem*var(--tw-space-y-reverse))
+}
+
+.space-y-2>:not([hidden])~:not([hidden]) {
+ --tw-space-y-reverse: 0;
+ margin-top: calc(0.5rem*calc(1-var(--tw-space-y-reverse)));
+ margin-bottom: calc(0.5rem*var(--tw-space-y-reverse))
+}
+
+.overflow-auto {
+ overflow: auto
+}
+
+.overflow-hidden {
+ overflow: hidden
+}
+
+.overflow-y-auto {
+ overflow-y: auto
+}
+
+.whitespace-nowrap {
+ white-space: nowrap
+}
+
+.whitespace-pre {
+ white-space: pre
+}
+
+.rounded {
+ border-radius: 0.25rem
+}
+
+.rounded-full {
+ border-radius: 9999px
+}
+
+.rounded-lg {
+ border-radius: 0.5rem
+}
+
+.rounded-md {
+ border-radius: 0.375rem
+}
+
+.border {
+ border-width: 1px
+}
+
+.border-b {
+ border-bottom-width: 1px
+}
+
+.border-b-2 {
+ border-bottom-width: 2px
+}
+
+.border-l {
+ border-left-width: 1px
+}
+
+.border-l-4 {
+ border-left-width: 4px
+}
+
+.border-r {
+ border-right-width: 1px
+}
+
+.border-t {
+ border-top-width: 1px
+}
+
+.border-gray-200 {
+ --tw-border-opacity: 1;
+ border-color: rgb(229 231 235/var(--tw-border-opacity))
+}
+
+.border-gray-300 {
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219/var(--tw-border-opacity))
+}
+
+.border-gray-800 {
+ --tw-border-opacity: 1;
+ border-color: rgb(31 41 55/var(--tw-border-opacity))
+}
+
+.border-transparent {
+ border-color: transparent
+}
+
+.border-0 {
+ border-width: 0px
+}
+
+.bg-black {
+ --tw-bg-opacity: 1;
+ background-color: rgb(0 0 0/var(--tw-bg-opacity))
+}
+
+.bg-blue-100 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(219 234 254/var(--tw-bg-opacity))
+}
+
+.bg-blue-600 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(37 99 235/var(--tw-bg-opacity))
+}
+
+.bg-gray-50 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(249 250 251/var(--tw-bg-opacity))
+}
+
+.bg-gray-100 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246/var(--tw-bg-opacity))
+}
+
+.bg-gray-500 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(107 114 128/var(--tw-bg-opacity))
+}
+
+.bg-white {
+ --tw-bg-opacity: 1;
+ background-color: rgb(255 255 255/var(--tw-bg-opacity))
+}
+
+.bg-yellow-100 {
+ --tw-bg-opacity: 1;
+ background-color: rgb(254 249 195/var(--tw-bg-opacity))
+}
+
+.bg-opacity-75 {
+ --tw-bg-opacity: 0.75
+}
+
+.bg-opacity-85 {
+ --tw-bg-opacity: 0.85
+}
+
+.bg-transparent {
+ background-color: transparent
+}
+
+.p-0 {
+ padding: 0px
+}
+
+.p-1 {
+ padding: 0.25rem
+}
+
+.p-2 {
+ padding: 0.5rem
+}
+
+.p-4 {
+ padding: 1rem
+}
+
+.px-2 {
+ padding-left: 0.5rem;
+ padding-right: 0.5rem
+}
+
+.px-3 {
+ padding-left: 0.75rem;
+ padding-right: 0.75rem
+}
+
+.px-4 {
+ padding-left: 1rem;
+ padding-right: 1rem
+}
+
+.py-1 {
+ padding-top: 0.25rem;
+ padding-bottom: 0.25rem
+}
+
+.py-2 {
+ padding-top: 0.5rem;
+ padding-bottom: 0.5rem
+}
+
+.py-3 {
+ padding-top: 0.75rem;
+ padding-bottom: 0.75rem
+}
+
+.py-8 {
+ padding-top: 2rem;
+ padding-bottom: 2rem
+}
+
+.py-12 {
+ padding-top: 3rem;
+ padding-bottom: 3rem
+}
+
+.pb-0 {
+ padding-bottom: 0px
+}
+
+.pb-20 {
+ padding-bottom: 5rem
+}
+
+.pl-4 {
+ padding-left: 1rem
+}
+
+.pl-8 {
+ padding-left: 2rem
+}
+
+.pl-9 {
+ padding-left: 2.25rem
+}
+
+.pl-10 {
+ padding-left: 2.5rem
+}
+
+.pr-3 {
+ padding-right: 0.75rem
+}
+
+.pt-1 {
+ padding-top: 0.25rem
+}
+
+.pt-4 {
+ padding-top: 1rem
+}
+
+.pt-5 {
+ padding-top: 1.25rem
+}
+
+.pt-16 {
+ padding-top: 4rem
+}
+
+.pt-20 {
+ padding-top: 5rem
+}
+
+.text-left {
+ text-align: left
+}
+
+.text-center {
+ text-align: center
+}
+
+.text-right {
+ text-align: right
+}
+
+.align-bottom {
+ vertical-align: bottom
+}
+
+.align-middle {
+ vertical-align: middle
+}
+
+.text-xs {
+ font-size: 0.75rem;
+ line-height: 1rem
+}
+
+.text-sm {
+ font-size: 0.875rem;
+ line-height: 1.25rem
+}
+
+.text-base {
+ font-size: 1rem;
+ line-height: 1.5rem
+}
+
+.text-lg {
+ font-size: 1.125rem;
+ line-height: 1.75rem
+}
+
+.text-xl {
+ font-size: 1.25rem;
+ line-height: 1.75rem
+}
+
+.text-2xl {
+ font-size: 1.5rem;
+ line-height: 2rem
+}
+
+.text-3xl {
+ font-size: 1.875rem;
+ line-height: 2.25rem
+}
+
+.font-bold {
+ font-weight: 700
+}
+
+.font-medium {
+ font-weight: 500
+}
+
+.font-semibold {
+ font-weight: 600
+}
+
+.leading-5 {
+ line-height: 1.25rem
+}
+
+.leading-6 {
+ line-height: 1.5rem
+}
+
+.leading-none {
+ line-height: 1
+}
+
+.leading-normal {
+ line-height: 1.5
+}
+
+.leading-relaxed {
+ line-height: 1.625
+}
+
+.list-disc {
+ list-style-type: disc
+}
+
+.list-none {
+ list-style-type: none
+}
+
+.text-black {
+ --tw-text-opacity: 1;
+ color: rgb(0 0 0/var(--tw-text-opacity))
+}
+
+.text-blue-600 {
+ --tw-text-opacity: 1;
+ color: rgb(37 99 235/var(--tw-text-opacity))
+}
+
+.text-gray-300 {
+ --tw-text-opacity: 1;
+ color: rgb(209 213 219/var(--tw-text-opacity))
+}
+
+.text-gray-400 {
+ --tw-text-opacity: 1;
+ color: rgb(156 163 175/var(--tw-text-opacity))
+}
+
+.text-gray-500 {
+ --tw-text-opacity: 1;
+ color: rgb(107 114 128/var(--tw-text-opacity))
+}
+
+.text-gray-600 {
+ --tw-text-opacity: 1;
+ color: rgb(75 85 99/var(--tw-text-opacity))
+}
+
+.text-gray-700 {
+ --tw-text-opacity: 1;
+ color: rgb(55 65 81/var(--tw-text-opacity))
+}
+
+.text-gray-800 {
+ --tw-text-opacity: 1;
+ color: rgb(31 41 55/var(--tw-text-opacity))
+}
+
+.text-gray-900 {
+ --tw-text-opacity: 1;
+ color: rgb(17 24 39/var(--tw-text-opacity))
+}
+
+.text-red-600 {
+ --tw-text-opacity: 1;
+ color: rgb(220 38 38/var(--tw-text-opacity))
+}
+
+.text-white {
+ --tw-text-opacity: 1;
+ color: rgb(255 255 255/var(--tw-text-opacity))
+}
+
+.text-yellow-600 {
+ --tw-text-opacity: 1;
+ color: rgb(217 119 6/var(--tw-text-opacity))
+}
+
+.no-underline {
+ text-decoration-line: none
+}
+
+.placeholder-gray-400::placeholder {
+ --tw-placeholder-opacity: 1;
+ color: rgb(156 163 175/var(--tw-placeholder-opacity))
+}
+
+.placeholder-gray-500::placeholder {
+ --tw-placeholder-opacity: 1;
+ color: rgb(107 114 128/var(--tw-placeholder-opacity))
+}
+
+.opacity-0 {
+ opacity: 0
+}
+
+.opacity-100 {
+ opacity: 1
+}
+
+.shadow-lg {
+ --tw-shadow: 0 10px 15px -3px rgb(0 0 0/0.1), 0 4px 6px -4px rgb(0 0 0/0.1);
+ --tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow))
+}
+
+.shadow-sm {
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0/0.05);
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow))
+}
+
+.shadow-xl {
+ --tw-shadow: 0 20px 25px -5px rgb(0 0 0/0.1), 0 8px 10px -6px rgb(0 0 0/0.1);
+ --tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow))
+}
+
+.outline-none {
+ outline: 2px solid transparent;
+ outline-offset: 2px
+}
+
+.cursor-pointer {
+ cursor: pointer
+}
+
+.clear-both {
+ clear: both
+}
+
+.float-left {
+ float: left
+}
+
+.float-right {
+ float: right
+}
+
+.transform {
+ transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))
+}
+
+.transition-all {
+ transition-property: all;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms
+}
+
+.transition-opacity {
+ transition-property: opacity;
+ transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
+ transition-duration: 150ms
+}
+
+/* Animation classes */
+@keyframes spin {
+ to {
+ transform: rotate(360deg)
+ }
+}
+
+.animate-spin {
+ animation: spin 1s linear infinite
+}
+
+/* Hover states */
+.hover\:bg-blue-700:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(29 78 216/var(--tw-bg-opacity))
+}
+
+.hover\:bg-gray-50:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(249 250 251/var(--tw-bg-opacity))
+}
+
+.hover\:bg-gray-100:hover {
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246/var(--tw-bg-opacity))
+}
+
+.hover\:text-gray-600:hover {
+ --tw-text-opacity: 1;
+ color: rgb(75 85 99/var(--tw-text-opacity))
+}
+
+.hover\:text-gray-700:hover {
+ --tw-text-opacity: 1;
+ color: rgb(55 65 81/var(--tw-text-opacity))
+}
+
+.hover\:text-gray-900:hover {
+ --tw-text-opacity: 1;
+ color: rgb(17 24 39/var(--tw-text-opacity))
+}
+
+.hover\:border-gray-300:hover {
+ --tw-border-opacity: 1;
+ border-color: rgb(209 213 219/var(--tw-border-opacity))
+}
+
+/* Focus states */
+.focus\:outline-none:focus {
+ outline: 2px solid transparent;
+ outline-offset: 2px
+}
+
+.focus\:ring-1:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)
+}
+
+.focus\:ring-2:focus {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)
+}
+
+.focus\:ring-blue-500:focus {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(59 130 246/var(--tw-ring-opacity))
+}
+
+.focus\:ring-offset-2:focus {
+ --tw-ring-offset-width: 2px
+}
+
+.focus\:border-blue-500:focus {
+ --tw-border-opacity: 1;
+ border-color: rgb(59 130 246/var(--tw-border-opacity))
+}
+
+.focus\:text-gray-600:focus {
+ --tw-text-opacity: 1;
+ color: rgb(75 85 99/var(--tw-text-opacity))
+}
+
+.focus\:text-gray-700:focus {
+ --tw-text-opacity: 1;
+ color: rgb(55 65 81/var(--tw-text-opacity))
+}
+
+.focus\:text-gray-900:focus {
+ --tw-text-opacity: 1;
+ color: rgb(17 24 39/var(--tw-text-opacity))
+}
+
+.focus\:bg-gray-100:focus {
+ --tw-bg-opacity: 1;
+ background-color: rgb(243 244 246/var(--tw-bg-opacity))
+}
+
+.focus\:placeholder-gray-400:focus::placeholder {
+ --tw-placeholder-opacity: 1;
+ color: rgb(156 163 175/var(--tw-placeholder-opacity))
+}
+
+/* Focus within states */
+.focus-within\:ring-2:focus-within {
+ --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
+ --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);
+ box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000)
+}
+
+.focus-within\:ring-blue-500:focus-within {
+ --tw-ring-opacity: 1;
+ --tw-ring-color: rgb(59 130 246/var(--tw-ring-opacity))
+}
+
+/* Responsive design */
+@media (min-width:640px) {
+ .sm\:block {
+ display: block
+ }
+
+ .sm\:inline-block {
+ display: inline-block
+ }
+
+ .sm\:flex {
+ display: flex
+ }
+
+ .sm\:align-middle {
+ vertical-align: middle
+ }
+
+ .sm\:h-screen {
+ height: 100vh
+ }
+
+ .sm\:h-10 {
+ height: 2.5rem
+ }
+
+ .sm\:w-10 {
+ width: 2.5rem
+ }
+
+ .sm\:w-auto {
+ width: auto
+ }
+
+ .sm\:max-w-2xl {
+ max-width: 42rem
+ }
+
+ .sm\:max-w-4xl {
+ max-width: 56rem
+ }
+
+ .sm\:flex-row-reverse {
+ flex-direction: row-reverse
+ }
+
+ .sm\:p-0 {
+ padding: 0px
+ }
+
+ .sm\:px-6 {
+ padding-left: 1.5rem;
+ padding-right: 1.5rem
+ }
+
+ .sm\:pb-4 {
+ padding-bottom: 1rem
+ }
+
+ .sm\:text-left {
+ text-align: left
+ }
+
+ .sm\:text-sm {
+ font-size: 0.875rem;
+ line-height: 1.25rem
+ }
+
+ .sm\:mx-0 {
+ margin-left: 0px;
+ margin-right: 0px
+ }
+
+ .sm\:ml-3 {
+ margin-left: 0.75rem
+ }
+
+ .sm\:ml-4 {
+ margin-left: 1rem
+ }
+
+ .sm\:mt-0 {
+ margin-top: 0px
+ }
+
+ .sm\:my-8 {
+ margin-top: 2rem;
+ margin-bottom: 2rem
+ }
+}
+
+@media (min-width:768px) {
+ .md\:grid-cols-2 {
+ grid-template-columns: repeat(2, minmax(0, 1fr))
+ }
+
+ .md\:col-span-2 {
+ grid-column: span 2/span 2
+ }
+}
diff --git a/martor/templates/martor/tailwind/editor.html b/martor/templates/martor/tailwind/editor.html
new file mode 100644
index 00000000..3162a92d
--- /dev/null
+++ b/martor/templates/martor/tailwind/editor.html
@@ -0,0 +1,57 @@
+{% load i18n %}
+
+
+
+
+
+
+
+
+
+
{% trans "Uploading... please wait..." %}
+
+
+
+ {{ martor }}
+
+
+
+
{% trans "Nothing to preview" %}
+
+
+
+
+ {% include 'martor/tailwind/guide.html' %}
+ {% include 'martor/tailwind/emoji.html' %}
+
diff --git a/martor/templates/martor/tailwind/emoji.html b/martor/templates/martor/tailwind/emoji.html
new file mode 100644
index 00000000..52df302e
--- /dev/null
+++ b/martor/templates/martor/tailwind/emoji.html
@@ -0,0 +1,184 @@
+{% load i18n %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "Choose an Emoji" %}
+
+
+
+ {% trans "Click on an emoji to insert it into your text" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Loading emojis..." %}
+
+
+
+
+
+
+
+
+
+ {% trans "All" %}
+
+
+ 😊 {% trans "Smileys" %}
+
+
+ 👥 {% trans "People" %}
+
+
+ 🌿 {% trans "Nature" %}
+
+
+ 🎯 {% trans "Objects" %}
+
+
+
+
+
+
+
+
+
+
{% trans "Popular" %}
+
+
+ 😊
+
+
+ ❤️
+
+
+ 👍
+
+
+ 👎
+
+
+ 🔥
+
+
+ ⭐
+
+
+ 🤔
+
+
+ 🎉
+
+
+
+
+
+
+
+ {% trans "Close" %}
+
+
+
+
+
+
+
diff --git a/martor/templates/martor/tailwind/guide.html b/martor/templates/martor/tailwind/guide.html
new file mode 100644
index 00000000..9ea14adc
--- /dev/null
+++ b/martor/templates/martor/tailwind/guide.html
@@ -0,0 +1,228 @@
+{% load i18n %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {% trans "Markdown Guide" %}
+
+
+
+ {% trans "Quick reference for Markdown syntax" %}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
{% trans "Text Formatting" %}
+
+
+ {% trans "Bold" %}
+ **text**
+
+
+ {% trans "Italic" %}
+ *text*
+
+
+ {% trans "Strikethrough" %}
+ ~~text~~
+
+
+ {% trans "Underline" %}
+ ++text++
+
+
+ {% trans "Inline Code" %}
+ `code`
+
+
+
+
+
+
+
{% trans "Headers" %}
+
+
+ {% trans "Header 1" %}
+ # H1
+
+
+ {% trans "Header 2" %}
+ ## H2
+
+
+ {% trans "Header 3" %}
+ ### H3
+
+
+ {% trans "Header 4" %}
+ #### H4
+
+
+ {% trans "Header 5" %}
+ ##### H5
+
+
+
+
+
+
+
{% trans "Lists" %}
+
+
+ {% trans "Unordered List" %}
+ * Item 1 * Item 2
+
+
+ {% trans "Ordered List" %}
+ 1. First 2. Second
+
+
+
+
+
+
+
{% trans "Links & Images" %}
+
+
+ {% trans "Link" %}
+ [text](url)
+
+
+ {% trans "Image" %}
+ 
+
+
+
+
+
+
+
{% trans "Code Blocks" %}
+
+
+ {% trans "Code Block" %}
+ ``` code here ```
+
+
+ {% trans "Language Specific" %}
+ ```python code here ```
+
+
+
+
+
+
+
{% trans "Other" %}
+
+
+ {% trans "Quote" %}
+ > text
+
+
+ {% trans "Horizontal Rule" %}
+ ---
+
+
+ {% trans "Line Break" %}
+ 2 spaces
+
+
+ {% trans "Mention" %}
+ @[user]
+
+
+ {% trans "Emoji" %}
+ :smile:
+
+
+
+
+
+
+
{% trans "Tables" %}
+
+ {% trans "Table Syntax" %}
+
+ | Header 1 | Header 2 |
+ |----------|----------|
+ | Cell 1 | Cell 2 |
+
+
+
+
+
+
+
{% trans "Keyboard Shortcuts" %}
+
+
+
+ {% trans "Bold" %}
+ Ctrl+B
+
+
+ {% trans "Italic" %}
+ Ctrl+I
+
+
+ {% trans "Link" %}
+ Ctrl+L
+
+
+
+
+ {% trans "Code" %}
+ Ctrl+Alt+C
+
+
+ {% trans "Quote" %}
+ Ctrl+Q
+
+
+ {% trans "List" %}
+ Ctrl+U
+
+
+
+
+
+
+
+
+
+
+ {% trans "Got it!" %}
+
+
+
+
+
diff --git a/martor/templates/martor/tailwind/toolbar.html b/martor/templates/martor/tailwind/toolbar.html
new file mode 100644
index 00000000..c6fc7c7a
--- /dev/null
+++ b/martor/templates/martor/tailwind/toolbar.html
@@ -0,0 +1,150 @@
+{% load i18n %}
+
+
diff --git a/martor/widgets.py b/martor/widgets.py
index 6b8c076f..dcfd16eb 100644
--- a/martor/widgets.py
+++ b/martor/widgets.py
@@ -23,7 +23,7 @@
def get_theme():
"""function to get the selected theme"""
- supported_themes = ["bootstrap", "semantic"]
+ supported_themes = ["bootstrap", "semantic", "tailwind"]
if MARTOR_THEME in supported_themes:
return MARTOR_THEME
return "bootstrap"
diff --git a/martor_demo/app/templates/tailwind/base.html b/martor_demo/app/templates/tailwind/base.html
new file mode 100644
index 00000000..fad2be65
--- /dev/null
+++ b/martor_demo/app/templates/tailwind/base.html
@@ -0,0 +1,110 @@
+
+
+
+
+
+ {% block title %}Martor Demo - Tailwind CSS{% endblock %}
+
+
+
+
+
+ {% load static %}
+ {% block css %}
+
+
+
+ {% endblock %}
+
+
+
+
+
+
+
+
+
+ {% block content %}
+ {% endblock %}
+
+
+
+
+
+
+
+ Martor Demo with Tailwind CSS Theme
+
+
+ Built with Django and Tailwind CSS
+
+
+
+
+
+
+ {% block js %}
+
+
+
+
+
+
+
+
+
+
+
+
+ {% endblock %}
+
+
diff --git a/martor_demo/app/templates/tailwind/form.html b/martor_demo/app/templates/tailwind/form.html
new file mode 100644
index 00000000..3a25a45a
--- /dev/null
+++ b/martor_demo/app/templates/tailwind/form.html
@@ -0,0 +1,228 @@
+{% extends 'tailwind/base.html' %}
+{% load static %}
+
+{% block title %}Simple Form - Martor Demo (Tailwind){% endblock %}
+
+{% block content %}
+
+
+
+
+
+ Martor Editor Demo
+
+
+ A powerful Django Markdown Editor with Tailwind CSS styling
+
+
+
+ Live Preview
+
+
+ Ace Editor
+
+
+ Emoji Support
+
+
+ File Upload
+
+
+
+
+
+
+
+
+
+
+
Features Available
+
+
+
+
+
Live Preview
+
Real-time markdown preview
+
+
+
+
+
+
Image Upload
+
Drag & drop image support
+
+
+
+
+
+
Emoji Support
+
Built-in emoji picker
+
+
+
+
+
+
Syntax Highlighting
+
Code block highlighting
+
+
+
+
+
+
User Mentions
+
@username support
+
+
+
+
+
+
Multiple Formats
+
Tables, lists, links & more
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/martor_demo/app/templates/tailwind/test_markdownify.html b/martor_demo/app/templates/tailwind/test_markdownify.html
new file mode 100644
index 00000000..c1bd23d5
--- /dev/null
+++ b/martor_demo/app/templates/tailwind/test_markdownify.html
@@ -0,0 +1,251 @@
+{% extends 'tailwind/base.html' %}
+{% load static %}
+{% load martortags %}
+
+{% block title %}Test Markdownify - Martor Demo (Tailwind){% endblock %}
+
+{% block content %}
+
+
+
+
+
+ Markdownify Test
+
+
+ See how Martor renders Markdown content with Tailwind CSS styling
+
+
+
+
+
+
+
+
+
+
+
+
+ Markdown Source
+
+
+
+
+
+
+
+
+
+
+
+ Rendered Output
+
+
+ {{ content|safe_markdown }}
+
+
+
+
+
+
+
Sample Markdown Examples
+
+
+
+
+
Headers
+
+
+
+# Heading 1
+## Heading 2
+### Heading 3
+
+
+
+
Heading 1
+ Heading 2
+ Heading 3
+
+
+
+
+
+
+
Text Formatting
+
+
+
+**Bold text**
+*Italic text*
+~~Strikethrough~~
+++Underline++
+`inline code`
+
+
+
+
Bold text
+
Italic text
+
Strikethrough
+
Underline
+
inline code
+
+
+
+
+
+
+
Lists
+
+
+
+* Unordered item 1
+* Unordered item 2
+
+1. Ordered item 1
+2. Ordered item 2
+
+
+
+
+ Unordered item 1
+ Unordered item 2
+
+
+ Ordered item 1
+ Ordered item 2
+
+
+
+
+
+
+
+
Links & Images
+
+
+
+[Link text](https://example.com)
+
+
+
+
+
+
+
+
+
+
Code Blocks
+
+
+
+```python
+def hello_world():
+ print("Hello, World!")
+```
+
+
+
+
def hello_world():
+ print("Hello, World!")
+
+
+
+
+
+
+
Tables
+
+
+
+| Name | Age | City |
+|------|-----|------|
+| John | 30 | NYC |
+| Jane | 25 | LA |
+
+
+
+
+
+
+ Name
+ Age
+ City
+
+
+
+
+ John
+ 30
+ NYC
+
+
+ Jane
+ 25
+ LA
+
+
+
+
+
+
+
+
+
+
Blockquotes
+
+
+
+> This is a blockquote
+> with multiple lines
+>
+> > Nested quote
+
+
+
+
+ This is a blockquote
+ with multiple lines
+
+ Nested quote
+
+
+
+
+
+
+
+
+
+
+
+
+
+{% endblock %}
diff --git a/martor_demo/martor_demo/settings.py b/martor_demo/martor_demo/settings.py
index c007808d..360dff34 100644
--- a/martor_demo/martor_demo/settings.py
+++ b/martor_demo/martor_demo/settings.py
@@ -31,7 +31,7 @@
ALLOWED_HOSTS = ["*"]
# Martor Configuration
-MARTOR_THEME = "bootstrap" # semantic
+MARTOR_THEME = "tailwind" # bootstrap, semantic
MARTOR_ENABLE_LABEL = True
MARTOR_ENABLE_CONFIGS = {
"emoji": "true", # to enable/disable emoji icons.
From e498be413e49cc41f28812b8460de10a9ab7561b Mon Sep 17 00:00:00 2001
From: agusmakmun
Date: Fri, 29 Aug 2025 22:15:21 +0700
Subject: [PATCH 2/3] feat: update functionalities and demo
---
martor/static/martor/css/martor.tailwind.css | 96 +-
.../static/martor/css/martor.tailwind.min.css | 410 +------
martor/static/martor/js/martor.tailwind.js | 1046 +++++++++++------
.../static/martor/js/martor.tailwind.min.js | 10 +-
martor_demo/app/templates/tailwind/base.html | 10 +-
martor_demo/app/templates/tailwind/form.html | 406 +++----
martor_demo/martor_demo/settings.py | 3 +
7 files changed, 982 insertions(+), 999 deletions(-)
diff --git a/martor/static/martor/css/martor.tailwind.css b/martor/static/martor/css/martor.tailwind.css
index 1d2bfef4..f66cb904 100644
--- a/martor/static/martor/css/martor.tailwind.css
+++ b/martor/static/martor/css/martor.tailwind.css
@@ -11,46 +11,76 @@ body.overflow {
/* Main Editor Container */
.martor {
- @apply h-[500px] max-h-[500px];
+ height: 500px;
+ max-height: 500px;
}
.martor-field {
- @apply w-full h-64 min-h-[100px] resize-y border-r border-b border-gray-300;
+ width: 100%;
+ height: 16rem;
+ /* 256px */
+ min-height: 100px;
+ resize: vertical;
+ border-right: 1px solid #d1d5db;
+ border-bottom: 1px solid #d1d5db;
}
.main-martor {
- @apply my-4 relative;
+ margin-top: 1rem;
+ margin-bottom: 1rem;
+ position: relative;
}
/* Modal Styles */
.main-martor .modal-header {
- @apply p-2 px-4;
+ padding: 0.5rem 1rem;
}
.main-martor .modal-header h5 {
- @apply text-base;
+ font-size: 1rem;
+ line-height: 1.5rem;
}
/* Upload Progress Overlay */
.main-martor .upload-progress {
- @apply absolute z-[100] w-full h-full pt-20 bg-black bg-opacity-85 text-white text-center;
+ position: absolute;
+ z-index: 100;
+ width: 100%;
+ height: 100%;
+ padding-top: 5rem;
+ background-color: rgba(0, 0, 0, 0.85);
+ color: white;
+ text-align: center;
}
/* Toolbar Styles */
.martor-toolbar {
- @apply z-[100];
+ z-index: 100;
}
.enable-living .martor-toolbar {
- @apply relative;
+ position: relative;
}
.martor-toolbar .markdown-image-upload {
- @apply relative overflow-hidden;
+ position: relative;
+ overflow: hidden;
}
.martor-toolbar .markdown-image-upload input[type=file] {
- @apply absolute top-0 right-0 w-full h-full text-2xl p-0 pl-9 text-right opacity-0 outline-none cursor-pointer block;
+ position: absolute;
+ top: 0;
+ right: 0;
+ width: 100%;
+ height: 100%;
+ font-size: 1.5rem;
+ padding: 0;
+ padding-left: 2.25rem;
+ text-align: right;
+ opacity: 0;
+ outline: none;
+ cursor: pointer;
+ display: block;
min-width: 100%;
min-height: 100%;
filter: alpha(opacity=0);
@@ -474,3 +504,49 @@ div.martor-preview pre code,
div.martor-preview pre tt {
@apply m-0 p-0 bg-transparent border-0;
}
+
+/* Form Integration Styles */
+/* Enhanced form styling for better integration */
+.form-field input[type="text"],
+.form-field textarea,
+form input[type="text"]:not(.martor input),
+form textarea:not(.martor textarea) {
+ @apply w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm;
+ @apply focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500;
+ @apply transition-colors duration-200;
+}
+
+/* Error state styling */
+.has-error input,
+.has-error textarea {
+ @apply border-red-300 focus:ring-red-500 focus:border-red-500;
+}
+
+/* Disabled state */
+input:disabled,
+textarea:disabled {
+ @apply bg-gray-50 text-gray-500 cursor-not-allowed;
+}
+
+/* Enhanced Martor Editor Styling */
+.main-martor {
+ border: 1px solid #d1d5db;
+ border-radius: 0.375rem;
+ overflow: hidden;
+}
+
+.main-martor .tab-martor-menu {
+ background-color: #f9fafb;
+ border-bottom: 1px solid #e5e7eb;
+}
+
+/* Force martor field height */
+.main-martor .martor-field {
+ height: 16rem !important;
+ min-height: 16rem !important;
+}
+
+.main-martor .ace_editor {
+ height: 100% !important;
+ min-height: 16rem !important;
+}
diff --git a/martor/static/martor/css/martor.tailwind.min.css b/martor/static/martor/css/martor.tailwind.min.css
index f7fa99c6..7130362a 100644
--- a/martor/static/martor/css/martor.tailwind.min.css
+++ b/martor/static/martor/css/martor.tailwind.min.css
@@ -1,401 +1,9 @@
-body.overflow {
- overflow: hidden !important
-}
-
-.martor {
- @apply h-[500px] max-h-[500px]
-}
-
-.martor-field {
- @apply w-full h-64 min-h-[100px] resize-y border-r border-b border-gray-300
-}
-
-.main-martor {
- @apply my-4 relative
-}
-
-.main-martor .modal-header {
- @apply p-2 px-4
-}
-
-.main-martor .modal-header h5 {
- @apply text-base
-}
-
-.main-martor .upload-progress {
- @apply absolute z-[100] w-full h-full pt-20 bg-black bg-opacity-85 text-white text-center
-}
-
-.martor-toolbar {
- @apply z-[100]
-}
-
-.enable-living .martor-toolbar {
- @apply relative
-}
-
-.martor-toolbar .markdown-image-upload {
- @apply relative overflow-hidden
-}
-
-.martor-toolbar .markdown-image-upload input[type=file] {
- @apply absolute top-0 right-0 w-full h-full text-2xl p-0 pl-9 text-right opacity-0 outline-none cursor-pointer block;
- min-width: 100%;
- min-height: 100%;
- filter: alpha(opacity=0)
-}
-
-.emoji-loader-init {
- min-height: 200px !important;
- @apply pt-16
-}
-
-.emoji-content-body {
- @apply text-xs
-}
-
-.insert-emoji {
- @apply cursor-pointer no-underline
-}
-
-.table.markdown-reference {
- @apply text-xs
-}
-
-.table.markdown-reference h1 {
- @apply text-2xl
-}
-
-.table.markdown-reference h2 {
- @apply text-xl
-}
-
-.table.markdown-reference ul, .table.markdown-reference ol {
- @apply pl-4
-}
-
-div.martor-preview {
- @apply p-4 overflow-auto bg-gray-50
-}
-
-div.martor-preview-stale {
- background: repeating-linear-gradient(-45deg, #fff, #fff 10px, #f8f8f8 10px, #f8f8f8 20px) !important
-}
-
-.main-martor .nav-tabs {
- @apply border-b-2 border-gray-200
-}
-
-.main-martor .nav-tabs .nav-link:hover, .main-martor .nav-tabs .nav-link:focus {
- @apply border-transparent
-}
-
-.main-martor .nav-tabs .nav-item.show .nav-link, .main-martor .nav-tabs .nav-link.active, .main-martor .nav-tabs .nav-link.active:hover {
- @apply border-transparent border-b-2 border-gray-800 text-gray-700
-}
-
-.main-martor .tab-pane {
- @apply relative
-}
-
-.icon.expand-editor {
- @apply absolute -bottom-2 right-2 z-[100]
-}
-
-.no-border {
- @apply border-0
-}
-
-div.enable-living .martor-preview {
- @apply block opacity-100 mt-4 border border-gray-200 rounded-md
-}
-
-div.enable-living .tab-martor-menu a.nav-link {
- @apply hidden
-}
-
-.section-martor ::-webkit-scrollbar-track {
- -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.3);
- @apply rounded-lg bg-gray-100
-}
-
-.section-martor ::-webkit-scrollbar {
- @apply h-1.5 w-1.5 bg-gray-100
-}
-
-.section-martor ::-webkit-scrollbar-thumb {
- @apply rounded-lg bg-gray-600;
- -webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, .3)
-}
-
-.ace_scrollbar-v {
- cursor: ns-resize
-}
-
-.main-martor-fullscreen {
- @apply bg-white fixed z-[9999] max-h-full h-full w-full m-0 left-0 top-0
-}
-
-.main-martor-fullscreen .fields.martor-toolbar {
- @apply border-b border-gray-300 m-0
-}
-
-.main-martor-fullscreen .section-martor {
- @apply h-[90%] relative
-}
-
-.main-martor-fullscreen .martor-field, .main-martor-fullscreen div.martor-preview {
- min-height: 95vh
-}
-
-.marked-emoji,
-div.martor-preview .marked-emoji {
- @apply max-w-5
-}
-
-div.martor-preview {
- @apply text-sm leading-relaxed
-}
-
-div.martor-preview>*:first-child {
- @apply mt-0
-}
-
-div.martor-preview>*:last-child {
- @apply mb-5
-}
-
-div.martor-preview a.absent {
- @apply text-red-600
-}
-
-div.martor-preview a.anchor {
- @apply block pl-8 -ml-8 cursor-pointer absolute top-0 left-0 bottom-0
-}
-
-div.martor-preview h1, div.martor-preview h2, div.martor-preview h3, div.martor-preview h4, div.martor-preview h5, div.martor-preview h6 {
- @apply my-5 mb-2 p-0 font-bold cursor-text relative;
- -webkit-font-smoothing: antialiased;
- background: none
-}
-
-div.martor-preview h1:hover a.anchor,
-div.martor-preview h2:hover a.anchor,
-div.martor-preview h3:hover a.anchor,
-div.martor-preview h4:hover a.anchor,
-div.martor-preview h5:hover a.anchor,
-div.martor-preview h6:hover a.anchor {
- @apply no-underline leading-none pl-0 -ml-6;
- top: 15%
-}
-
-div.martor-preview h1 {
- @apply text-3xl text-black
-}
-
-div.martor-preview h2 {
- @apply text-2xl text-black
-}
-
-div.martor-preview h3 {
- @apply text-lg
-}
-
-div.martor-preview h4 {
- @apply text-base
-}
-
-div.martor-preview h5 {
- @apply text-sm
-}
-
-div.martor-preview h6 {
- @apply text-gray-500 text-sm
-}
-
-div.martor-preview p, div.martor-preview blockquote, div.martor-preview ul, div.martor-preview ol, div.martor-preview dl, div.martor-preview table, div.martor-preview pre {
- @apply my-4
-}
-
-div.martor-preview hr {
- background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxBEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;
- @apply border-0 text-gray-300 h-1 p-0
-}
-
-div.martor-preview>h2:first-child, div.martor-preview>h1:first-child, div.martor-preview>h1:first-child+h2, div.martor-preview>h3:first-child, div.martor-preview>h4:first-child, div.martor-preview>h5:first-child, div.martor-preview>h6:first-child {
- @apply mt-0 pt-0
-}
-
-div.martor-preview a:first-child h1, div.martor-preview a:first-child h2, div.martor-preview a:first-child h3, div.martor-preview a:first-child h4, div.martor-preview a:first-child h5, div.martor-preview a:first-child h6 {
- @apply mt-0 pt-0
-}
-
-div.martor-preview h1+p, div.martor-preview h2+p, div.martor-preview h3+p, div.martor-preview h4+p, div.martor-preview h5+p, div.martor-preview h6+p {
- @apply mt-0
-}
-
-div.martor-preview li p.first {
- @apply inline-block
-}
-
-div.martor-preview ul li {
- @apply list-disc
-}
-
-div.martor-preview ul, div.martor-preview ol {
- @apply pl-8
-}
-
-div.martor-preview ul.no-list, div.martor-preview ol.no-list {
- @apply list-none p-0
-}
-
-div.martor-preview ul li>:first-child, div.martor-preview ul li ul:first-of-type, div.martor-preview ol li>:first-child, div.martor-preview ol li ul:first-of-type {
- @apply mt-0
-}
-
-div.martor-preview ul ul, div.martor-preview ul ol, div.martor-preview ol ol, div.martor-preview ol ul {
- @apply mb-0
-}
-
-div.martor-preview dl {
- @apply p-0
-}
-
-div.martor-preview dl dt {
- @apply text-sm font-bold italic p-0 my-4 mt-0
-}
-
-div.martor-preview dl dt:first-child {
- @apply p-0
-}
-
-div.martor-preview dl dt>:first-child {
- @apply mt-0
-}
-
-div.martor-preview dl dt>:last-child {
- @apply mb-0
-}
-
-div.martor-preview dl dd {
- @apply m-0 mb-4 pl-4
-}
-
-div.martor-preview dl dd>:first-child {
- @apply mt-0
-}
-
-div.martor-preview dl dd>:last-child {
- @apply mb-0
-}
-
-div.martor-preview blockquote {
- @apply border-l-4 border-gray-300 py-1 px-4 text-gray-500 bg-white
-}
-
-div.martor-preview blockquote>:first-child {
- @apply mt-0
-}
-
-div.martor-preview blockquote>:last-child {
- @apply mb-0
-}
-
-div.martor-preview table th {
- @apply font-bold
-}
-
-div.martor-preview table th, div.martor-preview table td {
- @apply border border-gray-300 py-1.5 px-3
-}
-
-div.martor-preview table tr {
- @apply border-t border-gray-300 bg-white
-}
-
-div.martor-preview table tr:nth-child(2n) {
- @apply bg-gray-50
-}
-
-div.martor-preview img, div.martor-preview p img {
- @apply max-w-full;
- -moz-box-sizing: border-box;
- box-sizing: border-box
-}
-
-div.martor-preview span.frame {
- @apply block overflow-hidden
-}
-
-div.martor-preview span.frame>span {
- @apply border border-gray-300 block float-left overflow-hidden my-3 mt-0 p-2 w-auto
-}
-
-div.martor-preview span.frame span img {
- @apply block float-left
-}
-
-div.martor-preview span.frame span span {
- @apply clear-both text-gray-800 block pt-1 pb-0
-}
-
-div.martor-preview span.align-center {
- @apply block overflow-hidden clear-both
-}
-
-div.martor-preview span.align-center>span {
- @apply block overflow-hidden my-3 mt-0 mx-auto text-center
-}
-
-div.martor-preview span.align-center span img {
- @apply mx-auto text-center
-}
-
-div.martor-preview span.align-right {
- @apply block overflow-hidden clear-both
-}
-
-div.martor-preview span.align-right>span {
- @apply block overflow-hidden my-3 mt-0 text-right
-}
-
-div.martor-preview span.align-right span img {
- @apply m-0 text-right
-}
-
-div.martor-preview span.float-left {
- @apply block mr-3 overflow-hidden float-left
-}
-
-div.martor-preview span.float-left span {
- @apply my-3 mt-0
-}
-
-div.martor-preview span.float-right {
- @apply block ml-3 overflow-hidden float-right
-}
-
-div.martor-preview span.float-right>span {
- @apply block overflow-hidden my-3 mt-0 mx-auto text-right
-}
-
-div.martor-preview code, div.martor-preview tt {
- @apply mx-0.5 py-0 px-1 border border-gray-200 bg-gray-100 rounded
-}
-
-div.martor-preview code {
- @apply whitespace-nowrap
-}
-
-div.martor-preview pre>code {
- @apply m-0 p-0 whitespace-pre border-0 bg-transparent
-}
-
-div.martor-preview .highlight pre, div.martor-preview pre {
- @apply border border-gray-200 p-4 overflow-auto text-sm leading-normal bg-gray-50 rounded
-}
-
-div.martor-preview pre code, div.martor-preview pre tt {
- @apply m-0 p-0 bg-transparent border-0
-}
+/**
+ * Name : Martor v1.6.45
+ * Created by : Agus Makmun (Summon Agus)
+ * Release date : 15-Nov-2024
+ * License : GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
+ * Repository : https://github.com/agusmakmun/django-markdown-editor
+ * CSS Minifier : https://www.minifier.org
+**/
+body.overflow{overflow:hidden!important}.martor{height:500px;max-height:500px}.martor-field{width:100%;height:16rem;min-height:100px;resize:vertical;border-right:1px solid #d1d5db;border-bottom:1px solid #d1d5db}.main-martor{margin-top:1rem;margin-bottom:1rem;position:relative}.main-martor .modal-header{padding:.5rem 1rem}.main-martor .modal-header h5{font-size:1rem;line-height:1.5rem}.main-martor .upload-progress{position:absolute;z-index:100;width:100%;height:100%;padding-top:5rem;background-color:rgb(0 0 0 / .85);color:#fff;text-align:center}.martor-toolbar{z-index:100}.enable-living .martor-toolbar{position:relative}.martor-toolbar .markdown-image-upload{position:relative;overflow:hidden}.martor-toolbar .markdown-image-upload input[type=file]{position:absolute;top:0;right:0;width:100%;height:100%;font-size:1.5rem;padding:0;padding-left:2.25rem;text-align:right;opacity:0;outline:none;cursor:pointer;display:block;min-width:100%;min-height:100%;filter:alpha(opacity=0)}.emoji-loader-init{min-height:200px!important;@apply pt-16}.emoji-content-body{@apply text-xs}.insert-emoji{@apply cursor-pointer no-underline}.table.markdown-reference{@apply text-xs}.table.markdown-reference h1{@apply text-2xl}.table.markdown-reference h2{@apply text-xl}.table.markdown-reference ul,.table.markdown-reference ol{@apply pl-4}div.martor-preview{@apply p-4 overflow-auto bg-gray-50}div.martor-preview-stale{background:repeating-linear-gradient(-45deg,#fff,#fff 10px,#f8f8f8 10px,#f8f8f8 20px)!important}.main-martor .nav-tabs{@apply border-b-2 border-gray-200}.main-martor .nav-tabs .nav-link:hover,.main-martor .nav-tabs .nav-link:focus{@apply border-transparent}.main-martor .nav-tabs .nav-item.show .nav-link,.main-martor .nav-tabs .nav-link.active,.main-martor .nav-tabs .nav-link.active:hover{@apply border-transparent border-b-2 border-gray-800 text-gray-700}.main-martor .tab-pane{@apply relative}.icon.expand-editor{@apply absolute -bottom-2 right-2 z-[100]}.no-border{@apply border-0}div.enable-living .martor-preview{@apply block opacity-100 mt-4 border border-gray-200 rounded-md}div.enable-living .tab-martor-menu a.nav-link{@apply hidden}.section-martor ::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgb(0 0 0 / .3);@apply rounded-lg bg-gray-100}.section-martor ::-webkit-scrollbar{@apply h-1.5 w-1.5 bg-gray-100}.section-martor ::-webkit-scrollbar-thumb{@apply rounded-lg bg-gray-600;-webkit-box-shadow:inset 0 0 6px rgb(0 0 0 / .3)}.ace_scrollbar-v{cursor:ns-resize}.main-martor-fullscreen{@apply bg-white fixed z-[9999] max-h-full h-full w-full m-0 left-0 top-0}.main-martor-fullscreen .fields.martor-toolbar{@apply border-b border-gray-300 m-0}.main-martor-fullscreen .section-martor{@apply h-[90%] relative}.main-martor-fullscreen .martor-field,.main-martor-fullscreen div.martor-preview{min-height:95vh}.marked-emoji,div.martor-preview .marked-emoji{@apply max-w-5}div.martor-preview{@apply text-sm leading-relaxed}div.martor-preview>*:first-child{@apply mt-0}div.martor-preview>*:last-child{@apply mb-5}div.martor-preview a.absent{@apply text-red-600}div.martor-preview a.anchor{@apply block pl-8 -ml-8 cursor-pointer absolute top-0 left-0 bottom-0}div.martor-preview h1,div.martor-preview h2,div.martor-preview h3,div.martor-preview h4,div.martor-preview h5,div.martor-preview h6{@apply my-5 mb-2 p-0 font-bold cursor-text relative;-webkit-font-smoothing:antialiased;background:none}div.martor-preview h1:hover a.anchor,div.martor-preview h2:hover a.anchor,div.martor-preview h3:hover a.anchor,div.martor-preview h4:hover a.anchor,div.martor-preview h5:hover a.anchor,div.martor-preview h6:hover a.anchor{@apply no-underline leading-none pl-0 -ml-6;top:15%}div.martor-preview h1{@apply text-3xl text-black}div.martor-preview h2{@apply text-2xl text-black}div.martor-preview h3{@apply text-lg}div.martor-preview h4{@apply text-base}div.martor-preview h5{@apply text-sm}div.martor-preview h6{@apply text-gray-500 text-sm}div.martor-preview p,div.martor-preview blockquote,div.martor-preview ul,div.martor-preview ol,div.martor-preview dl,div.martor-preview table,div.martor-preview pre{@apply my-4}div.martor-preview hr{background:#fff0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxBEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;@apply border-0 text-gray-300 h-1 p-0}div.martor-preview>h2:first-child,div.martor-preview>h1:first-child,div.martor-preview>h1:first-child+h2,div.martor-preview>h3:first-child,div.martor-preview>h4:first-child,div.martor-preview>h5:first-child,div.martor-preview>h6:first-child{@apply mt-0 pt-0}div.martor-preview a:first-child h1,div.martor-preview a:first-child h2,div.martor-preview a:first-child h3,div.martor-preview a:first-child h4,div.martor-preview a:first-child h5,div.martor-preview a:first-child h6{@apply mt-0 pt-0}div.martor-preview h1+p,div.martor-preview h2+p,div.martor-preview h3+p,div.martor-preview h4+p,div.martor-preview h5+p,div.martor-preview h6+p{@apply mt-0}div.martor-preview li p.first{@apply inline-block}div.martor-preview ul li{@apply list-disc}div.martor-preview ul,div.martor-preview ol{@apply pl-8}div.martor-preview ul.no-list,div.martor-preview ol.no-list{@apply list-none p-0}div.martor-preview ul li>:first-child,div.martor-preview ul li ul:first-of-type,div.martor-preview ol li>:first-child,div.martor-preview ol li ul:first-of-type{@apply mt-0}div.martor-preview ul ul,div.martor-preview ul ol,div.martor-preview ol ol,div.martor-preview ol ul{@apply mb-0}div.martor-preview dl{@apply p-0}div.martor-preview dl dt{@apply text-sm font-bold italic p-0 my-4 mt-0}div.martor-preview dl dt:first-child{@apply p-0}div.martor-preview dl dt>:first-child{@apply mt-0}div.martor-preview dl dt>:last-child{@apply mb-0}div.martor-preview dl dd{@apply m-0 mb-4 pl-4}div.martor-preview dl dd>:first-child{@apply mt-0}div.martor-preview dl dd>:last-child{@apply mb-0}div.martor-preview blockquote{@apply border-l-4 border-gray-300 py-1 px-4 text-gray-500 bg-white}div.martor-preview blockquote>:first-child{@apply mt-0}div.martor-preview blockquote>:last-child{@apply mb-0}div.martor-preview table th{@apply font-bold}div.martor-preview table th,div.martor-preview table td{@apply border border-gray-300 py-1.5 px-3}div.martor-preview table tr{@apply border-t border-gray-300 bg-white}div.martor-preview table tr:nth-child(2n){@apply bg-gray-50}div.martor-preview img,div.martor-preview p img{@apply max-w-full;-moz-box-sizing:border-box;box-sizing:border-box}div.martor-preview span.frame{@apply block overflow-hidden}div.martor-preview span.frame>span{@apply border border-gray-300 block float-left overflow-hidden my-3 mt-0 p-2 w-auto}div.martor-preview span.frame span img{@apply block float-left}div.martor-preview span.frame span span{@apply clear-both text-gray-800 block pt-1 pb-0}div.martor-preview span.align-center{@apply block overflow-hidden clear-both}div.martor-preview span.align-center>span{@apply block overflow-hidden my-3 mt-0 mx-auto text-center}div.martor-preview span.align-center span img{@apply mx-auto text-center}div.martor-preview span.align-right{@apply block overflow-hidden clear-both}div.martor-preview span.align-right>span{@apply block overflow-hidden my-3 mt-0 text-right}div.martor-preview span.align-right span img{@apply m-0 text-right}div.martor-preview span.float-left{@apply block mr-3 overflow-hidden float-left}div.martor-preview span.float-left span{@apply my-3 mt-0}div.martor-preview span.float-right{@apply block ml-3 overflow-hidden float-right}div.martor-preview span.float-right>span{@apply block overflow-hidden my-3 mt-0 mx-auto text-right}div.martor-preview code,div.martor-preview tt{@apply mx-0.5 py-0 px-1 border border-gray-200 bg-gray-100 rounded}div.martor-preview code{@apply whitespace-nowrap}div.martor-preview pre>code{@apply m-0 p-0 whitespace-pre border-0 bg-transparent}div.martor-preview .highlight pre,div.martor-preview pre{@apply border border-gray-200 p-4 overflow-auto text-sm leading-normal bg-gray-50 rounded}div.martor-preview pre code,div.martor-preview pre tt{@apply m-0 p-0 bg-transparent border-0}.form-field input[type="text"],.form-field textarea,form input[type="text"]:not(.martor input),form textarea:not(.martor textarea){@apply w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm;@apply focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500;@apply transition-colors duration-200}.has-error input,.has-error textarea{@apply border-red-300 focus:ring-red-500 focus:border-red-500}input:disabled,textarea:disabled{@apply bg-gray-50 text-gray-500 cursor-not-allowed}.main-martor{border:1px solid #d1d5db;border-radius:.375rem;overflow:hidden}.main-martor .tab-martor-menu{background-color:#f9fafb;border-bottom:1px solid #e5e7eb}.main-martor .martor-field{height:16rem!important;min-height:16rem!important}.main-martor .ace_editor{height:100%!important;min-height:16rem!important}
diff --git a/martor/static/martor/js/martor.tailwind.js b/martor/static/martor/js/martor.tailwind.js
index 9b1642e8..fb55c485 100644
--- a/martor/static/martor/js/martor.tailwind.js
+++ b/martor/static/martor/js/martor.tailwind.js
@@ -14,6 +14,24 @@
$.fn.martor = function () {
$('.martor').trigger('martor.init');
+ // CSRF code
+ var getCookie = function (name) {
+ var cookieValue = null;
+ var i = 0;
+ if (document.cookie && document.cookie !== '') {
+ var cookies = document.cookie.split(';');
+ for (i; i < cookies.length; i++) {
+ var cookie = jQuery.trim(cookies[i]);
+ // Does this cookie string begin with the name we want?
+ if (cookie.substring(0, name.length + 1) === (name + '=')) {
+ cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
+ break;
+ }
+ }
+ }
+ return cookieValue;
+ };
+
// Tailwind-specific utility functions
var TailwindUtils = {
showElement: function(element) {
@@ -41,24 +59,6 @@
}
};
- // CSRF code
- var getCookie = function (name) {
- var cookieValue = null;
- var i = 0;
- if (document.cookie && document.cookie !== '') {
- var cookies = document.cookie.split(';');
- for (i; i < cookies.length; i++) {
- var cookie = jQuery.trim(cookies[i]);
- // Does this cookie string begin with the name we want?
- if (cookie.substring(0, name.length + 1) === (name + '=')) {
- cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
- break;
- }
- }
- }
- return cookieValue;
- };
-
// Each multiple editor fields
this.each(function (i, obj) {
var mainMartor = $(obj);
@@ -125,23 +125,33 @@
if (data['status'] == 200) {
var wordList = [];
for (var i = 0; i < data['data'].length; i++) {
- wordList.push('@[' + data['data'][i] + ']')
+ wordList.push(data['data'][i].username)
}
callback(null, wordList.map(function (word) {
return {
caption: word,
- value: word + ' ',
- meta: 'users'
+ value: word,
+ meta: 'username'
};
}));
}
- }
+ }// end success
});
}
}
}
}
+ // Set autocomplete for ace editor
+ if (editorConfig.mention === 'true') {
+ editor.completers = [emojiWordCompleter, mentionWordCompleter]
+ } else {
+ editor.completers = [emojiWordCompleter]
+ }
+
+ // set css `display:none` for this textarea.
+ textareaId.attr({ 'style': 'display:none' });
+
// assign all `field_name`, uses for a per-single editor.
$(obj).find('.martor-toolbar').find('.markdown-selector').attr({ 'data-field-name': field_name });
$(obj).find('.upload-progress').attr({ 'data-field-name': field_name });
@@ -150,79 +160,15 @@
// Set if editor has changed.
editor.on('change', function (evt) {
- var content = editor.getSession().getValue();
- textareaId.val(content);
-
- // for validate markdown
- textareaId.parent().find('.invalid-feedback').remove();
- textareaId.parent().removeClass('has-error');
-
- // Auto update preview in realtime when editor activated
- if (editorConfig.living == 'true' && content.length > 0) {
- var preview_tab = $('.tab-preview-' + field_name);
- markdownfy(textareaId, preview_tab, false);
- }
+ var value = editor.getValue();
+ textareaId.val(value);
});
- // spellcheck
- if (editorConfig.spellcheck == 'true') {
- langTools = ace.require("ace/ext/language_tools");
- // NOTE: install typo.js first. https://github.com/cfinke/Typo.js
- // use `pip install typojs`
- var spellcheck = function (content) {
- var us_dict = new Typo("en_US", false, false, { dictionaryPath: "dicts" });
- var wordList = content.split(/\s+/);
- var suggestions = [];
-
- for (var i in wordList) {
- var word = wordList[i];
-
- // Check if our word contains a character that isn't a letter or an apostrophe.
- var nonWord = word.match(/[^a-zA-Z']/);
- if (!nonWord && word && !us_dict.check(word)) {
- var sugg = us_dict.suggest(word);
-
- if (sugg.length > 0) {
- suggestions.push({
- word: word,
- suggestions: sugg
- });
- }
- }
- }
-
- return suggestions;
- };
-
- var spellcheckCompleter = {
- getCompletions: function (editor, session, pos, prefix, callback) {
- var content = session.getValue();
- var suggestions = spellcheck(content);
- var wordList = [];
-
- suggestions.forEach(function (suggestion) {
- suggestion.suggestions.forEach(function (word) {
- wordList.push(word);
- });
- });
-
- callback(null, wordList.map(function (word) {
- return {
- caption: word,
- value: word,
- meta: 'spell'
- };
- }));
- }
- };
- langTools.addCompleter(spellcheckCompleter);
- }
-
+ // update the preview if this menu is clicked
+ var currentTab = $('#preview-content-' + field_name);
var editorTabButton = $('.tab-editor-' + field_name);
- editorTabButton.click(function () {
- // show the `.martor-toolbar` for this current editor if under preview.
- $(this).closest('.tab-martor-menu').find('.martor-toolbar').show();
- });
+ var previewTabButton = $('.tab-preview-' + field_name);
+ var toolbarButtons = $(this).closest('.tab-martor-menu').find('.martor-toolbar');
// Tailwind-specific tab handling
$('.tab-editor-' + field_name).click(function() {
@@ -236,11 +182,14 @@
previewTab,
previewContent
);
+
+ // show the `.martor-toolbar` for this current editor if under preview.
+ $(this).closest('.tab-martor-menu').find('.martor-toolbar').show();
});
$('.tab-preview-' + field_name).click(function() {
var editorContent = $('#editor-content-' + field_name);
- var previewContent = '#preview-content-' + field_name;
+ var previewContent = $('#preview-content-' + field_name);
var editorTab = $('.tab-editor-' + field_name);
TailwindUtils.toggleTab(
@@ -252,9 +201,78 @@
// hide the `.martor-toolbar` when activating tab preview.
$(this).closest('.tab-martor-menu').find('.martor-toolbar').hide();
- markdownfy(textareaId, $(previewContent), true);
+ refreshPreview();
});
+ var refreshPreview = function () {
+ var value = textareaId.val();
+ var form = new FormData();
+ form.append('content', value);
+ form.append('csrfmiddlewaretoken', getCookie('csrftoken'));
+ currentTab.addClass('martor-preview-stale');
+
+ $.ajax({
+ url: textareaId.data('markdownfy-url'),
+ type: 'POST',
+ data: form,
+ processData: false,
+ contentType: false,
+ success: function (response) {
+ if (response) {
+ currentTab.html(response).removeClass('martor-preview-stale');
+ currentTab.addClass('martor-preview');
+ $(document).trigger('martor:preview', [currentTab]);
+
+ if (editorConfig.hljs == 'true') {
+ $('pre').each(function (i, block) {
+ hljs.highlightBlock(block);
+ });
+ }
+ } else {
+ currentTab.html('Nothing to preview
');
+ }
+ },
+ error: function (response) {
+ console.log("error", response);
+ }
+ });
+ };
+
+ let timeoutID;
+
+ var refreshPreviewTimeout = function () {
+ if (timeoutID) {
+ clearTimeout(timeoutID);
+ }
+ timeoutID = setTimeout(refreshPreview, textareaId.data("save-timeout"));
+ }
+
+ // Refresh the preview unconditionally on first load.
+ window.onload = function () {
+ refreshPreview();
+ };
+
+ if (editorConfig.living !== 'true') {
+ previewTabButton.click(function () {
+ // hide the `.martor-toolbar` for this current editor if under preview.
+ toolbarButtons.hide();
+ refreshPreview();
+ });
+ } else {
+ editor.on('change', refreshPreviewTimeout);
+ }
+
+ // spellcheck
+ if (editorConfig.spellcheck == 'true') {
+ try {
+ enable_spellcheck(editorId);
+ } catch (e) {
+ console.log("Spellcheck lib doesn't installed.");
+ }
+ }
+
+
+
if (editorConfig.emoji == 'true') {
langTools = ace.require("ace/ext/language_tools");
langTools.addCompleter(emojiWordCompleter);
@@ -265,52 +283,7 @@
langTools.addCompleter(mentionWordCompleter);
}
- // The Markdown function.
- function markdownfy(textareaId, previewBox, isTabPreview) {
- var text = textareaId.val();
- var isLivePreview = editorConfig.living == 'true';
-
- if (text.length > 0) {
- var timeout = textareaId.data('save-timeout');
- var markdownfyUrl = textareaId.data('markdownfy-url');
- if (!isLivePreview && isTabPreview) {
- previewBox.html('Processing...
');
- }
-
- setTimeout(function () {
- $.ajax({
- url: markdownfyUrl,
- type: 'POST',
- data: {
- 'content': text,
- 'csrfmiddlewaretoken': getCookie('csrftoken')
- },
- success: function (data) {
- var content = data['content'];
- previewBox.html(content);
-
- // add class `.martor-preview` to applying the css.
- previewBox.addClass('martor-preview');
-
- // Scroll into bottom of preview only for non-living mode
- if (!isLivePreview && isTabPreview) {
- previewBox.animate({ scrollTop: previewBox[0].scrollHeight }, 800);
- }
-
- // Re-parse highlight on preview pane again.
- if (typeof (hljs) !== "undefined") {
- previewBox.find('pre code').each(function (i, block) {
- hljs.highlightBlock(block);
- });
- }
- }
- });
- }, timeout);
- } else {
- previewBox.html('Nothing to preview
');
- }
- }
// Handle toolbar dropdowns for Tailwind
$('.martor-toolbar .dropdown').each(function() {
@@ -348,19 +321,51 @@
});
// Toggle editor, preview, maximize
- $('.markdown-toggle-maximize[data-field-name=' + field_name + ']').click(function () {
- if ($(obj).hasClass('main-martor-fullscreen')) {
- $(obj).removeClass('main-martor-fullscreen');
- $('body').removeClass('overflow-hidden');
- } else {
- $(obj).addClass('main-martor-fullscreen');
- $('body').addClass('overflow-hidden');
+ var martorField = $('.martor-field-' + field_name);
+ var btnToggleMaximize = $('.markdown-toggle-maximize[data-field-name=' + field_name + ']');
+
+ // Toggle maximize and minimize
+ var handleToggleMinimize = function () {
+ $(document.body).removeClass('overflow-hidden');
+ $(this).attr({ 'title': 'Full Screen' });
+ $(this).find('svg.bi-arrows-angle-expand').removeClass('hidden');
+ $(this).find('svg.bi-arrows-angle-contract').addClass('hidden');
+ $('.main-martor-fullscreen').find('.martor-preview').removeAttr('style');
+ mainMartor.removeClass('main-martor-fullscreen');
+ martorField.removeAttr('style');
+ editor.resize();
+ }
+ var handleToggleMaximize = function (selector) {
+ selector.attr({ 'title': 'Minimize' });
+ selector.find('svg.bi-arrows-angle-expand').addClass('hidden');
+ selector.find('svg.bi-arrows-angle-contract').removeClass('hidden');
+ mainMartor.addClass('main-martor-fullscreen');
+
+ var clientHeight = document.body.clientHeight - 90;
+ martorField.attr({ 'style': 'height:' + clientHeight + 'px' });
+
+ var preview = $('.main-martor-fullscreen').find('.martor-preview');
+ preview.attr({ 'style': 'overflow-y: auto;height:' + clientHeight + 'px' });
+
+ editor.resize();
+ selector.one('click', handleToggleMinimize);
+ $(document.body).addClass('overflow-hidden');
+ }
+ btnToggleMaximize.on('click', function () {
+ handleToggleMaximize($(this));
+ });
+
+ // Exit full screen when `ESC` is pressed.
+ $(document).keyup(function (e) {
+ if (e.keyCode == 27 && mainMartor.hasClass('main-martor-fullscreen')) {
+ btnToggleMaximize.trigger('click');
}
});
// markdown insert emoji from the modal
$('.markdown-emoji[data-field-name=' + field_name + ']').click(function () {
var modalEmoji = $('.modal-emoji[data-field-name=' + field_name + ']');
+ TailwindUtils.showModal(modalEmoji);
var emojiList = typeof (emojis) != "undefined" ? emojis : []; // from `plugins/js/emojis.min.js`
var segmentEmoji = modalEmoji.find('.emoji-content-body');
var loaderInit = modalEmoji.find('.emoji-loader-init');
@@ -368,24 +373,22 @@
// setup initial loader
segmentEmoji.html('');
TailwindUtils.showElement(loaderInit);
- TailwindUtils.showModal(modalEmoji);
- setTimeout(function() {
for (var i = 0; i < emojiList.length; i++) {
var linkEmoji = textareaId.data('base-emoji-url') + emojiList[i].replace(/:/g, '') + '.png';
- segmentEmoji.append('');
+ segmentEmoji.append(''
+ + '');
$('a[data-emoji-target="' + emojiList[i] + '"]').click(function () {
markdownToEmoji(editor, $(this).data('emoji-target'));
TailwindUtils.hideModal(modalEmoji);
});
}
+
TailwindUtils.hideElement(loaderInit);
TailwindUtils.showElement(segmentEmoji);
- }, 100);
});
// Close emoji modal
@@ -396,264 +399,585 @@
// Set initial value if has the content before.
editor.setValue(textareaId.val(), -1);
- // Upload Image
- // reference: https://stackoverflow.com/questions/166221/how-can-i-upload-files-asynchronously
- var uploadProgress = $('.upload-progress[data-field-name=' + field_name + ']');
- $(obj).find('input[name=markdown-image-upload]').change(function () {
- if ($(this).val() === '') {
- return;
- }
- var formData = new FormData();
- var imageName = $(this)[0].files[0].name;
- var imageFile = $(this)[0].files[0];
- var imageSize = $(this)[0].files[0].size;
- var maxFileSize = 1024 * 1024 * 10; // 10MB
- if (imageSize > maxFileSize) {
- alert('Image size too large. Maximum file size is 10MB.');
- return;
+ // win/linux: Ctrl+B, mac: Command+B
+ var markdownToBold = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' **** ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + 3);
+ } else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '**' + text + '**');
+ originalRange.end.column += 4; // this because injected from 4 `*` characters.
+ editor.focus();
+ editor.selection.setSelectionRange(originalRange);
}
-
- formData.append('markdown-image-upload', imageFile);
- formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
-
- TailwindUtils.showElement(uploadProgress);
+ };
+ // win/linux: Ctrl+I, mac: Command+I
+ var markdownToItalic = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' __ ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + 2);
+ } else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '_' + text + '_');
+ originalRange.end.column += 2; // this because injected from 2 `_` characters.
+ editor.focus();
+ editor.selection.setSelectionRange(originalRange);
+ }
+ };
+ // win/linux: Ctrl+Shift+U, mac: Command+Shift+U
+ var markdownToUnderscores = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' ++++ ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + 3);
+ } else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '++' + text + '++');
+ originalRange.end.column += 4; // this because injected from 4 `*` characters.
+ editor.focus();
+ editor.selection.setSelectionRange(originalRange);
+ }
+ };
+ // win/linux: Ctrl+Shift+S, mac: Command+Shift+S
+ var markdownToStrikethrough = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' ~~~~ ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + 3);
+ } else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '~~' + text + '~~');
+ originalRange.end.column += 4; // this because injected from 4 `*` characters.
+ editor.focus();
+ editor.selection.setSelectionRange(originalRange);
+ }
+ };
+ // win/linux: Ctrl+H, mac: Command+H
+ var markdownToHorizontal = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '\n\n----------\n\n');
+ editor.focus();
+ editor.selection.moveTo(curpos.row + 4, curpos.column + 10);
+ }
+ else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '\n\n----------\n\n' + text);
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row + 4,
+ originalRange.end.column + 10
+ );
+ }
+ };
+ // win/linux: Ctrl+Alt+1, mac: Command+Option+1
+ var markdownToH1 = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '\n\n# ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row + 2, curpos.column + 2);
+ }
+ else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '\n\n# ' + text + '\n');
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row + 2,
+ originalRange.end.column + 2
+ );
+ }
+ };
+ // win/linux: Ctrl+Alt+2, mac: Command+Option+2
+ var markdownToH2 = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '\n\n## ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row + 2, curpos.column + 3);
+ }
+ else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '\n\n## ' + text + '\n');
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row + 2,
+ originalRange.end.column + 3
+ );
+ }
+ };
+ // win/linux: Ctrl+Alt+3, mac: Command+Option+3
+ var markdownToH3 = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '\n\n### ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row + 2, curpos.column + 4);
+ }
+ else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '\n\n### ' + text + '\n');
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row + 2,
+ originalRange.end.column + 4
+ );
+ }
+ };
+ // win/linux: Ctrl+Alt+P, mac: Command+Option+P
+ var markdownToPre = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '\n\n```\n\n```\n');
+ editor.focus();
+ editor.selection.moveTo(curpos.row + 3, curpos.column);
+ }
+ else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '\n\n```\n' + text + '\n```\n');
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row + 3,
+ originalRange.end.column + 3
+ );
+ }
+ };
+ // win/linux: Ctrl+Alt+C, mac: Command+Option+C
+ var markdownToCode = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' `` ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + 2);
+ } else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '`' + text + '`');
+ originalRange.end.column += 2; // this because injected from 2 `_` characters.
+ editor.focus();
+ editor.selection.setSelectionRange(originalRange);
+ }
+ };
+ // win/linux: Ctrl+Q, mac: Command+Shift+K
+ var markdownToBlockQuote = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '\n\n> \n');
+ editor.focus();
+ editor.selection.moveTo(curpos.row + 2, curpos.column + 2);
+ }
+ else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '\n\n> ' + text + '\n');
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row + 2,
+ originalRange.end.column + 2
+ );
+ }
+ };
+ // win/linux: Ctrl+U, mac: Command+U
+ var markdownToUnorderedList = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '\n\n* ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row + 2, curpos.column + 2);
+ }
+ else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '\n\n* ' + text);
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row + 2,
+ originalRange.end.column + 2
+ );
+ }
+ };
+ // win/linux: Ctrl+Shift+O, mac: Command+Option+O
+ var markdownToOrderedList = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '\n\n1. ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row + 2, curpos.column + 3);
+ }
+ else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '\n\n1. ' + text);
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row + 2,
+ originalRange.end.column + 3
+ );
+ }
+ };
+ // win/linux: Ctrl+L, mac: Command+L
+ var markdownToLink = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' [](https://) ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + 2);
+ } else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '[' + text + '](https://) ');
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row,
+ originalRange.end.column + 11
+ );
+ }
+ };
+ // win/linux: Ctrl+Shift+I, mac: Command+Option+I
+ // or via upload: imageData={name:null, link:null}
+ var markdownToImageLink = function (editor, imageData) {
+ var originalRange = editor.getSelectionRange();
+ if (typeof (imageData) === 'undefined') {
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, '  ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + 3);
+ } else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, ' ');
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row,
+ originalRange.end.column + 12
+ );
+ }
+ } else { // this if use image upload to imgur.
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' ');
+ editor.focus();
+ editor.selection.moveTo(
+ curpos.row,
+ curpos.column + imageData.name.length + 2
+ );
+ }
+ };
+ // win/linux: Ctrl+M, mac: Command+M
+ var markdownToMention = function (editor) {
+ var originalRange = editor.getSelectionRange();
+ if (editor.selection.isEmpty()) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' @[]');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + 3);
+ } else {
+ var range = editor.getSelectionRange();
+ var text = editor.session.getTextRange(range);
+ editor.session.replace(range, '@[' + text + ']');
+ editor.focus();
+ editor.selection.moveTo(
+ originalRange.end.row,
+ originalRange.end.column + 3
+ )
+ }
+ };
+ // Insert Emoji to text editor: $('.insert-emoji').data('emoji-target')
+ var markdownToEmoji = function (editor, data_target) {
+ var curpos = editor.getCursorPosition();
+ editor.session.insert(curpos, ' ' + data_target + ' ');
+ editor.focus();
+ editor.selection.moveTo(curpos.row, curpos.column + data_target.length + 2);
+ };
+ // Markdown Image Uploader auto insert to editor.
+ // with special insert, eg: 
+ var markdownToUploadImage = function (editor) {
+ var firstForm = $('#' + editorId).closest('form').get(0);
+ var field_name = editor.container.id.replace('martor-', '');
+ var form = new FormData(firstForm);
+ form.append('csrfmiddlewaretoken', getCookie('csrftoken'));
$.ajax({
url: textareaId.data('upload-url'),
type: 'POST',
- data: formData,
- processData: false,
+ data: form,
+ async: true,
+ cache: false,
contentType: false,
+ enctype: 'multipart/form-data',
+ processData: false,
beforeSend: function () {
- uploadProgress.find('.spinner').removeClass('hidden');
+ console.log('Uploading...');
+ $('.upload-progress[data-field-name=' + field_name + ']').show();
},
- success: function (data) {
- if (data['status'] == 200) {
- var imageUrl = data['image_url'];
- markdownToImageLink(editor, imageName, imageUrl);
+ success: function (response) {
+ $('.upload-progress[data-field-name=' + field_name + ']').hide();
+ if (response.status == 200) {
+ console.log(response);
+ markdownToImageLink(
+ editor = editor,
+ imageData = { name: response.name, link: response.link }
+ );
} else {
- alert(data['error']);
+ alert(response.error);
}
- TailwindUtils.hideElement(uploadProgress);
},
- error: function (xhr, textStatus, errorThrown) {
- alert('Image upload failed: ' + errorThrown);
- TailwindUtils.hideElement(uploadProgress);
+ error: function (response) {
+ console.log("error", response);
+ $('.upload-progress[data-field-name=' + field_name + ']').hide();
}
});
+ return false;
+ };
+
+ // Trigger Click
+ $('.markdown-bold[data-field-name=' + field_name + ']').click(function () {
+ markdownToBold(editor);
+ });
+ $('.markdown-italic[data-field-name=' + field_name + ']').click(function () {
+ markdownToItalic(editor);
+ });
+ $('.markdown-horizontal[data-field-name=' + field_name + ']').click(function () {
+ markdownToHorizontal(editor);
+ });
+ $('.markdown-h1[data-field-name=' + field_name + ']').click(function () {
+ markdownToH1(editor);
+ });
+ $('.markdown-h2[data-field-name=' + field_name + ']').click(function () {
+ markdownToH2(editor);
+ });
+ $('.markdown-h3[data-field-name=' + field_name + ']').click(function () {
+ markdownToH3(editor);
+ });
+ $('.markdown-pre[data-field-name=' + field_name + ']').click(function () {
+ markdownToPre(editor);
+ });
+ $('.markdown-code[data-field-name=' + field_name + ']').click(function () {
+ markdownToCode(editor);
+ });
+ $('.markdown-blockquote[data-field-name=' + field_name + ']').click(function () {
+ markdownToBlockQuote(editor);
+ });
+ $('.markdown-unordered-list[data-field-name=' + field_name + ']').click(function () {
+ markdownToUnorderedList(editor);
+ });
+ $('.markdown-ordered-list[data-field-name=' + field_name + ']').click(function () {
+ markdownToOrderedList(editor);
+ });
+ $('.markdown-link[data-field-name=' + field_name + ']').click(function () {
+ markdownToLink(editor);
+ });
+ $('.markdown-image-link[data-field-name=' + field_name + ']').click(function () {
+ markdownToImageLink(editor);
});
- // All the markdowns selector object
- var MarkdownSelectors = {
- bold: function () {
- markdownSyntaxWrap(editor, '**', '**', 'Bolded text');
- },
- italic: function () {
- markdownSyntaxWrap(editor, '*', '*', 'Italicized text');
- },
- horizontal: function () {
- markdownSyntaxWrap(editor, '', '\n***\n', '');
- },
- h1: function () {
- markdownSyntaxWrap(editor, '# ', '', 'Heading 1');
- },
- h2: function () {
- markdownSyntaxWrap(editor, '## ', '', 'Heading 2');
- },
- h3: function () {
- markdownSyntaxWrap(editor, '### ', '', 'Heading 3');
- },
- pre: function () {
- markdownSyntaxWrap(editor, '```\n', '\n```\n', 'Code goes here...');
- },
- code: function () {
- markdownSyntaxWrap(editor, '`', '`', 'Code goes here...');
- },
- quote: function () {
- markdownSyntaxWrap(editor, '> ', '', 'Quoted text');
- },
- ul: function () {
- markdownSyntaxWrap(editor, '* ', '', 'List item');
- },
- ol: function () {
- markdownSyntaxWrap(editor, '1. ', '', 'List item');
- },
- link: function () {
- markdownSyntaxWrap(editor, '[', '](http://)', 'link text');
- },
- image: function () {
- markdownSyntaxWrap(editor, '', 'image text');
- },
- mention: function () {
- markdownToDirectMention(editor);
- },
- emoji: function () {
- $('.markdown-emoji[data-field-name=' + field_name + ']').trigger('click');
- },
- toggle: function () {
- $('.markdown-toggle-maximize[data-field-name=' + field_name + ']').trigger('click');
- },
- help: function () {
- $('.markdown-help[data-field-name=' + field_name + ']').trigger('click');
- }
- };
+ // Custom decission for toolbar buttons.
+ var btnMention = $('.markdown-direct-mention[data-field-name=' + field_name + ']'); // To Direct Mention
+ var btnUpload = $('.markdown-image-upload[data-field-name=' + field_name + ']'); // To Upload Image
+
+ if (editorConfig.mention == 'true') {
+ btnMention.click(function () {
+ markdownToMention(editor);
+ });
+ } else {
+ btnMention.remove();
+ // Disable help of `mention`
+ $('.markdown-reference tbody tr')[1].remove();
+ }
+
+ if (editorConfig.imgur == 'true') {
+ btnUpload.on('change', function (evt) {
+ evt.preventDefault();
+ markdownToUploadImage(editor);
+ });
+ } else {
+ btnUpload.remove();
+ }
- // Markdowns selectors click events
- $(obj).find('.markdown-bold').click(function () { MarkdownSelectors.bold(); });
- $(obj).find('.markdown-italic').click(function () { MarkdownSelectors.italic(); });
- $(obj).find('.markdown-horizontal').click(function () { MarkdownSelectors.horizontal(); });
- $(obj).find('.markdown-h1').click(function () { MarkdownSelectors.h1(); });
- $(obj).find('.markdown-h2').click(function () { MarkdownSelectors.h2(); });
- $(obj).find('.markdown-h3').click(function () { MarkdownSelectors.h3(); });
- $(obj).find('.markdown-pre').click(function () { MarkdownSelectors.pre(); });
- $(obj).find('.markdown-code').click(function () { MarkdownSelectors.code(); });
- $(obj).find('.markdown-blockquote').click(function () { MarkdownSelectors.quote(); });
- $(obj).find('.markdown-unordered-list').click(function () { MarkdownSelectors.ul(); });
- $(obj).find('.markdown-ordered-list').click(function () { MarkdownSelectors.ol(); });
- $(obj).find('.markdown-link').click(function () { MarkdownSelectors.link(); });
- $(obj).find('.markdown-image-link').click(function () { MarkdownSelectors.image(); });
- $(obj).find('.markdown-direct-mention').click(function () { MarkdownSelectors.mention(); });
- $(obj).find('.markdown-emoji').click(function () { MarkdownSelectors.emoji(); });
- $(obj).find('.markdown-toggle-maximize').click(function () { MarkdownSelectors.toggle(); });
- $(obj).find('.markdown-help').click(function () { MarkdownSelectors.help(); });
-
- // Markdowns shorcuts key
+ // Trigger Keyboards
editor.commands.addCommand({
- name: 'bold',
+ name: 'markdownToBold',
bindKey: { win: 'Ctrl-B', mac: 'Command-B' },
- exec: function (editor) { MarkdownSelectors.bold(); },
- readOnly: false
+ exec: function (editor) {
+ markdownToBold(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'italic',
+ name: 'markdownToItalic',
bindKey: { win: 'Ctrl-I', mac: 'Command-I' },
- exec: function (editor) { MarkdownSelectors.italic(); },
- readOnly: false
+ exec: function (editor) {
+ markdownToItalic(editor);
+ },
+ readOnly: true
+ });
+ editor.commands.addCommand({
+ name: 'markdownToUnderscores',
+ bindKey: { win: 'Ctrl-Shift-U', mac: 'Command-Shift-U' },
+ exec: function (editor) {
+ markdownToUnderscores(editor);
+ },
+ readOnly: true
+ });
+ editor.commands.addCommand({
+ name: 'markdownToStrikethrough',
+ bindKey: { win: 'Ctrl-Shift-S', mac: 'Command-Shift-S' },
+ exec: function (editor) {
+ markdownToStrikethrough(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'horizontal',
+ name: 'markdownToHorizontal',
bindKey: { win: 'Ctrl-H', mac: 'Command-H' },
- exec: function (editor) { MarkdownSelectors.horizontal(); },
- readOnly: false
+ exec: function (editor) {
+ markdownToHorizontal(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'h1',
- bindKey: { win: 'Ctrl-Alt-1', mac: 'Command-Alt-1' },
- exec: function (editor) { MarkdownSelectors.h1(); },
- readOnly: false
+ name: 'markdownToH1',
+ bindKey: { win: 'Ctrl-Alt-1', mac: 'Command-Option-1' },
+ exec: function (editor) {
+ markdownToH1(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'h2',
- bindKey: { win: 'Ctrl-Alt-2', mac: 'Command-Alt-2' },
- exec: function (editor) { MarkdownSelectors.h2(); },
- readOnly: false
+ name: 'markdownToH2',
+ bindKey: { win: 'Ctrl-Alt-2', mac: 'Command-Option-3' },
+ exec: function (editor) {
+ markdownToH2(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'h3',
- bindKey: { win: 'Ctrl-Alt-3', mac: 'Command-Alt-3' },
- exec: function (editor) { MarkdownSelectors.h3(); },
- readOnly: false
+ name: 'markdownToH3',
+ bindKey: { win: 'Ctrl-Alt-3', mac: 'Command-Option-3' },
+ exec: function (editor) {
+ markdownToH3(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'pre',
- bindKey: { win: 'Ctrl-Alt-P', mac: 'Command-Alt-P' },
- exec: function (editor) { MarkdownSelectors.pre(); },
- readOnly: false
+ name: 'markdownToPre',
+ bindKey: { win: 'Ctrl-Alt-P', mac: 'Command-Option-P' },
+ exec: function (editor) {
+ markdownToPre(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'code',
- bindKey: { win: 'Ctrl-Alt-C', mac: 'Command-Alt-C' },
- exec: function (editor) { MarkdownSelectors.code(); },
- readOnly: false
+ name: 'markdownToCode',
+ bindKey: { win: 'Ctrl-Alt-C', mac: 'Command-Option-C' },
+ exec: function (editor) {
+ markdownToCode(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'quote',
- bindKey: { win: 'Ctrl-Q', mac: 'Command-Q' },
- exec: function (editor) { MarkdownSelectors.quote(); },
- readOnly: false
+ name: 'markdownToBlockQuote',
+ bindKey: { win: 'Ctrl-Q', mac: 'Command-Shift-K' },
+ exec: function (editor) {
+ markdownToBlockQuote(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'ul',
+ name: 'markdownToUnorderedList',
bindKey: { win: 'Ctrl-U', mac: 'Command-U' },
- exec: function (editor) { MarkdownSelectors.ul(); },
- readOnly: false
+ exec: function (editor) {
+ markdownToUnorderedList(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'ol',
- bindKey: { win: 'Ctrl-Shift-O', mac: 'Command-Shift-O' },
- exec: function (editor) { MarkdownSelectors.ol(); },
- readOnly: false
+ name: 'markdownToOrderedList',
+ bindKey: { win: 'Ctrl-Shift+O', mac: 'Command-Option-O' },
+ exec: function (editor) {
+ markdownToOrderedList(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'link',
+ name: 'markdownToLink',
bindKey: { win: 'Ctrl-L', mac: 'Command-L' },
- exec: function (editor) { MarkdownSelectors.link(); },
- readOnly: false
+ exec: function (editor) {
+ markdownToLink(editor);
+ },
+ readOnly: true
});
editor.commands.addCommand({
- name: 'image',
- bindKey: { win: 'Ctrl-Shift-I', mac: 'Command-Shift-I' },
- exec: function (editor) { MarkdownSelectors.image(); },
- readOnly: false
+ name: 'markdownToImageLink',
+ bindKey: { win: 'Ctrl-Shift-I', mac: 'Command-Option-I' },
+ exec: function (editor) {
+ markdownToImageLink(editor);
+ },
+ readOnly: true
});
+ if (editorConfig.mention === 'true') {
editor.commands.addCommand({
- name: 'mention',
+ name: 'markdownToMention',
bindKey: { win: 'Ctrl-M', mac: 'Command-M' },
- exec: function (editor) { MarkdownSelectors.mention(); },
- readOnly: false
- });
- });
-
- // Global function for markdown syntax wrapping
- function markdownSyntaxWrap(editor, startTag, endTag, defaultText) {
- var selectedText = editor.getSelectedText();
- var text = selectedText || defaultText;
- var range = editor.getSelectionRange();
-
- if (selectedText.length === 0) {
- // If no selection, place cursor between tags
- editor.session.replace(range, startTag + text + endTag);
- var newPos = range.start;
- newPos.column += startTag.length;
- editor.moveCursorToPosition(newPos);
- editor.clearSelection();
- } else {
- // If text is selected, wrap it with tags
- editor.session.replace(range, startTag + text + endTag);
+ exec: function (editor) {
+ markdownToMention(editor);
+ },
+ readOnly: true
+ });
}
- editor.focus();
- }
-
- // markdown to image link
- function markdownToImageLink(editor, imageName, imageUrl) {
- var text = '';
- var range = editor.getSelectionRange();
- editor.session.replace(range, text);
- editor.focus();
- }
-
- // markdown to emoji
- function markdownToEmoji(editor, emojiName) {
- var text = emojiName + ' ';
- var range = editor.getSelectionRange();
- editor.session.replace(range, text);
- editor.focus();
- }
-
- // markdown to direct mention
- function markdownToDirectMention(editor) {
- var text = '@[username] ';
- var range = editor.getSelectionRange();
- editor.session.replace(range, text);
-
- // Select the "username" part for easy replacement
- var newRange = range;
- newRange.start.column += 2; // position after @[
- newRange.end.column += 10; // position before ]
- editor.selection.setRange(newRange);
- editor.focus();
- }
+ });
};
+
+ $(function () {
+ $('.main-martor').martor();
+ });
+
+ if ('django' in window && 'jQuery' in window.django)
+ django.jQuery(document).on('formset:added', function (event) {
+ // add delay for formset to load
+ setTimeout(function(){
+ var row = $(event.target);
+ row.find('.main-martor').each(function () {
+ var id = row.attr('id');
+ id = id.substr(id.lastIndexOf('-') + 1);
+ // Notice here we are using our jQuery instead of Django's.
+ // This is because plugins are only loaded for ours.
+ var fixed = $(this.outerHTML.replace(/__prefix__/g, id));
+ $(this).replaceWith(fixed);
+ fixed.martor();
+ });
+ }, 1000);
+ });
})(jQuery);
diff --git a/martor/static/martor/js/martor.tailwind.min.js b/martor/static/martor/js/martor.tailwind.min.js
index d6d34d1b..4ab28191 100644
--- a/martor/static/martor/js/martor.tailwind.min.js
+++ b/martor/static/martor/js/martor.tailwind.min.js
@@ -1,5 +1,9 @@
/**
- * Martor v1.6.45 (Tailwind CSS Version) - Minified
- * License: GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
+ * Name : Martor v1.6.45
+ * Created by : Agus Makmun (Summon Agus)
+ * Release date : 15-Nov-2024
+ * License : GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007
+ * Repository : https://github.com/agusmakmun/django-markdown-editor
+ * JS Minifier : https://jscompress.com
**/
-!function(e){e=e||django.jQuery,e.fn.martor=function(){e(".martor").trigger("martor.init");var t={showElement:function(t){e(t).removeClass("hidden").addClass("block")},hideElement:function(t){e(t).removeClass("block").addClass("hidden")},showModal:function(t){e(t).removeClass("hidden").addClass("flex"),e("body").addClass("overflow-hidden")},hideModal:function(t){e(t).removeClass("flex").addClass("hidden"),e("body").removeClass("overflow-hidden")},toggleTab:function(t,n,o,r){e(o).removeClass("border-b-2 border-gray-800 text-gray-700").addClass("text-gray-500"),e(r).removeClass("block").addClass("hidden"),e(t).removeClass("text-gray-500").addClass("border-b-2 border-gray-800 text-gray-700"),e(n).removeClass("hidden").addClass("block")}},n=function(e){var t=null,n=0;if(document.cookie&&""!==document.cookie)for(var o=document.cookie.split(";");n0){var s=o.data("save-timeout"),d=o.data("markdownfy-url");l||!r||r.html('Processing...
'),setTimeout(function(){e.ajax({url:d,type:"POST",data:{content:c,csrfmiddlewaretoken:n("csrftoken")},success:function(e){var n=e.content;r.html(n),r.addClass("martor-preview"),l||!r||r.animate({scrollTop:r[0].scrollHeight},800),"undefined"!=typeof hljs&&r.find("pre code").each(function(e,t){hljs.highlightBlock(t)})}})},s)}else r.html('Nothing to preview
')}this.each(function(l,s){var d=e(s),u=d.data("field-name"),m=e("#id_"+u),f="martor-"+u,h=ace.edit(f),g=JSON.parse(m.data("enable-configs").replace(/'/g,'"'));h.setTheme("ace/theme/github"),h.getSession().setMode("ace/mode/markdown"),h.getSession().setUseWrapMode(!0),h.$blockScrolling=1/0,h.renderer.setScrollMargin(10,10),h.setAutoScrollEditorIntoView(!0),h.setShowPrintMargin(!1),h.setOptions({enableBasicAutocompletion:!0,enableSnippets:!0,enableLiveAutocompletion:!0,enableMultiselect:!1}),"true"==g.living&&e(s).addClass("enable-living");var p={getCompletions:function(e,t,n,o,r){var a="undefined"!=typeof emojis?emojis:[],i=e.getSession().getTokenAt(n.row,n.column.count);if("undefined"!=typeof i.value){var c=i.value.split(/\s+/);c[c.length-1][0]==":"&&r(null,a.map(function(e){return{caption:e,value:e.replace(":","")+" ",meta:"emoji"}}))}}},v={getCompletions:function(t,o,r,a,i){var c=t.getSession().getTokenAt(r.row,r.column.count);if("undefined"!=typeof c.value){var l=c.value.split(/\s+/),s=l[l.length-1];if("@"==s[0]&&"["==s[1]){username=s.replace(/([\@\[\/\]/])/g,""),e.ajax({url:m.data("search-users-url"),data:{username:username,csrfmiddlewaretoken:n("csrftoken")},success:function(e){if(200==e.status){for(var t=[],n=0;n0&&c(m,e(".tab-preview-"+u),!1)});var b=e(".tab-editor-"+u);b.click(function(){e(this).closest(".tab-martor-menu").find(".martor-toolbar").show()}),e(".tab-editor-"+u).click(function(){var n=e("#editor-content-"+u),o=e("#preview-content-"+u),r=e(".tab-preview-"+u);t.toggleTab(this,n,r,o)}),e(".tab-preview-"+u).click(function(){var n=e("#editor-content-"+u),o="#preview-content-"+u,r=e(".tab-editor-"+u);t.toggleTab(this,o,r,n),e(this).closest(".tab-martor-menu").find(".martor-toolbar").hide(),c(m,e(o),!0)}),"true"==g.emoji&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(p)),"true"==g.mention&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(v)),e(".martor-toolbar .dropdown").each(function(){var t=e(this),n=t.find(".dropdown-toggle"),o=t.find(".dropdown-menu");n.click(function(n){n.preventDefault(),n.stopPropagation(),e(".martor-toolbar .dropdown-menu").not(o).addClass("hidden"),o.toggleClass("hidden")}),e(document).click(function(e){t.is(e.target)||0!==t.has(e.target).length||o.addClass("hidden")})}),e(".markdown-help[data-field-name="+u+"]").click(function(){t.showModal(".modal-help-guide[data-field-name="+u+"]")}),e(".modal-help-guide[data-field-name="+u+"] .modal-close").click(function(){t.hideModal(".modal-help-guide[data-field-name="+u+"]")}),e(".markdown-toggle-maximize[data-field-name="+u+"]").click(function(){e(s).hasClass("main-martor-fullscreen")?(e(s).removeClass("main-martor-fullscreen"),e("body").removeClass("overflow-hidden")):(e(s).addClass("main-martor-fullscreen"),e("body").addClass("overflow-hidden"))}),e(".markdown-emoji[data-field-name="+u+"]").click(function(){var n=e(".modal-emoji[data-field-name="+u+"]"),o="undefined"!=typeof emojis?emojis:[],r=n.find(".emoji-content-body"),i=n.find(".emoji-loader-init");r.html(""),t.showElement(i),t.showModal(n),setTimeout(function(){for(var c=0;c '),e('a[data-emoji-target="'+o[c]+'"]').click(function(){a(h,e(this).data("emoji-target")),t.hideModal(n)})}t.hideElement(i),t.showElement(r)},100)}),e(".modal-emoji[data-field-name="+u+"] .modal-close").click(function(){t.hideModal(".modal-emoji[data-field-name="+u+"]")}),h.setValue(m.val(),-1);var y=e(".upload-progress[data-field-name="+u+"]");e(s).find("input[name=markdown-image-upload]").change(function(){if(""!==e(this).val()){var o=new FormData,a=e(this)[0].files[0].name,i=e(this)[0].files[0],c=e(this)[0].files[0].size;if(c>10485760)return void alert("Image size too large. Maximum file size is 10MB.");o.append("markdown-image-upload",i),o.append("csrfmiddlewaretoken",n("csrftoken")),t.showElement(y),e.ajax({url:m.data("upload-url"),type:"POST",data:o,processData:!1,contentType:!1,beforeSend:function(){y.find(".spinner").removeClass("hidden")},success:function(e){200==e.status?r(h,a,e.image_url):alert(e.error),t.hideElement(y)},error:function(e,n,o){alert("Image upload failed: "+o),t.hideElement(y)}})}});var k={bold:function(){o(h,"**","**","Bolded text")},italic:function(){o(h,"*","*","Italicized text")},horizontal:function(){o(h,"","\n***\n","")},h1:function(){o(h,"# ","","Heading 1")},h2:function(){o(h,"## ","","Heading 2")},h3:function(){o(h,"### ","","Heading 3")},pre:function(){o(h,"```\n","\n```\n","Code goes here...")},code:function(){o(h,"`","`","Code goes here...")},quote:function(){o(h,"> ","","Quoted text")},ul:function(){o(h,"* ","","List item")},ol:function(){o(h,"1. ","","List item")},link:function(){o(h,"[","](http://)","link text")},image:function(){o(h,"","image text")},mention:function(){i(h)},emoji:function(){e(".markdown-emoji[data-field-name="+u+"]").trigger("click")},toggle:function(){e(".markdown-toggle-maximize[data-field-name="+u+"]").trigger("click")},help:function(){e(".markdown-help[data-field-name="+u+"]").trigger("click")}};e(s).find(".markdown-bold").click(function(){k.bold()}),e(s).find(".markdown-italic").click(function(){k.italic()}),e(s).find(".markdown-horizontal").click(function(){k.horizontal()}),e(s).find(".markdown-h1").click(function(){k.h1()}),e(s).find(".markdown-h2").click(function(){k.h2()}),e(s).find(".markdown-h3").click(function(){k.h3()}),e(s).find(".markdown-pre").click(function(){k.pre()}),e(s).find(".markdown-code").click(function(){k.code()}),e(s).find(".markdown-blockquote").click(function(){k.quote()}),e(s).find(".markdown-unordered-list").click(function(){k.ul()}),e(s).find(".markdown-ordered-list").click(function(){k.ol()}),e(s).find(".markdown-link").click(function(){k.link()}),e(s).find(".markdown-image-link").click(function(){k.image()}),e(s).find(".markdown-direct-mention").click(function(){k.mention()}),e(s).find(".markdown-emoji").click(function(){k.emoji()}),e(s).find(".markdown-toggle-maximize").click(function(){k.toggle()}),e(s).find(".markdown-help").click(function(){k.help()}),h.commands.addCommand({name:"bold",bindKey:{win:"Ctrl-B",mac:"Command-B"},exec:function(e){k.bold()},readOnly:!1}),h.commands.addCommand({name:"italic",bindKey:{win:"Ctrl-I",mac:"Command-I"},exec:function(e){k.italic()},readOnly:!1}),h.commands.addCommand({name:"horizontal",bindKey:{win:"Ctrl-H",mac:"Command-H"},exec:function(e){k.horizontal()},readOnly:!1}),h.commands.addCommand({name:"h1",bindKey:{win:"Ctrl-Alt-1",mac:"Command-Alt-1"},exec:function(e){k.h1()},readOnly:!1}),h.commands.addCommand({name:"h2",bindKey:{win:"Ctrl-Alt-2",mac:"Command-Alt-2"},exec:function(e){k.h2()},readOnly:!1}),h.commands.addCommand({name:"h3",bindKey:{win:"Ctrl-Alt-3",mac:"Command-Alt-3"},exec:function(e){k.h3()},readOnly:!1}),h.commands.addCommand({name:"pre",bindKey:{win:"Ctrl-Alt-P",mac:"Command-Alt-P"},exec:function(e){k.pre()},readOnly:!1}),h.commands.addCommand({name:"code",bindKey:{win:"Ctrl-Alt-C",mac:"Command-Alt-C"},exec:function(e){k.code()},readOnly:!1}),h.commands.addCommand({name:"quote",bindKey:{win:"Ctrl-Q",mac:"Command-Q"},exec:function(e){k.quote()},readOnly:!1}),h.commands.addCommand({name:"ul",bindKey:{win:"Ctrl-U",mac:"Command-U"},exec:function(e){k.ul()},readOnly:!1}),h.commands.addCommand({name:"ol",bindKey:{win:"Ctrl-Shift-O",mac:"Command-Shift-O"},exec:function(e){k.ol()},readOnly:!1}),h.commands.addCommand({name:"link",bindKey:{win:"Ctrl-L",mac:"Command-L"},exec:function(e){k.link()},readOnly:!1}),h.commands.addCommand({name:"image",bindKey:{win:"Ctrl-Shift-I",mac:"Command-Shift-I"},exec:function(e){k.image()},readOnly:!1}),h.commands.addCommand({name:"mention",bindKey:{win:"Ctrl-M",mac:"Command-M"},exec:function(e){k.mention()},readOnly:!1})})}}(jQuery);
+!function(L){(L=L||django.jQuery).fn.martor=function(){L(".martor").trigger("martor.init");function A(e){var n=null,o=0;if(document.cookie&&""!==document.cookie)for(var t=document.cookie.split(";");oNothing to preview
')},error:function(e){console.log("error",e)}})};let g;if(window.onload=function(){u()},"true"!==a.living?n.click(function(){m.hide(),u()}):c.on("change",function(){g&&clearTimeout(g),g=setTimeout(u,r.data("save-timeout"))}),"true"==a.spellcheck)try{enable_spellcheck(t)}catch(e){console.log("Spellcheck lib doesn't installed.")}"true"==a.emoji&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(i)),"true"==a.mention&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(l)),L(".martor-toolbar .dropdown").each(function(){var n=L(this),e=n.find(".dropdown-toggle"),o=n.find(".dropdown-menu");e.click(function(e){e.preventDefault(),e.stopPropagation(),L(".martor-toolbar .dropdown-menu").not(o).addClass("hidden"),o.toggleClass("hidden")}),L(document).click(function(e){n.is(e.target)||0!==n.has(e.target).length||o.addClass("hidden")})}),L(".markdown-help[data-field-name="+s+"]").click(function(){I(".modal-help-guide[data-field-name="+s+"]")}),L(".modal-help-guide[data-field-name="+s+"] .modal-close").click(function(){U(".modal-help-guide[data-field-name="+s+"]")});function f(){L(document.body).removeClass("overflow-hidden"),L(this).attr({title:"Full Screen"}),L(this).find("svg.bi-arrows-angle-expand").removeClass("hidden"),L(this).find("svg.bi-arrows-angle-contract").addClass("hidden"),L(".main-martor-fullscreen").find(".martor-preview").removeAttr("style"),o.removeClass("main-martor-fullscreen"),p.removeAttr("style"),c.resize()}var p=L(".martor-field-"+s),v=L(".markdown-toggle-maximize[data-field-name="+s+"]");v.on("click",function(){!function(e){e.attr({title:"Minimize"}),e.find("svg.bi-arrows-angle-expand").addClass("hidden"),e.find("svg.bi-arrows-angle-contract").removeClass("hidden"),o.addClass("main-martor-fullscreen");var n=document.body.clientHeight-90;p.attr({style:"height:"+n+"px"}),L(".main-martor-fullscreen").find(".martor-preview").attr({style:"overflow-y: auto;height:"+n+"px"}),c.resize(),e.one("click",f),L(document.body).addClass("overflow-hidden")}(L(this))}),L(document).keyup(function(e){27==e.keyCode&&o.hasClass("main-martor-fullscreen")&&v.trigger("click")}),L(".markdown-emoji[data-field-name="+s+"]").click(function(){var e=L(".modal-emoji[data-field-name="+s+"]");I(e);var n="undefined"!=typeof emojis?emojis:[],o=e.find(".emoji-content-body"),t=e.find(".emoji-loader-init");o.html(""),_(t);for(var a=0;a '+n[a]+" "),L('a[data-emoji-target="'+n[a]+'"]').click(function(){K(c,L(this).data("emoji-target")),U(e)})}M(t),_(o)}),L(".modal-emoji[data-field-name="+s+"] .modal-close").click(function(){U(".modal-emoji[data-field-name="+s+"]")}),c.setValue(r.val(),-1);function w(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," **** "),e.focus(),e.selection.moveTo(o.row,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"**"+o+"**"),t.end.column+=4,e.focus(),e.selection.setSelectionRange(t))}function C(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," __ "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"_"+o+"_"),t.end.column+=2,e.focus(),e.selection.setSelectionRange(t))}function h(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n----------\n\n"),e.focus(),e.selection.moveTo(o.row+4,o.column+10)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n----------\n\n"+o),e.focus(),e.selection.moveTo(t.end.row+4,t.end.column+10))}function k(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n# "),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n# "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function y(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n## "),e.focus(),e.selection.moveTo(o.row+2,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n## "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+3))}function T(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n### "),e.focus(),e.selection.moveTo(o.row+2,o.column+4)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n### "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+4))}function b(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n```\n\n```\n"),e.focus(),e.selection.moveTo(o.row+3,o.column)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n```\n"+o+"\n```\n"),e.focus(),e.selection.moveTo(t.end.row+3,t.end.column+3))}function S(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," `` "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"`"+o+"`"),t.end.column+=2,e.focus(),e.selection.setSelectionRange(t))}function R(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n> \n"),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n> "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function x(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n* "),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n* "+o),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function j(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n1. "),e.focus(),e.selection.moveTo(o.row+2,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n1. "+o),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+3))}function O(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," [](https://) "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"["+o+"](https://) "),e.focus(),e.selection.moveTo(t.end.row,t.end.column+11))}function P(e,n){var o,t,a,i=e.getSelectionRange();void 0===n?e.selection.isEmpty()?(a=e.getCursorPosition(),e.session.insert(a,"  "),e.focus(),e.selection.moveTo(a.row,a.column+3)):(o=e.getSelectionRange(),t=e.session.getTextRange(o),e.session.replace(o," "),e.focus(),e.selection.moveTo(i.end.row,i.end.column+12)):(a=e.getCursorPosition(),e.session.insert(a," "),e.focus(),e.selection.moveTo(a.row,a.column+n.name.length+2))}function E(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," @[]"),e.focus(),e.selection.moveTo(o.row,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"@["+o+"]"),e.focus(),e.selection.moveTo(t.end.row,t.end.column+3))}var K=function(e,n){var o=e.getCursorPosition();e.session.insert(o," "+n+" "),e.focus(),e.selection.moveTo(o.row,o.column+n.length+2)};L(".markdown-bold[data-field-name="+s+"]").click(function(){w(c)}),L(".markdown-italic[data-field-name="+s+"]").click(function(){C(c)}),L(".markdown-horizontal[data-field-name="+s+"]").click(function(){h(c)}),L(".markdown-h1[data-field-name="+s+"]").click(function(){k(c)}),L(".markdown-h2[data-field-name="+s+"]").click(function(){y(c)}),L(".markdown-h3[data-field-name="+s+"]").click(function(){T(c)}),L(".markdown-pre[data-field-name="+s+"]").click(function(){b(c)}),L(".markdown-code[data-field-name="+s+"]").click(function(){S(c)}),L(".markdown-blockquote[data-field-name="+s+"]").click(function(){R(c)}),L(".markdown-unordered-list[data-field-name="+s+"]").click(function(){x(c)}),L(".markdown-ordered-list[data-field-name="+s+"]").click(function(){j(c)}),L(".markdown-link[data-field-name="+s+"]").click(function(){O(c)}),L(".markdown-image-link[data-field-name="+s+"]").click(function(){P(c)});i=L(".markdown-direct-mention[data-field-name="+s+"]"),l=L(".markdown-image-upload[data-field-name="+s+"]");"true"==a.mention?i.click(function(){E(c)}):(i.remove(),L(".markdown-reference tbody tr")[1].remove()),"true"==a.imgur?l.on("change",function(e){var n,o;e.preventDefault(),n=c,e=L("#"+t).closest("form").get(0),o=n.container.id.replace("martor-",""),(e=new FormData(e)).append("csrfmiddlewaretoken",A("csrftoken")),L.ajax({url:r.data("upload-url"),type:"POST",data:e,async:!0,cache:!1,contentType:!1,enctype:"multipart/form-data",processData:!1,beforeSend:function(){console.log("Uploading..."),L(".upload-progress[data-field-name="+o+"]").show()},success:function(e){L(".upload-progress[data-field-name="+o+"]").hide(),200==e.status?(console.log(e),P(n,imageData={name:e.name,link:e.link})):alert(e.error)},error:function(e){console.log("error",e),L(".upload-progress[data-field-name="+o+"]").hide()}})}):l.remove(),c.commands.addCommand({name:"markdownToBold",bindKey:{win:"Ctrl-B",mac:"Command-B"},exec:function(e){w(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToItalic",bindKey:{win:"Ctrl-I",mac:"Command-I"},exec:function(e){C(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToUnderscores",bindKey:{win:"Ctrl-Shift-U",mac:"Command-Shift-U"},exec:function(e){var n,o,t;t=(n=e).getSelectionRange(),n.selection.isEmpty()?(o=n.getCursorPosition(),n.session.insert(o," ++++ "),n.focus(),n.selection.moveTo(o.row,o.column+3)):(e=n.getSelectionRange(),o=n.session.getTextRange(e),n.session.replace(e,"++"+o+"++"),t.end.column+=4,n.focus(),n.selection.setSelectionRange(t))},readOnly:!0}),c.commands.addCommand({name:"markdownToStrikethrough",bindKey:{win:"Ctrl-Shift-S",mac:"Command-Shift-S"},exec:function(e){var n,o,t;t=(n=e).getSelectionRange(),n.selection.isEmpty()?(o=n.getCursorPosition(),n.session.insert(o," ~~~~ "),n.focus(),n.selection.moveTo(o.row,o.column+3)):(e=n.getSelectionRange(),o=n.session.getTextRange(e),n.session.replace(e,"~~"+o+"~~"),t.end.column+=4,n.focus(),n.selection.setSelectionRange(t))},readOnly:!0}),c.commands.addCommand({name:"markdownToHorizontal",bindKey:{win:"Ctrl-H",mac:"Command-H"},exec:function(e){h(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH1",bindKey:{win:"Ctrl-Alt-1",mac:"Command-Option-1"},exec:function(e){k(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH2",bindKey:{win:"Ctrl-Alt-2",mac:"Command-Option-3"},exec:function(e){y(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH3",bindKey:{win:"Ctrl-Alt-3",mac:"Command-Option-3"},exec:function(e){T(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToPre",bindKey:{win:"Ctrl-Alt-P",mac:"Command-Option-P"},exec:function(e){b(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToCode",bindKey:{win:"Ctrl-Alt-C",mac:"Command-Option-C"},exec:function(e){S(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToBlockQuote",bindKey:{win:"Ctrl-Q",mac:"Command-Shift-K"},exec:function(e){R(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToUnorderedList",bindKey:{win:"Ctrl-U",mac:"Command-U"},exec:function(e){x(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToOrderedList",bindKey:{win:"Ctrl-Shift+O",mac:"Command-Option-O"},exec:function(e){j(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToLink",bindKey:{win:"Ctrl-L",mac:"Command-L"},exec:function(e){O(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToImageLink",bindKey:{win:"Ctrl-Shift-I",mac:"Command-Option-I"},exec:function(e){P(e)},readOnly:!0}),"true"===a.mention&&c.commands.addCommand({name:"markdownToMention",bindKey:{win:"Ctrl-M",mac:"Command-M"},exec:function(e){E(e)},readOnly:!0})})},L(function(){L(".main-martor").martor()}),"django"in window&&"jQuery"in window.django&&django.jQuery(document).on("formset:added",function(e){setTimeout(function(){var n=L(e.target);n.find(".main-martor").each(function(){var e=(e=n.attr("id")).substr(e.lastIndexOf("-")+1),e=L(this.outerHTML.replace(/__prefix__/g,e));L(this).replaceWith(e),e.martor()})},1e3)})}(jQuery);
diff --git a/martor_demo/app/templates/tailwind/base.html b/martor_demo/app/templates/tailwind/base.html
index fad2be65..5e44912c 100644
--- a/martor_demo/app/templates/tailwind/base.html
+++ b/martor_demo/app/templates/tailwind/base.html
@@ -13,7 +13,7 @@
{% block css %}
-
+
{% endblock %}
{% endblock %}
diff --git a/martor_demo/martor_demo/settings.py b/martor_demo/martor_demo/settings.py
index 360dff34..a3d1b5bf 100644
--- a/martor_demo/martor_demo/settings.py
+++ b/martor_demo/martor_demo/settings.py
@@ -30,6 +30,9 @@
DEBUG = True
ALLOWED_HOSTS = ["*"]
+# Required for Martor AJAX functionality
+CSRF_COOKIE_HTTPONLY = False
+
# Martor Configuration
MARTOR_THEME = "tailwind" # bootstrap, semantic
MARTOR_ENABLE_LABEL = True
From 337b597c5566cb174fdc857d9a8a8d976800a9c2 Mon Sep 17 00:00:00 2001
From: agusmakmun
Date: Sat, 30 Aug 2025 00:00:14 +0700
Subject: [PATCH 3/3] fix: emoji and style
---
martor/static/martor/css/martor.tailwind.css | 177 +++++++-
.../static/martor/css/martor.tailwind.min.css | 2 +-
martor/static/martor/js/martor.tailwind.js | 164 ++++++--
.../static/martor/js/martor.tailwind.min.js | 2 +-
martor/templates/martor/tailwind/emoji.html | 145 ++-----
martor/templates/martor/tailwind/guide.html | 393 ++++++++----------
martor/templates/martor/tailwind/toolbar.html | 3 +-
martor_demo/app/templates/tailwind/base.html | 4 +-
martor_demo/app/templates/tailwind/form.html | 15 +-
9 files changed, 544 insertions(+), 361 deletions(-)
diff --git a/martor/static/martor/css/martor.tailwind.css b/martor/static/martor/css/martor.tailwind.css
index f66cb904..ca35ac97 100644
--- a/martor/static/martor/css/martor.tailwind.css
+++ b/martor/static/martor/css/martor.tailwind.css
@@ -41,6 +41,137 @@ body.overflow {
line-height: 1.5rem;
}
+/* Help Guide Modal */
+.modal-help-guide {
+ z-index: 99999 !important;
+}
+
+.modal-help-guide.flex {
+ display: flex !important;
+ position: fixed !important;
+ top: 0 !important;
+ left: 0 !important;
+ width: 100vw !important;
+ height: 100vh !important;
+ opacity: 1 !important;
+ visibility: visible !important;
+}
+
+.modal-help-guide .bg-white {
+ display: block !important;
+ background-color: white !important;
+ border-radius: 12px !important;
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25) !important;
+ max-width: 900px !important;
+ width: 95% !important;
+ max-height: 90vh !important;
+ margin: 0 auto !important;
+ z-index: 20 !important;
+ visibility: visible !important;
+ opacity: 1 !important;
+ position: relative !important;
+ overflow: hidden !important;
+}
+
+.modal-help-guide .flex.items-center {
+ display: flex !important;
+ align-items: center !important;
+ justify-content: center !important;
+ text-align: center !important;
+ width: 100% !important;
+ height: 100% !important;
+}
+
+/* Enhanced Table Styling */
+.modal-help-guide table {
+ border-collapse: separate !important;
+ border-spacing: 0 !important;
+ width: 100% !important;
+ font-size: 14px !important;
+ line-height: 1.5 !important;
+}
+
+.modal-help-guide th {
+ background-color: #f8fafc !important;
+ font-weight: 600 !important;
+ text-transform: uppercase !important;
+ letter-spacing: 0.05em !important;
+ font-size: 12px !important;
+ color: #64748b !important;
+ padding: 12px 16px !important;
+ border-bottom: 2px solid #e2e8f0 !important;
+ text-align: left !important;
+}
+
+.modal-help-guide td {
+ padding: 16px !important;
+ border-bottom: 1px solid #f1f5f9 !important;
+ vertical-align: top !important;
+}
+
+.modal-help-guide tr:hover td {
+ background-color: #f8fafc !important;
+}
+
+.modal-help-guide code {
+ background-color: #f1f5f9 !important;
+ color: #475569 !important;
+ padding: 6px 10px !important;
+ border-radius: 6px !important;
+ font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', 'Source Code Pro', monospace !important;
+ font-size: 13px !important;
+ font-weight: 500 !important;
+ border: 1px solid #e2e8f0 !important;
+ white-space: nowrap !important;
+}
+
+.modal-help-guide kbd {
+ background-color: #334155 !important;
+ color: white !important;
+ padding: 4px 8px !important;
+ border-radius: 4px !important;
+ font-family: -apple-system, BlinkMacSystemFont, sans-serif !important;
+ font-size: 11px !important;
+ font-weight: 600 !important;
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
+ border: 1px solid #1e293b !important;
+}
+
+.modal-help-guide h1,
+.modal-help-guide h2 {
+ margin: 0 !important;
+ font-weight: 700 !important;
+}
+
+.modal-help-guide blockquote {
+ margin: 0 !important;
+ font-style: italic !important;
+ color: #64748b !important;
+}
+
+.modal-help-guide ul,
+.modal-help-guide ol {
+ margin: 0 !important;
+ padding-left: 20px !important;
+}
+
+.modal-help-guide pre {
+ margin: 0 !important;
+ background-color: #f8fafc !important;
+ border: 1px solid #e2e8f0 !important;
+ border-radius: 6px !important;
+ padding: 12px !important;
+ font-size: 13px !important;
+ overflow-x: auto !important;
+}
+
+.modal-help-guide hr {
+ border: none !important;
+ height: 2px !important;
+ background-color: #e2e8f0 !important;
+ margin: 8px 0 !important;
+}
+
/* Upload Progress Overlay */
.main-martor .upload-progress {
position: absolute;
@@ -287,6 +418,7 @@ div.martor-preview pre {
div.martor-preview hr {
background: transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxBEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;
@apply border-0 text-gray-300 h-1 p-0;
+ margin: 1rem 0;
}
/* First Child Margin Reset */
@@ -323,13 +455,27 @@ div.martor-preview li p.first {
@apply inline-block;
}
-div.martor-preview ul li {
- @apply list-disc;
+div.martor-preview ul {
+ @apply pl-8;
+ margin: 1rem 0;
+ list-style-type: disc !important;
+ list-style-position: inside !important;
+ display: block !important;
}
-div.martor-preview ul,
div.martor-preview ol {
@apply pl-8;
+ margin: 1rem 0;
+ list-style-type: decimal !important;
+ list-style-position: inside !important;
+ display: block !important;
+}
+
+div.martor-preview ul li,
+div.martor-preview ol li {
+ margin: 0.25rem 0;
+ padding-left: 0.5rem;
+ display: list-item !important;
}
div.martor-preview ul.no-list,
@@ -337,6 +483,7 @@ div.martor-preview ol.no-list {
@apply list-none p-0;
}
+/* Nested list styles */
div.martor-preview ul li> :first-child,
div.martor-preview ul li ul:first-of-type,
div.martor-preview ol li> :first-child,
@@ -349,6 +496,14 @@ div.martor-preview ul ol,
div.martor-preview ol ol,
div.martor-preview ol ul {
@apply mb-0;
+ margin-top: 0.5rem;
+}
+
+/* Ensure nested lists have proper indentation */
+div.martor-preview li>ul,
+div.martor-preview li>ol {
+ @apply pl-4;
+ margin: 0.25rem 0;
}
/* Definition Lists */
@@ -386,15 +541,25 @@ div.martor-preview dl dd> :last-child {
/* Blockquotes */
div.martor-preview blockquote {
- @apply border-l-4 border-gray-300 py-1 px-4 text-gray-500 bg-white;
+ border-left: 4px solid #d1d5db !important;
+ padding: 0.25rem 1rem !important;
+ margin: 1rem 0 !important;
+ background-color: #f9fafb !important;
+ color: #6b7280 !important;
+ font-style: italic !important;
+ border-radius: 0 0.375rem 0.375rem 0 !important;
+}
+
+div.martor-preview blockquote p {
+ margin: 0.5rem 0 !important;
}
div.martor-preview blockquote> :first-child {
- @apply mt-0;
+ margin-top: 0 !important;
}
div.martor-preview blockquote> :last-child {
- @apply mb-0;
+ margin-bottom: 0 !important;
}
/* Tables */
diff --git a/martor/static/martor/css/martor.tailwind.min.css b/martor/static/martor/css/martor.tailwind.min.css
index 7130362a..56b88c81 100644
--- a/martor/static/martor/css/martor.tailwind.min.css
+++ b/martor/static/martor/css/martor.tailwind.min.css
@@ -6,4 +6,4 @@
* Repository : https://github.com/agusmakmun/django-markdown-editor
* CSS Minifier : https://www.minifier.org
**/
-body.overflow{overflow:hidden!important}.martor{height:500px;max-height:500px}.martor-field{width:100%;height:16rem;min-height:100px;resize:vertical;border-right:1px solid #d1d5db;border-bottom:1px solid #d1d5db}.main-martor{margin-top:1rem;margin-bottom:1rem;position:relative}.main-martor .modal-header{padding:.5rem 1rem}.main-martor .modal-header h5{font-size:1rem;line-height:1.5rem}.main-martor .upload-progress{position:absolute;z-index:100;width:100%;height:100%;padding-top:5rem;background-color:rgb(0 0 0 / .85);color:#fff;text-align:center}.martor-toolbar{z-index:100}.enable-living .martor-toolbar{position:relative}.martor-toolbar .markdown-image-upload{position:relative;overflow:hidden}.martor-toolbar .markdown-image-upload input[type=file]{position:absolute;top:0;right:0;width:100%;height:100%;font-size:1.5rem;padding:0;padding-left:2.25rem;text-align:right;opacity:0;outline:none;cursor:pointer;display:block;min-width:100%;min-height:100%;filter:alpha(opacity=0)}.emoji-loader-init{min-height:200px!important;@apply pt-16}.emoji-content-body{@apply text-xs}.insert-emoji{@apply cursor-pointer no-underline}.table.markdown-reference{@apply text-xs}.table.markdown-reference h1{@apply text-2xl}.table.markdown-reference h2{@apply text-xl}.table.markdown-reference ul,.table.markdown-reference ol{@apply pl-4}div.martor-preview{@apply p-4 overflow-auto bg-gray-50}div.martor-preview-stale{background:repeating-linear-gradient(-45deg,#fff,#fff 10px,#f8f8f8 10px,#f8f8f8 20px)!important}.main-martor .nav-tabs{@apply border-b-2 border-gray-200}.main-martor .nav-tabs .nav-link:hover,.main-martor .nav-tabs .nav-link:focus{@apply border-transparent}.main-martor .nav-tabs .nav-item.show .nav-link,.main-martor .nav-tabs .nav-link.active,.main-martor .nav-tabs .nav-link.active:hover{@apply border-transparent border-b-2 border-gray-800 text-gray-700}.main-martor .tab-pane{@apply relative}.icon.expand-editor{@apply absolute -bottom-2 right-2 z-[100]}.no-border{@apply border-0}div.enable-living .martor-preview{@apply block opacity-100 mt-4 border border-gray-200 rounded-md}div.enable-living .tab-martor-menu a.nav-link{@apply hidden}.section-martor ::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgb(0 0 0 / .3);@apply rounded-lg bg-gray-100}.section-martor ::-webkit-scrollbar{@apply h-1.5 w-1.5 bg-gray-100}.section-martor ::-webkit-scrollbar-thumb{@apply rounded-lg bg-gray-600;-webkit-box-shadow:inset 0 0 6px rgb(0 0 0 / .3)}.ace_scrollbar-v{cursor:ns-resize}.main-martor-fullscreen{@apply bg-white fixed z-[9999] max-h-full h-full w-full m-0 left-0 top-0}.main-martor-fullscreen .fields.martor-toolbar{@apply border-b border-gray-300 m-0}.main-martor-fullscreen .section-martor{@apply h-[90%] relative}.main-martor-fullscreen .martor-field,.main-martor-fullscreen div.martor-preview{min-height:95vh}.marked-emoji,div.martor-preview .marked-emoji{@apply max-w-5}div.martor-preview{@apply text-sm leading-relaxed}div.martor-preview>*:first-child{@apply mt-0}div.martor-preview>*:last-child{@apply mb-5}div.martor-preview a.absent{@apply text-red-600}div.martor-preview a.anchor{@apply block pl-8 -ml-8 cursor-pointer absolute top-0 left-0 bottom-0}div.martor-preview h1,div.martor-preview h2,div.martor-preview h3,div.martor-preview h4,div.martor-preview h5,div.martor-preview h6{@apply my-5 mb-2 p-0 font-bold cursor-text relative;-webkit-font-smoothing:antialiased;background:none}div.martor-preview h1:hover a.anchor,div.martor-preview h2:hover a.anchor,div.martor-preview h3:hover a.anchor,div.martor-preview h4:hover a.anchor,div.martor-preview h5:hover a.anchor,div.martor-preview h6:hover a.anchor{@apply no-underline leading-none pl-0 -ml-6;top:15%}div.martor-preview h1{@apply text-3xl text-black}div.martor-preview h2{@apply text-2xl text-black}div.martor-preview h3{@apply text-lg}div.martor-preview h4{@apply text-base}div.martor-preview h5{@apply text-sm}div.martor-preview h6{@apply text-gray-500 text-sm}div.martor-preview p,div.martor-preview blockquote,div.martor-preview ul,div.martor-preview ol,div.martor-preview dl,div.martor-preview table,div.martor-preview pre{@apply my-4}div.martor-preview hr{background:#fff0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxBEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;@apply border-0 text-gray-300 h-1 p-0}div.martor-preview>h2:first-child,div.martor-preview>h1:first-child,div.martor-preview>h1:first-child+h2,div.martor-preview>h3:first-child,div.martor-preview>h4:first-child,div.martor-preview>h5:first-child,div.martor-preview>h6:first-child{@apply mt-0 pt-0}div.martor-preview a:first-child h1,div.martor-preview a:first-child h2,div.martor-preview a:first-child h3,div.martor-preview a:first-child h4,div.martor-preview a:first-child h5,div.martor-preview a:first-child h6{@apply mt-0 pt-0}div.martor-preview h1+p,div.martor-preview h2+p,div.martor-preview h3+p,div.martor-preview h4+p,div.martor-preview h5+p,div.martor-preview h6+p{@apply mt-0}div.martor-preview li p.first{@apply inline-block}div.martor-preview ul li{@apply list-disc}div.martor-preview ul,div.martor-preview ol{@apply pl-8}div.martor-preview ul.no-list,div.martor-preview ol.no-list{@apply list-none p-0}div.martor-preview ul li>:first-child,div.martor-preview ul li ul:first-of-type,div.martor-preview ol li>:first-child,div.martor-preview ol li ul:first-of-type{@apply mt-0}div.martor-preview ul ul,div.martor-preview ul ol,div.martor-preview ol ol,div.martor-preview ol ul{@apply mb-0}div.martor-preview dl{@apply p-0}div.martor-preview dl dt{@apply text-sm font-bold italic p-0 my-4 mt-0}div.martor-preview dl dt:first-child{@apply p-0}div.martor-preview dl dt>:first-child{@apply mt-0}div.martor-preview dl dt>:last-child{@apply mb-0}div.martor-preview dl dd{@apply m-0 mb-4 pl-4}div.martor-preview dl dd>:first-child{@apply mt-0}div.martor-preview dl dd>:last-child{@apply mb-0}div.martor-preview blockquote{@apply border-l-4 border-gray-300 py-1 px-4 text-gray-500 bg-white}div.martor-preview blockquote>:first-child{@apply mt-0}div.martor-preview blockquote>:last-child{@apply mb-0}div.martor-preview table th{@apply font-bold}div.martor-preview table th,div.martor-preview table td{@apply border border-gray-300 py-1.5 px-3}div.martor-preview table tr{@apply border-t border-gray-300 bg-white}div.martor-preview table tr:nth-child(2n){@apply bg-gray-50}div.martor-preview img,div.martor-preview p img{@apply max-w-full;-moz-box-sizing:border-box;box-sizing:border-box}div.martor-preview span.frame{@apply block overflow-hidden}div.martor-preview span.frame>span{@apply border border-gray-300 block float-left overflow-hidden my-3 mt-0 p-2 w-auto}div.martor-preview span.frame span img{@apply block float-left}div.martor-preview span.frame span span{@apply clear-both text-gray-800 block pt-1 pb-0}div.martor-preview span.align-center{@apply block overflow-hidden clear-both}div.martor-preview span.align-center>span{@apply block overflow-hidden my-3 mt-0 mx-auto text-center}div.martor-preview span.align-center span img{@apply mx-auto text-center}div.martor-preview span.align-right{@apply block overflow-hidden clear-both}div.martor-preview span.align-right>span{@apply block overflow-hidden my-3 mt-0 text-right}div.martor-preview span.align-right span img{@apply m-0 text-right}div.martor-preview span.float-left{@apply block mr-3 overflow-hidden float-left}div.martor-preview span.float-left span{@apply my-3 mt-0}div.martor-preview span.float-right{@apply block ml-3 overflow-hidden float-right}div.martor-preview span.float-right>span{@apply block overflow-hidden my-3 mt-0 mx-auto text-right}div.martor-preview code,div.martor-preview tt{@apply mx-0.5 py-0 px-1 border border-gray-200 bg-gray-100 rounded}div.martor-preview code{@apply whitespace-nowrap}div.martor-preview pre>code{@apply m-0 p-0 whitespace-pre border-0 bg-transparent}div.martor-preview .highlight pre,div.martor-preview pre{@apply border border-gray-200 p-4 overflow-auto text-sm leading-normal bg-gray-50 rounded}div.martor-preview pre code,div.martor-preview pre tt{@apply m-0 p-0 bg-transparent border-0}.form-field input[type="text"],.form-field textarea,form input[type="text"]:not(.martor input),form textarea:not(.martor textarea){@apply w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm;@apply focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500;@apply transition-colors duration-200}.has-error input,.has-error textarea{@apply border-red-300 focus:ring-red-500 focus:border-red-500}input:disabled,textarea:disabled{@apply bg-gray-50 text-gray-500 cursor-not-allowed}.main-martor{border:1px solid #d1d5db;border-radius:.375rem;overflow:hidden}.main-martor .tab-martor-menu{background-color:#f9fafb;border-bottom:1px solid #e5e7eb}.main-martor .martor-field{height:16rem!important;min-height:16rem!important}.main-martor .ace_editor{height:100%!important;min-height:16rem!important}
+body.overflow{overflow:hidden!important}.martor{height:500px;max-height:500px}.martor-field{width:100%;height:16rem;min-height:100px;resize:vertical;border-right:1px solid #d1d5db;border-bottom:1px solid #d1d5db}.main-martor{margin-top:1rem;margin-bottom:1rem;position:relative}.main-martor .modal-header{padding:.5rem 1rem}.main-martor .modal-header h5{font-size:1rem;line-height:1.5rem}.modal-help-guide{z-index:99999!important}.modal-help-guide.flex{display:flex!important;position:fixed!important;top:0!important;left:0!important;width:100vw!important;height:100vh!important;opacity:1!important;visibility:visible!important}.modal-help-guide .bg-white{display:block!important;background-color:white!important;border-radius:12px!important;box-shadow:0 25px 50px -12px rgb(0 0 0 / .25)!important;max-width:900px!important;width:95%!important;max-height:90vh!important;margin:0 auto!important;z-index:20!important;visibility:visible!important;opacity:1!important;position:relative!important;overflow:hidden!important}.modal-help-guide .flex.items-center{display:flex!important;align-items:center!important;justify-content:center!important;text-align:center!important;width:100%!important;height:100%!important}.modal-help-guide table{border-collapse:separate!important;border-spacing:0!important;width:100%!important;font-size:14px!important;line-height:1.5!important}.modal-help-guide th{background-color:#f8fafc!important;font-weight:600!important;text-transform:uppercase!important;letter-spacing:0.05em!important;font-size:12px!important;color:#64748b!important;padding:12px 16px!important;border-bottom:2px solid #e2e8f0!important;text-align:left!important}.modal-help-guide td{padding:16px!important;border-bottom:1px solid #f1f5f9!important;vertical-align:top!important}.modal-help-guide tr:hover td{background-color:#f8fafc!important}.modal-help-guide code{background-color:#f1f5f9!important;color:#475569!important;padding:6px 10px!important;border-radius:6px!important;font-family:'SF Mono','Monaco','Inconsolata','Roboto Mono','Source Code Pro',monospace!important;font-size:13px!important;font-weight:500!important;border:1px solid #e2e8f0!important;white-space:nowrap!important}.modal-help-guide kbd{background-color:#334155!important;color:white!important;padding:4px 8px!important;border-radius:4px!important;font-family:-apple-system,BlinkMacSystemFont,sans-serif!important;font-size:11px!important;font-weight:600!important;box-shadow:0 2px 4px rgb(0 0 0 / .1)!important;border:1px solid #1e293b!important}.modal-help-guide h1,.modal-help-guide h2{margin:0!important;font-weight:700!important}.modal-help-guide blockquote{margin:0!important;font-style:italic!important;color:#64748b!important}.modal-help-guide ul,.modal-help-guide ol{margin:0!important;padding-left:20px!important}.modal-help-guide pre{margin:0!important;background-color:#f8fafc!important;border:1px solid #e2e8f0!important;border-radius:6px!important;padding:12px!important;font-size:13px!important;overflow-x:auto!important}.modal-help-guide hr{border:none!important;height:2px!important;background-color:#e2e8f0!important;margin:8px 0!important}.main-martor .upload-progress{position:absolute;z-index:100;width:100%;height:100%;padding-top:5rem;background-color:rgb(0 0 0 / .85);color:#fff;text-align:center}.martor-toolbar{z-index:100}.enable-living .martor-toolbar{position:relative}.martor-toolbar .markdown-image-upload{position:relative;overflow:hidden}.martor-toolbar .markdown-image-upload input[type=file]{position:absolute;top:0;right:0;width:100%;height:100%;font-size:1.5rem;padding:0;padding-left:2.25rem;text-align:right;opacity:0;outline:none;cursor:pointer;display:block;min-width:100%;min-height:100%;filter:alpha(opacity=0)}.emoji-loader-init{min-height:200px!important;@apply pt-16}.emoji-content-body{@apply text-xs}.insert-emoji{@apply cursor-pointer no-underline}.table.markdown-reference{@apply text-xs}.table.markdown-reference h1{@apply text-2xl}.table.markdown-reference h2{@apply text-xl}.table.markdown-reference ul,.table.markdown-reference ol{@apply pl-4}div.martor-preview{@apply p-4 overflow-auto bg-gray-50}div.martor-preview-stale{background:repeating-linear-gradient(-45deg,#fff,#fff 10px,#f8f8f8 10px,#f8f8f8 20px)!important}.main-martor .nav-tabs{@apply border-b-2 border-gray-200}.main-martor .nav-tabs .nav-link:hover,.main-martor .nav-tabs .nav-link:focus{@apply border-transparent}.main-martor .nav-tabs .nav-item.show .nav-link,.main-martor .nav-tabs .nav-link.active,.main-martor .nav-tabs .nav-link.active:hover{@apply border-transparent border-b-2 border-gray-800 text-gray-700}.main-martor .tab-pane{@apply relative}.icon.expand-editor{@apply absolute -bottom-2 right-2 z-[100]}.no-border{@apply border-0}div.enable-living .martor-preview{@apply block opacity-100 mt-4 border border-gray-200 rounded-md}div.enable-living .tab-martor-menu a.nav-link{@apply hidden}.section-martor ::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgb(0 0 0 / .3);@apply rounded-lg bg-gray-100}.section-martor ::-webkit-scrollbar{@apply h-1.5 w-1.5 bg-gray-100}.section-martor ::-webkit-scrollbar-thumb{@apply rounded-lg bg-gray-600;-webkit-box-shadow:inset 0 0 6px rgb(0 0 0 / .3)}.ace_scrollbar-v{cursor:ns-resize}.main-martor-fullscreen{@apply bg-white fixed z-[9999] max-h-full h-full w-full m-0 left-0 top-0}.main-martor-fullscreen .fields.martor-toolbar{@apply border-b border-gray-300 m-0}.main-martor-fullscreen .section-martor{@apply h-[90%] relative}.main-martor-fullscreen .martor-field,.main-martor-fullscreen div.martor-preview{min-height:95vh}.marked-emoji,div.martor-preview .marked-emoji{@apply max-w-5}div.martor-preview{@apply text-sm leading-relaxed}div.martor-preview>*:first-child{@apply mt-0}div.martor-preview>*:last-child{@apply mb-5}div.martor-preview a.absent{@apply text-red-600}div.martor-preview a.anchor{@apply block pl-8 -ml-8 cursor-pointer absolute top-0 left-0 bottom-0}div.martor-preview h1,div.martor-preview h2,div.martor-preview h3,div.martor-preview h4,div.martor-preview h5,div.martor-preview h6{@apply my-5 mb-2 p-0 font-bold cursor-text relative;-webkit-font-smoothing:antialiased;background:none}div.martor-preview h1:hover a.anchor,div.martor-preview h2:hover a.anchor,div.martor-preview h3:hover a.anchor,div.martor-preview h4:hover a.anchor,div.martor-preview h5:hover a.anchor,div.martor-preview h6:hover a.anchor{@apply no-underline leading-none pl-0 -ml-6;top:15%}div.martor-preview h1{@apply text-3xl text-black}div.martor-preview h2{@apply text-2xl text-black}div.martor-preview h3{@apply text-lg}div.martor-preview h4{@apply text-base}div.martor-preview h5{@apply text-sm}div.martor-preview h6{@apply text-gray-500 text-sm}div.martor-preview p,div.martor-preview blockquote,div.martor-preview ul,div.martor-preview ol,div.martor-preview dl,div.martor-preview table,div.martor-preview pre{@apply my-4}div.martor-preview hr{background:#fff0 url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAECAYAAACtBE5DAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyJpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBNYWNpbnRvc2giIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6OENDRjNBN0E2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6OENDRjNBN0I2NTZBMTFFMEI3QjRBODM4NzJDMjlGNDgiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4Q0NGM0E3ODY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4Q0NGM0E3OTY1NkExMUUwQjdCNEE4Mzg3MkMyOUY0OCIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PqqezsUAAAAfSURBVHjaYmRABcYwBiM2QSA4y4hNEKYDQxBEAAIMAHNGAzhkPOlYAAAAAElFTkSuQmCC) repeat-x 0 0;@apply border-0 text-gray-300 h-1 p-0;margin:1rem 0}div.martor-preview>h2:first-child,div.martor-preview>h1:first-child,div.martor-preview>h1:first-child+h2,div.martor-preview>h3:first-child,div.martor-preview>h4:first-child,div.martor-preview>h5:first-child,div.martor-preview>h6:first-child{@apply mt-0 pt-0}div.martor-preview a:first-child h1,div.martor-preview a:first-child h2,div.martor-preview a:first-child h3,div.martor-preview a:first-child h4,div.martor-preview a:first-child h5,div.martor-preview a:first-child h6{@apply mt-0 pt-0}div.martor-preview h1+p,div.martor-preview h2+p,div.martor-preview h3+p,div.martor-preview h4+p,div.martor-preview h5+p,div.martor-preview h6+p{@apply mt-0}div.martor-preview li p.first{@apply inline-block}div.martor-preview ul{@apply pl-8;margin:1rem 0;list-style-type:disc!important;list-style-position:inside!important;display:block!important}div.martor-preview ol{@apply pl-8;margin:1rem 0;list-style-type:decimal!important;list-style-position:inside!important;display:block!important}div.martor-preview ul li,div.martor-preview ol li{margin:.25rem 0;padding-left:.5rem;display:list-item!important}div.martor-preview ul.no-list,div.martor-preview ol.no-list{@apply list-none p-0}div.martor-preview ul li>:first-child,div.martor-preview ul li ul:first-of-type,div.martor-preview ol li>:first-child,div.martor-preview ol li ul:first-of-type{@apply mt-0}div.martor-preview ul ul,div.martor-preview ul ol,div.martor-preview ol ol,div.martor-preview ol ul{@apply mb-0;margin-top:.5rem}div.martor-preview li>ul,div.martor-preview li>ol{@apply pl-4;margin:.25rem 0}div.martor-preview dl{@apply p-0}div.martor-preview dl dt{@apply text-sm font-bold italic p-0 my-4 mt-0}div.martor-preview dl dt:first-child{@apply p-0}div.martor-preview dl dt>:first-child{@apply mt-0}div.martor-preview dl dt>:last-child{@apply mb-0}div.martor-preview dl dd{@apply m-0 mb-4 pl-4}div.martor-preview dl dd>:first-child{@apply mt-0}div.martor-preview dl dd>:last-child{@apply mb-0}div.martor-preview blockquote{border-left:4px solid #d1d5db!important;padding:.25rem 1rem!important;margin:1rem 0!important;background-color:#f9fafb!important;color:#6b7280!important;font-style:italic!important;border-radius:0 .375rem .375rem 0!important}div.martor-preview blockquote p{margin:.5rem 0!important}div.martor-preview blockquote>:first-child{margin-top:0!important}div.martor-preview blockquote>:last-child{margin-bottom:0!important}div.martor-preview table th{@apply font-bold}div.martor-preview table th,div.martor-preview table td{@apply border border-gray-300 py-1.5 px-3}div.martor-preview table tr{@apply border-t border-gray-300 bg-white}div.martor-preview table tr:nth-child(2n){@apply bg-gray-50}div.martor-preview img,div.martor-preview p img{@apply max-w-full;-moz-box-sizing:border-box;box-sizing:border-box}div.martor-preview span.frame{@apply block overflow-hidden}div.martor-preview span.frame>span{@apply border border-gray-300 block float-left overflow-hidden my-3 mt-0 p-2 w-auto}div.martor-preview span.frame span img{@apply block float-left}div.martor-preview span.frame span span{@apply clear-both text-gray-800 block pt-1 pb-0}div.martor-preview span.align-center{@apply block overflow-hidden clear-both}div.martor-preview span.align-center>span{@apply block overflow-hidden my-3 mt-0 mx-auto text-center}div.martor-preview span.align-center span img{@apply mx-auto text-center}div.martor-preview span.align-right{@apply block overflow-hidden clear-both}div.martor-preview span.align-right>span{@apply block overflow-hidden my-3 mt-0 text-right}div.martor-preview span.align-right span img{@apply m-0 text-right}div.martor-preview span.float-left{@apply block mr-3 overflow-hidden float-left}div.martor-preview span.float-left span{@apply my-3 mt-0}div.martor-preview span.float-right{@apply block ml-3 overflow-hidden float-right}div.martor-preview span.float-right>span{@apply block overflow-hidden my-3 mt-0 mx-auto text-right}div.martor-preview code,div.martor-preview tt{@apply mx-0.5 py-0 px-1 border border-gray-200 bg-gray-100 rounded}div.martor-preview code{@apply whitespace-nowrap}div.martor-preview pre>code{@apply m-0 p-0 whitespace-pre border-0 bg-transparent}div.martor-preview .highlight pre,div.martor-preview pre{@apply border border-gray-200 p-4 overflow-auto text-sm leading-normal bg-gray-50 rounded}div.martor-preview pre code,div.martor-preview pre tt{@apply m-0 p-0 bg-transparent border-0}.form-field input[type="text"],.form-field textarea,form input[type="text"]:not(.martor input),form textarea:not(.martor textarea){@apply w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm;@apply focus:outline-none focus:ring-1 focus:ring-blue-500 focus:border-blue-500;@apply transition-colors duration-200}.has-error input,.has-error textarea{@apply border-red-300 focus:ring-red-500 focus:border-red-500}input:disabled,textarea:disabled{@apply bg-gray-50 text-gray-500 cursor-not-allowed}.main-martor{border:1px solid #d1d5db;border-radius:.375rem;overflow:hidden}.main-martor .tab-martor-menu{background-color:#f9fafb;border-bottom:1px solid #e5e7eb}.main-martor .martor-field{height:16rem!important;min-height:16rem!important}.main-martor .ace_editor{height:100%!important;min-height:16rem!important}
diff --git a/martor/static/martor/js/martor.tailwind.js b/martor/static/martor/js/martor.tailwind.js
index fb55c485..f1a4c5e7 100644
--- a/martor/static/martor/js/martor.tailwind.js
+++ b/martor/static/martor/js/martor.tailwind.js
@@ -41,11 +41,76 @@
$(element).removeClass('block').addClass('hidden');
},
showModal: function(element) {
- $(element).removeClass('hidden').addClass('flex');
+ console.log('Showing modal:', element);
+ var $modal = $(element);
+ $modal.removeClass('hidden').addClass('flex');
+ $modal.css({
+ 'display': 'flex !important',
+ 'z-index': '99999',
+ 'position': 'fixed',
+ 'top': '0',
+ 'left': '0',
+ 'width': '100vw',
+ 'height': '100vh',
+ 'opacity': '1',
+ 'visibility': 'visible'
+ });
$('body').addClass('overflow-hidden');
+ console.log('Modal styles applied:', $modal.css(['display', 'z-index', 'position']));
+ console.log('Modal visibility:', $modal.is(':visible'));
+ console.log('Modal dimensions:', {
+ width: $modal.outerWidth(),
+ height: $modal.outerHeight(),
+ offset: $modal.offset()
+ });
+ // Also ensure the modal content is visible
+ $modal.find('.bg-white').css({
+ 'display': 'block',
+ 'position': 'relative',
+ 'z-index': '10'
+ });
+
+ // Force the modal container to be visible
+ $modal.show().fadeIn();
+
+ // Ensure modal content panel is visible
+ var modalPanel = $modal.find('.bg-white').first();
+ var modalContainer = $modal.find('.flex.items-center');
+
+ modalContainer.css({
+ 'display': 'flex !important',
+ 'align-items': 'center',
+ 'justify-content': 'center',
+ 'width': '100%',
+ 'height': '100%',
+ 'text-align': 'center'
+ });
+
+ modalPanel.css({
+ 'display': 'block !important',
+ 'visibility': 'visible',
+ 'opacity': '1',
+ 'background-color': 'white',
+ 'max-width': '800px',
+ 'width': '90%',
+ 'z-index': '20',
+ 'margin': '0',
+ 'border-radius': '8px',
+ 'box-shadow': '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
+ 'transform': 'none',
+ 'position': 'relative'
+ });
+
+ console.log('Modal panel found:', modalPanel.length);
+ console.log('Modal container found:', modalContainer.length);
+ console.log('Modal panel styles:', modalPanel.css(['display', 'visibility', 'background-color']));
+
+ // Force all content to be visible
+ $modal.find('*').css('visibility', 'visible');
},
hideModal: function(element) {
- $(element).removeClass('flex').addClass('hidden');
+ console.log('Hiding modal:', element);
+ $(element).removeClass('flex').addClass('hidden').css('display', 'none');
$('body').removeClass('overflow-hidden');
},
toggleTab: function(activeTab, activeContent, inactiveTabs, inactiveContents) {
@@ -271,8 +336,6 @@
}
}
-
-
if (editorConfig.emoji == 'true') {
langTools = ace.require("ace/ext/language_tools");
langTools.addCompleter(emojiWordCompleter);
@@ -283,8 +346,6 @@
langTools.addCompleter(mentionWordCompleter);
}
-
-
// Handle toolbar dropdowns for Tailwind
$('.martor-toolbar .dropdown').each(function() {
var dropdown = $(this);
@@ -311,15 +372,29 @@
});
// Modal Popup for Help Guide & Emoji Cheat Sheet
- $('.markdown-help[data-field-name=' + field_name + ']').click(function () {
- TailwindUtils.showModal('.modal-help-guide[data-field-name=' + field_name + ']');
+ $('.markdown-help[data-field-name=' + field_name + ']').click(function (e) {
+ e.preventDefault();
+ console.log('Help button clicked for field:', field_name);
+ var modalSelector = '.modal-help-guide[data-field-name=' + field_name + ']';
+ console.log('Modal selector:', modalSelector);
+ var modal = $(modalSelector);
+ console.log('Modal found:', modal.length);
+ TailwindUtils.showModal(modalSelector);
});
// Close modal functionality
- $('.modal-help-guide[data-field-name=' + field_name + '] .modal-close').click(function () {
+ $('.modal-help-guide[data-field-name=' + field_name + '] .modal-close').click(function (e) {
+ e.preventDefault();
TailwindUtils.hideModal('.modal-help-guide[data-field-name=' + field_name + ']');
});
+ // Also handle click on modal backdrop to close
+ $('.modal-help-guide[data-field-name=' + field_name + ']').click(function (e) {
+ if (e.target === this || $(e.target).hasClass('bg-gray-500')) {
+ TailwindUtils.hideModal('.modal-help-guide[data-field-name=' + field_name + ']');
+ }
+ });
+
// Toggle editor, preview, maximize
var martorField = $('.martor-field-' + field_name);
var btnToggleMaximize = $('.markdown-toggle-maximize[data-field-name=' + field_name + ']');
@@ -367,28 +442,52 @@
var modalEmoji = $('.modal-emoji[data-field-name=' + field_name + ']');
TailwindUtils.showModal(modalEmoji);
var emojiList = typeof (emojis) != "undefined" ? emojis : []; // from `plugins/js/emojis.min.js`
- var segmentEmoji = modalEmoji.find('.emoji-content-body');
+ var emojiGrid = modalEmoji.find('#emoji-grid-' + field_name);
var loaderInit = modalEmoji.find('.emoji-loader-init');
- // setup initial loader
- segmentEmoji.html('');
- TailwindUtils.showElement(loaderInit);
-
- for (var i = 0; i < emojiList.length; i++) {
- var linkEmoji = textareaId.data('base-emoji-url') + emojiList[i].replace(/:/g, '') + '.png';
- segmentEmoji.append(''
- + '');
- $('a[data-emoji-target="' + emojiList[i] + '"]').click(function () {
- markdownToEmoji(editor, $(this).data('emoji-target'));
- TailwindUtils.hideModal(modalEmoji);
- });
- }
+ // Only load emojis if grid is empty
+ if (emojiGrid.children().length === 0) {
+ // Show loader
+ TailwindUtils.showElement(loaderInit);
+
+ // Load emojis with timeout to show loading state
+ setTimeout(function() {
+ try {
+ console.log('Loading emojis, count:', emojiList.length);
+
+ for (var i = 0; i < Math.min(emojiList.length, 300); i++) { // Increased to 300 for more emojis
+ var emoji = emojiList[i];
+ var linkEmoji = textareaId.data('base-emoji-url') + emoji.replace(/:/g, '') + '.png';
+
+ var emojiButton = $('' +
+ ' ' +
+ '' + emoji + ' ' +
+ ' ');
+
+ emojiGrid.append(emojiButton);
+ }
+
+ // Attach click handlers to dynamically created buttons
+ modalEmoji.find('.insert-emoji').off('click').on('click', function() {
+ var emojiTarget = $(this).data('emoji-target');
+ console.log('Emoji selected:', emojiTarget);
+ markdownToEmoji(editor, emojiTarget);
+ TailwindUtils.hideModal(modalEmoji);
+ });
- TailwindUtils.hideElement(loaderInit);
- TailwindUtils.showElement(segmentEmoji);
+ TailwindUtils.hideElement(loaderInit);
+ console.log('Emojis loaded successfully');
+ } catch (error) {
+ console.error('Error loading emojis:', error);
+ TailwindUtils.hideElement(loaderInit);
+ emojiGrid.html('Error loading emojis. Please try again.
');
+ }
+ }, 100); // Small delay to show loading state
+ } else {
+ console.log('Emojis already loaded');
+ }
});
// Close emoji modal
@@ -396,11 +495,16 @@
TailwindUtils.hideModal('.modal-emoji[data-field-name=' + field_name + ']');
});
+ // Handle popular emoji buttons
+ $('.modal-emoji[data-field-name=' + field_name + '] .insert-emoji-popular').click(function () {
+ var emojiTarget = $(this).data('emoji-target');
+ markdownToEmoji(editor, emojiTarget);
+ TailwindUtils.hideModal('.modal-emoji[data-field-name=' + field_name + ']');
+ });
+
// Set initial value if has the content before.
editor.setValue(textareaId.val(), -1);
-
-
// win/linux: Ctrl+B, mac: Command+B
var markdownToBold = function (editor) {
var originalRange = editor.getSelectionRange();
diff --git a/martor/static/martor/js/martor.tailwind.min.js b/martor/static/martor/js/martor.tailwind.min.js
index 4ab28191..85cc1516 100644
--- a/martor/static/martor/js/martor.tailwind.min.js
+++ b/martor/static/martor/js/martor.tailwind.min.js
@@ -6,4 +6,4 @@
* Repository : https://github.com/agusmakmun/django-markdown-editor
* JS Minifier : https://jscompress.com
**/
-!function(L){(L=L||django.jQuery).fn.martor=function(){L(".martor").trigger("martor.init");function A(e){var n=null,o=0;if(document.cookie&&""!==document.cookie)for(var t=document.cookie.split(";");oNothing to preview')},error:function(e){console.log("error",e)}})};let g;if(window.onload=function(){u()},"true"!==a.living?n.click(function(){m.hide(),u()}):c.on("change",function(){g&&clearTimeout(g),g=setTimeout(u,r.data("save-timeout"))}),"true"==a.spellcheck)try{enable_spellcheck(t)}catch(e){console.log("Spellcheck lib doesn't installed.")}"true"==a.emoji&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(i)),"true"==a.mention&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(l)),L(".martor-toolbar .dropdown").each(function(){var n=L(this),e=n.find(".dropdown-toggle"),o=n.find(".dropdown-menu");e.click(function(e){e.preventDefault(),e.stopPropagation(),L(".martor-toolbar .dropdown-menu").not(o).addClass("hidden"),o.toggleClass("hidden")}),L(document).click(function(e){n.is(e.target)||0!==n.has(e.target).length||o.addClass("hidden")})}),L(".markdown-help[data-field-name="+s+"]").click(function(){I(".modal-help-guide[data-field-name="+s+"]")}),L(".modal-help-guide[data-field-name="+s+"] .modal-close").click(function(){U(".modal-help-guide[data-field-name="+s+"]")});function f(){L(document.body).removeClass("overflow-hidden"),L(this).attr({title:"Full Screen"}),L(this).find("svg.bi-arrows-angle-expand").removeClass("hidden"),L(this).find("svg.bi-arrows-angle-contract").addClass("hidden"),L(".main-martor-fullscreen").find(".martor-preview").removeAttr("style"),o.removeClass("main-martor-fullscreen"),p.removeAttr("style"),c.resize()}var p=L(".martor-field-"+s),v=L(".markdown-toggle-maximize[data-field-name="+s+"]");v.on("click",function(){!function(e){e.attr({title:"Minimize"}),e.find("svg.bi-arrows-angle-expand").addClass("hidden"),e.find("svg.bi-arrows-angle-contract").removeClass("hidden"),o.addClass("main-martor-fullscreen");var n=document.body.clientHeight-90;p.attr({style:"height:"+n+"px"}),L(".main-martor-fullscreen").find(".martor-preview").attr({style:"overflow-y: auto;height:"+n+"px"}),c.resize(),e.one("click",f),L(document.body).addClass("overflow-hidden")}(L(this))}),L(document).keyup(function(e){27==e.keyCode&&o.hasClass("main-martor-fullscreen")&&v.trigger("click")}),L(".markdown-emoji[data-field-name="+s+"]").click(function(){var e=L(".modal-emoji[data-field-name="+s+"]");I(e);var n="undefined"!=typeof emojis?emojis:[],o=e.find(".emoji-content-body"),t=e.find(".emoji-loader-init");o.html(""),_(t);for(var a=0;a '+n[a]+" "),L('a[data-emoji-target="'+n[a]+'"]').click(function(){K(c,L(this).data("emoji-target")),U(e)})}M(t),_(o)}),L(".modal-emoji[data-field-name="+s+"] .modal-close").click(function(){U(".modal-emoji[data-field-name="+s+"]")}),c.setValue(r.val(),-1);function w(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," **** "),e.focus(),e.selection.moveTo(o.row,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"**"+o+"**"),t.end.column+=4,e.focus(),e.selection.setSelectionRange(t))}function C(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," __ "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"_"+o+"_"),t.end.column+=2,e.focus(),e.selection.setSelectionRange(t))}function h(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n----------\n\n"),e.focus(),e.selection.moveTo(o.row+4,o.column+10)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n----------\n\n"+o),e.focus(),e.selection.moveTo(t.end.row+4,t.end.column+10))}function k(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n# "),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n# "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function y(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n## "),e.focus(),e.selection.moveTo(o.row+2,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n## "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+3))}function T(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n### "),e.focus(),e.selection.moveTo(o.row+2,o.column+4)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n### "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+4))}function b(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n```\n\n```\n"),e.focus(),e.selection.moveTo(o.row+3,o.column)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n```\n"+o+"\n```\n"),e.focus(),e.selection.moveTo(t.end.row+3,t.end.column+3))}function S(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," `` "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"`"+o+"`"),t.end.column+=2,e.focus(),e.selection.setSelectionRange(t))}function R(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n> \n"),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n> "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function x(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n* "),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n* "+o),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function j(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n1. "),e.focus(),e.selection.moveTo(o.row+2,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n1. "+o),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+3))}function O(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," [](https://) "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"["+o+"](https://) "),e.focus(),e.selection.moveTo(t.end.row,t.end.column+11))}function P(e,n){var o,t,a,i=e.getSelectionRange();void 0===n?e.selection.isEmpty()?(a=e.getCursorPosition(),e.session.insert(a,"  "),e.focus(),e.selection.moveTo(a.row,a.column+3)):(o=e.getSelectionRange(),t=e.session.getTextRange(o),e.session.replace(o," "),e.focus(),e.selection.moveTo(i.end.row,i.end.column+12)):(a=e.getCursorPosition(),e.session.insert(a," "),e.focus(),e.selection.moveTo(a.row,a.column+n.name.length+2))}function E(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," @[]"),e.focus(),e.selection.moveTo(o.row,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"@["+o+"]"),e.focus(),e.selection.moveTo(t.end.row,t.end.column+3))}var K=function(e,n){var o=e.getCursorPosition();e.session.insert(o," "+n+" "),e.focus(),e.selection.moveTo(o.row,o.column+n.length+2)};L(".markdown-bold[data-field-name="+s+"]").click(function(){w(c)}),L(".markdown-italic[data-field-name="+s+"]").click(function(){C(c)}),L(".markdown-horizontal[data-field-name="+s+"]").click(function(){h(c)}),L(".markdown-h1[data-field-name="+s+"]").click(function(){k(c)}),L(".markdown-h2[data-field-name="+s+"]").click(function(){y(c)}),L(".markdown-h3[data-field-name="+s+"]").click(function(){T(c)}),L(".markdown-pre[data-field-name="+s+"]").click(function(){b(c)}),L(".markdown-code[data-field-name="+s+"]").click(function(){S(c)}),L(".markdown-blockquote[data-field-name="+s+"]").click(function(){R(c)}),L(".markdown-unordered-list[data-field-name="+s+"]").click(function(){x(c)}),L(".markdown-ordered-list[data-field-name="+s+"]").click(function(){j(c)}),L(".markdown-link[data-field-name="+s+"]").click(function(){O(c)}),L(".markdown-image-link[data-field-name="+s+"]").click(function(){P(c)});i=L(".markdown-direct-mention[data-field-name="+s+"]"),l=L(".markdown-image-upload[data-field-name="+s+"]");"true"==a.mention?i.click(function(){E(c)}):(i.remove(),L(".markdown-reference tbody tr")[1].remove()),"true"==a.imgur?l.on("change",function(e){var n,o;e.preventDefault(),n=c,e=L("#"+t).closest("form").get(0),o=n.container.id.replace("martor-",""),(e=new FormData(e)).append("csrfmiddlewaretoken",A("csrftoken")),L.ajax({url:r.data("upload-url"),type:"POST",data:e,async:!0,cache:!1,contentType:!1,enctype:"multipart/form-data",processData:!1,beforeSend:function(){console.log("Uploading..."),L(".upload-progress[data-field-name="+o+"]").show()},success:function(e){L(".upload-progress[data-field-name="+o+"]").hide(),200==e.status?(console.log(e),P(n,imageData={name:e.name,link:e.link})):alert(e.error)},error:function(e){console.log("error",e),L(".upload-progress[data-field-name="+o+"]").hide()}})}):l.remove(),c.commands.addCommand({name:"markdownToBold",bindKey:{win:"Ctrl-B",mac:"Command-B"},exec:function(e){w(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToItalic",bindKey:{win:"Ctrl-I",mac:"Command-I"},exec:function(e){C(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToUnderscores",bindKey:{win:"Ctrl-Shift-U",mac:"Command-Shift-U"},exec:function(e){var n,o,t;t=(n=e).getSelectionRange(),n.selection.isEmpty()?(o=n.getCursorPosition(),n.session.insert(o," ++++ "),n.focus(),n.selection.moveTo(o.row,o.column+3)):(e=n.getSelectionRange(),o=n.session.getTextRange(e),n.session.replace(e,"++"+o+"++"),t.end.column+=4,n.focus(),n.selection.setSelectionRange(t))},readOnly:!0}),c.commands.addCommand({name:"markdownToStrikethrough",bindKey:{win:"Ctrl-Shift-S",mac:"Command-Shift-S"},exec:function(e){var n,o,t;t=(n=e).getSelectionRange(),n.selection.isEmpty()?(o=n.getCursorPosition(),n.session.insert(o," ~~~~ "),n.focus(),n.selection.moveTo(o.row,o.column+3)):(e=n.getSelectionRange(),o=n.session.getTextRange(e),n.session.replace(e,"~~"+o+"~~"),t.end.column+=4,n.focus(),n.selection.setSelectionRange(t))},readOnly:!0}),c.commands.addCommand({name:"markdownToHorizontal",bindKey:{win:"Ctrl-H",mac:"Command-H"},exec:function(e){h(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH1",bindKey:{win:"Ctrl-Alt-1",mac:"Command-Option-1"},exec:function(e){k(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH2",bindKey:{win:"Ctrl-Alt-2",mac:"Command-Option-3"},exec:function(e){y(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH3",bindKey:{win:"Ctrl-Alt-3",mac:"Command-Option-3"},exec:function(e){T(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToPre",bindKey:{win:"Ctrl-Alt-P",mac:"Command-Option-P"},exec:function(e){b(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToCode",bindKey:{win:"Ctrl-Alt-C",mac:"Command-Option-C"},exec:function(e){S(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToBlockQuote",bindKey:{win:"Ctrl-Q",mac:"Command-Shift-K"},exec:function(e){R(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToUnorderedList",bindKey:{win:"Ctrl-U",mac:"Command-U"},exec:function(e){x(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToOrderedList",bindKey:{win:"Ctrl-Shift+O",mac:"Command-Option-O"},exec:function(e){j(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToLink",bindKey:{win:"Ctrl-L",mac:"Command-L"},exec:function(e){O(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToImageLink",bindKey:{win:"Ctrl-Shift-I",mac:"Command-Option-I"},exec:function(e){P(e)},readOnly:!0}),"true"===a.mention&&c.commands.addCommand({name:"markdownToMention",bindKey:{win:"Ctrl-M",mac:"Command-M"},exec:function(e){E(e)},readOnly:!0})})},L(function(){L(".main-martor").martor()}),"django"in window&&"jQuery"in window.django&&django.jQuery(document).on("formset:added",function(e){setTimeout(function(){var n=L(e.target);n.find(".main-martor").each(function(){var e=(e=n.attr("id")).substr(e.lastIndexOf("-")+1),e=L(this.outerHTML.replace(/__prefix__/g,e));L(this).replaceWith(e),e.martor()})},1e3)})}(jQuery);
+!function(D){(D=D||django.jQuery).fn.martor=function(){D(".martor").trigger("martor.init");function K(e){var n=null,o=0;if(document.cookie&&""!==document.cookie)for(var t=document.cookie.split(";");oNothing to preview')},error:function(e){console.log("error",e)}})};let g;if(window.onload=function(){u()},"true"!==a.living?n.click(function(){m.hide(),u()}):c.on("change",function(){g&&clearTimeout(g),g=setTimeout(u,r.data("save-timeout"))}),"true"==a.spellcheck)try{enable_spellcheck(t)}catch(e){console.log("Spellcheck lib doesn't installed.")}"true"==a.emoji&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(i)),"true"==a.mention&&(langTools=ace.require("ace/ext/language_tools"),langTools.addCompleter(s)),D(".martor-toolbar .dropdown").each(function(){var n=D(this),e=n.find(".dropdown-toggle"),o=n.find(".dropdown-menu");e.click(function(e){e.preventDefault(),e.stopPropagation(),D(".martor-toolbar .dropdown-menu").not(o).addClass("hidden"),o.toggleClass("hidden")}),D(document).click(function(e){n.is(e.target)||0!==n.has(e.target).length||o.addClass("hidden")})}),D(".markdown-help[data-field-name="+l+"]").click(function(e){e.preventDefault(),console.log("Help button clicked for field:",l);var n=".modal-help-guide[data-field-name="+l+"]";console.log("Modal selector:",n);e=D(n);console.log("Modal found:",e.length),H(n)}),D(".modal-help-guide[data-field-name="+l+"] .modal-close").click(function(e){e.preventDefault(),z(".modal-help-guide[data-field-name="+l+"]")}),D(".modal-help-guide[data-field-name="+l+"]").click(function(e){e.target!==this&&!D(e.target).hasClass("bg-gray-500")||z(".modal-help-guide[data-field-name="+l+"]")});function f(){D(document.body).removeClass("overflow-hidden"),D(this).attr({title:"Full Screen"}),D(this).find("svg.bi-arrows-angle-expand").removeClass("hidden"),D(this).find("svg.bi-arrows-angle-contract").addClass("hidden"),D(".main-martor-fullscreen").find(".martor-preview").removeAttr("style"),o.removeClass("main-martor-fullscreen"),p.removeAttr("style"),c.resize()}var p=D(".martor-field-"+l),v=D(".markdown-toggle-maximize[data-field-name="+l+"]");v.on("click",function(){!function(e){e.attr({title:"Minimize"}),e.find("svg.bi-arrows-angle-expand").addClass("hidden"),e.find("svg.bi-arrows-angle-contract").removeClass("hidden"),o.addClass("main-martor-fullscreen");var n=document.body.clientHeight-90;p.attr({style:"height:"+n+"px"}),D(".main-martor-fullscreen").find(".martor-preview").attr({style:"overflow-y: auto;height:"+n+"px"}),c.resize(),e.one("click",f),D(document.body).addClass("overflow-hidden")}(D(this))}),D(document).keyup(function(e){27==e.keyCode&&o.hasClass("main-martor-fullscreen")&&v.trigger("click")}),D(".markdown-emoji[data-field-name="+l+"]").click(function(){var t=D(".modal-emoji[data-field-name="+l+"]");H(t);var a="undefined"!=typeof emojis?emojis:[],i=t.find("#emoji-grid-"+l),s=t.find(".emoji-loader-init");0===i.children().length?(A(s),setTimeout(function(){try{console.log("Loading emojis, count:",a.length);for(var e=0;e'+n+" ");i.append(n)}t.find(".insert-emoji").off("click").on("click",function(){var e=D(this).data("emoji-target");console.log("Emoji selected:",e),M(c,e),z(t)}),_(s),console.log("Emojis loaded successfully")}catch(e){console.error("Error loading emojis:",e),_(s),i.html('Error loading emojis. Please try again.
')}},100)):console.log("Emojis already loaded")}),D(".modal-emoji[data-field-name="+l+"] .modal-close").click(function(){z(".modal-emoji[data-field-name="+l+"]")}),D(".modal-emoji[data-field-name="+l+"] .insert-emoji-popular").click(function(){var e=D(this).data("emoji-target");M(c,e),z(".modal-emoji[data-field-name="+l+"]")}),c.setValue(r.val(),-1);function h(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," **** "),e.focus(),e.selection.moveTo(o.row,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"**"+o+"**"),t.end.column+=4,e.focus(),e.selection.setSelectionRange(t))}function w(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," __ "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"_"+o+"_"),t.end.column+=2,e.focus(),e.selection.setSelectionRange(t))}function y(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n----------\n\n"),e.focus(),e.selection.moveTo(o.row+4,o.column+10)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n----------\n\n"+o),e.focus(),e.selection.moveTo(t.end.row+4,t.end.column+10))}function C(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n# "),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n# "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function k(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n## "),e.focus(),e.selection.moveTo(o.row+2,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n## "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+3))}function b(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n### "),e.focus(),e.selection.moveTo(o.row+2,o.column+4)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n### "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+4))}function T(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n```\n\n```\n"),e.focus(),e.selection.moveTo(o.row+3,o.column)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n```\n"+o+"\n```\n"),e.focus(),e.selection.moveTo(t.end.row+3,t.end.column+3))}function x(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," `` "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"`"+o+"`"),t.end.column+=2,e.focus(),e.selection.setSelectionRange(t))}function S(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n> \n"),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n> "+o+"\n"),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function R(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n* "),e.focus(),e.selection.moveTo(o.row+2,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n* "+o),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+2))}function j(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o,"\n\n1. "),e.focus(),e.selection.moveTo(o.row+2,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"\n\n1. "+o),e.focus(),e.selection.moveTo(t.end.row+2,t.end.column+3))}function O(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," [](https://) "),e.focus(),e.selection.moveTo(o.row,o.column+2)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"["+o+"](https://) "),e.focus(),e.selection.moveTo(t.end.row,t.end.column+11))}function P(e,n){var o,t,a,i=e.getSelectionRange();void 0===n?e.selection.isEmpty()?(a=e.getCursorPosition(),e.session.insert(a,"  "),e.focus(),e.selection.moveTo(a.row,a.column+3)):(o=e.getSelectionRange(),t=e.session.getTextRange(o),e.session.replace(o," "),e.focus(),e.selection.moveTo(i.end.row,i.end.column+12)):(a=e.getCursorPosition(),e.session.insert(a," "),e.focus(),e.selection.moveTo(a.row,a.column+n.name.length+2))}function E(e){var n,o,t=e.getSelectionRange();e.selection.isEmpty()?(o=e.getCursorPosition(),e.session.insert(o," @[]"),e.focus(),e.selection.moveTo(o.row,o.column+3)):(n=e.getSelectionRange(),o=e.session.getTextRange(n),e.session.replace(n,"@["+o+"]"),e.focus(),e.selection.moveTo(t.end.row,t.end.column+3))}var M=function(e,n){var o=e.getCursorPosition();e.session.insert(o," "+n+" "),e.focus(),e.selection.moveTo(o.row,o.column+n.length+2)};D(".markdown-bold[data-field-name="+l+"]").click(function(){h(c)}),D(".markdown-italic[data-field-name="+l+"]").click(function(){w(c)}),D(".markdown-horizontal[data-field-name="+l+"]").click(function(){y(c)}),D(".markdown-h1[data-field-name="+l+"]").click(function(){C(c)}),D(".markdown-h2[data-field-name="+l+"]").click(function(){k(c)}),D(".markdown-h3[data-field-name="+l+"]").click(function(){b(c)}),D(".markdown-pre[data-field-name="+l+"]").click(function(){T(c)}),D(".markdown-code[data-field-name="+l+"]").click(function(){x(c)}),D(".markdown-blockquote[data-field-name="+l+"]").click(function(){S(c)}),D(".markdown-unordered-list[data-field-name="+l+"]").click(function(){R(c)}),D(".markdown-ordered-list[data-field-name="+l+"]").click(function(){j(c)}),D(".markdown-link[data-field-name="+l+"]").click(function(){O(c)}),D(".markdown-image-link[data-field-name="+l+"]").click(function(){P(c)});i=D(".markdown-direct-mention[data-field-name="+l+"]"),s=D(".markdown-image-upload[data-field-name="+l+"]");"true"==a.mention?i.click(function(){E(c)}):(i.remove(),D(".markdown-reference tbody tr")[1].remove()),"true"==a.imgur?s.on("change",function(e){var n,o;e.preventDefault(),n=c,e=D("#"+t).closest("form").get(0),o=n.container.id.replace("martor-",""),(e=new FormData(e)).append("csrfmiddlewaretoken",K("csrftoken")),D.ajax({url:r.data("upload-url"),type:"POST",data:e,async:!0,cache:!1,contentType:!1,enctype:"multipart/form-data",processData:!1,beforeSend:function(){console.log("Uploading..."),D(".upload-progress[data-field-name="+o+"]").show()},success:function(e){D(".upload-progress[data-field-name="+o+"]").hide(),200==e.status?(console.log(e),P(n,imageData={name:e.name,link:e.link})):alert(e.error)},error:function(e){console.log("error",e),D(".upload-progress[data-field-name="+o+"]").hide()}})}):s.remove(),c.commands.addCommand({name:"markdownToBold",bindKey:{win:"Ctrl-B",mac:"Command-B"},exec:function(e){h(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToItalic",bindKey:{win:"Ctrl-I",mac:"Command-I"},exec:function(e){w(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToUnderscores",bindKey:{win:"Ctrl-Shift-U",mac:"Command-Shift-U"},exec:function(e){var n,o,t;t=(n=e).getSelectionRange(),n.selection.isEmpty()?(o=n.getCursorPosition(),n.session.insert(o," ++++ "),n.focus(),n.selection.moveTo(o.row,o.column+3)):(e=n.getSelectionRange(),o=n.session.getTextRange(e),n.session.replace(e,"++"+o+"++"),t.end.column+=4,n.focus(),n.selection.setSelectionRange(t))},readOnly:!0}),c.commands.addCommand({name:"markdownToStrikethrough",bindKey:{win:"Ctrl-Shift-S",mac:"Command-Shift-S"},exec:function(e){var n,o,t;t=(n=e).getSelectionRange(),n.selection.isEmpty()?(o=n.getCursorPosition(),n.session.insert(o," ~~~~ "),n.focus(),n.selection.moveTo(o.row,o.column+3)):(e=n.getSelectionRange(),o=n.session.getTextRange(e),n.session.replace(e,"~~"+o+"~~"),t.end.column+=4,n.focus(),n.selection.setSelectionRange(t))},readOnly:!0}),c.commands.addCommand({name:"markdownToHorizontal",bindKey:{win:"Ctrl-H",mac:"Command-H"},exec:function(e){y(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH1",bindKey:{win:"Ctrl-Alt-1",mac:"Command-Option-1"},exec:function(e){C(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH2",bindKey:{win:"Ctrl-Alt-2",mac:"Command-Option-3"},exec:function(e){k(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToH3",bindKey:{win:"Ctrl-Alt-3",mac:"Command-Option-3"},exec:function(e){b(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToPre",bindKey:{win:"Ctrl-Alt-P",mac:"Command-Option-P"},exec:function(e){T(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToCode",bindKey:{win:"Ctrl-Alt-C",mac:"Command-Option-C"},exec:function(e){x(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToBlockQuote",bindKey:{win:"Ctrl-Q",mac:"Command-Shift-K"},exec:function(e){S(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToUnorderedList",bindKey:{win:"Ctrl-U",mac:"Command-U"},exec:function(e){R(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToOrderedList",bindKey:{win:"Ctrl-Shift+O",mac:"Command-Option-O"},exec:function(e){j(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToLink",bindKey:{win:"Ctrl-L",mac:"Command-L"},exec:function(e){O(e)},readOnly:!0}),c.commands.addCommand({name:"markdownToImageLink",bindKey:{win:"Ctrl-Shift-I",mac:"Command-Option-I"},exec:function(e){P(e)},readOnly:!0}),"true"===a.mention&&c.commands.addCommand({name:"markdownToMention",bindKey:{win:"Ctrl-M",mac:"Command-M"},exec:function(e){E(e)},readOnly:!0})})},D(function(){D(".main-martor").martor()}),"django"in window&&"jQuery"in window.django&&django.jQuery(document).on("formset:added",function(e){setTimeout(function(){var n=D(e.target);n.find(".main-martor").each(function(){var e=(e=n.attr("id")).substr(e.lastIndexOf("-")+1),e=D(this.outerHTML.replace(/__prefix__/g,e));D(this).replaceWith(e),e.martor()})},1e3)})}(jQuery);
diff --git a/martor/templates/martor/tailwind/emoji.html b/martor/templates/martor/tailwind/emoji.html
index 52df302e..3baf1503 100644
--- a/martor/templates/martor/tailwind/emoji.html
+++ b/martor/templates/martor/tailwind/emoji.html
@@ -1,52 +1,38 @@
{% load i18n %}
-
-
+
+
-
-
-
-
+
-
-
-
-
-
-
-
- {% trans "Choose an Emoji" %}
-
-
-
- {% trans "Click on an emoji to insert it into your text" %}
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+ {% trans "Choose an Emoji" %}
+
+
+ {% trans "Click on an emoji to insert it into your text" %}
+
-
-
-
-
-
{% trans "Loading emojis..." %}
-
+
+
+
+
{% trans "Loading emojis..." %}
+
+
+
-
+
-
-
-
-
- {% trans "All" %}
+
+
+
{% trans "Popular" %}
+
+
+ ❤️
+
+
+ 👍
-
- 😊 {% trans "Smileys" %}
+
+ 👎
-
- 👥 {% trans "People" %}
+
+ 🔥
-
- 🌿 {% trans "Nature" %}
+
+ ⭐
-
- 🎯 {% trans "Objects" %}
+
+ 🎉
-
+
-
-
-
-
+
{% trans "All Emojis" %}
+
+
-
-
-
-
{% trans "Popular" %}
-
-
- 😊
-
-
- ❤️
-
-
- 👍
-
-
- 👎
-
-
- 🔥
-
-
- ⭐
-
-
- 🤔
-
-
- 🎉
-
-
-
-
-
-
-
- {% trans "Close" %}
-
diff --git a/martor/templates/martor/tailwind/guide.html b/martor/templates/martor/tailwind/guide.html
index 9ea14adc..88754555 100644
--- a/martor/templates/martor/tailwind/guide.html
+++ b/martor/templates/martor/tailwind/guide.html
@@ -1,227 +1,194 @@
-{% load i18n %}
+{% load i18n static %}
-
-
+
+
-
-
-
-
+
-
-
-
-
-
-
-
- {% trans "Markdown Guide" %}
-
-
-
- {% trans "Quick reference for Markdown syntax" %}
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
{% blocktrans with repo_url='https://github.com/agusmakmun/django-markdown-editor' %}Copyright © Martor {% endblocktrans %}
+
+ {% blocktrans with doc_url='http://commonmark.org/help/' %}This editor is powered by Markdown. For full documentation, click here .{% endblocktrans %}
+
-
-
-
-
-
-
{% trans "Text Formatting" %}
-
-
- {% trans "Bold" %}
- **text**
-
-
- {% trans "Italic" %}
- *text*
-
-
- {% trans "Strikethrough" %}
- ~~text~~
-
-
- {% trans "Underline" %}
- ++text++
-
-
- {% trans "Inline Code" %}
- `code`
-
-
-
-
-
-
-
{% trans "Headers" %}
-
-
- {% trans "Header 1" %}
- # H1
-
-
- {% trans "Header 2" %}
- ## H2
-
-
- {% trans "Header 3" %}
- ### H3
-
-
- {% trans "Header 4" %}
- #### H4
-
-
- {% trans "Header 5" %}
- ##### H5
-
-
-
-
-
-
-
{% trans "Lists" %}
-
-
- {% trans "Unordered List" %}
- * Item 1 * Item 2
-
-
- {% trans "Ordered List" %}
- 1. First 2. Second
-
-
-
-
-
-
-
{% trans "Links & Images" %}
-
-
- {% trans "Link" %}
- [text](url)
-
-
- {% trans "Image" %}
- 
-
-
-
+
+
+
+
+ {% trans "Code" %}
+ {% trans "Or" %}
+ Linux/Windows
+ Mac OS
+ {% trans "... to Get" %}
+
+
+
+ {% if emoji_enabled %}
+
+ :emoji_name:
+ —
+ —
+ —
+
+
+ {% endif %}
-
-
-
{% trans "Code Blocks" %}
-
-
- {% trans "Code Block" %}
- ``` code here ```
-
-
- {% trans "Language Specific" %}
- ```python code here ```
-
-
-
+ {% if mentions_enabled %}
+
+ @[username]
+ —
+ Ctrl+M
+ Command+M
+ @username
+
+ {% endif %}
-
-
-
{% trans "Other" %}
-
-
- {% trans "Quote" %}
- > text
-
-
- {% trans "Horizontal Rule" %}
- ---
-
-
- {% trans "Line Break" %}
- 2 spaces
-
-
- {% trans "Mention" %}
- @[user]
-
-
- {% trans "Emoji" %}
- :smile:
-
-
-
-
-
-
-
{% trans "Tables" %}
-
- {% trans "Table Syntax" %}
-
- | Header 1 | Header 2 |
- |----------|----------|
- | Cell 1 | Cell 2 |
-
-
-
-
-
-
-
{% trans "Keyboard Shortcuts" %}
-
-
-
- {% trans "Bold" %}
- Ctrl+B
-
-
- {% trans "Italic" %}
- Ctrl+I
-
-
- {% trans "Link" %}
- Ctrl+L
-
-
-
-
- {% trans "Code" %}
- Ctrl+Alt+C
-
-
- {% trans "Quote" %}
- Ctrl+Q
-
-
- {% trans "List" %}
- Ctrl+U
-
-
-
-
-
-
-
+ {% if emoji_enabled or mentions_enabled %}
+
+
+
+ {% endif %}
-
-
- {% trans "Got it!" %}
-
+
+ *Italic*
+ _Italic_
+ Ctrl+I
+ Command+I
+ Italic
+
+
+ **Bold**
+ __Bold__
+ Ctrl+B
+ Command+B
+ Bold
+
+
+ ++Underscores++
+ —
+ Ctrl+Shift+U
+ Command+Shift+U
+ Underscores
+
+
+ ~~Strikethrough~~
+ —
+ Ctrl+Shift+S
+ Command+Shift+S
+ Strikethrough
+
+
+ # Heading 1
+ Heading 1 =========
+ Ctrl+Alt+1
+ Command+Option+1
+ Heading 1
+
+
+ ## Heading 2
+ Heading 2 ---------
+ Ctrl+Alt+2
+ Command+Option+2
+ Heading 2
+
+
+ [Link](http://a.com)
+ [Link][1] [1]: http://b.org
+ Ctrl+L
+ Command+L
+ Link
+
+
+ 
+ ![Image][1] [1]: http://url/b.jpg
+ Ctrl+Shift+I
+ Command+Option+I
+
+
+
+ > Blockquote
+ —
+ Ctrl+Q
+ Command+Shift+K
+ Blockquote
+
+
+ A paragraph. A paragraph after 1 blank line.
+ —
+ —
+ —
+
+ A paragraph.
+ A paragraph after 1 blank line.
+
+
+
+ * List * List * List
+ - List - List - List
+ Ctrl+U
+ Command+U
+
+
+
+
+
+ 1. One 2. Two 3. Three
+ 1) One 2) Two 3) Three
+ Ctrl+Shift+O
+ Command+Option+O
+
+
+ One
+ Two
+ Three
+
+
+
+
+ Horizontal Rule -----------
+ Horizontal Rule ***********
+ Ctrl+H
+ Command+H
+
+ Horizontal Rule
+
+
+
+
+ `Inline code` with backticks
+ —
+ Ctrl+Alt+C
+ Command+Option+C
+ Inline code with backticks
+
+
+ ``` def whatever(foo): return foo ```
+ with tab / 4 spaces ....def whatever(foo): .... return foo
+ Ctrl+Alt+P
+ Command+Option+P
+
+ def whatever(foo):
+ return foo
+
+
+
+
diff --git a/martor/templates/martor/tailwind/toolbar.html b/martor/templates/martor/tailwind/toolbar.html
index c6fc7c7a..7f44734b 100644
--- a/martor/templates/martor/tailwind/toolbar.html
+++ b/martor/templates/martor/tailwind/toolbar.html
@@ -117,7 +117,8 @@
{% if 'emoji' in toolbar_buttons %}
-
+
+
{% endif %}
diff --git a/martor_demo/app/templates/tailwind/base.html b/martor_demo/app/templates/tailwind/base.html
index 5e44912c..afe30735 100644
--- a/martor_demo/app/templates/tailwind/base.html
+++ b/martor_demo/app/templates/tailwind/base.html
@@ -13,7 +13,7 @@
{% block css %}
-
+
{% endblock %}