Fixes for keydown events

This commit is contained in:
Neale Pickett 2013-11-02 14:35:21 -06:00
parent 562ae7042f
commit 45845ab9ee
1 changed files with 364 additions and 337 deletions

View File

@ -28,10 +28,10 @@ longnames = false;
tenths = true; tenths = true;
/* State names */ /* State names */
var SETUP = 0; // !P 30:00 !J 2:00 var SETUP = 0; // !P 30:00 !J 2:00
var JAM = 1; // P J 2:00 var JAM = 1; // P J 2:00
var LINEUP = 2; // P J 1:00 var LINEUP = 2; // P J 1:00
var TIMEOUT = 3; // !P J 1:00 var TIMEOUT = 3; // !P J 1:00
var periodtext = ["Period 1", "Halftime", "Period 2", "Break"]; var periodtext = ["Period 1", "Halftime", "Period 2", "Break"];
var jamtext = ["Jam", "Lineup", "Timeout", "Setup"]; var jamtext = ["Jam", "Lineup", "Timeout", "Setup"];
@ -42,148 +42,148 @@ var state = SETUP;
var timer_updates = []; var timer_updates = [];
function update() { function update() {
for (var i in timer_updates) { for (var i in timer_updates) {
var u = timer_updates[i]; var u = timer_updates[i];
u(); u();
} }
} }
// Create a timer on [element]. // Create a timer on [element].
// If [tenths] is true, show tenths of a second. // If [tenths] is true, show tenths of a second.
// If [callback] is defined, call it when time runs out. // If [callback] is defined, call it when time runs out.
function startTimer(element, tenths, callback) { function startTimer(element, tenths, callback) {
var startTime; var startTime;
var running = false; var running = false;
var set_duration = 0; var set_duration = 0;
var duration = 0; var duration = 0;
var className; var className;
// Re-calculate and update displayed time // Re-calculate and update displayed time
function refresh () { function refresh () {
var remain = element.remaining(); var remain = element.remaining();
var min = Math.floor(Math.abs(remain / 60000)); var min = Math.floor(Math.abs(remain / 60000));
var sec = (Math.floor(Math.abs(remain / 100)) / 10) % 60; var sec = (Math.floor(Math.abs(remain / 100)) / 10) % 60;
// Set classes // Set classes
element.className = className; element.className = className;
if ((! className) && (remain <= 20000)) { if ((! className) && (remain <= 20000)) {
element.className += " lowtime"; element.className += " lowtime";
} }
if (! running) { if (! running) {
element.className += " paused"; element.className += " paused";
} }
// Has the timer run out? // Has the timer run out?
if ((set_duration > 0) && (remain <= 0)) { if ((set_duration > 0) && (remain <= 0)) {
duration = 0; duration = 0;
sec = 0; sec = 0;
running = false; running = false;
if (callback) { if (callback) {
callback(); callback();
} }
} }
// .toFixed() rounds, we want to truncate // .toFixed() rounds, we want to truncate
if (! tenths) { if (! tenths) {
sec = Math.floor(sec); sec = Math.floor(sec);
} else { } else {
sec = sec.toFixed(1); sec = sec.toFixed(1);
} }
// Zero-pad // Zero-pad
if (sec < 10) { if (sec < 10) {
sec = "0" + sec; sec = "0" + sec;
} }
var t = min + ":" + sec; var t = min + ":" + sec;
if (t != element.innerHTML) { if (t != element.innerHTML) {
element.innerHTML = t; element.innerHTML = t;
} }
} }
// Return remaining time in milliseconds // Return remaining time in milliseconds
element.remaining = function() { element.remaining = function() {
if (running) { if (running) {
var now = (new Date()).getTime(); var now = (new Date()).getTime();
return duration - (now - startTime); return duration - (now - startTime);
} else { } else {
return duration; return duration;
} }
} }
// Set timer to [d] milliseconds. // Set timer to [d] milliseconds.
// Put element into class [cn], if set. // Put element into class [cn], if set.
element.set = function(t, cn) { element.set = function(t, cn) {
startTime = (new Date()).getTime(); startTime = (new Date()).getTime();
set_duration = t; set_duration = t;
duration = t; duration = t;
className = cn; className = cn;
refresh(); refresh();
} }
// Start timer // Start timer
element.start = function() { element.start = function() {
if (! running) { if (! running) {
startTime = (new Date()).getTime(); startTime = (new Date()).getTime();
running = true; running = true;
} }
refresh(); refresh();
} }
// Stop timer // Stop timer
element.stop = function() { element.stop = function() {
if (running) { if (running) {
duration = element.remaining(); duration = element.remaining();
running = false; running = false;
} }
refresh(); refresh();
} }
timer_updates.push(refresh); timer_updates.push(refresh);
} }
// Transition state machine based on state // Transition state machine based on state
function transition(newstate) { function transition(newstate) {
var jt = e("jam"); var jt = e("jam");
var pt = e("period"); var pt = e("period");
var jtext = e("jamtext"); var jtext = e("jamtext");
var jno = e("jamno"); var jno = e("jamno");
if ((newstate === undefined) || (newstate == state)) { if ((newstate === undefined) || (newstate == state)) {
return; return;
} }
if ((state == SETUP) && window.penalties) { if ((state == SETUP) && window.penalties) {
penalties_duck(); penalties_duck();
} }
state = newstate; state = newstate;
if (state == JAM) { if (state == JAM) {
pt.start(); pt.start();
jt.set(120000); jt.set(120000);
jt.start(); jt.start();
jtext.innerHTML = jamtext[0]; jtext.innerHTML = jamtext[0];
jamno += 1; jamno += 1;
jno.innerHTML = jamno; jno.innerHTML = jamno;
} else if (state == LINEUP) { } else if (state == LINEUP) {
pt.start(); pt.start();
jt.set(30000, "lineup"); jt.set(30000, "lineup");
jt.start(); jt.start();
jtext.innerHTML = jamtext[1]; jtext.innerHTML = jamtext[1];
} else if (state == TIMEOUT) { } else if (state == TIMEOUT) {
pt.stop(); pt.stop();
if (pt.remaining() <= 0) { if (pt.remaining() <= 0) {
pt.set(1800000); pt.set(1800000);
} }
jt.set(0, "timeout"); jt.set(0, "timeout");
jt.start(); jt.start();
jtext.innerHTML = jamtext[2]; jtext.innerHTML = jamtext[2];
} }
// Reset lead jammer indicators // Reset lead jammer indicators
e("jammer-a").className = ""; e("jammer-a").className = "";
e("jammer-b").className = ""; e("jammer-b").className = "";
} }
@ -213,32 +213,32 @@ function notice_expire() {
} }
function notice(n) { function notice(n) {
var c = document.getElementById("notice"); var c = document.getElementById("notice");
c.style.display = "block"; c.style.display = "block";
if (notices[n]) { if (notices[n]) {
c.innerHTML = notices[n]; c.innerHTML = notices[n];
clearTimeout(notice_timer); clearTimeout(notice_timer);
notice_timer = setTimeout(function() {notice_expire()}, 8000); notice_timer = setTimeout(function() {notice_expire()}, 8000);
} else { } else {
notice_expire(); notice_expire();
} }
} }
function e(id) { function e(id) {
ret = document.getElementById(id); ret = document.getElementById(id);
if (! ret) { if (! ret) {
return Array(); return Array();
} }
return ret; return ret;
} }
function score(team, points) { function score(team, points) {
var te = document.getElementById("score-" + team); var te = document.getElementById("score-" + team);
var ts = Number(te.innerHTML); var ts = Number(te.innerHTML);
ts += points; ts += points;
te.innerHTML = ts; te.innerHTML = ts;
} }
/*********************************** /***********************************
@ -248,131 +248,158 @@ function score(team, points) {
var logo = {a:-1, b:-1}; var logo = {a:-1, b:-1};
function leadJammer(team) { function leadJammer(team) {
tgt = e("jammer-" + team); tgt = e("jammer-" + team);
var on = ! tgt.className; var on = ! tgt.className;
e("jammer-a").className = ""; e("jammer-a").className = "";
e("jammer-b").className = ""; e("jammer-b").className = "";
if (on) tgt.className = "lead"; if (on) tgt.className = "lead";
} }
function handle(event) { function handle(event) {
var tgt = event.target || window.event.srcElement; var tgt = event.target || window.event.srcElement;
var team = tgt.id.substr(tgt.id.length - 1); var team = tgt.id.substr(tgt.id.length - 1);
var adj = event.shiftKey?-1:1; var adj = event.shiftKey?-1:1;
var mod = (event.ctrlKey || event.altKey); var mod = (event.ctrlKey || event.altKey);
var newstate; var newstate;
switch (tgt.id) { switch (tgt.id) {
case "logo-a": case "logo-a":
case "logo-b": case "logo-b":
if (state == SETUP) { if (state == SETUP) {
if (true) { if (true) {
var t, name; var t, name;
logo[team] = (teams.length + logo[team] + adj) % teams.length; logo[team] = (teams.length + logo[team] + adj) % teams.length;
t = teams[logo[team]]; t = teams[logo[team]];
if (longnames) { if (longnames) {
name = t[2]; name = t[2];
} else { } else {
name = t[0]; name = t[0];
} }
e("name-" + team).innerHTML = name; e("name-" + team).innerHTML = name;
tgt.src = "logos/" + t[1]; tgt.src = "logos/" + t[1];
if (window.penalties) { if (window.penalties) {
penalties_setTeamName(team, t[0]); penalties_setTeamName(team, t[0]);
} }
} }
} else { } else {
score(team, -adj); score(team, -adj);
} }
break; break;
case "jammer-a": case "jammer-a":
case "jammer-b": case "jammer-b":
leadJammer(team); leadJammer(team);
break; break;
case "timeouts-a": case "timeouts-a":
case "timeouts-b": case "timeouts-b":
// Allow for timeouts > 3 // Allow for timeouts > 3
var v = Number(tgt.innerHTML); var v = Number(tgt.innerHTML);
v -= adj; v -= adj;
if (v == -1) v = 3; if (v == -1) v = 3;
tgt.innerHTML = v; tgt.innerHTML = v;
break; break;
case "period": case "period":
if ((state == SETUP) || (state == TIMEOUT)) { if ((state == SETUP) || (state == TIMEOUT)) {
// Nothin' // Nothin'
} else { } else {
newstate = TIMEOUT; newstate = TIMEOUT;
} }
break; break;
case "periodtext": case "periodtext":
var pt; var pt;
if (mod) { if (mod) {
pt = prompt("Enter new period indicator text", tgt.innerHTML); pt = prompt("Enter new period indicator text", tgt.innerHTML);
} else { } else {
var ptl = periodtext.length; var ptl = periodtext.length;
period = (period + ptl + adj) % ptl; period = (period + ptl + adj) % ptl;
pt = periodtext[period]; pt = periodtext[period];
} }
if (pt) { if (pt) {
tgt.innerHTML = pt; tgt.innerHTML = pt;
if (state == TIMEOUT) { if (state == TIMEOUT) {
jamno = 0; jamno = 0;
e("jamno").innerHTML = jamno; e("jamno").innerHTML = jamno;
} }
} }
break; break;
case "jam": case "jam":
if (state == JAM) { if (state == JAM) {
newstate = LINEUP; newstate = LINEUP;
} else { } else {
newstate = JAM; newstate = JAM;
} }
break; break;
case "jamno": case "jamno":
jamno -= adj; jamno -= adj;
tgt.innerHTML = jamno; tgt.innerHTML = jamno;
break; break;
case "score-a": case "score-a":
case "score-b": case "score-b":
if (state == SETUP) { if (state == SETUP) {
var s = prompt("Enter score for team " + team, tgt.innerHTML); var s = prompt("Enter score for team " + team, tgt.innerHTML);
if (s) { if (s) {
tgt.innerHTML = s; tgt.innerHTML = s;
} }
} else { } else {
score(team, adj); score(team, adj);
} }
break; break;
} }
transition(newstate); transition(newstate);
} }
function key(event) { function key(event) {
var e = event || window.event; var e = event || window.event;
var c; var k = e.which || e.keyCode || 0;
var newstate; var c;
var newstate;
switch (e.keyCode) { switch (k) {
case 32:
c = " ";
break;
case 38: case 38:
c = "up"; c = "up";
break; break;
case 40: case 40:
c = "down"; c = "down";
break; break;
case 188:
c = ",";
break;
case 190:
c = ".";
break;
case 221:
c = e.shiftKey ? "}" : "]";
break;
case 219:
c = e.shiftKey ? "{" : "[";
break;
default: default:
c = String.fromCharCode(e.which || e.keyCode || 0); if ((k >= 48) && (k <= 90)) {
c = String.fromCharCode(k);
if (! e.shiftKey) {
c = c.toLowerCase();
}
} else {
c = null;
}
break; break;
} }
switch (c) { bige = e;
console.log("Key " + k + " pressed: " + c + " === " + e.which);
switch (c) {
case "up": case "up":
if ((state == TIMEOUT) || (state == SETUP)) { if ((state == TIMEOUT) || (state == SETUP)) {
var pt = document.getElementById("period"); var pt = document.getElementById("period");
@ -387,59 +414,59 @@ function key(event) {
pt.set(rem - 1000); pt.set(rem - 1000);
} }
break; break;
case " ": case " ":
if (state == JAM) { if (state == JAM) {
newstate = LINEUP; newstate = LINEUP;
} else { } else {
newstate = JAM; newstate = JAM;
} }
break; break;
case "t": case "t":
newstate = TIMEOUT; newstate = TIMEOUT;
break; break;
case "a": case "a":
case "[": case "[":
score('a', 1); score('a', 1);
break; break;
case "b": case "b":
case "]": case "]":
score('b', 1); score('b', 1);
break; break;
case "A": case "A":
case "{": case "{":
score('a', -1); score('a', -1);
break; break;
case "B": case "B":
case "}": case "}":
score('b', -1); score('b', -1);
break; break;
case ",": case ",":
leadJammer('a'); leadJammer('a');
break; break;
case ".": case ".":
leadJammer('b'); leadJammer('b');
break; break;
case "1": case "1":
case "2": case "2":
case "3": case "3":
case "4": case "4":
case "5": case "5":
case "6": case "6":
case "7": case "7":
case "8": case "8":
case "9": case "9":
case "0": case "0":
var n = Number(c); var n = Number(c);
window.notice(n); window.notice(n);
} }
transition(newstate); transition(newstate);
} }
function save() { function save() {
chrome.storage.sync.set( chrome.storage.local.set(
{ {
"period_clock": e("period").remaining(), "period_clock": e("period").remaining(),
"name_a": e("name-a").innerHTML, "name_a": e("name-a").innerHTML,
@ -455,21 +482,21 @@ function save() {
} }
); );
} }
function iecheck() { function iecheck() {
// If it's IE, it's got to be at least 7 // If it's IE, it's got to be at least 7
var ua = navigator.userAgent; var ua = navigator.userAgent;
var ie = ua.indexOf("MSIE "); var ie = ua.indexOf("MSIE ");
if (ie == -1) { if (ie == -1) {
// Not IE // Not IE
return; return;
} else { } else {
var n = parseFloat(ua.substring(ie + 5, ua.indexOf(";", ie))); var n = parseFloat(ua.substring(ie + 5, ua.indexOf(";", ie)));
if (n < 7) { if (n < 7) {
alert("Your browser is too old to run the Woozle scoreboard.\nYou can use Firefox, Chrome, Opera, or Internet Explorer 7 and up."); alert("Your browser is too old to run the Woozle scoreboard.\nYou can use Firefox, Chrome, Opera, or Internet Explorer 7 and up.");
} }
} }
} }
function ei(name) { function ei(name) {
@ -481,12 +508,12 @@ function ei(name) {
} }
function start() { function start() {
resize(); resize();
iecheck(); iecheck();
var p = document.getElementById("period"); var p = document.getElementById("period");
var j = document.getElementById("jam"); var j = document.getElementById("jam");
var c; var c;
// XXX: I think, instead of null, you can pass in a dictionary of defaults // XXX: I think, instead of null, you can pass in a dictionary of defaults
function load(state) { function load(state) {
@ -505,51 +532,51 @@ function start() {
startTimer(p); startTimer(p);
p.set(c); p.set(c);
} }
chrome.storage.sync.get(null, load); chrome.storage.local.get(null, load);
ei("jammer-a"); ei("jammer-a");
ei("jammer-b"); ei("jammer-b");
ei("period"); ei("period");
ei("jam"); ei("jam");
ei("periodtext").innerHTML = periodtext[period]; ei("periodtext").innerHTML = periodtext[period];
ei("jamtext").innerHTML = jamtext[3]; ei("jamtext").innerHTML = jamtext[3];
transition(); transition();
startTimer(j, window.tenths); startTimer(j, window.tenths);
j.set(120000); j.set(120000);
save_timer = setInterval(save, 1000); save_timer = setInterval(save, 10000); // Every 10 seconds
update_itimer = setInterval(update, 33); update_itimer = setInterval(update, 33);
} }
function resize() { function resize() {
var b = document.getElementsByTagName("body")[0]; var b = document.getElementsByTagName("body")[0];
var w, h; var w, h;
// Internet Explorer makes everything a pain in the ass // Internet Explorer makes everything a pain in the ass
if (window.innerWidth) { if (window.innerWidth) {
w = window.innerWidth; w = window.innerWidth;
h = window.innerHeight; h = window.innerHeight;
} else if (document.documentElement && document.documentElement.clientWidth) { } else if (document.documentElement && document.documentElement.clientWidth) {
w = document.documentElement.clientWidth; w = document.documentElement.clientWidth;
h = document.documentElement.clientHeight; h = document.documentElement.clientHeight;
} else if (document.body) { } else if (document.body) {
w = document.body.clientWidth; w = document.body.clientWidth;
h = document.body.clientHeight; h = document.body.clientHeight;
} else { } else {
// Punt // Punt
w = 800; w = 800;
h = 600; h = 600;
} }
w /= 7; w /= 7;
h /= 5; h /= 5;
var fs = Math.min(w, h); var fs = Math.min(w, h);
b.style.fontSize = fs + 'px'; b.style.fontSize = fs + 'px';
} }
window.onload = start; window.onload = start;