• Working around "Click to activate and use this control"

    Aug 29 2006

    As you may likely be aware, the latest versions of Internet Explorer and Opera have decided not to give Eolas any money for their patent. Instead, users are forced to click on plugins (movies, sound, Flash and Java applets). In other words, anything inside object, embed or applet tags.

    Thankfully, there is a way around this. Microsoft has documented some workarounds. I've put together a solution here that works in Opera as well:

    // only execute code if 'getElementsByTagName' and 'outerHTML' are supported
    if (document.getElementsByTagName && document.body.outerHTML) {
        // repeat code for each affected tag
        var tags = ['object','embed','applet'];
    
        for (var i in tags) {
            // get all elements with tag
            var objs = document.getElementsByTagName(tags[i]);
    
            for (var j=0;j < objs.length;j++) {
                var obj = objs.item(j);
    
                // find param tags within object
                var params = obj.getElementsByTagName('param');
                var inner = '';
    
                // if there are params, but param tags can't be found within innerHTML
                if (params.length && !/<param/i.test(obj.innerHTML))
                    // add all param tags to 'inner' string
                    for (var x=0;x < params.length;x++)
                        inner += params.item(x).outerHTML;
    
                // put 'inner' string with param tags in the middle of the outerHTML
                obj.outerHTML = obj.outerHTML.replace('>', '>' + inner);
            }
        }
    }
    

    Download this script here.

    The code only executes on browsers which support getElementsByTagName and outerHTML (Internet Explorer, Opera and Safari - but not Firefox). It gets around the patent by dynamically "altering" the outerHTML (even though nothing is changed from the original HTML). But beware: you need to put it in an external JavaScript file to work.

    To do this, simply put the code into a file. Let's say it's called eolas.js. Then put this line anywhere after all the object, embed or applet tags:

    <script type="text/javascript" src="eolas.js"></script>
    

    Alternatively, you can keep the script tags out of the body by wrapping the code in eolas.js in a function, then use my addDOMLoadEvent function to run the Eolas script once the page has loaded. So if you change eolas.js like so:

    function fixEolas() {
        // same code above
    }
    

    then just put this in the <head> of the page:

    <script type="text/javascript" src="eolas.js"></script>
    <script type="text/javascript" src="adddomloadevent.js"></script>
    <script type="text/javascript">
    addDOMLoadEvent(fixEolas);
    </script>
    

    Unfortunately, the JavaScript file will be downloaded unnecessarily for users who don't use Internet Explorer or Opera. But if Safari or other browsers implement the same thing, this JavaScript code will already be in place to fix it.

    And there you have it. Three cheers for horrible software patents!

    Update: The code I posted before breaks objects with <param> tags in Internet Explorer. It turns out that outerHTML doesn't contain <param> tags, so extra work needs to be done to make sure they stay intact. I've updated the script accordingly.

  • Social Networking Spam

    Aug 28 2006

    So everyone knows MySpace has gotten big. Really big. There are start-ups appearing every minute destined to become the next MySpace. This has attracted it a lot of attention.

    Bands quickly realised the marketing power of MySpace. You can find MySpace pages for bands like Beck, Eminem, and of course millions of small bands.

    If you have a MySpace page, you know that bands caught on to using MySpace as a way to do marketing thanks to the 'Add a friend' feature. They seem to constantly search on MySpace for potential fans, then ask those people to be their friends.

    Now, the spammers have caught on. There are MySpace pages for the most mundane of commercial interests. How about this one which is just selling shoes, or this one which shallowly markets another web site. These aren't real people. Who wants to be friends with a shoe reseller?

    I know this is just the beginning. Soon, MySpace spam will end up on every marketer's to-do list (along with "viral" movies on YouTube). And when that happens, when every MySpace member has to deny a handful of "friends" every day, then I think MySpace will fall. People are excited about the "MySpace generation", but I'm not sure they understand them. The more something is cool today, the more it will suck tomorrow. MySpace is about to become as uncool as the Backstreet Boys.

  • How to add gravatars to your web page or blog

    Aug 23 2006

    Last night, I added gravatars to the comments on this site. The best blog post to see them is Blog Tipping.

    Gravatars are globally recognized avatars. It's a clever way to let people upload a little picture that goes beside their comments. This way, people only have to add them once (at the Gravatar website) and they automatically work across all web sites implementing them. They use the MD5 hash of your email address as an id, so you only need to put in the same email address when you write comments, and your gravatar will come.

    Implementation is very easy. You don't need to make any HTTP request on the server or anything. You only need to add an image that points at the gravatar URL, with some optional parameters, and the browsers of people visiting your site will download the images from gravatar.com.

    The only required parameter is gravatar_id, the md5 hash of the email address. Every programming language has a way of finding an MD5 hash. PHP probably has the most simple example:

    <img src="http://www.gravatar.com/avatar.php?gravatar_id="/>

    There are also optional parameters you can use. rating lets you make sure there are no pornographic or mature images on your site. size lets you set the width/height to something other than 80px. default lets you set the URL of a default image, in case you want to display something for people without a gravatar (a 1x1 invisible image is the default). border is supposed to let you set the colour of a 1px border on the image, though I wasn't able to get this working. So the output of a complex example might look like this:

    <img src="http://www.gravatar.com/avatar.php?size=50&border=000&gravatar_id=eb22390416c3b62025dc9ad2120a8ade"/>

    It's worth noting that adding gravatars can be a css and design challenge. You don't know whether the image will be a real gravatar or just a 1x1 invisible image. If you add margins or padding to the gravatar, they will end up on the invisible pixel as well, and this can look weird. I solved it by indenting all comments 60px to allow space for a 50px image. If the image isn't there, the comment is just indented anyway. You can also solve this by setting a default image to a "No gravatar" image.

    Gravatars can really be implemented anywhere you know an email address and may want to show an image. There is a Thunderbird add-on that lets you see Gravatars while you're reading emails.

    For more details, or to see how to implement gravatars in other languages and blog publishing software, the Gravatar web site has a detailed implementation guide. If you just want to upload your own gravatar, go sign up.

  • Connecting People

    Aug 22 2006

    I've become convinced the ultimate benefit of the Internet is and will always be the ability to connect people. Lots of people know this already. You can see evidence of it by the rapid pace of new Social Networking web sites being made. But I'm not interested in these billions of MySpace rip-offs.

    There have always been people-matching sites on the web. Dating and Friend-finding sites (connecting individuals to meet in real life) and sites for finding jobs (connecting employers with employees) are some of the most common examples. We can also see people connecting through the uses of forums, blogs, online groups and other communities. But I think there is a lot of potential for specialized sites that solve a very specific problem for a potentially large group of people.

    Take a look at BookMooch. This is a new site which lets people trade used books. No money is exchanged. Instead you get points for mailing books to people, and you can use those points to get books mailed to you. It is a perfect example of the potential of connecting people. It's not just connecting me to you so that we can chat about our shared interests. It's about connecting anyone who wants to trade books, and allowing the most complex of trades to happen very easily. "I'll give this book to her, and she'll give that other book to him, then he'll give some book to you, and finally you give this book to me."

    Web professionals should check out Programmer Meet Designer. It's a place for finding freelancing partners who can help out each other in any number of ways, from a few hours on a single project to a permanent professional partnership. Most notably, it's geared to a specific yet large problem of matching programmers and designers, and it solves the problem well.

    The possibilities are rather endless, and I think the room for competition or co-existence between these sites are quite large. For example, there are a large number of job searching sites which co-exist in harmony. As I outlined earlier this week, there are job searching sites which specialize in jobs for web professionals. There are also dating sites which specialize in every conceivable niche. People can use more than one of these sites at a time, and many do.

    If you're trying to come up with a new web business, try to find a way to connect people who can benefit from each other. These sites will always be in demand, simply because everybody benefits.

  • Carnival of the Web #3

    Aug 20 2006

    Hello and welcome to the third edition of the Carnival of the Web! Despite this being the middle of the summer, it's obviously not everyone has been on holiday. This month we have some more great blog posts I hope you'll enjoy. For more information on this carnival, or to submit an article, check out the carnival info page.

    First off, Dustin Diaz shows how JavaScript can be a bit more object-oriented by showing us How to achieve private, public, and privileged members in JavaScript.

    Next, Simon Willison gives a detailed review with the ups and downs of Sticking with Opera 9.

    Justin Palmer insists we should worry more about code readability than length by exploring Why Chef Boyardee Doesn't Write Javascript.

    If you're hungry for some Bite Size Standards, why not learn how to Clean up code with semantic anchors.

    Dean Edwards brings the for-loop into the 21st century in Enumerating JavaScript Objects.

    Jeremy Keith explains why the only way web developers are going to be able to work with JavaScript is by Learning JavaScript.

    James Bennett gives some perspective on what security really means with Let’s talk about frameworks, security edition.

    Clay Mabbitt over at Web Design Business Best Practices walks us through a useful but often overlooked aspect of database design, showing how to leave an audit trail in your database.

    Joe Kissell brings us the next Interesting Thing of the Day, a look at the million dollar homepage and how to make a fortune with paperclips and pixels.

    D Kai Wilson of Mechanical Regurgitation brings us through an often necessary sanity check by asking the question: Are YOU listed on spam blacklists?

    Sérgio Rebelo at twodotfive weighs the pros and cons of using a fixed layout with Blog Widths.

    And to finish things off with a laugh, Avant News brings us news all the way from the year 2008, letting us know that Social Networking Site Digg.com to Replace Traditional Voting.

  • WikiMapia: Easiest Google Maps Ever

    Aug 18 2006

    If you want to put a map on your web site using Google Maps, the easiest way to do that is by going to WikiMapia, finding the place you want, then going to the menu and selected "Map on your page". You'll be presented with a box that lets you pick the size and exact starting location of your map, and you'll be given a very simple HTML snippet (an iframe) you can put anywhere.

    For example, I found my home in Berlin and was given the following snippet:

    <iframe src=http://wikimapia.org/s/#y=52506879&x=13318394&z=19&l=0&m=a width=400 height=208 frameborder=0></iframe>

    I had to change the HTML to XHTML myself by adding quotes around the attribute values and escaping the ampersands in the URL:

    <iframe src="http://wikimapia.org/s/#y=52506879&amp;x=13318394&amp;z=19&amp;l=0&amp;m=a" width="400" height="208" frameborder="0"></iframe>

    Unfortunately, iframe is deprecated in XHTML Strict, so this would make my page invalid. The way to embed a frame on a page in XHTML Strict is to use an object tag instead like so:

    <object type="text/html" data="http://wikimapia.org/s/#y=52506879&amp;x=13318394&amp;z=19&amp;l=0&amp;m=a" width="400" height="208" style="border:0"></object>

    It seems WikiMapia doesn't support the object tag when used with Internet Explorer. Well, as long as you're not using IE, you can see where I live in Berlin! The rest of you can click here instead.

  • Finding a job as a web professional

    Aug 17 2006

    If you're a web professional looking for a job, or looking to find a better job, there are some really great job boards to keep an eye on:

    • 37signals Job Board

      This is a great site to find some of the best jobs out there. Many of them are looking for Rails developers, but there are other development, design and management jobs. Plus, I think it's a good sign when a company knows about 37signals.

    • jobs.rubynow.com

      Certainly the best place to find a Ruby On Rails job. There's new postings nearly every day.

    • Vitamin Job Board

      There's a nice variety of web professional jobs posted here, though mostly centred around development.

    • CSS Beauty

      If you're passionate about web standards and semantic markup, there's probably a good job for you on here. I bet it would be nice to work in a company where you don't have to convince anyone about the benefits of web standards.

    • craigslist

      If you know the city you want to work in, Craigslist is a great place to look for a job. It doesn't have every job, but in my experience the companies that post on there tend to be at least a little hip. The squares probably haven't even heard of craigslist.

    • Indeed

      Indeed's like the coolest job search out there. You can put together a complex search string and search across a number of job boards (including craigslist). Then, you can subscribe to the RSS feed for that search. This can be really great if you want to specialize in a particular technology or filter out all jobs mentioning ASP.NET.

    When looking for a job, it helps if you either live in a great location like California, New York or London, or you're willing to relocate. Who knows, though, maybe your dream job is just around the corner.

    I think all of these job boards have RSS available, so you can just subscribe now and keep an eye on the results while you mull over quitting your current job.

  • Avoiding Comment Spam with JavaScript

    Aug 16 2006

    Originally I explained this on the Code Igniter forum, and since others are blogging it, I thought I should bring it here.

    I guess I was nervous about sharing my anti-spam techniques on my own blog in case any spam bots are smart enough to read this article and somehow mutate and adapt. We'll see.

    For a while, I had no problems with comment spam. Then I started to get a couple. Then one day I got like 50 at once, so I did something "extreme" - I made it so users have to have JavaScript to submit comments. I have a randomly generated spam key in PHP, and then use something like this on the page:

    <form id="cform" style="display:none">
        <input id="txtauthor" name="<?= $spam ?>a"/>
        <input id="txtemail" name="<?= $spam ?>e"/>
        <input id="txturl" name="<?= $spam ?>u"/>
        <textarea id="txtbody" name="<?= $spam ?>b" rows="10" cols="40"></textarea>
        <input type="hidden" id="antispam" name="antispam"/>
    </form>
    <script type="text/javascript">
        document.getElementById('cform').style.display = 'block';
        document.getElementById('antispam').value = '<?= $spam ?>';
    </script>
    <noscript>Sorry, you need JavaScript to post comments.</noscript>

    So if the spam key is 'xxxx' the author field is 'xxxxa', email 'xxxxe', etc. The spam key is filled using JavaScript. Then on the server side I do this:

    if (isset($_POST['antispam'])) {
        $antispam = $_POST['antispam'];
        $cauthor = $_POST[$antispam . 'a'];
        $cbody = $_POST[$antispam . 'b'];
        $cemail = $_POST[$antispam . 'e'];
        $curl = $_POST[$antispam . 'u'];
        if ($cbody && $cauthor)
            addComment($id, $cemail, $cauthor, $cbody, $curl);
    }

    This has majorly cut down on the number of comment spam I get. I still get the occasional one here and there, but they must all be done by hand instead of with some automated bot.

    Unfortunately, this method means that users without JavaScript can't post comments on here. I regret that, but since nobody posts comments on here anyways, I figure it's not such a loss. :) One day, I would like to add some kind of captcha or approval system to allow posting of comments without JavaScript.

  • The Desktop Web

    Aug 15 2006

    That dynamic duo Tara Hunt and her PiC Chris Messina have got me thinking. They've been talking about web applications starting to move to the desktop. Okay, that doesn't seem so interesting, desktop applications are like the oldest things there are. But we've learnt some lessons from web apps that we can try to bring back to the desktop.

    Tara asks:

    I sync my iPhoto with Flickr and Riya - but why couldn't I store all of that data on my desktop?

    Chris sees web apps coming to the desktop more literally:

    I'm seeing a third generation stack emerging that holds a great deal of promise for sewing up the future of offline-sync-online experiences.

    That stack looks a bit more like Rails, SQL Lite (which the next rev of the Firefox bookmarks will be based on), Microformats, some blend of JSON/AMASS/jQuery/behaviour.js/scriptaculous/prototype and, yes, WebKit. What do they have in common? Well, enough inter-woven stickiness to make the heart of a true web geek start to murmur.

    This got me thinking about something nobody really talks or cares about anymore: peer-to-peer.

    Why doesn't every computer on the web run it's own web server? If you want to share something with the world (photos, music, a blog, etc.), you put it on your personal web server and people come to you.

    Try to do this today. I ran a web server off my own computer for a few years in University.. that is, until the assholes at Rogers Cable told me to block port 80 or they would cut off my Internet service.

    Okay, I understand the logistical problems here. Even our high-speed Internet connections couldn't handle the bandwidth issues of a busy web site, let alone a dial-up connection. And we would have to leave our computers running all the time. We would also need a static IP or heavily use dyndns.com, plus I can't picture average Internet users configuring their router to port forward to their personal web servers, nor configuring Apache. Not to mention the security implications.

    Okay, it sounds like a bad idea for 2006. But I'm talking about the future of the web here.

    Eventually, I hope, our current bandwidth will be as funny as 2400-baud modems are to us now. Eventually, perhaps, IPv6 will let every device have a static IP so we won't have to hide behind our routers. Eventually, when a web server becomes as easy to set up as a web browser, we will find them in every household. Eventually.

  • Swift: Safari for Windows?

    Aug 14 2006

    I just heard about Swift (via Chris Messina). Swift is a port of WebKit for Windows. WebKit is the rendering engine behind Safari (in the same way Gecko is behind Firefox and Mozilla). So I figure, sweet! Safari for Windows!

    I had some problems though. On one of my PCs, WebKit.dll couldn't be registered so the installation failed. Weird.

    On my other PC, I got Swift installed no problem. I ran it and.. well.. let's just say it's clearly Alpha software. Not only is the user interface extremely bare minimum (you're not going to make this your default browser any time soon), the functionality is a bit iffy. For example, it crashed when I clicked a normal link.

    Perhaps it will help you see how WebKit will render your page.. but I wouldn't rely on it. I had a password field go missing, and buttons are styled with CSS whereas I'm pretty sure they aren't in Safari.

    It seems there is also a problem with JavaScript. JavaScript executes, sometimes, but I had a problem getting popups to launch, or to load my new Google ads. Okay, maybe you won't miss popups and ads, but what else will break?

    I give massive kudos to WebKit and Chris Fuenty for putting this together. It's not there yet, but I can't wait until it is. Having a port of WebKit on Windows will help web developers without Macs immensely. Maybe one day Swift will even become a major player in the browser market.

  • Let people turn off ads Part 2

    Aug 13 2006

    As I warned yesterday, I've put ads back on the site. Currently, I only have them on the individual blog post pages (the pages that have comments on them). If you only read from the home page, or if you read via RSS, you won't see them.

    I also walked my own talk by letting people turn off the ads if they wish. I did it entirely with JavaScript, so I thought I'd share my methodology with you.

    The HTML just looks like this:

    <div class="ads">
        <script type="text/javascript" src="banner-ad.js"></script>
    </div>

    And the JavaScript in banner-ad.js looks like this:

    /* Customized Google Adsense codes */
    google_ad_client = "pub-3809601305027895";
    google_ad_width = 468;
    google_ad_height = 60;
    google_ad_format = "468x60_as";
    google_ad_type = "text";
    google_ad_channel ="8087340205";
    google_color_border = "99bbee";
    google_color_bg = "99bbee";
    google_color_link = "000000";
    google_color_url = "000000";
    google_color_text = "000000";
    
    /* cookie functions from QuirksMode */
    function setCookie (name,value,days) {
        if (days)
        {
            var date = new Date();
            date.setTime(date.getTime()+(days*24*60*60*1000));
            var expires = "; expires="+date.toGMTString();
        }
        else var expires = "";
        document.cookie = name+"="+value+expires+"; path=/";
    }
    
    function getCookie (name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for(var i=0;i < ca.length;i++)
        {
            var c = ca[i];
            while (c.charAt(0)==' ') c = c.substring(1,c.length);
            if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
        }
        return null;
    }
    
    /* onclick function to remove ads */
    function removeAds() {
        /* set a cookie for 10 years to stop showing ads */
        setCookie('hideads', '1', 365*10);
    
        /* hide every div on the page with the class name 'ads' */
        var ads = document.getElementsByTagName('div');
        for (var i=0;i < ads.length;i++) {
            if (ads[i].className == 'ads') {
                ads[i].style.display = 'none';
            }
        }
    
        return false;
    }
    
    /* don't show the ads if the cookie is there */
    if (getCookie('hideads') != '1') {
        /* write out the link to hide the ads */
        document.write('<a href="#" onclick="return removeAds()">Remove Ads</a>');
    
        /* write out the regular Adsense script tag */
        document.write('<script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>');
    }

    When the 'Remove Ads' link is clicked, the ads are instantly hidden using CSS and a cookie is set. Next time this script is loaded, as long as the cookie is set, the ads won't be written to the page anymore.

  • Best site in bleep!

    Aug 13 2006

    Pretty much the only comment/form spam I get is of the variety that ends with:

    Best site in bleep! My thnx to webmasters.

    The rest of the message is usually different. Two recent examples are "Excellent site you have! Awesome content. Thank you." and "Thanks for nice and actual info' Be the Best!". These examples don't have any URLs in them, but many often do. I suspect the ones without URLs are a sort of ping/robot system that is going around testing for new places to submit.

    The "From:" address is fairly consistent as well. It's nearly always from a mail.com address, though there are exceptions such as a recent one that came from Bush@yandex.com.

    What is this spam?? A search on Google only comes up with fellow blogger John Bokma's site, plus 37,800 other pages probably containing actual comment spam. John has logged a ton of different URLs and IP addresses of this spammer (nicknamed "Bleep"), and has concluded Bleep is actually comprised of a small botnet. He also describes Google's apparent inaction towards stopping this spammer on Blogspot.

    I have a theory that Bleep isn't just a single spammer, but perhaps the default output of some kind of comment spam software used by hundreds of different spammers.

    I'm rather interested to get my hands on some comment spam software - not to actually spam but just to see how the thing works to get some ideas of how to fight comment spam - but it seems impossible to find it. Searching on "comment spam" just brings up web pages against spam. Plus, I'm pretty sure whoever writes the software wouldn't name it "Comment Spam 2000" or something. It probably has a name like "Web Advertiser 2000" that makes it sound not-so-evil.

    Does anyone have any info on this Bleep bot? Or any ideas of where I can find comment-spamming software?

  • Let people turn off ads

    Aug 12 2006

    I mentioned in my review of dict.cc that I loved the ability to turn off ads. Unfortunately, now that ability is gone. There used to be is a large Adsense banner across the top of the page with a link to "Remove Ad". When you clicked the link, the ad would disappear. I guess it used a cookie to remember your preference so that the next time you went to the site, the ads would be gone. Now, there are just ads on the side with no way to hide them. Update: the banner and Remove Ad link is still there, just not on the home page!

    The ability to disable ads is great from a visitors perspective. People already use adblock software to block ads that they don't want to see and will never click on. Allowing visitors to customize a web site is not only helpful but generous as well. This also solves the dilema of sites which want to make a bit of money but don't want to ruin the experience of their loyal visitors.

    On a related note, I'm thinking of bringing back the Adsense ads (with a Remove Ads link) to see how they peform. I had taken them off back in December when I was only making a few cents per week, but my traffic situation has since changed. If anybody has any objections, speak now or forever hold your peace. :)

    Update: I've put back the ads with a 'Remove Ads' link, and wrote a follow-up explaining how.

  • Cross-Domain JSON without XHR

    Aug 11 2006

    I was just reading on the Ajaxian a quote from an article Why XHR should become opt-in cross-domain, so I started thinking, isn't there a way around this already?

    A quick explanation of what I'm talking about: XMLHttpRequest (the function behind Ajax) will only let you connect to URLs on the same domain as the page you're on. This means the Ajax happening on xyz.com can only connect to URLs on xyz.com. Even if XYZ wanted to use Ajax to pull some data from foobar.com, they wouldn't be able to.

    Now there is already one popular way around this. You can make a proxy page that gets the data for you. Using the same example, XYZ could make a URL like xyz.com/json_proxy that pulled data over from foobar.com behind the scenes, thus making the foobar.com data available on xyz.com. The problem with this is, XYZ would have to handle double the bandwidth of this data unnecessarily. This can be a big problem for smaller companies.

    I have an alternative solution to this problem. Instead of using XMLHttpRequest to load the data, we can just use <script> tags instead. These don't have the same cross-server restrictions as XMLHttpRequest. In fact, this is how Adsense works. You stick a <script> tag on the page which executes JavaScript coming from Google's server, and this writes out the ads on the page.

    To add a <script> tag to our page, we only need to call this function:

    function addScript(url) {
        var script = document.createElement('script');
        script.src = url;
        document.body.appendChild(script);
    }

    If we have a URL that returns some JSON data, we just pass that URL to this function and the page will load that data. Well, not entirely. There's a few things we need to do different. With JSON, you have some data like:

    {
       "firstname": "Jesse",
       "lastname": "Skinner"
    }

    and then use XMLHttpRequest with eval() to assign it to a variable. If you just stuck a script tag on the page to load this, nothing would happen. It would just load and the JavaScript parser would say "Great, nice little piece of data." But it's not going to assign it to a variable, so you'll have no way to access it.

    There's actually no way around this unless you change what is returned by the JSON data URL. This is the special trick. We would need the JavaScript to execute some function or assign the data to a variable. It would need to look like this:

    json_callback({
       "firstname": "Jesse",
       "lastname": "Skinner"
    });

    Now, we just need to make a simple function called json_callback() that takes the data and does something with it. Voila! Cross-server JSON.

    Rather than hardcode some callback function name, it would probably be better to add an optional "callback" parameter that would specify the function name. If the callback parameter is missing, the server can return standard ol' JSON.

    Let's say our simple JSON example above came from "foobar.com/data?format=json". If example.com was kind enough to provide this flexibility, they could add the parameter so that "foobar.com/data?format=json&callback=my_json_callback" formats the data as a function call, passing the data object to my_json_callback().

    Now, we just need to wait for web APIs with JSON to start supporting this parameter.

    Update: I've since discovered that Yahoo!'s JSON API already provides a 'callback' parameter exactly as I've described above, and I suspect that other APIs out there may support this as well. Either I'm psychic or there are time travellers working at Yahoo! ;) Here are the details from Yahoo!

  • JavaScript Games

    Aug 10 2006

    I've come across two JavaScript games in the past couple of days that have really impressed me:

    1. Lemmings! Seriously, it's nearly identical to the original lemmings game. It can run a bit slow but otherwise it's really impressive (via jim)
    2. A 3D Dungeon game from brothercake. This is a really cool usage of CSS border polygons and JavaScript to make a 3D world.

    Just a few fun examples to demonstrate the potential of JavaScript and CSS beyond Ajax, drag-and-drop and yellow-fade techniques - though of course nothing beats Buzzword Hellfire ;). Anyone have any more?

  • Freelancing Fulltime

    Aug 9 2006

    Big news: I'm quitting my job, moving back to Canada (with Svea of course) and taking the plunge into fulltime web development freelancing. This is something I've wanted to do for a long, long time (like seriously 10 years).

    I'll be available to do any sized projects, from debugging CSS to adding Ajax functionality to full-blown database-driven web applications in PHP or Ruby on Rails. I love doing it all, and I love the variety. I think that's why freelancing is going to be very fun for me. I also plan to have more time to work on my own projects and get some very interesting things started. Stay tuned for more on that.

    You can probably expect the content of this blog will start to include stuff about freelancing and self-employment. Hopefully I can help someone out by passing along any painful lessons learned. I'd also love to hear your stories and advice about going it alone.

    Anyway, if you'd like me to help you out with JavaScript, Ajax, CSS or whatever else, drop me a line.

  • JSON is not just Object Notation

    Aug 4 2006

    Until now, I've just considered JSON to be the equivalent to regular JavaScript object literal notation. Jonathan Snook has now explained the difference. It turns out JSON is a bit more picky than regular object literals. Key names must be quoted, and you can only use double-quotes around keys and values. Also, functions are not allowed as values.

    I gave an example of JSON some time ago that turns out to be wrong. I used single-quotes in my JSON example. I'll leave them there since the example works, but I just can't call it JSON.

    If you're doing JSON-style coding by hand for your Ajax communications, you can get away with using any object literals. So why care if it fits the JSON standard? Well, there are parsers and tools out there which can work with the JSON format, and if you don't fit the standard, they might not work.

    I have no idea why the designers of JSON didn't just make the standard flexible enough to handle single quotes and unquoted keys. It's also confusing that JSON stands for JavaScript Object Notation, and that Object Notation somehow means something different from the object literal notation in JavaScript. Great.

    Moral of the story: it probably doesn't matter if you use the JSON standard until you have to interoperate with JSON tools or feel the need to offer your JSON data to the public. You should probably stop calling it JSON if you use single-quotes, though.