Basics

Code Availability

To specify whether your JavaScript should run on the client, on the Jaxer server, or both, you add the runat and autoload attributes to your script tags. Both script blocks in HTML files and external JS files are supported.

A proxy token indicates that the script's functions are available on the server to be called by client-side code. Using the nocache token indicates that the script's functions are not available on the server when proxy functions are executing since, by default, all server functions are otherwise available.

The options for the runat attribute are:

OptionDescription
serveravailable on the server only
server-proxyavailable on the server only; also callable as a proxy function from client-side code
server-nocacheavailable on the server only during initial (DOM1) processing
bothavailable on the server and the browser
both-proxyavailable on the server and the browser and callable as a proxy function from client-side code
both-nocacheavailable on the server and the browser only during initial (DOM1) processing
clientavailable on the browser only

If you don't specify the runat attribute for a script block, it will only be available in the browser (DOM2).

Function availability can also be designated by assigning a value to the runat property on a function object.

The autoload Attribute

The autoload attribute lets you indicate whether an external included script should be automatically loaded and made available during a callback. A value of true will autoload the external script and make it available upon any callback to the page. The default value is false.

The difference between autoload=false and runat="server-nocache" or runat="both-nocache" is that the former works at the file level and the latter work at the function/script block level. Auto-loaded scripts will run, including execution of JavaScript contained in it, prior to the oncallback and the actual proxy function called.

Overrides

As Jaxer executes server-side code, certain standard functions—alert, confirm and prompt— lose their context so alternative implementations are provided that write info-level log messages in place of displaying popups.

Entry Points in Code

As with client-side JavaScript, any server-side JavaScript that is outside of a function scope will be executed as it is encountered, whether or not the entire DOM is available. Client-side JavaScript offers a mechanism for delaying script execution until the page has finished loading; namely, the window.onload handler. Jaxer provides an equivalent mechanism on the server side with the window.onserverload handler. Jaxer also provides an oncallback handler, which is invoked prior to execution of a proxied callback function.

Inlined runat Script Blocks

Note that Jaxer overrides the alert function on server-executed code to write to the log file.

Referenced runat Script Blocks

The Jaxer DOM

The Jaxer environment is based upon the very same Mozilla engine which powers Firefox 3. This means that, for the most part, DOM interaction in Jaxer is the same as interacting with the DOM in a web browser. It parses and executes pages progressively, building up the DOM as it goes along, and allowing JavaScript to interact with whatever DOM has already been built up at the time the JavaScript executes. Any document.write() calls will write to the DOM immediately following the current location on the page. The JavaScript that is part of a page, and loaded into the page, executes within the context of the global window object.

