Archive for the 'JavaScript' Category

Slides from JSConf

Tuesday, April 28th, 2009

I'm back from the most excellent JSConf (JavaScript Conference) in Washington D.C. I'm tired and need sleep but the conference was, hands down, the best conference I've ever attended. It was all about the community, it was inexpensive, with parties all around, both speakers and attendees were treated exceptionally well, in fact there wasn't a big difference since attendees presented just as good content on the B-track as did the A-track.

Here are my slides, "High Performance Kick Ass Web Apps (the JavaScript edition)". I changed the slides on the night before the presentation (and after the first night's party). The thing is that I was halfway through the slides and approaching 90 slides and I realized there's no way I will deliver so much content. One day... I'll prepare my slides way in advance and will actually practice delivering the talk...

 

Relative to absolute links with JavaScript

Tuesday, March 17th, 2009

I was toying with a completely different thing and specifically a Yahoo service that gives you the ability to use HTML as data and then lets you use xpath to query this data. I came up with a somewhat interesting idea (will post tomorrow, too late now), but all of a sudden I realized I need to convert relative links to absolute ones. I thought it's just a trivial thing (I mean how hard could it be) but then it turns out there are these little edge cases...

Anyway, I came up with something and posting here in case someone else might need it (or even me, for example two years from now. Hmm, will there be URLs in the future, in the distant 2011, or we'll all be just pure non-material consciousness ?)

So, the test page is here

And the actual code (also on github) is as follows:

function toAbs(link, host) {

  var lparts = link.split('/');
  if (/http:|https:|ftp:/.test(lparts[0])) {
    // already abs, return
    return link;
  }

  var i, hparts = host.split('/');
  if (hparts.length > 3) {
    hparts.pop(); // strip trailing thingie, either scriptname or blank 
  }

  if (lparts[0] === '') { // like "/here/dude.png"
    host = hparts[0] + '//' + hparts[2];
    hparts = host.split('/'); // re-split host parts from scheme and domain only
    delete lparts[0];
  }

  for(i = 0; i < lparts.length; i++) {
    if (lparts[i] === '..') {
      // remove the previous dir level, if exists
      if (typeof lparts[i - 1] !== 'undefined') {
        delete lparts[i - 1];
      } else if (hparts.length > 3) { // at least leave scheme and domain
        hparts.pop(); // stip one dir off the host for each /../
      }
      delete lparts[i];
    }
    if(lparts[i] === '.') {
      delete lparts[i];
    }
  }

  // remove deleted
  var newlinkparts = [];
  for (i = 0; i < lparts.length; i++) {
    if (typeof lparts[i] !== 'undefined') {
      newlinkparts[newlinkparts.length] = lparts[i];
    }
  }

  return hparts.join('/') + '/' + newlinkparts.join('/');

}

Update: added a check for ./ in the URLs thanks to QA from Boštjan

 

FireEagle and geo-location fun

Thursday, March 12th, 2009

fireeagle logo

FireEagle is a newer service from Yahoo, it's an API and service that stores your geo-location and lets other application read or update it. With your permission, of course.

Now there's a FireEagle Firefox extension, still marked experimental in Add-ons.Mozilla.org so you need a free AMO account in order to download it.

Once you install it, it will lead you through installing a prerequisite - the Geode extension from Mozilla Labs which checks the WiFi networks that are available to you and figures out where you are. The FireEagle extension then uses Geode to get the location and update its database. Of course you have full control over how precisely you want to share your location (exact, zip, neighborhood, city, state, country).

So what then? Well, then there's the FireEagle api and a bunch of applications using it to do all kinds of stuff, like update you Facebook profile and so on. Also the extension is just one way to figure out your location, there are also other ways like iPhone apps.

Geo-location via JavaScript

What I found fascinating is that once you have Geode, pages can request your location via JavaScript. This is actually a w3c standard.

A simple example of logging the position object - just type into Firebug's console:

navigator.geolocation.getCurrentPosition(console.log)

A warning appears that the page has requested you location and you can say No! or you can allow a degree of access - exact, neighborhood or city.

geo warning

Once you allow access, an async process kicks in and your callback (in this case console.log) gets notified when the location information is available. The callback receives a "position" object which has properties such as latitude, longitude, velocity, accuracy...

Pretty neat stuff.

 

Content-to-markup ratio bookmarklet

Thursday, March 5th, 2009

When you care about performance, or SEO (or just doing a good job as web dev) an interesting data point is the ratio of page content vs. the markup used to present this content. Or... how much crap we put in HTML in order to present what the users want to see - the content.

So I played tonight with a bookmarklet to provide this piece of stats.

Install

Right-click, add to favourites/bookmarks. Or simply click to see the ratio of this page.

content/markup

How it works

Since the scripts on the page may modify the content and markup, the bookmarklet makes an Ajax request to get a fresh copy of the page from the server. Then it runs a few regular expressions ("borrowed" from prototype.js) to strip all tags and the scripts/styles content. The first metric it provides is the size of the stripped content divided by the size of the original markup.

Then the bookmarklet tries to be more fair and count the alt, title and value attributes as content, including the size of attribute names themselves. And this is the second, "fair", metric. The content attributes are inspected using DOM methods, not regexp, so they can be affected by any javascript that has modified the page. Oh well, life's not fair.

Code

The bookmarklet code is served from here. The code is also on github.

Results

Here are some random results of running the bookmarklet on different sites.

http://www.cnn.com:

Total size: 92004 bytes
Content size: 11475 bytes
Content-to-markup ratio: 0.12
Fair ratio * : 0.16

http://www.sitepoint.com

Total size: 65989 bytes
Content size: 16199 bytes
Content-to-markup ratio: 0.25
Fair ratio * : 0.60

Article on http://en.wikipedia.org:
Total size: 21648 bytes
Content size: 3315 bytes
Content-to-markup ratio: 0.15
Fair ratio * : 0.35

http://www.phpied.com

Total size: 31899 bytes
Content size: 7933 bytes
Content-to-markup ratio: 0.25
Fair ratio * : 0.48

http://www.google.com SERP
Total size: 29963 bytes
Content size: 3351 bytes
Content-to-markup ratio: 0.11
Fair ratio * : 0.14

 

Replace the Home button with a script

Tuesday, March 3rd, 2009

Robert Ames commented on my previous post suggesting replacing the Home button with my little site search bookmarklet. I didn't even know this was possible, but I found it pretty cool, so I just had to try.

x-browser

I tried this in Firefox/Mac and IE/Windows and it works just fine.

ok, what is it?

Well, the idea is simple: when setting the homepage in your browser, instead of providing an http://... URL, you can use the javascript:... pseudo-protocol. So for example you can type:

javascript:alert(document.title)

And then every time you hit the Home button in the browser, an alert with the page title will pop up. How cool is that!

Naturally, you can replace the simple javascript with any sophisticated bookmarklet of your choosing (hint, hint)

how-to

In Firefox on the Mac you go Firefox / Preferences. On Windows: Tools / Options. Then in the Main tab, you type/paste the bookmarklet code.

Setting the Home to a javascript bookmarklet in Firefox

For IE/Windows go Tools / Internet Options and select the General tab

Internet Explorer - setting the Home button to a javascript bookmarklet

 

Search site bookmarklet with YUI and BOSS

Saturday, February 21st, 2009

Ever wanted to search only the web site you're currently on? Not the page, but the whole site. And only this site, not the rest of the web. This bookmarklet does just that.

Install

Right-click this link and add to your bookmarks/favorites. Or just drag to your bookmarks toolbar.

search site

Or if you don't want to add the bookmarklet, you can simply click the link above and try it out.

Use

You can search any site. Just visit the site and click the bookmarklet. There's also keyboard navigation to move up/down the results. The search results display as you type and the first results is highlighted so you can just press Enter and follow the first match of your query.

Here's a short video that shows how you can use the bookmarklet to search my blog.


search site bookmarklet @ Yahoo! Video

Under the hood

The bookmarklet uses YUI and BOSS to do its magic.

YUI (Yahoo User Interface) library's Dom, Event and Get utilities make a task like this so much easier.

BOSS (Build your Own Search Service) is a mildly confusing name for Yahoo Search's API second major iteration. The API allows you to specify a site (or sites) that you want to limit your search query.

The bookmarklet simply includes searchsite.js served from here; the bookmarklet was generated with the help of this bookmaker.

Show me code!

It's on GitHub, right here under the searchsite directory, it's just one script file searchsite.js, not at all documented, but I hope you'll make sense of it.

 

JSLint on Mac + TextMate integration

Saturday, February 21st, 2009

UPDATE: Ryan Grove has a better script to display the JSLint results. So basically follow the instructions here until you get to Step 2, point 5 (where you write the command to run JSLint). Then head over to Ryan's blog post to get the better script.

JSLint is an indispensable tool if you're serious about your JavaScript code quality. You can run it online for curiosity but for real development it has to be part of your coding environment and just a click/keystroke away.

While on PC I integrated JSLint with my text editor of choice - TextPad - and shared here. Now, ladies and gentlemen...[drum roll] I give you...[bzfghgang!] JSLint on the Mac!

Prerequisite: get Rhino running on your OSX

Don't worry, it's pretty straightforward, described here

Step 1: get JSLint

The Rhino version of JSLint is here. It's just one JS file. Find an appropriate place to copy it, I think ~/Library/JSLint is as good as any.

$ mkdir ~/Library/JSLint
$ curl http://jslint.com/rhino/jslint.js > ~/Library/JSLint/jslint.js

Test how it works from the command line:

$ java org.mozilla.javascript.tools.shell.Main ~/Library/JSLint/jslint.js myjavascript.js

Step 2: integrate with TextMate

TextMate extensions work their magic through the so called bundles. Here's what you do.

  1. Select menu: Bundles / Bundle Editor / Edit Commands...
  2. In the list of commands, expand JavaScript
  3. Click the + sign found under the list, select New Command
  4. type the name "jslint"
  5. Replace the contents of the Command(s) text field with
    java org.mozilla.javascript.tools.shell.Main ~/Library/JSLint/jslint.js "$TM_FILEPATH"
  6. In the Input: dropdown select "Entire Document", in the Output: "Show as Tool Tip" or "Show as HTML"
  7. In Activation, click on Key Equivalent and then select a key combination you like, for example Command + L (L for Lint)
  8. And this is it, refer to the screenshot below to compare with what you just did. Close the bundle editor window and you're done

textmate bundle editor

Now test your new shiny tool. Open a javascript file and press Command+L. Here's a sample output:

JSLint results in TextMate

And after fixing the missing semi-colon:

jslint fixed

 

Installing Rhino on Mac

Friday, February 20th, 2009

To quote http://www.mozilla.org/rhino/:

Rhino is an open-source implementation of JavaScript written entirely in Java. It is typically embedded into Java applications to provide scripting to end users.

Rhino allows you to use JavaScript:

  • on the server-side, so you can ditch RoR, Perl, PH... well, keep PHP :) ... in favor of JavaScript
  • on the command line, so you can shell scripts

Let's see how you can install Rhino on OSX.

Step 1 - download and unzip

Download the binary from the Rhino site and unzip to a temporary directory, say /tmp. On the command-line:

$ curl ftp://ftp.mozilla.org/pub/mozilla.org/js/rhino1_7R1.zip > /tmp/rhino.zip
$ cd /tmp
$ unzip rhino.zip

Now you have the file /tmp/rhino1_7R1/js.jar

Step 2: move js.jar where Java can find it

Your default Java install (comes "free" with OSX) will look for class libraries in a predefined directory ~/Library/Java/Extensions. This directory may not exists, so create it and move the js.jar there.

$ mkdir ~/Library/Java
$ mkdir ~/Library/Java/Extensions
$ mv /tmp/rhino1_7R1/js.jar ~/Library/Java/Extensions/

Step 3: Done! Now test it

That's all there is, your Rhino install is ready to use. To launch and test the Rhino shell try:

$ java org.mozilla.javascript.tools.shell.Main
Rhino 1.7 release 1 2008 03 06
js> print('hello!')
hello!
js> parseInt('123abc')
123
js> encodeURI('hola LA!')
hola%20LA!
js> for (var i = 0; i < 5; i++)
  > print('i is now ' + i)
i is now 0
i is now 1
i is now 2
i is now 3
i is now 4
js> quit()

Last example - create a script that reads the HTML source of my blog:

$ echo "print(readUrl('http://phpied.com'))" > read.js

now you have a script called read.js, let's run it:

$ java org.mozilla.javascript.tools.shell.Main read.js

Thanks for reading!

And happy JS-scripting!

 

>>> $$(selector)

Friday, January 30th, 2009

Gotta love the Firebug console, how can anyone not love the Firebug console. It makes testing random pieces of JavaScript a breeze and best of all - you're playing with the live page. Your page or any page for that matter.

Two nice shortcuts you can use in the console are $ and $$.

The first is like document.getElementById() and the second allows you to get elements by using a selector, like w3c's document.querySelectorAll(), now available in the latest browser versions, including IE8.

So go ahead, give $$ a try. For example you can visit yahoo.com, open up the console and try:
>>> $$('.first')
or
>>> $$('.patabs .first')
or
>>> $$('#tabs1 li')

Lots of fun!

So here's a little example application I came up with, it spits out unused selectors from your CSS. Just paste it in the multi-line console.

for(var i = 0; i < document.styleSheets.length; i++) {
  for (var j = 0; j < document.styleSheets[i].cssRules.length; j++) {
    s = document.styleSheets[i].cssRules[j].selectorText;
    if ($$(s).length === 0) console.log(s);
  }
}
 

smush.it update

Sunday, October 26th, 2008

What's new in smush.it?

  • The old domain smushit.com now redirects to the new one smush.it, which is what we originally intended but the domain registration took a while and we quickly got smushit.com just in time for the Ajax Experience announcement of the tool
  • There's a bookmarklet version of the Firefox extension so you can now run in IE or any other browser capable of bookmarking
  • There's an FAQ
  • The API, while not really documented, is at least described in the FAQ
  • So is the privacy policy. People said we should have privacy policy, we're not lawyers, so we couldn't write something that sounds important. The policy is basically: 1) we won't use the images you upload in any way other than gathering aggregated optimization statistics (how much we save on average, how many files get smushed daily...). 2) Images will be deleted from the server, once we get around to writing some sort of stats script, so download the optimized zip asap, don't rely on it being there for long. 3) The images you upload are available to anyone who can guess the random URL smush.it creates, so don't upload images you want to keep private
  • Flash 10 support, updated to YUI 2.6's flash uploader and sweated a lot to make the uploader work in the tightened flash 10 security, but that's a whole other blog post
  • Smu contest! What's a Smu? We want to know too. Send us you idea of a Smu to smu at smush.it
 

