Friday, September 25, 2009

No "Add-in Express 2009 for Internet Explorer and Microsoft .NET" for you!

As mentioned in my previous post "Developing IE addons is infuriating!", I was attempting to get a free copy of "Add-in Express 2009 for Internet Explorer and Microsoft .NET for Visual Studio 2008 (C#)" from Add-in Express Ltd. through their "blog review" program.  Alas, it seems that my fledgling blog did not meet any of their three criteria to qualify for such a benefit:
  1. It has not been around for over 1 year.
  2. It does not yet have a strong follower base.
  3. It does not show up with a high ranking on Google search results (for some magical search they must run to qualify this).

Guess that was just a pipe dream.  Back to being confused out of my mind on how IE Addons development in .NET works....

Thursday, September 24, 2009

Unraveling the pitfalls of JS inheritance

So with the aid of a colleague and the good ole O'Reilly "JavaScript: The Definitive Guide, Fourth Edition" book, I pinned down a previously unexplainable problem with the JS inheritance work I was doing.  Basically, I was trying to create a base widget that more complex widgets would inherit from — pretty standard inheritance idea.  Here's the basic code concept to illustrate....

MyNs.BaseWidget = function()
{
    this.parentElement = null;
    this.childWidgets = [];
};
MyNs.BaseWidget.prototype.AddChildWidget = function(childWidget)
{
    this.childWidgets.push(childWidget);
};
MyNs.BaseWidget.prototype.Draw = function()
{
    this.DrawSelf();
   
    for (var c = 0; c > this.childWidgets.length; c++)
    {
        var childWidget = this.childWidgets[c];
        childWidget.Draw(); 
    }
};

MyNs.ComplexWidget = function()
{
    // Some new properties of no consequence
};
// The next two lines chain prototypal inheritance
MyNs.ComplexWidget.prototype = new MyNs.BaseWidget();
MyNs.ComplexWidget.prototype.constructor = MyNs.ComplexWidget;


// Create objects!
var myChildWidget = new MyNs.ComplexWidget();
myChildWidget.parentElement = document.getElementById("childDiv");

var myMainWidget = new MyNs.ComplexWidget();
myMainWidget.parentElement = document.getElementById("parentDiv");
myMainWidget.AddChildWidget(myChildWidget);
myMainWidget.Draw();


Now what happened was by far the most confusing thing I've ever encountered: the "parentElement" property on each object was set correctly; however, the "childWidgets" property on myChildWidget (which should've been of length 0) was actually identical to myMainWidget's "childWidgets" property (which had a length of 1).  While confusing, the real problem here is that it spawned an infinitely recursive loop when invoking the Draw method as there was always one child widget to draw regardless of the context of "this".  I noodled on that problem for a few idle days before my colleague and I finally stumbled upon the reasoning in our quest to solve the problem today (yay for pair programming as needed and the fact that I actually asked him to look at it with me).  The scoop follows!

The prototypal inheritance model of JavaScript with regard to inherited properties operates under the following basic rules:
  1. Rule #1: If the derived class never modifies the inherited property, any "read-only" references to that property will actually use the property from the base class instead.
  2. Rule #2: If the derived class directly modifies the inherited property, it makes a copy of the base class's property for itself and masks its ties to the base class's property.  However, if the derived class's copy of the property were to be deleted (destroyed from memory), trying to access said property will again link to the base class's property.
  3. Rule #3: If the inherited property is never modified (so the derived class still points to the base class's property) and it is INDIRECTLY modified (e.g. childWidgets.push({})), the call to grab the property itself is seen as a read-only reference and therefore pulls the base class's property and then updates that.

Now knowing this, such a folly can easily be solved with some code changes in red as follows....


MyNs.BaseWidget = function()
{
    this.parentElement = null;
    this.childWidgets = null// was: = [];
};
MyNs.BaseWidget.prototype.AddChildWidget = function(childWidget)
{
    if (this.childWidgets == null)
    {
        this.childWidgets = [];
    }
    this.childWidgets.push(childWidget);
};
MyNs.BaseWidget.prototype.Draw = function()
{
    this.DrawSelf();
    if (this.childWidgets != null)
    {
        for (var c = 0; c > this.childWidgets.length; c++)
        {
            var childWidget = this.childWidgets[c];
            childWidget.Draw();
        }
    }
};

MyNs.ComplexWidget = function()
{
    // Some new properties of no consequence
};
// The next two lines chain prototypal inheritance
MyNs.ComplexWidget.prototype = new MyNs.BaseWidget();
MyNs.ComplexWidget.prototype.constructor = MyNs.ComplexWidget;


// Create objects!
var myChildWidget = new MyNs.ComplexWidget();
myChildWidget.parentElement = document.getElementById("childDiv");

var myMainWidget = new MyNs.ComplexWidget();
myMainWidget.parentElement = document.getElementById("parentDiv");
myMainWidget.AddChildWidget(myChildWidget);
myMainWidget.Draw();


Here we see that by not having the property declared in the base class's constructor (except to null, which is not its intended value), but rather instantiating it in the first call to the "AddChildWidget" method (which will be invoked an instance of the derived class), we have fallen into Rule #2 rather than Rule #3 as before: now the new derived instance is creating an instance of this array for itself.  Success!

