Michael Sync

Michael Sync

Crisp, minimal personal blog

29 Oct 2007

Script#: C# to Javascript Converter


Have you heard about Script#? I only heard about it last week even thoughNikhil started this project last year. I knew that there is a Java-to-Javascript converter called GWT (Google Web Toolkit) in Java World since long time back and I thought that it might be good if we, C# developers, also have that kinda tools for ASP.NET web development. Now, the dream come true. Nikhil created Script# project that can convert the C# code to Javascript. I think it is pretty interesting (and strange ) tool and I wonder how Script# will convert the C# code to Javascript. Anyway, I started learning about Script# on last Friday. I’m gonna share what I have learnt about it so far. If you are already familiar with this tool, please share your thoughts about this tool. Thanks.

Introduction

Script# is a compiler that generate the Javascript instead of MSIL (Microsoft Intermediate Language) from C# sourcecode. Like GWT (Google Web Toolkit) that can convert the Java code to browser-compliant JavaScript and HTML, Script# is able to convert the C# codes to Javascript (either human-readable format or compact one). It is the best tool for those who hate to write the Javascript in HTML view.

SourceCode: SSharp.zip

Example 1 : Getting Started with Script#

  • Download the ScriptSharp.zip from this link.
  • Extract it and double-click ScriptSharp.msi to install the Script# (You should note that Script# is currently available for Microsoft Visual Studio 2005. If you wanna use Script# with Visual Studio 2008, please check-out this post.)
  • Launch the Microsoft Visual Studio 2005 IDE and let’s create very sample Script# project
    _Note: I recommended you to run the VS 2005 IDE as an administrator if you are using Windows Vista series.

Visual Studio 2005 -Run as Admin

  • Click “Script#-Enabled Web site” Project Template from “New Web Site” dialog (File>New>Web Site)
  • We will create one button named “clickMeButton” and the div called “greetingDIV” within tag.
1
2
3
4
5
6
7
8
<div>
   <input type="button"  id="clickmeButton" value= "Click Me" />
   <br />
   <br />
   <div id="greetingDIV" class="divbox">
      Hello buddy!!
   </div>
</div>
  • Go to the design-view and right-click on “Scriptlet” control as picture below.

Script# - Scriptlet Control

  • Select “Edit C# Code” on content menu.

  • Paste the following code in Scriptlet Editor

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    
    using System.DHTML;
    using ScriptFX;
    using ScriptFX.UI;
    public class MyScriptlet: IDisposable {
    
      private DOMEventHandler _clickHandler;
    
      private MyScriptlet(ScriptletArguments arguments) {
        _clickHandler = new DOMEventHandler(OnClickMeButton_Click);
    
        DOMElement clickMeButton = Document.GetElementById("clickmeButton");
        clickMeButton.AttachEvent("onclick", _clickHandler);
      }
    
      public static void Main(ScriptletArguments arguments) {
        MyScriptlet scriptlet = new MyScriptlet(arguments);
    
      }
    
      public void Dispose() {
        if (_clickHandler != null) {
          DOMElement okButton = Document.GetElementById("clickmeButton");
          okButton.DetachEvent("onclick", _clickHandler);
          _clickHandler = null;
        }
      }
    
      private void OnClickMeButton_Click() {
        DOMElement divGreeting = Document.GetElementById("greetingDIV");
        divGreeting.Style.Display = "block";
      }
    }
        
    

    Script# - Scriptlet Editor

  • Click “Save and Close” on Scriptlet Editor

  • Build the web application and Press “F5” to run the application

  • (There is one button on the page.) Click this button.

  • “Hello Buddy!” message will be shown as picture below.

Script# - Example 1

That’s it. You just created one script#-enabled webpage. Do you want to know what code Script# generated from your C# code? It’s easy. Just go to “View Source” and you will see the following script which is generated by Script#.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
<script type="text/javascript">
   //<![CDATA[
   window.main = function main() {
   Type.createNamespace('Scriptlet');
    
   ////////////////////////////////////////////////////////////////////////////////
   // Scriptlet.MyScriptlet
    
   Scriptlet.MyScriptlet = function Scriptlet_MyScriptlet(arguments) {
   this._clickHandler = Delegate.create(this, this._onClickMeButton_Click);
   var clickMeButton = $('clickmeButton');
   clickMeButton.attachEvent('onclick', this._clickHandler);
   }
   Scriptlet.MyScriptlet.main = function Scriptlet_MyScriptlet$main(arguments) {
   var scriptlet = new Scriptlet.MyScriptlet(arguments);
   }
   Scriptlet.MyScriptlet.prototype = {
   _clickHandler: null,
    
   dispose: function Scriptlet_MyScriptlet$dispose() {
   if (this._clickHandler) {
   var okButton = $('clickmeButton');
   okButton.detachEvent('onclick', this._clickHandler);
   this._clickHandler = null;
   }
   },
    
   _onClickMeButton_Click: function Scriptlet_MyScriptlet$_onClickMeButton_Click() {
   var divGreeting = $('greetingDIV');
   divGreeting.style.display = 'block';
   }
   }
    
   Scriptlet.MyScriptlet.createClass('Scriptlet.MyScriptlet', null, IDisposable);
    
   // ---- Do not remove this footer ----
   // Generated using Script# v0.4.2.0 (http://projects.nikhilk.net)
   // -----------------------------------
    
   ScriptFX.Application.current.run(Scriptlet.MyScriptlet);
   }
   ScriptHost.initialize([
   'App_Scripts/ssfx.Core.js',
   'App_Scripts/ssfx.UI.Forms.js'
   ]);
   //]]>
</script>

Don’t you think that the generated Javascript code looks so similar to your C# code that you wrote in Scriptlet Editor?

