Lion is out, and with it Safari 5.1. This release of Safari disables one of my must-have plugins, Keywurl. This plugin uses SIMBL to hack into the Safari binary and provides keyword search from the address bar. I have become utterly dependent on this, and feel really crippled when it doesn’t work.
Safari 5.1 contains some cool new stuff for extension developers, however, one of the new features being the SafariBeforeNavigate event. This event is triggered before any page is loaded, and can be used to implement the same functionality as Keywurl.
Accordingly, I did the only right thing, and created a Safari extension that performs keyword search. At the moment there is no interface for setting it up, so you’ll have to edit the code and install the extension via the Extension Builder using your own developer certificate, but that will probably change in the future. Installation instructions are available on GitHub.
Update: The extension now has an integrated editor, accessible on right-click.
So I made a simple javascript-thing for creating iOS-style flickable image galleries on smartphones and tablets and such. You can view a demo on flickable.aurlien.net (works in desktop browser too, although it isn’t quite practical), and download the source code on GitHub. It is quite slick, has no dependencies, and uses CSS3 3d-transforms for optimal performance. Check it out.
…without using arguments.callee!
I have read several “simple” introductions to the Y combinator (some of which are truly excellent), but I don’t know if I’ll ever manage to wrap my head completely around it, and it seems a bit verbose in use (at least in Javascript). It is a very cool concept though, and I decided to try implementing something similar (but possibly simpler) on my own. I managed to do this by using Javascript-specific stuff, specifically dicking around with arguments.
Technically, what I came up with is not exactly the same as the Y combinator, but its purpose is the same: To allow anonymous recursion. I’ve taken the liberty of calling it “the Z combinator” and it looks something like this:
function Z(func) {
var fun = function() {
return func.apply(null, [fun].concat([].slice.apply(arguments)));
};
return fun;
}
var fact = Z(function(rec, i) {
if (i === 0) {
return 1;
} else {
return i * rec(i-1);
}
});
fact(4); //24
// It can also be inlined:
Z(function(rec, i) { return i===0 ? 1 : i * rec(i-1); })(4); // 24
The Z combinator takes a function as an argument, and returns a new function that wraps the original and prepends itself to the argument list (if that makes any kind of sense). When recursing, the function should use call first parameter (rec, in this case) instead of calling itself by name. Thus, anonymous recursion! Maybe not very useful, but it was fun to do.
22 seconds from outside work yesterday morning.
In my last project at work, I had to work with fairly large data structures in Javascript. More than once I needed to sort data stored in Javascript objects. Javascript objects are by definition unsorted, so naturally there is no built-in way of doing this. All browsers, however, keep objects in the order that properties were added, so I decided to write a comprehensive sorting function.
This function will sort a Javascript object by key, value or predicate function, by transforming it to a temporary array and using the built-in Array.sort() on that. Here it is in all its glory:
sortObj = function(obj, type, caseSensitive) {
var temp_array = [];
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (!caseSensitive) {
key = (key['toLowerCase'] ? key.toLowerCase() : key);
}
temp_array.push(key);
}
}
if (typeof type === 'function') {
temp_array.sort(type);
} else if (type === 'value') {
temp_array.sort(function(a,b) {
var x = obj[a];
var y = obj[b];
if (!caseSensitive) {
x = (x['toLowerCase'] ? x.toLowerCase() : x);
y = (y['toLowerCase'] ? y.toLowerCase() : y);
}
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
} else {
temp_array.sort();
}
var temp_obj = {};
for (var i=0; i<temp_array.length; i++) {
temp_obj[temp_array[i]] = obj[temp_array[i]];
}
return temp_obj;
};
And here are a couple of usage examples:
var obj = {c:'b',a:'c',b:'a'};
// Sort by key
sortObj(obj);
// {a:'c',b:'a',c:'b'}
// Sort by value
sortObj(obj, 'value');
// {b:'a',c:'b',a:'c'}
// Sort by predicate function
sortObj(obj, function(a,b) {
var data = {a:2,b:1,c:3};
var x = data[a];
var y = data[b];
return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
// {b:'a',a:'c':c:'a'}
If you want the sort to be case-sensitive, set the second parameter of .sort() to true.
As always when extending Object.prototype, don’t forget to use hasOwnProperty when iterating over the object. But you’re of course doing that already, right?
Update: Be careful using this with Chrome. If your object has both numbers and strings as keys, Chrome will sort the object with the number-keys first, even when sorting by value. Example:
var obj = {a:2, b:1, 1:'a'};
obj.sort('value'); // Other browsers: {b:1, a:2, 1:'a'}, Chrome: {1:'a', b:1, a:2}
A sincere THANK YOU to all those who have given color.aurlien.net the upwards-ponting thumb on StumbleUpon — I’ve had over 25.000 visitors in a month, which is awesome. Thanks, guys!
I recently had use for a map()-function while writing Javascript. Javascript has Array.map(), and jQuery has $.map(), but those only works on arrays, and I needed one that could do its magic on objects. So I wrote this one:
function mapObj(obj, fun) {
var ret = {};
for (i in obj) {
if (obj.hasOwnProperty(i)) {
fun.call({emit: function(key, value) {
ret[key] = value;
}}, i, obj[i]);
}
}
return ret;
}
mapObj() takes an object and a function, applies the function to each property of the object, gathers up the result and returns it as a new object. The function supplied to mapObj is called with two parameters, the key and value of the current property. To add properties to the final object, call this.emit(key, value) from the function. This may be called any number of times for each property (including zero).
Here’s a usage example:
var obj = {a:1, b:2, c:3, d:4};
var obj2 = mapObj(obj, function(key, val) {
if (val != 2) {
this.emit(key.toUpperCase(), val*2);
} else {
this.emit(key, val);
this.emit('aaa', 'bbb');
}
});
// {A:2, b:2, aaa:'bbb', C:6, D:8}
Maybe someone will find this useful.
First, chop an onion. And some garlic. Couple of cloves, I dunno.
Fry in some oil until tender. Toss in some meat. Like, half a kilo of minced meat or something. Keep frying until it’s, like, fried.
Add a couple of chopped tomatoes, and some salt and pepper. Can’t do without that shit. Then start adding head: Maybe a couple of red chili peppers, a habanero if you’re feeling feisty. Some dried chili, and a chipotle for that nice smoky flavour. Just like whatever you have on hand. Throw in some other spices as well, stuff like cumin, oregano, cilantro, paprika. Teaspoon of sugar, maybe some lemon juice. Maybe add some water and let it boil down to get everything together and tasty-like.
Cook a whole bunch of french fries. Preferably in a deep fryer, if you have one. I have one, it’s awesome. You should get one if you don’t have one. Throw them in a casserole, add some salt if you like. Pour on the meat-chili-stew-thing, add some jalapenos, and cover with a couple handfuls of grated cheese. Bake in the oven until the cheese is melted and golden and/or you’re desperately hungry.
Serve with sour cream, salsa and an antacid.
Computer scientists used to assume that understanding human language, both written and spoken, was a crucial step in creating computers with levels of intelligence approaching that of humans. However, the truth seems to be the other way around, and it’s getting more and more unlikely that we’ll ever achieve either.
My name is Arne Martin Aurlien. I run this thing. Here’s a few facts about me:
Here’s a few things I have made: