October 14th, 2011 Posted by Dave Mahon
We’ve discussed Date.js before. It is an amazing library that makes date manipulation simple. On their home page, perhaps the most elegant line of code is (3).days().ago();
There is a downside though – it’s abandoned. Its last full release was November 2007 and code was last committed May 2008. Moment.js, on the other hand, is still under active development.
It also has integrated support for NodeJS, but what’s particularly cool about it is the emphasis on human-friendly times. The from() and fromNow() methods will return strings like “in 5 days” or “a year ago”, while the format() method can simply be passed “LL” to display a localized date, without the time, simplifying development.
It also adds a diff() method, quickly returning the difference between two moment objects, but in units of your choice.
That said, there are some things it doesn’t do that Date.js does. The comparison methods like compareTo() and equals() are nowhere to be seen, although you could certainly use diff() to emulate them.
Likewise, hasDaylightSavingTime() can quickly be rewritten as
return moment({month: 0, day: 1}).getTimezoneOffset() !=
moment({month: 6, day: 1}).getTimezoneOffset();
which is actually more succinct than the Date.js implementation.
June 6th, 2011 Posted by Don Albrecht
As a follow up to my last post, I thought I’d put out an instruction on actually creating a Google Chrome retreat.
Step 1: Add a Chrome Frame header to your site.
Add this to the head of the Chrome Frame dependent pages:
<meta http-equiv="X-UA-Compatible" content="chrome=1">.
If this isn’t practical, You can also configure your server to send an HTTP header of
X-UA-Compatible: chrome=1
I advise against this approach, however because server configs won’t be immediately available to other users on a site. By its nature, a Chrome Frame retreat should be considered a reasonably unique event. It’s good to clearly document this dependency for anyone else who may need to debug things later. Once you’ve started to retreat, make sure you’re applying the header to every page of the site. The two engines render things differently and you may create an inconsistent experience for your users if they are transitioning between Chrome Frame and Trident environments frequently. In my experience, border-radius and drop shadow toggling on and off is a pretty strong “It’s Broken” signal for end users.
Step 2: Identify your Dependency Wall.
- Identify the range of pages / screens in your web app that you can’t support in IE.
- Identify the navigation routes to those pages.
- Leverage the routes to find natural locations for gatekeepers.
-
- Login Screens (the perfect location)
- Tutorial Screens (A natural context fit for users)
- An Advanced Mode (Similar to the “enriched mode” Microsoft uses for ActiveX requiring cloud apps).
- If you’re lucky, this will be a screen somewhere beyond your conversion pipeline.
- Create an interception event for IE users. You can bake this into your app, but the easy way is with conditional comments.
- Identify the Dom Nodes in your layout that must be presented to the user for them to progress.
- <div id=’loginbox’>…</div>
- Create a conditional comment to hide the nodes and prompt the user to install Chrome Frame.
- Be careful of z-index. The chrome install iframe doesn’t work well if IE is floating some other content node on top of the install button.
- UN-INSTALL chrome frame once you’ve tested your retreat perimeter. This is a big deal for ongoing development as you won’t be testing in IE otherwise.
- Becareful about your conversion pipeline. Your key selling points may be behind the perimeter, but the act of demanding Chrome Frame is a pretty severe barrier to forward movement.
<html>
<body> <div id='prompt'></div> <!--[if IE]>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script>
<style>
#loginBox{
display:none;
}
</style>
<script>
window.attachEvent("onload", function() {
CFInstall.check({
mode: "inline",
}); });
</script> <![endif]-->
</body>
</html>
Other Lessons Learned
Here’s a few lessons learned from deploying this.