keys: mode switches in page location hash
[sheet.git] / keys.js
diff --git a/keys.js b/keys.js
index b625db79b17a08e533f517a01ad8b2c0e310711b..e1b7038e197d66d298c5b04710b099de0bb38e97 100644 (file)
--- a/keys.js
+++ b/keys.js
@@ -1,4 +1,4 @@
-function setmode(classname) {
+function setmode(classname, restore) {
        // set style for each #rows>li>ul>li to display:none unless it matches classname
        var showclass = classname ? '^mode '+classname+'(?!\\w)' : '^(?!mode)';
        var rows = document.getElementById('rows').getElementsByTagName('TR');
@@ -11,10 +11,21 @@ function setmode(classname) {
        var h3s = document.getElementsByTagName('TH');
        for (var i = 0; i < h3s.length; i++) {
                if (h3s[i].parentNode.style.display != 'block') continue;
-               document.getElementsByTagName('H2')[0].innerHTML = h3s[i].firstChild.data;
+               var header = h3s[i].firstChild.data;
+               document.getElementsByTagName('H2')[0].innerHTML = header;
+               if (restore) break;
+               history.pushState(null, header, classname ? '#'+classname : '#');
+               break;
        }
 }
 
+window.addEventListener('hashchange', function(e) {
+       setmode(location.hash.slice(1), true);
+});
+if (location.hash) {
+       setmode(location.hash.slice(1), true);
+}
+
 var keyfocus = undefined;
 document.onkeypress = function(e) {
        var keylabels = document.getElementById('rows').getElementsByTagName('B');
@@ -23,19 +34,27 @@ document.onkeypress = function(e) {
                keys[keylabels[i].innerHTML] = keylabels[i].parentNode;
        }
        var input = e.charCode || e.keyCode;
+
+       // find key element matching input
        for (var i = 0; i < keylabels.length; i++) {
                var key = keylabels[i].parentNode;
-               if (!key.onclick) continue;
+               if (!key.onclick) continue; // link
                var keychar = key.className.match(/ chr(\d+)$/);
-               if (!keychar) continue; // not enterable
+               if (!keychar) continue; // has code
                keychar = keychar[1];
-               if (keychar != input) continue; // different key
+               if (keychar != input) continue; // matches code
+
+               // match mode (visibility)
                var row = key.parentNode;
+               var shown = row.style.display != 'none';
+               if (!shown) continue;
+
+               // match key modifiers
                var keymod = row.className;
-               if ((keymod.search(/\bctrl\b/) != -1) != e.ctrlKey) continue; // modifier mismatch
+               if ((keymod.search(/\bctrl\b/) != -1) != e.ctrlKey) continue;
                if ((keymod.search(/\bmeta\b/) != -1) != e.altKey) continue;
-               var shown = row.style.display != 'none';
-               if (!shown) continue; // foreign mode
+
+               // select
                if (keyfocus) keyfocus.style.outline = '';
                key.style.outline = '1px solid red';
                keyfocus = key;