Activate your free membership today | Log-in

Friday, January 9th, 2009

Beautiful Code Documentation

Category: Library, jQuery

Atul Varma (who I have the absolute pleasure to work with now) has created code documentation that actually looks beautiful. Typography matters.

You can check it out via his Ubiquity documentation example that shows you side by side documentation with the actual source code itself. This context is terrific. He does this all dynamically, and uses border padding to align the documentation with the code itself.

Here is what he has to say about how it is done:

The raw source code for the file being documented above just has chunks of comments that are marked-up in WikiCreole; when the parser runs into such a chunk, it renders it alongside the code it annotates using Ivan Fomichev and Chris Purcell’s JavaScript Creole 1.0 Parser.

The idea of using the documentation to annotate the code—or the code to annotate the documentation, depending on how you look at it—was inspired in part by some of the typography presented in Ellen Lupton’s excellent Thinking with Type, which I recommend to anyone interested in the field.

It’s nice not having a separate documentation build step: aside from making the process of writing and editing documentation quicker, it also lowers the barrier for entry to contributors since they don’t need to setup a toolchain. It also means that we get versioned documentation in every commit for free.

Right now there isn’t much else to the system; the only other feature I added is the auto-generation of quasimodal popup menus that link the names of XPCOM interfaces to their entries on XUL Planet and MDC. It’d be nice to have more features like this; other niceties would be an automatically-generated table of contents, JavaScript Doctests, search functionality, cross references to other code, and even the ability to fix code formatting errors in-page. For now, though, I need to focus on actually using this tool to document more code.

As soon as Ben and I saw this our minds started to race. What if you could navigate the code via hyperlinks too? Or have groups comment inline? Many exciting ideas.

It is fun to see the 80 character column limit in place (and seeing where that is ignored). 80 character limits with wide screen displays? I never get that :)

Posted by Dion Almaer at 9:11 am
1 Comment

+++--
3.4 rating from 16 votes

Tuesday, January 6th, 2009

QEvent: Small, Portable Event Library

Category: JavaScript, Library

Daniel Steigerwald told us about his labor of love: QEvent, a "powerful tiny extensible standalone event library". He provides this laundry-list of features:

