somewhere to talk about random ideas and projects like everyone else

stuff

Fluidizer fixed width → fluid width bookmarklet 14 July 2010

Yaay, fluid width!

I IZ NOM NOMMING ON HALF UR PIXELZ

This is another old one, something I made february fifteenth of this year.

One of the purely theoretical things that have always annoyed me, were fixed width themes. Because I love being a hypocrite, this blog right now is using a fixed width theme. Though I probably could make up an excuse, like to serve as a decent test case for Fluidizer in part of my grand scheme detailed via embedded steganographic messages inside all of my screenshots. Of course that’s all a lie (however much I would like otherwise).

It’s always bothered me how some web sites have these fixed-width layouts, sometimes with insanely thin boxes allocated to content. The vast majority of my screen becomes this orange blob of text. Chrome’s visual appearance motto is “Content not chrome”. That doesn’t help if the content is being obscured by the presentation of the content (gopher) might have solved that problem). Less chrome just means my eyes start to drown in +/- 1,732,405 pixels of orange. Even outside the extreme case, having a fixed-width layout isn’t efficient, and using something like Readability to only show the content removes the personality of the site or author, and only works on articles.

Fluidizer automatically resizes themes semi-pseudo-intelligently, and works with a lot of themes. It has several algorithms it uses, which are sort of alchemy-like and strange. I have no clue how it works, but there’s lots of strange stuff that goes on to magically do stuff. I think it even somehow has a CSS parser that uses CORS to load css through a server-side proxy.

Only tested in Chrome: [Fluidize]

javascript:(function(){function k(a){return(a||"").replace(/^\s+|\s+$/g,"")}function u(a,g){var b=new XMLHttpRequest;b.open("GET","http://anti15.chemicalservers.com/cssproxy.php?cssurl="+encodeURIComponent(a),true);b.onreadystatechange=function(){b.readyState==4&&b.status==200&&g(b.responseText)};b.send()}function o(){for(var a=0,g=0,b=false,h="*,div,p,body,span".split(",");!b&&g++<20;){if(document.body.scrollWidth>window.innerWidth){b=true;a-=100}else a+=100;for(var c=d.length;c--;){var f=d[c].text;try{for(var i=document.querySelectorAll(f),l=i.length;l--;){var n=i[l],p=parseFloat(d[c].width,10),q=d[c].width.replace(/^[\-\d\.]+/,"");if(q!="px")if(q=="em")p*=16;else console.warn("not used to handling non-px units");if(p>400&&h.indexOf(f)==-1){if(!n.a)n.a=p;n.style.width=n.a+a+"px"}}}catch(x){}}}try{c=d.length;a=0;for(var r;c--;)if(h.indexOf(d[c].text)==-1)try{var j=document.querySelectorAll(d[c].text);if(j.length==1&&j[0].getElementsByTagName("*").length>15&&(j[0]==document.body||j[0].parentNode==document.body||j[0].parentNode.parentNode==document.body))if(parseInt(d[c].width,10)>a){a=parseInt(d[c].width,10);r=j[0]}}catch(y){}if(a>500)r.style.width="100%"}catch(z){}}function v(a){function g(){var i=h.split(";").map(function(l){if(k(l.split(":")[0])=="width")return k(l.split(":")[1]);return""}).join("");b&&k(b)&&i&&k(i)&&d.push({text:k(b),width:i});h=b=""}for(var b="",h="",c=0,f=0;f<a.length;f++)if(a[f]=="{")c=1;else if(a[f]=="}"){g();c=0}else if(c==0)b+=a[f];else if(c==1)h+=a[f];g();o()}for(var d=[],s=document.styleSheets,t=s.length;t--;){var e=s[t];if(e.href&&!e.cssRules){console.log(e.href);u(e.href,v)}else{e=e.cssRules;for(var m=e.length;m--;){var w=e[m].selectorText;e[m].style&&e[m].style.width&&d.push({text:w,width:e[m].style.width})}}}window.addEventListener("resize",function(){setTimeout(function(){o()},100)});o()})();

Multicore Javascript Pi Computing with WebWorkers 14 July 2010

Selection_012
http://antimatter15.github.com/pi/partial.html It’s not using the fastest algorithm, but the nice thing about this one is that it’s capable of digit-extraction (calculating one section without knowing the digits before it) and was nice for doing distributed computing. This also has the nice side effect of working pretty well with the MapReduce paradigm (To calculate a block, calculate primes 3 to 2*N, map it all to the magical pi algorithm and then add it all up and truncate the fractional part, however it doesn’t really use MapReduce because there aren’t enough machines/threads to make it really necessary to distribute out the reducing part). So on the time-memory tradeoff scale, this algorithm uses low memory and is slower, which makes it pretty good for the purposes of something implemented with WebWorkers as I can’t imagine it would be good to have the same data multiplied by the number of threads and having lots of data being passed with each postMessage.

