Archive for April, 2010

Palm Dev Day: Adventures in Facebook

by on Apr.27, 2010, under Palm, webOS

Last Friday and Saturday Palm hosted their Dev Day event at their Sunnyvale campus, which I had the pleasure of presenting some of the techniques we learned while developing the Facebook for webOS application.

This presentation covered everything from our best practices to debugging and development tools to the common libraries we developed for the application. I would recommend webOS developers take a look as the topics covered deal with many common app development concerns.

As part of this presentation we have open sourced a collection of the libraries and tools that are used in the Facebook app development.

The slides from my presentation are available on slideshare and a video should be published in the near future. Additional presentations from the event have been made available under the palmdev slideshare tag

On a personal note, I would like to say that it was awesome to meet some of the developers who are using webOS, particularly in the Apps Lab breakout section!

Stay tuned for in depth posts on the topics discussed in my presentation.

Comments Off on Palm Dev Day: Adventures in Facebook :, , , more...

border-image-generator

by on Apr.04, 2010, under border-image-generator

Update: border-image-generator is not hosted on border-image.com. The previous URLs are configured to redirect to this url.

Example of the border-image-generator visual editor. The CSS3 border-image property allows for some very cool and efficient design but after implementing them in both Mozilla for the Firebug search panel and WebKit for the Palm Facebook notifications badge, I’ve learned that they can be quite frustrating to properly tweak by hand.

Background

For those who have not been exposed to this property, it allows a single image to be used to style the borders and background of a particular element. In the example above, each section will map to a different border, corner, or the content background, allowing for a single element and image to provide styling the previously required significantly more of each.

Using these properties the following element can be rendered using simple semantic HTML and CSS.

Element rendered using border-image
<div class="stylishContent">Some stylish content</div>
.stylishContent {
    display: inline-block;
    border-width: 27px 27px 27px 27px;
    -moz-border-image: url(http://www.w3.org/TR/css3-background/border.png) 27 27 27 27; -webkit-border-image: url(http://www.w3.org/TR/css3-background/border.png) 27 27 27 27;
    border-image: url(http://www.w3.org/TR/css3-background/border.png) 27 27 27 27;
}

For more detail, John Resig has published an excellent writeup on the Mozilla implementation.

App

As noted above there is a bit of tweaking involved in getting these settings right. To ease some of this pain I’ve created the border-image-generator project, which allows for WYSIWYG editing of these properties. Rather than manually adjusting each parameter, border-image-generator allows the various parameters involved to be changed visually with instant preview of what these changes will look like in the current browser.

Seen in action demonstrating Resig’s examples here and here.

Features

  • WYSIWYG editing of border-image properties
  • Cross-browser border-image CSS generation
  • URL-based State (History + Preview in multiple browsers)

It can be accessed through any of the following URLs:

Any issues or suggestions for improvements can be sent to myself or logged in the github issue tracker.

Warning

As a preliminary warning this is currently a vendor experimental feature but it is currently set to be included in the CSS3 specification. There are some significant differences between the vendor implementations and the W3C candidate, so some caution should be used. Border-image-generator attempts to handle these cases as defined by the spec, but many things could change between the current implementations and the release of CSS3 implementations in the wild.

Related Links:

5 Comments :, more...

Garbage Collection Gotchas in webOS

by on Apr.02, 2010, under Palm, webOS

Making the jump to mobile development from desktop and server development can lead to quite a few gotchas due to the resource constraints inherent to mobile environments. This became very clear to me today while debugging an intermittent failure in the Facebook application’s news and notifications scenes.

Like every other debugging session for intermittent issues there were quite a few choice words used in the process and many dead ends, but eventually it became apparent that some vital Mojo.Service.Request service requests were not calling any of their notification callbacks. Expecting the onComplete callback to occur at the very least, I was very perplexed until I spoke with some of my esteemed colleagues at Palm and they pointed me to the garbage collector as the possible culprit for this situation.

The code in question was instantiating Request objects but not maintaining references to these objects. This is fine up until the point that the garbage collector runs and the request object as well as all callbacks are collected. At this point these requests could no longer notify the application of their completion, blocking further processing of the queues associated with these requests.

After storing the instantiated Request objects until completion all of the calls that were previously disappearing into the ether began to return as expected.

The moral of the story is that you need to be very careful about what references are maintained when working with garbage-collected languages in memory-constrained environments. If you want something to stay around, like callback methods, you need to be certain that it is referenced somewhere. To ease this task for Mojo.Service.Request calls (controller.serviceRequest calls are safe as the controller maintains a reference to the request object or cancels the request prior to popping the scene), we implemented the following wrapper:

var ServiceRequestWrapper = Class.create({
    initialize: function() {
        this.requestId = 0;
        this.requests = {};
    },

    request: function(url, optionsIn, resubscribe) {
        Mojo.Log.info("Service request wrapper url: '%s' method: '%s' CALLED", url, optionsIn.method);
        var options = Object.clone(optionsIn),
            requestId = this.requestId++;
        options.onComplete = this.completeHandler.bind(this, url, optionsIn, requestId);

        this.requests[requestId] = new Mojo.Service.Request(url, options, resubscribe);
        return this.requests[requestId];
    },

    completeHandler: function(url, optionsIn, requestId, response) {
        Mojo.Log.info("Service request wrapper url: '%s' method: '%s' requestId: %d COMPLETE", url, optionsIn.method, requestId);
        delete this.requests[requestId];

        optionsIn.onComplete && optionsIn.onComplete(response);
    }
});

By instantiating this on a location that will not be collected during the application’s lifetime and using the request method rather than direct Mojo.Service.Request calls for all requests that the result is necessary you can avoid this problematic scenario as well as save the choice words for a later time :)

7 Comments :, , , more...

Visit our friends!

A few highly recommended friends...