Archive for October, 2008

* Aptana Cloud Officially Released

Posted on October 31st, 2008 by Dave Johnson. Filed under Uncategorized, cloud.


There has been a lot of talk these days about cloud computing with big announcements by by Google, Amazon and Microsoft practically daily.

Now add Aptana to that list. Not only do they make a great Ajax IDE in Aptana Studio but they have also been developing their own cloud solution. Kevin Hakman from Aptana puts it thusly:

Aptana Cloud is an elastic hosting and application lifecycle management service that’s integrated right into Aptana Studio and thus Eclipse. Basically it takes all the sys-admin work out of the process and gives developer and their teams instant scalable production environments that take only minutes to deploy to, and delivers hosted source control, staging environments, backups, monitoring, reports, stats, etc… to streamline the entire app lifecycle – even before you go live. (and it costs just $0.04 cents an hour to get started, except there’s also a free trial promotion for a limited time too).

Andre and I recorded a video with Kevin back at JavaOne where Kevin gave the world it’s first peak at Aptana Cloud so it is cool to see it get to the 1.0 release!

Check out this blog post form Aptana for a little more info about it.

Tags: , , .



* Welcome humans and machines alike

Posted on October 24th, 2008 by Dave Johnson. Filed under Uncategorized.



.



* Voting Green

Posted on October 13th, 2008 by Dave Johnson. Filed under Politics.


The Canadian election is set to happen in less than 24 hours now and it is looking like the Conservative party is going to get another minority.

While in a perfect world I would be voting Green there is a very real possibility in this election that voting Green could give the Tories a majority by splitting the green vote between Green and Liberals. Therefore, I have decided to vote for the environment. By giving my vote to the Liberals I am supporting a great environmental policy in the Green Shift, which in terms of climate change is the same policy as the Greens.

In my riding of Vancouver Kingsway there is really no chance that the conservatives could get in given the whole Emerson episode, yet, there is quite a bit of support for the NDP and I really don’t like Jack Layton nor the NDP environmental policies.

If ou are interested in strategic voting then check out Vote for Environment and see what it looks like in your riding.

Tags: , , , , , , , .



* Surfin’ Safari

Posted on October 9th, 2008 by Dave Johnson. Filed under AJAX, CSS, JavaScript, XML, completeui, quirks, safari.


For the past little while I have been busy fixing up Complete UI to work in Safari. The big problem for us in getting Complete UI working in the WebKit powered browser was that there was no client side XSLT JavaScript API until Safari 3.

So there were a few things I had to update to get things all working properly - and this more or less applies to Chrome now as well but I need to check on a few things.

XMLDocument::selectNodes

The first problem I came across was using the XMLDocument::selectNodes method. To get selectNodes working I had to implement my own NamespaceResolver which is usually handled for you by the browser.

I had to change the call to the XMLDocument:evaluate method a bit to look like this:

var oResult = this.evaluate(
  sExpr,
  (oContextNode?oContextNode:this),
  new MyNSResolver(),
  XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
  null);

Where the MyNSResolver class essentially implements the lookupNamespaceURI method through a switch statement returning the appropriate URI for the specified namespace prefix. Pretty easy but kinda annoying to figure out!


function MyNSResolver() {};
MyNSResolver.prototype.lookupNamespaceURI = function(prefix) {
  switch (prefix) {
    case "xsl":
      return "http://www.w3.org/1999/XSL/Transform";
      break;
    case "ntb":
      return "http://www.nitobi.com";
      break;
    default:
      return null;
  }
}

XSLT Transformations

Then there was the actual act of performing an XSLT transformation. Doing the transformations was fine but getting the output node or string from the transformations - depending on if the <xsl:output /> was text, html or xml - was rather different than both Firefox and Internet Explorer. Go figure.

For transforming to an XMLDocument here is what I found to be the output of an XML transformation for the various output methods.

Text:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <title></title>
  </head>
  <body>
    <pre>innerText</pre>
  </body>
</html>

XML:

<output>innerText</output>

HTML:

<html>
  <body>
    <output>innerText</output>
  </body>
</html>

XSLT Parameters

There is also one difference in how the Safari XSLT processor deals with parameters. Rather than casting true / false to 1 / 0 the Safari XSLT processor does not recognize true or false values and requires the inputs to be 1 / 0. I have started setting all my XSLT params like this:


oXsltProc.addParameter("paramName", val+0, "");