Short Amazon affiliate links – a bookmarklet

Sunday, October 19th, 2008

It's a pain to link to a specific product on Amazon if you have to use their UI to build an affiliate link. It's good to have nice, clean and short affiliate links. This post gives you the details and also a bookmarklet to built the links by visiting the product page you want to link to.

Anatomy of an Amazon affiliate link

Let's see the anatomy of a link in its shortest possible form.
Basically you have:

  • http://www.amazon.com/ - self-explanatory, I think
  • /dp/ - standing for "details product" or maybe "details page"
  • /1847194141/ - a 10 character product code, aka ASIN code, Amazon Standard Identification Number
  • ?tag=affiliatecode-20 - your affiliate code, or tag

For example my Amazon affiliate code is w3clubs-20, and an affiliate link to my book would be:
http://www.amazon.com/dp/1847194141/?tag=w3clubs-20

Amazon also uses longer search engine friendly URLs containing the book title, like:
http://www.amazon.com/Object-Oriented-JavaScript-Stoyan-Stefanov/dp/1847194141/?tag=w3clubs-20

But the book title/product name doesn't really matter, so this is fine too:

http://www.amazon.com/War-and-Piece-by-Stoyan-Stefanov/dp/1847194141/?tag=w3clubs-20

So I went ahead and created a bookmarklet that lets you visit the product page you want to link to, click the bookmarklet and copy a short affiliate URL.

