Blog


Trivial JavaScript

I've been chatting with the Free Software Foundation and they've posed a tricky question: What is trivial JavaScript? - or - What is not trivial JavaScript?

It seems like an especially hard question to answer - especially without using subjective terms.

For example I would say that the following are all trivial:

  • Use of inline JavaScript/DOM 0-style code (ex. onclick="...").
  • Use of unobtrusive scripting to layer on basic page behaviors (ex. Twitter).

Whereas the following are sufficiently complex as to be deemed not trivial:

  • Applications that do Ajax requests to a server-side component (ex. GMail).
  • Applications where the majority of the initial download is executable code (ex. 280 Slides).
  • Applications that are unable to function without the use of JavaScript (ex. Google Maps).

But this brings up the question: What about poorly-designed pages that have a small amount of JavaScript but are unable to function without the use of JavaScript? I'd still deem it trivial.

And what about sites that are somewhere in-between? For example Netflix has a significant amount of unobtrusive JavaScript on their site but I would hardly consider it to be trivial (pop-ups, Ajax-loading, all sorts of unobtrusive interaction).

Is there a tangible line that is crossed on the road to complex JavaScript development? Is it an externality like storing script in a separate file (ex. <script src='...'></script>)? or is it inside the script itself like in using Function prototypes or closures? It feels like the measure should be put upon an external source (as to not make restrictions upon what someone could, or couldn't, write using the language) but what would the proper external measurement be?

Thoughts?

Tags: javascript

Writing ECMAScript 4, Today

A very cool new utility has just been released by Olav Junker Kjær called Mascara which is an ECMAScript 4 to JavaScript translator (written in Python).

Using this utility you can begin writing ECMAScript 4 code today, receiving its full benefits (such as IDE integration and compile-time type-checking) while still being able to run the resulting code in all modern browsers.

A simple demonstration is up on the Mascara web site which provides a view into the translated source code, along with run-time (and inline) error messages.

A full break-down of the features currently supported are:

  • Type verification
  • Classes and inheritance, constructors, super initializers
  • Static members
  • Type inference from initialization
  • Parameterized types, Map and Vector
  • Union types
  • Structural types
  • Getters/setters
  • Namespaces
  • Nullable types

Definitely be aware, however, that while the above feature list is more than enough to get started there are still a a few items left to be implemented.

The most important question, when looking at the above code, should be: How do I begin using this today? Olav went ahead and made it easy to do IDE integration - even setting up instructions on how to integrate with Eclipse on Windows (he currently shows how to integrate using the JScript command-line interface, but it can easily be expanded). I'm quite excited by this prospect - having the ability to do compile-time type-checking and be able to succinctly write classes with inheritance will be a major boon to development.

Additionally, he provides information on how to do automatic CGI translation (naturally, you would want to do this only in a development environment).

He's continuing to provide frequent updates on the Mascara blog - be sure to follow along if you're interested in starting to use ECMAScript 4 sooner, rather than later.

Tags: javascript, ecmascript, python

Recent Presentations

During the past couple weeks I've given a number of talks around the globe. Here's a quick dump of the talks for those that are interested in them.

  1. jQuery (BarCamp Boston)
  2. Processing and Processing.js (BarCamp Boston)
  3. jQuery (MeshU)
  4. Managing the Mozilla Way (Slashdot, ITWorld)
  5. jQuery (DrupalCamp Toronto)
  6. JavaScript 1.5 to 2.0 - A new talk examining all the language features introduced by the various versions of JavaScript (and the upcoming features of JavaScript 1.9 and 2.0).
  7. JavaScript Libraries (Kings of Code)
  8. JavaScript Libraries (@Media)
  9. jQuery (BostonPHP)

For the jQuery talks here are the demos that I used:

I want to thank the above conferences and venues for inviting me to speak, it was a lot of fun. I want to thank everyone who attended my talks - it was great to be able to see everyone and get tons of excellent feedback. I'm definitely looking forward to my next batch of speaking.

Tags: speaking, conferences, presentations, javascript, jquery

__FILE__ in JavaScript

A quick snippet that I spotted within the up-and-coming Johnson project (A Ruby/Spidermonkey hybridization.):

(function(){
  this.__defineGetter__("__FILE__", function() {
    return (new Error).stack.split("\n")[2].split("@")[1].split(":").slice(0,-1).join(":");
  });
})();

The above defines a global variable __FILE__ which, when called, returns the file name of the current JavaScript file. It's defined using a getter in particular so that the proper file name will be determined no matter what file it's called in (so you can safely include the above in a library file and it'll still report the correct, current, filename).

Currently the above will only work in Spidermonkey as only it supports the .stack stacktrace Error property. If there are reasonable alternatives for WebKit or Opera (which also support __defineGetter__) let me know.

Tags: javascript, ruby, spidermonkey

Processing.js Tower Defense

I'm currently in the process of touring the globe (I've given four talks in two cities, have two talks in two cities left) but I dug up something that should prove to be a lot of fun.

Will Larson has gone about revising the classic Tower Defense genre, porting it to the open web using Processing.js. The port is pretty basic still - but it definitely offers a lot of promise (and is a ton of fun to play, to boot!).

» Play Processing.js Tower Defense

He's written a full post describing the construction of the game (which he did in JavaScript using the Processing API).

Will has been a machine - writing tons of demos and articles on Processing.js. Feel free to read through them to get a better feel for what you can do with the library.

Update: After a minor hiccup the game is working again (there was some problems with mouse input). Thanks Will!

Tags: games, javascript, processing

Injecting Word Breaks with JavaScript

Recently Eduardo Lundgren pinged me wondering if I had an alternate solution to injecting wbr tags inside a long word.

The wbr tag tells the browser where a possible line break can be inserted, should the need arise. (Opera has some problems with rendering them correctly, but it can be rectified using some CSS.) By adding wbr tags into words at strategic locations you can allow a content area to resize gracefully while still being readable.

I looked at his simplified solutions for a moment and came up with this solution:

function wbr(str, num) { 
  return str.replace(RegExp("(\\w{" + num + "})(\\w)", "g"), function(all,text,char){
    return text + "<wbr>" + char;
  });
}

You would use it like so:

wbr("Hello everyone how are you doing?" +
  "I'm writing an extravagently long string.", 6);

"Hello everyo<wbr>ne how are you doing? I'm writin<wbr>g an extrav<wbr>agently long string."

Now this is an incredibly simple solution and having breaks like writin<wbr>g are quite undesirable. After I wrote the above I did some more digging and read about various hyphenation algorithms that exist.

Looking in the above article I found a recent JavaScript library which provides a full solution (breaking in appropriate places for multiple languages). Of course, the resulting code checks in at about 80kb (15kb base library + 65kb English word library) so you'll need to strongly consider if that solution is appropriate for your situation.

Tags: javascript, words, language

postMessage API Changes

It's been a little while since I last wrote about Cross-Window Messaging in Firefox 3 using postMessage and since that time it's since a few API updates.

Specifically the postMessage API has become much simpler and has stronger security brought into mind.

If you're unfamiliar with postMessage here's a quick re-cap: It's a way to communicate simple string-based messages across browser windows (this includes frames, iframes, and popups). It's a part of HTML 5 specification and is included in Firefox 3, Internet Explorer 8, WebKit Nightlies, and Opera 9.5.

Here's the revised process works using the final postMessage API (currently only works in Firefox 3):

Sending

Sending is still done by calling the postMessage method on a window object. The one addition is that an extra targetOrigin argument is now required. This argument allows you to specify the exact origin that you're expecting this message to reach (this can help prevent malicious attempts to redirect the contents of frames to intercepting pages).

It's highly recommended that you provide an origin, but if you don't wish to you can specify "*" instead (which will work for any origin).

Demo: http://ejohn.org/apps/message/

<iframe src="http://dev.jquery.com/~john/message/" id="iframe"></iframe>
<form id="form">
  <input type="text" id="msg" value="Message to send"/>
  <input type="submit"/>
</form>
<script>
window.onload = function(){
        var win = document.getElementById("iframe").contentWindow;
        document.getElementById("form").onsubmit = function(e){
                win.postMessage(
                        document.getElementById("msg").value,
                        "http://dev.jquery.com"
                );
                e.preventDefault();
        };
};
</script>

Receiving

The primary change to receiving is that you must now listen for the incoming event on the window object, instead of the document. This is a smart API change (keeping document/window straight would've surely caused implementation problems).

Additionally, in the incoming event object, there use to be a number of properties made available for determining the origin of the request. Now, however, there is only a single property: event.origin. This property contains the base origin from which the request is coming.

For example in the above demo the full URL is "http://ejohn.org/apps/message/" but the event.origin is just "http://ejohn.org". It's highly recommended that you verify the incoming origin of the request in order to prevent any malicious attempts to inject data.

Additionally, even though it's not done below, it's important to do some validation on the incoming message contents. It's entirely possible that the origin page may have been compromised so you'll need to take that into consideration.

Demo: http://dev.jquery.com/~john/message/ (Use the above demo to see this page in action)

<b>This iframe is located on dev.jquery.com</b>
<div id="test">Send me a message!</div>
<script>
window.addEventListener("message", function(e){
        if ( e.origin !== "http://ejohn.org" )
                return;

        document.getElementById("test").textContent = e.origin + " said: " + e.data;
}, false);
</script>

I'm pleased with these changes and I'm glad that there were able to make it in to Firefox 3 in time. I hope we see some more implementation convergence here as it would be really good to have all four browsers with an HTML 5 feature in it.

Tags: security, javascript, browsers, firefox

Title Capitalization in JavaScript

The excellent John Gruber recently released a Perl script which is capable of providing pretty capitalization of titles (generally most useful for posting links or blog posts).

The code handles a number of edge cases, as outlined by Gruber:

  • It knows about small words that should not be capitalized. Not all style guides use the same list of words — for example, many lowercase with, but I do not. The list of words is easily modified to suit your own taste/rules: "a an and as at but by en for if in of on or the to v[.]? via vs[.]?" (The only trickery here is that “v” and “vs” include optional dots, expressed in regex syntax.)
  • The script assumes that words with capitalized letters other than the first character are already correctly capitalized. This means it will leave a word like “iTunes” alone, rather than mangling it into “ITunes” or, worse, “Itunes”.
  • It also skips over any words with line dots; “example.com” and “del.icio.us” will remain lowercase.
  • It has hard-coded hacks specifically to deal with odd cases I’ve run into, like “AT&T” and “Q&A”, both of which contain small words (at and a) which normally should be lowercase.
  • The first and last word of the title are always capitalized, so input such as “Nothing to be afraid of” will be turned into “Nothing to Be Afraid Of”.
  • A small word after a colon will be capitalized.

He goes on to provide a full list of edge cases that this script handles.

My Perl is a little bit rusty but I worked through the code and ported it to JavaScript.

You would use the above code like so:

titleCaps("Nothing to Be Afraid of?")
"Nothing to Be Afraid Of?"
titleCaps("Q&A With Steve Jobs: 'That's What Happens In Technology'")
"Q&A With Steve Jobs: 'That's What Happens in Technology'"

I hope this code will be useful to some - I suspect that it'll be easy to plug into most blogging software (without having to worry about messing around with the server-side code), or even useful as some sort of bookmarklet.

Tags: javascript, blog

Next entries » · « Previous entries

JavaScript Books

Secrets of the JavaScript Ninja

JavaScript Secrets

Secret techniques of top JavaScript programmers. Coming Fall 2009.

Pro JavaScript Techniques

Pro JavaScript

The best techniques for professional JavaScript. Published by Apress.

Micro Updates

John Resig Twitter Updates

@jeresig

Infrequent, short, updates and links.

JavaScript Jobs



Hosting provided by: Ruby Hosting by Engine Yard