bug: fixed syntax highlighting bug on large pasted text

This commit is contained in:
Asad 2025-02-21 15:29:23 -05:00
parent 7e7452a016
commit d928702e89
4 changed files with 56 additions and 11 deletions

@ -1,4 +1,4 @@
# [BinCode](jsbin.asadk.dev) - A Complete Self-Hostable JSFiddle Alternative
# [BinCode](https://bincode.asadk.dev) - A Complete Self-Hostable JSFiddle Alternative
## Overview
BinCode is a minimalist platform for managing and sharing code snippets, built with Vue.js and SQLite. It runs entirely on your own infrastructure, giving you full control over your data and workflow.

@ -153,6 +153,11 @@ createApp({
},
mounted() {
const textarea = document.querySelector('.editor-content textarea');
if (textarea) {
textarea.addEventListener('paste', this.handlePaste);
}
this.loadPrismTheme();
this.initThemeListener();
@ -172,8 +177,37 @@ createApp({
};
}
},
beforeUnmount() {
const textarea = document.querySelector('.editor-content textarea');
if (textarea) {
textarea.removeEventListener('paste', this.handlePaste);
}
},
methods: {
handlePaste(event) {
const textarea = event.target;
// scroll to cursor
requestAnimationFrame(() => {
this.scrollToCursor(textarea);
});
},
scrollToCursor(textarea) {
const cursorPosition = textarea.selectionStart;
const lineHeight = parseInt(getComputedStyle(textarea).lineHeight, 10);
const lines = textarea.value.substr(0, cursorPosition).split('\n').length;
const scrollTop = (lines - 1) * lineHeight;
textarea.scrollTop = scrollTop;
const pre = textarea.nextElementSibling;
if (pre) {
pre.scrollTop = scrollTop;
}
},
loadPrismTheme() {
const existingTheme = document.querySelector("link[data-prism-theme]");
if (existingTheme) {
@ -214,6 +248,9 @@ createApp({
const textarea = event.target;
const pre = textarea.nextElementSibling;
if (pre) {
pre.style.width = `${textarea.offsetWidth}px`;
pre.style.height = `${textarea.offsetHeight}px`;
pre.scrollTop = textarea.scrollTop;
pre.scrollLeft = textarea.scrollLeft;
}

@ -13,6 +13,14 @@
<link rel="stylesheet" href="./font.css">
<!-- Prismjs css -->
<link rel="stylesheet" href="./libraries/prism/theme/prism.min.css" />
<!-- Code Mirror 6 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror6/0.0.1/codemirror.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror6/0.0.1/language/javascript.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror6/0.0.1/language/css.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror6/0.0.1/language/html.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/codemirror6/0.0.1/theme/dark.min.js"></script>
</head>
<body>
<div id="app">
@ -80,15 +88,15 @@
<!-- Editor content -->
<div class="editor-content">
<textarea
:value="currentCode"
@input="handleInput"
@scroll="handleScroll"
@keydown="handleKeydown"
:class="{ 'active-editor': true }"
spellcheck="false"
autocomplete="off"
:placeholder="'Enter your ' + activeTab.toUpperCase() + ' code here...'"
></textarea>
:value="currentCode"
@input="handleInput"
@scroll="handleScroll"
@keydown="handleKeydown"
:class="{ 'active-editor': true }"
spellcheck="false"
autocomplete="off"
:placeholder="'Enter your ' + activeTab.toUpperCase() + ' code here...'"
></textarea>
<pre
class="editor-highlight"
aria-hidden="true"

@ -1 +1 @@
code[class*=language-],pre[class*=language-]{color:#d4d4d4;font-size:13px;text-shadow:none;font-family:Menlo,Monaco,Consolas,"Andale Mono","Ubuntu Mono","Courier New",monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#264f78}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;background:#1e1e1e}:not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#db4c69;background:#1e1e1e}.namespace{opacity:.7}.token.boolean,.token.doctype .token.doctype-tag,.token.entity,.token.important,.token.keyword,.token.operator.arrow,.token.punctuation.interpolation-punctuation,.token.tag{color:#569cd6}.token.atrule .token.url,.token.attr-name,.token.console,.token.constant,.token.doctype .token.name,.token.exports .token.maybe-class-name,.token.imports .token.maybe-class-name,.token.interpolation,.token.parameter,.token.property,.token.variable,code[class*=language-javascript],code[class*=language-jsx],code[class*=language-tsx],code[class*=language-typescript],pre[class*=language-javascript],pre[class*=language-jsx],pre[class*=language-tsx],pre[class*=language-typescript]{color:#9cdcfe}.token.comment,.token.prolog{color:#6a9955}.language-html .language-css .token.punctuation,.language-html .language-javascript .token.punctuation,.token.atrule .token.url .token.punctuation,.token.attr-value .token.punctuation.attr-equals,.token.entity,.token.operator,.token.punctuation,code[class*=language-html],pre[class*=language-html]{color:#d4d4d4}.token.boolean,.token.constant,.token.inserted,.token.number,.token.property,.token.symbol,.token.tag,.token.unit{color:#b5cea8}.token.atrule,.token.attr-name,.token.attr-value,.token.attr-value .token.punctuation,.token.builtin,.token.char,.token.deleted,.token.selector,.token.string,code[class*=language-css],pre[class*=language-css]{color:#ce9178}.language-css .token.string.url{text-decoration:underline}.token.atrule .token.rule,.token.keyword.control-flow,.token.keyword.module{color:#c586c0}.language-regex .token.anchor,.token.atrule .token.url .token.function,.token.function,.token.function .token.maybe-class-name{color:#dcdcaa}.token.regex{color:#d16969}.token.italic{font-style:italic}.token.class-name,.token.maybe-class-name,.token.namespace{color:#4ec9b0}.token.escape,.token.selector{color:#d7ba7d}.language-html .token.punctuation,.token.cdata,.token.tag .token.punctuation{color:grey}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}.line-highlight.line-highlight{background:#f7ebc6;box-shadow:inset 5px 0 0 #f7d87c;z-index:0}
code[class*=language-],pre[class*=language-]{color:#d4d4d4;font-size:13px;text-shadow:none;font-family:Menlo,Monaco,Consolas,"Andale Mono","Ubuntu Mono","Courier New",monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-] ::selection,code[class*=language-]::selection,pre[class*=language-] ::selection,pre[class*=language-]::selection{text-shadow:none;background:#264f78}@media print{code[class*=language-],pre[class*=language-]{text-shadow:none}}pre[class*=language-]{padding:1em;margin:.5em 0;overflow:auto;background:#1e1e1e}:not(pre)>code[class*=language-]{padding:.1em .3em;border-radius:.3em;color:#db4c69;background:#1e1e1e}.namespace{opacity:.7}.token.boolean,.token.doctype .token.doctype-tag,.token.entity,.token.important,.token.keyword,.token.operator.arrow,.token.punctuation.interpolation-punctuation,.token.tag{color:#569cd6}.token.attr-equals,.token.operator,.token.punctuation{background:0 0!important}.token.atrule .token.url,.token.attr-name,.token.console,.token.constant,.token.doctype .token.name,.token.exports .token.maybe-class-name,.token.imports .token.maybe-class-name,.token.interpolation,.token.parameter,.token.property,.token.variable,code[class*=language-javascript],code[class*=language-jsx],code[class*=language-tsx],code[class*=language-typescript],pre[class*=language-javascript],pre[class*=language-jsx],pre[class*=language-tsx],pre[class*=language-typescript]{color:#9cdcfe}.token.comment,.token.prolog{color:#6a9955}.language-html .language-css .token.punctuation,.language-html .language-javascript .token.punctuation,.token.atrule .token.url .token.punctuation,.token.attr-value .token.punctuation.attr-equals,.token.entity,.token.operator,.token.punctuation,code[class*=language-html],pre[class*=language-html]{color:#d4d4d4}.token.boolean,.token.constant,.token.inserted,.token.number,.token.property,.token.symbol,.token.tag,.token.unit{color:#b5cea8}.token.atrule,.token.attr-name,.token.attr-value,.token.attr-value .token.punctuation,.token.builtin,.token.char,.token.deleted,.token.selector,.token.string,code[class*=language-css],pre[class*=language-css]{color:#ce9178}.language-css .token.string.url{text-decoration:underline}.token.atrule .token.rule,.token.keyword.control-flow,.token.keyword.module{color:#c586c0}.language-regex .token.anchor,.token.atrule .token.url .token.function,.token.function,.token.function .token.maybe-class-name{color:#dcdcaa}.token.regex{color:#d16969}.token.italic{font-style:italic}.token.class-name,.token.maybe-class-name,.token.namespace{color:#4ec9b0}.token.escape,.token.selector{color:#d7ba7d}.language-html .token.punctuation,.token.cdata,.token.tag .token.punctuation{color:grey}pre[class*=language-]>code[class*=language-]{position:relative;z-index:1}.line-highlight.line-highlight{background:#f7ebc6;box-shadow:inset 5px 0 0 #f7d87c;z-index:0}