Skip to content

Commit 9d240de

Browse files
committed
Merge remote-tracking branch 'origin/dev' into iss1703
2 parents ba16b58 + ecc7d01 commit 9d240de

36 files changed

Lines changed: 512 additions & 1503 deletions

api/controller/RenderController.php

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -145,35 +145,68 @@ public function __invoke(Request $request, Response $response, array $args): Res
145145
// Request for full rendering. We replace placeholders with input renders and basic feedback and validation divs.
146146
// Iframes are rendered but will still need to be registered on the front end.
147147
$uri = $request->getUri();
148-
$baseurl = $uri->getScheme() . '://' . $uri->getHost();
149-
$port = $uri->getPort();
150-
if ($port && !in_array($port, [80, 443], true)) {
151-
$baseurl .= ':' . $port;
148+
if ($uri) {
149+
$baseurl = $uri->getScheme() . '://' . $uri->getHost();
150+
$port = $uri->getPort();
151+
if ($port && !in_array($port, [80, 443], true)) {
152+
$baseurl .= ':' . $port;
153+
}
154+
} else {
155+
// Older versions of Moodle don't have UriInterface as part of PSR.
156+
// We don't really care as this code isn't run via Moodle but unit
157+
// tests fail without a fallback.
158+
$baseurl = '';
152159
}
153160

154161
[$validationprefix, $feedbackprefix] = $data['fullRender'];
155162
$validationprefix = trim($validationprefix);
156163
$feedbackprefix = trim($feedbackprefix);
157164
preg_match_all('/\[\[input:([^\]]*)\]\]/', $renderresponse->questionrender, $inputtags);
158165
foreach ($inputtags[1] as $tag) {
159-
$renderresponse->questionrender = str_replace("[[input:{$tag}]]", $renderresponse->questioninputs->$tag->render, $renderresponse->questionrender);
160-
$renderresponse->questionrender = str_replace("[[validation:{$tag}]]", "<span name='{$validationprefix}{$tag}'></span>", $renderresponse->questionrender);
166+
$renderresponse->questionrender = str_replace(
167+
"[[input:{$tag}]]",
168+
$renderresponse->questioninputs->$tag->render,
169+
$renderresponse->questionrender
170+
);
171+
$renderresponse->questionrender = str_replace(
172+
"[[validation:{$tag}]]",
173+
"<span name='{$validationprefix}{$tag}'></span>",
174+
$renderresponse->questionrender
175+
);
161176
}
162177
foreach ($renderresponse->iframes as $iframe) {
163178
$iframe[1] = str_replace('<head>', "<head><base href=\"{$baseurl}\" />", $iframe[1]);
164-
$renderediframe = "<iframe id=\"{$iframe[0]}\" style=\"width: 100%; height: 100%; border: 0;" . ($iframe[4] === 'false' ? ' overflow: hidden;' : '') . "\" scrolling=\"" . ($iframe[4] === 'false' ? 'no' : 'yes') . "\" title=\"{$iframe[4]}\" referrerpolicy=\"no-referrer\" " . (!$iframe[5] ? 'allow-scripts allow-downloads ' : '') . "srcdoc=\"" . htmlentities($iframe[1]) . "\"></iframe>";
165-
$renderresponse->questionrender = str_replace("id=\"{$iframe[2]}\"></div>", "id=\"{$iframe[2]}\">{$renderediframe}</div>", $renderresponse->questionrender);
166-
$renderresponse->questionsamplesolutiontext = str_replace("id=\"{$iframe[2]}\"></div>", "id=\"{$iframe[2]}\">{$renderediframe}</div>", $renderresponse->questionsamplesolutiontext);
179+
$renderediframe = "<iframe id=\"{$iframe[0]}\" style=\"width: 100%; height: 100%; border: 0;" .
180+
($iframe[4] === 'false' ? ' overflow: hidden;' : '') . "\" scrolling=\"" .
181+
($iframe[4] === 'false' ? 'no' : 'yes') .
182+
"\" title=\"{$iframe[4]}\" referrerpolicy=\"no-referrer\" " .
183+
(!$iframe[5] ? 'allow-scripts allow-downloads ' : '') .
184+
"srcdoc=\"" . htmlentities($iframe[1]) . "\"></iframe>";
185+
$renderresponse->questionrender = str_replace(
186+
"id=\"{$iframe[2]}\"></div>",
187+
"id=\"{$iframe[2]}\">{$renderediframe}</div>",
188+
$renderresponse->questionrender
189+
);
190+
$renderresponse->questionsamplesolutiontext = str_replace(
191+
"id=\"{$iframe[2]}\"></div>", "id=\"{$iframe[2]}\">{$renderediframe}</div>",
192+
$renderresponse->questionsamplesolutiontext
193+
);
167194
}
168195
foreach ($renderresponse->questionassets as $name => $file) {
169196
$renderresponse->questionrender = str_replace($name, "{$baseurl}/plots/{$file}", $renderresponse->questionrender);
170-
$renderresponse->questionsamplesolutiontext = str_replace($name, "{$baseurl}/plots/{$file}", $renderresponse->questionsamplesolutiontext);
197+
$renderresponse->questionsamplesolutiontext = str_replace(
198+
$name,
199+
"{$baseurl}/plots/{$file}", $renderresponse->questionsamplesolutiontext
200+
);
171201
foreach ($renderresponse->questioninputs as $input) {
172202
$input->samplesolutionrender = str_replace($name, "{$baseurl}/plots/{$file}", $input->samplesolutionrender);
173203
}
174204
}
175205
$renderresponse->questionrender = $this->replace_feedback_tags($renderresponse->questionrender, $feedbackprefix);
176-
$renderresponse->questionsamplesolutiontext = $this->replace_feedback_tags($renderresponse->questionsamplesolutiontext, $feedbackprefix);
206+
$renderresponse->questionsamplesolutiontext = $this->replace_feedback_tags(
207+
$renderresponse->questionsamplesolutiontext,
208+
$feedbackprefix
209+
);
177210
}
178211

