From ac4aace95800d8bb2cd0681c94ec8d60329179e6 Mon Sep 17 00:00:00 2001 From: smmercuri Date: Wed, 8 Nov 2023 13:54:36 +0000 Subject: [PATCH] abstract more functionality to js --- corsscripts/stacksortable.js | 18 +++++++---- corsscripts/stacksortable.min.js | 7 ++-- stack/cas/castext2/blocks/parsons.block.php | 36 ++++----------------- 3 files changed, 23 insertions(+), 38 deletions(-) diff --git a/corsscripts/stacksortable.js b/corsscripts/stacksortable.js index 78e6401bfbb..6fb58bed4f0 100644 --- a/corsscripts/stacksortable.js +++ b/corsscripts/stacksortable.js @@ -7,9 +7,10 @@ export const stack_sortable = class { - constructor(state, availableId, usedId, inputId = null, options = null) { - this.state = state; + constructor(proofSteps, availableId, usedId, inputId = null, options = null) { + this.proofSteps = proofSteps; this.inputId = inputId; + this.state = this._generate_state(this.proofSteps, this.inputId); if (inputId != null) { this.input = document.getElementById(this.inputId); }; @@ -28,20 +29,25 @@ export const stack_sortable = class { this.options = Object.assign(this.userOptions, {ghostClass: "list-group-item-info", group: "shared"}); } - generate_available(proofSteps) { + _generate_state(proofSteps, inputId) { + let stateStore = document.getElementById(inputId); + return stateStore.value && stateStore.value != "" ? JSON.parse(stateStore.value) : {used: [], available: [...Object.keys(proofSteps)]}; + } + + generate_available() { for (const key in this.state.available) { let li = document.createElement("li"); - li.innerHTML = proofSteps[this.state.available[key]]; + li.innerHTML = this.proofSteps[this.state.available[key]]; li.setAttribute("data-id", this.state.available[key]); li.className = "list-group-item"; this.available.append(li); }; } - generate_used(proofSteps) { + generate_used() { for (const key in this.state.used) { let li = document.createElement("li"); - li.innerHTML = proofSteps[this.state.used[key]]; + li.innerHTML = this.proofSteps[this.state.used[key]]; li.setAttribute("data-id", this.state.used[key]); li.className = "list-group-item"; this.used.append(li); diff --git a/corsscripts/stacksortable.min.js b/corsscripts/stacksortable.min.js index 8c21e8938a3..edacc4f0cec 100644 --- a/corsscripts/stacksortable.min.js +++ b/corsscripts/stacksortable.min.js @@ -1,5 +1,6 @@ -export const stack_sortable=class{constructor(state,availableId,usedId,inputId=null,options=null){this.state=state;this.inputId=inputId;if(inputId!=null){this.input=document.getElementById(this.inputId);};this.availableId=availableId;this.available=document.getElementById(this.availableId);this.usedId=usedId;this.used=document.getElementById(this.usedId);this.defaultOptions={animation:50};if(options==null){this.userOptions=this.defaultOptions;}else{this.userOptions=Object.assign(this.defaultOptions,options);};this.options=Object.assign(this.userOptions,{ghostClass:"list-group-item-info",group:"shared"});} -generate_available(proofSteps){for(const key in this.state.available){let li=document.createElement("li");li.innerHTML=proofSteps[this.state.available[key]];li.setAttribute("data-id",this.state.available[key]);li.className="list-group-item";this.available.append(li);};} -generate_used(proofSteps){for(const key in this.state.used){let li=document.createElement("li");li.innerHTML=proofSteps[this.state.used[key]];li.setAttribute("data-id",this.state.used[key]);li.className="list-group-item";this.used.append(li);};} +export const stack_sortable=class{constructor(proofSteps,availableId,usedId,inputId=null,options=null){this.proofSteps=proofSteps;this.inputId=inputId;this.state=this._generate_state(this.proofSteps,this.inputId);if(inputId!=null){this.input=document.getElementById(this.inputId);};this.availableId=availableId;this.available=document.getElementById(this.availableId);this.usedId=usedId;this.used=document.getElementById(this.usedId);this.defaultOptions={animation:50};if(options==null){this.userOptions=this.defaultOptions;}else{this.userOptions=Object.assign(this.defaultOptions,options);};this.options=Object.assign(this.userOptions,{ghostClass:"list-group-item-info",group:"shared"});} +_generate_state(proofSteps,inputId){let stateStore=document.getElementById(inputId);return stateStore.value&&stateStore.value!=""?JSON.parse(stateStore.value):{used:[],available:[...Object.keys(proofSteps)]};} +generate_available(){for(const key in this.state.available){let li=document.createElement("li");li.innerHTML=this.proofSteps[this.state.available[key]];li.setAttribute("data-id",this.state.available[key]);li.className="list-group-item";this.available.append(li);};} +generate_used(){for(const key in this.state.used){let li=document.createElement("li");li.innerHTML=this.proofSteps[this.state.used[key]];li.setAttribute("data-id",this.state.used[key]);li.className="list-group-item";this.used.append(li);};} update_state(newUsed,newAvailable){var newState={used:[],available:[]};newState.used=newUsed.toArray();newState.available=newAvailable.toArray();if(this.inputId!=null){this.input.value=JSON.stringify(newState);this.input.dispatchEvent(new Event('change'));};this.state=newState;}};export default{stack_sortable}; \ No newline at end of file diff --git a/stack/cas/castext2/blocks/parsons.block.php b/stack/cas/castext2/blocks/parsons.block.php index 7ff7c65e070..920ee594a42 100644 --- a/stack/cas/castext2/blocks/parsons.block.php +++ b/stack/cas/castext2/blocks/parsons.block.php @@ -31,7 +31,6 @@ class stack_cas_castext2_parsons extends stack_cas_castext2_block { public static $namedversions = [ 'local' => [ 'css' => 'cors://sortable.min.css', - 'js' => 'cors://sortable.min.js', ] ]; @@ -55,27 +54,19 @@ public function compile($format, $options): ? MP_Node { if (isset($xpars['overridecss'])) { unset($xpars['overridecss']); } - if (isset($xpars['overridejs'])) { - unset($xpars['overridejs']); - } // Set a title. $xpars['title'] = 'STACK Parsons ///PARSONS_COUNT///'; // Figure out what scripts we serve. $css = self::$namedversions['local']['css']; - $js = self::$namedversions['local']['js']; if (isset($this->params['version']) && isset(self::$namedversions[$this->params['version']])) { $css = self::$namedversions[$this->params['version']]['css']; - $js = self::$namedversions[$this->params['version']]['js']; } if (isset($this->params['overridecss'])) { $css = $this->params['overridecss']; } - if (isset($this->params['overridejs'])) { - $js = $this->params['overridejs']; - } $r->items[] = new MP_String(json_encode($xpars)); @@ -89,10 +80,6 @@ public function compile($format, $options): ? MP_Node { new MP_String('style'), new MP_String(json_encode(['href' => $css])) ]); - /*$r->items[] = new MP_List([ - new MP_String('script'), - new MP_String(json_encode(['type' => 'text/javascript', 'src' => $js])) - ]);*/ // We need to define a size for the inner content. $width = '100%'; @@ -167,26 +154,17 @@ public function compile($format, $options): ? MP_Node { } else { $code .= 'var id;' . "\n"; }; - - // Generate state - $code .= 'var state;' . "\n"; - // If we already have a stored state in the statestringinput input, then we use this state - $code .= 'let stateStore = document.getElementById(id);' . "\n"; - $code .= 'if (stateStore.value && stateStore.value != ""){' . "\n"; - $code .= 'state = JSON.parse(stateStore.value);}' . "\n"; - - // otherwise we generate the initial state based on the contents of the block - $code .= 'else {' . "\n"; - $code .= 'state = {used: [], available: [...Object.keys(proofSteps)]};}' . "\n"; - - // Create the sortable objects by filling in the container div - $code .= 'const sortable = new stack_sortable(state, "availableList", "usedList", id, userOpts);' . "\n"; - $code .= 'sortable.generate_used(proofSteps);' . "\n"; - $code .= 'sortable.generate_available(proofSteps);' . "\n"; + // Instantiate STACK sortable helper class + $code .= 'const sortable = new stack_sortable(proofSteps, "availableList", "usedList", id, userOpts);' . "\n"; + // Generate the two lists in HTML + $code .= 'sortable.generate_used();' . "\n"; + $code .= 'sortable.generate_available();' . "\n"; + // Typeset MathJax if (count($inputs) > 0) { $code .= 'MathJax.typesetPromise();' . "\n"; }; + // Create the Sortable objects $code .= 'var opts = {...sortable.options, ...{onSort: () => {sortable.update_state(sortableUsed, sortableAvailable);}}}' . "\n"; $code .= 'var sortableUsed = Sortable.create(usedList, opts);' . "\n"; $code .= 'var sortableAvailable = Sortable.create(availableList, opts);' . "\n";