Yes. This is one of the advantages of using Script#. It can generate the human-readable Javascript that has the same structure as your C# code. If you are not sure how to write the object-oriented code in Javascript, you can just write the code in C# with the rich features such as IntelliSense, refactoring, compile-time and let Script# convert the C# code to the object-oriented Javascript code.

Note: The sample is already attached in this post. Please check-out “Example1.aspx” in zip file.

Okay. We’ve just done one sample with Script#. As the project is in very early stage, I notice that there are a few weak points and bugs in that project while I’m learning. And also, I’m kinda agreed with Dimitri Glazkov regarding on Script# project. (Check-out his post). Anyway, let’s learn more about Script# and we’ll see whether we should use it in real project or not.

Example 2 : Script# Ajax

  • Create the another Script#-enabled project
  • Add the “Generic Handler” to your project and name it “ExampleWebHandler.ashx”
  • Paste the following code in “ProcessRequest (HttpContext context)” function.
1
2
context.Response.ContentType = "text/xml";
context.Response.Write("Hi " + HttpUtility.HtmlEncode(context.Request.QueryString["name"]) + "!");

_Note: What this code does is that write the “Hi” after appending the name that came as a parameter in response.

  • Add one textbox to accept the user inputs, one button to invoke the server-side script and the div for displaying the result.
1
2
3
4
5
6
<div>
   Please Enter your name : &nbsp;&nbsp;
   <input type="text" id="nameTextBox" /> &nbsp;&nbsp;
   <input type="button" id="sayHiButton" value="Say Hi!!"/> <br /><br />
   <div id="result"></div>
</div>
  • Add the argument to your scriptlet control. (Right-click on Scriptlet control and select “Edit” Arguments. then, Add one member (Name: name and Value: ExampleWebHandler.ashx?name={0}))

Edit Arguments - ScriptletArgument Collection Editor

  • then, Click “OK” to close the “ScriptletArgument Collection Editor”
  • Paste the following code in “Scriptlet Editor”
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
using System;
using System.DHTML;
using ScriptFX;
using ScriptFX.UI;
using ScriptFX.Net;

public class MyScriptlet: IDisposable {

  private string _urlName;
  private DOMEventHandler _clickHandler;
  private XMLHttpRequest _request;
  DOMElement resultDIV = null;

  public static void Main(ScriptletArguments arguments) {
    MyScriptlet scriptlet = new MyScriptlet(arguments);
  }

  public void Dispose() {
    if (_clickHandler != null) {
      DOMElement okButton = Document.GetElementById("sayHiButton");
      okButton.DetachEvent("onclick", _clickHandler);
      _clickHandler = null;
    }
    if (_request != null) {
      _request.Onreadystatechange = (Callback) Delegate.Null;
      _request.Abort();
      _request = null;
    }
  }

  private MyScriptlet(ScriptletArguments arguments) {
    _urlName = arguments.name;

    _clickHandler = new DOMEventHandler(OnSayHiButton_Click);

    DOMElement clickMeButton = Document.GetElementById("sayHiButton");
    clickMeButton.AttachEvent("onclick", _clickHandler);
  }

  private void OnSayHiButton_Click() {
    InputElement nameTextBox = (InputElement) Document.GetElementById("nameTextBox");
    resultDIV = Document.GetElementById("result");
    resultDIV.Style.Display = "block";

    _request = new XMLHttpRequest();
    _request.Onreadystatechange = this.OnRequestComplete;
    _request.Open("GET", String.Format(_urlName, nameTextBox.Value.Escape()), /* async */ true);
    _request.Send(null);
  }

  private void OnRequestComplete() {
    if (_request.ReadyState == 4) {
      //if (_request.Status == 200) {
      _request.Onreadystatechange = (Callback) Delegate.Null;
      if (resultDIV != null) {
        resultDIV.ClassName = "divbox";
        resultDIV.InnerHTML = _request.ResponseText;
      }
      _request = null;
      // }
    } else {
      if (resultDIV != null) resultDIV.InnerHTML = @ "<img src="
      "./images/indicator_technorati.gif"
      ">";
    }
  }
}

Note: I assumed that you already have some ideas about Ajax before reading this article.

  • Build the application and run it. (You will see one textbox and one button as you have added on the page.)
  • Type the name you like
  • Click “Say Hi!” button. (You will see the result as below with the name that you enter.)

Oh Yes

This demo is very sample that shows the way how to communicate between Script# code and the Server-side code. You can probably extends the web handler to get the more features as you need for your Script#-enabled application.

Debugging the Script#-enabled application

For IE Users, Go to “Debug->Windows->Script Explorer” or Press “Ctl+Alt+N” while you are running the project. You will see the list of script files that are included in page. Select the script file that you wanna debug and set the breakpoint. You know [how to debug the Javascript with Visual Studio 2005][http://www.google.com/search?q=how+to+debug+javascript+with+visual+studio&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a], right?

For Firefox Users, Firebug is the best tool for debugging the Javascript.

Yeah. It is so sad to say that you are not able to debug the C# code that you wrote. Instead, you will be debugging the Javascript code which is generated by Script# compiler.. It makes you feel like debugging the MSIL code after writing the C# in IDE even the generated code is so much like the C# code that you wrote and human-readable but it is by-design so we can do nothing.

Conclusion

I’m gonna stop learning the Script# project for today. I’ll read about building the Script# library and Vista Sidebar Gadget and will post them in my blog. For the time being, I do have a few disappointments in using Script#. However, I will look more information about this project and I will share the conclusion with you.. If you are also learning this project like me, please let me know. We can probably discuss more about this project.. Thanks…

More Information about Script# ~