This commit is contained in:
2025-05-09 18:41:43 +08:00
parent 976c68199d
commit 232343324a
7 changed files with 108 additions and 1 deletions

View File

@@ -3,6 +3,50 @@
@{ @{
} }
@section Styles {
<!-- 引入 CodeMirror CSS -->
<link rel="stylesheet" href="/admin/codemirror/codemirror.min.css">
<!-- 引入 CodeMirror JS -->
<script src="/admin/codemirror/codemirror.min.js"></script>
<script src="/admin/codemirror/htmlmixed.min.js"></script>
<!-- 引入语法高亮模式(如 JavaScript) -->
<script src="/admin/codemirror/javascript.min.js"></script>
<style>
/* 自定义 CodeMirror 样式 */
.CodeMirror {
border: 1px solid #ddd;
border-radius: 8px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
font-family: 'Fira Code', monospace;
font-size: 14px;
line-height: 1.5;
background-color: #f9f9f9;
min-height: 600px;
}
.CodeMirror-linenumbers {
color: #888;
background-color: #f0f0f0;
padding-right: 10px;
width: 40px;
}
.CodeMirror-cursor {
border-left: 2px solid #007bff;
}
.editor-container {
max-width: 800px;
margin: 20px auto;
padding: 20px;
background-color: #fff;
border-radius: 10px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
}
</style>
}
<template x-data x-if="$store.errorMessage||1"> <template x-data x-if="$store.errorMessage||1">
<div class="alert alert-danger floating-div" x-show="$store.errorMessage" x-transition x-html="$store.errorMessage"></div> <div class="alert alert-danger floating-div" x-show="$store.errorMessage" x-transition x-html="$store.errorMessage"></div>
@@ -33,7 +77,14 @@
<div class="col-lg-9 col-md-9 col-sm-9"> <div class="col-lg-9 col-md-9 col-sm-9">
<div class="form-group"> <div class="form-group">
<textarea class="form-control" id="editor" x-model="file.content" style="min-height: 600px;"></textarea> <div id="code-editor" style="width: 100%; min-height: 600px;"></div>
<!-- 高亮编辑器容器 -->
<!-- 隐藏的 textarea 用于保存纯文本 -->
<textarea id="code-content" name="code" style="display: none;" x-model="file.content"></textarea>
</div> </div>
<div class="btn-toolbar list-toolbar pull-right"> <div class="btn-toolbar list-toolbar pull-right">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using clean-css v5.3.2.
* Original file: /npm/codemirror@5.65.2/theme/dracula.css
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
.cm-s-dracula .CodeMirror-gutters,.cm-s-dracula.CodeMirror{background-color:#282a36!important;color:#f8f8f2!important;border:none}.cm-s-dracula .CodeMirror-gutters{color:#282a36}.cm-s-dracula .CodeMirror-cursor{border-left:solid thin #f8f8f0}.cm-s-dracula .CodeMirror-linenumber{color:#6d8a88}.cm-s-dracula .CodeMirror-selected{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-line::selection,.cm-s-dracula .CodeMirror-line>span::selection,.cm-s-dracula .CodeMirror-line>span>span::selection{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-line::-moz-selection,.cm-s-dracula .CodeMirror-line>span::-moz-selection,.cm-s-dracula .CodeMirror-line>span>span::-moz-selection{background:rgba(255,255,255,.1)}.cm-s-dracula span.cm-comment{color:#6272a4}.cm-s-dracula span.cm-string,.cm-s-dracula span.cm-string-2{color:#f1fa8c}.cm-s-dracula span.cm-number{color:#bd93f9}.cm-s-dracula span.cm-variable{color:#50fa7b}.cm-s-dracula span.cm-variable-2{color:#fff}.cm-s-dracula span.cm-def{color:#50fa7b}.cm-s-dracula span.cm-operator{color:#ff79c6}.cm-s-dracula span.cm-keyword{color:#ff79c6}.cm-s-dracula span.cm-atom{color:#bd93f9}.cm-s-dracula span.cm-meta{color:#f8f8f2}.cm-s-dracula span.cm-tag{color:#ff79c6}.cm-s-dracula span.cm-attribute{color:#50fa7b}.cm-s-dracula span.cm-qualifier{color:#50fa7b}.cm-s-dracula span.cm-property{color:#66d9ef}.cm-s-dracula span.cm-builtin{color:#50fa7b}.cm-s-dracula span.cm-type,.cm-s-dracula span.cm-variable-3{color:#ffb86c}.cm-s-dracula .CodeMirror-activeline-background{background:rgba(255,255,255,.1)}.cm-s-dracula .CodeMirror-matchingbracket{text-decoration:underline;color:#fff!important}
/*# sourceMappingURL=/sm/ba8d009adc9d54938ea88252c099a2b773ed3a4f5515ae9c2f937a8a4cb399df.map */

View File

@@ -0,0 +1,8 @@
/**
* Minified by jsDelivr using Terser v5.37.0.
* Original file: /npm/codemirror@5.65.2/mode/htmlmixed/htmlmixed.js
*
* Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files
*/
!function(t){"object"==typeof exports&&"object"==typeof module?t(require("../../lib/codemirror"),require("../xml/xml"),require("../javascript/javascript"),require("../css/css")):"function"==typeof define&&define.amd?define(["../../lib/codemirror","../xml/xml","../javascript/javascript","../css/css"],t):t(CodeMirror)}((function(t){"use strict";var e={script:[["lang",/(javascript|babel)/i,"javascript"],["type",/^(?:text|application)\/(?:x-)?(?:java|ecma)script$|^module$|^$/i,"javascript"],["type",/./,"text/plain"],[null,null,"javascript"]],style:[["lang",/^css$/i,"css"],["type",/^(text\/)?(x-)?(stylesheet|css)$/i,"css"],["type",/./,"text/plain"],[null,null,"css"]]};var a={};function n(t,e){var n=t.match(function(t){var e=a[t];return e||(a[t]=new RegExp("\\s+"+t+"\\s*=\\s*('|\")?([^'\"]+)('|\")?\\s*"))}(e));return n?/^\s*(.*?)\s*$/.exec(n[2])[1]:""}function l(t,e){return new RegExp((e?"^":"")+"</\\s*"+t+"\\s*>","i")}function r(t,e){for(var a in t)for(var n=e[a]||(e[a]=[]),l=t[a],r=l.length-1;r>=0;r--)n.unshift(l[r])}t.defineMode("htmlmixed",(function(a,o){var i=t.getMode(a,{name:"xml",htmlMode:!0,multilineTagIndentFactor:o.multilineTagIndentFactor,multilineTagIndentPastTag:o.multilineTagIndentPastTag,allowMissingTagName:o.allowMissingTagName}),c={},s=o&&o.tags,u=o&&o.scriptTypes;if(r(e,c),s&&r(s,c),u)for(var m=u.length-1;m>=0;m--)c.script.unshift(["type",u[m].matches,u[m].mode]);function d(e,r){var o,s=i.token(e,r.htmlState),u=/\btag\b/.test(s);if(u&&!/[<>\s\/]/.test(e.current())&&(o=r.htmlState.tagName&&r.htmlState.tagName.toLowerCase())&&c.hasOwnProperty(o))r.inTag=o+" ";else if(r.inTag&&u&&/>$/.test(e.current())){var m=/^([\S]+) (.*)/.exec(r.inTag);r.inTag=null;var f=">"==e.current()&&function(t,e){for(var a=0;a<t.length;a++){var l=t[a];if(!l[0]||l[1].test(n(e,l[0])))return l[2]}}(c[m[1]],m[2]),g=t.getMode(a,f),p=l(m[1],!0),h=l(m[1],!1);r.token=function(t,e){return t.match(p,!1)?(e.token=d,e.localState=e.localMode=null,null):function(t,e,a){var n=t.current(),l=n.search(e);return l>-1?t.backUp(n.length-l):n.match(/<\/?$/)&&(t.backUp(n.length),t.match(e,!1)||t.match(n)),a}(t,h,e.localMode.token(t,e.localState))},r.localMode=g,r.localState=t.startState(g,i.indent(r.htmlState,"",""))}else r.inTag&&(r.inTag+=e.current(),e.eol()&&(r.inTag+=" "));return s}return{startState:function(){return{token:d,inTag:null,localMode:null,localState:null,htmlState:t.startState(i)}},copyState:function(e){var a;return e.localState&&(a=t.copyState(e.localMode,e.localState)),{token:e.token,inTag:e.inTag,localMode:e.localMode,localState:a,htmlState:t.copyState(i,e.htmlState)}},token:function(t,e){return e.token(t,e)},indent:function(e,a,n){return!e.localMode||/^\s*<\//.test(a)?i.indent(e.htmlState,a,n):e.localMode.indent?e.localMode.indent(e.localState,a,n):t.Pass},innerMode:function(t){return{state:t.localState||t.htmlState,mode:t.localMode||i}}}}),"xml","javascript","css"),t.defineMIME("text/html","htmlmixed")}));
//# sourceMappingURL=/sm/e2c7ccb5e794d8515250b328c4947e850defb14ee2247c63cd3549e4879addb0.map

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,17 @@
document.addEventListener('alpine:init', function () { document.addEventListener('alpine:init', function () {
Alpine.data('data', function () { Alpine.data('data', function () {
// 初始化 CodeMirror 编辑器
const editor = CodeMirror(document.getElementById("code-editor"), {
mode: "text/html", // 设置语法模式
lineNumbers: true, // 显示行号
theme: "dracula", // 可选主题
value: "",
onChange: function (cm) {
// 实时同步内容到隐藏的 textarea
document.getElementById("code-content").value = cm.getValue();
}
});
const themeName = getUrlParameter("themeName")||"default"; const themeName = getUrlParameter("themeName")||"default";
const fileName = getUrlParameter("fileName") || "Index.liquid"; const fileName = getUrlParameter("fileName") || "Index.liquid";
@@ -26,6 +38,7 @@
axios.get('/themes/' + themeName + '/files/' + fileName) axios.get('/themes/' + themeName + '/files/' + fileName)
.then(data => { .then(data => {
this.file = data; this.file = data;
editor.setValue(this.file.content);
}); });
return this; return this;
}, },
@@ -51,6 +64,9 @@
} }
}, },
init() { init() {
this.loadFiles().loadFile(); this.loadFiles().loadFile();
this.themeName = themeName; this.themeName = themeName;
this.fileName = fileName; this.fileName = fileName;