Using GreyBox in your HTML Applications: The Unobtrusive JavaScript Solution | WebReference

Using GreyBox in your HTML Applications: The Unobtrusive JavaScript Solution

By Rob Gravelle


Today we're going to continue along the path that we started on last time as we looked at various ways of altering Orangoo's GreyBox library to work with HTML Applications (HTAs). The common thread throughout the solutions presented was that they all necessitated making changes - albeit minor ones - to the main GreyBox gb_scripts.js file. Some might argue that it's not a good idea to modify the library source. Reasons include that our changes could create unforeseen bugs in the library's behavior, or future upgrades could cause problems in porting our changes to the new version. For these reasons, it may be desirable to make the changes in a local script, so that they only apply to that specific HTA. Today I'd like to present just such a solution, using AJAX and the DOM scripts collection.

Technically, Unobtrusive JavaScript pertains to the separating of content from behavioral elements such as scripts, but I would suggest that the practice of leaving external libraries "as-is" as much as is realistic be a part of the unobtrusive philosophy. The solution that we will be reviewing here could have just as easily been written in VBScript since HTAs are a Microsoft technology. However, I chose to use JavaScript instead so that the technique could be extended to any web application or web page that makes use of JavaScript libraries and require some customizing of their behavior.

The JavaScript Execution Model

One of the advantages that interpreted languages such as those used in scripting have over those that are compiled is that the former can run dynamically generated code at runtime. In JavaScript, this is accomplished using the eval() function. It accepts a string parameter, which it tries to execute as code. The key word is "tries" because the string has to be valid JavaScript syntax in order to run. The same conditions that apply to any JavaScript code are applicable here as well, so any errors that can occur during runtime can be thrown by the eval() function:

With respect to the loading of dynamic code, performing string operations such as cut & paste on source code can be utilized to manipulate code that is unavailable to the rest of the page. That is exactly the case here, because the d variable that we want to alter is private to the initFrame() function. In fact, any variable created within a function using the "var x" declaration style is private.

Should you be hesitant about using a language feature to access private variables, remember that we were already modifying the script in a text editor. By extension, any modifying of source code can be considered to be un-OOP. It is standard operating procedure to avoid altering existing methods in code because of the risk of breaking dependent components. In Java proper, one way to preserve the code is to encapsulate the new functionality in a second function of the same name, using a different signature. Then the old function calls the new one with the default value. This is called function overloading. In the following example, the Account class contains a method called openAccount(). It sets the opening balance at 0 and sets the type to the AccountType SAVINGS enum:

All is well, until a change request comes in to provide the ability to open a different kind of account. Rather than change many function calls, one would create an overloaded method of the same name, which accepts an AccountType parameter. The existing code can then be transferred over to the new function and the old one would now call it by supplying the same value as before. That way, the original functionality is preserved, but the function can also perform additional processing based on the AccountType parameter:

In JavaScript, function overloading is not an option, so we need another way to link functionality with a condition. Taking advantage of the JavaScript execution model, we will simply load the appropriate function within our page.

Switching the gb_scripts.js File with Our Local Modified Version

We'll modify the same file that we created in the last article because that will allow us to quickly verify whether or not we were successful in loading up the HTA-compatible version of the gb_script.js file:

Comment out the original <script type="text/javascript" src="greybox/gb_scripts.js" id="SS"></script> line and replace it with the following as demonstrated above: