From fad01eef66910f51a2507aa96ac7475e8a7d295c Mon Sep 17 00:00:00 2001 From: Baoshuo Date: Tue, 14 Mar 2023 16:55:11 +0800 Subject: [PATCH 1/3] feat: add UOJForm::addMarkdownEditor() --- .../controllers/subdomain/api/markdown.php | 24 +++ web/app/controllers/subdomain/api/route.php | 5 + web/app/models/UOJForm.php | 44 +++++ web/js/uoj.js | 156 +++++++++++++++++- 4 files changed, 226 insertions(+), 3 deletions(-) create mode 100644 web/app/controllers/subdomain/api/markdown.php diff --git a/web/app/controllers/subdomain/api/markdown.php b/web/app/controllers/subdomain/api/markdown.php new file mode 100644 index 0000000..2ff856a --- /dev/null +++ b/web/app/controllers/subdomain/api/markdown.php @@ -0,0 +1,24 @@ +purify($parsedown->line(UOJRequest::post('markdown', 'is_string'))); +} else { + $html = $purifier->purify($parsedown->text(UOJRequest::post('markdown', 'is_string'))); +} + +die($html); diff --git a/web/app/controllers/subdomain/api/route.php b/web/app/controllers/subdomain/api/route.php index e4bde77..bbbe0eb 100644 --- a/web/app/controllers/subdomain/api/route.php +++ b/web/app/controllers/subdomain/api/route.php @@ -6,9 +6,14 @@ call_user_func(function () { // to prevent variable scope leak 'domain' => UOJConfig::$data['web']['main']['host'], ], function () { + // Remote Judge Route::post("/api/remote_judge/custom_account_validator", '/subdomain/api/remote_judge/custom_account_validator.php'); + // Submission Route::any('/api/submission/submission_status_details', '/subdomain/api/submission/submission_status_details.php'); + + // Misc + Route::post('/api/markdown', '/subdomain/api/markdown.php'); } ); }); diff --git a/web/app/models/UOJForm.php b/web/app/models/UOJForm.php index 68e02a6..2371f34 100644 --- a/web/app/models/UOJForm.php +++ b/web/app/models/UOJForm.php @@ -507,6 +507,50 @@ class UOJForm { $this->config['has_file'] = true; } + public function addMarkdownEditor($name, $config = []) { + $config += [ + 'div_class' => '', + 'default_value' => '', + 'label' => '', + 'label_class' => 'form-label', + 'placeholder' => '', + 'help' => '', + 'help_class' => 'form-text', + 'validator_php' => function ($str, &$vdata) { + return ''; + }, + 'validator_js' => null, + ]; + + $html = ''; + $html .= HTML::tag_begin('div', ['class' => $config['div_class'], 'id' => "div-$name"]); + + $default_value = json_encode($config['default_value']); + + if ($config['label']) { + $html .= HTML::tag('label', [ + 'class' => $config['label_class'], + 'for' => "input-$name", + 'id' => "label-$name" + ], $config['label']); + } + + $html .= << + + EOD; + + if ($config['help']) { + $html .= HTML::tag('div', ['class' => $config['help_class']], $config['help']); + } + + $html .= HTML::tag_end('div'); + + $this->add($name, $html, $config['validator_php'], $config['validator_js']); + } + public function printHTML() { echo HTML::tag_begin('form', [ 'action' => UOJContext::requestURI(), diff --git a/web/js/uoj.js b/web/js/uoj.js index 4b3aef5..bece091 100644 --- a/web/js/uoj.js +++ b/web/js/uoj.js @@ -42,8 +42,16 @@ uojLocaleData = { }, "editor::upload from local": { "en": "Local file", - "zh-cn": "本地文件" - } + "zh-cn": "本地文件", + }, + "editor::edit": { + "en": "Edit", + "zh-cn": "编辑", + }, + "editor::preview": { + "en": "Preview", + "zh-cn": "预览", + }, }; function uojLocale(name) { @@ -873,7 +881,7 @@ $.fn.text_file_form_group = function(name, text) { monaco_editor_instance = monaco.editor.create(div_editor[0], { language: 'text', automaticLayout: true, - fontSize: "14px", + fontSize: "16px", }); $('#' + spinner_id).css('display', 'none !important'); @@ -1645,6 +1653,148 @@ function custom_test_onsubmit(response_text, div_result, url) { setTimeout(update, 500); } +// markdown input editor +$.fn.markdown_input_editor = function(name, type, text) { + return this.each(function() { + var input_editor_name = name; + var input_editor_id = 'input-' + name + '_editor'; + var spinner_id = 'spinner-' + name + '_editor'; + var div_editor_id = 'div-' + name + '_editor'; + var div_preview_id = 'div-' + name + '_preview'; + + var btn_editor = $('