JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
tweak clicking/activating, more keybindings
authorJason Woofenden <jason@jasonwoof.com>
Sat, 31 Aug 2013 23:00:44 +0000 (19:00 -0400)
committerJason Woofenden <jason@jasonwoof.com>
Sat, 31 Aug 2013 23:07:31 +0000 (19:07 -0400)
numbered_links.user.js

index 1042d50..f9fb5f0 100644 (file)
@@ -180,11 +180,10 @@ function generateHint(el, label) {
        // hint.style.webkitBorderRadius = '6px'; // slow
        return hint;
 }
-//Here we choose what to do with an element if we
-//want to "follow" it. On form elements we "select"
-//or pass the focus, on links we try to perform a click,
-//but at least set the href of the link. (needs some improvements)
-function clickElem(item) {
+
+// This function takes action on the element chosen by entering the "numbered
+// link" shortcut key(s)
+function do_element(item) {
        removeAllHints();
        if (item) {
                var name = item.tagName;
@@ -192,22 +191,45 @@ function clickElem(item) {
                        click_element(item);
                        window.location = item.href;
                } else if (name == 'INPUT') {
-                       var type = item.getAttribute('type').toUpperCase();
-                       if (type == 'TEXT' || type == 'FILE' || type == 'PASSWORD') {
-                               item.focus();
-                               item.select();
-                       } else {
-                               item.click();
+                       var type = (item.getAttribute('type') || 'text').toLowerCase();
+                       switch (type) {
+                               case 'checkbox':
+                                       item.checked = !item.checked;
+                               break;
+                               case 'radio':
+                                       item.checked = true;
+                               break;
+                               case 'submit':
+                               case 'reset':
+                               case 'image':
+                               case 'button':
+                                       item.click(); // only tested on submit buttons
+                               break;
+                               case 'file': // don't think js can activate this, so focus
+                               case 'text':
+                               case 'password':
+                               case 'search':
+                               case 'number':
+                               case 'email':
+                               case 'url':
+                               case 'range':
+                               default:
+                                       // give it keyboard focus
+                                       item.focus();
+                                       item.select();
+                               break;
                        }
                } else if (name == 'TEXTAREA' || name == 'SELECT') {
                        item.focus();
                        item.select();
                } else {
+                       // as a catch-all, try simulating a mouse click on that element
                        click_element(item);
                        window.location = item.href;
                }
        }
 }
+
 //Returns a list of all links (in this version
 //just the elements itself, but in other versions, we
 //add the label here.
@@ -302,7 +324,7 @@ function followLinks(follow) {
        var oldDiv = doc.getElementById(uzbldivid);
        var leftover = [[], []];
        if (s.length == len && linknr < elems[0].length && linknr >= 0) {
-               clickElem(elems[0][linknr]);
+               do_element(elems[0][linknr]);
                got = '';
                active = 0;
        } else {
@@ -362,7 +384,22 @@ function init() {
                                        }
                                } else {
                                        // general keybinding, unrelated to numbered links
-                                       if (document.activeElement == document.body) { // FIXME get more specific
+                                       var active_type = (document.activeElement.type || 'a').toLowerCase();
+                                       var typing = true;
+                                       if (document.activeElement == document.body) {
+                                               typing = false;
+                                       } else {
+                                               switch ((document.activeElement.type || 'a').toLowerCase()) {
+                                                       case 'checkbox':
+                                                       case 'radio':
+                                                       case 'submit':
+                                                       case 'reset':
+                                                       case 'image':
+                                                       case 'button':
+                                                               typing = false;
+                                               }
+                                       }
+                                       if (!typing) {
                                                var c = key_to_char[e.keyCode];
                                                switch (c) {
                                                        case 'c':
@@ -373,6 +410,25 @@ function init() {
                                                                window.scrollBy(0, 200);
                                                                stop_event(e);
                                                        break;
+                                                       case 'h':
+                                                               if (e.shiftKey) {
+                                                                       history.back()
+                                                                       stop_event(e);
+                                                               }
+                                                       break;
+                                                       case 'n':
+                                                               if (e.shiftKey) {
+                                                                       history.forward()
+                                                                       stop_event(e);
+                                                               }
+                                                       break;
+                                                       case 'f':
+                                                               if (!active) {
+                                                                       followLinks(got);
+                                                                       active = 1;
+                                                                       stop_event(e);
+                                                               }
+                                                       break;
                                                }
                                        } else if (e.keyCode == 27) {
                                                // unfocus on ESC