Events and Focus

There were some other small issues that I came across regarding implementing rich keyboard navigation and events in general.

For example, in our Grid component I had to change the HTML element that we used to “focus” the Grid so that we could capture key presses from a <DIV> to an <INPUT>. Apparently you can’t call Element:focus on a <DIV> element from JavaScript but you can on an <INPUT> (even with a tabIndex set but I try to avoid those for accessibility reasons anyhow).

However, that was not my only problem with keyboard navigation. The other problem was that the focusable element (the newly created <INPUT> in this case) was still not getting focus due to a small code snippet like this:


oMyInput.focus();
cancelEvent(evt);

That second line where I cancel the event (wrapped nicely in a cross browser library call) somehow prevents the <INPUT> from getting the focus. Never figured out a workaround aside from a browser check before calling cancelEvent.

CSS

Finally, in some of our components we also generate CSS using XSTL and dynamically insert it into the page. For example, the developer defined column widths in a Grid produce dynamically generated CSS. However, WebKit does not seem to support the bulk creation of stylesheets neither using the document.createStylesheet method of Internet Explorer nor the hacky way of doing in Firefox by creating a <STYLE&gt element and setting the innerText. Instead Safari requires that you use the uber slow DOM API for adding rules to stylesheets :(

Miscellany

You will often see the “xml namespace prefix mapped to wrong URI” error when working with XSLT in Safari.

Be careful that you are using double quotes in your XSLT for attributes etc and only use single quotes in attribute values.

Of course you also have to be very careful about the nodes that you are transforming / selecting as you are also likely to get the “WRONG_DOCUMENT_ERR” fairly frequently.

Oh yah and depending on the application expect a lot of random “Stack overflow” errors!

Tags: , , , , , , , .



* Rails Timezones

Posted on October 5th, 2008 by Dave Johnson. Filed under AJAX, Components, Flex, Uncategorized, Web.


In my spare time I have been working on a geo-location application that runs on a BlackBerry mobile phone connecting to a Rails server where the geo data is stored.

If you happen to still be using Rails < 2.1 then this may be interesting, however, with the recent release of 2.1 timezones have been fixed up pretty well. Of course I wanted to get something that worked for my application in pre 2.1 days so I rolled together a few different libraries that seems to work pretty well. Having said that, the JavaScript will help you determine a users timezone no matter what version of Rails you are using.

The particular use case that I want to hit is that people can login to the web application from wherever they want and the application will automagically display the times in the timezone of the user viewing the site - not the timezone of the user that created the geo data and not the timezone of the server.

The general approach taken is to get the users timezone offset through JavaScript in the browser, then save that in the users profile, and then have a helper method to convert any times that are saved in the servers timezone to the users local zone.

Prerequisites

Gems: tzinfo (0.3.9, 0.3.8), tztime (0.1.0)

Plugins, tzinfo_timezone, tztime

Now for the code

So how do we figure out the users timezone? Through JavaScript of course! In application.js put the following script at the top - don’t put it on the onload event since it should set as soon as a user hits the page:


Cookie.set("tz", (new Date()).getTimezoneOffset());

This sets a cookie in the browsr to be the JavaScript timezone offset, which we will use later on the server. Note that this is using a simple cookie abstraction.

Now in application.rb we need some magic that will take that timezone offset from the cookie and update the users profile with their current timezone. This will be achieved with an around_filter (damn I love around filters) like so:


around_filter :set_timezone

def set_timezone
  if logged_in? && browser_timezone && (browser_timezone.name != current_user.time_zone || current_user.time_zone.nil?)
    current_user.update_attribute(:time_zone, browser_timezone.name)
  end
  TzTime.zone = logged_in? ? current_user.time_zone : browser_timezone
  yield
  TzTime.reset!
end

def browser_timezone
  return nil if cookies[:tz].blank?
  @browser_timezone ||= begin
    min = cookies[:tz].to_i
    TimeZone[-min/60]
  end
end

That takes care of getting the users current timezone. Now all we have left is to make it accessible to the application with a simple function in the application_helper.rb as follows:


def local_time(time_at)
  TimeZone[TzTime.zone].utc_to_local(time_at.utc)
end

Finally, we can just call local_time from anywhere passing in a time that is in the servers timezone from the database:


local_time(location.updated_at)

So if you are stuck on Rails < 2.1 that is a good approach to getting timezones working.

.