WMLScript
In the fourth article in the Wireless Access Protocol series, authors Chris Bennett and Frank Coyle provide an overview of the language basics behind WMLScript.
In our last two articles on the Wireless Application Protocol (WAP), we explored the Wireless Markup Language (WML), an XML-based markup language for displaying content on mobile devices. WMLScript is a scripting language that extends WML to provide programmable functionality. We provide a brief overview of the language basics. (Further information can be obtained from the "WMLScript Specification," currently specified at version 1.2, available from the WAP Forum Web site.) WMLScript programs rely heavily on standard library functionsfunction libraries exist for numeric, string, and URL manipulation; browser state interaction; user dialog boxes; and even cryptographic functions (digital signatures). We will outline the libraries (currently specified at version 1.3) and run through a brief tutorial illustrating a few common uses of WMLScript. We also will show how you can use this tool to perform validation, user interaction, formatting, calculations, and telephone operations.
Language Basics
WMLScript is an extended subset of ECMAScript (formerly JavaScript); we assume that you are already familiar with these scripting languages or a C-type language, such as C, C++, or Java. WMLScript differs from ECMAScript in many ways, primarily because of the limited execution environment provided by mobile devices. Unlike ECMAScript, WMLScript is always contained in separate compilation units (not embedded in WML). WMLScript executes only on the client side and is encoded into bytecodes before transmission to the client.
Essential Language Elements
Like WML, WMLScript is case-sensitive. In general, whitespace is not significant (except within string literals), so you can format your WML script to make it readable without affecting functionality. Semicolons are used to end statements such as expressions, variable declarations, and return statements.
WMLScript supports a number of data types but does not require that variables be declared or contain a specific type. Types supported are listed here:
-
IntegerThese are 32-bit signed values (231 to 231).
-
FloatThese are 32-bit single precision (1.17549435E-38 to 3.40282347E+38).
-
StringThese may be defined using single (`...') or double ("...") quotes.
-
BooleanThese are initialized to true or false and contain the result of a logical test.
-
InvalidThis is a special type useful when denoting an invalid value.
A number of reserved words (language key words such as name, var, and agent), literals (such as true and false), and future reserved words (including export and struct) exist. A complete list can be found in the "WMLScript Specification." C++-style comments are supported allowing blocks (/*...*/) and single-line (//) comments.
Operators and Expressions
Operators enable you to assign values to variables, compare values, test truth, and perform arithmetic. For a complete list of operators, see Chapter 6 of the "WMLScript Specification." Operators follow the C language conventions.
Statements
The normal set of statements supported in any procedural language are available to the WMLScript developer. These include the following:
-
Variable initialization
-
Expressions
-
if statements
-
for and while loops
-
Block statements
-
break, continue, and return
-
Empty statements
Variables can be declared and initialized or simply declared, in which case their value is automatically set to the empty string "" (such as var str; or var x=78;). Variables can be declared at any point in a function before their first use. The if, for, while, and other statements follow the C syntax.
Functions
To make use of WMLScript, statements are organized by function, and functions are declared within compilation units. A WMLScript function is simply a named collection of WMLScript statements that returns a value. When a function is called, it must be passed exactly the same number of parameters as are in its declaration. Functions always return a value (the default being an empty string). A simple function that returns the largest of three numbers follows:
function maxOfThree(first, second, third) {...};
Functions are defined in compilation units, which may be libraries (defined as part of the WAP standards) or files that you create. When declaring functions in a file, use the keyword extern to make a function available to WML decks or other compilation units (such as extern function maxOfThree...). At least one function in a file must be declared external.
Functions can be called from WML cards or WMLScript. When calling a function from WML, you need to specify the following:
-
The URL of the compilation unit
-
The name of a public function in the compilation unit
-
All parameters required by the function
For example, to call function maxOfThree found in a WMLScript file called math.wmls located at www.cup.org /scripts, you would insert the following line in a WML card:
<go href="http://www.cup.org/scripts/math.wmls#maxOfThree(x, y, z)"/>;
Note that <setvar> can also be used to pass information to a script from WML. Variables that are set by the script in the browser context can be accessed as regular WML variables following script execution. However, it is not possible to directly retrieve a return value from the script, so a script that will be called from WML should set a variable containing the return value; this can then be accessed by the card to which control is returned. Note that there is no provision to call standard library functions directly from WML with the exception of the Wireless Telephony Application Interface libraries, discussed in the "Libraries" section later in this article.
When calling a function from WMLScript, you must specify its name and provide a list of parameters the same length as that in the function declarationfor example, largest = maxOfThree(x, y, z);. When calling a local function (that is, one within the same compilation unit), you may call this function before its declaration. If the function that you are calling is a standard library function, you must specify the library name before the function namefor example, largest = Lang.max(x, y);, where Lang is the core language standard library and max is the maximum function. We discuss the standard libraries later in this article. If you need to reference a function that is declared in another compilation unit, you must include an explicit reference to the file within which it is declared. This is done using the pragma directive use url (pragmas are discussed later in this article). In addition, you must reference the external function in the same way that you refer to a location in any URL, using the # separator:
use url myScript "http:/www.cup.org/scripts/myscript.wmls"; function doTests(x, y, z) { . . var largest = myScript#maxOfThree(x, y, z); . . };
Note that the use url pragma assigns a name (myScript) to the URL that is later used when accessing the maxOfThree function. Of course, maxOfThree(...) must be declared as extern within myscript.wmls to make it accessible for this call.
Pragmas
Pragmas are used to specify information at the level of the compilation unit. All pragmas begin with the keyword use and are declared before any function declarations. We have already seen the use url pragma, which allows a function to reference external functions within another compilation unit. Pragmas are also available for the following purposes:
-
Access controlControls which URLs can invoke functions in this compilation unit
-
MetadataSpecifies information about the compilation unit that may be used by servers or the user agent, or passed as an HTTP header
Access control is achieved in a similar way to WML deck access control, using a domain or path to determine which URLs can access this compilation unitfor example, use access domain "www.gov.ns.ca" path "/health"; will limit access to those URLs within the domain www.gov.ns.ca below the path /health. By default, no access control is implemented for a compilation unit (all external functions have public access).
Metadata is specified using properties; three property attributes can be specified as strings: property name, value, and scheme (which specifies a way to interpret the property value). Metadata to be passed to the server is specified using the use meta name directive (as in use meta name "Author" "Arthur Dent";). Metadata to be sent to the user agent is specified using the use meta user agent directive (as in use meta user agent "ServerVersion", "1.2"). Metadata can also be passed as HTTP headers using the use meta http equiv directive (as in use meta http equiv "Keywords" "Galaxy,HitchHiker").
That concludes our brief tour of WMLScript language basics. In addition to understanding these basics, to do real-world programming, you will also need to be familiar with the standard libraries.