Thursday, March 3, 2011

Silverlight SharePoint Web Part using the HTML Bridge

I recently ran across an issue with the HTML Bridge and conflicting behavior between IE and Firefox.

HTML Bridge info: http://msdn.microsoft.com/en-us/library/cc645076(v=VS.95).aspx

I had the following code in Silverlight to set a JavaScript variable to a Silverlight web part instance on a SharePoint page. By creating this variable I was able to call and pass in parameters into the Silverlight control from the JavaScript running on the page.

private static void InitializeReceiverJsVariable()
{
    string pluginId = HtmlPage.Plugin.Id;

    if (string.IsNullOrEmpty(pluginId))
        throw new Exception("No Silverlight Plugin found!  Ensure the Silverlight plugin has an ID!");

    string jsCode = string.Format("var {0} = document.getElementById('{1}').content.{0};", JS_VARIABLE_NAME, pluginId);

    HtmlPage.Window.Eval(jsCode);
}

Note: any Silverlight methods that you want call from JavaScript will need to have the [ScriptableMember] property on them. Alternatively you could create a class to house all your Scriptable methods and add the [ScriptableType] property to the whole class.

After compiling and deploying the web part to SharePoint, testing the JavaScript proved to be a success. Internet Explorer was allowing for communication between the Silverlight web part and the document library. Firefox was not allowing this. After several tests and some trial and error it turned out to be an issue with declaring the JavaScript variable from Silverlight. The solution was to declare the JavaScript variable on the page and just set the value from Silverlight instead of creating the variable too.

JavaScript addition:

var slWebPart = null;

Silverlight change:

private static void InitializeReceiverJsVariable()
{
    string pluginId = HtmlPage.Plugin.Id;

    if (string.IsNullOrEmpty(pluginId))
        throw new Exception("No Silverlight Plugin found!  Ensure the Silverlight plugin has an ID!");

    string jsCode = string.Format("{0} = document.getElementById('{1}').content.{0};", JS_VARIABLE_NAME, pluginId);

    HtmlPage.Window.Eval(jsCode);
}

After the change to the web part it worked in IE, Firefox, and Chrome. I still have not figured the exact issue or why you can’t declare the variable using the HTML Bridge, but the work around solved the problem. If you have come across this or know the technical reason, comments are always welcome.