JasonWoof Got questions, comments, patches, etc.? Contact Jason Woofenden
numbered links in google chrome!
authorJason Woofenden <jason@jasonwoof.com>
Sat, 23 Jan 2010 11:39:17 +0000 (06:39 -0500)
committerJason Woofenden <jason@jasonwoof.com>
Sat, 23 Jan 2010 11:39:17 +0000 (06:39 -0500)
Makefile [new file with mode: 0644]
digg_sponsered.user.js [new file with mode: 0644]
numbered_links.user.js [new file with mode: 0644]

diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..ae1742c
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,9 @@
+all: usage
+
+usage:
+       @echo '"make install" to copy into google chrome extensions. if you change'
+       @echo "the sites it affects or anything you'll have to re-add it to chrome"
+       @echo "manually. (go to file:///home/blah/blah/blah)"
+
+install:
+       cp numbered_links.user.js $(HOME)/config/google-chrome/Default/Extensions/nbhpmaoejlnohbchnhamgfeekimhkoma/1.0/script.js
diff --git a/digg_sponsered.user.js b/digg_sponsered.user.js
new file mode 100644 (file)
index 0000000..b3eb289
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+*   written by JasonWoof 2009 public domain\r
+*/\r
+\r
+// ==UserScript==\r
+// @name          kill digg "sponsored digg"\r
+// @namespace     http://patcavit.com/greasemonkey\r
+// @description   digg's sponsored diggs look way too much like content\r
+// @include       http://digg.com/*\r
+// ==/UserScript==\r
+\r
+(function() \r
+{\r
+       var divTags;\r
+       if((divTags = document.getElementsByTagName("DIV"))) {\r
+               for(var a=0; a<divTags.length; a++) {\r
+                       for(var x=0; x<divTags[a].attributes.length; x++) {\r
+                               if(divTags[a].attributes[x].nodeName.toLowerCase()=='rel') {\r
+                                       if(divTags[a].attributes[x].nodeValue.indexOf("digg-ad:")!=-1) {\r
+                                               // divTags[a].innerHTML = '';\r
+                                               divTags[a].parentNode.removeChild(divTags[a]);\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+})();\r
diff --git a/numbered_links.user.js b/numbered_links.user.js
new file mode 100644 (file)
index 0000000..ec51ef0
--- /dev/null
@@ -0,0 +1,318 @@
+/*
+*   This script is derived (by Jason Woofenden) from an example script from
+*   uzbl (see uzbl.org) and is thus presumably licensed under the GNU GPLv3. In
+*   any case, Jason's changes are in the public domain.
+*/
+
+// ==UserScript==
+// @name          numbered links
+// @namespace     http://patcavit.com/greasemonkey
+// @description   make all links followable with the keyboard
+// @include       http://*
+// ==/UserScript==
+
+(function() 
+{
+
+
+// This is activated (and canceled) by pressing the `/~ key. To change it to a
+// differet key, edit the ascii value on line 301
+// 
+// Also, you can change the character set a few lines down. Don't use the "L"
+// key unless you change the on line 235.
+
+
+
+//Just some shortcuts and globals
+var charset = 'thsnd-rcgmvwb/;789aefijkopquxyz234';
+var uzblid = 'uzbl_link_hint';
+var uzbldivid = uzblid + '_div_container';
+var doc = document;
+var win = window;
+var links = document.links;
+var forms = document.forms;
+//Make onlick-links "clickable"
+try {
+    HTMLElement.prototype.click = function() {
+        if (typeof this.onclick == 'function') {
+            this.onclick({
+                type: 'click'
+            });
+        }
+    };
+} catch(e) {}
+//Calculate element position to draw the hint
+//Pretty accurate but on fails in some very fancy cases
+function elementPosition(el) {
+    var up = el.offsetTop;
+    var left = el.offsetLeft;
+    var width = el.offsetWidth;
+    var height = el.offsetHeight;
+    while (el.offsetParent) {
+        el = el.offsetParent;
+        up += el.offsetTop;
+        left += el.offsetLeft;
+    }
+    return [up, left, width, height];
+}
+//Calculate if an element is visible
+function isVisible(el) {
+    if (el == doc) {
+        return true;
+    }
+    if (!el) {
+        return false;
+    }
+    if (!el.parentNode) {
+        return false;
+    }
+    if (el.style) {
+        if (el.style.display == 'none') {
+            return false;
+        }
+        if (el.style.visibility == 'hidden') {
+            return false;
+        }
+    }
+    return isVisible(el.parentNode);
+}
+//Calculate if an element is on the viewport.
+function elementInViewport(el) {
+    offset = elementPosition(el);
+    var up = offset[0];
+    var left = offset[1];
+    var width = offset[2];
+    var height = offset[3];
+    return up < window.pageYOffset + window.innerHeight && left < window.pageXOffset + window.innerWidth && (up + height) > window.pageYOffset && (left + width) > window.pageXOffset;
+}
+//Removes all hints/leftovers that might be generated
+//by this script.
+function removeAllHints() {
+    var elements = doc.getElementById(uzbldivid);
+    if (elements) {
+        elements.parentNode.removeChild(elements);
+    }
+}
+//Generate a hint for an element with the given label
+//Here you can play around with the style of the hints!
+function generateHint(el, label) {
+    var pos = elementPosition(el);
+    var hint = doc.createElement('div');
+    hint.setAttribute('name', uzblid);
+    hint.innerText = label;
+    hint.style.display = 'inline';
+    hint.style.backgroundColor = '#B9FF00';
+    hint.style.border = '2px solid #4A6600';
+    hint.style.color = 'black';
+    hint.style.fontSize = '9px';
+    hint.style.fontWeight = 'bold';
+    hint.style.lineHeight = '9px';
+    hint.style.margin = '0px';
+    hint.style.width = 'auto'; // fix broken rendering on w3schools.com
+    hint.style.padding = '1px';
+    hint.style.position = 'absolute';
+    hint.style.zIndex = '1000';
+    hint.style.textTransform = 'uppercase';
+    hint.style.left = Math.max(-1, (pos[1] - (7 + label.length * 9))) + 'px';
+    hint.style.top = (pos[0] + 1) + 'px';
+    var img = el.getElementsByTagName('img');
+    //if (img.length > 0) {
+        //hint.style.top = pos[1] + img[0].height / 2 - 6 + 'px';
+    //}
+    hint.style.textDecoration = 'none';
+    // 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) {
+    removeAllHints();
+    if (item) {
+        var name = item.tagName;
+        if (name == 'A') {
+            item.click();
+            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();
+            }
+        } else if (name == 'TEXTAREA' || name == 'SELECT') {
+            item.focus();
+            item.select();
+        } else {
+            item.click();
+            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.
+function addLinks() {
+    res = [[], []];
+    for (var l = 0; l < links.length; l++) {
+        var li = links[l];
+        if (isVisible(li) && elementInViewport(li)) {
+            res[0].push(li);
+        }
+    }
+    return res;
+}
+//Same as above, just for the form elements
+function addFormElems() {
+    res = [[], []];
+    for (var f = 0; f < forms.length; f++) {
+        for (var e = 0; e < forms[f].elements.length; e++) {
+            var el = forms[f].elements[e];
+            if (el && ['INPUT', 'TEXTAREA', 'SELECT'].indexOf(el.tagName) + 1 && isVisible(el) && elementInViewport(el)) {
+                res[0].push(el);
+            }
+        }
+    }
+    return res;
+}
+//Draw all hints for all elements passed. "len" is for
+//the number of chars we should use to avoid collisions
+function reDrawHints(elems, chars) {
+    removeAllHints();
+    var hintdiv = doc.createElement('div');
+    hintdiv.setAttribute('id', uzbldivid);
+    for (var i = 0; i < elems[0].length; i++) {
+        if (elems[0][i]) {
+            var label = elems[1][i].substring(chars);
+            var h = generateHint(elems[0][i], label);
+            hintdiv.appendChild(h);
+        }
+    }
+    if (document.body) {
+        document.body.appendChild(hintdiv);
+    }
+}
+// pass: number of keys
+// returns: key length
+function labelLength(n) {
+       var oldn = n;
+       var keylen = 0;
+       if(n < 2) {
+               return 1;
+       }
+       n -= 1; // our highest key will be n-1
+       while(n) {
+               keylen += 1;
+               n = Math.floor(n / charset.length);
+       }
+       return keylen;
+}
+// pass: number
+// returns: label
+function intToLabel(n) {
+       var label = '';
+       do {
+               label = charset.charAt(n % charset.length) + label;
+               n = Math.floor(n / charset.length);
+       } while(n);
+       return label;
+}
+// pass: label
+// returns: number
+function labelToInt(label) {
+       var n = 0;
+       var i;
+       for(i = 0; i < label.length; ++i) {
+               n *= charset.length;
+               n += charset.indexOf(label[i]);
+       }
+       return n;
+}
+//Put it all together
+function followLinks(follow) {
+    if(follow.charAt(0) == 'l') {
+        follow = follow.substr(1);
+        charset = 'thsnlrcgfdbmwvz-/';
+    }
+    var s = follow.split('');
+    var linknr = labelToInt(follow);
+    var linkelems = addLinks();
+    var formelems = addFormElems();
+    var elems = [linkelems[0].concat(formelems[0]), linkelems[1].concat(formelems[1])];
+    var len = labelLength(elems[0].length);
+    var oldDiv = doc.getElementById(uzbldivid);
+    var leftover = [[], []];
+    if (s.length == len && linknr < elems[0].length && linknr >= 0) {
+        clickElem(elems[0][linknr]);
+        got = '';
+        active = 0;
+    } else {
+        for (var j = 0; j < elems[0].length; j++) {
+            var b = true;
+            var label = intToLabel(j);
+            var n = label.length;
+            for (n; n < len; n++) {
+                label = charset.charAt(0) + label;
+            }
+            for (var k = 0; k < s.length; k++) {
+                b = b && label.charAt(k) == s[k];
+            }
+            if (b) {
+                leftover[0].push(elems[0][j]);
+                leftover[1].push(label);
+            }
+        }
+        reDrawHints(leftover, s.length);
+    }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+       var active = 0;
+       var got = '';
+       document.addEventListener(
+               'keypress',
+               function(e) {
+                       if(e.keyCode == 96) {  // change this if you want a different activation key
+                               if(active) {
+                                       got = '';
+                                       removeAllHints();
+                               } else {
+                                       followLinks(got);
+                               }
+                               active = 1 - active;
+                               return;
+                       } else {
+                               if(active == 1) {
+                                       got += String.fromCharCode(e.keyCode);
+                                       followLinks(got);
+                               }
+                       }
+               },
+               true);
+})();