Activate your free membership today | Log-in

Thursday, February 19th, 2009

Nextpoint releases open source project Growl4Rails

Category: Component, JavaScript, Prototype, Rails

The team at Nextpoint has released the open source project Growl4Rails, a component providing Growl-like functionality in Rails web applications.

Nextpoint’s e-discovery product deals with many very large documents. Indexing, imaging and PDF-ing of those documents can take a bit of time, which requires us to execute these tasks asynchronously. Background processing demands a solid way of notifying users when that process has completed. We’re a Mac shop, and one of the first things most Mac users install is Growl. We thought that Growl’s interface could really be successful on the web and provide a great way of notifying our users when this background processing has completed.

Read more about how Nextpoint is using Growl4Rails.

Growl4Rails is available as a Rails plugin on Github. It requires Prototype 1.6 and Scriptaculous 1.7, and it has been tested on FF, IE 6-8, Safari, Opera and Chrome.

Posted by Dion Almaer at 12:01 am
1 Comment

+++--
3.8 rating from 25 votes

Wednesday, February 18th, 2009

JavaScriptMVC 1.5 Released

Category: JavaScript

Justin Meyer emailed me to let me know that JavaScriptMVC, the framework that provides a Model-View-Controller (MVC) pattern for JavaScript development, has been updated and version 1.5 is offically available for download.

New features include:

  • Env.js/Shrinksafe based compression: A custom env to simulate the browser. As the browser encounters script tags, it adds them to a collection and then compresses them. This means instant file concat and compression from the command line with no extra work.
  • Env.js Testing: Prior to 1.5, tests ran in the browser only. With Env, the same tests can be run from the command line. Great for projects where you need a quick way of checking if functionality works before check-in.
  • Documentation:New JavaScript based documentation library split between JSDoc and NaturalDocs.
  • Code Generators: Added code generators and made building custom ones easy too by using EJS.
  • Scaffolding: Helps you develop iteratively by connecting to default Rest services and providing an easily expandable CRUD interface.
  • Engines+Plugins: Added a command line plugin and dependency installer. So, if a developer wanted a jQuery plugin, he can install it from the command line, and it will also grab jQuery.
  • Custom Event Delegation: Besides improving event delegation to cover all the cases that even live doesn’t do, they’ve expanded it to include custom events such as drag+drop, lasso, hoverenter, mousenter. Developers can have the benefits of event delegation with these complex events.
  • Easy Update: JavaScriptMVC can update itself from the command line.

JavaScriptMVC v1.5 is now available for download and a new, updated “Getting Started” page is available to get you up to speed quickly.

Update: A more detailed writeup can be found here: http://javascriptmvc.com/wiki/index.php?title=1.5

Posted by Rey Bango at 3:31 pm
Comment here

+++--
3.4 rating from 28 votes

JavaScript Inheritance Performance

Category: JavaScript, Performance

Robert Kieffer has run some benchmarks on the performance of JavaScript inheritance using different inheritance techniques:

One area of the Prototype JavaScript library that I have a bit of a love-hate relationship with is its support for mimicing OO inheritance.   The ability to call $super from within a function to refer to a superclass’ implementation is pretty darn cool, but I’ve I’ve found myself more and more annoyed at having to navigate what seem like unnecessarily deep and complicated stack traces when trying to debug code.  It was while mired in the bowels of Class.create() and Class#addMethods() that I found myself wondering how much of a performance penalty this stuff was incurring.  To find out, I put together a test to determine how different the strategies for emulating OO inheritance in JavaScript performed.  Here’s what I tested:

  • Ad hoc inheritance – This is a common(?) homebrew technique for allowing prototypes to leverage the code in objects further up the prototype-food chain.  Methods are overridden by keeping a reference to the parent method in a separate property , which can then be invoked as needed.  It’s fast but not very pretty, and it’s arguable whether or not this qualifies as real “OO” inheritance.
  • Prototype-style inheritance – Prototype uses a strategy inspired by Alex Arenell’s Inheritance library. Subclass methods declare a “$super” argument that is set up by Prototype to reference the superclass’ method.
  • Base2-style inheritance – Dean Edwards’ library.  Subclass methods invoke “this.base()” to call their superclass’ implementation.
  • John Resig inheritance – JR, of jquery fame, experimented with a Base2 variant which he published on his blog.  It’s a bit simpler than Base2, but seemed worth testing.

Tests were performed by using  JSLitmus to create a Inheritance Performance testbed.

Robert shows that when $super is used, you get a perf drop with Prototype, however he also realizes that this is “only really important if you’re making 100,000’s of calls per second to overridden methods, however.”

Posted by Dion Almaer at 6:34 am
19 Comments

++++-
4.8 rating from 9 votes

Tuesday, February 17th, 2009

Xopus Application Framework: Objective-J Done Different

Category: Framework, JavaScript

The good folks at Xopus (the really cool browser-based XML editor) have been working largely in silence on a new version of their application. They've recently posted a presentation that talks about the framework behind this new version of Xopus.

