Saturday, September 20, 2008

Error page quirks in IE and Chrome

Here's another quirk of Internet Explorer and Chrome, the documentation of which is tough to find anywhere. In implementing the 404 error page on Resin, I came across a weird situation where FF, Opera and Safari would display the error page correctly but IE and Chrome would display their own error pages. This led to quite some frustration, having checked and rechecked all of the application and resin settings over and over.

It turned out that the only reason for this was that the size of the custom error page I had designed was lower than the threshold set by IE and Chrome for the 404 page. Basically, the error pages must be greater than 512 bytes to be viewable on all browsers. For IE, the settings of the error pages are stored in the registry at
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\MAIN\ErrorThresholds
The following image shows the registry entries for the various error codes in RegEdit:


The setting in Chrome (for 404) is tied into the source code and can't be modified just as easily. Check out the comment in this source code of Chrome around line 259.

// If it's a 404 page, we wait until we get 512 bytes of data before trying
// to load the document. This allows us to put up an alternate 404 page if
// there's short text.

Surprising that Chrome had this setting as well, especially considering that Safari also uses the same WebKit HTML and CSS rendering engine and it doesn't exhibit this quirk.

Cheers.

Wednesday, September 17, 2008

Reading Chrome's bookmarks in java

Google recently released Chrome, a browser based on WebKit (the same one used by Safari). The user interface is quite pleasant and so is its functionality. A few improvements need to be made (for eg.: addition of plugins, RSS feed reader, autofill in textboxes) before it endears itself to techies and common users. Its V8 engine definitely appears to make JavaScript run a whole lot faster than other browsers (even better than Opera in my tests). This video explains a little more on its architecture and working:
V8: an open source JavaScript engine

Having worked on synchronizing various user settings and files from within the major browsers (namely IE, FF, Safari, Opera and Konqueror), it was only natural I started breaking down Chrome and its settings. The first thing I've looked into is finding a way to synchronize its bookmarks. As of this writing, Chrome currently is built for only Windows XP and Windows Vista, with versions for Mac and Linux expected sometime in the near future. Chrome uses SqlLite databases to save all of the settings and preferences. The following blog entry provided some great insights into how the bookmarks are stored in these files:
Greg Duncan's blog

Enriched with the information from the link above, I found writing a java program to extract the bookmarks really simple. With the inclusion of the SQLLite Java wrapper and the corresponding JDBC driver binary, reading from the tables turned out to be a snap. The program was compiled in Netbeans 6.1 with Java 1.6 on a Windows Vista Home Basic edition.

You can download the entire netbeans project from the following link:
ChromeBookmarks.rar

Please feel free to use this code in any way you would like. Just don't point my way if anything crashes ;-)

Cheers.

Wednesday, August 27, 2008

JavaScript DOM property listeners

Here's a scenario.... Say we have an image on an HTML page that can be dragged and dropped anywhere within the browser window. Now, we need to perform some operations such as displaying the current location of the image as soon as the position of the image changes. The most common way of changing the position of an element in JavaScript is by modifying its style attribute's "top" and "left" properties. Now, we can detect such modifications in most current browsers by using functions available on the DOM elements. The syntax and working of these events is very different between the various browsers but suffice for most situations.

Basically, IE supports the "onpropertychange" event on DOM elements while FF and Opera support the "DOMAttrModified" event. Here's some sample code that's been tested in IE7, FF2 and Opera 9.5, that illustrates how these events can be used. Safari has no equivalent event in its repertoire, so the code below doesn't work in it at the moment.