Install the bookmarklet

Drag the link below to your favorites/bookmarks or right-click and add to favorites. Then right click the new bookmark and change its properties, replacing my Amazon affiliate code "w3clubs-20" with yours.

Amazon aff

After installing the bookmarklet, just go to any Amazon product page, click the bookmarklet and it will create an affiliate link for you to copy.

The bookmarklet code, readable version

Here's the code for the bookmarklet, simply find the ASIN (product code) and build a new URL with it.

(function(){
    var aff = 'w3clubs-20';
    if (!document.getElementById('ASIN')) {
        alert('Can\'t find the product ID');
        return;
    }
    var asin = document.getElementById('ASIN').value;
    prompt(
        'Here is the link:',
        'http://www.amazon.com/dp/' + asin + '/?tag=' + aff);
})()

Misc

There's a page in the Amazon affiliates section that let's you check if the links are OK, it's here

Sometimes you might see (usually for non-book products) URLs that instead of /dp/ have /gp/product/, but if you build /dp/ links it's totally fine, according to their link checker, see previous paragraph.

 

Javascript console in IE

Saturday, October 18th, 2008

I'm a sucker for consoles. The ability to quickly type some code and see it executed right then and there... priceless. That's why I'm a huge fan of Firebug's JavaScript console. But what about IE?