In the linked PDF, the framework is revealed to be an "object-oriented 'extended subset' of JavaScript", much like Objective-J, but while Objective-J brings a syntax very similar to an existing language (Objective-C), the Xopus framework brings its own syntax to the game:

JavaScript:
  1.  
  2. Package("com.xopus.code" );
  3.  
  4. Import("com.xopus.code.Food" );
  5. Extends("com.xopus.code.Animal" );
  6.  
  7. Class(
  8.     function Monkey (name) { this.name = name; },
  9.     function getName () { return this.name; },
  10.     function favorite () { return new Food("banana" ) ; },
  11.     Static, function kind () return "chimp" ; }
  12. );
  13.  

Among the features of the Xopus framework are:

  1. Hierarchically structuring programs into packages
  2. Some forms of program veri?cation
  3. Making dependencies explicit
  4. Dependency resolution
  5. Consistent ?le-system layout
  6. Server side compilation to ?attened form
  7. Serving the client efficient and possibly obfuscated code
  8. Preserved stack trace for easier client-side debugging
  9. Inheritance
  10. Annotations, including visibility (public, private, protected), static, continuation, test, deprecated, API--they are used for documentation and compilation and stick around at run-time for reflective access

The server-side compiler is presently based on SpiderMonkey; the compiler is entirely written in JavaScript and includes "extensions for profiling, coverage, and dependency visualization."

Unit Tests

Unit testing is baked into the class format, as in:

JavaScript:
  1.  
  2. Class(
  3.     function ArrayUtilTest() { this.TestCase(); },
  4.     Static, function () { new ArrayUtilTest().start(); },
  5.     Test, function last()
  6.     {
  7.         var obj = {};
  8.         var arr = [1, 2, 3, obj];
  9.         this.assertTrue(
  10.             "last() should return the last value in the array",
  11.             arr.last() === obj);
  12.     }
  13. );
  14.  

The PDF also shows screenshots from the framework's unit test runner as well as a continuous integration server.

While the bits aren't yet available (that we can tell), forgive us for posting about it anyway--it sounds really interesting.

Posted by Ben Galbraith at 11:00 am
8 Comments

++---
2.7 rating from 18 votes

Monday, February 16th, 2009

Designing a JavaScript client for a REST API

Category: Articles, JavaScript

This is a guest post by Jared Jacobs of the KaChing, an exciting new way to do your own hedge fund, the Web 2.0 way (a.k.a. don't give it to Madoff!). I was very happy when he said he would be willing to do a post on REST APIs, and what makes a good design.

So you want to write a script that sites all over the web can use to access your REST API, eh? Well, that would be pretty straightforward if it weren’t for two things:

  1. browser same-origin restrictions on XMLHttpRequests (XHRs) and inter-window/frame access
  2. the lack of wide browser support for HTML 5-style message passing between windows.

The Same-Origin Policy and its minor browser-specific variations are detailed elsewhere, so I’ll just summarize it with a few key points. I use the term window to mean window object, which can be a top-level page or reside inside a frame or iframe.

  • XHRs can only be issued to the same domain as the originating window (not the originating script).
  • Two windows can read, write, and call each other’s properties if and only if they are from the same domain (host, port, and scheme).
  • There is one notable exception to the previous statement that is consistent across browsers: A window can change (but not necessarily read) the location of its own iframes and of the top window, regardless of their domains.

Recall that native browser primitives for sending or receiving information across domains include frames, iframes, images, scripts, stylesheets, and forms.

With these constraints and possibilities in mind, let’s first consider how best to support GET requests to the REST API.

Transport for GET Requests

XHRs would be the ideal way to retrieve data, since they provide meta information about each response, such as the the HTTP status code, in addition to the content. As noted above, however, other sites cannot use XHRs to directly to access your REST API.

One possible workaround is for each site that uses the JS client to install a server-side proxy on its domain that proxies REST API calls to your servers. That’s a pretty big barrier to the adoption of your JS client, though. We can do better.

Another possibility is having the JS client delegate the XHRs to a helper iframe that it creates specifically for that purpose. The iframe’s page must, of course, reside on the same domain as the REST API. Then there are also the problems of 1) passing the request URI from the parent window to the helper iframe and 2) passing the response status and content from the helper iframe back to the parent window. These problems are manageable, but not worth solving for GET requests, it turns out. We’ll return to them later.

Textual data can also be loaded across domains within scripts and stylesheets, both of which are lighter-weight than iframes and free of same-origin restrictions. To use one of these techniques, you must 1) either embed the data in a comment or encode it as part of either a valid script or stylesheet, and 2) determine when the data has finished loading.

A popular solution that addresses these two issues nicely, sometimes called script transport or JSONP, is formatting the data in JavaScript Object Notation (JSON) and wrapping it in a JS function call. This is the route I chose for kaChing’s JS client. A JSONP request typically includes the callback name as an HTTP request parameter. You’ll want to host a simple proxy on your domain that handles these requests by taking off the callback name parameter, relaying the request to your REST API servers, then formatting the response as the appropriate JS function call. Your JS client should generate a unique callback name for each request to avoid mix-ups in the event that multiple requests overlap in time. Also make sure that your proxy can relay both success and error responses from the REST API to your JS client.

