The JavaScriptManager

Calipso implements a set of JavaScript-related features that are managed by Comkarl.Web.JavaScriptManager class.

JavaScriptManager is responsible of:
  • JavaScript source file dependency management.
  • Server and client-side framework depencency management.
  • Local JavaScript file compression (using AjaxMin by default).
  • Provide infrastructure to client-server Web controls.

After all, JavaScriptManager is a server control. In order to use it in any Master Page or Page, you'll need to register it on top of the .master or .aspx file:
<%@ Register Assembly="Comkarl.Web" Namespace="Comkarl.Web" TagPrefix="Calipso" %>

1. Understanding JavaScriptManager and its concepts

JavaScriptManager can manage two types of script files:
  • Actual JavaScript source files of these kinds:
    • File. It's a physical JavaScript file located in some place of file system.
    • Embedded resource. It's a JavaScript file that's embedded to some assembly.
    • External URL. It's a file located in some external server.
  • JavaScript code that's declared "as is" in your server code and it's executed in the client-side.

Includes and References.

JavaScriptManager has two different concepts that work together in order to define a JavaScript dependency:
  • Include. An include is pointer to a JavaScript file. Either physical, embedded or from an external URL. This isn't adding a JavaScript file to a Web page, but it's just telling JavaScriptManager that some file is available to be included in some Web page. An include has two arguments:
    • id: An arbitrary identifier. For example: "MyJavaScriptFile".
    • source: The file path, full qualified file path for an embedded resource or an URL.
    • kind: File, Resource or ExternalUrl, depending on how you gave the source.
  • Reference. A reference is identified by an include id. It tells JavaScriptManager that the referenced include must be added to the page.

Why includes and references? Calipso avoids spreading literal JavaScript file references across your pages, meaning that if you need to update a JavaScript file, you do in a single point and it affects the entire project.

Imagine that you've a JavaScript file called "\Scripts\MyFile.js". An include to this file would be:
  • id: MyFile.
  • source: /Scripts/MyFile.js.
  • kind: File.

Note that physical JavaScript files must be in your ASP.NET application root or in any subfolder.

And this JavaScript include would be referenced as "MyFile" in your pages. Question is: how to add includes and references?

How to add includes

Includes can be added by configuration or during run-time.

Any Calipso-enabled project must have a Calipso.config file.

In order to add it by configuration, go to the whole configuration file and add an include as child of <includes> elements inside <javascriptManager> element.


A file kind include looks like this
<add id="MyFile" source="/Scripts/MyFile.js" kind="File" />


A resource kind include looks like this
<add id="MyFile" source="SomePath.Other.Blah.js, AssemblyName" kind="Resource" />


An external resource kind include looks like this
<add id="MyFile" source="http://mypage.com/myfile.js" kind="ExternalUrl" />


To add it during run-time, you can do in various levels.
  • Page-level. Any page that hosts Calipso-based controls must inherit Comkarl.Web.UI.Page. Then, you can get current JavaScriptManager instance thanks to Page.JavaScriptManager property. Add your include this way (IMPORTANT THIS MUST BE DURING PAGE.LOAD EVENT!!!!):
    • JavaScriptManager.RegisterInclude(id: "MyFile", source: "/Scripts/MyFile.js", kind: JavaScriptIncludeKind.File);
  • Control-level. Any Calipso control inherits Comkarl.Web.UI.Controls.ScriptControl. The code to do the run-time include is exactly the same as the example in page-level (previous point). Read how to create your very first control following this link.

How to add references

Once you've some includes configured, for example an include having "MyFile" as identifier, if you want your script file in some concrete page, there're two ways of telling JavaScriptManager to do so:
  • Page-level. Page-level approach supports doing so in code or in the ,aspx/.master.
    • In code requires that you register the references in the Page.Load event:
      • JavaScriptManager.RegisterReference("MyFile"); .
    • In your .aspx or .master. Your top-most master page must have added a JavaScriptManager to the <head />_ (X)HTML section. But nested master pages or content pages may require a JavaScriptManager if the concrete page adds ScriptControl-derived classes, or if you want to add references. For example, your JavaScriptManager control would look like this:
<Calipso:JavaScriptManager CombinedFileName="Some.js" runat="server">
   <References>
         <Calipso:JavaScriptRef RefId="MyFile" />
    </References>
</Calipso:JavaScriptManager>
  • (Please refer to Step 9 in this wiki page in order to learn how to register JavaScriptManager in your Master Page or Content Page).
  • Control-level. This can only be made in code the same way as it's done in the page-level above.

Includes of embedded JavaScript files and external files

In addition to include JavaScript files that points to a local file system location, JavaScriptManager supports embedded files and external URLs to files.