option 1 - Firebug lite

Firebug lite is a lighter version of the proper Firebug which runs in browsers other than Firefox. You "install" the bookmarklet and voila - JavaScript console and other goodies are available on any page.

You visit any page and click the "Firebug lite" bookmarklet...
firebug lite bookmarklet

... then you hack away in the shiny console!
firebug lite bookmaklet in action

option 2 - built-in MS script editor/debugger

If you do any javascript in IE, it's a good idea to have this debugger guy enabled. There's actually at least three different debuggers, but one of them is already installed without you lifting a finger. If you enable it, you can debug any time there's a JavaScript error on the page. It also features a console! You can't get to the console unless there's a JS error, so you may need to cause the error yourself. Here's the step-by-step scenario.

Go to menu Tools / Internet Options... / Advanced tab. Under the "Browsing" category uncheck the box that says "Disable Script Debugging"
set the IE options

Go to any page and cause an error, by typing in the address bar some non-existing property or some non-existing object for example. Like javascript:alert(a.a.a)
Go to anypage and cause an error

Non-surprisingly, you get an error, but now you have the option of debugging the error:
A error and a debug option

You're given a list of debuggers, in case you've installed more debuggers from MS. Select your debugger or just hit Yes:
pick a debugger

Just say OK here...
step into procedure

Click "Break"...
Break

Finally - a console! We're in! The console is the so-called "Immediate" window, which is not displayed by default. To see it go to menu Debug / Windows / Immediate. Then just start fiddling with the page. Type anything and hit enter to see it evaluated. You also list the properties of an object by typing its name, like document.images[0] or just document.
Fiddle with document.images[0]

Once you've had your fun, stop debugging:

Enjoy the results of your hard work, a.k.a. replacing some logo with a shot of your favorite book ;)
your fav book

 

JavaScript’s class-less objects

Thursday, October 16th, 2008

javaranch newsletter

"JavaScript's class-less objects" article up at the JavaRanch's newsletter.

Update: and mentioned on Ajaxian, sweet.

 

OOJS book free chapter 8 on YUIblog

Friday, September 26th, 2008

Chapter 8 of the Object-Oriented JavaScript is available at the YUIblog.com. Enjoy!

Chapter 2 is also available at the publisher's site.

Probably thanks to YUIBlog, the book was #7#6 in the JavaScript category on Amazon today, not bad. It's the highest I've seen it, not that I'm obsessed with checking sales rank. It's the journey, not the destination :)

Other than that.. pretty busy lately. Off to Boston for Ajax Experience next week, where I'll be giving 3 (three!) talks. Will have some good stuff to share after that - ppts and a new tool!

 

location=location

Saturday, July 26th, 2008

location = location
... and 534 other ways to reload the page with JavaScript

How many ways you can think of when you want to reload the current page with JavaScript? I counted 535 before I got bored, maybe someone can pick up from there? The cases are so much that I had to write a script to generate them :)

» have fun, see for yourself

Just occurred to me that I didn't even include the frames property in those 535 ways. Consider the limitless possibilities having in mind for example that:

>>> window.frames === window
true
>>> frames === window.self
true

Could you come up with 500 more ways? A 1000? One condition: no recursion, for example window.self.window is not allowed.

 

The book, the book

Friday, July 25th, 2008

OOJS is almost officially out. I mean it's out officially, but not yet up on amazon, which these days means it's not really out, is it. It will probably take a couple more days, maybe next week.

So far there has been a great interest, even enthusiasm, expressed by people running web dev sites who would like to do a review, I'll list the reviews and give link love back as soon as I see the published reviews. If you're interested in reviewing the book on your web site/blog, doing an interview with me or something to that effect, pitch the idea to me (ssttoo at gmail) with your URL, etc, I'll promptly forward to the great marketing folks at my publisher, Packt.

Thanks!

OOJS

 

My online footprint lately

Wednesday, July 23rd, 2008

