Integrating Bloglines and del.icio.us #

Want to easily post things you read in Bloglines to del.icio.us? Follow these steps:

  • If you haven't already, install the excellent greasemonkey Firefox extension.
  • Open up this user script (in Firefox).
  • From the "Tools" menu, select "Install User Script.." and confirm all of the various prompts
  • Go to your Bloglines account.
  • Observe that all "Clip/Blog this" links at the bottom of each entry have been changed to "Post to del.icio.us."
  • Click on one to post that item to del.icio.us (you will be prompted for your username the first time you do this).

As an added bonus, the script makes the "Extras" section in the sidebar toggleable, so that it doesn't always take up so much room. This is all done in a very straightforward manner using DOM operations. It is possible that things could be made more elegant with some XPath-Fu. Things may stop working if Bloglines alters their markup significantly.

I would like to integrate the two services even further, but I'm not sure how much more can be done. Ideally each item in Bloglines would have the tags you've assigned it and perhaps the top N community tags as well. However, given the limitations imposed by the JavaScript security model, I'm not sure how to talk to del.icio.us directly, since the scripts will execute within the Bloglines context. In any case, this JavaScript del.icio.us API looks promising.

XmlSerializer and JavaScript #

At work I've been digging around the WebCore code base, trying to see how Safari supports (or more correctly, doesn't support) XML-related things. I happened to notice a XMLSerializer class that I hadn't heard of before. A bit more digging turned up that Mozilla implements it and Opera 8 will too, thus it is a de facto standard of sorts.

Safari's implementation seems rather limited, with the only method that it supports being serializeToString. Furthermore, it only accepts complete DOM documents. However, it may still be useful in certain circumstances. For example, click here to view the serialized version of my RSS feed. To code to do this is:

function serializeRSS() {
  var request = new XMLHttpRequest();

  request.open("GET", "/index.xml", false);
  request.send(null);

  var serializer = new XMLSerializer();
  alert(serializer.serializeToString(request.responseXML));
}

The best part about the above code snippet is that it's very straightforward and natural-looking. No IFRAME tricks required. No need for regexp-based parsing. Although browser-based development still has a ways to go, I'm glad it's headed in the right direction.

Thefacebook Adoption Rates #

Thefacebook reached my school in the second semester of my senior year. Although I haphazardly copied over my Orkut profile and added a bunch of friends, I never really got into it, having more pressing things to occupy my time.

