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,48 @@ 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
+ * @param SubmissionFile $file The submission file to render
928
+ * @return string The JavaScript source assignable to a model variable.
929
+ */
930
+ public function getMonacoModel (SubmissionFile $ file ): string
931
+ {
932
+ if (array_key_exists ($ file ->getSubmitfileid (), $ this ->renderedSources )) {
933
+ return sprintf (
934
+ <<<JS
935
+ monaco.editor.getModel(monaco.Uri.parse("diff/%d/%s"));
936
+ JS ,
937
+ $ file ->getSubmitfileid (),
938
+ $ file ->getFilename (),
939
+ );
940
+ }
941
+ $ this ->renderedSources [$ file ->getSubmitfileid ()] = true ;
942
+
943
+ return sprintf (
944
+ <<<JS
945
+ monaco.editor.createModel(
946
+ "%s",
947
+ undefined,
948
+ monaco.Uri.parse("diff/%d/%s")
949
+ );
950
+ JS ,
951
+ $ this ->twig ->getRuntime (EscaperRuntime::class)->escape ($ file ->getSourcecode (), 'js ' ),
952
+ $ file ->getSubmitfileid (),
953
+ $ file ->getFilename (),
954
+ );
955
+ }
956
+
920
957
public function showDiff (string $ id , SubmissionFile $ newFile , SubmissionFile $ oldFile ): string
921
958
{
922
959
$ editor = <<<HTML
923
960
<div class="editor" id="__EDITOR__"></div>
924
961
<script>
925
962
$(function() {
926
963
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
- );
964
+ const originalModel = %s
965
+ const modifiedModel = %s
937
966
938
967
const initialDiffMode = getDiffMode();
939
968
const radios = $("#diffselect-__EDITOR__ > input[name='__EDITOR__-mode']");
@@ -988,10 +1017,8 @@ public function showDiff(string $id, SubmissionFile $newFile, SubmissionFile $ol
988
1017
989
1018
return sprintf (
990
1019
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 (),
1020
+ $ this ->getMonacoModel ($ oldFile ),
1021
+ $ this ->getMonacoModel ($ newFile ),
995
1022
);
996
1023
}
997
1024
0 commit comments