Introduction

ClockWork Script Builder is a .NET library (2.0) to make the building of scripts more readable and structured.

An extendible architecture lets developers add script building blocks (Script Items) for languages such as the ones provided in the download for JavaScript (Js) and XML (Xs).

Background

Recently I started playing with ExtJs and I ended up needing to build large chunks of JavaScript from .NET code. I've never found a nice way to construct scripts in C# so this time I decided to write a library to help.

However there's a lot more to it. Scripts don't just understand strings but accept any type of object. In particular, objects based on an IScriptItem are specifically designed to work with scripts and can be written by anyone to extend scripting abilities.

You will have noticed all the Script items are created using "Sb.". To make scripts easier to write and read, I have created a helper classes for each set of script items. They provide static methods that will create instances of script items for you.

Script Languages

I have currently developed the following sets of script items to help in writing scripts:

Items to construct basic XML nodes of Element, Attribute, Text and CData. Also supports direct writing to an XmlElement or XmlDocument

ClockWork.ScriptBuilder.XmlScript.Xs

ExtJs

Class and Component items designed to make it easier to write subclasses for ExtJs classes

ClockWork.ScriptBuilder.JavaScript.ExtJs.ExtJs

Points of Interest

DOM & Rendering

All objects added to a script are stored as-is (like a DOM). The string representation of the script is only created when its Render method is called. Among other things, this lets you build the script in steps letting you structure your builder code.

If an IScriptItem is found while rendering then it will use its own Render method to render itself. Other objects are rendered using ToString with an optional format provider.

Rendering is performed using a ScriptWriter which is passed into the Render methods. This object provides the ability to render to several destinations and also handles indentation.

ScriptLayout

Most items have the option to select a layout mode (Inline, InlineBlock, Block). The effects if the item will render across multiple lines.

ScriptIf

This item will do an if-then-else check at render time and then render the object that won.

A collection based ScriptItem (ScriptSet) will result in false if its collection is empty. Therefore you can decide if something is rendered based on the content of another item (all at render time).

Objects can implement the IScriptIfCondition interface if they wish to dynamically provide results for the if condition.

I haven't looked at the code, so forgive me if you've already got this. But, it would be a beneficial feature if you added it...

You have .Render(), but why not add .RenderCompressed().

So, in cases where you're wanting to debug and see the script, you can see it in the 'human' readable form. Otherwise, you can render out the compressed form for release, where you just want to improve efficiency by reducing the overall codesize of your Javascript.

Shouldn't be difficult to manage either, since you're storing the Javascript as-is in memory.

I think compressing variable names would be a more important feature. I also played with this then removed it! I will look at it again. The idea is to have a ScriptItem for variables. This would render as the full variable name or a unique short name if compressed rendering is required.

Short names would be sequential. Something like a,b,c...y,z,aa,ab,ac...

I've uploaded version 1.0.1 which includes a Compress option in the ScriptWriter.

This can be used in conjunction with the ScriptCompressible class to render text that compresses when requested.

There is a JsVariableFactory class which uses this framework to provide an automated sequence of compressible javascript variables.

A website demo is now included that can be compressed by specifying the query string value of Compress=true. The demo compresses by about 33%, mainly from not including tabs or new lines, but also by compressing variable names.