Skip to main content
Sign in
Snippets Groups Projects
Commit 33e95d94 authored by Chris Sangwin's avatar Chris Sangwin
Browse files

Code tidy.

parent d2e88af9
No related branches found
No related tags found
No related merge requests found
...@@ -44,12 +44,11 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { ...@@ -44,12 +44,11 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block {
// Define iframe params. // Define iframe params.
$xpars = []; $xpars = [];
$inputs = []; // From inputname to variable name. $inputs = []; // From inputname to variable name.
$clone = "false"; // whether to have all keys in available list cloned $clone = "false"; // Whether to have all keys in available list cloned.
foreach ($this->params as $key => $value) { foreach ($this->params as $key => $value) {
if ($key === 'clone') { if ($key === 'clone') {
$clone = $value; $clone = $value;
} } else if ($key !== 'input') {
else if ($key !== 'input') {
$xpars[$key] = $value; $xpars[$key] = $value;
} else { } else {
$inputs[$key] = $value; $inputs[$key] = $value;
...@@ -69,8 +68,8 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { ...@@ -69,8 +68,8 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block {
unset($xpars['orientation']); unset($xpars['orientation']);
} }
// Set default width and height here, we want to push forward to overwrite the iframe defaults // Set default width and height here.
// if they are not provided in the block parameters // We want to push forward to overwrite the iframe defaults if they are not provided in the block parameters.
$width = array_key_exists('width', $xpars) ? $xpars['width'] : "100%"; $width = array_key_exists('width', $xpars) ? $xpars['width'] : "100%";
// TODO: set default based on number of proof steps // TODO: set default based on number of proof steps
/*$opt2 = []; /*$opt2 = [];
...@@ -148,27 +147,28 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { ...@@ -148,27 +147,28 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block {
$orientation = isset($this->params['orientation']) ? $this->params['orientation'] : 'horizontal'; $orientation = isset($this->params['orientation']) ? $this->params['orientation'] : 'horizontal';
$outer = $orientation === 'horizontal' ? 'row' : 'col'; $outer = $orientation === 'horizontal' ? 'row' : 'col';
$inner = $orientation === 'horizontal' ? 'col' : 'row'; $inner = $orientation === 'horizontal' ? 'col' : 'row';
$innerUl = '<ul class="list-group ' . $inner . '" id="usedList"></ul> $innerui = '<ul class="list-group ' . $inner . '" id="usedList"></ul>
<ul class="list-group ' . $inner . '" id="availableList"></ul>'; <ul class="list-group ' . $inner . '" id="availableList"></ul>';
if ($clone === 'true') { if ($clone === 'true') {
$innerUl .= '<ul class="list-group ' . $inner . '" id="bin"></ul>'; $innerui .= '<ul class="list-group ' . $inner . '" id="bin"></ul>';
} }
$r->items[] = new MP_String('<button> Orientation </button>'); $r->items[] = new MP_String('<button> Orientation </button>');
$r->items[] = new MP_String('<div class="container" style="' . $astyle . '"> $r->items[] = new MP_String('<div class="container" style="' . $astyle . '">
<div class=row>' . $innerUl . ' <div class=row>' . $innerui . '
</div> </div>
</div>'); </div>');
// JS script. // JS script.
$r->items[] = new MP_String('<script type="module">'); $r->items[] = new MP_String('<script type="module">');
$importCode = "\nimport {stack_js} from '" . stack_cors_link('stackjsiframe.min.js') . "';\n"; $importcode = "\nimport {stack_js} from '" . stack_cors_link('stackjsiframe.min.js') . "';\n";
$importCode .= "import {Sortable} from '" . stack_cors_link('sortable.min.js') . "';\n"; $importcode .= "import {Sortable} from '" . stack_cors_link('sortable.min.js') . "';\n";
$importCode .= "import {preprocess_steps, stack_sortable, add_orientation_listener} from '" . stack_cors_link('stacksortable.min.js') . "';\n"; $importcode .= "import {preprocess_steps, stack_sortable, add_orientation_listener} from '" .
$r->items[] = new MP_String($importCode); stack_cors_link('stacksortable.min.js') . "';\n";
// TODO :automatically set orientation based on device $r->items[] = new MP_String($importcode);
// TODO :automatically set orientation based on device.
$r->items[] = new MP_String('add_orientation_listener();' . "\n"); $r->items[] = new MP_String('add_orientation_listener();' . "\n");
// Extract the proof steps from the inner content // Extract the proof steps from the inner content.
$r->items[] = new MP_String('var proofSteps = '); $r->items[] = new MP_String('var proofSteps = ');
$opt2 = []; $opt2 = [];
...@@ -178,49 +178,52 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { ...@@ -178,49 +178,52 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block {
$opt2['in iframe'] = true; $opt2['in iframe'] = true;
foreach ($this->children as $item) { foreach ($this->children as $item) {
// Assume that all code inside is JavaScript and that we do not // Assume that all code inside is JavaScript.
// want to do the markdown escaping or any other in it. // Assume we do not want to do the markdown escaping or any other in it.
$c = $item->compile(castext2_parser_utils::RAWFORMAT, $opt2); $c = $item->compile(castext2_parser_utils::RAWFORMAT, $opt2);
if ($c !== null) { if ($c !== null) {
$r->items[] = $c; $r->items[] = $c;
} }
} }
// parse steps and Sortable options separately if they exist // Parse steps and Sortable options separately if they exist.
$code = 'var userOpts;' . "\n"; $code = 'var userOpts;' . "\n";
$code .= '[proofSteps, userOpts] = preprocess_steps(proofSteps, userOpts);' . "\n"; $code .= '[proofSteps, userOpts] = preprocess_steps(proofSteps, userOpts);' . "\n";
// Link up to STACK inputs // Link up to STACK inputs.
if (count($inputs) > 0) { if (count($inputs) > 0) {
$code .= 'var inputPromise = stack_js.request_access_to_input("' . $this->params['input'] . '", true);' . "\n"; $code .= 'var inputPromise = stack_js.request_access_to_input("' . $this->params['input'] . '", true);';
$code .= "\n";
$code .= 'inputPromise.then((id) => {' . "\n"; $code .= 'inputPromise.then((id) => {' . "\n";
} else { } else {
$code .= 'var id;' . "\n"; $code .= 'var id;' . "\n";
}; };
// Instantiate STACK sortable helper class. // Instantiate STACK sortable helper class.
$code .= 'const stackSortable = new stack_sortable(proofSteps, "availableList", "usedList", id, userOpts, "' . $clone .'");' . "\n"; $code .= 'const stackSortable = new stack_sortable(proofSteps, "availableList", "usedList", id, userOpts, "' .
$clone .'");' . "\n";
// Generate the two lists in HTML. // Generate the two lists in HTML.
$code .= 'stackSortable.generate_used();' . "\n"; $code .= 'stackSortable.generate_used();' . "\n";
$code .= 'stackSortable.generate_available();' . "\n"; $code .= 'stackSortable.generate_available();' . "\n";
// Create the Sortable objects.
$code .= 'var usedOpts = {...stackSortable.options.used, ...{onSort: () => ' .
// Create the Sortable objects '{stackSortable.update_state(sortableUsed, sortableAvailable);}}}' . "\n";
$code .= 'var usedOpts = {...stackSortable.options.used, ...{onSort: () => {stackSortable.update_state(sortableUsed, sortableAvailable);}}}' . "\n"; $code .= 'var availableOpts = {...stackSortable.options.available, ' .
$code .= 'var availableOpts = {...stackSortable.options.available, ...{onSort: () => {stackSortable.update_state(sortableUsed, sortableAvailable);}}}' . "\n"; '...{onSort: () => {stackSortable.update_state(sortableUsed, sortableAvailable);}}}' . "\n";
$code .= 'var sortableUsed = Sortable.create(usedList, usedOpts);' . "\n"; $code .= 'var sortableUsed = Sortable.create(usedList, usedOpts);' . "\n";
$code .= 'var sortableAvailable = Sortable.create(availableList, availableOpts);' . "\n"; $code .= 'var sortableAvailable = Sortable.create(availableList, availableOpts);' . "\n";
// Create bin for clone mode // Create bin for clone mode.
if ($clone === "true") { if ($clone === "true") {
$code .= 'var sortableBin = Sortable.create(bin, {group: {name: "sortableBin", pull: false, put: "sortableUsed"}, onAdd: (e) => {document.getElementById("bin").removeChild(e.item);}});' . "\n"; $code .= 'var sortableBin = Sortable.create(bin, {group: {name: "sortableBin", pull: false, put: ' .
'"sortableUsed"}, onAdd: (e) => {document.getElementById("bin").removeChild(e.item);}});' . "\n";
} }
// Add double-click events // Add double-click events.
$code .= 'stackSortable.update_state_dblclick(sortableUsed, sortableAvailable);' . "\n"; $code .= 'stackSortable.update_state_dblclick(sortableUsed, sortableAvailable);' . "\n";
// Typeset MathJax // Typeset MathJax.
$code .= 'MathJax.Hub.Queue(["Typeset", MathJax.Hub]);' . "\n"; $code .= 'MathJax.Hub.Queue(["Typeset", MathJax.Hub]);' . "\n";
if (count($inputs) > 0) { if (count($inputs) > 0) {
...@@ -247,7 +250,7 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { ...@@ -247,7 +250,7 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block {
} }
public function validate_JSON_contents($contents) : bool { public function validate_JSON_contents($contents) : bool {
// TODO : check steps are reasonable // TODO : check steps are reasonable.
$val_types = array_unique(array_map('gettype', array_values($contents))); $val_types = array_unique(array_map('gettype', array_values($contents)));
return array_keys($contents) === ["steps", "options"] || (count($val_types) == 1 && $val_types[0] == "string"); return array_keys($contents) === ["steps", "options"] || (count($val_types) == 1 && $val_types[0] == "string");
} }
...@@ -319,32 +322,39 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { ...@@ -319,32 +322,39 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block {
} }
// Check version is only one of valid options. // Check version is only one of valid options.
if (array_key_exists('version', $this->params) && !array_key_exists($this->params['version'], self::$namedversions)) { if (array_key_exists('version', $this->params) && !array_key_exists($this->params['version'],
self::$namedversions)) {
$valid = false; $valid = false;
$validversions = ['cdn', 'local']; $validversions = ['cdn', 'local'];
$err[] = stack_string('stackBlock_parsons_unknown_named_version', ['version' => implode(', ', $validversions)]); $err[] = stack_string('stackBlock_parsons_unknown_named_version', ['version' => implode(', ',
$validversions)]);
} }
// Check that only valid parameters are passed to block header. // Check that only valid parameters are passed to block header.
$valids = null; $valids = null;
foreach ($this->params as $key => $value) { foreach ($this->params as $key => $value) {
if ($key !== 'width' && $key !== 'height' && $key !== 'aspect-ratio' && if ($key !== 'width' && $key !== 'height' && $key !== 'aspect-ratio' &&
$key !== 'version' && $key !== 'overridecss' && $key !== 'input' && $key !== 'orientation' && $key !== 'clone') { $key !== 'version' && $key !== 'overridecss' && $key !== 'input' &&
$key !== 'orientation' && $key !== 'clone') {
$err[] = "Unknown parameter '$key' for Parson's block."; $err[] = "Unknown parameter '$key' for Parson's block.";
$valid = false; $valid = false;
if ($valids === null) { if ($valids === null) {
$valids = ['width', 'height', 'aspect-ratio', 'version', 'overridecss', 'overridejs', 'input', 'orientation', 'clone']; $valids = ['width', 'height', 'aspect-ratio', 'version', 'overridecss',
'overridejs', 'input', 'orientation', 'clone'];
$err[] = stack_string('stackBlock_parsons_param', [ $err[] = stack_string('stackBlock_parsons_param', [
'param' => implode(', ', $valids)]); 'param' => implode(', ', $valids)]);
} }
} }
} }
// Check the JSON contents are of the right format, i.e., either the depth is 1 or the depth is 2 and the keys are ['steps', 'options']. // Check the JSON contents are of the right format.
// Either the depth is 1 or the depth is 2 and the keys are ['steps', 'options'].
$contents = json_decode(($this->children[0]->compile(castext2_parser_utils::RAWFORMAT, []))->value, true); $contents = json_decode(($this->children[0]->compile(castext2_parser_utils::RAWFORMAT, []))->value, true);
// Either this is a string (when using Maxima and stackjson_stringify) or it's a JSON. The former case we sanitise on the JS side so we can ignore this here. // Either this is a string (when using Maxima and stackjson_stringify) or it's a JSON.
// The former case we sanitise on the JS side so we can ignore this here.
if (!gettype($contents) == "string") { if (!gettype($contents) == "string") {
if (!self::validate_JSON_contents(json_decode(($this->children[0]->compile(castext2_parser_utils::RAWFORMAT, []))->value, true))) { if (!self::validate_JSON_contents(json_decode(($this->children[0]->compile(castext2_parser_utils::RAWFORMAT,
[]))->value, true))) {
$err[] = stack_string('stackBlock_parsons_contents'); $err[] = stack_string('stackBlock_parsons_contents');
} }
}; };
... ...
......
...@@ -96,7 +96,7 @@ class stack_inputvalidation_test_data { ...@@ -96,7 +96,7 @@ class stack_inputvalidation_test_data {
array('true', 'php_true', 'true', 'cas_true', '\mathbf{True}', '', "Booleans"), array('true', 'php_true', 'true', 'cas_true', '\mathbf{True}', '', "Booleans"),
array('false', 'php_true', 'false', 'cas_true', '\mathbf{False}', '', ""), array('false', 'php_true', 'false', 'cas_true', '\mathbf{False}', '', ""),
array('"1+1"', 'php_true', '"1+1"', 'cas_true', '\mbox{1+1}', '', array('"1+1"', 'php_true', '"1+1"', 'cas_true', '\mbox{1+1}', '',
"Strings - generally discouraged in STACK. Note, this is a string within a mathematical expression, not literally 1+1."), "Strings - generally discouraged. Note, this is a string within a mathematical expression, not literally 1+1."),
array('"Hello world"', 'php_true', '"Hello world"', 'cas_true', '\mbox{Hello world}', '', ''), array('"Hello world"', 'php_true', '"Hello world"', 'cas_true', '\mbox{Hello world}', '', ''),
// In the continuous integration, this works with GCL but not with SBCL. // In the continuous integration, this works with GCL but not with SBCL.
// array("\"We \u{1F497} STACK!\"", 'php_true', "\"We \u{1F497} STACK!\"", 'cas_true', "\mbox{We \u{1F497} STACK!}", '', ''), // array("\"We \u{1F497} STACK!\"", 'php_true', "\"We \u{1F497} STACK!\"", 'cas_true', "\mbox{We \u{1F497} STACK!}", '', ''),
... ...
......
File changed. Contains only whitespace changes. Show whitespace changes.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment