Archive for the ‘javascript’ tag
Run Javascript, Run!
We’re pretty much a Mac shop here at imedo and, as our application is built using Ruby on Rails, it’s safe to say that we are legally obliged to use TextMate for all our editing needs
.
One of the features I love about TextMate, catered for in most bundles, is the ability to execute a script and get a nice pop-up window displaying the results. Scrolling through my installed language bundles, I see they all have a “Run Script” command. All, that is, except my second favourite language – Javascript. You fancy rectifying this? You fancy giving Javascript some TextMate/V8 lurv? Then walk this way …
First, lets grab V8. We’ll be using scons to build it. Scons? Aren’t they a strange muffin-like concoction originating in the fair British Isles? That’ll be ‘scones‘ you’re thinking of. Scons is a software construction tool written in Python. Check it out at here. It must be good – Zed likes it. Install with macports.
And on with the build.
Get v8:
$> svn co http://v8.googlecode.com/svn/trunk v8
- or -
$> git clone git://github.com/v8/v8.git v8
…
$> cd v8
$> scons
The build should have been successful. V8 comes with a shell which we’re going to use. Build like so:
$> g++ ./samples/shell.cc -o v8-shell -I include libv8.a
Make sure that ‘v8-shell’ is in your PATH. And now for the final step. In TextMate: Bundles > Bundle Editor > Show Bundle Editor. Scroll down to the Javascript bundle and Create a new Command. We’ll use our imagination here and call it “Run Script”. In the Edit Command Window:
Save: Nothing
Command(s):
$(type -p "${TM_RUBY:-ruby}") -e'
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/executor"
require ENV["TM_SUPPORT_PATH"] + "/lib/tm/save_current_document"
TextMate.save_current_document
TextMate::Executor.make_project_master_current_document
TextMate::Executor.run("v8-shell", ENV["TM_FILEPATH"])'
Input: Entire Document
Output: Show as HTML
Activation: Key Equivalent > Cmd+R
Scope Selector: source.js
This is copied and adapted from the “Run Script” Command for the Ruby bundle.
And that – as they say – is that. Time to check it out:
Open a new window in TextMate and type the following:
function addSomeValues (first, second) {
return first + second;
}
print(addSomeValues(2,3))
Select the Javascript scope. Wait for it … Ready? … Go Cmd+R! Hopefully you saw the number five.
Now change the last line to read
print(addSomeValueCATsaTOnKeyboArD(2,3))
Run again and you should get a nice ReferenceError.
Thanks go to gs over at StackOverflow for this post detailing the steps for getting the v8 shell built.
Popularity: 1% [?]
Design for Usability
RailsConf Europe 2008
Session – Design for Usability
presented by Christian Lupp
In his talk at RubyConf Europe 2008 Christian Lupp showed a designers approach to solving problems. It my seem strange to have a designer give a talk in front of a developer crowd, but I think you will find, that we can learn a few things by observing other professions’ methodologies.
He told the audience that many great ideas have evolved on paper. You start out with rough sketches and prototypes. In this stage you basically create a landscape of your application and it should help you to understand what the problems are you want to solve. Once you’ve dont that, you redefine these prototypes iteratetively. Be confident to throw stuff away that isn’t working out and explore alternative solutions. Fail fast and early.
Hmm, this all sounds an aweful lot much like agile software development, doesn’t it?
He also mentioned that you should always take the context into account when constructing your application. Without thinking about the user’s perspective and his needs, may it be a human or a machine, it’s likely that you develop in the wrong direction.
If you have two equal solutions to a problem, take the simple solution. This is called the Occham’s razor Behold! Knowledge from the 14th century folks, but still true. In order to find the simplest solution, you reduce functionality until your application is missing something important, then you go one step back.
Then the talk got technical after all.
Christian asked why we as web developers should use techniques like unobstrusive javascript at all and listed some valid points. First, people using screenreaders will love you. Second, the marketing and SEO guys will love you. You improve the overall performance of your website and thus speed up the overall user experience on your website. Users don’t like to wait. If a page is snappy and responsive, they are more likely to come back.
Christian also shared some basic design tipps with us.
Repeat with DRY. Don’t show different elements on every page. Instead develop an overall graphical and UX concept. It doesn’t only make you site look more professional but will also help users to find their way around on your site. Usability equals recognizable patterns, so repeat yourself and use layout grids etc. that will help your users to understand the content of your site faster.
Another good tipp is to always validate user input immediately by javascript for example. Give your user feedback all the time and instantly, eventough the action he started may take longer. Be creative and entertain you user while he is waiting for search results. Instead of letting the user wait for the search to finish, you can show him an immediary screen which informs him that his search is beeing performed and could take a few moments to finish. You informed your user and in the backgorund your server is already working on finding relevant results for him. This pattern is already used by most forum software.
That was “Design for Usability”, a very interesting talk.
Popularity: 1% [?]
Accessible Ajax on Rails – RailsConf Europe 2008
RailsConf Europe 2008
Tutorial – Accessible Ajax on Rails
presented by Jarkko Laine and Geoffrey Grosenbach
In this tutorial on tuesday Jarkko showed how to use unobstrusive Javascript techniques, in particular LowPro, to seperate javascript logic from content. His example of choice was a simple ToDo list with checkboxes. He started out by using the standard Rails helpers and the refactored the application to use unobstrusive javascript.
If you’ve never heard of unobstrusive Javascript before the first part was very interesting, because here he pointed out that inline scripts not only block the browser, but also clutter your html code with unneccessary output. It bloats your file and is not very DRY. Imagine you use standard Rails helpers in a list of checkboxes to do Ajax calls. The same code over and over again.
The next step was a introduction to LowPro by Dan Webb (Prototype Core Team member), which makes it easy to attach javascript logic to elements on a page by the Event.addBehavior method:
Event.addBehaviour({
'#add_form' : RemoteForm({
onComplete: doSomething here ...
})
});
Here are some tips from Jarkko:
Be careful when using Event.addBehaviour.reassignAfterAjax = true;, because all your behavior code will run again after every Ajax request and potentially mess up your page. Instead apply behaviors inside the onComplete callback of the Ajax call like this: onComplete: function(){ Event.addBehaviour.reload(); }
He also suggested that instead of using too many classes to identify your behavior targets, you could use CSS3 selectors like "input[type=checkbox]" instead. The question here is if this performs better than classes on slow browsers like IE6.
All this ujs sounds pretty interesting, but you should use it wisely. For example if you need to apply a behavior to every cell in a large table. If you attach a behavior object to every single cell, it will not only eat a lot of memory, but will slow down the initialization of the page overall. If you add observers to each of these objects, the site will be sluggish. This is where Event.delegate comes in! Instead of applying the behavior to every single cell, you attach it on the table and let Event-propagation do the work for you.
LowPro comes in handy here, because it has this functionality built in through the Event.delegate method, which you can use like this:
Event.addBehaviour({
'table:click':Event.delegate({
'td':function(e){
var targetElement = e.element();
},
'a':function(e){
e.stop(); // stops the event from bubbling
}
})
});
Make sure you explicitly stop events from bubbling, because otherwise if a link inside a table cell is clicked, both actions will be executed. But there is a caveat to this method: unfortunately not all events bubble up. In particular ‘focus’ and ‘blur’, so be aware of this.
If you need to store state inside your behavior you can also attach custom objects to these elements, like you’ve seen it with RemoteForm in the first example. First you need the class:
var Hover = Behaviour.create(
initialize: function(className){
this.lassName = className || 'over';
},
onmouseover:function(){
// this will be a event handler
}
);
which will contain all your logic and observers.
Then you attach the Hover class to the DOM element like you’ve seen before:
Event.addBehaviour({
'.hover_thing':Hover
});
More on UJS will follow.
Popularity: 1% [?]
Unobstrusive Javascript User Interface Framework
We are proud to announce the first alpha release of our unobstrusive user interface framework, written in Javascript. This release is codenamed THC2, and will be renamed as soon as we find time to think about a better name. Suggestions are always welcome.
What is Unobtrusive Javascript?
The idea behind unobstrusive Javascript is to decouple the Javascript from the HTML-Code, similar to decoupling style information from HTML. There are lots of immediate advantages in this approach:
- Optical aspects; it just looks nicer.
- Its DRYer. Using inline Javascript makes you repeat code all over the place.
- Easier to maintain validity. Using inline Javascript invites you to do certain hacks that break XHTML compliance.
- Bandwidth savings. No Javascript in the markup means less markup.
- Web designers understand your markup. Heck, they even start to understand the whole thing, and deliver Javascript-enriched interfaces—without using any Javascript.
- It’s compatible with screen readers.
- In contrast to inline Javascript, unobstrusive Javascript can be completely unit tested.
Because of our somewhat specialized audience, we have to present interfaces that are understandable by accessibility helpers, more than anyone else. Invalid XHTML, inline Javascript, seemingly unneccessary markup and so on, all might get in the way of accessibility software. So the main design goal for this Javascript library seems a bit paradox: Work with Javascript not working or turned off. This is actually another nice property that can be achieved using unobstrusive Javascript: Just design an interface with minimal markup that is usable without Javascript, and then enrich it with Javascript afterwards. Unobstrusive Javascript is all about enriching interfaces.
Features
- The library features a total of 12 helper classes, 18 ready-to-use widgets, and 6 extensible base classes to more complex widgets. For details, see the Demo page or the Documentation.
- The widgets are extremely easy to use, and the documentation is almost complete.
- There is a cross-browser javascript profiler, written in javascript, as an extra, available here.
- The library is unit-tested, so there is nothing to be worried about (some tests are still missing)
What about an example?
Ok. Suppose you need a link to open another page in a popup window; not a target="_blank" window, no, a real javascripted popup window. The easy and obvious way to do this is the following:
<a href="#"
onclick="window.open('http://www.wikipedia.org', 'popup', 'width=640,height=480');
return false;">Click</a>
Or, as a link: Click
The first problem of this solution is that Javascript does not belong in HTML code. It simply doesn’t, for the above mentioned reasons. The second problem is that on failure, no window is opened at all. Failure might happen, when Javascript is turned off, or a screen reader is used.
<a href="http://www.wikipedia.org"
target="_blank"
onclick="window.open('http://www.wikipedia.org', 'popup', 'width=640,height=480');
return false;">Click</a>
Or, as a link: Click
This is an improvement to the first version, in that the actual target URL is given in the href attribute, so this has a real chance to work with screen readers. Also, for turned-off Javascript, the URL opens in a new window (note the target="_blank" fallback). There are two problems with this code, though. First, it is not DRY: The URL is repeated. Also, several occurrences of this kind of popup link repeat almost identical Javascript. This is a waste of bandwidth. Second, it is hard to understand. Try to have your CSS guy debug HTML code with inline Javascript. It isn’t fun to watch, trust me.
<a href="http://www.wikipedia.org" target="_blank" class="thc2-popup">Click</a>
Or, as a link: Click
This last version solves all above mentioned problems. First, it uses the target="_blank" fallback to open a window in any situation. Second, it has the target URL in the href attribute, so it works with accessibility tools. Third, and most important, it contains no trace of Javascript.
So, how does the link know that it has to open the link as a popup window? The answer is in the class attribute: The class thc2-popup tells the THC2 Javascript framework to apply the popup behaviour on the link. The popup behaviour, or PopupWidget, installs an onclick event handler on the link, which opens the URL that is specified in the elements href attribute in a popup window.
The code for the PopupWidget class might look something like the following:
var PopupWidget = Class.create(Widget, {
initialize: function(element) {
Widget.prototype.initialize.apply(this, arguments);
this.url = this.element.href;
Event.observe(this.element, "click", this.showPopup.bindAsEventListener(this));
},
showPopup: function(event) {
event.stop();
win = window.open(this.url, 'popup', "width=640,height=480");
}
});
CurrentPage.registerBehaviour("thc2-popup", PopupWidget);
On first sight, this doesn’t look like any bandwidth saving at all. You’re almost right. Except for the fact that Javascript classes can and should be put in an external file, which can be cached by the browser forever. So over time, you will actually save bandwidth.
Dependencies
The THC2 framework depends on the Prototype (Version 1.6 and above) and Scriptaculous (version 1.8 or later) libraries. A few optional widgets need the TinyMCE WYSIWYG editor (version 3 or later); without TinyMCE, the widgets will use regular text areas.
Getting it, License and Patches
Get the library or the complete source code through the links on top of this page. License is MIT. That means that you can do whatever you want with the software, as long as the copyright statement stays intact. Please be a kind open source citizen, and give back your patches and extensions. Just fork the code on Github, and after you’re done, send us a pull request. Thanks for your help!
Popularity: 1% [?]
Cross-Browser javascript profiler
Everyone who ever seriously developed for Internet Explorer using Javascript knows that there will be a point where IE just can’t keep up with execution times. There are some tools for introspection, but none of them provide javascript profiling functionality (which is btw. built into firebug). Another serious issue is that there is no way to compare the performance characteristics across different browsers. And since imedo.de hit the IE performance wall when migrating to prototype 1.6 last week, we had to come up with a solution fast.
First of all, the simplest solution is upgrading IE to the latest version. But this won’t help here, because it is close to impossible to get users to update their browsers, even though they are constantly reminded of updates from within Windows. So we came up with the idea to build a profiling tool that works in Internet Explorer.
Design goals
The Profiler should be easy to integrate. It should not break any functionality. It also should be universal, which means that it should be able to profile any javascript function. It should not have any dependencies besides core Javascript. It should be possible to enable or disable the profiler on the fly. It should be unobstrusive, i.e. integration should be painless. Execution times with profiling enabled should be tolerable (for patient developers).
Using it
The profiler is extremely easy to integrate. You need to include the profiler.js in your HTML file and call
|
|
Profiler.init(); |
after your javascript code is loaded and before any of the code is executed that you want to profile. If you are using Internet Explorer, you might need to tell the profiler about your javascript objects and functions. See below on how to do that. You’ll get a popup for controlling the profiler:

Or course, you need to disable the popup blocker for your website. To create a profile of your javascript, click “Enable Profiler”, reload the page and have your Browser execute the code you want to profile. After it is finished, click on “Show Report” to get the execution profile:

How it works
First, the Profiler scans the javascript object tree and stores all objects it finds in an array (the discover phase). Herein lies the first problem: There is no way to enumerate all user-defined global functions or variables just with javascript in Internet Explorer. So we have to help out a little. There are several solutions to this problem, but since we recursively discover the whole object tree anyways, our solution is to make all global variables known to the window object (which equals the this-object in the global scope). Suppose we have a Greeter object:
1 2 3 4 5 |
var Greeter = { greet: function() { alert('Hello'); } }; |
We tell the profiler about this object by by making it available as a property to the window object (in global scope):
|
|
this._$_Greeter = Greeter;
|
Now, when browsing the object tree with root window, the Greeter object will be found.
The second phase is the rewrite phase: it takes all scanned objects and replaces each of their function properties with a wrapped version that measures the execution time. The following code extends the Function prototype with a method that converts any function to its profiled version.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Function.prototype.profiledFunction = function(name) { var func = this; var f = function() { try { Profiler.start(name); var result = func.apply(this, arguments); Profiler.stop(name); return result; } catch(e) { Profiler.stop(name); throw(e); } } f.prototype = this.prototype; for (var property in this) { f[property] = this[property]; } return f; } |
The f variable is an anonymous function that wraps the original function. Since functions are objects in javascript that can themselves have properties, the f function needs to inherit all the properties from the original function (remember: A “Class” in javascript is just a function / object with properties that are functions (i.e. methods)). One of the problems here is that there are enumerable and not enumerable properties in javascript. All enumerable properties can be discovered by using the for (var ... in ...) construct. A kind of important non-enumerable property is the prototype property, which needs to be assigned to the f variable separately.
Again, Internet Explorer has a problem with global functions: They are not known to the window object, so they are not discoverable by the Profiler. However, it is easy to profile them anyway. Suppose we have a function called greet():
1 2 3 |
function greet() { alert('hello'); } |
We profile the greet() function by replacing it with its profiled version like so:
|
|
greet = greet.profiledFunction('greet');
|
Since the above steps are very repetitive and error-prone, and since we promised an extremely easy-to-use and non-invasive profiler, here is a short Ruby snippet that scans a list of folders for javascript files and extracts global variables and functions, and spits out a javascript file that makes them available to the profiler, if enabled:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
vars = [] funcs = [] ARGV.each do |root| ["#{root}/*.js", "#{root}/**/*.js"].each do |dir| Dir.glob(dir).collect do |f| file = File.read(f) vars << file.scan(/^var\s+([\w\$]*)/) funcs << file.scan(/^function\s+([\w\$]*)\s*\(/) end end end vars.flatten!.uniq! funcs.flatten!.uniq! puts "if (Profiler.isEnabled()) {" vars.each do |var| puts "this._$_#{var} = #{var};" end funcs.each do |func| puts "#{func} = #{func}.profiledFunction('Global.#{func}');" end puts "}" puts "Profiler.init();" |
Specify the root directory of your javascript folder on the command line and redirect the output to a javascript file (e.g. profile_helper.js):
ruby jsprof.rb one/path/to/javascript another/path/to/javascript > profile_helper.js
Include that file after your javascript code, but such that it is executed before any of the code you want to profile. The easiest way to accomplish that is to have your page initialization in a separate file that is loaded last.
Known issues
- You need to reload the page after enabling the profiler. We tried to enable it on the fly, but that just doesn’t work in IE
- There is no way to detach the profiler from your javascript yet.
- The control window is ugly. So is the report window.
- The percentage value is not really usable at the moment, since we don’t measure the function’s “own time” yet.
Getting it, license and patches
For now, there is no code repository, but this will change soon. In the meantime, here are some pointers for obtaining the source code:
- Get the profiler.js and ruby snippet via github
License is MIT. That means, do whatever you want to do with it, we don’t care. But there are no warranties.
Please send patches to tkadauke [:.4t.:] imedo [:.d0t.:] de. Use the comments below to ask questions, suggest improvements or to report bugs.
Have fun profiling your apps!
Popularity: 1% [?]