This is a sort of a catch-up post for listing what I've been up to lately.

  • YUI Blog just published my first article, I'm so proud. It's about loading JavaScript in non-blocking fashion, because JavaScripts, they, you know, like, block downloads. Luckily, there's an easy fix - DOM includes, which I've previously discussed, discussed and discussed.
  • SitePoint published an update to my older article that introduces AJAX, ok, Ajax, by creating a command-line-like interface with PHP on the server side. The updated article features improved code, jQuery example, YUI example, JSON discussion and example. Check it out, bookmark and recommend to your friends that keep asking you "What's this AJAX (they are new, don't know it's now spelled "Ajax") thing? Do you know of a good article?"
  • YDN (developer.yahoo.com) published a video presentation of me and my lovely teammate Nicole Sullivan where we talk about some new and cool front-end performance techniques. So if you wandered how I look and are eager to hear my fabulous Balkan peninsula accent, give it a shot. The talk is called "After YSlow 'A'" and is targeted at those of you who have reached performance nirvana, but are still hungry for more. We talk about preloading components, post-loading, javascript, images, using flush() in PHP to send first byte early on and other fun stuff.
  • Last, not least, I decided to try and find some time to update my JavaScript patterns site. Unfortunately I got sidetracked (yep, I'm easily distracted by shiny objects) and played with a not-so-javascript pattern. The post I published (includes a pretty lame screencast! and) demonstrates how you can use animated background position to indicate loading progress.

Whew, c'est tout pout ce moment, expect a lot more now that the JavaScript book is out of the way. Ah, yep, if you feel like it, join me on Facebook, I created a JS book page.

 

The JavaScript book is almost there

Wednesday, July 16th, 2008

Whew, after a whole year of writing, preparation, edits, blood, sweat, tears, I finished all the latest edits and reviews for my new book, Beginning Object-Oriented JavaScript. It should be out any day now. I can't be happier!

cover.png

You can pre-order with 10% off from the publisher's site.

 

Load a photo in a canvas, then flip

Saturday, May 3rd, 2008

zlati-nathalie.jpg

Today our family went to the yearly photo session with the girls. We took one shot that can be looked normally, as well as upside down, so I was wondering can you flip an image using a canvas tag. Turns out, yes, you can and it's pretty easy.

» Demo is here.

How to load an image in a canvas tag?

Start unpretentiously with an empty canvas tag:

<canvas id="canvas"></canvas>

Now the javascript. Two variables to store a handle to the canvas element and the 2D context of the canvas:

var can = document.getElementById('canvas');
var ctx = can.getContext('2d');

Now let's load an image into the canvas. Using the new Image() constructor you can create an image object, then set its src property to point to the location of the image file. Then set an onload handler for the image which is an anonymous function to be called when the image is done loading. There you put the image inside the canvas using the drawImage() method of the canvas context.

var img = new Image();
img.onload = function(){
    can.width = img.width;
    can.height = img.height;
    ctx.drawImage(img, 0, 0, img.width, img.height);
}
img.src = 'zlati-nathalie.jpg';

You can also notice how the dimensions of the canvas are adjusted to match the dimensions of the image.

How to flip the image upside down

The canvas context provides a rotate() method. The rotation always happens around the top left corner of the image, so we first translate() the image to the bottom right. This way when the image is rotated, it fits back into the canvas. (There is also a one pixel correction, I have no idea why, just saw that the image wasn't flipping exactly otherwise). Assigning this functionality to the onclick:

can.onclick = function() {
    ctx.translate(img.width-1, img.height-1);
    ctx.rotate(Math.PI);
    ctx.drawImage(img, 0, 0, img.width, img.height);
};

C'est tout! Once again, the demo is here.

 

strftime() in JavaScript

Friday, April 25th, 2008

Philip "Bluesmoon" Tellis has posted a tiny (under 3K minified) JavaScript library to format dates, inspired by PHP's strftime()

Examples:

d.strftime('%Y/%m/%d')
» en: 2008/04/25
» fr: 2008/04/25
» de: 2008/04/25

d.strftime('%A, %d %B')
» en: Friday, 25 April
» fr: Vendredi, 25 Avril
» de: Freitag, 25 April

There's also a demo to fiddle with.

I've previously had fun with kinda like the opposite: translating human-readable times into JS Date objects. Also here and here you have strtotime() look-alikes that take human-readable dates and turn them into Date objects.

 

When client-only validation is good for business

Sunday, April 13th, 2008
You should never never ever rely on client-side validation only. Client-side validation is for enhancing user experience, server-side is the validation. This is a rule, never to be broken. But here's a funny story how skipping the server-side validation actually helped.

This is a real story, but the actual names have been replaced in XXX, just not to make other people look bad :D

There is this site called xxxxxxxxx.com that charges you $XX membership access. Having just moved from Canada, last year I didn't have a US credit card to pay the fee and tried to use my Canadian visa. Problem: the input field for postal code (zip code) accepts 5 characters only, since the zip codes in US a like 90404, 90066 and so on. A Canadian postal code is like H0H-0H0 or H0H0H0, six characters. So seemed like I couldn't pay online. Or could I?

Checking the source code with Firebug gives me this:

client.png

From here it's trivial to change maxlength attribute of the input. Even with IE it's super easy just to type in the address bar something like:
javascript:document.getElementsByName('XXXXXXX')[0].maxLength = 100;

So I did change it, typed my Canadian CC#, Canadian postal code and submitted the form, crossing fingers that the developers who built the site were too pressed by deadlines to do a proper server-side validation. Lo and behold, it worked!

At the end with the help of an innocent client-side tweak I got what I needed (membership), xxxxxxxx.com got more business, and everybody's happy.

There's a lesson in this: sometimes being too strict in data validation for things that don't matter is just in your way.
And another: don't assume all your potential clients are from US.

 

JSPatterns.com up again

Wednesday, March 26th, 2008

After getting 300 megs of wiki content spam, I deleted the old wiki over at http://www.jspatterns.com.

Now restarted the project as a blog with static pages for the javascript patterns and blog posts for anything interesting in the ever so exciting world of JavaScript. So far nothing special there (example), but keep an eye on it, as I plan to fill up the TOC (recovered from the old wiki) with top quality content ;)

I suck at design and wasted two nights to come up with some custom wordpress theme for the new blog. I like the result, but that's just me. I also made the theme available for download, in case someone wants to consider it for a future project.

Talking of spam, yesterday my host deleted 2 gigs!!! of email spam from my hosting account, how crazy is that.

The new JSPatterns.com is running the latest release candidate WordPress 2.5, slick stuff.

 

JoJo: Javascript Junk generator

Tuesday, March 25th, 2008

Ever needed to be able to generate random, but valid JavaScript code? Well, today is your lucky day: meet J.J. or JoJo, the Javascript Junk code generator.

All you need to specify is how many kilobytes of code you need. Available also as a web service.

» tools.w3clubs.com/jojo

If anyone can think of any application of JoJo, other than performance experiments, I'll be most intrigued to hear it.

 

sleep() in JavaScript

Monday, March 24th, 2008

PHP has a sleep() function, but JavaScript doesn't. Well, this is because it's useless, you might say, and you'll be right. But for simulating heavy processing and for misc performance measurements, it could be useful. So here's how you can go about creating a sleep() in JavaScript.

The code

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}