However, noticing the steady stream of friend requests from people in younger classes, I was curious to see where it stood now. I was initially surprised by how many people in my year (2004) got around to signing up (perhaps they hadn't suffered social networking exhaustion like me). More shocking were the numbers that I saw when looking at the classes still enrolled in school. The class of 2008 has 84% of its members on Thefacebook, which is amazing when considering that this is a third party service with no endorsement whatsoever from the school. With such reach, I can see why some people get excited about the field.

Flexible Drop Shadows #

While working on yet another pet project, I decided to add an alpha-blended shadow around a draggable container. Although I have done such things before (for the magnifier), up until now I have only needed this effect for fixed-sized objects. In this case, the container could have any dimensions (within reasonable bounds). After some experimentation, I came up with a method that used two sliding door style <div>s with a background image (I'm not a big fan of the cutesy names that the designer community chooses for CSS techniques, but such is life). The net result is visibible here.

Each image is wrapped in a shadow <div> that also has four inner ones for each corner of the image. These corner <div>s are absolutely positioned within the container. Two of them are rather small, and only have the non-repeated parts of the of the upper-right and lower-left corners as their background images. The other two corners also have background images, except they are much larger (1000 x 1000 pixels, though even larger sizes should be feasible since they compress very well). However, we only want to display part of these images, making them big enough to contain the inner <div>. We accomplish this by giving them heights and widths of 100%. We then use negative position offsets to move these four <div>s outward so that they do not overlap.

One issue encountered is that MSIE does not directly support PNG transparency. The usual workaround is to use the filter CSS attribute. However, it does not seem to support the relative pinning that regular CSS background images can have. Due to the lack of a workaround, the best I could come up with was to disable this effect for this browser. It can be done in JavaScript, but I chose to rely on MSIE's lack of support for the direct descendant CSS selector. As a result, all drop-shadow related rules are prefixed by html>body so that MSIE does not see them.

As a bonus, I also threw in an image loader that can load any URL and determine the image's dimensions with JavaScript. Since some browsers do not immediately populate the width and height properties of the JavaScript object, the solution was to use a timeout (via window.setTimeout), checking for these properties until they were non-zero (actually, until they were greater than 24, since MSIE seems to default to the placeholder's image dimensions until the real one is loaded).

Having done all this, I discovered that nearly the same technique has already been covered on A List Apart. I suppose I can take some pride in having come up with it independently, and also in the fact that my shadows go all the way around the image (though they are nearly imperceptible on the upper and left-hand sides), allowing for the possibility of fancier borders.

As a side note, it's interesting to see how my JavaScript coding style has improved since my earlier experiments. Now I use closures and other fun things. It's always good to know that your skills have room to improve.

Bluetooth Internet Access with the Motorola v710 #

Even though I have been disappointed with my v710's crippling by Verizon, it should still make an acceptable internet connection platform. Verizon has a 1xRTT network with coverage in most interesting places. A bit of searching turned up these instructions on using the v710 as a Bluetooth Modem with Mac OS X. They work pretty much as advertised, with the only caveat being that the connection can be dropped occasionally. I initially thought this was due to some limiting by Verizon, but it doesn't seem to be dependent on the amount of data transferred or frequency of access.

My experiences, performance-wise, seem to mirror everybody else's - faster than a 56K modem, but with worse latency. As an example of the latter, compare these two ping statistics (to www.google.com):

v710 via Verizon 1xRTT:
  round-trip min/avg/max = 344.774/457.334/589.046 ms
TimeWarner Cable:
  round-trip min/avg/max = 11.13/16.128/32.77 ms

Speed seemed to vary based on signal intensity. A speed test reported 62 kbps down and 46 kbps up, but I could get the sustained transfer rate to vary between 144 kbps and 40 kpbs depending on where I placed my phone. Burstiness was also an issue, even when holding the phone still. In general this is better than my experiences with T-Mobile's GPRS network, though we'll have to see how much this ends up costing me.

The New Machine Order #

The introduction of the Mac mini significantly alters the possibile configurations that I can have. Even taking into account recent revelations that it has a 2.5 inch drive, it is still a decent enough machine for my needs. First, where I stand right now:

  • 1 GHz TiBook with 1 GB of RAM, 60 GB internal storage and 80 GB internal storage (2.5 inch), and a combo drive. Used as the primary computer, usually in conjunction with an external flat panel, keyboard and mouse.
  • Dual 450 MHz G4 with 1.5 GB of RAM, 100 + 120 + 300 GB internal storage and DVD burner. Used as a headless server.
  • Toshiba Portege R100 with 768 MB of RAM, and 40 GB internal storage.

All machines have wireless (802.11b cards in the computers, 802.11g on the basestation), and the two Macs have Gigabit Ethernet (and are interconnected with a Gigabit switch).

Step 1

Wait for more enterprising people to purchase a Mac mini and take it apart. Ensure that RAM and hard drive can be upgraded by the user with minimal hassle (the fact that this may void the warranty does not bother me). Determine if the inevitable flaws in a Rev. A product are acceptable.

Step 2

Purchase low-end Mac mini with Airport Extreme card and third party 1 GB of RAM for a total of ~$750. Install the 80 GB 2.5 inch drive internally.

Step 3

Sell the TiBook on eBay for ~$1600 (assuming not too much depreciation in the meantime).

Sell the dual G4 (minus 300 GB of the internal storage) on eBay for ~$400.

Step 4

Wait and see if I actually need to do anything more. I will in theory have a slightly more performant main machine that takes up less room and requires less external doohickeys.

Step 5

If the lack of a big honking tower leaves me unsatisfied and unmanly, build an Athlon 64 machine for ~$1500 or a dual Opteron workstation for $2500.

Unofficial Comic Feeds #

RSS is an ideal medium for reading online comics, since it removes the need to check sites repeatedly or keep track of update schedules. Some are enlightened about this, others don't seem to get it yet. For the laggards, the usual approach is to scrape the site. Below is a list of the comics that I read for which this has been done, in the hope that others will find these Atom or RSS feeds useful.