A Bright Coloured Fish Parsing ID3v2 Tags in Javascript (and ExtensionFM) 10 July 2010

Stolen from wikipedia

After having fun reinstalling Ubuntu, only to get extremely bored by the newfound stability and familiarity of 10.04, I upgraded to the Maverick Meerkat, where I was greeted by a friendly GRUB error. After consulting the Live CD a few times, I got into a normal desktop. Then I proceeded to install the two apps I ever use which aren’t included in Ubuntu: Chromium and Shutter (Maybe you could include git as well). After a bit of dismay as it seems Chromium didn’t sync extensions as advertised, I proceeded to reinstall my extensions. At least the issue where I couldn’t delete bookmarks was resolved.

It was also a neat opportunity to try out some new things, one of them was Neat Bookmarks after finding out that —bookmark-menu didn’t work (I only found it ever existed when it was announced that it was removed, though), which has a far prettier icon than some other bookmarks menu addon I had previously.

Another extension I tried out was Extension.FM. I’ve heard of it a while ago, but I never actually installed it for some reason, and there was a post on Ajaxian on it recently so I decided to try it out. The interface was neat (I knew that beforehand). I have an interesting (maybe not so much), system for storing my music on a local networked server (in my basement). So I went to it’s apache URL and browsed to the file location. ExtensionFM loaded it all and stuck it into my library (as advertised), but all the cover art, song name, album name and artist information was missing! Oh noes! Obviously it was missing ID3 data.

The great thing about Chrome, Firefox and Greasemonkey extensions, is that the source code is practically open to anyone who uses it. View source or otherwise, you can always get at it and hack stuff to make things right (ignoring the legal implications that ruin innovation). Some people think that there needs to be more done to secure the author’s source code from the user’s prying eyes, but that could not be further from the case. Hopefully this will be a case for why the source code should be exposed to the user.

So, after finding the location, which wasn’t the easiest thing as Chrome gives them these folder names based on a random generated public key which gives no hint on what the contents are. But as I only had a few plugins, getting ~/.config/chromium/Default/Extensions/ehohhddamheegbbkabfgegbaeminghlb/1.4.9_0/js wasn’t too hard. I found sound-parser.js and looked a little into it, and lo and behold, no ID3 parsing!

That’s probably expected as ID3v2 is a binary format, and JS was never that great at handling binary. I knew that there was an ID3v1 parser. But I wasn’t aware of an ID3v2 parser at the time, it seems that there is one that a quick google search would have saved me hours yesterday. So after implementing the spec, and googling several times why Picture Type $11 is “A bright coloured fish”, I hacked it onto song-parser.js and through means detailed here, I got ID3v2 support in ExtensionFM. So yay, now what was missing: cover art, album name, song title and artist now all work :)

Anyway, the project for the ID3v2 parser (mine, the one you shouldn’t use), is on github at http://github.com/antimatter15/js-id3v2. If you want a neat little online demo, just go to the URL below. I wouldn’t suggest any browser other than the Chromium nightlies or possibly Firefox 4.0 to view it as it relies on multi-file input and FileReader. Basically, this is how you use it: Press <Browse> and multi-select all the music that you have, and automagically, it reads it and parses ID3v2 data (all locally, mind you, so your secret collection of pirated music is not going to be sent to me for forwarding to the RIAA of your jurisdiction). It’s then shown at a 5 second slideshow. Cover art (if not present in the song) is of a probably copyright-infringing image of a sad fish that google referred me to because of this interesting fish theme.

http://antimatter15.com/misc/js-id3v2/id3v2.html <— Live Demo, you probably want to click it if you tl;dr’d this whole post.


Anony-bot 30 June 2010

A little robot using the Robots V2 API to expose a wave to a URL. If the URL is shared, then anyone can post anonymously on the wave.


μwave 30 June 2010

microwave-screen630
microwave-screen630-wave
μwave is the first true third-party wave client which is compatible with Google Wave. It’s free to use at http://micro-wave.appspot.com/ and works great on mobile devices. It supports searching for waves, opening them and writing replies. The source code for the server component is open-source and can be found on github (though it’s slightly outdated, but the important stuff is there). It’s fairly simple (It’s based on the original example code so I’m going to have the same MIT license), but one of the few python scripts which can do authentication with google and pass commands to the data api. It relies on thePython OAuth Library. A list of posts related to this can be found here.