✨ feat: 优化代码编辑器样式和增强预览功能
This commit is contained in:
@@ -38,11 +38,12 @@
|
|||||||
style.textContent = [
|
style.textContent = [
|
||||||
'.hustoj-vditor-hidden{display:none !important;}',
|
'.hustoj-vditor-hidden{display:none !important;}',
|
||||||
'.hustoj-vditor-wrapper{width:100%;margin:0 0 12px;}',
|
'.hustoj-vditor-wrapper{width:100%;margin:0 0 12px;}',
|
||||||
'.hustoj-vditor-code{--hustoj-vditor-font-size:18px;}',
|
'.hustoj-vditor-code{--hustoj-vditor-font-size:18px;text-align:left;}',
|
||||||
'.hustoj-vditor-code .vditor-toolbar{display:none !important;}',
|
'.hustoj-vditor-code .vditor-toolbar{display:none !important;}',
|
||||||
'.hustoj-vditor-code .vditor-reset,',
|
'.hustoj-vditor-code .vditor-reset,',
|
||||||
'.hustoj-vditor-code .vditor-content,',
|
'.hustoj-vditor-code .vditor-content,',
|
||||||
'.hustoj-vditor-code textarea{font-family:Consolas,Monaco,"Courier New",monospace !important;font-size:var(--hustoj-vditor-font-size) !important;line-height:1.5 !important;}',
|
'.hustoj-vditor-code .vditor,',
|
||||||
|
'.hustoj-vditor-code textarea{text-align:left !important;font-family:Consolas,Monaco,"Courier New",monospace !important;font-size:var(--hustoj-vditor-font-size) !important;line-height:1.5 !important;}',
|
||||||
'.hustoj-vditor-code .vditor-sv,',
|
'.hustoj-vditor-code .vditor-sv,',
|
||||||
'.hustoj-vditor-code .vditor-ir{min-height:100%;}',
|
'.hustoj-vditor-code .vditor-ir{min-height:100%;}',
|
||||||
'.hustoj-vditor-dark .vditor{background:#272822;border-color:#4a4a4a;}',
|
'.hustoj-vditor-dark .vditor{background:#272822;border-color:#4a4a4a;}',
|
||||||
@@ -51,7 +52,35 @@
|
|||||||
'.hustoj-vditor-dark textarea{color:#f8f8f2 !important;background:#272822 !important;}',
|
'.hustoj-vditor-dark textarea{color:#f8f8f2 !important;background:#272822 !important;}',
|
||||||
'.hustoj-vditor-dark .vditor-toolbar svg{fill:#f8f8f2;}',
|
'.hustoj-vditor-dark .vditor-toolbar svg{fill:#f8f8f2;}',
|
||||||
'.hustoj-vditor-mail .vditor-toolbar{border-bottom:1px solid #ddd;}',
|
'.hustoj-vditor-mail .vditor-toolbar{border-bottom:1px solid #ddd;}',
|
||||||
'.hustoj-vditor-mail .vditor{height:100%;min-height:180px;}'
|
'.hustoj-vditor-mail .vditor{height:100%;min-height:180px;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset pre{position:relative;margin:16px 0;padding:16px 18px;border:1px solid #cfd7e6;border-radius:12px;background:linear-gradient(180deg,#f9fbff 0%,#f3f7ff 100%);box-shadow:0 8px 20px rgba(15,23,42,0.06);}',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset pre code{display:block;font-size:15px;line-height:1.7;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-copy{display:block !important;position:absolute;top:12px;right:12px;z-index:2;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-copy span{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border:1px solid #c8d3e6;border-radius:999px;background:rgba(255,255,255,0.96);box-shadow:0 4px 12px rgba(15,23,42,0.08);font-size:12px;font-weight:600;color:#2f4f7f;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-copy span::after{content:attr(aria-label);}',
|
||||||
|
'.hustoj-vditor-preview .vditor-copy svg{width:14px !important;height:14px !important;color:currentColor;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart{margin:18px 0;padding:14px;border:1px solid #d7dce5;border-radius:12px;background:#fff;overflow:auto;text-align:center;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid svg,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart svg{display:block;max-width:100%;height:auto !important;overflow:visible;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid foreignObject,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart foreignObject,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid .label,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart .label{overflow:visible;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid .label div,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart .label div,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid .edgeLabel,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart .edgeLabel{white-space:normal !important;line-height:1.4 !important;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid .nodeLabel,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart .nodeLabel,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid .nodeLabel *,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart .nodeLabel *,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid svg text,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid svg tspan,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart svg text,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart svg tspan{font-family:"Cascadia Mono","JetBrains Mono",Consolas,"Noto Sans SC","Microsoft YaHei",sans-serif !important;font-variant-ligatures:none;letter-spacing:0.01em;text-rendering:geometricPrecision;}',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-mermaid .nodeLabel p,',
|
||||||
|
'.hustoj-vditor-preview .vditor-reset .language-flowchart .nodeLabel p{margin:0;line-height:1.4 !important;}'
|
||||||
].join('');
|
].join('');
|
||||||
documentRef.head.appendChild(style);
|
documentRef.head.appendChild(style);
|
||||||
styleInjected = true;
|
styleInjected = true;
|
||||||
@@ -339,6 +368,44 @@
|
|||||||
return previewOptions;
|
return previewOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function decorateRenderedPreview(element) {
|
||||||
|
if (!element || !element.classList) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.classList.add('hustoj-vditor-preview');
|
||||||
|
|
||||||
|
Array.prototype.forEach.call(
|
||||||
|
element.querySelectorAll('.language-mermaid, .language-flowchart'),
|
||||||
|
function (diagramContainer) {
|
||||||
|
Array.prototype.forEach.call(diagramContainer.querySelectorAll('svg'), function (svgElement) {
|
||||||
|
svgElement.style.maxWidth = '100%';
|
||||||
|
svgElement.style.height = 'auto';
|
||||||
|
svgElement.style.overflow = 'visible';
|
||||||
|
});
|
||||||
|
|
||||||
|
Array.prototype.forEach.call(
|
||||||
|
diagramContainer.querySelectorAll('foreignObject, .label, .label div, .edgeLabel, .nodeLabel, .nodeLabel p'),
|
||||||
|
function (node) {
|
||||||
|
if (node.tagName === 'FOREIGNOBJECT') {
|
||||||
|
node.style.overflow = 'visible';
|
||||||
|
}
|
||||||
|
if (node.tagName === 'DIV' || node.tagName === 'SPAN') {
|
||||||
|
node.style.whiteSpace = 'normal';
|
||||||
|
}
|
||||||
|
if (node.tagName === 'P') {
|
||||||
|
node.style.margin = '0';
|
||||||
|
node.style.lineHeight = '1.4';
|
||||||
|
}
|
||||||
|
if (node.classList && node.classList.contains('nodeLabel')) {
|
||||||
|
node.style.lineHeight = '1.4';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function renderMarkdownBlocks(target, options) {
|
function renderMarkdownBlocks(target, options) {
|
||||||
var renderOptions = options || {};
|
var renderOptions = options || {};
|
||||||
|
|
||||||
@@ -355,6 +422,7 @@
|
|||||||
|
|
||||||
tasks.push(new Promise(function (resolve, reject) {
|
tasks.push(new Promise(function (resolve, reject) {
|
||||||
var previewOptions = buildPreviewOptions(renderOptions, function () {
|
var previewOptions = buildPreviewOptions(renderOptions, function () {
|
||||||
|
decorateRenderedPreview(element);
|
||||||
if (typeof renderOptions.afterEach === 'function') {
|
if (typeof renderOptions.afterEach === 'function') {
|
||||||
renderOptions.afterEach(element, source);
|
renderOptions.afterEach(element, source);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,14 +24,57 @@ if ($pr_flag) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.copy {
|
.copy {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
min-width: 68px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
color: #4d4d4d;
|
font-weight: 600;
|
||||||
background-color: white;
|
color: #2f4f7f;
|
||||||
padding: 2px 8px;
|
background: rgba(255, 255, 255, 0.96);
|
||||||
margin: 8px;
|
padding: 6px 12px;
|
||||||
border-radius: 4px;
|
margin: 0;
|
||||||
|
border: 1px solid #c8d3e6;
|
||||||
|
border-radius: 999px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.05), 0 2px 4px rgba(0, 0, 0, 0.05);
|
box-shadow: 0 4px 10px rgba(15, 23, 42, 0.08);
|
||||||
|
}
|
||||||
|
|
||||||
|
.copy:hover {
|
||||||
|
background: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sample-header {
|
||||||
|
display: flex !important;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sample-box {
|
||||||
|
border: 1px solid #cfd7e6 !important;
|
||||||
|
background: linear-gradient(180deg, #f9fbff 0%, #f3f7ff 100%) !important;
|
||||||
|
box-shadow: 0 8px 20px rgba(15, 23, 42, 0.06);
|
||||||
|
}
|
||||||
|
|
||||||
|
.sample-box pre {
|
||||||
|
margin: 0;
|
||||||
|
padding: 16px 18px;
|
||||||
|
overflow: auto;
|
||||||
|
background: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sample-box code {
|
||||||
|
display: block;
|
||||||
|
font-family: "Cascadia Mono", "JetBrains Mono", Consolas, "Courier New", monospace;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hustoj-md-io-label {
|
||||||
|
margin: 12px 0 8px;
|
||||||
|
font-weight: 600;
|
||||||
|
color: #3d4d66;
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
@@ -213,12 +256,12 @@ if ($pr_flag) {
|
|||||||
<?php if (strlen($sinput) > 0 && $sinput != "\n" || isset($_GET['spa'])) { ?>
|
<?php if (strlen($sinput) > 0 && $sinput != "\n" || isset($_GET['spa'])) { ?>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<h4 class="ui top attached block header"><?php echo $MSG_Sample_Input ?>
|
<h4 class="ui top attached block header sample-header"><?php echo $MSG_Sample_Input ?>
|
||||||
<span class="copy" id="copyin"
|
<span class="copy" id="copyin"
|
||||||
data-clipboard-text="<?php echo htmlentities($sinput, ENT_QUOTES, 'UTF-8'); ?>"><?php echo $MSG_COPY; ?></span>
|
data-clipboard-text="<?php echo htmlentities($sinput, ENT_QUOTES, 'UTF-8'); ?>"><?php echo $MSG_COPY; ?></span>
|
||||||
</h4>
|
</h4>
|
||||||
<!-- <span class=copy id=\"copyin\" data-clipboard-text=\"".($sinput)."\"><?php echo $MSG_COPY; ?></span> -->
|
<!-- <span class=copy id=\"copyin\" data-clipboard-text=\"".($sinput)."\"><?php echo $MSG_COPY; ?></span> -->
|
||||||
<div class="ui bottom attached segment font-content">
|
<div class="ui bottom attached segment font-content sample-box">
|
||||||
<!-- <pre><?php echo ($sinput); ?></pre> -->
|
<!-- <pre><?php echo ($sinput); ?></pre> -->
|
||||||
<pre
|
<pre
|
||||||
style="margin-top: 0; margin-bottom: 0; "><code id='sinput' class="lang-plain"><?php echo ($sinput); ?></code></pre>
|
style="margin-top: 0; margin-bottom: 0; "><code id='sinput' class="lang-plain"><?php echo ($sinput); ?></code></pre>
|
||||||
@@ -229,12 +272,12 @@ if ($pr_flag) {
|
|||||||
<?php if (strlen($soutput) > 0 && $soutput != "\n" || isset($_GET['spa'])) { ?>
|
<?php if (strlen($soutput) > 0 && $soutput != "\n" || isset($_GET['spa'])) { ?>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="column">
|
<div class="column">
|
||||||
<h4 class="ui top attached block header"><?php echo $MSG_Sample_Output ?>
|
<h4 class="ui top attached block header sample-header"><?php echo $MSG_Sample_Output ?>
|
||||||
<span class="copy" id="copyout"
|
<span class="copy" id="copyout"
|
||||||
data-clipboard-text="<?php echo htmlentities($soutput, ENT_QUOTES, 'UTF-8'); ?>"><?php echo $MSG_COPY; ?></span>
|
data-clipboard-text="<?php echo htmlentities($soutput, ENT_QUOTES, 'UTF-8'); ?>"><?php echo $MSG_COPY; ?></span>
|
||||||
</h4>
|
</h4>
|
||||||
<!-- <span class=copy id=\"copyout\" data-clipboard-text=\"".($soutput)."\"><?php echo $MSG_COPY; ?></span> -->
|
<!-- <span class=copy id=\"copyout\" data-clipboard-text=\"".($soutput)."\"><?php echo $MSG_COPY; ?></span> -->
|
||||||
<div class="ui bottom attached segment font-content">
|
<div class="ui bottom attached segment font-content sample-box">
|
||||||
<!-- <div class="ui existing segment"> -->
|
<!-- <div class="ui existing segment"> -->
|
||||||
<pre
|
<pre
|
||||||
style="margin-top: 0; margin-bottom: 0; "><code id='soutput' class="lang-plain"><?php echo ($soutput); ?></code></pre>
|
style="margin-top: 0; margin-bottom: 0; "><code id='soutput' class="lang-plain"><?php echo ($soutput); ?></code></pre>
|
||||||
|
|||||||
@@ -2,9 +2,26 @@
|
|||||||
<?php include("template/$OJ_TEMPLATE/header.php");?>
|
<?php include("template/$OJ_TEMPLATE/header.php");?>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
|
#frmSolution {
|
||||||
|
width: 100%;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
|
||||||
#source {
|
#source {
|
||||||
width: 80%;
|
display: block;
|
||||||
|
width: 100% !important;
|
||||||
height: 600px;
|
height: 600px;
|
||||||
|
margin: 14px 0 0 !important;
|
||||||
|
text-align: left !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hustoj-vditor-code,
|
||||||
|
.hustoj-vditor-code .vditor,
|
||||||
|
.hustoj-vditor-code .vditor-content,
|
||||||
|
.hustoj-vditor-code .vditor-reset,
|
||||||
|
.hustoj-vditor-code textarea {
|
||||||
|
width: 100% !important;
|
||||||
|
text-align: left !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ace-chrome .ace_marker-layer .ace_active-line{ /*当前行*/
|
.ace-chrome .ace_marker-layer .ace_active-line{ /*当前行*/
|
||||||
@@ -412,6 +429,8 @@ function reloadtemplate(lang){
|
|||||||
document.cookie="lastlang="+lang;
|
document.cookie="lastlang="+lang;
|
||||||
var url=window.location.href;
|
var url=window.location.href;
|
||||||
var i=url.indexOf("sid=");
|
var i=url.indexOf("sid=");
|
||||||
|
if(lang!=<?php echo $lastlang?>)
|
||||||
|
autoSave(<?php echo $lastlang ?>);
|
||||||
switchLang(lang);
|
switchLang(lang);
|
||||||
if(lang!=<?php echo $lastlang?>)
|
if(lang!=<?php echo $lastlang?>)
|
||||||
document.location.href=url;
|
document.location.href=url;
|
||||||
@@ -471,11 +490,21 @@ function loadFromBlockly(){
|
|||||||
fontSize: "18px"
|
fontSize: "18px"
|
||||||
});
|
});
|
||||||
reloadtemplate($("#language").val());
|
reloadtemplate($("#language").val());
|
||||||
function autoSave(){
|
function getSourceDraftKey(languageOverride){
|
||||||
|
let language=languageOverride;
|
||||||
|
if(language===undefined||language===null||language===""){
|
||||||
|
language=$("#language").val();
|
||||||
|
}
|
||||||
|
if(language===undefined||language===null||language===""){
|
||||||
|
language="<?php echo $lastlang ?>";
|
||||||
|
}
|
||||||
|
return "<?php echo $_SESSION[$OJ_NAME.'_user_id']?>source:"+location.href+":lang:"+language;
|
||||||
|
}
|
||||||
|
function autoSave(languageOverride){
|
||||||
var mark="<?php echo isset($id)?'problem_id':'cid';?>";
|
var mark="<?php echo isset($id)?'problem_id':'cid';?>";
|
||||||
var problem_id=$("#"+mark).val();
|
var problem_id=$("#"+mark).val();
|
||||||
if(!!localStorage){
|
if(!!localStorage){
|
||||||
let key="<?php echo $_SESSION[$OJ_NAME.'_user_id']?>source:"+location.href;
|
let key=getSourceDraftKey(languageOverride);
|
||||||
if(typeof(editor) != "undefined")
|
if(typeof(editor) != "undefined")
|
||||||
$("#hide_source").val(editor.getValue());
|
$("#hide_source").val(editor.getValue());
|
||||||
localStorage.setItem(key,$("#hide_source").val());
|
localStorage.setItem(key,$("#hide_source").val());
|
||||||
@@ -486,7 +515,7 @@ function loadFromBlockly(){
|
|||||||
$("#source").css("height",window.innerHeight-180);
|
$("#source").css("height",window.innerHeight-180);
|
||||||
if($("#vcode")!=undefined) $("#vcode").click();
|
if($("#vcode")!=undefined) $("#vcode").click();
|
||||||
if(!!localStorage){
|
if(!!localStorage){
|
||||||
let key="<?php echo $_SESSION[$OJ_NAME.'_user_id']?>source:"+location.href;
|
let key=getSourceDraftKey();
|
||||||
let saved=localStorage.getItem(key);
|
let saved=localStorage.getItem(key);
|
||||||
if(saved!=null&&saved!=""&&saved.length>editor.getValue().length){
|
if(saved!=null&&saved!=""&&saved.length>editor.getValue().length){
|
||||||
//let load=confirm("发现自动保存的源码,是否加载?(仅有一次机会)");
|
//let load=confirm("发现自动保存的源码,是否加载?(仅有一次机会)");
|
||||||
|
|||||||
Reference in New Issue
Block a user