For each request at the server, Jaxer provides a document object model. This DOM (which we'll refer to as DOM1) can be used to insert data and otherwise transform the page before it is first returned to the browser. You interact with and manipulate the DOM much the same as you would in the browser. Some third party Javascript toolkits, such as jQuery, can also be used to modify this DOM.

The document is accessible through the document object, and the root element of the DOM is accessible through the document.documentElement object.

To ensure that element properties are serialized properly when the DOM is returned to the browser, use element.setAttribute("attr", "value") rather than element.foo = "value". Form element values set with formElement.value [code font] are an exception; they'll still be serialized as expected. To attach an event handler to an element, use the special Jaxer method Jaxer.setEvent().

Transforming the DOM

Some cases must be specially handled because they do not permanently modify the DOM of the page which is returned to the browser. For example, to modify a document's title or to attach an event handler you must use one of the Jaxer functions included to close this gap, such as Jaxer.setTitle and Jaxer.setEvent.

Jaxer's Configuration Files

Jaxer uses five core configuration files:

  1. config.js: Core settings, including server mode (defaults to Production, otherwise Development), Mozilla preferences and relative URLs
  2. JaxerManager.cfg: Provides override values for the JaxerManager executable, such as maxrequests and min/max processes
  3. configApps.js: Holds application-specific settings, discussed in detail in Applications
  4. configLog.js: Controls logging, discussed in detail in Logging
  5. Jaxer_prefs.js: This file has been deprecated and any values you set here should instead be set in config.js in the Config.MOZ_PREFS array.

config.js

Possibly the most important setting to understand is server mode since it controls whether Jaxer reloads files each time a browser makes a request, optimizes performance by caching bytecode and determines whether errors should be displayed within the served page or in callbacks. The default is set to Production mode and in production mode Jaxer does not reload files until the server is restarted, does cache bytecode and does not display error in the served page. Development mode does the opposite.

To include scripts and access files and so on, Jaxer may need to get that content from the web server. If your web server needs to be reached via a different domain/port than the incoming request, you can configure Jaxer to do so by setting Config.REWRITE_RELATIVE_URL and Config.REWRITE_RELATIVE_URL_REGEX.

To have Jaxer use MySQL rather than SQLite for its own needs across all your applications on the server, set Config.FRAMEWORK_DB as shown in the commented out block in this file.

Config.MOZ_PREFS contains settings for the Mozilla engine inside Jaxer including:

  • user agent, including related properties such as locale and default character set
  • whether NewHTMLEvents are fired for specific element tags
  • override the core log level otherwise set in configLog.js
  • log the communication between JaxerManager and mod_jaxer for debugging
  • Jaxer DOM canvas dimensions
  • network proxy
  • custom error file to serve if the Jaxer framework cannot be loaded

To see some a more complete list, launch Firefox and browse to about:config

JaxerManager.cfg

Values in this file can also be set in a separate config file passed as a command line argument or as individual command line arguments when launching Jaxer. The priority when the same argument is specified in more than one of them is

  1. JaxerManager.cfg
  2. Separate config file passed as a command line argument
  3. Individual command line arguments

Refreshing Jaxer Configuration Files

In certain circumstances you will want to get a fresh new set of Jaxer configuration files and this is easily done with both standalone Jaxer and the Jaxer bundled inside of Aptana Studio. The files are kept in a folder called local_jaxer/conf.

Standalone Jaxer has this folder directly inside its top-level folder (e.g., on Windows in c:\Program Files\Aptana\Aptana Jaxer, on OS X in Applications/Aptana Jaxer) but in Studio the conf directory is a bit trickier to find and the easiest way to get to it is by right clicking on the Jaxer Internal Server inside the Servers view and choosing Browse local_jaxer folder from the menu. This will select the folder in the File browser.

Local Jaxer Conf dir (OS X)

In either version once you have the conf folder located you simply rename it, quit Studio or Jaxer and restart the same. As part of the Jaxer startup script the presence of this directory is checked and when not found it's recreated with default copies of the base files written to it.

The reason for renaming, rather than deleting, the folder is that after you get the fresh files you can port over any changes you made, such as setting the log level to something other than the default or database and path settings for your applications.

You must restart Jaxer for the changed files to take effect (same applies to the Jaxer inside Aptana Studio, you need to restart Studio).

Including Content and Scripts

Additional HTML content may be injected into the requested page using the <jaxer:include src="..."> and <jaxer:include path="..."> tags; use src to specify a URL (full or relative path is okay) and path to specify a local file reference. An additional technique to load html content is to use the Jaxer.File object to load content which can then be inserted into the DOM using Element.innerHTML.

Including Content with <jaxer:include>

Loading Scripts Programatically

Jaxer.load injects JavaScript into the DOM, and you may optionally specify the runat location (defaults to the most recently evaluated value). This is useful when you need to determine the script file to load at run time, during initial load or in a callback, as well as getting around JavaScript's inability to load other JavaScript files.

Loading Scripts in a Callback

Script Inclusion

Pull in your JavaScript library, from inside another JavaScript file!
// content of myApp.js
// ...
// other JS code
var lf = new Array;
lf.push(Jaxer.Dir.resolve("lib/myLib1.js", Jaxer.request.currentFolder));
lf.push(Jaxer.Dir.resolve("lib/myLib2.js", Jaxer.request.currentFolder));
lf.push(Jaxer.Dir.resolve("lib/myLib3.js", Jaxer.request.currentFolder));
Jaxer.Util.foreach(lf, function(curItem, index) {
	Jaxer.load(curItem);
});
// ...
// more JS code