function changeDivAttrs(){
var div = $("testDiv");
div.style.borderColor = "green";
}
function setWatches(){
var div = $("testDiv");
if(browser.IE)
div.setAttribute("onpropertychange",handleChange);
else
div.addEventListener("DOMAttrModified",
handleChange,false);
}
function handleChange(e){
if(browser.IE) {
//comment this line to view all attributes affected
if(event.propertyName == "style.borderColor")
showMessage(event.srcElement,
event.srcElement.id,
event.propertyName);
}
else //Firefox and Opera
showMessage(e.target,e.target.id,e.attrName);
}
function showMessage(element,id,propertyName){
alert(element + ":" + id + ":" + propertyName);
}
//HTML Section
< body onload="setWatches()" >
< div id="testDiv"
style="border-color:red;
border-style:solid;
border-width:2px" >
Test DIV Container
< /div >
< input type="button" onclick="changeDivAttrs()"
value="Change" />
< /body >
FF and Opera return the property name as just "style" while IE returns "style.borderColor" (kudos to the IE developers, for once!!!). Also, FF and Opera really watch for just changes i.e. the event is fired only when the previous value of the attribute is different from the new value. IE, on the other hand, fires every time the property is set or reset, even if the value hasn't really been modified. Additionally, comment the check in the function "handleChange" to see that the properties "borderTopColor","borderRightColor","borderBottomColor" and "borderLeftColor" are also getting affected.

Cheers.

Tuesday, August 26, 2008

Comet in ASP.Net

Comet, in general, is the technique of enabling server-side push instead of having client-side pull for refreshing information in the user's interface. The latter involves regular pinging of the server from the client to check for any changes that may have occurred on the server and send the corresponding information to update the user's UI accordingly. In applying Comet, one can notify the server-side changes to the client without the need of the constant pinging. Typical scenarios where Comet appears to have a relevant niche involve browser based chat applications, online collaboration and editing systems (such as GoogleDocs) and browser based web OSs.

Comet ties client-side JavaScript tightly with the server-side by having a long-running HTTP connection through which the server can push updates to the client as and when they occur. One technique that has worked well for me has been opening having one connection open in a hidden iframe on the page that's long-running. Another connection that sends information from the client up to the server is also established whenever corresponding user interaction takes place. This second connection opens and closes just like a regular HTTP request and can be performed using AJAX.

In an great example by Dave Ward at Encosia, he provides a very basic example of how the server can push data down to the client by using sleep states on the server. He performs a callback on the client by writing out pieces of JavaScript to the long-running connection, thus making it run within the iframe and, since its in the same domain, can call methods in the parent window to perform updates in the browser window. This and a number of other articles I read up elsewhere prompted me to try and use this technique in a real world application. The application I felt I could quickly demonstrate Comet was a chat application.

The image below shows the chat application in operation in two different browsers on the same machine. The example was written in Visual Web Developer 2008 using the Microsoft Dot Net Framework 3.5. The code works in FF2 and Opera 9.5 so far. Not too many optimizations have been performed as the goal of this was to just demonstrate a way in which Comet could work without having to switch to any "dedicated Comet" servers. The same principles could be applied in Java too where the two connections could be established with two separate servlets to achieve the same results. In case anyone would like to view the source code for this, email me at avinpr@yahoo.com.

Cheers.

Monday, August 18, 2008

Namespacing in JavaScript

Namespacing, in general, allows one to provide a context for the content to be declared in one's code. It helps resolve same name ambiguities by having variables, functions and even objects residing in different namespaces. JavaScript, unlike Java, does not have the "namespace" keyword as part of its standard list.

Now, there are different ways of defining namespaces in JS. The root namespace's name should be as unique as possible and should generally be having application scope, but there is no restriction present and can be named according to one's preferences. Before delving into more details, I think an example will give all a better idea on this. So, here goes:

var MyNameSpace = {};

MyNameSpace.MyClass = function(str){
this.name = str;
this.alertClassName = function(){ alert(this.name); }
}

//usage
with(MyNameSpace){
var myObject = new MyClass("Class1");
myObject.alertClassName();
}

Here, an object called "MyNameSpace" is created in the global(window) scope of things. Now, one must ensure that only one root namespace exists. There are a variety of ways one can do so but I shall not delve into those methods at this time.

The class declaration basically creates a property of the "MyNameSpace" object and hence declaration of any object created from this class must use the root namespace before an instance can be created. This also encapsulates the class("MyClass") and ties it to the root namespace and hence prevents name conflicts with any other included javascript classes or variables that may also have the same name "MyClass".

There exists other ways in which namespaces can be declared but I feel the example above is easiest to understand and implement. In case you feel otherwise, I'd like to know why.