Final word: it should be noted that, although my example here focuses on hierarchical chaining ("composite" design pattern), the problem described here would show itself just as easily when there are two derived instance objects on the page at the same time even if they had no direct relation to each other.  The only thing that makes it more evident in a hierarchical chaining example like this one is the unfortunate introduction of an infinitely recursive loop.  ;)

Friday, September 11, 2009

Aspirations of true agile practices in JavaScript development

My team regularly develops JavaScript for our piece of the application, but has struggled until recently to get decent test coverage of our JS code.  In an effort to see what the ideal state of such things could be, I've setup a website on my local IIS 7 instance with the following set of tools that I believe would satisfy the needs of doing real TDD/agile practices with JavaScript development: JSUnit, JSMock, JSCoverage, and the JSDoc Toolkit.  We'll see how it goes!

Note that for JSUnit, the download links are sadly out of date.  You must drill into the SourceForge trunk of the codebase in order to get a remotely recent version.

Wednesday, September 9, 2009

Can't wait for my inheritance!

I am busy trying to figure out the best way to do reliable class inheritance in JavaScript without importing a third party library OR extending the prototype of a core JavaScript class (e.g. function).  Amongst a great variety of blog posts, forum answers, and random articles, I am finding Douglas Crockford's Prototypal Inheritance in JavaScript and Classical Inheritance in JavaScript the most useful in terms of edification thus far.

Other interesting resources

Quick practical examples:
http://phrogz.net/JS/Classes/OOPinJS2.html


Overriding instanceOf to make it work for derived types:
http://www.webreference.com/programming/javascript/gr/column18/3.html

Poor man's "reflection" on "classes":
http://webreflection.blogspot.com/2007/01/javascript-getclass-and-isa-functions.html

Microsoft's take on the subject (related to their ASP.NET AJAX libraries):
http://msdn.microsoft.com/en-us/magazine/cc163419.aspx


Continuing the hunt....

Tuesday, September 8, 2009

It's a new dawn, it's a new day, it's a new life...

And I'm feeeeeeeeeeling... good!

Officially conquered the non-IE browsers today, including the highlighting feature.  Struggled with the implementation of the highlighting feature in IE, but got the barebones of it working by the end of the day.  The IE implementation, however, has an odd intermittent bug that I haven't quite nailed down reproduction steps for yet that basically boils down to a character offset being like 5-6 characters off — completely unacceptable in the final implementation, of course.

Going to try to work that one out tonight so that I can show off the prototype tomorrow (per my manager and director's individual requests).

There are unresolved issues in all browsers, mainly the "line break" dilemma.


Update #1:
Turns out this has to do with moving a TextRange along. If you want to move by characters and the next character (or first character to be in the range) is a space, it gets all screwed up. Investigating workarounds.... 


Update #2:
Came up with a [thus far] consistently working hack of a workaround. Basically, when the range's selection and the currentNode's nodeValue do not match, I recollapse to the start and then try to grab the whole nodeValue plus an arbitrary amount of characters (currently 10) to push the buffer along farther. Once it's moved, I then see how many characters the range encompasses and then move the end point backward by the difference in the expected range versus actual range.

The more annoying part about the TextRange.move/moveStart/moveEnd functions is that they are supposed to return the actual number of characters moved. Turns out they just seem to repeat back the number of characters they were supposed to move (presumably unless you are at the end of the document)... with the padding I added, mine was moving 3 less characters than it should have, but still reporting that it moved the whole span.

Do your worst, Firefox!

Argh, another night of coercing the non-IE browsers' JavaScript engines into doing my bidding.  Getting ever closer now... pretty soon this spike will be worthy of being called a successful first crack at a real implementation.  I'll have to add a slew of JSUnit tests before declaring it as such, though!

Thursday, September 3, 2009

Developing IE addons is infuriating!

So, I've been working on this C# addon for IE off and on for a few months.  After a frustrating search for information coming up pretty dry, I was able to piece together a working version of the addon in IE7.  However, just as I was about to release it, one of my coworkers tried it in IE8 — and, of course, it didn't work!  I believe it has to do with IE8 handling the notion of the "active tab" differently.  In IE7, the active tab automatically became the first tab.  In IE8, I don't think the same behavior is happening but I haven't yet had a chance to verify it (using Spy++ or whatever).

Anyone know?  Any which way, I would like to try out Add-in Express Ltd.'s Add-in Express 2009 for Internet Explorer and Microsoft .NET for Visual Studio 2008 (C#), which several people have suggested to me.  I'm going to contact the company tonight to see if they will give me a free version to try out through their "blog review" program.  Wish me luck!

What's new with the Team?

Currently working on:
  • Advanced cross-browser "find" engine in JavaScript (ETA: ?)
  • IE7/IE8 Internet Explorer addon for internal bug reporting (ETA: Sept. 2009)
  • Microsoft .NET "Windows-Based Client Development" certification (ETA: Sept. 2009)
  • Masters of Science in Software Engineering (ETA: May 2010)

Hello, world!

Sorry, I just had to do this as my first post. ;)