4343
4444class TwigExtension extends AbstractExtension implements GlobalsInterface
4545{
46+ /**
47+ * @param array<int, bool> $renderedSources
48+ */
4649 public function __construct (
4750 protected readonly DOMJudgeService $ dj ,
4851 protected readonly ConfigurationService $ config ,
@@ -55,7 +58,8 @@ public function __construct(
5558 protected readonly AuthorizationCheckerInterface $ authorizationChecker ,
5659 protected readonly RouterInterface $ router ,
5760 #[Autowire('%kernel.project_dir% ' )]
58- protected readonly string $ projectDir
61+ protected readonly string $ projectDir ,
62+ protected array $ renderedSources = []
5963 ) {}
6064
6165 public function getFunctions (): array
@@ -917,23 +921,47 @@ public function codeEditor(
917921 sprintf ($ editor , $ code , $ editable ? 'false ' : 'true ' , $ mode , $ extraForEdit ));
918922 }
919923
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+
920956 public function showDiff (string $ id , SubmissionFile $ newFile , SubmissionFile $ oldFile ): string
921957 {
922958 $ editor = <<<HTML
923959<div class="editor" id="__EDITOR__"></div>
924960<script>
925961$(function() {
926962 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
937965
938966 const initialDiffMode = getDiffMode();
939967 const radios = $("#diffselect-__EDITOR__ > input[name='__EDITOR__-mode']");
@@ -988,10 +1016,8 @@ public function showDiff(string $id, SubmissionFile $newFile, SubmissionFile $ol
9881016
9891017 return sprintf (
9901018 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 ),
9951021 );
9961022 }
9971023
0 commit comments