43
43
44
44
class TwigExtension extends AbstractExtension implements GlobalsInterface
45
45
{
46
+ /**
47
+ * @param array<int, bool> $renderedSources
48
+ */
46
49
public function __construct (
47
50
protected readonly DOMJudgeService $ dj ,
48
51
protected readonly ConfigurationService $ config ,
@@ -55,7 +58,8 @@ public function __construct(
55
58
protected readonly AuthorizationCheckerInterface $ authorizationChecker ,
56
59
protected readonly RouterInterface $ router ,
57
60
#[Autowire('%kernel.project_dir% ' )]
58
- protected readonly string $ projectDir
61
+ protected readonly string $ projectDir ,
62
+ protected array $ renderedSources = []
59
63
) {}
60
64
61
65
public function getFunctions (): array
@@ -917,23 +921,47 @@ public function codeEditor(
917
921
sprintf ($ editor , $ code , $ editable ? 'false ' : 'true ' , $ mode , $ extraForEdit ));
918
922
}
919
923
924
+ /**
925
+ * Gets the JavaScript to get a Monaco model instance for the submission file.
926
+ * Renders the source code of the file as Monaco model, if not already rendered.
927
+ * @return string The JavaScript source assignable to a model variable.
928
+ */
929
+ public function getMonacoModel (SubmissionFile $ file ): string
930
+ {
931
+ if (array_key_exists ($ file ->getSubmitfileid (), $ this ->renderedSources )) {
932
+ return sprintf (
933
+ <<<JS
934
+ monaco.editor.getModel(monaco.Uri.parse("diff/%d/%s"));
935
+ JS ,
936
+ $ file ->getSubmitfileid (),
937
+ $ file ->getFilename (),
938
+ );
939
+ }
940
+ $ this ->renderedSources [$ file ->getSubmitfileid ()] = true ;
941
+
942
+ return sprintf (
943
+ <<<JS
944
+ monaco.editor.createModel(
945
+ "%s",
946
+ undefined,
947
+ monaco.Uri.parse("diff/%d/%s")
948
+ );
949
+ JS ,
950
+ $ this ->twig ->getRuntime (EscaperRuntime::class)->escape ($ file ->getSourcecode (), 'js ' ),
951
+ $ file ->getSubmitfileid (),
952
+ $ file ->getFilename (),
953
+ );
954
+ }
955
+
920
956
public function showDiff (string $ id , SubmissionFile $ newFile , SubmissionFile $ oldFile ): string
921
957
{
922
958
$ editor = <<<HTML
923
959
<div class="editor" id="__EDITOR__"></div>
924
960
<script>
925
961
$(function() {
926
962
require(['vs/editor/editor.main'], function () {
927
- const originalModel = monaco.editor.createModel(
928
- "%s",
929
- undefined,
930
- monaco.Uri.parse("diff-old/%s")
931
- );
932
- const modifiedModel = monaco.editor.createModel(
933
- "%s",
934
- undefined,
935
- monaco.Uri.parse("diff-new/%s")
936
- );
963
+ const originalModel = %s
964
+ const modifiedModel = %s
937
965
938
966
const initialDiffMode = getDiffMode();
939
967
const radios = $("#diffselect-__EDITOR__ > input[name='__EDITOR__-mode']");
@@ -988,10 +1016,8 @@ public function showDiff(string $id, SubmissionFile $newFile, SubmissionFile $ol
988
1016
989
1017
return sprintf (
990
1018
str_replace ('__EDITOR__ ' , $ id , $ editor ),
991
- $ this ->twig ->getRuntime (EscaperRuntime::class)->escape ($ oldFile ->getSourcecode (), 'js ' ),
992
- $ oldFile ->getFilename (),
993
- $ this ->twig ->getRuntime (EscaperRuntime::class)->escape ($ newFile ->getSourcecode (), 'js ' ),
994
- $ newFile ->getFilename (),
1019
+ $ this ->getMonacoModel ($ oldFile ),
1020
+ $ this ->getMonacoModel ($ newFile ),
995
1021
);
996
1022
}
997
1023
0 commit comments