Jaxer; Ameliorating IE8

January 23rd, 2008 by Leons Petrazickis

John Resig writes very positively about Jaxer. It runs Javascript on the server while serving documents to the client, with seamless communication between JS on the client and JS on the server.

Jaxer provides:

  1. Full DOM on the server
  2. Shared code between client and server
  3. Database, file, and socket access from JavaScript
  4. Familiar APIs
  5. Integration with PHP, Java, Rails, etc. apps

In other news, IE8 will use the latest rendering mode by default for documents with the HTML5 doctype:

<!DOCTYPE html>
 

Finally, Good Math has a published a good defense of Google’s MapReduce algorithm.

Posted in javascript, ajax, html | No Comments »

One step forward, two steps back

January 22nd, 2008 by Leons Petrazickis

After an internal build of Internet Explorer 8 passed the Acid2 test, they’ve announced that the new engine will only be used for sites with a special, opt-in meta tag:

<!– IE8 engine –>
<meta http-equiv="X-UA-Compatible" content="IE=8">
<!– latest engine –>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
 

It can also be triggered from the server via an HTTP header:

X-UA-Compatible: IE=8;
 

Firefox is unlikely to follow suit.

In other news, John Resig has done some testing on sub-pixel rounding across browsers.

Posted in javascript, css, html | No Comments »

Dean Edwards releases beta of base2

December 20th, 2007 by Leons Petrazickis

Base2 has just come out in beta on Google Code. It’s hosted there and can be included straight off the Google Code server.

I think it’s a really neat library because it basically fixes all browsers so that the built-in DOM, events, etc work the same way. Instead of providing an API of its own, it makes the existing API work consistently and reliably.

Base2 Features:
- A fast implementation of the Selectors API
- Fixes broken browser implementations of the DOM events module including document.createEvent(), dispatchEvent(), addEventListener(), etc
- Supports DOMContentLoaded
- Fixes getAttribute()/hasAttribute()/setAttribute() (Internet Explorer)
- Implements a few other useful DOM methods like getComputedStyle() and compareDocumentPosition()
- Supports a variety of browsers including ancient browsers like IE5.0 (Windows and Mac)

Dean Edwards has also done the excellent Packer Javascript minifier. It has probably the most in-depth support for obscure language features that simpler minifiers tend to mangle.

Posted in javascript, ajax, base2 | No Comments »

ECMAScript 4

November 8th, 2007 by Leons Petrazickis

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.

Posted in javascript | No Comments »

Creating Start Menu Shortcuts with Javascript

August 14th, 2007 by Leons Petrazickis

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.

Posted in javascript, windows | No Comments »

Behold, the Web 2.0 Starter Toolkit for DB2!

August 9th, 2007 by Leons Petrazickis

The Starter Toolkit is an easy way to deploy a WAD-on-PHP stack – Windows Apache DB2 PHP. It includes some neat functionality for generating Atom feeds from XML data in your DB2 databases, and some excellent REST-ful web service wrappers from tables and stored procedures.

I’ve spent my last few months tinkering with it, so do take a look. There should be a few posts about it coming down the line, from both external and internal perspectives.
Install Apache, DB2, PHP, and lots of goodiesControl Panel MenuCreate Atom FeedsCreate REST-ful PHP web services
How is it different from Zend Core for IBM? Well, the toolkit has the Atom stuff, and the web services stuff, and a bunch of helpful resources to help folks get started making apps full of Web 2.0-ey goodness.

We’ll be pushing out a fresh revision in double-time, so give me some feedback, consarnit!:-)

Posted in javascript, php, db2 | 1 Comment »

Using Safari Web Inspector on Windows

June 21st, 2007 by Leons Petrazickis

The latest nightlies of Webkit (development branch of Apple Safari) now have the web inspector in them. It doesn’t replace the tools in the other browsers, but it does have one very effective piece of unique functionality — a page load graph that gives an exact breakdown of order-of-loading and time-to-load of each script, stylesheet, and image.

