Document Information

Last modified:
2008/06/17 17:46 by thron7

Variants

Variants enable the selection and removal of code from the build version. A variant consists of a collection of states from which exactly one is active at load time of the framework. The global map qxvariants can be used to select a variant before the Framework is loaded. Depending on the selected variant a specific code path can be choosen using the select method. The generator is able to set a variant and remove all code paths which are not selected by the variant.

Variants are used to implement browser optimized builds and to remove debugging code from the build version. It is very similar to conditional compilation in C/C++.

Browser optimized builds

qooxdoo tries to hide browser incompatibilities from the application developer. To provide browser independent functionality it is often necessary to use different code on different browsers. Low level code like the key handler have often their own implementation for each supported browser.

The generator selects for browser optimized builds only the code which is needed for one specific browser and removes the unused code. For each supported browser engine an optimized build is generated and on load time the appropriate build is loaded. As a fall back there is always the unoptimized build.

Code like this was very common in older versions of qooxdoo:

if (qx.core.Client.getInstance().isMshtml()) {
  // some Internet Explorer specific code
} else if(qx.core.Client.getInstance().isOpera()){
  // Opera specific code
} else {
  // common code for all other browsers
}

Using Variants the same code looks like this:

if (qx.core.Variant.isSet("qx.client", "mshtml")) {
  // some Internet Explorer specific code
} else if(qx.core.Variant.isSet("qx.client", "opera")){
  // Opera specific code
} else {
  // common code for all other browsers
}

The variant qx.client is always set to the current browser, so this code works exactly like the first version. What is new is that the generator knows about variants and is able to optimize the build for one value of a variant and remove the unused code for all other values of the variant.

Browser optimization is enabled by default in skeleton based applications. The Makefile variable APPLICATION_OPTIMIZE_BROWSER can be used to toggle browser optimization.

Removal of debugging code

Often one wants to add additional checks and assertions to the code but don’t want the build to suffer from these checks. This can be solved elegantly by using variants too. The variant qx.debug with the allowed values on and off can be used to add debugging code which is only active in the source version and removed from the build version.

Example:

function foo(a, b) {
  if (qx.core.Variant.isSet("qx.debug", "on")) {
    if ( (arguments.length != 2) || (typeof a != "string") ) {
      throw new Error("Bad arguments!");   
  }
}

This check is now only enabled in the source version. By default qx.debug is set to off in build versions.

The Makefile variable APPLICATION_OPTIMIZE_REMOVE_DEBUG can be used to toggle the removal of debugging code.

Details

Variants are used to select certain code paths. Each variant has a name and exactly one value from a limited list of allowed values. The variant names have a namespace prefix to avoid name conflicts. The value of a variant is immutable and once set cannot be altered in the JavaScript code.

Definition of a Variant

The method qx.core.Variant.define is used to define a variant. this is how qx.debug is defined:

qx.core.Variant.define("qx.debug", [ "on", "off" ], "on");

The first parameter is the name of the variant, the second is a string array of all allowed values and the third the default value. The default is taken if the variant is not set otherwise.

Using Variants

Variants can be used in two ways. They can be used to select code using if statements or to select whole functions.

Select

If the whole definition of a function should be selected the select method can be used as follows:

var f = qx.core.Variant.select("qx.client", {
  "gecko": function() { ... },
  "mshtml|opera": function() { ... },
  "default": function() { ... }
});

Depending on the value of the

"qx.client"

variant the corresponding function is selected. The first case is selected if the variant is “gecko”, the second is selected if the variant is “mshtml” or “opera” and the third function is the default one. It is selected if none of the other keys match the variant.

isSet

This method is used to check whether a variant is set to a given value. The first parameter is the name of the variant and the second parameter is the value to check for. Several values can be “or”-combined by separating them with the “|” character. A value of “mshtml|opera” would for example check whether the variant is set to “mshtml” or “opera”.

To enable the generator to optimize this selection, both parameters must be string literals.

This method is meant to be used in if statements to select code paths. If the condition of an if statement is only this method, the generator is able to optimize the if statement. Example:

 if (qx.core.Variant.isSet("qx.client", "mshtml")) {
  // some Internet Explorer specific code
} else if(qx.core.Variant.isSet("qx.client", "opera")){
  // Opera specific code
} else {
  // common code for all other browsers
}

Setting the Value of a Variant

There are three ways to set a variant

  • Setting the value in the global variable qxvariants before qooxdoo is loaded.
  • Set the variant using the generator
  • Set the variant using a makefile variable

For the first approach just define a global map named qxvariants. This is how qx.debug can be set to off using in the loader HTML file of a qooxdoo application:

<script language="JavaScript" type="text/javascript">
qxvariants = {
    "qx.debug": "off"
}
</script>     
<script language="JavaScript" type="text/javascript" src="script/qooxdoo_application.js"></script>

For the second approach you pass the parameter “–use-variant” following the value you want to set to your generator call.

generator.py --use-variant VARIANT-NAME:VARIANT-VALUE

And to use the third approach you have to edit your Makefile and can use the two Makefile variables APPLICATION_ADDITIONAL_SOURCE_OPTIONS and APPLICATION_ADDITIONAL_BUILD_OPTIONS depending on for which version you like to set your variant value.

// source version
APPLICATION_ADDITIONAL_SOURCE_OPTIONS = --use-variant=VARIANT-NAME:VARIANT-VALUE

// build version
APPLICATION_ADDITIONAL_BUILD_OPTIONS = --use-variant=VARIANT-NAME:VARIANT-VALUE

Optimizing the Build using the Generator

The generator supports the option –use-variant to optimize the build for a given variant. To remove all debugging code by setting qx.debug to off the following generator parameter can be used.

generator.py --use-variant qx.debug:off ....

Predefined Variants

Here is a list of variants currently predefined in qooxdoo:

Variant Possible Values Default
“qx.client” [ “gecko”, “mshtml”, “opera”, “webkit” ] qx.bom.client.Engine.NAME
“qx.debug” [ “on”, “off” ] “on”
“qx.compatibility” [ “on”, “off” ] “on”
“qx.eventMonitorNoListeners” [ “on”, “off” ] “off”
“qx.aspects” [ “on”, “off” ] “off”
“qx.deprecationWarnings” [ “on”, “off” ] “on”

Information

Last modified:
2008/06/17 17:46 by thron7

Account

Not logged in

 
 

Job Offers

To further improve qooxdoo we are seeking javascript developers. Read more...

Rich Ajax Platform (RAP)

RAP uses qooxdoo, Java and the Eclipse development model to build rich web applications. Read more...

qooxdoo Web Toolkit (QWT)

Similar to GWT this framework allows to create impressive qooxdoo applications just using Java. Read more...

Pustefix

Pustefix is a MVC-based web application framework using Java and XML/XSLT. Read more...

 
SourceForge.net Logo

Bad Behavior has blocked 0 potential spam attempts in the last 7 days.