You can use Silverlight 2 to build full-page Windows Presentation Foundation (WPF)-like Web applications or to enrich HTML-based pages with additional features such as animations, advertising, and specific applets. The browser doesn't directly process the eXtensible Application Markup Language (XAML) content that makes up a Silverlight application. Instead, within the HTML page, an <object> tag points to the Silverlight 2 plug-in and has among its parameters the URL to download any necessary XAML resources.
The bottom line is that there's always an HTML page wrapped around a Silverlight plug-in, even though you often can't see it because the Silverlight application is configured to run in full-screen mode. In addition, the content hosted by the Silverlight plug-in is not isolated from the surrounding page in a same-site situation. When the Silverlight content comes from a different domain than the hosting HTML page, then it is indeed isolated from the page.
Silverlight comes with a browser interoperability layer that allows managed code to access the document object model (DOM) of the underlying page and register managed handlers for page-level events. At the same time, any JavaScript code running in the page can gain access to the XAML content of the plug-in and even make modifications. Finally, JavaScript code running in the page can also invoke managed functions as long as these functions are exposed properly. This month I'll discuss the browser interoperability layer of Silverlight 2 and the ways you can take advantage of it in your applications.
Configuring the Silverlight Control
As mentioned, the Silverlight plug-in is invoked through an <object> tag. However, this tag can be created for you by an ASP.NET control in ASP.NET pages. When you create a sample Silverlight application in Visual Studio 2008, the following markup for the Silverlight server control is automatically inserted in the test page:
<asp:Silverlight ID="Xaml1" runat="server"
Source="~/ClientBin/SilverTestApp.xap"
MinimumVersion="2.0.30523"
Width="100%"
Height="100%" />
The MinimumVersion attribute indicates the minimum version of the Silverlight runtime that is required to run the application specified in the Source attribute. Width and Height define the size of the Silverlight window with respect to the host page. As you can see, by default the Silverlight plug-in is configured to run in full-size mode.
Figure 1 lists the properties you can set to configure the Silverlight plug-in. The properties in Figure 1 refer to the Silverlight ASP.NET control that executes on the server side and spits out an <object> tag that may have differently named parameters or no equivalent parameters. For the purposes of this column, you should pay a lot of attention to the HtmlAccess property. (Note that this part of the Silverlight SDK changed a bit in the transition from Beta 1 to Beta 2.)
Figure 1: Properties of the Silverlight ASP.NET Server Control
|
Property
|
Description
|
|
AutoUpgrade
|
Indicates
whether the Silverlight plug-in should automatically be upgraded. The default
is false.
|
|
DefaultScriptType
|
The
default type of the client JavaScript object to
create and associate with the Silverlight plug-in. By default, it is Sys.UI.Silverlight.Control.
|
|
EnableFrameRateCounter
|
Indicates
whether to display the current frame rate in the hosting browser's status
bar. The default is true.
|
|
EnableRedrawRegions
|
Indicates
whether to show the areas of the Silverlight plug-in that are being redrawn
for each frame. The default is true.
|
|
HtmlAccess
|
Indicates
whether to allow the Silverlight application to access the page DOM.
|
|
InitParameters
|
Defines
an optional set of user-defined initialization parameters.
|
|
MaxFrameRate
|
Maximum
number of frames to render per second for the Silverlight document.
|
|
MinimumVersion
|
Minimum
version of the plug-in that is required for the current application. The
default is 1.0.
|
|
PluginBackground
|
Indicates
the plug-in background color.
|
|
PluginNotInstalledTemplate
|
HTML
markup to render if the Silverlight plug-in is not
installed.
|
|
ScaleMode
|
Indicates
how the Silverlight plug-in fills the available space: none, zoom, or
stretch. The default is none.
|
|
ScriptType
|
The
type of the client JavaScript object to create and associate with the
Silverlight plug-in.
|
|
Source
|
The
URL for the XAML source file or the Extensible Ajax Platform (XAP) source
package to download.
|
|
SplashScreenSource
|
The
URL of the splash screen document to render when the source document is
loading.
|
|
Windowless
|
Indicates
whether the Silverlight plug-in is rendered directly in the browser's client
area or within an aptly created window. The default is true.
|
The HtmlAccess property indicates the level of access to the underlying page DOM that the Silverlight application is allowed. The property accepts values from the HtmlAccess enumerated type. Values are listed in Figure 2.
Figure 2: Values to Control Access to the Page DOM
|
Value
|
Description
|
|
Disabled
|
The
application is not allowed access to the DOM of the underlying page.
|
|
Enabled
|
The
application is allowed access to the DOM of the underlying page.
|
|
SameDomain
|
The
application is allowed access to the DOM of the underlying page only if the
page comes from the same domain of the Silverlight XAP application. This is
the default setting.
|
Obviously, Enabled and Disabled are self-explanatory. The default setting is SameDomain, which doesn't inject any script in the page's markup. Note that a Silverlight application can be hosted in a page that is, in turn, hosted within a frame outside of its native domain. In this case, the Silverlight managed code is able to access the DOM of the host page in a cross-domain manner. Browsers have their own barriers to prevent cross-domain scripting, but they can't do much to stop the managed code within the Silverlight plug-in. Authors of Silverlight pages use HtmlAccess to control cross-domain access.
Accessing the DOM from Silverlight
Once access to the underlying page DOM has been granted, a Silverlight application can use the members on the static class HtmlPage to accomplish its own tasks. Figure 3 lists properties and methods of the HtmlPage class.
Figure 3: Members of the HtmlPage Class
|
Member
|
Description
|
|
BrowserInformation
|
Gets
general information about the browser, such as name, version, and operating
system.
|
|
Document
|
Provides
access to the document object of the page.
|
|
IsEnabled
|
Indicates
whether access to the page DOM is allowed.
|
|
Plugin
|
Gets
a reference to the Silverlight object.
|
|
Window
|
Provides
access to the window object of the page.
|
|
RegisterCreateableType
|
Registers
a managed type as available for creation from JavaScript code.
|
|
RegisterScriptableObject
|
Registers
a managed object as scriptable by JavaScript code in the page.
|
|
UnregisterCreateableType
|
Unregisters
a type that was previously registered as createable
using the RegisterCreteableType method.
|
The Document property returns a reference to an object of the managed type System.Windows.Browser.HtmlDocument, which represents the DOM of the underlying page. The Document property is strongly typed and exposes to Silverlight applications most of the features available to script in a weakly typed manner. Properties include the list of cookies, the query string, the body of the document, and the reference to the root of the DOM. The object also features a Boolean IsReady property to signal whether the browser's document has been fully loaded, which is paired with transposition of the DocumentReady event in the browser's DOM.
The HtmlDocument class also features methods such as Submit, AttachEvent, DetachEvent, GetElementById, and CreateElement. In addition, a couple of inherited methods—GetProperty and SetProperty—allow you to get and set attributes of the HTML elements from within managed code.
Full browser information is available through the BrowserInformation property. Also, in this case, the property is of a managed type that wraps any user agent information that is available at the browser level. The following code snippet shows how to access user-agent data:
string info = HtmlPage.BrowserInformation.UserAgent;
The BrowserInformation object also exposes a Boolean property that indicates whether the browser supports cookies.
The following code shows how to retrieve a reference to a DOM element using managed code:
HtmlElement label1 = HtmlPage.Document.GetElementById("Label1");
label1.SetProperty("innerHTML", "Dino");
The GetElementById method takes an ID string and attempts to locate a corresponding element in the underlying DOM. The object returned is of type HtmlElement—a managed type acting as the wrapper for a reference to an underlying browser object.
HtmlElement features a set of properties that makes it look like an HTML element. It has methods such as AppendChild, RemoveChild, GetAttribute, RemoveAttribute, and SetAttribute. Properties are Id, Parent, TagName, and Children.
All HTML script objects you manipulate from within Silverlight code derive from the base ScriptObject class. This class defines a couple of methods—SetProperty and GetProperty—that all derived classes such as HtmlDocument inherit.
What's the difference between getting and setting attributes and properties? Attributes are always managed as strings; properties are managed as strongly typed values.