Loading...
[-]

Chrome Extension – Transperth Live Train Times

Install: Transperth Live Train Times Extension (8kb)Source: ArbitraryWebSlice2.zip

Chrome Extension IconAfter finding how simple it was to build the Arbitrary Web Slice Chrome Extension for the BOM website I decided to try another site. This time I wanted to get the TransPerth live train times because the full site is slow to load, the refresh reloads the whole page and some of the images don’t work. I wanted to just capture this part, but with working images rather than broken links:

By taking a slice I could address all of these issues and get the functionality I wanted. For this project, although still small, I expanded my horizons just a little and incorporated some manipulation of the returned data, an options page, some local caching via the localStorage and a very minor use of the Chrome API to load a new tab with the full page.

The code in the extension is split across three files:

  1. popup.html : Performs the core page retrieval and slicing action, showing the train times
  2. options.html : Allows the user to select a station (list of stations also sliced)
  3. common.js : Functions/variables common to both the popup and options

The popup.html file contains the most interesting code, with options.html performing largely similar tasks. The three core functions in popup.html are:

  1. addHandlers : When the sliced HTML is on the page we first delete the original onclick handler and add our own click actions here to do a custom refresh. Note: chrome.tabs.create is the call to the Chrome API which creates a new tab
  2. storeMain : Once the HTML has been retrieved:
    • Start with the <h2> with “Live Departure Board” and searching back up the tree grab the contents of first (0-indexed) table, then go one step up to capture the <table> too rather than just the contents.
    • Check that something was retrieved and if not assume no service
    • Search and replace to fix the broken images, then store the html to localStorage
  3. $(document).ready : When the page loads this runs and:
    • Checks to see if there is something in localStorage and if yes whether it is the station we are currently interested in

      • True: Grab the HTML from storage, display it so the user can immediately see what old times were, then fire the click handler to start the refresh process to get new times
      • False: Tell the user which station we are retrieving and then run the slicing code

When reviewing the code you might spot the unusual use of setTimeout to invoke the slicing rather than direct invokation, this gives us the ability to provide a small amount of feedback to tell the user that something is going on, with an AJAX spinner in this case. Credit to author of the Coffee, Code and Chocolate which is where I learned this method. Here’s the javascript from the popup.html file:

function addHandlers() {
    $("input").removeAttr("onclick")
              .click(function() {
                        $input = $("body").find("input").parent()
                                          .attr("align","left")
                                          .html("&nbsp;<img src=\"ajaxinfo_spinner.gif\"/>Refreshing Times...");
                        takeSlice();
                    });
    
    $("a").click(function() {chrome.tabs.create({url: url})});
}

function store(html) {
    storeOptions(html);
    return storeMain(html);
}

function storeMain(html) {
    var $slice = $(html).find("h2:contains('Live Departure Board')").parents("table:eq(0)").parent();
    if ($slice.html() == null) {
        return "No services currently scheduled for " + station_name;
    }
    
    $("<a href='#'>Transperth: Live Train Times</a>").appendTo($slice);
    
    localStorage["last_slice"] = ($slice.html()).replace(/www.dev.transperth/g,"www.transperth");
    localStorage["last_slice_stn"] = station_name;
    
    return localStorage["last_slice"];
}


$(document).ready(function() {
    setup();
        
    if ( (typeof(localStorage["last_slice"]) != "undefined") && (station_name == localStorage["last_slice_stn"])) {    
        $("body").html(localStorage["last_slice"]);
        addHandlers();
        setTimeout(function() {$("input").click();}, CONST_TIMEOUT_MS);
    } else {
        $("span").html("Loading times for " + station_name);
        setTimeout(takeSlice, CONST_TIMEOUT_MS);
    }

})

Here’s the completed extension:

Notes: The actual slicing action is not shown but performed by an AJAX call takeSlice() in the common.js file. The station options are sliced from the page every time the popup.html loads and stored in localStorage["options"] to keep them fresh. Lastly this extension is also a content script which fixes the broken images on the Transperth train times page.

Known Issues: Because jquery is loaded from Google’s CDN if you get a cache miss there could be a long period where jQuery is downloaded without feedback to the user that something is happening leading to a poor user experience.

Disclaimer: This is not a Transperth product and is not endorsed by them. There is no association between this site, this extension and Transperth.

One Comment

  1. Posted April 9, 2010 at 09:14 | Permalink

    Very nice!

2 Trackbacks

  1. [...] is an extension he’s made that I’ve found useful: Transperth Live Train Times. It even allows you to pick which train station you’re interested in. Just click the icon [...]

  2. [...] Cheesy Code Programming in C, C++ and C# Skip to content AboutPrivacy Loading… [-] « C++ pointers to non-static functions Chrome Extension – Transperth Live Train Times » [...]

Post a Comment

Your email is never shared. Required fields are marked *

*
*