Just as jQuery kicks off its first jQuery conference adjunct with The Ajax Experience in Boston tomorrow, it gets an energy boost from some big double-barrel news:
Microsoft and jQuery
Microsoft is looking to make jQuery part of their official development platform. Their JavaScript offering today includes the ASP.NET Ajax Framework and they’re looking to expand it with the use of jQuery. This means that jQuery will be distributed with Visual Studio (which will include jQuery intellisense, snippets, examples, and documentation).
Additionally Microsoft will be developing additional controls, or widgets, to run on top of jQuery that will be easily deployable within your .NET applications. jQuery helpers will also be included in the server-side portion of .NET development (in addition to the existing helpers) providing complementary functions to existing ASP.NET AJAX capabilities.
Scott Guthrie talks about the news and details some of the features. His blog shows intellisense at work, and more.
Here is the sample code that shows the weaving of jQuery and Client template APIs. The script src at the top is to an "intellisense" version of jQuery, which includes the addition of special comments to make Intellisense work. The Open Ajax Alliance is trying to standardize on this metadata so we can share it between the various tools (e.g. Aptana has a very nice sdoc that does this, and allows you to put it external to the file so you don't have to have clients download it).
Nokia is looking to use jQuery to develop applications for their WebKit-based Web Run-Time. The run-time is a stripped-down browser rendering engine that allows for easy, but powerful, application development. This means that jQuery will be distributed on all Nokia phones that include the web run-time.
To start Nokia will be moving a number of their applications to work on the run-time (such as Maps) and building them using jQuery. jQuery will become part of their widget development platform, meaning that any developer will be able to use jQuery in the construction of widgets for Nokia phones.
How will these companies work with the project?
Microsoft and Nokia aren’t looking to make any modifications to jQuery (both in the form of code or licensing) - they simply wish to promote its use as-is. They’ve recognized its position as the most popular JavaScript library and wish to see its growth and popularity continue to flourish.
In fact their developers will begin to help contribute back to the jQuery project by proposing patches, submitting test cases, and providing comprehensive testing against their runtimes. As with any contribution that comes in to the jQuery project it’ll be closely analyzed, reviewed, and accepted or rejected, based upon its merits, by the jQuery development team - no free ride will be given.
A significant level of testing will be added to the project in this respect. The jQuery test suite is already integrated into the test suites of Mozilla and Opera and this move will see a significant level of extra testing being done on Internet Explorer and WebKit - above-and-beyond what is already done by the jQuery team.
IE 8 has an onhashchange event, and Ajax history / bookmark management has been a long time problem of choice for developers.
Zach Leatherman has revisited the problem and has another solution that doesn't require setInterval to check on the location.
On initialization, we load an iframe onto the page that is positioned absolutely at -500px,-500px so the user can’t see it. It is a skeleton page that only needs cross browser code to add an “onscroll” event, and to be able to calculate the scrolled position of the iframe itself. For my example, I use jQuery and the dimensions plugin to accomplish this, but it could easily be trimmed down to only the bare essentials (or ported to a different library).
To add an AJAX history entry into the browser’s history under an assigned hash string, we first add a <a name="hashString">hashString</a> to the <body> tag of the iframe. Using css to increase the size of the a tag proportional to the iframe’s height, we can guarantee scrolling will happen.
Then, we change the location.hash of the iframe to point to that <a> tag. This will scroll the iframe to the content, and create a new entry in the browser’s history object.
Inside the iframe, we have our onscroll event that fires when the scrolling in the previous step took place. (Minor IE-related workaround: The browser’s history object is changed, but the hash property doesn’t when attempting to read it later. Instead, we find the <a> that matches up with the scrollY/pageOffsetY property inside of the iframe, and retrieve the matching hash from the <a> tag.)
The solution gives you history management and back button support in one fell swoop, with the side effect of not having bookmarkability (since the iframe is updated).
The window.name transport is a new technique for secure cross-domain browser based data transfer, and can be utilized for creating secure mashups with untrusted sources. window.name is implemented in Dojo in the new dojox.io.windowName module, and it is very easy to make web services available through the window.name protocol. window.name works by loading a cross-domain HTML file in an iframe. The HTML file then sets its window.name to the string content that should be delivered to the requester. The requester can then retrieve the window.name value as the response. The requested resource never has access to the requester’s environment (JavaScript variables, cookies, and DOM).
var deferred = dojox.io.windowName.send("GET", {url:"http://somesite.com/resource"});
deferred.addCallback(function(result){
alert("The request returned " + result);
});
Kris then goes on to show how to use this with Web services and other scenarios, and explains why you may be interested:
This technique has several advantages over other cross-domain transports:
It is secure, JSONP is not. That is, it is as secure as other frame based secure transports like fragment identifier messaging (FIM), and Subspace. (I)Frames also have their own security issues because frames can change other frames locations, but that is quite a different security exploit, and generally far less serious.
It is much faster than FIM, because it doesn’t have to deal with small packet size of a fragment identifier, and it doesn’t have as many “machine gun” sound effects on IE. It is also faster than Subspace. Subspace requires two iframes and two local HTML files to be loaded to do a request. window.name only requires one iframe and one local file.
It is simpler and more secure than Subspace and FIM. FIM is somewhat complicated, and Subspace is very complicated. Subspace also has a number of extra restrictions and setup requirements, like declaring all of the target hosts in advance and having DNS entries for a number of different particular hosts. window.name is very simple and easy to use.
It does not require any plugins (like Flash) or alternate technologies (like Java).
OpenLaszlo is a fascinating project, and got even more interesting when they went meta, and allowed you to general Ajax applications as well as SWF ones. The 4.1 release is a big one, as it brings full parity to the Ajax side of the house:
OpenLaszlo 4.1 is a major release bringing full support for both the DHTML/Ajax and the SWF/Flash platforms. It also includes over 800 bug fixes and a significantly improved documentation suite.
OpenLaszlo 4.1 has been fully-qualified across the following browser/platform combinations: Safari3/OSX, Firefox2/OSX, Internet Explorer 7/WinXP, Firefox 2/WinXP, and Firefox 2/Linux. We have tested the full suite of demos, samplers, and example applications with the requirement that, when possible, DHTML applications behave the same as their SWF counterparts.
OpenLaszlo 4.1 is now the recommended release for all developers on all platforms, and current users of OL 3.x and 4.0 should investigate upgrading to this new release.
Preliminary support for SWF9 is included in this release but has not been enabled in the developer console.
Kyle Simpson has announced a new family of opensource projects called flensed and the first project being flXHR which "utilizes javascript+flash to create a complete, literal drop-in replacement (by being API identical) for the native browser XHR (Ajax) communication mechanism. However, flXHR uses Flash Player's security model to enable direct cross-domain communication, and also has a number of other very helpful extensions."
http://flxhr.flensed.com/code/tests/flxhr-4.html
There are a number of demos which illustrate how it easy it is to take the API-compatible flXHR and swap it to any of your favorite JS frameworks (Dojo, Prototype, YUI, ExtJS, etc) in place of its usage of native XHR... once the simple adapt/swap happens, everything else about the framework library communication works the same, because flXHR speaks the same familiar protocol and API, and so it really is what I like to call "set it and forget it" good.
Hasn't this been done before?
There have been several other attempts at similar things before, including SWFHttpRequest, FlashXMLHttpRequest, Fjax, and F4A. However, all those fell short of the mark in different ways. On my site, there are comparison charts and detailed FAQ's which show how flXHR stands up to these predecessors, and exceeds them in very important and powerful ways. I believe flXHR has accomplished its goal, which was to be *the* complete solution for SWF-based Ajax calls as an identical API-compatible drop-in replacement for native XHR, not to mention many helpful improvements including robust error callback handling, timeouts, and convenience configuration functions, to name a few.
Ivan Bozhanov walked us through his jQuery-based tree component recently. The state of trees out there is interesting. YUI! has a nice, stable tree control but Dojo's once feature-rich tree has been replaced with a fairly basic tree (i.e., doesn't appear to have in-line editing and drag-and-drop still seems flakey; Dojo guys, correct me if I'm wrong) at the moment and jQuery UI lacks an official tree component (though a few treeplug-ins are out there); as you might expect, Ext JS has a nice tree component.
Let me highlight a few areas where jsTree stands out. First, it has some basic features that many trees out there lack:
jsTree allows the user to create, rename, reorder, move, and delete note (which is realised in a file-browser manner - eg. inplace)
It also has a rich event API which is fairly standard across most editable tree components, though the event types are finer-grained than in most trees I've seen (not sure whether that's a good thing):
You can attach callbacks to almost every action:
- onbeforechange
- onchange
- onrename
- onmove
- oncreate
- ondelete
- onopen
- onclose
It also allows you to provide rules that govern what the user may or may not do based on the "type" of a node:
jsTree lets developers define rules for moving, selecting, deleting, and focusing nodes. The rules are based on developer-definable types of each node passed in the data (different sources define it differently). This limits the user in his actions. The developer can also attach inline rules which override global rules. One scenario in which these rules are useful is when you build a CMS and need a fixed number of top level nodes because of a design restriction.
While you could accomplish the same functionality with event handlers, it's nice to have a simple built-in scheme that can be easily data-driven.
These rules are applied real-time as the user attempts to interact with the tree:
When you drag a node around a pointer tells you where you are about to insert it, and prevents the user from dropping anywhere against the rules. The warning is real time - as you drag and drop the pointer is replaced by a red cross if the action is against the defined rules. I'm still working on displaying definable text messages.
jsTree can be configured to reference a custom property in each node object to determine its type.
It also has built-in localization support; you specify string identifiers corresponding to the different languages that the tree should support on construction:
In addition to XML data types, it also supports JSON and in-line HTML. But it also has built-in support for doing XSL transforms on XML data sources, including a scheme that lets you include flat data that it then makes into a hierarchy:
jsTree supports XSL transformations when using the XML data source option. This is a bit faster than javascript parsing. It includes an XSL stylesheet for transforming a flat list of entries into a tree. This can be useful if you use adjacency for maintaing a tree in a database. In such situations it is quite heavy on the server to dump the whole tree as you need N-1 queries where N is the number of nodes in the tree. With this XSL solution you can just dump the table flat out with id and parent_id attributes and the XSL will transform it into a nested structure.
Unfortunately, what jsTree is lacking is the visual refinement of many of the trees out there, but as jsTree is built on top of jQuery, we suppose Ivan can add that kind of polish easily.
For many data-driven applications, high-quality grid and tree components are really important; kudos to Ivan for some interesting ideas in jsTree. The docs are certainly better than some I've seen, but not as complete as I'd like.
Kris Kowal dropped us a line pointing us towards his year-long labor of love: modules.js, a stand-alone dynamic JavaScript module loader.
As the module-loading space is quite crowded at the moment (e.g., Google, Dojo, Yahoo, JSModule, etc.), we asked Kris to explain what makes modules.js different. He had some interesting things to say.
Existing Module Loaders Fall Short of Traditional Language Import Semantics
Kris started out his notes to us with an interesting point:
Ideally, you [would be able to] use import semantics similar to Java, Python, or even Perl [in JavaScript]. All [existing JavaScript module loaders] fall short in one way or another.
He then points out some ways in which modules.js meets this objective where others fail (along with an admission that some of his information about these other loaders might be a bit out-of-date):
Compared to JSModule
JSModule is the most similar [to modules.js]. It also uses XHR, eval, singleton
module cache, and scope injection. It's also lighter. In general,
modules.js is what JSModule could grow up to be. JSModule is a bit
messy; it pollutes the scope chain that it implicitly passes to its
modules with its own internal variables because it uses eval in local
scope instead of global scope (I have a fun way around this problem).
JSModule also adds itself to global scope; modules.js cleverly avoids
this. modules.js includes modules using their URL relative to the
module loader URL or the module URL if it's prefixed with a dot; this
permits easy migration and refactoring. JSModule also supports an
include path; when I explored that feature for modules.js, I
determined that searching for the script over HTTP performed very
poorly even though it provides a better approximation of how other
languages work server side.
Compared to the Dojo and Google Loaders
Dojo loader (last I checked) and Google's loader both perform strictly
asynchronous loads and piggyback one layer of dependency management on
the onLoad handler. The key difference here is that module's loaded
with modules.js can have recursive dependencies. In Dojo and Goog,
there is an important distinction between loading scripts in global
scope and in module scope. In global scope, you simply initiate an
asynchronous load of all the modules you want and attach an onLoad
observer that will be signaled when the page has loaded AND all of the
requested modules have loaded. However, onLoad may fire before all of
the modules required by your modules are loaded. To get around this,
in module scope, you have to write complicated dependency management
code to ensure that the scripts load in order: [your dependencies,
your continuation, the onload continuation]. This can be very
complicated and detracts from time spent actually writing features.
Google loader uses document.write to do script insertion which has two
advantages over modules.js: it prevents script flicker on pages with
long DOMs, and it can load cross domain scripts, which is handy if
you're loading standard libraries from their cache.
Compared to YUI Loader
YUI Loader uses a static dependency table to ensure that YUI modules
are loaded in the correct order. This means that third party modules
have to monkey patch this table if they have inter-module
dependencies. It's similar to modules.js in that it uses XHR.
A Note about Global Scope
YUI, Goog, and Dojo all evaluate modules in global scope. modules.js
protects global scope with an enclosure and provides developers with
the ability to share functions without adding them to the transitive
global scope. Instead, you add them to the module object and import
them into your imported object's scope. Nothing ever /needs/ to be
added to global scope, and developers are protected in many ways from
accidentally "sharing" variables with other modules on global scope.
In conclusion:
It's not a solution for everybody, but it's a good solution for many
people.
Frankly, the community sees a lot of new Ajax libraries written by folks who don't appear to have familiarized themselves with the state of the art before diving in. While I have respect for anyone who takes the time to contribute to the community, it's refreshing to see a craftsman at work. Nice work, Kris!
Some good stuff came out from my employer. First, we have the Gears 0.3 release which includes support for Firefox 3! I have been using it for awhile, and it has been great. The team wanted to get it out before the Firefox 3 launch (planned for June 17th). A plugin like Gears can get deep into browser internals, so it is a challenge to keep up to date as APIs change in beta releases, so it is great to be out there now and I we will take a close look at the final release!
I just got to announce the Google AJAX Libraries API which exists to make Ajax applications that use popular frameworks such as Prototype, Script.aculo.us, jQuery, Dojo, and MooTools faster and easier for developers.
Whenever I wrote an application that uses one of these frameworks, I would picture a user accessing my application, having 33 copies of prototype.js, and yet downloading yet another one from my site. It would make me squirm. What a waste!
At the same time, I was reading research from Steve Souders and others in the performance space that showed just how badly we are doing at providing these libraries. As developers we should setup the caching correctly so we only send that file down when absolutely necessary. We should also gzip the files to browsers that accept them. Oh, and we should probably use a minified version to get that little bit more out of the system. We should also follow the practice of versioning the files nicely. Instead, we find a lot of jquery.js files with no version, that often have little tweaks added to the end of the fils, and caching is not setup well at all so the file keeps getting sent down for no reason.
When I joined Google I realised that we could help out here. What if we hosted these files? Everyone would see some instant benefits:
Caching can be done correctly, and once, by us... and developers have to do nothing
Gzip works
We can serve minified versions
The files are hosted by Google which has a distributed CDN at various points around the world, so the files are "close" to the user
The servers are fast
By using the same URLs, if a critical mass of applications use the Google infrastructure, when someone comes to your application the file may already be loaded!
A subtle performance (and security) issue revolves around the headers that you send up and down. Since you are using a special domain (NOTE: not google.com!), no cookies or other verbose headers will be sent up, saving precious bytes.
This is why we have released the AJAX Libraries API. We sat down with a few of the popular open source frameworks and they were all excited about the idea, so we got to work with them, and now you have access to their great work from our servers.
Details of what we are launching
You can access the libraries in two ways, and either way we take the pain out of hosting the libraries, correctly setting cache headers, staying up to date with the most recent bug fixes, etc.
The first way to access the scripts is simply be using a standard <script src=".."> tag that points to the correct place.
For example, to load Prototype version 1.6.0.2 you would place the following in your HTML:
You will notice that the version used was just "1". This is a smart versioning feature that allows your application to specify a desired version with as much precision as it needs. By dropping version fields, you end up wild carding a field. For instance, consider a set of versions: 1.9.1, 1.8.4, 1.8.2.
Specifying a version of "1.8.2" will select the obvious version. This is because a fully specified version was used. Specifying a version of "1.8" would select version 1.8.4 since this is the highest versioned release in the 1.8 branch. For much the same reason, a request for "1" will end up loading version 1.9.1.
Note, these versioning semantics work the same way when using google.load and when using direct script urls.
By default, the JavaScript that gets sent back by the loader will be minified, if there is a version supported. Thus, for the example above we would return the minified version of jQuery. If you specifically want the raw JavaScript itself, you can add the "uncompressed" parameter like so:
Today we are starting with the current versions of the library, but moving forward we will be archiving all versions from now onwards so you can be sure they are available.
Here I am, talking about what we are doing in two short slides:
The Future
This is just the beginning. We obviously want to add more libraries as you find them useful. Also, if you squint a little you can see how this can extend even further.
If we see good usage, we can work with browser vendors to automatically ship these libraries. Then, if they see the URLs that we use, they could auto load the libraries, even special JIT'd ones, from their local system. Thus, no network hit at all! Also, the browser could have the IP addresses for this service available, so they don't have the hit of a DNS lookup. Longer lived special browser caches for JavaScript libraries could also use these URLs.
The bottom line, and what I am really excited about, is what this could all mean for Web developers if this happens. We could be removed of the constant burden of having to re-download our standard libraries all the time. What other platform makes you do this?! Imagine if you had to download the JRE everytime you ran a Java app! If we can remove this burden, we can spend more time flushing out functionality that we need, and less time worrying about the actual download bits. I am all for lean, but there is more to life.
Acknowledgements
I want to acknowledge the other work that has been done here. Some libraries such as jQuery and Dean Edwards Base were already kind of doing this by hot linking to their Google Code project hosting repository. We thought this was great, but we wanted to make it more official, and open it up to libraries that don't use our project hosting facilities.
Also, AOL does a great job of hosting Dojo already. We recommend using them for your Dojo needs, but are proud to also offer the library. Choice is good. Finally, Yahoo! placed the YUI files on their own CDN for all to use.
To understand what aspects of a Web application you need to improve, you must properly analyze the components of the application. This article looks at how you can use the Firebug extension to Firefox and the YSlow add-on to instrument a Web application. After you install these tools, connect to the site that you are developing and click YSlow on the Firefox status bar. This opens the YSlow interface in Firebug. Now click the Performance button. YSlow performs an analysis of your application and provides a report on the different parts of the network transfer time of your application, as Figure 1 shows.
Most of the concepts mentioned are derived from the 10 rules defined by Yahoo! for better web application performance but Kristopher breaks down some of the concepts into examples and provides explanation on how to interpret the data. The explanation of the FireBug profiler is especially helpful to those just coming into the Ajax development space and want a better understanding of how to optimize their code:
John Resig put together a nice overview of the ARIA Live Regions specification with an example of how you can track a list of people in a way that a screen reader can understand when someone is added or deleted. Imagine a todo list application.
aria-live="polite" How polite the live area is (as in, how likely is it to butt in to what the user is currently listening to/interacting with). The default is 'polite' - in that it waits until all forms of user interaction have been completed before describing the updates to the user.
aria-relevant="additions removals" Only notify the user about new node additions and removals. Since we wish to provide the user with a live list of users we can expect them to be both transitioning online and offline - this will give us the appropriate level of updates to make this possible.
wishes to know more about what the contents of the field represent this element can be read to them.
Firefox supports this right now (as of 2.0) and we covered AxsJax the toolkit that helps you implement these features, which Google Reader uses to get the job done.
I really liked getting the Ajax Language API out into developers hands as god knows we shouldn't have to worry about translations. Now we can use the API and have the Google back-end do all of the work.
I have recently had a couple of scenarios where I really wanted a quick translation. I had a few twitter messages pass through my stream in French and Spanish. I had the answer to some technical issues show up on foreign forums.
So, I decided to create a Translate bookmarklet that allows me to select any foreign text, click on the bookmark, and a little window pops up with the English translation if it can work it out. Automatic translation is far from perfect yet, but for many scenarios you can easily get the gist (e.g. you wouldn't want to automatically convert a book).
This is how I created the bookmarklet:
The source
First, I have the raw JavaScript source that will become the bookmarklet. There are a few sections of the code. First, we setup a method that will go off and call the Ajax Language API, passing in the translation and language that we want. This is where you would change the language code for non-English.
alert('No translation found for "' + text + '" guessing the language: ' + dresult.language);
}
});
}
});
}});
}
};
}
Then we setup a method that is able to display a window showing the result. I used the Prototype UI Window object if available, and good old alert() if not:
Finally, we load the Google API loader, and use the dynamic loading option with the ?callback=apiLoaded. This kicks off the main driver that we saw first, and if it is already loaded we call it directly (for multiple translations on the same page).
This is the raw form, and we need to get the bookmarklet form, which you can just use right away if you are wanting English. For this, I use John Grubber's makebookmarklet Perl script to do the conversion.
The Server
The Prototype UI code lives on the server, so I put a striped down version over there which just contains a combined Prototype + Window JavaScript file, and just the one theme CSS set.
In Action
Unsure what I am talking about? Just watch it in action:
I also saw that Mibbit, the Web based IRC application has a new "translate" function that auto translates in the chat rooms. It works two way, so you can go into a foreign channel and be seen to just be a bad speaker as you convert their words back.
Following discussions at the Highland Fling conference with the audience and Gareth Rushgrove (whose excellent presentation on API design we featured here already) I sat down and came up with a wishlist for a great Ajax API.
As an example I used the Google translation API, pointed out its good points and explained what I'd love to see added to it. Specifically any JavaScript Ajax API to me should have the following:
Have a good documentation with immediate copy and paste examples backed up by a full class documentation
Build your APIs modular and allow the implementer to choose the version they want to have
Provide a hook to link the result of the API methods to the initial data entered. The easiest way is to repeat this data, more sophisticated is to allow for a connection ID.
Allow for multiple values to be sent through, it’ll save you API calls and the implementer hacking around the problem of unreliable order of returns.
Allow implementers to add an own object to send and get back to allow for namespacing and other data state retention.
Allow for a timeout, connections are not to be trusted.
With the YouTube API recently released, there's bound to be lots of cool controls coming out soon. Thorsten Suckow-Homberg spent a weekend hacking up a Ext-based user extension that leverages YouTube's chromeless API to build The Ext.ux.YoutubePlayer.
The Ext.ux.YoutubePlayer allows developers to embed youtube videos into Ext applications, using native Ext components for controlling the video playback. It’ll show the buffer status and let’s you jump to any part in the video using a slider component.
Cool features include:
Showing the buffer status
Playback slider that let's you jump to any position in the video playback
When Jay Salvat set out to build markItUp!, he wasn't trying to build the next FCKEditor or TinyMCE. He just wanted to build a simple editor that could allow developers to add enhanced markup capability to textarea elements.
markItUp! is a JavaScript plugin built on the jQuery library. It allows you to turn any textarea into a markup editor. Html, Textile, Wiki Syntax, Markdown, BBcode or even your own Markup system can be easily implemented. markItUp! is not meant to be a “Full-Features-Out-of-the-Boxâ€-editor. Instead it is a very lightweight, customizable and flexible engine made to meet the developer's needs in their CMSes, blogs, forums or websites. markItUp! is not a WYSIWYG editor, and it never will be.
The usage is very straightforward. The following code demonstrates the ease of using markItUp!:
As the title asks, will IE8 & HTML5 make Really Simple History (and other Ajax history managers) irrelevant? Not so much says Brian Dillard, project lead for the Really Simple History project. While additions to HTML 5 & IE8 will definitely make managing page history easier, Brian anticipates that libraries such as RSH will evolve into tools for handling session data, especially as offline storage tools mature:
Other browsers will still require polling and other browser-specific hacks. Even after all browsers support the hashchange event and all non-supporting browsers fade into obscurity, Ajax history management will still play a role. For one thing, we'll still need a mechanism for our Ajax apps to associate state information with a given hash value (assuming, of course, that the hash token itself doesn't contain all the state information you need).
Right now, RSH accomplishes this with a hidden textarea. In the future, though, offline storage mechanisms will probably play the textarea's role. Once we get to the point where offline storage and the hashchange event are universal standards, Ajax history management will morph from a collection of hacks to a collection of convenience methods for native browser capabilities. Let's hope that time is sooner rather than later.
His thought seem to be on target and I think that apart from handling state information, RSH will eventually fill the holes that hashchange leaves behind.