Archive for category Developer
Understanding Time Zone Detection in JavaScript
Posted by Jon in Developer, Javascript on March 5, 2011
Since writing this post, the code has changed dramatically. The code below still serves to describe the algorithm though. Read on!
After some hard searching online for help with automatically detecting user’s timezones with Javascript, I only came up with this one really good hit. Josh Fraser had done some preliminary work on the subject here. And his script worked really well for many cases.
However it soon became clear that there is an extreme abundance of ambiguities when it comes to time zones. And it all comes down to daylight saving time (DST), without which, the world would be a better place. :)
The difficult part is distinguishing between timezones,
- in the same UTC offset,
- in the same hemisphere,
- and that all use daylight saving time,
- but use daylight saving time differently!
My favorite example is the UTC+2 region, where many timezones differ only in which hour of the day DST starts yearly.
Anyway, for many reasons, it is very handy to have a robust determination of a user’s timezone at hand, I and wanted to do this the right way.
I set out trying to improve on Josh Fraser’s script and had two goals in mind:
- Automatically detect all unique modern time zones. (I don’t care about timezones as they were in the 18th century, and I don’t care that Helsinki time and Istanbul time are different historically, in modern time they are indistinguishable).
- Map these timezones to the Olson zoneinfo database, so that I can save a user’s time zone for use in system generated mails, batches, and even for displaying server generated pages to the user in their local time.
Using a simple algorithm wherein all known ambiguities regarding daylight savings are sorted out, I set about doing just this. The result of my work is now open sourced as the project jsTimezoneDetect on Bitbucket. And you can test the demo of it here.
Just to briefly describe the algorithm, it goes a little something like this. Imagine that you are in Alaska when you read this code:
function get_timezone_info() { // Alaska offset in january is -540 minutes from UTC var january_offset = get_january_offset(); // Alaska offset in june is -480 minutes from UTC var june_offset = get_june_offset(); // returns 480 // There's a -60 minutes offset difference between january and june in Alaska var diff = january_offset - june_offset; // Diff = -60, so we know that this region uses daylight savings, // and is in the northern hemisphere. Also we know that the January // offset is the common denominator for the timezone, i.e 540 minutes = 9 hours if (diff < 0) { return {'utc_offset' : january_offset, 'dst': 1, 'hemisphere' : HEMISPHERE_NORTH} } // This is where we end up for southern hemisphere daylight savings time zones else if (diff > 0) { return {'utc_offset' : june_offset, 'dst' : 1, 'hemisphere' : HEMISPHERE_SOUTH} } // this is returned for non DST time zones return {'utc_offset' : january_offset, 'dst': 0, 'hemisphere' : HEMISPHERE_UNKNOWN} }
Here are some return examples from the function, for different timezones:
// Central Australian Time (Audelaide): {utc_offset=570, dst=1, hemisphere="south"} // Central Australian Standard Time (Darwin) {utc_offset=570, dst=0, hemisphere="N/A"} // Central European Time {utc_offset=60, dst=1, hemisphere="north"} // Alaska {utc_offset=-540, dst=1, hemisphere="north"} // Mountain Time {utc_offset=-420, dst=1, hemisphere="north"}
Using the info provided by this function I can map to a list of Olson timezone info keys. However, there are ambiguities. In many cases it is not enough to check January and June to make a granular enough distinction. Therefore I added the added knowledge of ambiguous time zones to the script, and when it detects possible ambiguities it will sort them out for you by checking known dates when DST started in different regions.
If you feel the need to use this script, check out the Bitbucket repository for the complete source code.
If you just want to test it, go to the demo page.
Use tap events instead of click events in iPhone browser
Posted by Jon in iPhone, Javascript on June 18, 2010
When working on a web app for embedding in a iPhone application we came across jQTouch, a really nifty little jQuery plugin which makes it easy to create a web application UI that really resembles that of a native iPhone application.
We soon encountered a problem due to the fact that click events are rather slow to fire on the iPhone. There is a delay due to the fact that the iPhone waits for the user to complete a gesture before deciding that the intended gesture was in fact a click.
JQTouch uses divs to navigate between screens, so for example if you have the div
<div id="primary-view"></div>
you can simply navigate to it through a normal anchor link, and the transition will thanks to jQTouch be really “iPhone like”.
<a href="#primary-view">Primary view</a>
Our main problem is that we load our content dynamically through Ajax. So our links looked like this:
<a onclick="fetchContent();" href="#primary-view">Primary view</a>
This resulted in a race condition. The anchor link listens to the tap event which is fired much earlier than the click event, and therefore we mostly ended up in empty views. So we needed to replace all onclicks to ontap listeners. The problem then is that we could no longer test our webapp in a normal desktop based Safari browser.
So, we decided to happily go along and write inline onclick events on our links and other interaction elements. But while in the iPhone we see to it that the onClicks are removed and replaced with tap listeners.
That function looks like this:
function rebindClicks(){ var userAgent = navigator.userAgent.toLowerCase(); var isIphone = (userAgent.indexOf('iphone') != -1) ? true : false; if (isIphone) { // For each event with an inline onclick $('[onclick]').each(function() { var onclick = $(this).attr('onclick'); $(this).removeAttr('onclick'); // Remove the onclick attribute $(this).bind("click", preventClickEvent); // See to it that clicks never happen $(this).bind('tap', onclick); // Point taps to the onclick }); } } function preventClickEvent(event) { event.preventDefault(); }
We now call this little function everytime the DOM is changed. If something turns up with an inline onclick. It is will be rerouted by jQuery to a tap listener instead.
Again, we felt we needed to do this because many of our developers do not have a Mac (and hence do not have the iPhone simulator). And testing on the iPhone can be really time consuming. So for testing during development we wanted to use onClick, and when testing on iPhone we wanted to use taps instead.
But the biggest bonus was without a doubt that things are overall much faster in the web application. Taps fire much faster than clicks in the iPhone.
Here’s how it looks running the same app both in desktop safari and embedded into the iPhone simulator.
Flickr Searches in 3D
Posted by PEZ in Flex/AS, Innovation on November 3, 2009
I’m experimenting with tying that 3D Album I mentioned earlier to Flickr Searches. Looks like this for now
ThreeDeeGallery.swf
Work in progress, both the app and this blog post.
So you wanna be a front end developer?
Posted by Olle in Javascript on May 13, 2009
Back in the day when I was a young boy in the big IT-industry I wanted to become the greatest front end developer the web had seen. Due to circumstances, out of my hands of course, I did not reach my goal, but I did get to “know” some great ones along the way!
So I guess you possibly have some schooling to bring to the table, or you have been working with back-end stuff stuff for quite some time, you know what object oriented programming is or at least want to learn, and most importantly you have the will to learn!
When I started to become really interested in front end development back in the late 90′s, front end development was not looked upon as real programming, real programming was C++, Java and the likes. But now, we have job titles like Senior Front End Developer at for instance Yahoo and Google, so I guess that the understanding of the importance of good front end code has really elevated.
So my way of learning the craftsmanship, was to study the masters below, downloaded their code, read it, and then write my own! If it worked for me, I’m sure it will for you!
Scott Andrew LePera
What really got me started was a guy named Scott Andrew LePera(http://www.scottandrew.com/). He got me all warm and fuzzy talking about for instance event handlers in javascript and how event bubbles
Aaron Boodman
After that I stumbled over Aaron Boodman, the youngpup (and creator of Greasemonky among things) showed me all about how to create the menus that we love to have, how to make the Javascripts run smooth in animations, and how drag of elements shall be done. Back in the beginning of the 2000 he had the coolest UI on his blog, and nothing I have seen since has turned me on as much as viewing youngpup.net for the first time(except possibly 13thparallel)!
13thparallel
13thparallel made me think about coding for portability, introduced me to the concept of the Viewport among other things.
WebFX
Emil A Eklund and Erik Arvidsson at WebFX showed me that it was possible to create a forum on the web with outstanding functionality and speed(unfortunately it only looks good in MS IE), how to work with XML in advanced Javascript.
Peter-Paul Koch @Quirksmode
Quirksmode helped me really understand the differences between browsers and what do do about it. He also really introduced me to Unobtrusive JavaScript.
Remember that most of the examples above have been written back in 2001-2002, and they still work..What does this tell us, well to use the standards, and no browser specific hack, because browsers change and you will end up chasing your own tail to make things work in new browsers.
Rails deploy using sqlite3
I had a hard time figuring out why, when reading up on capistrano, I couldn’t find any info on how to deal with the database file. That was until I realized most people don’t deploy on sqlite3. With mysql and other databases you have a server and it’s automatically “shared” then.
The only information I found on deployment on sqlite3 was an excellent deploy script in this blog article. Basically, using sqlite3 you have to make sure the database is in a shared directory across releases. But the sqlite3 parts of that deploy script didn’t work for me as they were. I had to make sure I referenced the shared database path all the way or I risked overwriting my database with a symlink. Below are the sqlite3 parts of the resulting capistrano script.
Setting up the shared database path. NB: Lazy binding. Important if you’re using multistaging from capistrano-ext.
set(:shared_database_path) {"#{shared_path}/databases"}
Sqlite3 tasks.
namespace :sqlite3 do desc "Generate a database configuration file" task :build_configuration, :roles => :db do db_options = { "adapter" => "sqlite3", "database" => "#{shared_database_path}/production.sqlite3" } config_options = {"production" => db_options}.to_yaml put config_options, "#{shared_config_path}/sqlite_config.yml" end desc "Links the configuration file" task :link_configuration_file, :roles => :db do run "ln -nsf #{shared_config_path}/sqlite_config.yml #{release_path}/config/database.yml" end desc "Make a shared database folder" task :make_shared_folder, :roles => :db do run "mkdir -p #{shared_database_path}" end end
Hooks (or whatever they’re called, I’m new to all this).
after "deploy:setup", "sqlite3:make_shared_folder" after "deploy:setup", "sqlite3:build_configuration" before "deploy:migrate", "sqlite3:link_configuration_file"
Hope this helps someone. Please don’t hesitate to ask should something need more explaining. And of course suggest improvements. This is all the makings of a capistrano newbie.
Submitting iPhone app to App Store
Posted by Samuel in Innovation, iPhone on May 8, 2009
Finally, after two bounces and three weeks of waiting, our first app on App Store is available!
I’ll keep this post really short!
Pros
Cons
Some good to knows!
The App Store review process: 4 stars out of 5Conclusion
If you are curious about our iPhone application, please visit our app section @ App Store.Projectplace for iPhone
Stopp Internet Explorer’s CTRL – MouseWheel
As a Flex developer I come in contact with all sorts of problems when I run my applications in Internet Explorer 7. One of the most annoying ones is the one where CTRL – MouseWheel will resize the Flex application area itself, even when the application is scaled to 100% * 100% of your browser window and has focus. This is impossible to accept and here is the solution to the problem.
Assuming that you’re working with Flex Builder, all you have to do is edit the index.template.html file a little bit. Such that it contains the following JavaScript.
function catchCtrlMouseWheel() { if (window.event.type == "mousewheel" ) { if (window.event && window.event.wheelDelta ) { return window.event.ctrlKey ? false : true; } } return true; }
And in the <body>-tag:
<body onmousewheel="return catchCtrlMouseWheel()">
Use cacheAsBitmap correctly – or not at all
You may have heard that the cacheAsBitmap functionality introduced in FlashPlayer 8 and available since Flex SDK 3 can sometimes help you improve performance. That is true, but only as long as the disply object is only moved.
- If you apply any other transformation on the display object, FlashPlayer will cache a new rasterised version of the object for each iteration of the transformation.
- If you apply any filters to your object, two versions are cached, one “normal” and one for the filtered result.
Both of these things may result in a higher than necessary load on your CPU and memory resources, when doing anything but only moving the display object.
Therefore, use cacheAsBitmap only on display objects that you know will only be moved around the stage, never on objects that will have any other sort of transformation.
An added problem with cacheAsBitmap is a known “bug” in the Mac version of the FlashPlayer where display objects that are using it can misunderstand their own redraw regions, resulting in a corrupted view. It seems rather rare though.
Also, when extending UIComponents – the default FlashPlayer behaviour is to heuristically try to find out if you usually cacheAsBitmap. If you look at the code in UIComponent of Flex 3 SDK you will find the following statement:
private var _cachePolicy:String = UIComponentCachePolicy.AUTO;
To make sure that the default behaviour of all of your objects that inherit from UIComponent instead inherit from your own extension of UIComponent which could invoke
this.setCachePolity = UIComponentCachePolicy.OFF
There are many people out there who have opinions about the cacheAsBitmap functionality as it is implemented today. Two examples are:
Use Flex and set it free
Posted by PEZ in Flex/AS, Innovation, iPhone, Values on April 17, 2009
I work at Projectplace Labs. In fact I’m managing it. No doubt it’s the best job I’ve ever had. Imagine getting payed for experimenting with far out things all day. Two examples:
- Samuel, who also works at the lab and blogs on this site, started to play with the iPhone SDK some month ago and just yesterday he sent a Projectplace client for the iPhone to AppStore. It should appear there any day soon. Computer Sweden wrote about it today (Swedish).
- A year ago I tried out Sandy3D (awesome 3D engine for Flash written in AS3) and quickly got a prototype up for a Cooliris-inspired photo wall, it was WOW to me so I called it WowAlbum. Not as immediately business applicable as Samuel’s iPhone app, but a fun thing to do.
Projectplace Labs is very much inspired by those big, innovative, forces out there. Mozilla Labs, Microsoft Office Labs, Adobe Labs and, of course, Google Labs. Google is probably our main inspirational source. We’re trying to reverse engineer Google’s innovation machine and apply what we feel fits us (or at least try to convince our managers to let us apply it). We’ve also taken Quincy Jones’ receipt for success to our hearts;
We apply it on all levels. Ideas, creativity, people, innovation, inspiration, code, joy, love. Unleash!

Yap - planning made fun
Ummm, I was definately not planning to write about Projectplace Labs in this blog. Got a bit carried away there. I was mainly about to use the Bagonca server to make a development version of Yap available to a guy I’m working with at A-Dato. Then I thought, heck I can blog about it, and then I felt I needed to tell about where I work.
And now I need to tell you something about Yap too, right? You can read a little about it at Projectplace Labs and also at Projectplace Ideas. To cut a long story short:
We, Projectplace, want to be the company who made project planning fun.
That development version of Yap that you can access even before it appears on Projectplace Labs? Don’t worry, I haven’t fogotten, here goes:
Now, how cool does this make Bagonca? It even publishes Projectplace Labs stuff before Labs! =)
