|
|
@@ -1,10 +1,23 @@
|
|
|
-var f=[];function h(a,b,c){var d=document.createElement("div");d.className="cell";if(a.i)d.classList.add("cell-disabled");else if(null!==a.b){d.classList.add("cell-definition");for(var e=document.createElement("span"),g=0,k=a.b.length;g<k;g++){var A=a.b[g],n=document.createElement("span");n.dataset.x=b;n.dataset.y=c;n.dataset.definition=g;n.className="definition";n.innerHTML=A.text.join("<br/>");e.appendChild(n)}d.appendChild(e)}else d.classList.add("cell-letter");return d}
|
|
|
-function l(){for(var a=document.createDocumentFragment(),b=0;b<m.l;b++){var c=document.createElement("div");c.className="crossword-line";a.appendChild(c);for(var d=0;d<m.c;d++){var e=h(m.f[d][b],d,b);e.dataset.x=d;e.dataset.y=b;c.appendChild(e);f.push({x:d,y:b,a:e,data:m.f[d][b]})}}for(b=0;b<m.l;b++)for(d=0;d<m.c;d++)e=f[b*m.c+d],e.data.b&&e.data.b.forEach(function(a){switch(a.direction){case 2:f[b*m.c+d+1].a.classList.add("definition-right-vt");break;case 1:f[b*m.c+d+1].a.classList.add("definition-right-hz");
|
|
|
-break;case 4:f[(b+1)*m.c+d].a.classList.add("definition-bottom-vt");break;case 3:f[(b+1)*m.c+d].a.classList.add("definition-bottom-hz")}});p();document.body.textContent="";document.body.appendChild(a)}function p(){f.forEach(function(a){a.data.b||a.data.i||(a.data.j?(a.a.textContent=a.data.j,a.data.g&&a.a.classList.add("cell-letter-correct")):a.a.textContent="")})}
|
|
|
-function q(a){for(a=a.target;a&&a.dataset&&!a.dataset.x;)a=a.parentElement;if(a&&a.dataset&&a.dataset.x&&a.dataset.y){var b=f[parseInt(a.dataset.x,10)+parseInt(a.dataset.y,10)*m.c];if(b.data.i)r();else if(b.data.b){var c=!0;r();b.data.b[a.dataset.definition]&&b.data.b[a.dataset.definition].o.forEach(function(a){t(a[0],a[1]);c&&!f[a[0]+a[1]*m.c].data.g&&(u=f[a[0]+a[1]*m.c],u.a.classList.add("cell-input"));c=!1})}else{var d=v(b.x,b.y);r();d.forEach(function(a){a.forEach(function(a){t(a[0],a[1])})});
|
|
|
-a.classList.add("cell-input");u=b}}};function w(a){this.text=a.text;this.direction=a.pos;this.o=null}function x(){this.i=!1;this.b=null;this.g=!1;this.j=null}x.prototype.update=function(a){if(null===a.type)this.i=!0;else if(void 0!==a.definitions)this.b=[],a.definitions.forEach(function(a){this.b.push(new w(a))}.bind(this));else if(a.letter)return this.j=a.letter,this.g=!0,a.v;return 0};function y(a){this.c=a.w;this.l=a.h;this.m=[];this.f=[];for(a=0;a<this.c;a++){this.f[a]=[];for(var b=0;b<this.l;b++)this.f[a][b]=new x}}
|
|
|
-function z(a,b,c,d,e){if(!a.f[b+d]||!a.f[b+d][c+e]||a.f[b+d][c+e].b||a.f[b+d][c+e].i)return[[b,c]];a=z(a,b+d,c+e,d,e);a.unshift([b,c]);return a}function v(a,b){var c=[];m.m.forEach(function(d){for(var e=0,g=d.length;e<g;e++)if(d[e][0]==a&&d[e][1]==b){c.push(d);break}});return c}
|
|
|
-y.prototype.update=function(a){var b=null,c=this.f,d=!1;a.forEach(function(a){a=c[a.x][a.y].update(a);b=Math.max(b||0,a);0===a&&(d=!0)});if(d){for(var e=[],g=0;g<this.c;g++)for(var k=0;k<this.l;k++)c[g][k].b&&c[g][k].b.forEach(function(a){var b;switch(a.direction){case 2:b=z(this,g+1,k,0,1);break;case 1:b=z(this,g+1,k,1,0);break;case 4:b=z(this,g,k+1,0,1);break;case 3:b=z(this,g,k+1,1,0)}e.push(b);a.o=b}.bind(this));this.m=e}return b};var B,C=0,m,D=[],u=null;function E(a,b){var c=new XMLHttpRequest;c.onreadystatechange=function(){if(4===c.readyState){var a=null;if(200===c.status){a=c.response;try{a=JSON.parse(a)}catch(e){a=null}}b(c.status,a)}};c.open("GET",a,!0);c.send(null)}function F(){E("/api/poll?grid="+B+"&v="+C,function(a,b){b&&(m=new y(b),b.grid&&(C=Math.max(m.update(b.grid)||0,C),l()),C=Math.max(C,b.v||0))})}
|
|
|
-function G(){E("/api/poll?grid="+B+"&v="+C,function(a,b){if(b&&b.grid){var c=Math.max(m.update(b.grid)||0,C);c!==C&&(p(),C=c)}})}function H(a){var b=u;b.a.classList.add("cell-letter-pending");E("/api/put?grid="+B+"&key="+a+"&x="+b.x+"&y="+b.y,function(c){b.a.classList.remove("cell-letter-pending");403!==c||b.data.g?204===c?(b.a.classList.remove("cell-letter-wrong"),b.data.j=a,b.data.g=!0,p()):G():b.a.classList.add("cell-letter-wrong")})}
|
|
|
-function r(){D.forEach(function(a){a.a.classList.remove("cell-selected")});u&&(u.a.classList.remove("cell-input"),u=null);D=[]}function t(a,b){var c=f[a+b*m.c];D.push(c);c.a.classList.add("cell-selected")}
|
|
|
-document.addEventListener("DOMContentLoaded",function(){B=document.location.hash.substr(1);""==B?document.location.href="/":(document.addEventListener("click",q),document.addEventListener("keypress",function(a){u&&!u.data.g&&(a=a.key.charAt(0).toUpperCase(),a.match(/[A-Z]/)&&(u.data.j=a,H(a),p()))}),F())});
|
|
|
+var R={id:{scoreboard:"scoreboard",grid:"grid"},klass:{line:"crossword-line",cell:{item:"cell",black:"cell-disabled",definition:"cell-definition",letter:"cell-letter",definitions:{item:"definition",rightVertical:"definition-right-vt",rightHorizontal:"definition-right-hz",bottomVertical:"definition-bottom-vt",bottomHorizontal:"definition-bottom-hz"},found:"cell-letter-correct",pending:"cell-letter-pending",wrong:"cell-letter-wrong",selected:"cell-selected",currentInput:"cell-input"}}};var UI_CELLS=[],UI_PLAYERS={},playerDomList;function dCreate(domName){return document.createElement(domName)}function dGet(id){return document.getElementById(id)}
|
|
|
+function uiCreateCell(cellData,x,y){var cell=dCreate("div");cell.className=R.klass.cell.item;if(cellData.isBlack)cell.classList.add(R.klass.cell.black);else if(cellData.definitions!==null){cell.classList.add(R.klass.cell.definition);var cellContent=dCreate("span");for(var i=0,nbDefinitions=cellData.definitions.length;i<nbDefinitions;i++){var definition=cellData.definitions[i],domDefinition=dCreate("span");domDefinition.dataset.x=x;domDefinition.dataset.y=y;domDefinition.dataset.definition=i;domDefinition.className=
|
|
|
+R.klass.cell.definitions.item;domDefinition.innerHTML=definition.text.join("<br/>");cellContent.appendChild(domDefinition)}cell.appendChild(cellContent)}else cell.classList.add(R.klass.cell.letter);return cell}function uiCreatePlayer(player){var dom=dCreate("li"),playerName=dCreate("span");playerName.textContent=player.name;dom.appendChild(playerName);dom.score=dCreate("span");dom.appendChild(dom.score);dom.style.color=player.color;return dom}
|
|
|
+function uiCreateGrid(){var frag=document.createDocumentFragment();for(var i=0;i<GRID.height;i++){var line=dCreate("div");line.className=R.klass.line;frag.appendChild(line);for(var j=0;j<GRID.width;j++){var cell=uiCreateCell(GRID.grid[j][i],j,i);cell.dataset.x=j;cell.dataset.y=i;line.appendChild(cell);UI_CELLS.push({x:j,y:i,dom:cell,data:GRID.grid[j][i]})}}for(var i=0;i<GRID.height;i++)for(var j=0;j<GRID.width;j++){var cell=UI_CELLS[i*GRID.width+j];if(cell.data.definitions)cell.data.definitions.forEach(function(d){switch(d.direction){case Definition.RIGHT_VERTICAL:UI_CELLS[i*
|
|
|
+GRID.width+j+1].dom.classList.add(R.klass.cell.definitions.rightVertical);break;case Definition.RIGHT_HORIZONTAL:UI_CELLS[i*GRID.width+j+1].dom.classList.add(R.klass.cell.definitions.rightHorizontal);break;case Definition.BOTTOM_VERTICAL:UI_CELLS[(i+1)*GRID.width+j].dom.classList.add(R.klass.cell.definitions.bottomVertical);break;case Definition.BOTTOM_HORIZONTAL:UI_CELLS[(i+1)*GRID.width+j].dom.classList.add(R.klass.cell.definitions.bottomHorizontal);break}})}onGridUpdated();var gridContainer=dGet(R.id.grid);
|
|
|
+gridContainer.textContent="";gridContainer.appendChild(frag)}function onGridUpdated(){UI_CELLS.forEach(function(i){if(!i.data.definitions&&!i.data.isBlack)if(i.data.letter){i.dom.textContent=i.data.letter;if(i.data.found){i.dom.classList.add(R.klass.cell.found);i.dom.classList.remove(R.klass.cell.wrong);i.dom.style.color=i.data.found.color}}else i.dom.textContent=""})}
|
|
|
+function onPlayersUpdated(){var container;for(var i in GRID.players){var uiPlayer=UI_PLAYERS[i];if(!uiPlayer){uiPlayer=UI_PLAYERS[i]=uiCreatePlayer(GRID.players[i]);if(!container)container=dGet(R.id.scoreboard);container.appendChild(uiPlayer)}uiPlayer.score.textContent=GRID.players[i].score}}
|
|
|
+function gridClickDelegate(e){var target=e.target;while(target&&(target.dataset&&!target.dataset.x))target=target.parentElement;if(target&&target.dataset&&target.dataset.x&&target.dataset.y){var clickedCell=UI_CELLS[parseInt(target.dataset.x,10)+parseInt(target.dataset.y,10)*GRID.width];if(clickedCell.data.isBlack)unselect();else if(clickedCell.data.definitions){var first=true;unselect();if(clickedCell.data.definitions[target.dataset.definition])clickedCell.data.definitions[target.dataset.definition].word.forEach(function(coordinates){select(coordinates[0],
|
|
|
+coordinates[1]);if(first&&!UI_CELLS[coordinates[0]+coordinates[1]*GRID.width].data.found){CURRENTINPUT=UI_CELLS[coordinates[0]+coordinates[1]*GRID.width];CURRENTINPUT.dom.classList.add(R.klass.cell.currentInput)}first=false})}else{var words=GRID.getWord(clickedCell.x,clickedCell.y);unselect();words.forEach(function(word){word.forEach(function(coordinates){select(coordinates[0],coordinates[1])})});target.classList.add(R.klass.cell.currentInput);CURRENTINPUT=clickedCell}}};function Definition(data){this.text=data["text"];this.direction=data["pos"];this.word=null}Definition.RIGHT_HORIZONTAL=1;Definition.RIGHT_VERTICAL=2;Definition.BOTTOM_HORIZONTAL=3;Definition.BOTTOM_VERTICAL=4;function Cell(){this.isBlack=false;this.definitions=null;this.found=null;this.letter=null}
|
|
|
+Cell.prototype.update=function(data,players){if(data["type"]===null)this.isBlack=true;else if(data["definitions"]!==undefined){this.definitions=[];data["definitions"].forEach(function(definition){this.definitions.push(new Definition(definition))}.bind(this))}else if(data["letter"]){this.letter=data["letter"];this.found=players[data["found"]];return data["v"]}return 0};
|
|
|
+function Player(data){this.id=data["name"];this.idEncoded=encodeURIComponent(data["name"]);this.score=data["score"];var pos=data["name"].indexOf("|");this.name=data["name"].substr(0,pos);this.color="#"+data["name"].substr(pos+1);console.log(this)}Player.prototype.update=function(data){this.score=data["score"];return data["v"]};
|
|
|
+function Grid(data){this.title=data["title"]||"";this.difficulty=data["difficulty"];this.width=data["w"];this.height=data["h"];this.players={};this.playerSelf=null;this.words=[];this.grid=[];for(var i=0;i<this.width;i++){this.grid[i]=[];for(var j=0;j<this.height;j++)this.grid[i][j]=new Cell}}
|
|
|
+Grid.prototype.computeWord=function(x,y,dx,dy){if(!this.grid[x+dx]||!this.grid[x+dx][y+dy]||this.grid[x+dx][y+dy].definitions||this.grid[x+dx][y+dy].isBlack)return[[x,y]];var word=this.computeWord(x+dx,y+dy,dx,dy);word.unshift([x,y]);return word};Grid.prototype.getWord=function(x,y){var words=[];this.words.forEach(function(word){for(var i=0,nbLetters=word.length;i<nbLetters;i++)if(word[i][0]==x&&word[i][1]==y){words.push(word);break}});return words};
|
|
|
+Grid.prototype.updatePlayers=function(playerData){var maxVersion=0;playerData.forEach(function(player){var localPlayer=this.players[player["name"]];if(!localPlayer)localPlayer=this.players[player["name"]]=new Player(player);maxVersion=Math.max(maxVersion,localPlayer.update(player))}.bind(this));return maxVersion};
|
|
|
+Grid.prototype.update=function(data){var maxVersion=null,topologyUpdated=false;data.forEach(function(cellData){var updateResult=this.grid[cellData["x"]][cellData["y"]].update(cellData,this.players);maxVersion=Math.max(maxVersion||0,updateResult);if(updateResult===0)topologyUpdated=true}.bind(this));if(topologyUpdated){var words=[];for(var i=0;i<this.width;i++)for(var j=0;j<this.height;j++)if(this.grid[i][j].definitions)this.grid[i][j].definitions.forEach(function(definition){var word;switch(definition.direction){case Definition.RIGHT_VERTICAL:word=
|
|
|
+this.computeWord(i+1,j,0,1);break;case Definition.RIGHT_HORIZONTAL:word=this.computeWord(i+1,j,1,0);break;case Definition.BOTTOM_VERTICAL:word=this.computeWord(i,j+1,0,1);break;case Definition.BOTTOM_HORIZONTAL:word=this.computeWord(i,j+1,1,0);break}words.push(word);definition.word=word}.bind(this));this.words=words}return maxVersion};var POLL_INTERVAL=5E3;function doGet(url,callback){var xhr=new XMLHttpRequest;xhr.onreadystatechange=function(e){if(xhr.readyState===4){var resp=null;if(xhr.status===200){resp=xhr.response;try{resp=JSON.parse((resp))}catch(e){resp=null}}callback(xhr.status,resp)}};xhr.open("GET",url,true);xhr.send(null)}
|
|
|
+function initPolling(){lazyGetPseudonyme(function(pseudo){if(pseudo)doGet("/api/poll?grid="+GRID_PUBLIC_ID+"&v="+KNOWN_VERSION,function(status,resp){if(resp){GRID=new Grid(resp);updateOnPollResult(resp);GRID.playerSelf=GRID.players[pseudo];scheduleNextPoll()}})})}
|
|
|
+function pollNow(){if(pollNow.polling!==true){if(pollNow.pollSchedule){clearTimeout(pollNow.pollSchedule);pollNow.pollSchedule=0}pollNow.polling=true;doGet("/api/poll?grid="+GRID_PUBLIC_ID+"&v="+KNOWN_VERSION,function(status,resp){pollNow.polling=false;if(resp)updateOnPollResult(resp);scheduleNextPoll()})}}function scheduleNextPoll(){if(!pollNow.pollSchedule)pollNow.pollSchedule=setInterval(pollNow,POLL_INTERVAL)};var GRID_PUBLIC_ID,KNOWN_VERSION=0,GRID,SELECTED=[],CURRENTINPUT=null;function lazyGetPseudonyme(cb){var pseudo=window["sessionStorage"].getItem("pseudonyme_"+GRID_PUBLIC_ID);if(pseudo)cb(pseudo);else doGet("/api/register?grid="+GRID_PUBLIC_ID,function(status,pseudo){if(status&&pseudo){window["sessionStorage"].setItem("pseudonyme_"+GRID_PUBLIC_ID,pseudo);cb(pseudo)}else cb(null)})}
|
|
|
+function keyPressHandler(cell,key){cell.dom.classList.add(R.klass.cell.pending);doGet("/api/put?grid="+GRID_PUBLIC_ID+"&key="+key+"&x="+cell.x+"&y="+cell.y+"&me="+GRID.playerSelf.idEncoded,function(status,resp){cell.dom.classList.remove(R.klass.cell.pending);if(status===403&&!cell.data.found)cell.dom.classList.add(R.klass.cell.wrong);else if(status===204)pollNow();else pollNow()})}
|
|
|
+function updateOnPollResult(resp){if(resp["players"]){GRID.updatePlayers(resp["players"]);onPlayersUpdated();console.log("players updated")}if(resp["grid"]){GRID.update(resp["grid"]);uiCreateGrid()}KNOWN_VERSION=Math.max(KNOWN_VERSION,resp["v"]||0)}function unselect(){SELECTED.forEach(function(cell){cell.dom.classList.remove(R.klass.cell.selected)});if(CURRENTINPUT){CURRENTINPUT.dom.classList.remove(R.klass.cell.currentInput);CURRENTINPUT=null}SELECTED=[]}
|
|
|
+function select(x,y){var cell=UI_CELLS[x+y*GRID.width];SELECTED.push(cell);cell.dom.classList.add(R.klass.cell.selected)}
|
|
|
+document.addEventListener("DOMContentLoaded",function(){GRID_PUBLIC_ID=document.location.hash.substr(1);if(GRID_PUBLIC_ID==""){document.location.href="/";return}document.addEventListener("click",gridClickDelegate);document.addEventListener("keypress",function(e){if(CURRENTINPUT&&!CURRENTINPUT.data.found)if(e.key.length===1){var key=e.key.charAt(0).toUpperCase();if(key.match(/[A-Z]/)){CURRENTINPUT.data.letter=key;keyPressHandler(CURRENTINPUT,key);onGridUpdated()}}else if(e.key.toUpperCase()=="DELETE"){CURRENTINPUT.data.letter=
|
|
|
+null;onGridUpdated()}else if(e.key.toUpperCase()=="BACKSPACE"){CURRENTINPUT.data.letter=null;onGridUpdated()}console.log(e)});initPolling()});
|