Embedded JavaScriptFiles

In order to make an include to an embedded JavaScript, either adding the include in code or in your JavaScriptManager configuration file, you must give include arguments like this:
  • id: Same as any other include, for example "MyFile".
  • source: The full resource path. For example: "YourProject.NamespaceA.NamespaceB.MyFile.js, AssemblyName".
  • kind: Resource. This is very important, because JavaScriptManager must know what kind of source has your include.

External URLs

Sometimes you may need to add external JavaScript files, for example ones from CDN or external APIs. For example, http://somedomain.com/scripts/MyFile.js.

In this case you would be giving this arguments in code or in your JavaScriptManager.config:
  • id: Same as any other include, for example "MyFile".
  • source: The URL of your file. For example http://somedomain.com/scripts/MyFile.js.
  • kind: ExternalUrl. This is very important, because JavaScriptManager must know what kind of source has your include.

Arbitrary JavaScript files executed in the client-side and defined in the server-side as literals or variables

JavaScriptManager supports an approach to execute some JavaScript code in the client-side that's defined in the server-side. Note that this should be used carefully because it's a feature that's available for a limited number of cases.

This can only be made in code in the server side and it's available in page-level and control-level.

An example of doing so would be this code:
JavaScriptManager.RegisterAfterLoadScript("MyArbitraryCode", "var a = \"hello world\";");


Arbitrary code could aid some developments in doing very specific tasks like initializing some API, setting some default value to some variable, object property or things like that in the client-side from the server-side.

2. JavaScriptManager file caching, combination and minification

Every reference that's included in an actual page, even if this happened in code or in the JavaScriptManager server control, gets cached as a temporal file in the specified folder by the cachePath in the Calipso.config file located in your application root, as an attribute of <javascriptManager> element (f.e. <javascriptManager cachePath="~\js">...).

JavaScriptManager works in two modes: debug and release. This is defined in the standard Web.config:
  <system.web>
    <compilation debug="true" targetFramework="4.0" />
  </system.web>


When JavaScript manager is in...
  • ...debug mode (<compilation debug="true"...)...
    • JavaScript includes/references to local file system aren't cached, because those already exist!
    • JavaScript includes/references to embedded files are cached for each request. Pay attention to this feature, because it's important to point that a Calipso-based solution in debug mode shouldn't be used in a production environment, because more than a request may write the same file. This behavior is very important because this way your ASP.NET application will be executing the up-to-date version of your embedded JavaScript file!.
    • JavaScript includes/references to external URLs aren't cached, because as they're external, you shouldn't need to cache them (the responsible of delivering fast JavaScript files is the server where these are stored!).
  • ...release mode (<compilation debug="false"...),,,
    • JavaScript includes/references to local file system and embedded files are combined and compressed.

JavaScriptManager doesn't combine ALL JavaScript code in a single file. It combines all referenced files by a JavaScriptManager instance.

For example, if your Master Page has its JavaScriptManager, it'll combine and compress all referenced JavaScript files for this concrete instance. Later, some Content Page may have it's own JavaScriptManager, so this will combine and compress its own references, and so on.

REMEMBER that no JavaScriptManager will work properly if you didn't give the combined file name:
<Calipso:JavaScriptManager ID="blah" CombinedFileName="Master.js" runat="server" />

Other important point is that application pool's identity must have read-write access to the temporal directory where Calipso places cached JavaScript files!.

When JavaScript files get cached?

JavaScript file caching occurs in run-time. First time an user request a page, JavaScriptManager will generate the necessary file cache, and after that, subsequent requests will be using the already created one.

3. Standalone references: non-combined JavaScript sources.

Sometimes a project may require that a particular JavaScript file don't get combined with the rest of ones because it should be cached alone at the browser-level (or other reasons).

Calipso introduces standalone references. In other words, a standalone reference will render a script tag in the browser and the JavaScript file behind the scenes will not be combined with others.

Standalone references configured in design time

That is configuring a standalone reference in the server JavaScript control in some master page or content page:
<Calipso:JavaScriptManager CombinedFileName="Some.js" runat="server">
   <References>
         <Calipso:JavaScriptRef RefId="MyFile" Standalone="true" /> /* NOTE THE SECOND ATTRIBUTE!! */
    </References>
</Calipso:JavaScriptManager>

Standalone references configuring during run-time

That is configuring a standalone reference in server code:

JavaScriptManager.RegisterReference("MyFile", true); /* SECOND PARAMETER IS "STANDALONE" TRUE OR FALSE */ 


Last edited Oct 18, 2012 at 9:23 AM by MFidemraizer, version 33

Comments

No comments yet.