Just sharing some of my inconsequential lunch conversations with you... RSS  

Tuesday, December 05, 2006

REF: Script#

Will we finally have a decent scripting language on our browsers?


The latest release of Script# (0.2.0.0), also published today, contains a code-behind model that allows me to add c# code-behind to a page, and have that converted into script. I'll blog more about that in the coming days, but this post is mostly about WPF/E.

Here is a portion of my Scriptlet class, which contains c# code-behind for the page. The code in bold shows the scriptlet instantiating a WPF/E plugin instance with some XAML markup.

using System;
using System.DHTML;
using System.WPFE;
using ScriptFX.UI;

namespace PhotoViewer {

public sealed class PhotoViewerScriptlet : IDisposable {
private PhotoViewerControl _photoViewerControl;
...

public static void Main(Dictionary arguments) {
PhotoViewerScriptlet scriptlet = new PhotoViewerScriptlet(arguments);
}

private PhotoViewerScriptlet(Dictionary arguments) {
...
Button searchButton = new Button((DOMElement)arguments["SearchButtonElement"]);
searchButton.Click += OnSearchLinkClick;

WPFEPlayer player =
WPFEFactory.CreateWPFEPlayer((string)arguments["ID"],
(DOMElement)arguments["ParentElement"],
(string)arguments["MarkupURL"],
"Black", /* windowLess */ true);
_photoViewerControl =
new PhotoViewerControl(player, (string)arguments["FlickrKey"]);
...
}

private void OnSearchLinkClick(object sender, EventArgs e) {
string[] tags = _tagsTextBox.Text.Trim().Split(' ');
_photoViewerControl.Start(tags);
}

...
}
}

And here is some code from the PhotoViewerControl that wraps the WPF/E plugin and implements the functionality to make requests to Flickr and progress the presentation from one photo to the next.

internal sealed class PhotoViewerControl : IDisposable {

private WPFEPlayer _player;
private string _flickrKey;

private Image _photo1;
private TextBlock _title1;
private Storyboard _storyboard1;

private HTTPRequest _request;

private Photo[] _photos;
private int _nextPhoto1;

public PhotoViewerControl(WPFEPlayer player, string flickrKey) {
_player = player;
_flickrKey = flickrKey;
}

public void Initialize() {
_photo1 = (Image)_player.FindName("image1");
_title1 = (TextBlock)_player.FindName("title1");
_storyboard1 = (Storyboard)_player.FindName("storyboard1");
...
}

public void Start(string[] tags) {
Dictionary scriptTransportParams = new Dictionary();
scriptTransportParams["callbackParameterName"] = "jsoncallback";

string uri = String.Format(FlickrSearchURLFormat, _flickrKey, tags.Join("+"));
uri = HTTPTransport.CreateURI(uri, typeof(ScriptTransport), scriptTransportParams);

_request = HTTPRequest.CreateRequest(uri, HTTPVerb.GET);
_request.Invoke(OnRequestComplete, null);
}

private void OnRequestComplete(HTTPRequest request, object userContext) {
IHTTPResponse response = request.Response;

if (response.StatusCode == HTTPStatusCode.OK) {
PhotoSearchResponse searchResponse = (PhotoSearchResponse)response.GetObject();
_photos = searchResponse.photos.photo;
StartInternal();
}
}

private static string CreateFlickrPhotoURL(Photo photo) {
return String.Format(FlickrPhotoURLFormat, photo.server, photo.id, photo.secret);
}

private void ShowFirstPhoto() {
_photo1.Source = CreateFlickrPhotoURL(_photos[_nextPhoto1]);
_title1.Text = _photos[_nextPhoto1].title;
Window.SetTimeout(StartFirstTimeline, 1000);

_nextPhoto1 += 2;
if (_nextPhoto1 >= _photos.Length) {
_nextPhoto1 = 0;
}
}

private void StartInternal() {
_nextPhoto1 = 0;

ShowFirstPhoto();
Window.SetTimeout(ShowSecondPhoto, 8000);
}

private void StartFirstTimeline() {
_storyboard1.Begin();
Window.SetTimeout(ShowFirstPhoto, 14000);
}
...
}

One other thing to observe in the sample... the sample makes requests to the Flickr service directly without going through a server-side proxy. To make these cross-domain calls successfully, It uses

<script>
tags rather than XMLHttp to work against Flickr, and uses the JSONP support provided by the service. Script# provides a mechanism to work against this protocol transparently by hiding away the plumbing in the ScriptTransport class that is referenced in the code above. If this is of interest, drop me a comment, and I'll blog about it further.

The sample is packaged into the Script# msi that you can download to delve into the code. In addition to this sample, the msi contains the Script# compiler, and various other samples. There is also a document with a how-to guide on using Script# with a lot of new content, that should help you get up and running using the installed project templates.


in: nikhilt.net

No comments:

Development Catharsis :: Copyright 2006 Mário Romano