First of all, enable the debug menu. It gives you access to the Javascript console and such things.

  1. Open C:\Documents and Settings\chng1me.T40-92U-V46\Application Data\Apple Computer\Safari
  2. Open Preferences.plist
  3. Insert the lines below mid-file:
        <key>IncludeDebugMenu</key>
        <true/>
 

Safari on lpetr.org
Open Safari by executing run-nightly-webkit.cmd in your Webkit install. Right-click and the inspect an element from the context menu.
Safari Web Inspector
Now, click on the icon in the bottom left-hand corner and choose Network.
Safari Web Inspector - Network mode
Voila!

Posted in javascript, css | 2 Comments »

Reflection in Javascript

May 11th, 2007 by Leons Petrazickis

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. :-)

Posted in javascript | 1 Comment »

When all you have is a hammer, perhaps you should contemplate acquiring a table saw

February 6th, 2007 by Leons Petrazickis

I had a an application that parsed an XML document and transformed it into a dojo.widget.Tree. This is how long it took with documents sized 15k, 34k, and 93k:


IE6 IE7 Firefox2 Opera9
15k 24 6 11 6
34k 69 11 21 21
93k 157 124

“Hmm,” I thought. “I don’t really need it to be collapsible or fancy. What if I replace the tree with a sequence of nbsp-indented lines and put that in via innerHTML?”


IE6 IE7 Firefox2 Opera9
15k 5 6 4 3
34k 14 11 19 10
93k

Then Internet Explorer 6 doesn’t look as pathetic as it is.

But why am I doing data munging in Javascript? The browsers seem to very unhappy about loading 93 kilobytes of XML into DOM. Would it be faster in PHP?


IE6 IE7 Firefox2 Opera9
15k 1 1 1 1
34k 1 1 1 1
93k 5 2 6 3

Yes. Yes, it would. 80x faster, in fact.

In conclusion, currently PHP is far faster for hundreds of kilobytes of data munging. Javascript is optimized for something else entirely — page management. Use it to move data around, but don’t transform with it.

Posted in javascript, php | No Comments »

Changing dojo.widget.TabContainer appearance

January 8th, 2007 by Leons Petrazickis

[Edit: This was written for 0.3. I will update shortly with correct procedure under 0.4.1]

TabContainer Customization
Speaking of dojo.widget.TabContainer being easier to customize, how do you customize dojo.widget.TabContainer?

There’s no need to fiddle with Javascript. A minor catch aside, it’s all straightforward CSS.

Take a look at its default CSS:

/* snip */
.dojoTab {
position : relative;
float : left;
padding-left : 9px;
border-bottom : 1px solid #6290d2;
background : url(images/tab_left.gif) no-repeat left top;
cursor: pointer;
white-space: nowrap;
z-index: 3;
}
/* snip */
.dojoTab div {
display : block;
padding : 4px 15px 4px 6px;
background : url(images/tab_top_right.gif) no-repeat right top;
color : #333;
font-size : 90%;
}
/* snip */

Well, that’s that. You just need to find tab_left.gif and tab_top_right.gif, copy them to your images/ directory, and tweak them to your liking. Once done, add code to your CSS that looks like this:

body .dojoTabPaneTab {
background: url(../images/tab_left.gif) no-repeat left top;
}
body .dojoTabPaneTab span {
background : url(../images/tab_top_right.gif) no-repeat right top;
}

The two catches are:

  1. I’ve added a body for a reason. It has to be more specific than the widget CSS, or the widget CSS will override it.
  2. Image paths in CSS files have to relative to the CSS file.

Oh, and if you think your CSS is being mysterious overridden in the greater cascade of stylesheets, you can stick in an !important thusly:

color:#000000 !important;

That forces the rule to win out over conflicting rules. It’s not a good practice, but it’s standards-compliant and helpful for debugging.

Posted in javascript, dojo | No Comments »

« Previous Entries