Using Silverlight As a Replacement for Javascript Libraries

As organizations adopt Silverlight, it is unreasonable to expect that they will simply toss out their HTML-based web applications and replace them entirely with Silverlight applications. For most scenarios, the only reasonable approach will be to slowly begin utilizing Silverlight in hybrid web pages. Hybrid, meaning, mixed Silverlight and HTML.

One option in the hybrid model is to utilize Silverlight as a high-performance, relatively secure replacement for Javascript libraries. In this scenario, we embed a Silverlight application on the page, but make it invisible. We can then use the Silverlight browser bridging capabilities to expose one or more utility classes as scriptable objects to the browser.

In this post, I will walk through the steps required to do this with a simple Date Library example. I chose a Date Library because I wanted to mimic, but extend, the functionality in the ASP.NET AJAX Client Library’s extensions to the Date type.

There are six main steps to that I will demonstrate in implementing this functionality:

  1. Define a root ScriptableObject
  2. Define zero or more additional ScriptableTypes
  3. Expose the ScriptableObject in the Loaded event handler for your Silverlight application
  4. Make the Silverlight application invisible in the browser
  5. Get a reference to the root Scriptable object in the OnPluginLoaded event handler in the browser
  6. Use the library

1. Define a root ScriptableObject

To define a ScriptableObject is you first create a class that has been marked as scriptable by using the ScriptableType attribute. The screenshot below shows a simple class that formats a date. I will be extending the functionality of the class as I go though this demonstration.  I will show you how to expose this ScriptableType to the Javascript engine shortly.  

using System;
using System.Windows.Browser;

[ScriptableType]
public class DateLibrary
{
   [ScriptableMember]
   public string FormatDate(string format, int day, int month, int year) { ... }
}

Note also that any method you want to to expose to Javascript must be public and marked with the ScriptableMember attribute.

2. Define zero or more additional ScriptableTypes

For the purposes of this demonstration I also define a second simple ScriptableType that I will be using as a parameter and/or return type to methods I will be implementing in the DateLibrary class.

[ScriptableType]
public class DateLibrary
{
   [ScriptableMember]
   public string FormatDate(string format, int day, int month, int year) {...}

   [ScriptableMember]
   public string FormatDate2(string format, JSDate date) {...}
}

[ScriptableType]
public class JSDate
{
   [ScriptableMember]
   public int Day { get; set; }
   [ScriptableMember]
   public int Month { get; set; }
   [ScriptableMember]
   public int Year { get; set; }
}

3.  Expose the ScriptableObject in the Loaded event handler for your Silverlight application

In the Loaded event eventhandler you need to expose the ScriptableType defined in step 1 as a singleton to the Javascript world. The Silverlight plugin exposes this singleton as a property of its content property. We do this by calling the HtmlPage.RegisterScriptableObject function. Normallw we would also register any additional ScriptableTypes at the same time as follows:

private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
   HtmlPage.RegisterScriptableObject("DateLibrary", new DateLibrary());
   HtmlPage.RegisterCreateableType("Date", typeof(JSDate));
}

4.  Make the Silverlight application invisible in the browser

If you just want a library i.e. no UI from Silverlight, then all you have to do is hide plugin. A simple way to do this is to set the height and width of the div containing the plugin to zero. Do I really need to show you a code fragment to demostrate how to do this :) ?

5. Get a reference to the root Scriptable object in the OnPluginLoaded event handler in the browser

To call the functions in our library we need to get a reference to the singleton ScriptableObject that we registered in step 4. A typical way to do this is to hook the OnPluginLoaded event of the Silverlight plugin as follows:

   <script language="javascript" type="text/javascript">
      
var silver;     // Global reference to the Silverlight plugin
      
var dateLib; // 'Handle' to our library

      
function OnPluginLoaded(sender, args)
      {
         silver = $get("Xaml1");                          // Get a reference to the plugin
        
dateLib = silver.content.DateLibrary; // Retrieve our Scriptable object
     
}
   </script>
</
head>
<
body style="height:100%;margin:0;">
   <form id="form1" runat="server" style="height:100%;">
      <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
     
<div style="height:0;">
     
<asp:Silverlight ID="Xaml1"  OnPluginLoaded="OnPluginLoaded" ... />

6. Use the library

The last thing left to do is to use our new Silverlight library. This is just a matter of calling the functions exposed by our library. In that demo code that follows, I have examples of:

  • Calling a function with simple arguments and returning a string.
  • Calling a function, passing in a ScriptableType (note the call to the createObject function) and returning a string.
  • Calling a function that returns a ScriptableType.
  • Calling a function that returns a ScriptableType and then passes the return object back into Silverlight as the argument to a function.

function formatDate() {
   var day = $get("txtDay").value;
   var month = $get("txtMonth").value;
   var year = $get("txtYear").value;
   var format = $get("txtFormat").value;
   var res = dateLib.FormatDate(format, day, month, year);
   $get("results").innerText = res;
}

function formatDate2()  {
  
var dt = silver.content.services.createObject("Date");
   dt.Day = 11;
   dt.Month = 3;
   dt.Year = 1999;
   $get("results").innerText = dateLib.FormatDate2("D", dt);
}

function parseDateString() {
  
var dt = dateLib.StringToDate("1/1/2008");
   $get("results").innerText = dt.Year + "-" + dt.Month + "-" + dt.Day;
}

function dayOfWeek() {
  
var dt = dateLib.StringToDate("1/1/2008");
   $get("results").innerText = dateLib.Format2("D", dt) +" was a " + dateLib.DayOfWeek(dt);
}

The code for this demo can be downloaded from SoftSource's demo repository.

posted @ Monday, January 01, 0001 12:00 AM

Print

Comments on this entry:

# re: Using Silverlight As a Replacement for Javascript Libraries

Left by dirol at 5/28/2009 4:45 AM
Gravatar
And why does Adobe http://rapid4me.com/?q=Adobe need to have Javascript in their PDF reader?
Comments have been closed on this topic.
«March»
SunMonTueWedThuFriSat
28123456
78910111213
14151617181920
21222324252627
28293031123
45678910