Chapter 33. JavaScript in JBoss Portal

33.1. Declaring a Module

A JavaScript module is the declaration of a JavaScript self-executing function and its declaration in the gatein-resources.xml descriptor of the web application.
The descriptor defines the module and its dependencies. The portal builds a graph of resources and their dependencies at runtime. When a client requires a particular module, it invokes a JavaScript function that calls RequireJS to resolve dependencies.

Example 33.1. foo.js


(function ($) {
// Do something with jQuery
})(jQuery)
This module is declared as a self-executing function in the foo.js file.
The foo.js file is then declared in the gatein-resources.xml file:

Example 33.2. gatein-resources.xml


...
<module>
  <name>foo</name>
  <script>
    <path>/foo.js</path>
  </script>
  <depends>
    <module>jquery</module>
    <as>jQuery</as>
  </depends>
</module>
...
The self-executing function declares:
  • The parameter for the function: $.
  • The arguments of the function's invocation: jQuery.
The self-executing function argument must match the dependencies.
  • Functions do not need to match the XML dependencies order.
  • Functions can use a parameter subset; a dependency can be declared in the XML but not consumed as an argument.
  • Parameters must be aliased in dependencies with the <as> XML tag.

Note

The self-executing function argument is a JavaScript construct. The purpose of this construct is to pass arguments to the function, let the function name the arguments and override the current scope of execution.
For example, jQuery uses the following:
(function(window, undefined) { .... })(window);
Resources are related by dependency relationships, which specify how scripts are related to each other and how the modular system should be honored.
In our example, the foo module uses jQuery. They are in relationship: foo depends on jQuery. When the foo module is loaded, the jQuery module must be available to it.

33.2. Translation to the AMD System

The portal will translate logical identifiers into an AMD module:

define("SHARED/foo", ["SHARED/jquery"], function(jQuery) {
  return (function($) {
  // Do something with jQuery
  })(jQuery);
});
  • Logical identifiers are translated to AMD identifiers:
    • The foo module is translated to the SHARED/foo AMD module identifier; the SHARED prefix is added by the portal for scoping the name.
      Other existing scopes include PORTLET and PORTAL.
    • The dependency on the jquery module is translated to a ["SHARED/jquery"] AMD module dependency.
  • The module function is wrapped twice:
    • Once by the portal module wrapper which delegates to the module's function. The goal of this function is to provide a ? evaluation of the module's self-executing function.
    • Then by the define AMD function that manages loading the module properly.
  • The self-executing function module's arguments must match the module dependencies expressed in the XML declaration.
    • The jquery dependency is aliased to the jQuery name in the XML as tag. As a consequence the portal function wrapper parameter is called jQuery.
    • The module's self-executing function argument is named jQuery to match the declared alias.
    • The module's self-executing function parameter is named $ and thus redefines the jquery dependency to $ locally.
At runtime, the process happens in the following order of events:
  • The defined function is invoked and declares its dependencies.
  • Once the dependencies are resolved, the module wrapper is invoked with the jQuery argument containing the jquery dependency.
  • The module wrapper evaluates the self-executing function that resolves the jQuery argument to the jquery dependency.
  • The self-executing function is invoked and the jquery dependency is available under the name $.

33.3. Producing Dependencies

The previous example illustrated that a module is able to consume dependencies as arguments. This section explains how a module can produce a dependency.
When a module self-executing function is evaluated it can return an object. You can modify the previous example to return a value.

Example 33.3. foo.js


(function ($) {
  // Do something with jQuery
  return {hello:"world"}
})($)
In this second example, we return a simple JavaScript object. This object will be stored by the dependency system of AMD and provided as arguments of modules that consume the foo module.