Cheers.

Tuesday, August 5, 2008

JavaScript String Reversal

I was just surfing through some snippets when I came across some code for string reversal in JavaScript. Often people post code without having tested it themselves, which is just wrong!!! Here's a snippet I saw when going through one of these posts:
//NOTE: Non-functional JS code for string reversal
for (var i = 0; i < middle; i++) {
var temp = thestring[i];
thestring[i] = thestring[last-i];
thestring[last-i] = temp;
}
Now, one basic thing most people don't realize is that in JavaScript, individual characters of a string cannot be altered by using just the indexes. The above piece of code leaves the string unaltered not throwing any exceptions. The assignment to the individual characters is just ignored and "thestring" remains unchanged. Tested this in FF2, IE7 and Opera 9.51 and they all yielded the same result.

Since string reversal is a very common operation, it could be added to the String prototype if it makes sense. The following snippet does the job quite well, using two very useful functions available to arrays, reverse and join.
/* Full credit to Shachi Bista
http://www.bytemycode.com/snippets/snippet/400 */
String.prototype.reverse = function(){
splitext = this.split("");
revertext = splitext.reverse();
reversed = revertext.join("");
return reversed;
}
Now I prefer to always explicitly declare variables before using them. In this case, "splitext" and "revertext" become global members and could affect other variables that have the same name. Thus, to keep it localized, always explicitly declare the variable within the functions unless you want it to be available everywhere. So here's my revised version of it:
String.prototype.reverse = function(){
var splitext = this.split("");
var revertext = splitext.reverse();
return revertext.join("");
}
If you have a different approach or find a bug in my logic, do let me know.

Cheers.

Monday, August 4, 2008

JavaScript type checking and "isArray" function

Now javascript is a loosely typed language. What do I mean by that? It means just one "type" of variable exists in javascript represented by "var". Even declaring objects of your own type is done in the same manner. This is unlike Java or C++ in which the basic data types are declared as:
int a = 10; string b = "hello world"; ...

In JS, all variables (and even functions) can be referenced by using simple "var" declarations. For example, var a = 10; var b = "hello world";...

Now this causes a problem in checking the type of any object passed into a function. For example, when a function is expecting a string but the callee passes in an integer as a parameter, the function may falter. To do this, checking the type of the variable being passed in can help avoid unexpected errors and continue program execution even when an error occurs or using appropriate error handling capabilities (which I shall speak of on another post).

One of the most common operations when dealing with JSON(JavaScript Object Notation) during AJAX communications is the need to check if the returned object is a single object or an array of similar objects. For doing this there are a variety approaches:
function isArray(obj){
return obj && (obj.constructor == Array);
//return obj && (obj instanceof Array || typeof obj == "array"); //DOJO toolkit approach
/* if(obj.constructor.toString().indexOf("Array") == -1)
return false;
else
return true;*/
/* if(!obj || typeof obj == "string")
return false;
return obj.length != null; */ //had to use this for Nokia S60 browsers since constructor wasn't recognized
}

I found the first solution very concise and works on most modern browsers. A useful piece of information is that the "===" (triple equals to) checks for type equality compared to the "==" which checks only the values, which can be used in various other situations.

I'll leave this topic open to debate. There's no one perfect solution on every platform for this, primarily due to the differences in implementation in the various browsers.

Cheers.

Thursday, July 31, 2008

An Introduction

Hi folks.

I'm Avinash Prasad, a software engineer who's just starting to understand (I think) what software programming is all about. I've worked with a few technologies and programming languages but have never really mastered any. One reason I feel this is is because I never went back to examining what I had really done in any project. I wrote the code, made sure it worked, checked it in and then just forgot about it.

This is an attempt at understanding the code I shall be writing from now on and sharing my experiences with you folks. I may tackle some areas which may be of your interest and some that you may have never worked with. I may talk about some intricate problems with browsers or just muse about the latest addition to the Java programming language. Through this, I hope to help those in need of any information I may have and be able to share what I may know and others don't with the programming community at large. Hopefully, it shall also help me improve on my programming skills, so I may, someday, call myself a "Programmer".

Cheers.