Skip to content

Commit

Permalink
markdown syntax highlighter
Browse files Browse the repository at this point in the history
  • Loading branch information
Bowrna committed Oct 5, 2024
1 parent 58b13af commit 452e1b2
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 2 deletions.
1 change: 1 addition & 0 deletions frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"codeflask": "^1.4.1",
"dayjs": "^1.11.10",
"indent.js": "^0.3.5",
"prismjs":"^1.29.0",
"qs": "^6.10.1",
"textversionjs": "^1.1.3",
"tinymce": "^5.10.9",
Expand Down
9 changes: 7 additions & 2 deletions frontend/src/components/Editor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@
<!-- raw html editor //-->
<html-editor v-if="form.format === 'html'" v-model="form.body" />

<!-- plain text / markdown editor //-->
<b-input v-if="form.format === 'plain' || form.format === 'markdown'" v-model="form.body" @input="onEditorChange"
<!-- markdown editor //-->
<markdown-editor v-if="form.format === 'markdown'" v-model="form.body" />

<!-- plain text //-->
<b-input v-if="form.format === 'plain'" v-model="form.body" @input="onEditorChange"
type="textarea" name="content" ref="plainEditor" class="plain-editor" />

<!-- campaign preview //-->
Expand Down Expand Up @@ -136,6 +139,7 @@ import { colors, uris } from '../constants';
import Media from '../views/Media.vue';
import CampaignPreview from './CampaignPreview.vue';
import HTMLEditor from './HTMLEditor.vue';
import MarkdownEditor from './MarkdownEditor.vue';
const turndown = new TurndownService();
Expand All @@ -158,6 +162,7 @@ export default {
Media,
CampaignPreview,
'html-editor': HTMLEditor,
'markdown-editor': MarkdownEditor,
TinyMce,
},
Expand Down
87 changes: 87 additions & 0 deletions frontend/src/components/MarkdownEditor.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
<template>
<div ref="markdownEditor" id="markdown-editor" class="markdown-editor" />
</template>

<script>
import 'prismjs/components/prism-markdown';
import CodeFlask from 'codeflask';
import { colors } from '../constants';
export default {
props: {
value: { type: String, default: '' },
language: { type: String, default: 'markdown' },
disabled: Boolean,
},
data() {
return {
data: '',
flask: null,
};
},
methods: {
initMarkdownEditor(body) {
// CodeFlask editor is rendered in a shadow DOM tree to keep its styles
// sandboxed away from the global styles.
const el = document.createElement('code-flask');
el.attachShadow({ mode: 'open' });
el.shadowRoot.innerHTML = `
<style>
.codeflask .codeflask__flatten { font-size: 15px; }
.codeflask .codeflask__lines { background: #f5f5f5; z-index: 10; }
.codeflask .token.tag { font-weight: bold; color: ${colors.primary}; }
.codeflask .token.attr-name { color: #111; }
.codeflask .token.attr-value { color: ${colors.secondary} !important; }
.codeflask .token.keyword { color: #ff4500; }
.codeflask .token.comment { color: #6a737d; font-style: italic; }
.codeflask .token.heading { font-weight: bold; color: #00f; }
.codeflask .token.important,.token.bold,.token.strong { font-weight: bold; }
.codeflask .token.em,.token.italic { font-style: italic; }
.codeflask .token.punctuation { color: #999; }
.codeflask .token.comment { color: slategray; }
.codeflask .token.keyword { color: #ff4500; }
.codeflask .token.string { color: #22863a; }
.codeflask .token.function { color: #6f42c1; }
.codeflask .token.url { color: #0366d6; text-decoration: underline; }
</style>
<div id="area"></area>
`;
this.$refs.markdownEditor.appendChild(el);
this.flask = new CodeFlask(el.shadowRoot.getElementById('area'), {
language: this.$props.language || 'markdown',
lineNumbers: false,
styleParent: el.shadowRoot,
readonly: this.disabled,
});
this.flask.onUpdate((v) => {
this.data = v;
this.$emit('input', v);
});
// Set the initial value.
this.flask.updateCode(body);
this.$nextTick(() => {
document.querySelector('code-flask').shadowRoot.querySelector('textarea').focus();
});
},
},
mounted() {
this.initMarkdownEditor(this.$props.value || '');
},
watch: {
value(newVal) {
if (newVal !== this.data) {
this.flask.updateCode(newVal);
}
},
},
};
</script>

0 comments on commit 452e1b2

Please sign in to comment.