views:

259

answers:

1

feel free to skip down to the question below

I'm trying to create a bridge so a huge javascript application can be replaced by a new Silverlight-based rewrite as smoothly as possible.

In the legacy application, there is this JS class:

function LatLng(lat, lng, url) { /* snip... */ }

And it is being used a lot throughout my customer's codebase like this:

var ll = new LatLng(12, 34, '567');

However, as the bridge in Silverlight is required to be backwards-compatible and that it be done with maximum maintainibility, I decided to re-create the LatLng class as a ScriptableType in Silverlight:

[ScriptableType]
public class LatLng { /* similar snipped stuff ... */ }

As I go about re-implementing the methods in the class in Silverlight/C#, going so far as to asked and implement this delegate util. Which had allowed me to wire calls from the Javascript side right into the Silverilght runtime with 0 change, by doing this:

var x = new LatLng() // <-- constructor now calls into Silverlight
                     //     and ask for methods to be wired into it

Unfortunately, this approach doesn't work with property getters/setters as there is no such concept in JavaScript (at least not in every major browser yet), the only way to get property getters/setters to work is to let the Silverlight runtime be the one creating the wrapper for my class

i.e. an instance must be created from the Content.services.createObject in JavaScript:

var ll = silverlightObject.Content.services.createObject("LatLng");

This single change, will requires all existing users of the application to go-over their entire codebase in order to upgrade... not good at all


The Problem

Is there a way to re-wire the new operator in Javascript to returns an instance from another function instead?

var ll = new LatLng(13, 100)
/*        ^
          ^
   should returns instance created from
   silverlightObject.Content.services.createObject
*/

And there are 2 gotchas:

  • createObject is a Silverlight-managed function, Function.apply or Function.call does not work
  • The result from createObject is a wrapper, which you cannot iterate over (thus me asking for the delegate util in the first place)

I hope that there is a way out without really having to walk every customers through changing the way LatLng are created...

If you have any ideas please kindly share it here, I've been trying to get this ironed out for the last week to no avail :-(

A: 

The new command in JavaScript represents an instance of a function without actually using the base function. This is important to protect a function's inner mechanisms from interference in expectation of reuse.

To circumvent the new command I would transform the LatLng function into a method. A method is a function that is executed using dot notation for the purpose of modifying a variable with a stored value. The original LatLng function contained 3 arguments. When rewriting LatLng rewrite to take only the first two arguments so that the variable that will be activating the method can contain what was originally the third argument.

var ll.LatLng(13, 100);

But remember the variable should have a value before any method is executed against it or it is likely to throw an error. That is why I recommend the original third argument of LatLng instead be used a the value of the variable prior to use of the method.

That is the same as calling the createObject method directly. A simple method rename is an option but that still requires existing codebase to be changed.
chakrit