This page is likely outdated (last edited on 14 Jun 2007). Visit the new documentation for updated content.

MoonlightHostingNotes

These are some notes on Silverlight Hosting APIs and how the plugin works / should work. They are likely incorrect

Table of contents

Moonlight plugin

How it works

First step: create an <object> element of type application/ag-plugin

This is not mandatory unless you run silverlight apps written in Microsoft ways:

  • The web browser loads HTML, which contains “SilverlightControlHost” element.
  • SilverlightControlHost invokes “createSilverlight()” which is defined in the HTML’s bound Javascript.
  • createSilverlight() invokes createObjectEx() which is defined in silverlight.js.
  • createObjectEx() either creates an <object> element of type application/ag-plugin, or download/support links.
  • <object> element of type application/ag-plugin is recognized by the moonlight plugin.

We could just directly include such an <object> element in the HTML instead.

Second step: bootstrapping Silverlight control

It is done by moonlight plugin.

  • The plugin is triggered by the <object> element.
  • It loads the “source” XAML file. If there isn’t, then nothing is warned.
  • It looks for the implementation class from “x:class”, which looks like : “SilverlightProject1.Page;assembly=ClientBin/SilverlightProject1.dll”
    • If there isn’t, then Javascript warning is raised.
    • If the referenced type is not an expected type (only Canvas?), then Javascript warning is raised.
  • Create a GTK+ canvas for Silverlight object (indicated by “source”)

Hosting APIs

System.Silverlight.dll and Microsoft.Scripting.Silverlight.dll are involved.

Microsoft.Scripting.Silverlight is smaller:

  • ErrorHandler : static aggregated class of error handling which dispatch managed exceptions to browser.
  • HtmlDocumentMemberInjector
  • HtmlElementMemberInjector
  • IDlrNameScope
  • SilverlightPAL
  • SilverlightScriptHost
  • XamlDlrScriptHost

ScriptableObject

  • it is nothing to do with JavaScriptSerializer (methods and events are ignored in the serializer).
  • For now simple string and primitive types are supported as method parameters. (See below for details.)

How to enable ScriptableObject in managed code

  • Add ScriptableAttribute on the class, and property, method and events.
  • Call WebApplication.Current.RegisterScriptableObject(nameOnJS, instance).

How to use ScriptableObject in client Javascript

  • registered scriptable objects are accessible via document.getElementById (“SilverlightControl”).Content as its properties.
  • Properties are created as Javascript objects.
  • Events are created as event triggers which expects two arguments (sender, eargs).
  • functions are created as functions as they are.
  • Types are strictly limited: bool, string, char, numeric types except for Decimal are OK. No other types are allowed (object, Guid, DateTime, IDictionary<string,object>, any custom types). Only In parameters allowed.

Hosted environment

  • Every ScriptableObject seems to check its hosting environment. For example, HtmlPage.Document causes an error (NRE at alpha1) outside hosted environment (for example console app).

ScriptableObject injection

See also: http://www.silverlight.net/QuickStarts/Dom/ManagedCodeAccess.aspx

List for some objects/methods that need interaction from managed code to DOM:

  • ScriptableObject.GetProperty<T>(string name)
    • T must be derived from ScriptableObject. For example, HtmlPage.Document.GetProperty<object>(“documentElement”)
  • ScriptableObject.SetProperty(string,object)
  • HtmlObject.AttachEvent(string name,EventHandler handler)
  • HtmlObject.DetachEvent(string name,EventHandler handler)
  • generic way to invoke methods (e.g. getElementByTagName(), createElement() etc.)

Error handling

In agclr, System.Windows.ErrorEventHandler and ErrorEventArgs are used to handle errors at managed side.

Microsoft.Scripting.Silverlight.ErrorHandler is (in a sense) the closest API to the browser. It is tied to ErrorEventArgs in agclr and “default_error_handler” in silverlight.js, which

  • expects ParserError and RuntimeError as errorType (ParserErrorEventArgs/RuntimeErrorEventArgs in agclr)
  • expects errorCode, errorType and errorMessage (ErrorEventArgs properties)

Misc notes

  • WebApplication.Current is created and used to serve RegisterScriptableObject().
    • NPN_CreateObject() is likely used.
  • I’m not sure if SilverlightScriptHost and SilverlightPAL are created on silverlight apps. ScriptDomainManager.CurrentManager.PAL is not an instance of SilverlightPAL on silverlight apps.
  • static property HtmlPage.Document accesses to the document. It somehow causes NRE on non-silverlight app.

Implementation status notes

Already written as DllImport (note that they are not in moon/plugin yet):

  • WebApplication
    • InvokeMethodInternal(IntPtr xpp, IntPtr obj, string name,object[] args)
    • GetPropertyInternal(IntPtr xpp,IntPtr obj, string name)
    • SetPropertyInternal(IntPtr xpp,IntPtr obj, string name, object value); They are commonized accessors and used by several classes such as HtmlElement.AppendChild().
  • BrowserInformation
    • LoadBrowserInformation(BrowserInformation)
  • BrowserRuntimeSettings
    • LoadBrowserRuntimeSettings(BrowserRuntimeSettings)
  • HtmlObject
    • AttachEvent(IntPtr xpp, IntPtr obj, string name, EventHandler h)
    • AttachEvent(IntPtr xpp, IntPtr obj, string name, EventHandler<HtmlEventArgs> h)
    • DetachEvent(IntPtr xpp, IntPtr obj, string name, EventHandler h)
    • DetachEvent(IntPtr xpp, IntPtr obj, string name, EventHandler<HtmlEventArgs> h)
  • HtmlPage
    • Navigate (IntPtr npp, string uri)
    • Navigate (IntPtr npp, string uri, string target, string features) (returns a handle)
    • NavigateToBookmark (IntPtr xpp, string bookmark)
    • Submit (IntPtr xpp, string formId)

Just rough ideas:

  • WebApplication.Current is likely hold a pointer to NPP instance, a pointer to PluginInstance, and so on. Use AppDomain.GetData() to return pointers here.
  • WebApplication.RegisterScriptableObject() has to create a NPObject. Also, access to the members must be reflected to the managed object (and vice versa).
  • WebApplication.StartupArguments. Not sure what should be set here.
  • HtmlTimer. Probably it generates call to setTimeout() and calls Javascript eval(), depending on Enabled and Interval. Not sure where it is used.
  • HtmlPage properties:
    • Cookies, string
    • CurrentBookmark, string
    • Document, IntPtr to NPObject?
    • DocumentUri, string
    • QueryString, string or dictionary
    • Window, IntPtr to PluginInstance->window
  • HtmlElement.SetStyleAttribute() and RemoveStyleAttribute() ; not sure how it is done.