Back | Minified | Changelog

Sugar v1.0 is out and once again it will the biggest release so far. I'm psyched. Let's go.

Date Locales

My own personal holy grail, Sugar dates now support 11 major locales out of the box: English, French, German, Spanish, Portuguese, Italian, Russian, Japanese, Korean, Simplified Chinese, and Traditional Chinese. Each locale has its own set of formats that can be both parsed in and formatted out. Although a single global flag can be set from the outset, locale codes can also be passed into each method that creates or formats a date as it is called. This allows for some really cool functionality -- languages can be mixed and matched within the page, set by the user, and locally overriden. Each localization is lazy loaded and adds its formats only when first called, so the only code executed is for locales that are actually used.

In addition to the main 11 languages, localization objects can also be passed to extend Sugar with other locales, and I plan to keep a main "locales" file as a main source for everything that didn't make it into the release package. The format handles quite a wide range of complexity, and so far I think I can say that this system should be able to handle any language that can be thrown at it. Did I mention that all 11 languages include relative date formats as well? Think "11 hours ago" in any language.

Okay, let's see the methods:

In addition, most date related methods now gain a locale parameter:

Other methods that don't accept a locale parameter will still accept a date object directly created by Date.create, which simply returns itself. For date creation methods, a locale only has to be passed once to be initialized (or set through Date.setFormat). Once it has added its methods, any date in that locale will correctly parse, whether a locale code is passed or not.

That's it! Creating multi-lingual dates couldn't be simpler. I'll continue to amass various locales so that even speakers of minor languages will be able to simply pull down their locale from the repo and plug it in. Also, I will be working to create a stand alone version of the Date module for those who just want this Date functionality by itself. This will be available in the repo but not on the site.

Object class changes

I almost wish that were all, but there's still some big updates left to go. First, the Object class has gained 2 methods:

Object.watch can observe standard Javascript objects and fire a callback when certain properties have been changed. This opens the door to do some really interesting stuff like property validation, etc. Unfortunately this functionality cannot be supported by IE8 and earlier (and also Opera at the moment), and this will be the only method in Sugar that does not have full support. This is probably a deal-killer for many of you, but now that Sugar is also available for node.js, I think it's justified. IE8 requirements as well will continue to fade in the future until this barrier is gone.

The sugar method on the Object class actually exists for all classes, but I'm choosing to only document it here. It allows methods that were overwritten -- mainly due to collisions with other libraries like Prototype -- to be restored. This can be done for the entire class by calling that class's sugar method with no arguments, or on a per-method basis. This is very useful for projects that still require Prototype support but want to opt-in functionality for a single method.

In the case of the Object class alone, the sugar method also serves another purpose. If it is called without arguments it will map all "extended object" instance methods onto the Object.prototype. This means that all objects will have hash-like methods such as keys, each, and merge. They also will have typing methods like isString, isFunction, etc. Now as we all know, modifying Object.prototype is "evil", which is why this feature will always remain opt-in. However, it still uses the standard Object.defineProperty method which, when available, means that for proper, modern browsers all methods will be non-enumerable, and will not appear in for..in loops, making them safe to use. If you feel like being a bit adventurous you can turn this on and enjoy extended methods on every object.

Function class changes

Function#debounce, which "settles down" function calls by only calling them once within a given period, now has the ability to fire off the callback immediately and lock itself, waiting for the specified period to elapse. Although similar in functionality, this makes interesting effects possible. The default behavior would be useful if a user tabs through form fields quickly and a callback is required when they "settle" on one. The new behavior would be useful if, for example, you wanted to instantly fire the callback to respond to user activity and make the effect feel more responsive, but still need to prevent the function from being "hammered on".

Function.lazy is useful for creating non-blocking, throttled functions that will wait a certain period to execute, even if called in rapid succession. In many cases, you want all calls to complete eventually, however there may be situations in which it is more important to prevent the call stack from going too high. One example of this would be something similar to the previous example, where a user is using the arrow keys to quickly navigate a UI. Rather than firing after they settle on one choice (ie. debounce), each keypress handler should be triggering a move to the next "step". However, if these functions are executed lazily, holding down the arrow key will quickly cause the calls to stack, and they will continue executing long after the key has been released. The new limit parameter for lazy functions will prevent this stack from going too high, so that lazy function execution can be capped at a reasonable threshold.

String class changes

Strings have also gained a couple new methods of interest:

String#assign allows assignment of variables and hashes to tokens within a string. This is similar to templating systems of some Javascript engines, but is designed to quickly get variables into strings, and solve the notable absence of string interpolation in Javascript.

String#spacify spaces out a camel-case, dasherized, or underscore string to a properly spaced out phrase. Use together with String#capitalize for great success.

String#hasLatin/isLatin added to the "hasType/isType" set.

Other changes

That's all for now!