Usage

Sleep for 1 second (1000 milliseconds):

console.log(new Date());
console.log('Dude!');
sleep(1000);
console.log(new Date());

Result in Firebug's console:

sleep.png

 

PHP-style $GLOBALS in Javascript?

Saturday, March 8th, 2008

Javascript has implied globals. When you skip the var in var a = 1; and go a = 1;, then a becomes a global variable. Some consider this an error in the language. Global variables should be avoided because they tend to overwrite each other in unexpected places, especially if the project grows in LOC and number of developers.

In PHP on the other hand, variables are local. If you need a global variable, then you have to have to be explicit about it using the $GLOBALS superglobal array.

So how about this: adopt the $GLOBALS convention in your JavaScripts? At the top of the script you go:

$GLOBALS = {};

Then every time you need a global variable, you do:

$GLOBALS['myglob'] = 1; // very PHP-like

or if you prefer:

$GLOBALS.myglob = 1;

Benefits of the approach:

  • global variables easy to spot (even from an aeroplane)
  • if it's not $GLOBAL, it's meant to be local. If it's missing the var, it's an error

Drawback:

  • It's a convention, so it can only help, but not enforce any coding practices

How many globals

Here's a quick test to check how many globals you have in a page.

(function(){
  var globs = 0;
  for (var i in window){
    globs++;
  }
  alert(globs);
})()

Run this script in your page without the scripts. Then add the scripts to the page run again. The result should be only one more global var if you followed the $GLOBALS convention.