Wednesday, August 20th, 2008
Category: Framework
, JavaScript
, Library
Creating a lot of HTML using DOM methods can be a real pain. This is what students of the Juku training course that I held two weeks ago found out quite quickly and complained about the verbosity of it all. I listened to their concerns and came up with a framework for JavaScript applications called
ViewsHandler.
One of the tasks I had given the class is to create a thumbnail show with image information from a link pointing to Flickr using the JSON API. The following is a solution using and showing the options of ViewsHandler:
A flickr show created with ViewsHandler
ViewsHandler is not another JavaScript templating solution but works on the assumption that in most cases you'll have to create a lot of HTML initially but you'll only have to change the content of some elements dynamically as new information gets loaded or users interact with the app. So instead of creating a lot of HTML over and over again all I wanted to provide is a way to create all the needed HTML upfront and then have easy access to the parts of the HTML that need updating.
The first thing you'll need to do to define your application is to create an object with the different views and pointers to the methods that populate the views:
JAVASCRIPT:
var views = {
index:{
create:createIndex
},
detail:{
create:createDetail
},
info:{
create:createInfo
}
};
ViewsHandler then creates DIV elements for each of these views and hides them for you. In your methods you create all the HTML the different views need to have and apply it with an add() method. You then define the parts of the HTML that should change later on as fields using the define() method and you can use the set() method to change the content of these fields and the view() method to change between views.
The benefit is that for setting the data you don't need to access the DOM any longer or use innerHTML or nodeValue. ViewsHandler created a pointer to the element all of this is cached. The set() method also allows you to either add a new node as the value or a string. In the latter case it'll create a text node for you.
One convenience method is linkto() which creates links pointing to the different views for you. None of this is rocket science, but it helped the class to create large applications with complex views without losing track of what they are doing. Maybe it can help you, too.
Category: Aptana
, JavaScript
, Server
![[image]](http://mowser.com/img?url=http%3A%2F%2Fwww.codegobbler.com%2Fsites%2Fcodegobbler.com%2Ffiles%2Ffckeditor%2Fjaxer.process.png)
Tom Kirkpatrick has written about a new API in Jaxer, Jaxer.Process, that allows you to call out to the host operating system. His example has a call out to get the uptime on the machine:
JAVASCRIPT:
<script runat="server-proxy">
function runUptime() {
// run the uptime and return the output from STDOUT
return Jaxer.Process.exec("/usr/bin/uptime");
}
</script>
You can see the application running live.
Tuesday, August 19th, 2008
Category: Examples
, JavaScript
, Library
Jacob Seidelin is up to more tricks, this time playing with the binary side of life and writing a library that can reading ID3 tags from MP3 files and such.
JAVASCRIPT:
// URL of the mp3 file (must be on the same domain!)
var file = "mymusicfile.mp3";
// define your own callback function
function mycallback() {
// either call the ID3.getAllTags([file]) function which returns an object holding all the tags
alert(
"All tags in this file: " + ID3.getAllTags(file).toSource()
);
// or call ID3.getTag([file], [tag]) to get a specific tag
alert(
"Title: " + ID3.getTag(file, "title") + " by artist: " + ID3.getTag(file, "artist")
);
}
ID3.loadTags(file, mycallback);
You can view a demo at work or download the code.
Of course, Jacob realises that this doesn't make sense for many use cases:
Of course, one big disadvantage of doing this on the client in JavaScript is that the you need to download the entire MP3 file before the tags are available, so it might be better to stick to server-side solutions in many cases if all you need is the tag info.
Category: JavaScript
Yehuda Katz saw the Harmony news, and wondered if there was a change to get _noSuchMethod, which currently works in implementations such as SpiderMonkey, into the new JavaScript world of: Harmony = ES3.1++.
In summary, it seems that the two groups agreed to focus cooperative effort of ECMAScript 3.1, a modest improvement of the current JavaScript that includes some new features like the ability to mark properties as non-enumerable and freezing objects (which can be used to implement classes).
After that is complete, the two groups have agreed to work on a new version of JavaScript dubbed “Harmonyâ€, which will be a more modest evolution of the current JavaScript, minus some of the more ambitious features like namespaces and packages. Other features, like classes, will likely be implemented in terms of new features in ES3.1 like freeze().
Which brings me to the title of my post. Now that it seems as though ES3.1 will be embraced by all the browser vendors moving forward (and will likely be the implemented iteration of JS for at least a little while), I wondered what sorts of features might still make it into ES3.1 before the spec was closed.
Specifically, I’ve long been interested in trying to get method_missing into JavaScript, and in fact, it is already available in Firefox/Spidermonkey as __noSuchMethod__. In fact, Johnson makes use of noSuchMethod in its Ruby proxy.
Want to get it in ASAP? Make your voice heard to the technical committee.
Category: JavaScript
Alex Russell has seen the confusion of the many names that were bandied around with the Harmony news last week. There are so many names, that involve specs, projects, and general technical jargon that it can get a little confusing. Alex has made it very clear:
- ECMAScript 3
- Aka: JavaScript, ES3, ECMAScript 262-3, and JScript.
The current JavaScript that every browser implements (more or less). This is the current ratified standard and represents the 3rd edition of the ECMAScript spec. It is very old. Nothing else in this list is (yet) a ratified standard of any sort.
- ECMAScript 4
- Aka: ES4, “JavaScript 2?.
A new language which was to be mostly backwards compatible but add optional (gradual) typing and class-based inheritance. Based loosely on Adobe’s ActionScript 3. This is the language effort which died as a result of Harmony.
- ECMAScript 3.1
- Aka: ES3.1. A set of small additions to ES3.
Planning for this edition was started at Microsoft and Yahoo’s behest late last year, causing the split in the working group which has been healed by the Harmony announcement.
- ActionScript 3
- Aka: AS3
Adobe’s current JavaScript-like language, only with many features lifted from languages like Java which also enforce types and class-based semantics. This was the starting point for much of the work which became known as ES4.
- Tamarin
- A JIT-ing byte-code virtual machine (VM) which is at the core of the Flash Player and was donated by Adobe to the Mozilla Foundation. This is the VM that runs ActionScript 3 code today but will likely run “real†JavaScript for Mozilla in the future. It is not a full implementation of ES3 or ES4, but instead implements its own byte-code and needs to be wedded to a “front end†(like the ActionScript 3
compiler from Adobe) in order to be usable by programmers.
- Tamarin-tracing
- A VM which implements the same byte-code language as Tamarin (known as “ABCâ€) but which is designed for use in mobile devices and other scenarios where code size and VM footprint are important. It implements trace-tree JIT-ing as a way to speed up hot-spots. Also donated to Mozilla by Adobe.
- TC39
- The name of the ECMA technical committee which is chartered to evolve the JavaScript language.
- Harmony
- A new code-name for a language which is to come after ES3.1. It will feature many of the things ES4 was trying to accomplish, but may attempt them from different directions and will
focus much more on incremental, step-wise evolution of the language.
- JavaScript 2
- A now-defunct name. This name was originally given to Waldemar Horwat’s first proposal at a large-scale evolution of the JavaScript language in 1999. That effort did not succeed (although Microsoft implemented some of it in JScript.NET) and subsequent work via the current TC39 charter to build ES4 has sometimes been given the name “JavaScript 2?, but it never really stuck. Not a name that describes any ratified standard or current proposal.
- ECMAScript
- The formalized name of the JavaScript language. Since Sun Microsystems owns the name JavaScript and has no idea what to do with the trademark (but has been benevolent thus far), the ECMA committee which standardized the language was forced to adopt a different name.
Monday, August 18th, 2008
Category: Examples
, JavaScript
, Tip
, jQuery
![[image]](http://mowser.com/img?url=http%3A%2F%2Fitknowledgeexchange.techtarget.com%2Fweb-standards%2Ffiles%2F2008%2F08%2Fitke-script2.png)
Jeffrey Olchovy has posted a simple tutorial on using jQuery to solve a "select-to-input toggle" that shows and hides a text field when you select "Other". It overloads the same form name, so the server side gets just one value, and doesn't know or care if it was in the drop down or typed in. You can try it live here.
This is a simple little solution to the issue that there isn't a native control to really do the job. What you really probably want here is the ability to drop down and select items, or just type into the select box field itself. This is one reason why people implement auto-complete text fields instead of using select boxes for this case, but wouldn't it be nice to be able to tag your <select> and be done?
Category: JavaScript
, Tip
Eric Wendelin has posted on getting a JavaScript stack trace no matter that the browser.
With Firebug you can call console.trace() but what about the rest?
Luke Smith took Eric's work and added to it, ending up with:
JAVASCRIPT:
(function () {
YOUR_NAMESPACE.getStackTrace = (function () {
var mode;
try {(0)()} catch (e) {
mode = e.stack ? 'Firefox' : window.opera ? 'Opera' : 'Other';
}
switch (mode) {
case 'Firefox' : return function () {
try {(0)()} catch (e) {
return e.stack.replace(/^.*?\n/,'').
replace(/(?:\n@:0)?\s+$/m,'').
replace(/^\(/gm,'{anonymous}(').
split("\n");
}
};
case 'Opera' : return function () {
try {(0)()} catch (e) {
var lines = e.message.split("\n"),
ANON = '{anonymous}',
lineRE = /Line\s+(\d+).*?in\s+(http\S+)(?:.*?in\s+function\s+(\S+))?/i,
i,j,len;
for (i=4,j=0,len=lines.length; i<len; i+=2) {
if (lineRE.test(lines[i])) {
lines[j++] = (RegExp.$3 ?
RegExp.$3 + '()@' + RegExp.$2 + RegExp.$1 :
ANON + RegExp.$2 + ':' + RegExp.$1) +
' -- ' + lines[i+1].replace(/^\s+/,'');
}
}
lines.splice(j,lines.length-j);
return lines;
}
};
default : return function () {
var curr = arguments.callee.caller,
FUNC = 'function', ANON = "{anonymous}",
fnRE = /function\s*([\w\-$]+)?\s*\(/i,
stack = [],j=0,
fn,args,i;
while (curr) {
fn = fnRE.test(curr.toString()) ? RegExp.$1 || ANON : ANON;
args = stack.slice.call(curr.arguments);
i = args.length;
while (i--) {
switch (typeof args[i]) {
case 'string' : args[i] = '"'+args[i].replace(/"/g,'\\"')+'"'; break;
case 'function': args[i] = FUNC; break;
}
}
stack[j++] = fn + '(' + args.join() + ')';
curr = curr.caller;
}
return stack;
};
}
})();
Friday, August 15th, 2008
Category: Interview
, JavaScript
ECMAScript Harmony has been the big news of the week. It isn't hard to see why, the next version of JavaScript is going to affect us all, for a long time (even more than a presidents term!)
Alex Russell, John Resig, and myself got Brendan Eich and Arun Ranganathan on the phone to talk about the news. This is episode 2 of the Open Web Podcast (see the new website, and subscribe to the series, including via iTunes.)
The podcast is over an hour long and goes into a ton of detail covering a lesson on language design, politics and process, a lot of history, and hopefully the path to a positive future.
We have other postings going on in the community too. Douglas Crockford writes an opinion on how The Only Thing We Have To Fear Is Premature Standardization, Mike Chambers wraps up the thoughts of Adobe on ActionScript 3 and ECMAScript 4, and Alex Russell talks sense into the fallout.
Have you seen any interesting posts or thoughts on the news?
Category: Examples
, JavaScript
Inspired by the Gmail team and how they created well known Greasemonkey endpoints and the custom events work that I have been doing, I was lead to play with custom events as a way to tie into key bindings. This lead to the following post on my blog:
On the back of my example enjoying the Observer pattern with custom events I have started to play with a pet project also involving custom events.
I love keyboard shortcuts. I hate the mouse. I wish that Web applications would offer more keyboard shortcuts a la Gmail, and wondered if there could be a generic way to tie keys to actions in an app. There are things such as accessKey, but we need more.
If you start to follow the pattern of creating named events for public integration points, then how about tieing in keys? I implemented this on the quote example, where you can now use up and down arrows, and N and P, to move through the list of names.
To use the system you declare the keys and tie them to events:
JAVASCRIPT:
KeyBindings.add({
eventname: 'action:move-up',
// keys: KeyBindings.caseInsensitive('p'),
keys: ['p', Key.ARROW_UP ],
description: "Move up the stack"
});
KeyBindings.add({
eventname: 'action:move-down',
keys: ['n', Key.ARROW_DOWN ],
description: "Move down the stack"
});
This code ties the keys to the actions, and thus fires those actions when pressed. Next, you need to capture those events to do the work when the key is fired:
JAVASCRIPT:
document.observe('action:move-up', function(e) {
Selection.moveUp();
});
document.observe('action:move-down', function(e) {
Selection.moveDown();
});
With a standardized way of annotating events, interesting side effects appear. You can hit the '?' key to bring down a heads up display sharing what keys do. You could imagine a Greasemonkey script, or browser plugin, that loads the keybindings.js code, and looks for the key binding definitions. The declaration could be done in HTML too, which could be found by the plugin and tied into the system. What do you think?
Thursday, August 14th, 2008
Category: JavaScript
, Yahoo!
YUI 3 has a preview release for us to check out.
The goals are:
lighter (less K-weight on the wire and on the page for most uses) faster (fewer http requests, less code to write and compile, more efficient code) more consistent (common naming, event signatures, and widget APIs throughout the library) more powerful (do more with less implementation code) more securable (safer and easier to expose to multiple developers working in the same environment; easier to run under systems like Caja or ADsafe)
What's New
Sandboxing: Each YUI instance on the page can be self-contained, protected and limited (YUI().use()). This segregates it from other YUI instances, tailors the functionality to your specific needs, and lets different versions of YUI play nicely together. Modularity: YUI 3 is architected to use smaller modular pieces, giving you fine-grained control over what functionality you put on the page. If you simply want to make something draggable, you can include the dd-drag submodule, which is a small subset of the Drag & Drop Utility. Self-completing: As long as the basic YUI seed file is in place, you can make use of any functionality in the library. Tell YUI what modules you want to use, tie that to your implementation code, and YUI will bring in all necessary dependencies in a single HTTP request before executing your code. Selectors: Elements are targeted using intuitive CSS selector idioms, making it easy to grab an element or a group of elements whenever you’re performing an operation. Custom Events++: Custom Events are even more powerful in YUI 3.0, with support for bubbling, stopping propagation, assigning/preventing default behaviors, and more. In fact, the Custom Event engine provides a common interface for DOM and API events in YUI 3.0, creating a consistent idiom for all kinds of event-driven work. Nodes and NodeLists: Element references in YUI 3.0 are mediated by Node and NodeList facades. Not only does this make implementation code more expressive (Y.Node.get("#main ul li").addClass("foo");), it makes it easier to normalize differences in browser behavior (Y.Node.get("#promo").setStyle("opacity", .5);). Chaining: We’ve paid attention throughout the new architecture to the return values of methods and constructors, allowing for a more compressed chaining syntax in implementation code.
Some example snippets
JAVASCRIPT:
// Creates a YUI instance with the node module (and any dependencies) and adds the class "enabled" to the element with the id of "demo".
YUI().use('node', function(Y) {
Y.get('#demo').addClass('enabled');
});
// Creates an instance of YUI with basic drag functionality (a subset of the dd module), and makes the element with the id of "demo" draggable.
YUI().use('dd-drag', function(Y) {
var dd = new Y.DD.Drag({
node: '#demo'
});
});
// Adds the class "enabled" to the all elements with the className "demo".
Y.all('.demo').addClass('enabled');
// Sets the title attribute of all elements with the className "demo" and removes the class "disabled" from each.
Y.all('.demo').set('title', 'Ready!').removeClass('disabled');
// Adds the Drag plugin to the element with the id "demo", and enables all of its h2 children drag as handles.
Y.get('#demo').plug(Y.Plugin.Drag, {
handles: 'h2'
});
// Attaches a DOM event listener to all anchor elements that are children of the element with the id "demo". The event handler prevents the anchor from navigating and then sets a value for the innerHTML of the first em element of the clicked anchor.
Y.on('click', function(e) {
e.preventDefault();
e.target.query('em').set('innerHTML', 'clicked');
}, '#demo a');
Very exciting stuff to the team. I look forward to seeing a full up code repository too!
Category: Books
, JavaScript
John Resig is working on the Secrets of the JavaScript Ninja book, which I am sure will be a success.
Manning has been kind enough to give us a sneak peak at some of the chapters:
How closures work
This content introduces the closure, an important aspect of JavaScript, and describes its use. It goes into detail on making private data, and dealing with callbacks and timers.
Using (function(){})()
Next up introduces the construct (function(){})() and describes its use in relationship to closures. See how you can create encapsulated temporary scopes.
Instantiation and Prototypes
This section introduces the technique of instantiating a function to give its prototype property functionality.
Class-like Code
And finally we are introduced to the technique of emulating classical-style inheritance in JavaScript.
Wednesday, August 13th, 2008
Category: JavaScript
, Standards
I discussed my worries about JavaScript 2 recently. I could only do so as I saw some light at the end of the tunnel. That light came from an ECMA meetup in Oslo where it seems people came together to rally behind the idea that something needs to be done.
Brendan Eich posted to a mailing list on the work, and I think I will let him talk below:
It's no secret that the JavaScript standards body, Ecma's Technical
Committee 39, has been split for over a year, with some members
favoring ES4, a major fourth edition to ECMA-262, and others
advocating ES3.1 based on the existing ECMA-262 Edition 3 (ES3)
specification. Now, I'm happy to report, the split is over.
The Ecma TC39 meeting in Oslo at the end of July was very productive,
and if we keep working together, it will be seen as seminal when we
look back in a couple of years. Before this meeting, I worked with
John Neumann, TC39 chair, and ES3.1 and ES4 principals, especially
Lars Hansen (Adobe), Mark Miller (Google), and Allen Wirfs-Brock
(Microsoft), to unify the committee around shared values and a common
roadmap. This message is my attempt to announce the main result of
the meeting, which I've labeled "Harmony".
Executive Summary
The committee has resolved in favor of these tasks and conclusions:
1. Focus work on ES3.1 with full collaboration of all parties, and
target two interoperable implementations by early next year.
2. Collaborate on the next step beyond ES3.1, which will include
syntactic extensions but which will be more modest than ES4 in both
semantic and syntactic innovation.
3. Some ES4 proposals have been deemed unsound for the Web, and are
off the table for good: packages, namespaces and early binding. This
conclusion is key to Harmony.
4. Other goals and ideas from ES4 are being rephrased to keep
consensus in the committee; these include a notion of classes based
on existing ES3 concepts combined with proposed ES3.1 extensions.
Detailed Statement
A split committee is good for no one and nothing, least of all any
language specs that might come out of it. Harmony was my proposal
based on this premise, but it also required (at least on the part of
key ES4 folks) intentionally dropping namespaces.
This is good news for everyone, both those who favor smaller changes
to the language and those who advocate ongoing evolution that
requires new syntax if not new semantics. It does mean that some of
the ideas going back to the first ES4 proposals in 1999, implemented
variously in JScript.NET and ActionScript, won't make it into any ES
standard. But the benefit is collaboration on unified successor
specifications to follow ES3, starting with ES3.1 and continuing
after it with larger changes and improved specification techniques.
One of the use-cases for namespaces in ES4 was early binding (use
namespace intrinsic), both for performance and for programmer
comprehension -- no chance of runtime name binding disagreeing with
any earlier binding. But early binding in any dynamic code loading
scenario like the web requires a prioritization or reservation
mechanism to avoid early versus late binding conflicts.
Plus, as some JS implementors have noted with concern, multiple open
namespaces impose runtime cost unless an implementation works
significantly harder.
For these reasons, namespaces and early binding (like packages before
them, this past April) must go. This is final, they are not even a
future possibility. To achieve harmony, we have to focus not only on
nearer term improvements -- on "what's in" or what could be in -- we
must also strive to agree on what's out.
Once namespaces and early binding are out, classes can desugar to
lambda-coding + Object.freeze and friends from ES3.1. There's no need
for new runtime semantics to model what we talked about in Oslo as a
harmonized class proposal (I will publish wiki pages shortly to show
what was discussed).
We talked about desugaring classes in some detail in Oslo. During
these exchanges, we discussed several separable issues, including
classes, inheritance, like patterns, and type annotations. I'll avoid
writing more here, except to note that there were clear axes of
disagreement and agreement, grounds for hope that the committee could
reach consensus on some of these ideas, and general preference for
starting with the simplest proposals and keeping consensus as we go.
We may add runtime helpers if lambda-coding is too obscure for the
main audience of the spec, namely implementors who aim to achieve
interoperation, but who may not be lambda-coding gurus. But we will
try to avoid extending the runtime semantic model of the 3.1 spec, as
a discipline to guard against complexity.
One possible semantic addition to fill a notorious gap in the
language, which I sketched with able help from Mark Miller: a way to
generate new Name objects that do not equate as property identifiers
to any string. I also showed some sugar, but that is secondary at
this point. Many were in favor of this new Name object idea.
There remain challenges, in particular getting off of the untestable
and increasingly unwieldy ES1-3.x spec formalism. I heard some
generally agree, and no one demur, about the ES4 approach of using an
SML + self-hosted built-ins reference implementation (RI).
We are going to look into stripping the RI of namespaces and early
binding (which it uses to ensure normative self-hosted behavior, not
susceptible to "user code" modifying the meaning of built-ins),
simplifying it to implement ES3.1plus or minus (self-hosted built-ins
may require a bit more magic). More on that effort soon.
ES3.1 standardizes getters and setters that were first implemented at
Mozilla and copied by Apple and Opera. More such de-facto
standardization is on the table for a successor edition in the
harmonized committee.
I heard good agreement on low-hanging "de-facto standard" fruit,
particularly let as the new var, to match block-scoped const as still
proposed (IIRC) in 3.1. Also some favorable comments about simple
desugarings such as expression closures and destructuring assignment,
and other changes in JS1.7 and 1.8 that do not require new runtime
semantic models.
Obviously, these require new syntax, which is appropriate for a major
post-3.1 "ES-harmony" edition. Syntax is user interface, there's no
reason to avoid improving it. What's more, the intersection semantics
of extended ES3 implementations conflict and choke off backward-
compatible *semantics* for syntax that may even parse in all top four
browsers (e.g., functions in blocks).
Both the appropriateness of new syntax, and the need to make
incompatible (with ES3 extensions) semantic changes, motivate opt-in
versioning of harmonized successor edition. I believe that past
concerns about opt-in versioning requiring server file suffix to MIME
type mapping maintenance were assuaged (browsers in practice, and
HTML5 + RFC 4329, do not consider server-sent Content-Type -- the web
page author can write version parameters directly in script tag type
attributes).
Some expressed interest in an in-language pragma to select version;
this would require immediate version change during parsing. It's a
topic for future discussions.
The main point, as important as cutting namespaces in my view, is
that the committee has a vision for extending the language
syntactically, not trying to fit new semantics entirely within some
combination of existing "three of four top browsers" syntax and
standard library extensions.
As Waldemar Horwat (Google) said on the final day, the meeting was
seminal, and one of the most productive in a long while. Much work
remains on 3.1 and Harmony, but we are now on a good footing to make
progress as a single committee.
There is still a lot to do, and I look forward to hearing Doug's side of things too (going to blog about it Doug?).
What are your thoughts?
UPDATE: John Resig has added his thoughts.
Category: JavaScript
, Ruby
I am a fan of Ruby, and when I saw Red the framework that allows you to write Ruby and get JavaScript out the other end I was excited. It allows you to write this:
RUBY:
class MyClass
@@my_var = 500
def initialize(arg)
@arg = arg
end
def my_method
alert(@arg)
end
end
And you end up with:
JAVASCRIPT:
1| var MyClass = function(arg) { this.arg = arg;this.myMethod = function() { alert(this.arg); } }; MyClass.myVar = 500
You can also have fun with blocks:
RUBY:
[1,2,3].sort do |x,y|
return y - x
end
JAVASCRIPT:
[1, 2, 3].sort(function(x,y) { return y - x; })
You also get convention conversion, which can lead to some weird things such as:
On one hand I am excited about being able to think that I am hacking on Ruby, even though I am not. On the other hand, I worry about the abstraction leaking (ending with weird bugs) and how ruby is great because of all of the MOP, the libraries, and other things that you can't really do with this system. This makes it a bit of a tease.
Tuesday, August 12th, 2008
Category: JavaScript
, Mobile
, Performance
, iPhone
HTML:
function recurse(n) {
if (n> 0) {
return recurse(n - 1);
}
return 0;
}
try {
// recurse(43687); // Highest that works for me in WebKit
// nightly builds as of 24 Jul 2008.
// recurse(2999); // Highest that works for me in Firefox 3.0.1
// recurse(499); // Highest that works for me in Safari 3.1.2
recurse(3000);
document.write("Could be SquirrelFish.");
} catch(e) {
document.write("Not SquirrelFish.");
}
</script>
This is the hack that John Grubber used to test whether iPhone 2.x had snuck in SquirrelFish. He was curious due to the performance improvements that he witnessed:

What about iPhone limits though? David Golightly tests the limits on the iPhone with a script that keeps downloading tiles until it can no longer do so:
After downloading about 210 images, the iPhone simply stops downloading new ones. This is probably due to hitting the hard 30MB same-page resource limit.
Monday, August 11th, 2008
Category: JavaScript
, Testing
Johannes Link is an Agile fellow who wasn't 100% happy with the existing JavaScript unit test frameworks, and he explained why. He gives an example:
JAVASCRIPT:
testDoubleSpeaker: function() { with(this) {
var actualMsg = null;
var mockSay = function(msg) {
actualMsg = msg;
};
Speaker.say = mockSay;
DoubleSpeaker.say('oops');
assertEqual('oopsoops', actualMsg);
}}
It works, but he discusses how this changes the global world, which is a bad thing. Would it be nicer to spy and end up with:
JAVASCRIPT:
testDoubleSpeaker: function() { with(this) {
mock(Speaker).andDo(function() {
DoubleSpeaker.say('oops');
verify(Speaker.say)('oopsoops');
});
}},
This is an example from his new framework, MockMe, which has the main features:
The basic granularity of mocking should be the function. If I want to, I can fake the behaviour of a single function without influencing the rest (of an object or a prototype or the global namespace or whatever). Most of the time, spying is a better idea than mocking because it’s simpler. Spying basically means that, instead of specifying the expected interaction with your mock spy object before doing the test, you use the mock spy object to spy into the interaction as it happens and verify that afterwards. In that respect I borrowed heavily from mockito, a spying framework that’s gaining more and more attention in the Java world.
A few other examples:
JAVASCRIPT:
when(f)('in').thenReturn('out');
assertEqual('out', f('in'));
when(f)({name: 'hello'}).thenReturn('yeah');
assertEqual('yeah', f({name: 'hello'}));
when(f)(any(