diff --git a/.gitignore b/.gitignore index 0d3af8984..a12592a2a 100644 --- a/.gitignore +++ b/.gitignore @@ -21,4 +21,8 @@ crossword_puzzle.egg-info dist # dev tools -.ruff_cache \ No newline at end of file +.ruff_cache + +# npm +node_modules +yarn.lock diff --git a/Gulpfile.js b/Gulpfile.js new file mode 100644 index 000000000..5e04c749d --- /dev/null +++ b/Gulpfile.js @@ -0,0 +1,22 @@ +/* To begin transpiling the javascript: +1. npm install --global yarn +2. yarn install +3. gulp +*/ + +const gulp = require("gulp"); +const babel = require("gulp-babel"); +const terser = require("gulp-terser"); +const rename = require("gulp-rename") + +const presets = ["@babel/preset-env"]; + +gulp.task("main", () => { + return gulp.src("./crossword_puzzle/cword_webapp/static/interaction.js") + .pipe(babel({ presets })) // preset-env for ES5 + .pipe(terser()) // minify + .pipe(rename("interaction.min.js")) + .pipe(gulp.dest("./crossword_puzzle/cword_webapp/static/")); +}); + +gulp.task("default", gulp.series("main")); \ No newline at end of file diff --git a/crossword_puzzle/cword_webapp/static/interaction.js b/crossword_puzzle/cword_webapp/static/interaction.js index 17c79d436..2eea589e8 100644 --- a/crossword_puzzle/cword_webapp/static/interaction.js +++ b/crossword_puzzle/cword_webapp/static/interaction.js @@ -1,3 +1,11 @@ +const arrowKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"]; +const spacebarKeys = ["Spacebar", " "]; +const backspaceKeys = ["Backspace", "Delete"]; +const compoundInputPlaceholders = [ + "ㅇ", "+", "ㅏ", "=", "아", "क​", "+", "इ", "=", "कै", +]; +const onlyLangRegex = /\p{L}/u; // Ensure user only types language characters + class Interaction { /* Class to handle all forms of interaction with the web app, as well as to implement ergonomic features to improve the user experience. @@ -5,14 +13,6 @@ class Interaction { Also contains utility functions to perform cell-related calculations. */ - static arrowKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"]; - static spacebarKeys = ["Spacebar", " "]; - static backspaceKeys = ["Backspace", "Delete"]; - static compoundInputPlaceholders = [ - "ㅇ", "+", "ㅏ", "=", "아", "क​", "+", "इ", "=", "कै", - ]; - static onlyLangRegex = /\p{L}/u; // Ensure user only types language characters - constructor() { this.direction = "ACROSS"; // The default direction to choose, if possible this.currentWord = null; // e.x. "HELLO" @@ -82,11 +82,11 @@ class Interaction { document.querySelectorAll(".non_empty_cell").forEach(element => { element.onclick = event => this.onCellClick(event, element); element.classList.add("zoomTarget"); // Prevents the user from having - // to click twice to zoom initially + // to click twice to zoom initially }); document.querySelectorAll(".empty_cell").forEach(element => { - element.onclick = () => this.removeCompoundInput(false) + element.onclick = () => this.removeCompoundInput(false); }); // Detect the user clicking on a word's definition @@ -177,7 +177,7 @@ class Interaction { } // User wants to clear the current word with [Shift + Backspace] - if (Interaction.backspaceKeys.includes(inputValue) && event.shiftKey) { + if (backspaceKeys.includes(inputValue) && event.shiftKey) { return this.doSpecialButtonAction("word", "clear", false); } @@ -200,21 +200,21 @@ class Interaction { } if ( - [...Interaction.arrowKeys.slice(2, 4)].includes(inputValue) && + [...arrowKeys.slice(2, 4)].includes(inputValue) && event.shiftKey ) { return this.shiftWordSelection(event, inputValue); } // Move the user's cell focus since they have pressed an arrow key - if (Interaction.arrowKeys.includes(inputValue)) { + if (arrowKeys.includes(inputValue)) { return this.handleArrowPress(inputValue, event); } // Alternate the user's direction since they are at an intersection if ( this.intersections.includes(JSON.stringify(this.cellCoords)) && - Interaction.spacebarKeys.includes(inputValue) // Pressing "Spacebar" + spacebarKeys.includes(inputValue) // Pressing "Spacebar" ) { return this.handleSpacebarPress(event); } @@ -226,7 +226,7 @@ class Interaction { handleStandardInput(inputValue) { /* Handle a normal keyboard input from the user. */ - let mode = Interaction.backspaceKeys.includes(inputValue) ? "del" : "enter"; + let mode = backspaceKeys.includes(inputValue) ? "del" : "enter"; let currentCell = Interaction.getCellElement(this.cellCoords); if (mode === "enter") { @@ -234,7 +234,7 @@ class Interaction { // than 1 character if ( !( - inputValue.length === 1 && inputValue.match(Interaction.onlyLangRegex) + inputValue.length === 1 && inputValue.match(onlyLangRegex) ) ) { return; @@ -328,7 +328,7 @@ class Interaction { */ if (this.wordToggle.checked) { let arrow = - mode === "del" ? Interaction.arrowKeys[2] : Interaction.arrowKeys[3]; + mode === "del" ? arrowKeys[2] : arrowKeys[3]; if ( oldCellCoords.isEqualTo(this.cellCoords) && (!Interaction.isEmpty(Interaction.getCellElement(this.cellCoords)) || @@ -344,8 +344,8 @@ class Interaction { on the grid. */ event?.preventDefault(); // This method is not always called by a listener, - // so optional chaining is used - let offset = arrow === Interaction.arrowKeys[2] ? -1 : 1; + // so optional chaining is used + let offset = arrow === arrowKeys[2] ? -1 : 1; let def = this.getDefinitionsListItemFromWord(); let newWordNum = Number(def.getAttribute("data-num")) + offset; let newDef = document.querySelector(`[data-num="${newWordNum}"`); @@ -655,7 +655,7 @@ class Interaction { cell.classList.remove("wrong"); Interaction.setValue(cell, cell.getAttribute("data-value")); cell.classList.add("lock_in"); // This cell must now be correct, so lock - // it in + // it in } else if (mode === "check") { if (!Interaction.isEmpty(cell)) { if (cell.hasCorrectValue()) { @@ -755,7 +755,7 @@ class Interaction { let [row, col] = this.cellCoords; this.isDown = this.direction === this.directions[1]; this.staticIndex = this.isDown ? col : row; // The index that never changes (the row - // if direction is across, etc) + // if direction is across, etc) let [startCoords, endCoords] = this.isDown ? [row, row] : [col, col]; // Find starting coords of the word @@ -848,7 +848,7 @@ class Interaction { if (document.getElementsByClassName("compound_input")[0]) { return this.removeCompoundInput(andShiftForwarder); } - let nodes = Interaction.getCellElement(this.cellCoords).childNodes + let nodes = Interaction.getCellElement(this.cellCoords).childNodes; let priorValue = nodes[0].nodeValue; if (nodes.length > 1) { nodes[1].style.display = "none"; // Hide number label if possible @@ -860,22 +860,22 @@ class Interaction { if (!this.compoundInputActive) { return; } // Maybe the user triggered this method with a click but no compound input - // element exists + // element exists let compoundInput = document.getElementsByClassName("compound_input")[0]; let cellOfCompoundInput = compoundInput.parentElement; let enteredText = compoundInput.value; try { - if (!enteredText[0].match(Interaction.onlyLangRegex)) { + if (!enteredText[0].match(onlyLangRegex)) { enteredText = ""; } } catch (err) { enteredText = ""; } compoundInput.remove(); - let nodes = cellOfCompoundInput.childNodes + let nodes = cellOfCompoundInput.childNodes; nodes[0].nodeValue = enteredText[0]; if (nodes.length > 1) { - nodes[1].style.display = "inline"; // Reset number label display + nodes[1].style.display = "inline"; // Reset number label display } cellOfCompoundInput.onclick = event => this.onCellClick(event, cellOfCompoundInput); @@ -885,10 +885,10 @@ class Interaction { this.currentPlaceholder = 0; if (this.checkToggle.checked) { - this.doGridOperation(cellOfCompoundInput, "check") + this.doGridOperation(cellOfCompoundInput, "check"); } if (andShift) { - this.handleCellShift("enter", cellOfCompoundInput); // Shift focus for + this.handleCellShift("enter", cellOfCompoundInput); // Shift focus for // ease of use } } @@ -900,10 +900,10 @@ class Interaction { return; } compoundInput.placeholder = - Interaction.compoundInputPlaceholders[this.currentPlaceholder]; + compoundInputPlaceholders[this.currentPlaceholder]; if ( this.currentPlaceholder === - Interaction.compoundInputPlaceholders.length - 1 + compoundInputPlaceholders.length - 1 ) { this.currentPlaceholder = 0; } else { diff --git a/crossword_puzzle/cword_webapp/static/interaction.min.js b/crossword_puzzle/cword_webapp/static/interaction.min.js new file mode 100644 index 000000000..eb764660a --- /dev/null +++ b/crossword_puzzle/cword_webapp/static/interaction.min.js @@ -0,0 +1 @@ +"use strict";function _typeof(t){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},_typeof(t)}function _regeneratorRuntime(){/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */_regeneratorRuntime=function(){return e};var t,e={},u=Object.prototype,n=u.hasOwnProperty,o=Object.defineProperty||function(t,e,u){t[e]=u.value},r="function"==typeof Symbol?Symbol:{},i=r.iterator||"@@iterator",l=r.asyncIterator||"@@asyncIterator",s=r.toStringTag||"@@toStringTag";function a(t,e,u){return Object.defineProperty(t,e,{value:u,enumerable:!0,configurable:!0,writable:!0}),t[e]}try{a({},"")}catch(t){a=function(t,e,u){return t[e]=u}}function D(t,e,u,n){var r=e&&e.prototype instanceof p?e:p,i=Object.create(r.prototype),l=new L(n||[]);return o(i,"_invoke",{value:w(t,u,l)}),i}function c(t,e,u){try{return{type:"normal",arg:t.call(e,u)}}catch(t){return{type:"throw",arg:t}}}e.wrap=D;var d="suspendedStart",h="suspendedYield",C="executing",F="completed",f={};function p(){}function E(){}function A(){}var m={};a(m,i,(function(){return this}));var y=Object.getPrototypeOf,v=y&&y(y(S([])));v&&v!==u&&n.call(v,i)&&(m=v);var g=A.prototype=p.prototype=Object.create(m);function B(t){["next","throw","return"].forEach((function(e){a(t,e,(function(t){return this._invoke(e,t)}))}))}function b(t,e){function u(o,r,i,l){var s=c(t[o],t,r);if("throw"!==s.type){var a=s.arg,D=a.value;return D&&"object"==_typeof(D)&&n.call(D,"__await")?e.resolve(D.__await).then((function(t){u("next",t,i,l)}),(function(t){u("throw",t,i,l)})):e.resolve(D).then((function(t){a.value=t,i(a)}),(function(t){return u("throw",t,i,l)}))}l(s.arg)}var r;o(this,"_invoke",{value:function(t,n){function o(){return new e((function(e,o){u(t,n,e,o)}))}return r=r?r.then(o,o):o()}})}function w(e,u,n){var o=d;return function(r,i){if(o===C)throw Error("Generator is already running");if(o===F){if("throw"===r)throw i;return{value:t,done:!0}}for(n.method=r,n.arg=i;;){var l=n.delegate;if(l){var s=I(l,n);if(s){if(s===f)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===d)throw o=F,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=C;var a=c(e,u,n);if("normal"===a.type){if(o=n.done?F:h,a.arg===f)continue;return{value:a.arg,done:n.done}}"throw"===a.type&&(o=F,n.method="throw",n.arg=a.arg)}}}function I(e,u){var n=u.method,o=e.iterator[n];if(o===t)return u.delegate=null,"throw"===n&&e.iterator.return&&(u.method="return",u.arg=t,I(e,u),"throw"===u.method)||"return"!==n&&(u.method="throw",u.arg=new TypeError("The iterator does not provide a '"+n+"' method")),f;var r=c(o,e.iterator,u.arg);if("throw"===r.type)return u.method="throw",u.arg=r.arg,u.delegate=null,f;var i=r.arg;return i?i.done?(u[e.resultName]=i.value,u.next=e.nextLoc,"return"!==u.method&&(u.method="next",u.arg=t),u.delegate=null,f):i:(u.method="throw",u.arg=new TypeError("iterator result is not an object"),u.delegate=null,f)}function k(t){var e={tryLoc:t[0]};1 in t&&(e.catchLoc=t[1]),2 in t&&(e.finallyLoc=t[2],e.afterLoc=t[3]),this.tryEntries.push(e)}function _(t){var e=t.completion||{};e.type="normal",delete e.arg,t.completion=e}function L(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(k,this),this.reset(!0)}function S(e){if(e||""===e){var u=e[i];if(u)return u.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var o=-1,r=function u(){for(;++o=0;--r){var i=this.tryEntries[r],l=i.completion;if("root"===i.tryLoc)return o("end");if(i.tryLoc<=this.prev){var s=n.call(i,"catchLoc"),a=n.call(i,"finallyLoc");if(s&&a){if(this.prev=0;--u){var o=this.tryEntries[u];if(o.tryLoc<=this.prev&&n.call(o,"finallyLoc")&&this.prev=0;--e){var u=this.tryEntries[e];if(u.finallyLoc===t)return this.complete(u.completion,u.afterLoc),_(u),f}},catch:function(t){for(var e=this.tryEntries.length-1;e>=0;--e){var u=this.tryEntries[e];if(u.tryLoc===t){var n=u.completion;if("throw"===n.type){var o=n.arg;_(u)}return o}}throw Error("illegal catch attempt")},delegateYield:function(e,u,n){return this.delegate={iterator:S(e),resultName:u,nextLoc:n},"next"===this.method&&(this.arg=t),f}},e}function _slicedToArray(t,e){return _arrayWithHoles(t)||_iterableToArrayLimit(t,e)||_unsupportedIterableToArray(t,e)||_nonIterableRest()}function _nonIterableRest(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _iterableToArrayLimit(t,e){var u=null==t?null:"undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(null!=u){var n,o,r,i,l=[],s=!0,a=!1;try{if(r=(u=u.call(t)).next,0===e){if(Object(u)!==u)return;s=!1}else for(;!(s=(n=r.call(u)).done)&&(l.push(n.value),l.length!==e);s=!0);}catch(t){a=!0,o=t}finally{try{if(!s&&null!=u.return&&(i=u.return(),Object(i)!==i))return}finally{if(a)throw o}}return l}}function _arrayWithHoles(t){if(Array.isArray(t))return t}function _createForOfIteratorHelper(t,e){var u="undefined"!=typeof Symbol&&t[Symbol.iterator]||t["@@iterator"];if(!u){if(Array.isArray(t)||(u=_unsupportedIterableToArray(t))||e&&t&&"number"==typeof t.length){u&&(t=u);var n=0,o=function(){};return{s:o,n:function(){return n>=t.length?{done:!0}:{done:!1,value:t[n++]}},e:function(t){throw t},f:o}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var r,i=!0,l=!1;return{s:function(){u=u.call(t)},n:function(){var t=u.next();return i=t.done,t},e:function(t){l=!0,r=t},f:function(){try{i||null==u.return||u.return()}finally{if(l)throw r}}}}function _toConsumableArray(t){return _arrayWithoutHoles(t)||_iterableToArray(t)||_unsupportedIterableToArray(t)||_nonIterableSpread()}function _nonIterableSpread(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function _unsupportedIterableToArray(t,e){if(t){if("string"==typeof t)return _arrayLikeToArray(t,e);var u=Object.prototype.toString.call(t).slice(8,-1);return"Object"===u&&t.constructor&&(u=t.constructor.name),"Map"===u||"Set"===u?Array.from(t):"Arguments"===u||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(u)?_arrayLikeToArray(t,e):void 0}}function _iterableToArray(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}function _arrayWithoutHoles(t){if(Array.isArray(t))return _arrayLikeToArray(t)}function _arrayLikeToArray(t,e){(null==e||e>t.length)&&(e=t.length);for(var u=0,n=new Array(e);u0&&void 0!==arguments[0]?arguments[0]:null,e=arguments.length>1?arguments[1]:void 0;null==t||t.preventDefault();var u=e===arrowKeys[2]?-1:1,n=this.getDefinitionsListItemFromWord(),o=Number(n.getAttribute("data-num"))+u,r=document.querySelector('[data-num="'.concat(o,'"'));if(!r){var i=1===u?"1":this.wordCount;r=document.querySelector('[data-num="'.concat(i,'"]'))}var l=this.cellCoords;r.focus(),r.click(),r.blur(),this.followCellZoom(l)}},{key:"skipCellCoords",value:function(t,e){var u=this.shiftCellCoords(t,e,"enter");if(u.isEqualTo(t))return u;if(!this.wasEmpty)return u;for(this.wasEmpty=!1;!Interaction.isEmpty(Interaction.getCellElement(u));){var n=u;if(u=this.shiftCellCoords(u,e,"enter"),n.isEqualTo(u))break}return Interaction.isEmpty(Interaction.getCellElement(u))?u:this.shiftCellCoords(t,e,"enter")}},{key:"shiftCellCoords",value:function(t,e,u){var n=arguments.length>3&&void 0!==arguments[3]&&arguments[3],o="enter"==u?1:-1,r=e===this.directions[1]?[t[0]+o,t[1]]:[t[0],t[1]+o],i=Interaction.getCellElement(r);return null!==i&&i.classList.contains("non_empty_cell")||n?r:t}},{key:"onDefinitionsListItemClick",value:function(t,e,u){var n=document.querySelector('[data-num_label="'.concat(e,'"]')).parentElement;this.preventZoomIfRequired(t),this.removeCompoundInputIfRequired(n),this.setFocusMode(!1),document.activeElement.blur(),this.compoundInputActive&&document.getElementsByClassName("compound_input")[0].focus(),this.direction=u,this.cellCoords=Interaction.updateCellCoords(n),this.currentWord=this.updateCurrentWord(),this.setFocusMode(!0)}},{key:"onCellClick",value:function(t,e){if(this.doNotHandleStandardCellClick)return this.doNotHandleStandardCellClick=!1;this.preventZoomIfRequired(t),this.removeCompoundInputIfRequired(e),this.setFocusMode(!1);var u=Interaction.updateCellCoords(e);(this.intersections.includes(JSON.stringify(u))&&u.isEqualTo(this.cellCoords)||this.shouldDirectionBeAlternated(u))&&this.alternateDirection(),this.cellCoords=u,this.currentWord=this.updateCurrentWord(),this.setFocusMode(!0),this.updateDefinitionsListPos()}},{key:"handleArrowPress",value:function(t,e){e.preventDefault();var u="ArrowDown"===t||"ArrowRight"===t?"enter":"del",n="ArrowDown"===t||"ArrowUp"===t?this.directions[1]:this.directions[0],o=Interaction.getCellElement(this.cellCoords),r=this.shiftCellCoords(this.cellCoords,n,u,!0),i=!1;try{for(;Interaction.getCellElement(r).classList.contains("empty_cell");)r=this.shiftCellCoords(r,n,u,!0),i=!0}catch(t){r=this.cellCoords}this.setFocusMode(!1),this.shouldDirectionBeAlternated(r)?(this.alternateDirection(),i&&(this.cellCoords=r),i=!1):this.cellCoords=r,this.followCellZoom(o),this.currentWord=this.updateCurrentWord(),this.setFocusMode(!0),this.updateDefinitionsListPos()}},{key:"handleEnterPress",value:function(t){t.target.classList.contains("def")?(t.target.click(),t.target.blur(),this.zoomToggle.checked&&(this.doNotHandleStandardCellClick=!0,Interaction.getCellElement(this.cellCoords).click())):t.target.classList.contains("toggle")&&t.target.click()}},{key:"handleEnterKeybindPress",value:function(t){Interaction.unfocusActiveElement(),this.hideDropdowns();var e=t.shiftKey?"reveal":"check";this.doSpecialButtonAction("word",e,!1)}},{key:"handleSpacebarPress",value:function(t){t.preventDefault(),this.setFocusMode(!1),this.alternateDirection(),this.currentWord=this.updateCurrentWord(),this.setFocusMode(!0),this.updateDefinitionsListPos()}},{key:"handleEscapePress",value:function(t){null==t||t.preventDefault(),Interaction.unfocusActiveElement(),this.hideDropdowns(),this.setFocusMode(!1),this.zoomOut(),this.cellCoords=null,this.currentWord=null}},{key:"crosswordCompletionHandler",value:function(){var t=this;this.isCrosswordComplete()&&Interaction.sleep(1).then((function(){t.handleEscapePress(null),t.displayCompletionPopup(),t.jazz.play()}))}},{key:"doSpecialButtonAction",value:function(t,e){var u=this,n=arguments.length>3&&void 0!==arguments[3]&&arguments[3];if((!(arguments.length>2&&void 0!==arguments[2])||arguments[2])&&this.onDropdownClick(e+"_dropdown"),null===this.cellCoords&&"grid"!==t)return alert(this.errMsgs[0]);switch(t){case"cell":var o=Interaction.getCellElement(this.cellCoords);this.doGridOperation(o,e),"reveal"===e&&this.handleCellShift("enter",o);break;case"word":var r,i=_createForOfIteratorHelper(this.getWordElements());try{for(i.s();!(r=i.n()).done;){var l=r.value;this.doGridOperation(l,e)}}catch(t){i.e(t)}finally{i.f()}"reveal"===e&&this.wordToggle.checked&&this.shiftWordSelection(null,"ArrowDown");break;case"grid":document.querySelectorAll(".non_empty_cell").forEach((function(t){return u.doGridOperation(t,e,n)}))}this.crosswordCompletionHandler()}},{key:"doGridOperation",value:function(t,e){var u=arguments.length>2&&void 0!==arguments[2]&&arguments[2];"reveal"===e?(t.classList.remove("wrong"),Interaction.setValue(t,t.getAttribute("data-value")),t.classList.add("lock_in")):"check"===e?Interaction.isEmpty(t)||(t.hasCorrectValue()?t.classList.add("lock_in"):t.classList.add("wrong")):"clear"===e&&(u&&!t.classList.contains("lock_in")||!u)&&(t.classList.remove("lock_in"),t.classList.remove("wrong"),Interaction.setValue(t,""))}},{key:"shouldDirectionBeAlternated",value:function(t){return this.shiftCellCoords(t,this.direction,"enter").isEqualTo(t)&&this.shiftCellCoords(t,this.direction,"del").isEqualTo(t)}},{key:"setFocusMode",value:function(t){null!==this.cellCoords&&(this.changeWordFocus(t),this.changeCellFocus(t),this.changeDefinitionsListItemFocus(t))}},{key:"changeWordFocus",value:function(t){var e,u=_createForOfIteratorHelper(this.getWordElements());try{for(u.s();!(e=u.n()).done;){e.value.style.backgroundColor=t?this.colourPalette.WORD_FOCUS:this.colourPalette.SUB}}catch(t){u.e(t)}finally{u.f()}}},{key:"changeCellFocus",value:function(t){return Interaction.getCellElement(this.cellCoords).style.backgroundColor=t?this.colourPalette.CELL_FOCUS:this.colourPalette.SUB}},{key:"changeDefinitionsListItemFocus",value:function(t){return this.getDefinitionsListItemFromWord().style.backgroundColor=t?this.colourPalette.WORD_FOCUS:""}},{key:"updateCurrentWord",value:function(){var t,e="",u=_createForOfIteratorHelper(this.getWordElements());try{for(u.s();!(t=u.n()).done;){e+=t.value.getAttribute("data-value")}}catch(t){u.e(t)}finally{u.f()}return e.toUpperCase()}},{key:"getWordElements",value:_regeneratorRuntime().mark((function t(){var e,u,n,o,r,i;return _regeneratorRuntime().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:e=this.getWordIndices(),u=_slicedToArray(e,2),n=u[0],o=u[1],r=n;case 2:if(!(r<=o)){t.next=9;break}return i=this.isDown?[r,this.staticIndex]:[this.staticIndex,r],t.next=6,Interaction.getCellElement(i);case 6:r++,t.next=2;break;case 9:case"end":return t.stop()}}),t,this)}))},{key:"getWordIndices",value:function(){var t=_slicedToArray(this.cellCoords,2),e=t[0],u=t[1];this.isDown=this.direction===this.directions[1],this.staticIndex=this.isDown?u:e;for(var n=_slicedToArray(this.isDown?[e,e]:[u,u],2),o=n[0],r=n[1];o>0&&this.grid[this.isDown?o-1:e][this.isDown?u:o-1]!=this.empty;)o--;for(;r0&&void 0!==arguments[0])||arguments[0];if(null===this.cellCoords)return alert(this.errMsgs[0]);if(document.getElementsByClassName("compound_input")[0])return this.removeCompoundInput(t);var e=Interaction.getCellElement(this.cellCoords).childNodes,u=e[0].nodeValue;e.length>1&&(e[1].style.display="none"),this.setCompoundInput(u)}},{key:"removeCompoundInput",value:function(){var t=this,e=!(arguments.length>0&&void 0!==arguments[0])||arguments[0];if(this.compoundInputActive){var u=document.getElementsByClassName("compound_input")[0],n=u.parentElement,o=u.value;try{o[0].match(onlyLangRegex)||(o="")}catch(t){o=""}u.remove();var r=n.childNodes;r[0].nodeValue=o[0],r.length>1&&(r[1].style.display="inline"),n.onclick=function(e){return t.onCellClick(e,n)},n.classList.remove("lock_in","wrong"),this.compoundInputActive=!1,this.currentPlaceholder=0,this.checkToggle.checked&&this.doGridOperation(n,"check"),e&&this.handleCellShift("enter",n)}}},{key:"cycleCompoundInputPlaceholderText",value:function(){var t=document.getElementsByClassName("compound_input")[0];void 0!==t&&(t.placeholder=compoundInputPlaceholders[this.currentPlaceholder],this.currentPlaceholder===compoundInputPlaceholders.length-1?this.currentPlaceholder=0:this.currentPlaceholder+=1)}},{key:"removeCompoundInputIfRequired",value:function(t){this.compoundInputActive&&t!==Interaction.getCellElement(this.cellCoords)&&this.removeCompoundInput()}},{key:"followCellZoom",value:function(t){if(1===document.querySelectorAll(".non_empty_cell.selectedZoomTarget").length){var e=Interaction.getCellElement(this.cellCoords);if(e!==t)return this.doNotHandleStandardCellClick=!0,e.click()}}},{key:"handleClick",value:function(t){t.target.closest(".special_button, .dropdown, .dropdown_button")||(this.hideDropdowns(),this.removeCompoundInput(!1))}},{key:"handleDropdownFocusOut",value:function(t){var e,u,n,o,r,i,l,s,a;(null===(e=t.relatedTarget)||void 0===e||!e.classList.contains("dropdown_button")||null!==(u=t.target)&&void 0!==u&&u.classList.contains("dropdown_button")&&null!==(n=t.relatedTarget)&&void 0!==n&&n.classList.contains("special_button")&&(null===(o=t.relatedTarget)||void 0===o||!o.id.startsWith(null===(r=this.currentDropdown)||void 0===r?void 0:r.substring(0,null===(i=this.currentDropdown)||void 0===i?void 0:i.indexOf("_"))))||null!==(l=t.target.id)&&void 0!==l&&l.endsWith("button")&&(null!==(s=t.relatedTarget)&&void 0!==s&&null!==(s=s.id)&&void 0!==s&&s.endsWith("button")||null===(a=t.relatedTarget)||void 0===a||null===(a=a.classList)||void 0===a||!a.contains("dropdown_button")))&&this.hideDropdowns()}},{key:"hideDropdowns",value:function(){document.querySelectorAll(".dropdown").forEach((function(t){return t.classList.remove("show_dropdown")})),document.querySelectorAll(".special_button").forEach((function(t){return t.innerHTML=t.innerHTML.replace("▲","▼")})),this.currentDropdown=null}},{key:"onDropdownClick",value:function(t){this.removeCompoundInput(!1);var e=document.getElementById(t);if(t===this.currentDropdown)return this.hideDropdowns(),void(this.currentDropdown=null);this.hideDropdowns();var u=document.getElementById(t.replace("_dropdown","_button"));u.innerHTML=u.innerHTML.replace("▼","▲"),e.classList.add("show_dropdown"),this.currentDropdown=t}},{key:"displayOnloadPopup",value:function(){this.onloadPopupToggled=!0,Interaction.sleep(200).then((function(){document.getElementById("blur").classList.toggle("active"),document.getElementById("onload_popup").classList.toggle("active"),Interaction.sleep(301).then((function(){document.getElementsByClassName("continue_button")[0].focus({focusVisible:!0})}))}))}},{key:"displayCompletionPopup",value:function(){this.completionPopupToggled=!this.completionPopupToggled,document.getElementById("blur").classList.toggle("active"),document.getElementById("completion_popup").classList.toggle("active"),this.completionPopupToggled&&Interaction.sleep(501).then((function(){return document.getElementsByClassName("close_button")[0].focus({focusVisible:!0})}))}},{key:"closeOnloadPopup",value:function(){var t=arguments.length>0&&void 0!==arguments[0]&&arguments[0];this.onloadPopupToggled=!1,document.getElementById("blur").classList.toggle("active"),document.getElementById("onload_popup").classList.toggle("active"),t&&document.querySelector('[data-num="1"').click()}},{key:"preventZoomIfRequired",value:function(t){document.getElementById("tz").checked&&!this.preventInitialLIZoom||(this.preventInitialLIZoom=!1,t.stopImmediatePropagation())}}],[{key:"dummyCellClick",value:function(t){return t.stopImmediatePropagation()}},{key:"unfocusActiveElement",value:function(){document.activeElement.blur()}},{key:"emulateEscapePress",value:function(){return document.dispatchEvent(new KeyboardEvent("keyboard",{key:"Escape"}))}},{key:"sleep",value:function(t){return new Promise((function(e){return setTimeout(e,t)}))}},{key:"isEmpty",value:function(t){var e;return!(null!=t&&null!==(e=t.childNodes[0])&&void 0!==e&&e.nodeValue)}},{key:"setValue",value:function(t,e){return t.childNodes[0].nodeValue=e}},{key:"getCellElement",value:function(t){return document.querySelector('[data-row="'.concat(t[0],'"][data-column="').concat(t[1],'"]'))}},{key:"updateCellCoords",value:function(t){return[parseInt(t.getAttribute("data-row")),parseInt(t.getAttribute("data-column"))]}},{key:"configureScrollHeights",value:function(){var t=document.querySelector(".definitions_a"),e=document.querySelector(".definitions_d");document.getElementById("return_def_zoom").style.height=Math.max(t.scrollHeight,e.scrollHeight)+"px";var u=document.getElementById("no_scroll");u.scrollHeight-1>u.clientHeight&&(u.style.overflowY="auto")}}])}();Array.prototype.isEqualTo=function(t){return JSON.stringify(this)===JSON.stringify(t)},Element.prototype.hasCorrectValue=function(){return this.childNodes[0].nodeValue.toUpperCase()===this.getAttribute("data-value")};var interaction=new Interaction; \ No newline at end of file diff --git a/crossword_puzzle/cword_webapp/templates/index.html b/crossword_puzzle/cword_webapp/templates/index.html index 76e5710b0..d3ef260d9 100644 --- a/crossword_puzzle/cword_webapp/templates/index.html +++ b/crossword_puzzle/cword_webapp/templates/index.html @@ -11,7 +11,7 @@ {{ _('Crossword Puzzle - Game') }} - + diff --git a/package.json b/package.json new file mode 100644 index 000000000..46f0fb51b --- /dev/null +++ b/package.json @@ -0,0 +1,12 @@ +{ + "devDependencies": { + "@babel/cli": "^7.24.5", + "@babel/core": "^7.24.5", + "@babel/preset-env": "^7.24.5", + "gulp": "^5.0.0", + "gulp-babel": "^8.0.0", + "gulp-rename": "^2.0.0", + "gulp-terser": "^2.1.0", + "terser": "^5.31.0" + } +}