Another nice property of the JSONP approach is that anyone can write a JS client and run a JSONP proxy server for any REST API, then share their JS client with anyone who trusts them.

Two weaknesses of the JSONP approach to be aware of: 1) it adds another failure point (the proxy server), and 2) detecting loading errors is harder with scripts than with XHRs.

Transport for Non-GET Requests

For HTTP methods other than GET (e.g. HEAD, POST, PUT, DELETE), script transport would require disguising the request as a GET, which has different semantics. Then there’s also the fact that a large request might not fit into a single URL. There must be a better alternative.

HTML forms can do POSTs, but that still leaves out the other HTTP methods.

What about the approach we proposed earlier—delegating XHRs to helper iframes? The JS client can construct a hidden iframe each time it needs to make a non-GET request. Iframe construction is quite fast (7-25 ms for most browsers on today’s machines) if the iframe page is small and cached. The request specification (i.e. verb, URL, and possibly parameters and content) can be passed to the helper iframe in its URL fragment.[1] The helper iframe page deserializes the request specification from its URL fragment immediately upon loading and issues the request. Simple enough. Now to relay the server’s response to the parent window. The simplest and most efficient way is HTML 5’s window.postMessage. The latest versions of some browsers support it already, but most people’s browsers don’t yet. (IE 6 & 7 don’t, but IE 8 will.) Unfortunately, the best two alternatives[2] to window.postMessage both require additional cooperation from sites using the JS client.

Approach 1. Sites using the JS client must host a small HTML file that we’ll call caller.html. They should inform your JS client of its URL as an initialization step. When the XHR response arrives, the XHR iframe creates a child iframe pointing to caller.html and including a URL fragment containing the response status, content, and a callback name from the original window. caller.html simply parses its URL fragment and passes the response information to its grandparent window via a direct function call that looks something like this: parent.parent[callbackName](status, responseText).

Approach 2. Sites using the JS client must inform your JS client of the URL of any valid resource on their domain as an initialization step.[3] That’s right, it can be an image, a stylesheet, an HTML page, or anything else—anything they don’t mind you requesting repeatedly. Its content is irrelevant. It just has to exist. We’ll call it cleardot.gif. When the XHR response arrives, the XHR iframe creates a child iframe pointing to cleardot.gif and including a URL fragment containing the response status and content. The JS client will have been polling for the existence of this grandchild iframe and can decode the response from its location’s URL fragment.

For kaChing’s JS client, I chose Approach 1 because it avoids polling and feels less hacky. Asking sites to allow our JS client to reuse an existing resource on their site seems more fragile because the resource’s original purpose may change or disappear someday. I also built in future compatibility with window.postMessage. (For our implementation, see the _send method in kaChing’s client.js. The helper iframe pages are xhr.html and caller.html.)

Regardless of which approach you choose, it’s important for optimal performance that the helper files (both the ones that you are hosting and the ones that your clients are hosting) be long-term cacheable. Also consider having your JS client preload them to warm the browser cache.

The Programming Interface

Now that we’ve decided on transport mechanisms, let’s turn our attention to the JavaScript programming interface. Since our transport mechanisms are all asynchronous, callers who care about the results of their requests will need to provide callbacks.

A first stab might be to have a JS method for each (verb, resource) pair in the REST API:

kaching.getUser(31, function(user) {

  // Use user.
});

That approach is certainly clear and simple, and is probably the best pattern for requests with side effects, like POST, PUT, and DELETE.

An improvement for GET requests would be what I call the shopping list pattern, which allows callers to easily request multiple resources together with a single callback:

kaching.get(
  kaching.user(31),
  kaching.portfolio(31),
  kaching.watchlist(31),

  function(user, portfolio, watchlist) {
    // Use user, portfolio, and watchlist.
  });

In addition to the added convenience, this pattern reduces latency by allowing your JS client to request the desired resources in parallel. The two tricky parts in the implementation of this pattern are what I call the joining callback, which collects all of the expected responses before firing, and the use of Function.prototype.apply to invoke the caller’s callback. For a working example of this pattern, see kaching.fetch in kaChing’s client.js.

Other best practices for JavaScript libraries to consider:

  • Avoid polluting the global namespace. Define only a single global name (e.g. kaching).
  • Make the loading of your library idempotent, in case it gets included in a page multiple times.
var kaching = kaching || ...;

Authentication

Authentication issues are beyond the scope of this post. If you’re looking for more information on this topic, you might consider starting with the Google Data APIs Authentication Overview.

Your Prize

For making it this far, you’ve earned an invitation to:

The API Garage Event

1:00pm Sat Feb 21 at kaChing HQ

Come eat, drink, celebrate, meet the kaChing team, and hack on our API.

Oh, and we’re hiring!

Footnotes

[1] We brush up against a limit on request size here—namely, the browser’s upper bound on URL length—but it’s not insurmountable. If you anticipate large requests, you can create additional helper iframes that each accept a portion of the request data in their URL fragments along with a sequence number and then pass them to the XHR iframe via a direct function call that looks something like this: parent.frames[xhrFrameName].acceptRequestData(data, seqNumber).

