Skip to content

Instantly share code, notes, and snippets.


Johan Sundström johan

View GitHub Profile
We couldn’t find that file to show.
View hardlinks.zsh
johan / chrome-addBookmarkRemoveListener.js
Created Aug 17, 2010
Like the chrome.bookmarks.onRemoved.addListener call at but guaranteed to fire even if the onremove event fired on a containing folder
View chrome-addBookmarkRemoveListener.js
// 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 ( === id) return path;
johan / sandbox-breaker.js
Created Aug 23, 2010
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.
View sandbox-breaker.js
// 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 / GM_queryContentVar.js
Created Sep 27, 2010
Lets a GM script safely read variables from the content scope (untested)
View GM_queryContentVar.js
// 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 /
Created Mar 26, 2011
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.
use strict;
use warnings;
use Getopt::Std;
use File::Basename;
use JSON;
use utf8;
my $prog = basename($0);
johan / gravatar.rb
Created Apr 3, 2011
Takes a list of email addresses (or files with email addresses) and lists gravatars for them, if set.
View gravatar.rb
#! /usr/bin/ruby
require 'digest/md5'
require 'net/http'
require 'uri'
$unknown_gravatar = 'd5fe5cbcc31cff5f8ac010db72eb000c'
$email_addr_regex = /[^\[{(< @"']+@[^\]})> @"']+\.[^\]})> @"']+/
def md5(str)
johan / google-closure-library.js
Created May 22, 2011
Google Closure Library loader bookmarklet
View google-closure-library.js
// 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 = ''
, iframe = document.body.appendChild(document.createElement('iframe'));
iframe.src = 'about:blank'; = 'none';
iframe.contentWindow.cb = callback;
iframe.contentDocument.write('<head><script src="'+ base +'base.js"></script><script src="'+ base +
johan / draw-svg.js
Created Jun 4, 2011
Draw an SVG bit by bit
View draw-svg.js
var steps = 0 // steps drawn on the current element, so far
, info = document.getElementById('next_step')
, svgs = []'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 / github-logo.svg
Created Jun 4, 2011
Github social coding logo, minimal SVG
View github-logo.svg
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
You can’t perform that action at this time.