Archive for 'Javascript'

setTimeout() require qualification

The two javascript functions above are very useful. The first one executes something after a set delay, and the second executes something at regular intervals. The syntax is very similar.

var time = 2000; // 2 seconds
window.setTimeout(function() { alert('Yay!'); }, time);
window.setInterval(function() { alert('Woo!'); }, time);

Unfortunately, they weren’t working for me earlier. It turns out I wasn’t fully-qualifying them. Specifically, I was calling setTimeout() rather than window.setTimeout(). The latter works.

Most examples use the abbreviated form, which consistently doesn’t work for me.

ECMAScript 4

John Resig has posted a whitepaper outlining the new features in ECMAScript4 (aka the Javascript standard), how it differs from ECMAScript3, and the rationale for any incompatibilities.

Many of the features have already made their way into Opera and Firefox, which is at Javascript 1.7 level. ES3 is equivalent to JS1.3, and ES4 is the basis for forthcoming JS2.

I look forward to optional strict typing, multiline strings, comprehensions, and generators making their way into browsers. A lot of the new features make Javascript more like Python without losing all the nice things tabout Javascript.

Creating Start Menu shortcuts with Javascript

While preparing the installer for the Web 2.0 Starter Toolkit for IBM DB2, I had to set up Start Menu shortcuts. The way to do that is to work through the Windows Scripting Host (WSH).

The WSH supports two built-in languages – VBScript and Jscript – and a theoretical number of third-party alternatives. VBScript is the better documented of the two in terms of examples, but I find its syntax ugly and constrained. Fortunately, Jscript can do anything VBScript can.

So here’s how we can create Start Menu shortcuts with Javascript.

Locate the Start Menu Programs folder

Most interesting Windows folders can be found by working with special folders

var shell = new ActiveXObject("WScript.Shell");
var startmenu = shell.SpecialFolders("Programs");

The shell object will be reused in code below, but you can redeclare it every time if you like.

Create a Folder

Scripting Guy has more details

var folder = "My App";
var group = startmenu + "\\" + name;

var fso = new ActiveXObject("Scripting.FileSystemObject");
if (!fso.FolderExists(folder)) fso.CreateFolder(folder);

startmenu is defined above.

Create an LNK Shortcut

The very hidden file extension of standard Windows shortcuts is LNK. This distinguishes them from website shortcuts, which have the equally hidden extension of URL.

If you are interested in something closer to the symbolic links of Unix, the NTFS equivalent is called junctions. You may find Junction Link Magic of interest.

var name = "My Shortcut";
var file = "myfile.txt";
var path = "C:\\Program Files";

var shortcut = shell.CreateShortcut(group + "\\" + name + ".lnk");
shortcut.TargetPath = path + "\\" + file;
shortcut.WorkingDirectory = path;
shortcut.Save();

See the full list of properties. I recommend always setting the working directory for application links. If you don’t, your program won’t be able to load resources from it’s installation folder.

shell and group are defined above.

Create a URL Shortcut

This is very similar. The main difference is that you set the extension to URL.

var name2 = "My Other Shortcut";
var address = "http://example.org/";

var shortcut = shell.CreateShortcut(group + "\\" + name2 +".url");
shortcut.TargetPath = address;
shortcut.Save();

See the full list of properties.

shell and group are defined above.

Locate Program Files

When creating shortcuts, it is often useful to know where a user’s Program Files directory is located. It is called different things in different versions of Windows, and some advanced users like to move it or rename it.

var REG_PF = "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ProgramFilesDir";

var progFiles = null;
var process = shell.Environment("PROCESS");
if (process)
	progFiles = process("ProgramFiles");
if (!progFiles)
	progFiles = shell.RegRead(REG_PF);

shell is defined in the first code excerpt.

Reflection in Javascript

It’s very easy to do reflection in Javascript. Reflection is when your code looks onto itself to discover its variables and functions. It allows two different Javascript codebases to learn about each other, and it’s useful for exploring third-party APIs.

Preamble

In Javascript, all objects are hashes/associative arrays/dictionaries. A hash is like an array, except that values are associated with unique key string rather than a numeric index.

Adding a new variable to an object is as simple as assigning a new value to a key in the object.

You can declare everything in place:

var o = {
	count: 0,
	name: 'Jane Doe',
	greeting: function() { return "Hi"; }
};
o.greeting();

Or you can start with a blank object and assign things later:

var o = {};

o.count = 0;
o.name = 'Jane Doe';
o.greeting = function() { return "Hi"; };

o.greeting();

Or you can do the same, but in a different notation:

var o = {};

o['count'] = 0;
o['name'] = 'Jane Doe';
o['greeting'] = function() { return "Hi"; }

o.greeting();

The last is especially handy because it allows you to go from the string name of the variable to the variable without the performance penalties of eval().

{} is synonymous with new Object().

Reflection

The loop below pops up a dialog box with the name and value of every variable in object:

for (var member in object) {
	alert('Name: ' + member);
	alert('Value: ' + object[member]);
}

Everything in Javascript is an object. Functions are objects! document and window are objects. The most reliable reference for Javascript in a given browser is reflection into its innards.

Finally, some slightly more useful code:

/**
	Returns the names of all the obj's
	 variables and functions in a sorted
	 array
*/
function getMembers(obj) {
	var members = new Array();
	var i = 0;

	for (var member in obj) {
		members[i] = member;
		i++;
	}

	return members.sort();
}

/**
	Print the names of all the obj's variables
	 and functions in an HTML element with id
*/
function printMembers(obj, id) {
	var members = getMembers(obj);
	var display = document.getElementById(id);

	for (var i = 0; i < members.length; i++) {
		var member = members[i];
		var value = obj[member];
		display.innerHTML += member + ' = ';
		display.innerHTML += value + '<br>';
	}
}

More sophisticated uses are left as an exercise for the reader. :-)