[2] Here I thought I’d catalog a few other ways of relaying the server’s response to the parent window that I considered or tried and why I nixed them.

Attempt Outcome
When the response arrives, set the parent window’s location fragment. Doing this adds an annoying new browser history entry. Plus, the new location fragment is visible in the browser’s location bar.
Before issuing the request, create a helper iframe with no src attribute in the parent window; then when the response arrives, set its location to that of the parent window plus a fragment. In IE 7 this works, but it results in the browser loading the containing page in the helper iframe, a potentially large waste of resources. Permissions errors in Firefox and Safari.
Before issuing the request, create a helper iframe with src=”about:blank” in the parent window; then when the response arrives, add a url fragment. Permissions errors again while adding the fragment in Firefox and Safari. Permissions error when the parent tried to read the fragment in IE 7.
Before issuing the request, create a helper iframe with src=”/favicon.ico” in the parent window; then when the response arrives, add a url fragment. This works in IE for sites that have favicons, but it’s not a very robust solution. Plus, if the site’s favicon isn’t very cacheable, your JS client could end up re-downloading it with each API call.
Instead of adding the xhr iframe directly to the page, create an intermediate iframe with no src attribute and document.write its content (just the xhr iframe); when the response arrives, the xhr iframe sets the url fragment of its parent, the intermediate iframe. I thought this might work because the intermediate iframe inherits the document.domain of its parent, so the parent should be able to poll its location. The problem I encountered was that the intermediate iframe’s window had no location property to set (presumably since that iframe had no src attribute).

[3] A variation on Approach 2 is not to ask sites to inform your JS client of the URL of a cacheable resource, but instead have your JS client probe for a favicon and/or walk the DOM of its host page to identify a suitable image or stylesheet. While this could work in many cases, I’d advocate being up front about the requirements of your JS client and avoiding making unnecessary assumptions.

Posted by Dion Almaer at 9:01 am
10 Comments

+++--
3.7 rating from 22 votes

xLazyLoader: Lazy loader callback framework

Category: JavaScript, Library, jQuery

Oleg Slobodskoi, guru behind jimdo.com, has open sourced xLazyLoader a jQuery plugin that lets you asynchronously load resources such as JavaScript, CSS, and images. Quite useful if you want to head of and load some CSS to do something custom and you need the callback.

Example

JAVASCRIPT:
  1.  
  2.  $.xLazyLoader({
  3.      js: ['ui.core.js','ui.dialog.js'],
  4.      css: ['ui.core.css', 'ui.dialog.css'],
  5.      image: ['your_image.jpg', 'your_image1.jpg', 'your_image2.jpg'],
  6.      name: 'dialog',
  7.      load: function(){
  8.          alert('All files are loaded');
  9.      }
  10.  });
  11.  

Features

  • load one or multiple files for each type
  • onload callback for javascript, CSS and images
  • prevents double loaded scripts or css files
  • method to remove scripts/css by using group name
  • method to disable/enable css files by using group name, so you can use this plugin like a css switcher
  • Tested in IE6, IE7, FF2/3, Opera 9, Safari 3, Chrome

Posted by Dion Almaer at 6:55 am
Comment here

+++--
3.7 rating from 45 votes

Thursday, February 12th, 2009

Bespin: A new Mozilla Labs experimental extensible code editor using Canvas

Category: Canvas, JavaScript, Mozilla, Showcase, Utility

Ben and I are excited to be releasing the first concept out of the Mozilla Developer Lab. As you know, we are big believers in the Open Web. Chris Wilson mentioned that many people are still building Web applications on top of browser technology from yester year. What if we built on more leading edge browser technology? As a challenge, we wanted to take on an interesting project that you would normally thing of as a desktop application, and see if it would fly on the Web.

Being developers, why not develop something that we know and use every day. Our code editor. There are great editors out there, and we are partial to many. From Vi and Emacs, to Textmate and IntelliJ IDEA.

We have all seen enhanced textarea and div code editors, and while some have done a great job with them, they often seem to fall down in performance with large files and have strange bugs that make them more of a toy than you would like.

How could we change this? What if we used Canvas? That question lead to our Bespin announcement at Mozilla Labs today. What would our dream editor be like?

Let's get to the meat. To check out Bespin yourself, fire up a browser that supports Canvas, and the text rendering portion of Canvas. We have tested Bespin on Firefox 3+ and WebKit Nightly, which both support the feature. Link over to bespin.mozilla.com and signup.

Once logged in you will see a dashboard view of your projects, and a sample project will be sitting there waiting for you. Navigate into the project and open up one of the files via double click. You will be taken into the code editor itself. Tinker around. Try out the command line at the bottom (try the help command to see what is out there).

Even though this is a tech preview, where the goal was to share it with the community, we wanted to make the editor as solid as possible. It had to scale to a large number of lines and continue to remain very responsive.

