|
|
@@ -1,23 +1,15 @@
|
|
|
-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()});
|
|
|
+var e={};function h(a){var b=document.createElement("li"),c=document.createElement("span");c.className="player-name";c.textContent=a.name;b.appendChild(c);b.i=document.createElement("span");b.i.className="player-score";b.appendChild(b.i);b.style.color=a.color;return b}
|
|
|
+function k(){var a,b=[],c;for(c in l.g){var d=e[c];d||(d=e[c]=h(l.g[c]),c===l.j.id&&d.classList.add("player-self"),a||(a=document.getElementById("scoreboardPlayers")),a.appendChild(d));d.i.textContent=l.g[c].i;b.push(c)}b.sort(function(a,b){return l.g[b].i-l.g[a].i});c=0;for(a=b.length;c<a;c++)e[b[c]].style.order=c}
|
|
|
+setInterval(function(){if(l){var a=(Date.now()-l.D)/1E3,b=Math.floor(a%60),a=(a-b)/60,c=Math.floor(a%60),a=Math.floor((a-c)/60),a=(a?a+":":"")+((10>c?"0":"")+c+":")+((10>b?"0":"")+b);document.getElementById("gridTime").textContent=a}},1E3);var m=[];function p(a,b,c){var d=document.createElement("div");d.className="cell";if(a.o)d.classList.add("cell-disabled");else if(null!==a.f){d.classList.add("cell-definition");for(var f=document.createElement("span"),g=0,G=a.f.length;g<G;g++){var H=a.f[g],n=document.createElement("span");n.dataset.x=b;n.dataset.y=c;n.dataset.definition=g;n.className="definition";n.innerHTML=H.text.join("<br/>");f.appendChild(n)}d.appendChild(f)}else d.classList.add("cell-letter");return d}
|
|
|
+function q(){var a=document.createDocumentFragment();document.getElementById("gridTitle").textContent=l.F;document.getElementById("gridDifficulty").textContent=l.G;for(var b=0;b<l.s;b++){var c=document.createElement("div");c.className="crossword-line";a.appendChild(c);for(var d=0;d<l.b;d++){var f=p(l.c[d][b],d,b);f.dataset.x=d;f.dataset.y=b;c.appendChild(f);m.push({x:d,y:b,a:f,data:l.c[d][b]})}}for(b=0;b<l.s;b++)for(d=0;d<l.b;d++)f=m[b*l.b+d],f.data.f&&f.data.f.forEach(function(a){switch(a.direction){case 2:m[b*
|
|
|
+l.b+d+1].a.classList.add("definition-right-vt");break;case 1:m[b*l.b+d+1].a.classList.add("definition-right-hz");break;case 4:m[(b+1)*l.b+d].a.classList.add("definition-bottom-vt");break;case 3:m[(b+1)*l.b+d].a.classList.add("definition-bottom-hz")}});r();c=document.getElementById("grid");c.textContent="";c.appendChild(a)}
|
|
|
+function r(){m.forEach(function(a){a.data.f||a.data.o||(a.data.m?(a.a.textContent=a.data.m,a.data.l&&(a.a.classList.add("cell-letter-correct"),a.a.classList.remove("cell-letter-wrong"),a.a.style.color=a.data.l.color)):a.a.textContent="")})}function t(){var a=u,b=document.getElementById("input");b.style.top=a.a.offsetTop+"px";b.style.left=a.a.offsetLeft+"px";b.focus()}
|
|
|
+function v(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=m[parseInt(a.dataset.x,10)+parseInt(a.dataset.y,10)*l.b];if(b.data.o)w();else{if(b.data.f){var c=!0;w();b.data.f[a.dataset.definition]&&b.data.f[a.dataset.definition].B.forEach(function(a){x(a[0],a[1]);c&&!m[a[0]+a[1]*l.b].data.l&&(u=m[a[0]+a[1]*l.b],u.a.classList.add("cell-input"));c=!1})}else{var d=y(b.x,b.y);w();d.forEach(function(a){a.forEach(function(a){x(a[0],a[1])})});
|
|
|
+a.classList.add("cell-input");u=b}t()}}};function z(a){this.text=a.text;this.direction=a.pos;this.B=null}function A(){this.o=!1;this.m=this.l=this.f=null}A.prototype.update=function(a,b){if(null===a.type)this.o=!0;else if(void 0!==a.definitions)this.f=[],a.definitions.forEach(function(a){this.f.push(new z(a))}.bind(this));else if(a.letter)return this.m=a.letter,this.l=b[a.found],a.v;return 0};
|
|
|
+function B(a,b){this.F=a.title||"";this.G=a.difficulty;this.b=a.w;this.s=a.h;this.D=a.startTime||0;this.g={};this.j=null;this.u=b;this.A=[];this.c=[];for(var c=0;c<this.b;c++){this.c[c]=[];for(var d=0;d<this.s;d++)this.c[c][d]=new A}}function C(a,b,c,d,f){if(!a.c[b+d]||!a.c[b+d][c+f]||a.c[b+d][c+f].f||a.c[b+d][c+f].o)return[[b,c]];a=C(a,b+d,c+f,d,f);a.unshift([b,c]);return a}
|
|
|
+function y(a,b){var c=[];l.A.forEach(function(d){for(var f=0,g=d.length;f<g;f++)if(d[f][0]==a&&d[f][1]==b){c.push(d);break}});return c}function D(a){var b=0;a.forEach(function(a){var c=this.g[a.name];c||(c=this.g[a.name]=new E(a));b=Math.max(b,c.update(a))}.bind(l))}
|
|
|
+B.prototype.update=function(a){var b=null,c=!1;a.forEach(function(a){a=this.c[a.x][a.y].update(a,this.g);b=Math.max(b||0,a);0===a&&(c=!0)}.bind(this));if(c){for(var d=[],f=0;f<this.b;f++)for(var g=0;g<this.s;g++)this.c[f][g].f&&this.c[f][g].f.forEach(function(a){var b;switch(a.direction){case 2:b=C(this,f+1,g,0,1);break;case 1:b=C(this,f+1,g,1,0);break;case 4:b=C(this,f,g+1,0,1);break;case 3:b=C(this,f,g+1,1,0)}d.push(b);a.B=b}.bind(this));this.A=d}return b};function E(a){this.id=a.name;this.C=encodeURIComponent(a.name);this.i=a.score;var b=a.name.indexOf("|");this.name=a.name.substr(0,b);this.color="#"+a.name.substr(b+1)}E.prototype.update=function(a){this.i=a.score;return a.v};function F(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(f){a=null}}b(c.status,a)}};c.open("GET",a,!0);c.send(null)}function I(){J(function(a){a&&F("/api/poll?grid="+K+"&v="+L,function(b,c){c&&(l=new B(c,a),c.players&&(D(c.players),l.j||(l.j=l.g[l.u]),k()),c.grid&&(l.update(c.grid),q()),L=Math.max(L,c.v||0),M())})})}
|
|
|
+function N(){!0!==N.c&&(N.b&&(clearTimeout(N.b),N.b=0),N.c=!0,F("/api/poll?grid="+K+"&v="+L,function(a,b){N.c=!1;b&&(b.players&&(D(b.players),l.j||(l.j=l.g[l.u]),k()),b.grid&&(l.update(b.grid),r()),L=Math.max(L,b.v||0));M()}))}function M(){N.b||(N.b=setInterval(N,5E3))};var K,L=0,l,O=[],u=null;function J(a){var b=window.sessionStorage.getItem("pseudonyme_"+K);b?a(b):F("/api/register?grid="+K,function(b,d){b&&d?(window.sessionStorage.setItem("pseudonyme_"+K,d),a(d)):a(null)})}function P(a){var b=u;b.a.classList.add("cell-letter-pending");F("/api/put?grid="+K+"&key="+a+"&x="+b.x+"&y="+b.y+"&me="+l.j.C,function(a){b.a.classList.remove("cell-letter-pending");403!==a||b.data.l?N():b.a.classList.add("cell-letter-wrong")})}
|
|
|
+function w(){O.forEach(function(a){a.a.classList.remove("cell-selected")});u&&(u.a.classList.remove("cell-input"),u=null);O=[]}function x(a,b){var c=m[a+b*l.b];O.push(c);c.a.classList.add("cell-selected")}
|
|
|
+document.addEventListener("DOMContentLoaded",function(){K=document.location.hash.substr(1);""==K?document.location.href="/":(document.addEventListener("click",v),document.addEventListener("keypress",function(a){if(u&&!u.data.l)if(1===a.key.length){var b=a.key.charAt(0).toUpperCase();b.match(/[A-Z]/)&&(u.data.m=b,P(b),r())}else"DELETE"==a.key.toUpperCase()?(u.a.classList.remove("cell-letter-wrong"),u.data.m=null,r()):"BACKSPACE"==a.key.toUpperCase()&&(u.a.classList.remove("cell-letter-wrong"),u.data.m=
|
|
|
+null,r());console.log(a)}),I())});
|