replacing codeflask with code-input

This commit is contained in:
Bowrna 2024-11-05 12:12:15 +05:30
parent 2abc0a8651
commit 80e6dd191a
4 changed files with 147 additions and 101 deletions

3
frontend/index.html vendored
View file

@ -17,5 +17,8 @@
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
<script src="./node_modules/@webcoder49/code-input/code-input.js"></script>
<link rel="stylesheet" href="./node_modules/@webcoder49/code-input/code-input.min.css">
</body>
</html>

View file

@ -11,6 +11,7 @@
},
"dependencies": {
"@tinymce/tinymce-vue": "^3",
"@webcoder49/code-input": "github:WebCoder49/code-input",
"axios": "^1.7.4",
"buefy": "^0.9.25",
"bulma": "^0.9.4",

View file

@ -1,10 +1,18 @@
<template>
<div ref="htmlEditor" id="html-editor" class="html-editor" />
<div ref="htmlEditor" class="html-editor">
<code-input
ref="editor"
:value="value"
@input="handleInput"
language="html"
:data-readonly="disabled"
spellcheck="false"
/>
</div>
</template>
<script>
import CodeFlask from 'codeflask';
import { colors } from '../constants';
import Prism from 'prismjs';
export default {
props: {
@ -13,66 +21,60 @@ export default {
disabled: Boolean,
},
data() {
return {
data: '',
flask: null,
};
},
methods: {
initHTMLEditor(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;
white-space: pre-wrap ;
word-break: break-word ;
}
.codeflask .codeflask__lines { background: #fafafa; z-index: 10; }
.codeflask .token.tag { font-weight: bold; }
.codeflask .token.attr-name { color: #111; }
.codeflask .token.attr-value { color: ${colors.primary} !important; }
</style>
<div id="area"></area>
`;
this.$refs.htmlEditor.appendChild(el);
handleInput(event) {
this.$emit('input', event.target.value);
},
this.flask = new CodeFlask(el.shadowRoot.getElementById('area'), {
language: this.$props.language,
lineNumbers: false,
styleParent: el.shadowRoot,
readonly: this.disabled,
});
initializeEditor() {
// const textarea = this.$refs.editor;
// textarea.setAttribute('is', 'code-input');
// textarea.setAttribute('data-language', this.language);
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();
});
// Register Prism for syntax highlighting if needed
if (window.codeInput) {
window.codeInput.registerTemplate(
'syntax-highlighted',
window.codeInput.templates.prism(Prism, []),
);
// window.codeInput.setDefaultTemplate('syntax-highlighted');
}
},
},
mounted() {
this.initHTMLEditor(this.$props.value || '');
},
watch: {
value(newVal) {
if (newVal !== this.data) {
this.flask.updateCode(newVal);
}
},
this.initializeEditor();
},
};
</script>
<style>
/* Hide the non-editable preview content */
.code-input pre[aria-hidden="true"] {
display: none !important;
}
/* Additional styling */
.html-editor {
width: 100%;
position: relative;
}
.html-editor textarea {
font-size: 15px;
min-height: 200px;
width: 100%;
padding: 8px;
border: none;
resize: none;
}
.token.tag { font-weight: bold; }
.token.attr-name { color: #111; }
.token.attr-value { color: #0066cc; }
.html-editor textarea:focus {
outline: none;
border-color: #0066cc;
}
</style>

View file

@ -1,11 +1,20 @@
<template>
<div ref="markdownEditor" id="markdown-editor" class="markdown-editor" />
<div ref="markdownEditor" class="markdown-editor">
<code-input
ref="editor"
:value="value"
@input="handleInput"
language="markdown"
:data-readonly="disabled"
spellcheck="false"
/>
</div>
</template>
<script>
import 'prismjs/components/prism-markdown';
import CodeFlask from 'codeflask';
import { colors } from '../constants';
// import 'code-input'; // Import the web component
// import 'prismjs/components/prism-markdown';
import Prism from 'prismjs';
export default {
props: {
@ -17,63 +26,94 @@ export default {
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' });
handleInput(event) {
this.$emit('input', event.target.value);
},
el.shadowRoot.innerHTML = `
<style>
.codeflask .codeflask__flatten { font-size: 15px; }
.codeflask .token.tag { font-weight: bold; color: ${colors.primary} !important; }
.codeflask .token { color: ${colors.primary} !important; }
.codeflask .token.heading { font-weight: bold; }
.codeflask .token.important,.token.bold,.token.strong { font-weight: bold; }
.codeflask .token.em,.token.italic { font-style: italic; }
.codeflask .token.comment { color: slategray; }
.codeflask .token.url { color: ${colors.primary}; text-decoration: underline; }
</style>
<div id="area"></area>
`;
this.$refs.markdownEditor.appendChild(el);
initializeEditor() {
// const textarea = this.$refs.editor;
// textarea.setAttribute('is', 'code-input');
// textarea.setAttribute('data-language', this.language);
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();
});
// Register Prism for syntax highlighting if needed
if (window.codeInput) {
window.codeInput.registerTemplate(
'syntax-highlighted',
window.codeInput.templates.prism(Prism, []),
);
// window.codeInput.setDefaultTemplate('syntax-highlighted');
}
},
},
mounted() {
this.initMarkdownEditor(this.$props.value || '');
this.initializeEditor();
},
watch: {
value(newVal) {
if (newVal !== this.data) {
this.flask.updateCode(newVal);
this.data = newVal;
}
},
},
};
</script>
<style>
.markdown-editor {
width: 100%;
position: relative;
}
/* Base editor styles */
.markdown-editor textarea {
font-size: 15px;
min-height: 200px;
width: 100%;
height: 100%;
border: none;
border-radius: 2px;
padding: 8px;
box-sizing: border-box; /* Keep padding within the width/height */
resize: none; /* Optional: Prevent resizing */
}
/* Markdown syntax highlighting */
.markdown-editor .token {
color: var(--primary-color, #0066cc);
}
.markdown-editor .token.heading {
font-weight: bold;
}
.markdown-editor .token.important,
.markdown-editor .token.bold,
.markdown-editor .token.strong {
font-weight: bold;
}
.markdown-editor .token.em,
.markdown-editor .token.italic {
font-style: italic;
}
.markdown-editor .token.comment {
color: slategray;
}
.markdown-editor .token.url {
color: var(--primary-color, #0066cc);
text-decoration: underline;
}
/* Focus state */
.markdown-editor textarea:focus {
outline: none;
border-color: var(--primary-color, #0066cc);
}
</style>