Over in the dashboard, you will notice some interesting UI elements. Shrink the width of the file panes and the filenames will be truncated in the middle a la Mac OS X (e.g. Take a file "syntaxhighligher.js" that doesn't have room and becomes "syntax...r.js" instead of a simpler "...ghligher.js"). The open sessions tabs at the bottom can be moved around and as more space is made available, they offer more information and change font size. This is all part of Thunderhead, a very early fun experiment to create a Canvas GUI toolkit. We will blog more about that later.

To see this in action, please check out this video of us showing the tool in action:

It has been a lot of fun building the tool. A lightbulb went off when you see the power of having a tool written in the platform that you write code in all day. You can easily extend and tweak it to your whim. Extensibility has been a core guideline for us. The command line gives us an easy way to add functionality (Ubiquity showed us the way here). Bespin commands look like Ubiquity commands, and we want to fully integrate them. We also made a big use out of custom events as a way to loosely couple code to functionality.

This means that you can write code that listens to editor events and does something new. On the other side of the coin, you can fire of events and the editor will consume them and do the right thing.

If you wanted to add some functionality whenever a new file is loaded into the editor, you would listen for an open success event. Here is an example of us doing just that in our command line object, to tell the user that something has been opened:

JAVASCRIPT:
  1.  
  2. document.observe("bespin:editor:openfile:opensuccess", function(event) {
  3.     var file = event.memo.file;
  4.  
  5.     commandline.showInfo('Loaded file: ' + file.name, true);
  6. });
  7.  

We have a lot to share about our experience building Bespin, and we will be posting a lot about them in the future. For now though, we want to hear from you. What do you think? What would you like to see? Have some cool concepts and features? Want to join us hacking on your tool? Have a project that you would like to embed the Bespin editor in? Let us know!

More resources

Looking forward to your thoughts and ideas.

Posted by Dion Almaer at 9:50 pm
49 Comments

++++-
4.7 rating from 78 votes

Monday, February 9th, 2009

Building an isNative method

Category: JavaScript

If you want to test if a method is "native" in that the host provided the methods, versus a third party method (including one that has overridden a native function) it can be tricky.

Kangax posted on the issue where he took a note Diego Perini on an impl:

JAVASCRIPT:
  1.  
  2. // detect native method in object
  3. // not same scope of isHostObject
  4. var isNative = function(object, method) {
  5.   return object && method in object &&
  6.     typeof object[method] != 'string' &&
  7.     // IE & W3C browser return "[native code]"
  8.     // Safari <= 2.0.4 will return "[function]"
  9.     (/{\s*[native code]\s*}|^[function]$/).test(object[method]);
  10. }
  11.  

and then shows how it can easily create false positives.

Kangax then shows one solution:

The solution I came up with is not perfect. It doesn’t rely on any specified behavior either; That’s because there doesn’t seem to be any standard, describing what built-in host method should be like / act like / represent itself like. The most robust solution seems to be to test for a presence of a method in a different DOM context. For example, to check whether native window.addEventListener is present, we could use something along these lines:

JAVASCRIPT:
  1.  
  2. var isNativeWindowAddEventListenerPresent = (function(global){
  3.   // feature test following methods as needed
  4.   var el = document.createElement('iframe');
  5.   var root = document.body || document.documentElement;
  6.   root.appendChild(el);
  7.   var frame = global.frames[global.frames.length-1];
  8.   var result = (typeof frame.addEventListener != "undefined");
  9.   root.removeChild(el);
  10.   el = null;
  11.   return result;
  12. })(this);
  13.  

In all browsers I tested, same-named methods from any of two non-modified DOM contexts behave identically. This means that if window.addEventListener is present in one non-modified context, it will be present in another non-modified context. It will also function identically. This seems to be a de-facto standard; unlike string representation, all browsers seem to be pretty consistent in this regard.

Posted by Dion Almaer at 3:49 am
15 Comments

++---
2.1 rating from 17 votes

Friday, February 6th, 2009

True JavaScript Hash Table

Category: JavaScript

While it's great that JavaScript has a built-in hash-like mechanism, but it is limited to string keys. Tim Down recently filled us in on his project to create a more flexible hash table:

I occasionally want a proper hash table in JavaScript, by which I mean
something that can map an arbitrary key object with another arbitrary
value object. JavaScript does this for string keys, but not for
objects. My googling found nothing except lots of people wrapping an
ordinary JavaScript object and calling it a hash table. So I've
implemented my own, only about three years after making this point
before
, minus the actual code.

It looks for methods called hashCode and equals on keys, much like
Java's Hashtable. Implementing these methods on your objects is not
required but vastly improves performance, particularly on large hash
tables, and gives you control over which keys are considered equal.

The other advantage of jshashtable is that you can use it like a
normal JavaScript object with string keys and get a reliable list of
its properties using the keys() method, without worrying about
filtering out properties defined by objects further up the prototype
chain.

This code snippet illustrates what happens when you try to use a non-string key:

Regular JavaScript objects:

JavaScript:
  1.  
  2. var key1 = new Object();
  3. var key2 = new Object();
  4. var o = new Object();
  5. o[key1] = "First";
  6. o[key2] = "Second";
  7. alert( o[key1] ); // Alerts "Second", not "First" - both keys are
  8. stored under the key "[object Object]"
  9.  

But, with jshashtable, behold:

JavaScript:
  1.  
  2. var key1 = new Object();
  3. var key2 = new Object();
  4. var h = new Hashtable();
  5. h.put(key1, "First");
  6. h.put(key2, "Second");
  7. alert( h.get(key1) ); // Alerts "First"
  8. alert( h.get(key2) ); // Alerts "Second"
  9.  

Handy.

Posted by Ben Galbraith at 9:00 am
7 Comments

+++--
3.1 rating from 38 votes

Thursday, February 5th, 2009

Chrome Extension Process Model Design Doc

Category: Chrome, JavaScript

The chaps in Chrome land that know a thing or two about writing extensions are getting their design docs on and we see a new draft of how extensions mesh with the process model of Chrome:

Chromium extensions will follow a multi-process architecture to share the same kind of stability and security that regular web pages have in Chromium. All of an extension's code runs in a single process, separate from the browser (with the exception of user scripts which run in whichever renderers they apply to). Extension code can communicate with user scripts, and vice versa, through a message passing API.

The document discusses an example extension and the "chrome scripts" that pull off the work:

Much like with user scripts, an extension can register "chrome scripts" to run in the context of the extension process. These scripts have special access to the browser UI, and can communicate with extension UI and user scripts. Chrome scripts are loaded and run when the extension is loaded (generally on browser startup). They can register to listen for special events, like tab switching, window closing, navigation, etc.

As an example, consider an Auto-Link extension that shows a button on the toolbar which converts all addresses on the page to links to Google Maps. Maybe the button is disabled when there are no addresses on the page. This extension would consist of:

  1. a user script which detects addresses and has the ability to convert addresses to links
  2. a toolstrip containing the HTML, CSS, and script necessary to draw the button
  3. a chrome script that listens for browser events and controls the state of the toolbar button

manifest.json (snippet):

JAVASCRIPT:
  1.  
  2.     ...
  3.     // these two are loaded into the extension process
  4.     chrome_scripts: ["chrome/main.js"],
  5.     toolstrip: "chrome/toolstrip.html",
  6.     // this is loaded into renderers
  7.     user_scripts: {
  8.       "matches": ["http://*/*", "https://*/*"],
  9.     "files": ["content/address.js"]
  10.     },
  11.     ...
  12.  

content/address.js:

JAVASCRIPT:
  1.  
  2. extension.addEventListener("on-message", function (e) {
  3.   if (e.message == "autolink") {
  4.     doAutoLink();
  5.   } else if (e.message == "check-for-addresses") {
  6.     var found = checkForAddresses()// implemented elsewhere
  7.     e.channel.postMessage({hasAddresses: found});
  8.   }
  9. }, false);
  10.  

chrome/main.js:

JAVASCRIPT:
  1.  
  2.     extension.addEventListener("tab-changed", function (e) {
  3.       // user switched tabs, so check if our button should be enabled
  4.       e.tab.postMessage("check-for-addresses");
  5.     }, false);
  6.  
  7.  
  8.     extension.addEventListener("on-message", function (e) {
  9.       // we got a response from our user script
  10.       var found = e.message["hasAddresses"];
  11.       var toolstrip = e.tab.browserWindow.getToolstrip("autolink");
  12.       toolstrip.contentWindow.document.getElementById("autolink").disabled = !found;
  13.     }, false);
  14.  

chrome/toolstrip.html:

HTML:
  1.  
  2.   <button onclick="autolink()" id="autolink">Auto-Link</button>
  3.     function autolink() {
  4.       extension.currentTab.postMessage("autolink");
  5.     }
  6.   </script>
  7. </body>
  8. </html>
  9.  

Posted by Dion Almaer at 7:32 am
6 Comments

++++-
4.2 rating from 12 votes

Speeding up your JavaScript: Part 3 and 4

Category: JavaScript, Performance

Nicholas C. Zakas wraps up his series on speeding up JavaScript with two more posts on the subject.

First up, he delves deeper into a generic memoizer:

In part 2 of this series, I wrote briefly about handling too much recursion in a function through memoization. Memoization is a technique for caching previously calculated values so that they need not be recalculated; when a recursive function is doing such a calculation, memoization is incredibly useful. The memoizer I presented was Crockford’s, and is useful primarily for recursive functions that return integers. All recursive functions, of course, don’t return integers. A more generic memoizer() function can be created to deal with any type of recursive function:

JAVASCRIPT:
  1.  
  2. function memoizer(fundamental, cache){
  3.     cache = cache || {}
  4.     var shell = function(arg){
  5.         if (!(arg in cache)){
  6.             cache[arg] = fundamental(shell, arg)
  7.         }
  8.         return cache[arg];
  9.     };
  10.     return shell;
  11. }
  12.  

Then he gets into other examples, and concludes:

The bottom line: always be on the look out for recursion in your JavaScript. Memoization and iteration are two ways to avoid excessive recursion and the long-running script dialog.

The final part of the series deals with the DOM, and looks at practices such as using DOMFragments instead of touching the live DOM (John Resig has been talking a lot about that):

JAVASCRIPT:
  1.  
  2. var fragment = document.createDocumentFragment();
  3. for (var i=0; i <items.length; i++){
  4.     var item = document.createElement("li");
  5.     item.appendChild(document.createTextNode("Option " + i);
  6.     fragment.appendChild(item);
  7. }
  8. list.appendChild(fragment);
  9.  

Posted by Dion Almaer at 5:15 am
3 Comments

++++-
4.5 rating from 13 votes

Opera comes out with new JavaScript engine in Carakan, new hardware API in Vega

Category: JavaScript, Opera, Performance

Opera isn't sitting on their heels as the other browser vendors get snappy (even if other claim so!)

Today they announced Carakan a new register based JavaScript VM that is currently 2.5 times faster than their existing one (based on SunSpider). It does native code generation including at specializing for Regex (interestingly since irregex for Chrome was just announced too). Here is their words:

We have focused our efforts to improve upon our previous engine in three main areas:

Register-based bytecode

The last couple of generations of Opera's ECMAScript engine have used a stack-based bytecode instruction set. This type of instruction set is based around a stack of values, where most instructions "pop" input operands from the value stack, process them, and "push" the result back onto the value stack. Some instructions simply push values onto the value stack, and others rearrange the values on the stack. This gives compact bytecode programs and is easy to generate bytecode for.

In the new engine, we've instead opted for a register-based bytecode instruction set. In a register-based machine, instead of a dynamically sized stack of values, there's a fixed size block of them, called "registers". Instead of only looking at the values at the top of the stack, each instruction can access any register. Since there is no need to copy values to and from the top of the stack to work on them, fewer instructions need to be executed, and less data needs to be copied.

Native code generation

Although our new engine's bytecode instruction set permits the implementation of a significantly faster bytecode execution engine, there is still significant overhead involved in executing simple ECMAScript code, such as loops performing integer arithmetics, in a bytecode interpreter. To get rid of this overhead we are implementing compilation of whole or parts of ECMAScript programs and functions into native code.

This native code compilation is based on static type analysis (with an internal type system that is richer than ECMAScript's ordinary one) to eliminte unnecessary type-checks, speculative specialization (with regards to statically indeterminate types) where appropriate, and a relatively ambitious register allocator that allows generation of compact native code with as few unnecessary inter-register moves and memory accesses as possible.

Automatic object classification

Another area of major improvement over our current engine is in the representation of ECMAScript objects. In the new engine, each object is assigned a class that collects various information about the object, such as its prototype and the order and names of some or all of its properties. Class assignment is naturally very dynamic, since ECMAScript is a very dynamic language, but it is organized such that objects with the same prototype and the same set of properties are assigned the same class.

Nice to see, and interesting that the browsers aren't (or aren't able too?) share their VM work. Each browser has a new VM implementation going. Wouldn't it be nice if they could share effort?

Then we have Vega a vector graphics library that Opera uses to power SVG, Canvas, and more.

Vega was created shortly after we started working on SVG support.
When we added SVG support in Opera we needed a vector graphics
library. We looked into what what available to use and met our
requirements (fast, low memory usage and works on platforms
ranging from phones to TVs and desktop computers). We did not
find and good match for our needs, so we decided to write our
own.

Shortly after we created Vega we added <canvas> support, which
also uses Vega.

The most recent addition to Vega is the ability to use a
hardware accelerated back-end. The back-ends we are using at the
moment are OpenGL and Direct3D.

A busy day for Opera!

Posted by Dion Almaer at 12:01 am
10 Comments

++++-
4.7 rating from 30 votes

Tuesday, February 3rd, 2009

Joose 2.0 released

Category: JavaScript, Library

JAVASCRIPT:
  1.  
  2. Class("Point", {
  3.     has: {
  4.         x: {is: "ro"},
  5.         y: {is: "rw"},
  6.     },
  7.     methods: {
  8.         clear: function () {
  9.             this.x = 0;
  10.             this.setY(0);
  11.         }
  12.     }
  13. })
  14.  

Malte Ubl and the Joose folk are always pushing the boundaries on munging JavaScript to their whim. They have a new 2.0 release, titled "death of parseInt" which has the new features of:

Major News

Support for types and type coercions in attributes and method signatures: JavaScript purists might find this a little disturbing but Joose now supports type declaration. Joose types, however, are quite the opposite of static types, because they try very hard to convert everything you throw at them to the type you want. parseInt is dead!
Here is the documentation.

News

  • Builtin support for turning a class into a singleton

    JAVASCRIPT:
    1.  
    2.     Class("MySingleton", {
    3.         does: [Joose.Singleton],
    4.    
    5.         has: {
    6.             test: {
    7.                 init: function () { return [] }
    8.             }
    9.         }
    10.     })
    11.  
    12.     var single = MySingleton.getInstance();
    13.  
  • Support for Rhino without need for special configuration
  • The default namespace for types (which used to be experimental) is now Joose.Type
  • Experimental support for multi method dispatch. Examples.
  • Made integrating Joose with other class builders easier.
  • Fixed type checks for arrays (thanks Silvan).
  • Fixed an issue when overriding getters and setters defined in a super class.
  • Improved error messages when defining properties of classes, etc. but passing null to the property (happens easily when you have a typo in the last part of a name spaced identifier).

For those that haven't seen us post on it before, what is Joose?

Joose is a self-hosting meta object system for JavaScript with support for classes, inheritance, mixins, traits, method modifiers and more.

Joose makes object-oriented programming with JavaScript easy, declarative and very productive. The Joose meta-object system is multi-paradigm. It supports class-based and prototype-based programming styles as well as class-based inheritance and role-based extention.

The Joose framework has been successfully used in multiple production systems for twelve months now and has been proven to be very stable. Joose is being tested using an automated unit-test suite that is being run in all major browsers (Firefox, IE, Safari, Opera and Chrome).

To get started with Joose we recommend to read the getting started guide.

Posted by Dion Almaer at 8:56 am
7 Comments

++++-
4 rating from 24 votes

Monday, February 2nd, 2009

Writing a JavaScript Tetris; Lessons learned from a Ruby chap

Category: Examples, Games, JavaScript, Tutorial

We often get games sent our way, and try to keep those posts for Fridays. This one is different though. Thomas Kjeldahl Nilsson didn't just write another Tetris clone in JavaScript, he documented his experience. He posted a series of articles on the various steps, and not only do you learn how to build a nice Tetris game, but you get to see how to develop nice testable code. Thomas comes from the Ruby world and it shows.

Take some time to poke through his series on JavaScript Tetris:

  1. Rationale
  2. Planning
  3. Infrastructure
  4. Graphics & Input
  5. The Life Of A Piece
  6. Lights, Action, Music!
  7. Gameplay
  8. Javascript Tetris Pt 8: Post Mortem & References

Posted by Dion Almaer at 8:18 am
Comment here

++++-
4 rating from 27 votes

JSINQ: LINQ style access for JavaScript objects

Category: JavaScript

JAVASCRIPT:
  1.  
  2. from customer in $0
  3. group customer by customer.lastname into g
  4. select {lastname: g.getKey(), count: g.count()}
  5. into r
  6. orderby r.count descending
  7. select r
  8.  

The code above should look similar to LINQ in .NET and runs with JSINQ a framework created by Kai Jäger.

With JSINQ, you can write SQL-like queries (or LINQ-like if you will) against arrays, DOM node lists or your own enumerable types. It's a complete implementation of LINQ in that it has the complete set of LINQ extension methods and also comes with a query compiler that translates LINQ queries to JavaScript code.

Not only do you have a query language in JavaScript, but also a lot more. For example you can use JSINQ to create DOM nodes from JSON or XML you have received over XMLHttpRequest, you can build sortable tables with ease and you can write less code by doing things in a more declarative manner.

The playground lets you tinker around with queries in real time:

Posted by Dion Almaer at 7:09 am
14 Comments

++++-
4.1 rating from 13 votes

Friday, January 30th, 2009

w00t! Feeling Chatty

Category: Aptana, JavaScript, Showcase, jQuery

Live Ajax chat is one of those Comet 101 kind of examples (as RSS readers were to Ajax back in the day!).

We saw a couple of items from this meme recently.

First, jChat, a showcase chat application using Jaxer:

Jaxer ships with a number of basic samples, but I've seen quite a few people online in search of more complex examples and specifically ones that make use of the new ActiveRecord.js library. The extended example I developed is called jChat. jChat is fully functional chatroom application that demonstrates integration of the following web related technologies; HTML, CSS, JavaScript, MySQL, YUI, Jaxer, and Activerecord.js.

jChat's DOM access/manipulation, event handling, and animation code makes heavy use of YUI. The YUI Library is a set of utilities and controls, written in JavaScript, for building richly interactive web applications using techniques such as DOM scripting, DHTML and AJAX.

Then we get to Red tag crazy (or w00t! for girls) who told us about their live chat implementation in the wild:

We wanted this to be really fun for our shoppers, and chicks like to chat. Then came the idea, “what if we have a chat system right on our home page?”. The pre-requisites were: it has to be super easy to use, not require any sign-up, no plugins, and it has to support thousands of users at once. Solution = jQuery Ajax.

Our server crashed on day 2 from the memory used by PHP to refresh hundreds of ajax clients at once. Our solution was to cache a single JavaScript file that is loaded via ajax by each client every 15 seconds. This file contains all the necessary data to update a page with a bunch of chat bubbles and slide in new comments as if it were some sort of crazy java plugin. PHP runs via cron-job to update this cached JS/jQuery powered file every 2 seconds on our server, which turns out to be a lot less memory intensive than at every ajax request.

Posted by Dion Almaer at 5:16 am
9 Comments

+++--
3.4 rating from 24 votes

« Previous PageNext Page »