Skip to content

Instantly share code, notes, and snippets.

View johan's full-sized avatar

Johan Sundström johan

View GitHub Profile
We couldn’t find that file to show.
@johan
johan / chrome-addBookmarkRemoveListener.js
Created August 17, 2010 02:00
Like the chrome.bookmarks.onRemoved.addListener call at http://code.google.com/chrome/extensions/bookmarks.html#event-onRemoved but guaranteed to fire even if the onremove event fired on a containing folder
// makes sure fn gets called when bm_id is removed, whether it was a direct kill
// or it got caught in collateral damage from a recursive bookmark removal spree
function addBookmarkRemoveListener(bm_id, fn) {
// as we won't get an onRemoved callback for bm_id when any of its parents got
// removed recursively, keep a list of all its parents to know when to fire fn
function indexParentsFor(bm_id, bookmarks) {
function bookmarkParents(id, bms, path) {
////console.log('bookmarkParents(', id, bms, path, ')');
for (var i = 0, bm, found; bm = bms[i]; i++) {
if (bm.id === id) return path;
@johan
johan / sandbox-breaker.js
Created August 23, 2010 10:39
Breaks out of the Greasemonkey / Google Chrome user script sandbox and runs the code in the page scope instead, free of sandbox gotchas and deprived of all privileged API:s.
// This block of code injects our source in the content scope and then calls the
// passed callback there. The whole script runs in both GM and page content, but
// since we have no other code that does anything, the Greasemonkey sandbox does
// nothing at all when it has spawned the page script, which gets to use jQuery.
// (jQuery unfortunately degrades much when run in Mozilla's javascript sandbox)
(function(run_me_in_page_scope) {
if ('undefined' == typeof __RUNS_IN_PAGE_SCOPE__) { // unsandbox, please!
var src = arguments.callee.caller.toString(),
script = document.createElement('script');
script.setAttribute("type", "application/javascript");
@johan
johan / GM_queryContentVar.js
Created September 27, 2010 05:01
Lets a GM script safely read variables from the content scope (untested)
// Query page javascript for the identifier "name", and call callback(value),
// when found, or undefined, if not found or some error occurred. This works
// only for values that can be JSON serialized -- numbers, strings, booleans,
// null, or nested structures like Arrays and Objects that only contain above
// mentioned types of data.
function queryContentVar(name, callback) {
// makes a random 20-char lowercase id
function random() {
var rand = '';
while (rand.length < 20)
@johan
johan / grep-count.pl
Created March 26, 2011 10:25
Like fgrep / egrep (symlink it as egrep-count to regexp match by default), but for more than one pattern at a time, generating tsv output, and where you list all the patterns and what you want the count columns to be named as a JSON object on stdin.
#!/usr/bin/perl
use strict;
use warnings;
use Getopt::Std;
use File::Basename;
use JSON;
use utf8;
my $prog = basename($0);
@johan
johan / gravatar.rb
Created April 3, 2011 09:01
Takes a list of email addresses (or files with email addresses) and lists gravatars for them, if set.
#! /usr/bin/ruby
require 'digest/md5'
require 'net/http'
require 'uri'
$unknown_gravatar = 'd5fe5cbcc31cff5f8ac010db72eb000c'
$email_addr_regex = /[^\[{(< @"']+@[^\]})> @"']+\.[^\]})> @"']+/
def md5(str)
@johan
johan / google-closure-library.js
Created May 22, 2011 03:09
Google Closure Library loader bookmarklet
// Enumerate your own list of goog.require:s, if you want something else than TableSorter and XhrIo.
// Similarly, you can pass a callback that will get the library in its first parameter, once loaded,
// or leave it as is, if you'd rather overwrite the top window's "goog" with your own custom version.
javascript:(function(requires, callback) {
var base = 'http://closure-library.googlecode.com/svn/trunk/closure/goog/'
, iframe = document.body.appendChild(document.createElement('iframe'));
iframe.src = 'about:blank';
iframe.style.display = 'none';
iframe.contentWindow.cb = callback;
iframe.contentDocument.write('<head><script src="'+ base +'base.js"></script><script src="'+ base +
@johan
johan / draw-svg.js
Created June 4, 2011 10:18
Draw an SVG bit by bit
var steps = 0 // steps drawn on the current element, so far
, info = document.getElementById('next_step')
, svgs = [].slice.call(document.getElementsByTagName('svg'))
, svg, walker, current;
function lexSVGPath(d) {
function command(seg) {
var cmd = seg.match(/[a-z]/i), arg, cnt;
if (cmd) {
cmd = cmd[0]; // which subcommand
@johan
johan / github-logo.svg
Created June 4, 2011 11:15
Github social coding logo, minimal SVG
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.