* lightweight footprint
* no namespace pollution - everything is wrapped in obj.$QEvent
* normalizes the DOM event model
* work also with Javascript objects
* fixes common IE bugs including: all common used event properties, IE 2px bug http://ajaxian.com/archives/javascript-tip-cross-browser-cursor-positioning, fix many IE leaks, event handlers are FIFO executed
* prevents repeated registration of same type and listener
* 'this' in listeners references to object or element itself
* fixes window 'beforeunload' issue (doesn't work in Opera)
* fixes window 'unload' (must be removed by itself)
* fixes focus and blur events
* DOM events are more extendable: event keys, event objects ( event.myCustomFn() ), custom events
* firing events works for elements
* toggled and flashed events (removed after first fire)
* tested on (IE6-7, Firefox2/3, Safari, Opera, Chrome)

Isn't event sugar a solved problem? Daniel replies:

* Occasionally, I need a lightweight library that will work with other frameworks. Frameworks such as jQuery which don't extend the native prototype and therefor have no compatibility issues are not modular enough to meet my needs.
* No event implementation is perfect. So I took my own approach to the issue and created my dream package.
* This implementation could serve as a model for others.

The syntax is straight-forward:

JAVASCRIPT:
  1. QEvent.add(window, 'domready', function() { ... } );
  2.  
  3. // custom event
  4. QEvent.add(kitty, 'purr', onKittyPurr);
  5. QEvent.fire(kitty, 'purr', 'Sandy');
  6.  
  7. QEvent.remove(document.getElementById('testKeyEnter'), 'keyenter', keyenter);

Posted by Ben Galbraith at 10:45 am
2 Comments

+++--
3.5 rating from 11 votes

Monday, December 22nd, 2008

jQuery Gestures

Category: JavaScript, Library, jQuery

Adrien Friggeri has taken the music player ui and spent some time to create a really nice gestures library that allows you to add mouse gestures to a web page, supports complex (i.e. sequences of) gestures and provides visual feedback through the use of a canvas element.

Example code looks like this:

JAVASCRIPT:
  1.  
  2. // initialize the engine, inactive by default and set the trace color to red
  3. $.gestures.init({active:false,color:'#ff0000'});
  4.  
  5. // adds a new gesture : Down
  6. $.gestures.register('D', function() {
  7.   alert('down !');
  8.   });
  9.  
  10. // a more complex gesture : Down, Left, Up, Right
  11. $.gestures.register('DLUR', function() {
  12.   alert('this is a rectangle, no ?');
  13.   });
  14.  
  15. // you can log unknown gestures :
  16. $.gestures.error(function(gesture) {
  17.   alert("oops, I don't understand what \""+gesture+"\" means");
  18. });
  19.  
  20. // useful keyboard tricks :
  21. $(window).keydown(function(e) {
  22.   if ($.gestures.active() && e.which==27) {
  23.     // disable capture when user presses ESC
  24.     $.gestures.disable();
  25.   } else if (!$.gestures.active() && e.which==17) {
  26.     // enable capture when CTRL is pressed
  27.     $.gestures.enable();
  28.   }
  29. });
  30. $(window).keyup(function(e) {
  31.   // disable capture when CTRL is not pressed
  32.   if ($.gestures.active() && e.which==17) {
  33.   $.gestures.disable();
  34.   }
  35. });
  36.  

Posted by Dion Almaer at 8:28 am
10 Comments

++++-
4 rating from 31 votes

Friday, December 19th, 2008

DWR 3.0 near final release with RC

Category: Java, JavaScript, Library

Joe Walker and team have announced the first RC for DWR 3.0. We asked Joe to tell us what is new:

DWR now supports:

  • varargs
  • method overloading
  • typed parameters
  • binary file upload/download
  • it has a set of new types it can marshall

DWR will let you use JavaScript to implement Java interfaces (e.g. to register a Listener interface to publish changes to waiting browsers using Reverse Ajax), we now have 3 modes to control resource usage and there is a more scalable Reverse Ajax layer.

There are new integrations with Dojo, TIBCO GI and Aptana Jaxer, and a new DOM manipulation library.

We have special asynchronous servlet support for Tomcat and Glassfish, and our Spring and Guice integrations have been beefed up.

We now support JSONP and JSON-RPC, and there's a whole bunch of etc thrown in for good measure too.

There is a more complete list at Joe's blog, or you can just skip straight to the download page.

Posted by Dion Almaer at 6:02 am
Comment here

++++-
4.5 rating from 17 votes

Monday, December 15th, 2008

PNG support in IE6 that reclaims background repetition and position

Category: JavaScript, Library

Drew Diller has created a helper library in the "yup, you still have to get things working in IE 6" department. DD_belatedPNG adds PNG support to IE6 that works with background-repeat and background-position.

You just do this:

HTML:
  1.  
  2. <!--[if IE 6]>
  3. <script src="DD_belatedPNG.js"></script>
  4.     DD_belatedPNG.fix('.png_bg'); /* EXAMPLE */
  5.     /* string argument can be any CSS selector */
  6.     /* using .png_bg example is unnecessary */
  7.     /* change it to what suits you! */
  8. </script>
  9. <![endif]-->
  10.  

It is fun to see how it works:

It turns out that using another Microsoft language, VML, correctly implements the PNG format, or at least enough for our purposes.

More specifically,

  • Invoking DD_belatedPNG.fix() adds a line of CSS to the document via DOM.
  • The selector of this CSS is provided by the first argument for fix, which should be a string (such as #content div).
  • The declaration of this CSS is an MSIE-proprietary behavior.
  • The content of the behavior executes a function in the scope of each element matched.
  • The first duty of this function is to reset its own style.behavior to no longer have a value; allowing behaviors to continue unchallenged is a recipe of for CPU-eating disaster.
  • The function then examines the element's dimensions, location, and styles using element.offsetWidth, element.offsetHeight, element.offsetLeft, element.offsetTop, and element.currentStyle
  • Using the above information, a VML <DD_belatedPNG:rect/> node is constructed and prepended (element.insertBefore) to the element. Yes, element name prefixes are valid in XHTML.
  • The VML node is absolutely positioned to follow behind the element like a lost little puppy. It copies the matched element's z-index.

Drew also implemented border-width in a way that gets it working in IE 6 too.

Posted by Dion Almaer at 7:24 am
6 Comments

++++-
4.4 rating from 29 votes

Wednesday, December 3rd, 2008

A great example of sharing; Sizzle Engine in Dojo Foundation

Category: CSS, Dojo, JavaScript, Library, Prototype, jQuery

Voting has started in Dojo land to take in John Resig's Sizzle next-gem CSS selector engine.

This is incredibly exciting, as it shows how Ajax libraries are working together more and more. Instead of reinventing the wheel in different ways for each project, is it possible to find some core pieces that can be nicely shared? Of course, if our world was nicer and we could share code by linking in a nice way maybe this would happen more.

As I mentioned in my thanksgiving note, the work that the Ajax library developers do is hugely important and impactful, and having them work together can only be great news.

Take a look at this public email to the Dojo Foundation on the vote:

Overview

The Sizzle project is a JavaScript library for performing selections
across a DOM tree using CSS selectors. The library is designed to be
standalone (have no external dependencies), lightweight, fast, and
extensible. This culminates in a library that is perfectly suited for
integration into other libraries. While it's feasible that a developer
may use Sizzle directly the target audience for it is other library
authors.

The code for Sizzle can be found in the following Git repository:
http://github.com/jeresig/sizzle/tree/master

All of the code for the project has been written by John Resig and is
released under an MIT license. There are some patches pending from
some other contributors (namely Prototype).

Right now the following libraries are adopting or are looking to adopt
Sizzle as their primary CSS selector engine:

It's likely that Sizzle will become the unified engine behind a
majority of the JavaScript libraries on the market (if not in numbers
then certainly in market share).

The project is owned by John Resig who will serve as BDFL/Project lead
if the project is accepted. There is no formal voting process, as of
yet, but it's likely that one will come about, considering the number of
projects using the codebase.

If the project is accepted to the foundation then all contributors to
the project will be required to have a CLA and follow the policies of
the Dojo foundation.

It's very likely that Sizzle will eventually expand into other areas
of JavaScript libraries (such as DOM manipulation and event binding).

That last line excites me too! It is interesting to see this happen in the Dojo Foundation. Remember, Dojo was founded out of toolkits coming together to aggregate forces. Kudos to everyone involved, and good luck!

Posted by Dion Almaer at 12:58 am
12 Comments

++++-
4.5 rating from 52 votes

Friday, November 28th, 2008

SproutCore: Mixins and Talk

Category: JavaScript, Library

If you skip in 20 minutes to the presentation above you will find Charles Jolley talking about SproutCore:

During this presentation I actually built and deployed a small application on stage but the most interesting thing, I think, is the part where I talk about how thick client frameworks like SproutCore change the way you build your server side as well. It’s a model I call “microservices.”

SproutCore 1.0 is coming together nicely, and we keep seeing improvements such as mixin support that allows you to simply:

JAVASCRIPT:
  1.  
  2. MyApp.MyMixin = {
  3.   initMixin: function() {
  4.    console.log("mixin inited!")// just for demo
  5.   }
  6. };
  7.  
  8. MyApp.myController = SC.Object.create(MyApp.MyMixin, {
  9.   // other properties
  10. });
  11. // => "mixin inited!"
  12.  

Posted by Dion Almaer at 5:07 am
1 Comment

++---
2 rating from 12 votes

Friday, November 14th, 2008

Guid0: JavaScript GUIDs

Category: JavaScript, Library, Tip

Our own Michael Mahemoff is at it again, creating a simple little GUID generator called Guid0:

Guid0 is a GUID library for Javascript. Okay, it doesn't yet do official, bona fide, 128-bit, GUIDs yet, mainly for API design reasons. But this is a library you might find useful if you want to generate a unique ID in your Ajax app.

JAVASCRIPT:
  1.  
  2. // simple
  3. guid = new Guid();
  4. var newguid = guid.generate();
  5.  
  6. // options
  7. guid = new Guid(
  8.   {
  9.         chars: Guid.constants.base85// or you could say "abc" if you only wanted those chars to appear
  10.         epoch: "June 1, 2003",
  11.         counterSequenceLength: 2, // a counter field appended to the end
  12.         randomSequenceLength: 2 // a random field appended to the end
  13.   }
  14. );
  15.  

He is working on 128-bit support.

Posted by Dion Almaer at 6:47 am
3 Comments

++---
2.9 rating from 14 votes

Wednesday, November 5th, 2008

SproutCore: From MobileMe to 1.0

Category: Library

SproutCore drove onto the scene when MobileMe launched using it.

Since that blast, the team has been diligently working on getting a 1.0 release, and Charles Jolley has
posted on the future of SproutCore:

It’s been nearly four months since SproutCore launched to the public at WWDC and we couldn’t be happier with the results.  18,000 developers have installed SproutCore (sudo gem install sproutcore ftw), nearly 1,000 developers have joined the mailing list, and dozens of projects are underway at companies around the world.  One additional one has already gone public (OtherInbox).

During this time the developers working on SproutCore haven’t stood still either.  150 tickets closed, some major new features, and enhancements for Windows, IE7, Chrome, and others.  Many of the changes we’ve applied have come from you, the community.  In fact, over 20 people have contributed code to SproutCore now, which is outstanding for such a young project.

Now that I’m back from my trip, though, I thought we should spend a little time talking about where we are headed next.

Put simply, our next major milestone is SproutCore 1.0.  When I started planning SproutCore 1.0, here were the criteria I laid out for it:

  • Make the common easy and the uncommon possible. Typical behavior for an application should be nearly automatic without limiting a developer’s ability to hack something cool.
  • Support the whole application. SproutCore must support the whole application development process, including the model, view, and controller layers as well as design, testing, documentation, and deployment concerns.
  • A small consistent API. Favor configuration over class-bloat.  Use consistent “guessable” design patterns.  The API should be vetted well enough that it will not need to change dramatically once released.
  • Offer broad platform support. Perform well on all modern browsers.  Perform adequately on IE7 and earlier.

Charles then goes into detail on some of the bigger changes:

Faster Observers and Bindings

Property observing and bindings underpin almost everything you do in the SproutCore framework.  Because of that it is really important to make this feature small and fast.  We have currently rewritten this code to make it almost 2x faster on its own, and to use significantly less memory.  More on this in the coming days.

DOM Library Independence

Currently, SproutCore depends on Prototype for a few cross-platform functions.  This really doesn’t make much sense.  In particular we think of Prototype, jQuery, and others as “DOM manipulation libraries”; somewhat like low-level drawing APIs.  SproutCore should live above this layer, allowing you to choose whichever drawing library you like to create custom views.  Additionally, removing this dependence will allow those who do not want to use Prototype to eliminate that page weight from their apps.

New Model Layer

The current implementation for SC.Store, SC.Collection, SC.Record and the servers have not been revisited since they were written almost two years ago. When these were first deployed, they worked fairly well for the small apps that used them.  Since then we’ve seen applications loading 40,000+ records into memory in a regular basis and a move towards investigating use of the coming local storage facilities on modern browsers.  This code is going to see a wholesale rewrite as we update the API to accommodate this new, larger scale world.

There has been other SproutCore related news recently:

Posted by Dion Almaer at 9:59 am
1 Comment

++---
2.1 rating from 49 votes

Tuesday, October 28th, 2008

How to structure your JavaScript code

Category: JavaScript, Library

Peter Michaux has shared how he structures his code these days, as he has settled on a pattern:

The code example below is a simple little logger widget. It appends messages to a list and has a clear link to delete all the recorded messages.

JAVASCRIPT:
  1.  
  2. // Wrap code with module pattern.
  3. (function() {
  4.   var global = this;
  5.  
  6.   // helper functions
  7.   var sanatize = function(msg) {
  8.     return (String(msg)).replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;');
  9.   };
  10.  
  11.   // widget constructor function
  12.   global.MY_makeLogger = function() {
  13.  
  14.     // private instance methods   
  15.     var clear = function() {
  16.       LIB_emptyElement(logEl);
  17.     };
  18.     var append = function(msg, className) {
  19.       LIB_insertBottom(logEl,
  20.         '<dt class="'+className+'">' + (new Date()) + '</dt>' +
  21.         '<dd class="'+className+'">' + sanatize(msg) + '</dd>');
  22.     };
  23.  
  24.     // create widget DOM fragment
  25.     var parser = document.createElement('div');
  26.     LIB_upateElement(parser,
  27.       '<div class="Logger">' +
  28.         '<p><a href="#" class="clearLink">clear</a></p>' +
  29.         '<dl class="log"></dl>' +
  30.       '</div>');
  31.  
  32.     // find pieces and enliven DOM fragment
  33.     var rootEl = LIB_find('.Logger', parser)[0];
  34.     parser = null; // enable garbage collection of parser div
  35.     var logEl = LIB_find('.log', rootEl)[0];
  36.     LIB_on(LIB_find('.clearLink', rootEl), 'click', function(e) {
  37.         LIB_preventDefault(e);
  38.         clear();
  39.     }