179212
$response->getBody()->write(json_encode($renderresponse));

api/public/cors.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,11 @@
3939
$scriptname = urldecode($_GET['name']);
4040
$corslocation = dirname($CFG->dirroot) . '/corsscripts/';
4141
$questionlocation = dirname($CFG->dirroot) . '/samplequestions/';
42-
43-
if (!str_starts_with(realpath($scriptname), $corslocation) && !str_starts_with(realpath($corslocation . $scriptname), $corslocation)) {
42+
if (
43+
!str_starts_with(realpath($scriptname), $corslocation)
44+
&& !str_starts_with(realpath($corslocation . $scriptname), $corslocation)
45+
&& $scriptname !== 'styles.css'
46+
) {
4447
// Give a special exception for sample questions.
4548
if (!($is_question && str_starts_with(realpath($questionlocation . $scriptname), $questionlocation))) {
4649
die("No such script here.");

api/public/stackshared.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,12 +105,15 @@ function send() {
105105
correctAnswers += `\\[{${input.samplesolutionrender}}\\]`;
106106
}
107107
if (input.samplesolution) {
108-
correctAnswers += `, which can be typed as follows: `;
108+
let answerOutput = "";
109109
for (const [name, solution] of Object.entries(input.samplesolution)) {
110-
if (name.indexOf('_val') === -1) {
111-
correctAnswers += `<span class='correct-answer'>${solution.replace(/\n/g, '<br>')}</span>`;
110+
if (name.indexOf('_val') === -1 && !(typeof solution === 'string' && solution.startsWith('[[{"used":'))) {
111+
answerOutput += `<span class='correct-answer'>${solution.replace(/\n/g, '<br>')}</span>`;
112112
}
113113
}
114+
if (answerOutput) {
115+
correctAnswers += `, which can be typed as follows: ` + answerOutput;
116+
}
114117
}
115118
correctAnswers += '.</p>';
116119
} else if (name !== 'remember' && input.samplesolution) {

cli/stack_maxima_compiler.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,6 @@ function comment_annotations(string $comment): array {
416416
false
417417
);
418418

419-
420419
$ast = null;
421420
try {
422421
$ast = $parser->parse($po->get_lexer($content));
@@ -641,7 +640,7 @@ function comment_annotations(string $comment): array {
641640
$doc = '<!-- NOTE! This file is autogenerated from files under stack/maximasrc do not edit here. -->';
642641
$rootlink = str_repeat('../', substr_count($path, '/'));
643642

644-
$doc .= "\n# Section documentation for [STACK-Maxima]($rootlink) $path\n\n";
643+
$doc .= "\n# Section documentation for [STACK-Maxima]({$rootlink}index.md) $path\n\n";
645644

646645

647646
if ($node->description !== '') {

doc/en/Authoring/Accessibility​.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Authoring accessible STACK questions is simpler than writing accessible material
1010
However, this is not the whole picture. Colleagues must still consider accessibility when authoring questions.
1111

1212
Please consider/check the following key points:
13+
1314
* Images:
1415
* If inserting a screenshot, consider if you could format the information you wish to communicate using HTML, e.g. code snippets and mathematical equations.
1516
* Add meaningful alternative text to all non-text objects, in particular images. This can be done using `<img src="/path/to.img.jpg" alt="Alt text">` in HTML, or `![Alt text](/path/to/img.jpg)` in markdown.
@@ -25,3 +26,4 @@ Please consider/check the following key points:
2526
* Consider users may be using keyboard navigation, be careful with interactive assesseed tasks requiring the user to click on the board to add points. Add an `add point` button.
2627

2728
Detailed guidance on digital accessibility is given by the WCAG 2.1 Accessibility Guidelines.
29+

doc/en/Authoring/Languages.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Multilingual content can be developed using two systems.
55
1. The multilang-filter that comes with Moodle.
66
2. STACK's own language blocks (recommended).
77

8-
Please note that the TinyMCE editor considers paragraph tags (`<p>..</p>`) inside any span tags (e.g. `<span lang="en" class="multilang">...</span>`) to be invalud. The TinyMCE editor will potentially "clean up" (i.e. ruin) your multilingual content if using both the Moodle multilang filter and TinyMCE(as of June 2024). This is a known issue, and one reason we recommend against using TinyMCE for editing STACK content. (It does nasty things to Javascript content as well).
8+
Please note that the TinyMCE editor considers paragraph tags (`<p>..</p>`) inside any span tags (e.g. `<span lang="en" class="multilang">...</span>`) to be invalid. The TinyMCE editor will potentially "clean up" (i.e. ruin) your multilingual content if using both the Moodle multilang filter and TinyMCE (as of June 2024). This is a known issue, and one reason we recommend against using TinyMCE for editing STACK content. (It does nasty things to Javascript content as well).
99

1010
## Using the built-in castext block in STACK
1111

doc/en/Authoring/Question_blocks/Dynamic_blocks.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,3 +159,4 @@ input.addEventListener("change", () => {
159159
});
160160
[[/javascript]]
161161
```
162+
Do note that the use of `input-ref-...` attributes will lead to rewriting parts of the JavaScript code. Basically, the contents of the block are wrapped as a function that will be called after the input references have been fully registered. During that wrapping, all `import`-statements in that code will be lifted outside of that function, that lifting is unaware of JS-comments. If such rewriting causes trouble for your logic, you may choose to not use the `input-ref-...` feature and instead do any access to inputs through [STACK-JS](../../Specialist_tools/STACK-JS/index.md). No rewriting happens, if those attributes are not used.

doc/en/CAS/Library/basen/binary/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!-- NOTE! This file is autogenerated from files under stack/maximasrc do not edit here. -->
2-
# Section documentation for [STACK-Maxima](../../) /basen/binary
2+
# Section documentation for [STACK-Maxima](../../index.md) /basen/binary
33

44
Functions specific for working with binary [`stackbasen`](../index.md#stackbasen) objects.
55

doc/en/CAS/Library/basen/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!-- NOTE! This file is autogenerated from files under stack/maximasrc do not edit here. -->
2-
# Section documentation for [STACK-Maxima](../) /basen
2+
# Section documentation for [STACK-Maxima](../index.md) /basen
33

44
A collection of functions meant for dealing with base-N numbers coming
55
through the expanded syntax mode and being presented as inert functions.

doc/en/CAS/Library/expressions/extraction/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!-- NOTE! This file is autogenerated from files under stack/maximasrc do not edit here. -->
2-
# Section documentation for [STACK-Maxima](../../) /expressions/extraction
2+
# Section documentation for [STACK-Maxima](../../index.md) /expressions/extraction
33

44
Functions for extracting parts from expressions, i.e., trees of operations.
55

0 commit comments

Comments
 (0)