1<!DOCTYPE HTML> 2<html> 3 4<!-- 5 pgn4web javascript chessboard 6 copyright (C) 2009-2015 Paolo Casaschi 7 see README file and http://pgn4web.casaschi.net 8 for credits, license and more details 9--> 10 11<head> 12 13<title>pgn4web live broadcast</title> 14 15<!-- use the base tag to host live-compact.html on a different server than pgn4web.js 16 17<base href="http://pgn4web.casaschi.net"> 18 19--> 20 21<link href="live-compact.css" type="text/css" rel="stylesheet" /> 22 23<link rel="icon" sizes="16x16" href="pawn.ico" /> 24 25<script src="pgn4web.js" type="text/javascript"></script> 26 27<script src="fide-lookup.js" type="text/javascript"></script> 28 29<script type="text/javascript"> 30 "use strict"; 31 32 var demoFlag, alertFlag; 33 if ((gup("demo") == "true") || (gup("demo") == "t") || 34 (gup("refreshDemo") == "true") || (gup("refreshDemo") == "t")) { 35 demoFlag = true; alertFlag = true; 36 } else { demoFlag = false; alertFlag = false; } 37 38 var pgnFile_default = detectBaseLocation() ? 39 location.protocol + "//" + location.hostname + location.pathname.replace(/\/[^\/]*$/, "/live/live.pgn") : 40 "live/live.pgn"; 41 // accepts pgnData as alias for pgnFile for consistency with board.html 42 var pgnFile; 43 if ((pgnFile = gup("pgnData")) === "") { 44 if ((pgnFile = gup("pgnFile")) === "") { 45 pgnFile = pgnFile_default; 46 } 47 } 48 49 var refreshMinutes; 50 if ((refreshMinutes = gup("refreshMinutes")) === "") { 51 refreshMinutes = 1; 52 } else { 53 var testMinutes = refreshMinutes + ""; 54 if ((testMinutes.match(/[^0-9\.]/)) || (refreshMinutes === 0)) { 55 if (alertFlag) { 56 alert("ERROR: refreshMinutes parameter must be a positive number.\n" + 57 "Supplied " + testMinutes + "; defaulting to 1."); 58 } 59 refreshMinutes = 1; 60 } 61 } 62 63 var iniGame; 64 if ((iniGame = gup("initialGame")) === "") {iniGame = 1; } 65 66 if ((gup("showComments") == "true") || (gup("showComments") == "t")) { SetCommentsIntoMoveText(true); } 67 else { SetCommentsIntoMoveText(false); } 68 69 if ((gup("help") == "true") || (gup("help") == "t")) { developer_help(); } 70 71 SetPgnUrl(pgnFile); 72 SetImagePath("images/alpha/26"); 73 SetImageType("png"); 74 SetHighlightOption(true); // true or false 75 SetGameSelectorOptions(" select a game...", true, 0, 0, 0, 18, 18, 3, 0); // (head, num, chEvent, chSite, chRound, chWhite, chBlack, chResult, chDate) 76 77 SetCommentsOnSeparateLines(true); 78 SetAutoplayDelay(1000); // milliseconds 79 SetAutostartAutoplay(false); 80 SetAutoplayNextGame(false); 81 SetInitialGame(iniGame); 82 SetInitialVariation(0); 83 SetInitialHalfmove("end",true); 84 SetShortcutKeysEnabled(true); 85 86 SetLiveBroadcast(refreshMinutes, alertFlag, demoFlag); 87 88 function customFunctionOnCheckLiveBroadcastStatus() { 89 var theObj = document.getElementById("GameLiveStatus"); 90 theObj.innerHTML = theObj.title; 91 document.getElementById("playersDetails").className = LiveBroadcastStarted ? "headerHighlighted" : "header"; 92 document.getElementById("statusDetails").className = ((!LiveBroadcastStarted) || (LiveBroadcastEnded)) ? "headerHighlighted" : "header"; 93 document.getElementById("additionalMessage").innerHTML = LiveBroadcastEnded ? (theObj.innerHTML ? ", " : "") + "click H6 for the next event" : ""; 94 } 95 96 function customFunctionOnPgnTextLoad() { 97 // cope with occasional failures to load the live PGN data 98 if ((LiveBroadcastDelay !== 0) && (LiveBroadcastTicker > 0) && (!LiveBroadcastFoundOldGame)) { 99 var thisCurrentGame = currentGame; 100 SetInitialGame(iniGame); 101 SetInitialVariation(0); 102 setCurrentGameFromInitialGame(); 103 if (currentGame != thisCurrentGame) { 104 SetInitialHalfmove("end",true); 105 Init(); 106 GoToInitialHalfmove(); 107 } 108 } 109 } 110 111 function customFunctionOnPgnGameLoad() { 112 var ii, theObj, timeControl, gameTermination; 113 var objectsToTitle = ["GameEvent", "GameSite", "GameDate", "GameWhite", "GameBlack"]; 114 for (ii in objectsToTitle) { 115 if (theObj = document.getElementById(objectsToTitle[ii])) { theObj.title = simpleHtmlentitiesDecode(theObj.innerHTML); } 116 } 117 if (timeControl = customPgnHeaderTag("TimeControl")) { 118 if (theObj = document.getElementById("GameWhiteClock")) { theObj.title = simpleHtmlentitiesDecode("timecontrol: " + timeControl); } 119 if (theObj = document.getElementById("GameBlackClock")) { theObj.title = simpleHtmlentitiesDecode("timecontrol: " + timeControl); } 120 } else { 121 if (theObj = document.getElementById("GameWhiteClock")) { theObj.title = ""; } 122 if (theObj = document.getElementById("GameBlackClock")) { theObj.title = ""; } 123 } 124 if (gameTermination = customPgnHeaderTag("Termination")) { 125 if (theObj = document.getElementById("GameResult")) { theObj.title = simpleHtmlentitiesDecode("termination: " + gameTermination); } 126 } else { 127 if (theObj = document.getElementById("GameResult")) { theObj.title = ""; } 128 } 129 if ((gameRound[currentGame] !== undefined) && 130 (gameRound[currentGame] !== "") && 131 (gameRound[currentGame] != "*") && 132 (gameRound[currentGame] != "?")) { 133 document.getElementById("roundDetails").innerHTML = " (" + gameRound[currentGame] + ")"; 134 } else { 135 document.getElementById("roundDetails").innerHTML = ""; 136 } 137 138 if (gameResult[currentGame] !== undefined) { 139 if ((gameResult[currentGame] == "*") || (gameResult[currentGame] == "?")) { 140 document.getElementById("GameResult").className = "headerNosize"; 141 } else { 142 document.getElementById("GameResult").className = "headerHighlightedNosize"; 143 } 144 } else { 145 document.getElementById("GameResult").className = "headerNosize"; 146 document.getElementById("GameResult").innerHTML = ""; 147 } 148 theObj = document.getElementById("GameText"); 149 if ((theObj) && (theObj.scrollHeight !== undefined) && (theObj.scrollTop !== undefined) && ((!LiveBroadcastFoundOldGame) || (LiveBroadcastOldCurrentPlyLast && (LiveBroadcastOldCurrentPly < StartPly+PlyNumber)))) { 150 theObj.scrollTop = theObj.scrollHeight; 151 } 152 } 153 154 function customFunctionOnMove() { 155 document.getElementById("systemMessage").style.display = 156 customPgnCommentTag("pgn4web", "pgn4webMessage") !== "" ? "none" : "inline"; 157 } 158 159 var checkForNewLiveEventInterval = null; 160 function checkForNewLiveEvent() { 161 document.getElementById("messageLine").style.visibility = "hidden"; 162 if (checkForNewLiveEventInterval) { clearTimeout(checkForNewLiveEventInterval); } 163 // started as timeout otherwise some browser could suppress visual feedback 164 checkForNewLiveEventInterval = setTimeout('refreshPgnSource();document.getElementById("messageLine").style.visibility = "visible";', 111); 165 } 166 167 // customShortcutKey_Shift_1 defined by fide-lookup.js 168 // customShortcutKey_Shift_2 defined by fide-lookup.js 169 170 171function gup(name) { 172 173 name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); 174 var regexS = "[\\?&]"+name+"=([^&#]*)"; 175 // commented below to match first occurrence (to avoid users overruling setting) 176 // regexS = regexS+"(?!.*"+regexS+")"; // matches the LAST occurrence 177 var regex = new RegExp( regexS, "i" ); 178 var results = regex.exec( window.location.href ); 179 if (results !== null) { return decodeURIComponent(results[1]); } 180 181 // allows for short version of the URL parameters, for instance sC matches squareColor 182 var compact_name = name.charAt(0); 183 for (var i=1; i<name.length; i++) { 184 if (name.charAt(i).match(/[A-Z]/)) { compact_name = compact_name + name.charAt(i).toLowerCase(); } 185 } 186 name = compact_name; 187 188 name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]"); 189 regexS = "[\\?&]"+name+"=([^&#]*)"; 190 // commented below to match first occurrence (to avoid users overruling setting) 191 // regexS = regexS+"(?!.*"+regexS+")"; // matches the LAST occurrence 192 regex = new RegExp( regexS, "i" ); 193 194 results = regex.exec( window.location.href ); 195 if (results !== null) { return decodeURIComponent(results[1]); } 196 197 return ""; 198} 199 200function developer_help() { 201 alert("pgn4web live-compact.html parameters" + "\n" + 202 " - pgnData = " + pgnFile + "; PGN file to load (default " + pgnFile_default + ")" + "\n" + 203 " - initialGame = " + iniGame + "; initial game to load, a number or first, last, random or a search string (default 1)" + "\n" + 204 " - refreshMinutes = " + refreshMinutes + "; refresh interval in minutes, decimals allowed (default 1)" + "\n" + 205 " - showComments = " + commentsIntoMoveText + "; (default false)" + "\n" + 206 " - refreshDemo = " + demoFlag + "; sets live demo mode (default false)" + "\n" + 207 " - help = true; prints this help (default false)"); 208} 209 210function user_help() { 211 212 var plural = refreshMinutes != 1 ? "s" : ""; 213 var demoString = demoFlag ? "demo mode enabled" + "\n" : ""; 214 215 var helpText = "Chess games live broadcast using pgn4web v" + pgn4web_version + "\n" + 216 "\n" + 217 "Games are automatically updated every " + 218 refreshMinutes + " minute" + plural + " from the remote file " + 219 "(" + pgnFile + "). " + 220 "If the shown game is kept at the last available move, " + 221 "upon refresh the chessboard automatically advances " + 222 "to the game's latest position. " + 223 "The refresh stops once all games are finished. " + 224 "If no games are shown, just wait for the live broadcast to start. " + 225 "There is no need to reload the webpage to refresh games, " + 226 "but it's possible to manually force a refresh by clicking on square H6." + "\n" + 227 "\n" + 228 "Chessboard squares are input buttons controlling games display (full list by clicking square G8), including:" + "\n" + 229 "\n" + 230 "A1 / H1: game start / end" + "\n" + 231 "D1 / E1: move back / forwards" + "\n" + 232 "A3 / H3: load first / last game" + "\n" + 233 "C3 / F3: load previous / next game" + "\n" + 234 "A6 / B6: pause / restart live broadcast automatic refresh" + "\n" + 235 "C6 / F6: jump to previous / next finished game" + "\n" + 236 "D6 / E6: jump to previous / next unfinished game" + "\n" + 237 "H6: force games refresh during live broadcast" + "\n" + 238 "A8: debug info" + "\n" + 239 "G8 / H8: shortcut squares help / pgn4web help" + "\n" + 240 "\n" + 241 "Please note all squares are listed assuming White on bottom, plese adjust square labels if the chessboard is flipped." + "\n" + 242 "\n" + 243 "Press OK for more pgn4web help information" + 244 "\n "; 245 246 if (confirm(helpText)) { displayHelp(); } 247} 248 249</script> 250 251</head> 252 253<body> 254 255<!-- paste your PGN below and make sure you dont specify an external source with SetPgnUrl() --> 256<form style="display: none;"><textarea style="display: none;" id="pgnText"> 257 258</textarea></form> 259<!-- paste your PGN above and make sure you dont specify an external source with SetPgnUrl() --> 260 261<center> 262 263<!-- need the external table to force height of 360 (see blackberry background issue) --> 264<!-- 460 is the max width for a 480 wide screen allowing for scrollbars --> 265<!-- 360 is the max height for a 360 tall screen --> 266<table id="outerTable" width=460 height=360 cellpadding=5 cellspacing=0 border=0> 267<tr><td align=center valign=top> 268 269<!-- width 450 = 460 outerTable width - 2 * 5 cellpadding --> 270<table width=450 cellpadding=0 cellspacing=0 border=0> 271<tr height=27> 272<td align=center valign=bottom style="padding-bottom: 4px;"> 273<div id="GameSelector"></div> 274</td> 275</tr> 276</table> 277 278<!-- same 450 width as above --> 279<table id="eventDetails" class="header" width=450px cellpadding=0 cellspacing=0 border=0> 280<tr> 281<td width=100 align=left valign=middle style="padding: 3px;"> 282<div id="GameSite" style="width: 94px; height: 1.3em; line-height: 1.3em; overflow: hidden; white-space: nowrap;"></div> 283</td> 284<td width=250 align=center valign=middle style="padding: 3px;"> 285<div style="width: 244px; height: 1.3em; line-height: 1.3em; overflow: hidden;"><span id="GameEvent"></span><span id="roundDetails"></span></div> 286</td> 287<td width=100 align=right valign=middle style="padding: 3px;"> 288<div id="GameDate" style="width: 94px; height: 1.3em; line-height: 1.3em; overflow: hidden"></div> 289</td> 290</tr> 291</table> 292 293<!-- same 450 width as above --> 294<table id="playersDetails" class="header" width=450px cellpadding=0 cellspacing=0 border=0> 295<tr> 296<td width=65 align=left valign=middle style="padding: 3px;"> 297<div id="GameWhiteClock" style="width: 59px; height: 1.3em; line-height: 1.3em; overflow: hidden; white-space: nowrap;"></div> 298</td> 299<td width=320 align=center valign=middle style="padding: 3px;"> 300<div style="width: 314px; height: 1.3em; line-height: 1.3em; overflow: hidden; white-space: nowrap;"> 301<span id="GameWhite"></span> 302 303<span id="GameBlack"></span> 304</div> 305</td> 306<td width=65 align=right valign=middle style="padding: 3px;"> 307<div id="GameBlackClock" style="width: 59px; height: 1.3em; line-height: 1.3em; overflow: hidden; white-space: nowrap;"></div> 308</td> 309</tr> 310</table> 311 312<!-- same 450 width as above --> 313<table width=450px cellpadding=0 cellspacing=0 border=0> 314<tr> 315<!-- 240 chessboard size = 8 * (26 square size + 2 * (2 square border)) --> 316<!-- 246 = (chessboard size) + (6 right padding) --> 317<td width=246 align=left valign=top style="padding-top: 8px; padding-bottom: 8px; padding-left: 0px; padding-right: 6px;"> 318<span id="GameBoard"></span> 319</td> 320 321<!-- right column width 204 = (460 outer cell width) - (246 left column width) - (2 * 5 cellpaddding) --> 322<td width=204 align=left valign=top style="padding-top: 8px; padding-bottom: 8px; padding-left: 0px; padding-right: 0px;"> 323<!-- height 240 = chessboard size --> 324<!-- width 199 = table cell size - 5 padding --> 325<div class="movebox" id="GameText" style="height: 240px; width:199px; padding-right: 5px; overflow-x: hidden; overflow-y: auto;"> 326</div> 327</td> 328<tr> 329</table> 330 331<!-- same 450 width as above --> 332<table id="statusDetails" class="header" width=450px cellpadding=0 cellspacing=0 border=0> 333<tr> 334<td width=55 align=left valign=middle style="padding: 3px;"> 335<div style="width: 49px; height: 1.3em; line-height: 1.3em; overflow: hidden; white-space: nowrap;"> 336<span id="GameResult" class="headerNosize"></span> 337</div> 338</td> 339<td width=340px style="padding: 3px;" align=center valign=middle> 340<div id="messageLine" style="width: 334px; height: 1.3em; line-height: 1.3em; overflow: hidden; white-space: nowrap;"> 341<span id="pgn4webMessage"></span> 342<span id="systemMessage"><span id="GameLiveStatus"></span><span id="additionalMessage"></span></span> 343</div> 344</td> 345<td width=55 align=right valign=middle style="padding: 3px;"> 346<div style="width: 49px; height: 1.3em; line-height: 1.3em; overflow: hidden; white-space: nowrap;"> 347<a id="helplink" class="helplinkNosize" href="javascript: user_help();" onFocus="this.blur()" title="pgn4web live broadcast help">help</a> 348</div> 349</td> 350</tr> 351</table> 352 353</td></tr> 354</table> 355</center> 356 357<script type="text/javascript"> 358 "use strict"; 359 var theObj = document.getElementById("helplink"); 360 if (demoFlag && theObj) { theObj.innerHTML = "demo"; } 361</script> 362 363</body> 364 365</html> 366