Richard Evers, Editor

A new plague hit the world in 1995 in the form of hack generalists who could copy and paste together awful HTML sites.

As the years trickled by, and dot com bubbles burst, bandwidth improved along with the languages, techniques and software used to create really decent web sites.

While many conventional sites are pretty good now, the wireless world of WAP is still wallowing in an awkward stage of existence. Unlike traditional sites, WAP sites look basic at best because they are constrained to work within the confines of wireless devices with small screens, modest memory and limited bandwidth.

Topics within this section include

The Basics

The Wireless Markup Language (WML) is a broad, fairly easy to use language that permits site developers to create reasonable content that can be viewed on all WAP browsers. Unfortunately, it lacks many of the useful things found in a true scripting language.

The solution is WMLScript, a wireless scripting language that can co-exist with WML decks. It is similar to JavaScript, and is a modified subset of ECMAScript.

WMLScripts are independent files called as external references within WML decks. They are compiled into byte code at run time on the server before being sent to the WAP browser. Like C, C++ and Java, the language is case sensitive and has a construct that is similar to C.

The format of a WMLScript function is as follows:

extern function NAME( [PARAMETERS(S)] )
{
// body of function
}

The 'extern' keyword is used to make the function public to external files. Do not include ‘extern’ on functions that are only called from within the script.

The following example consists of a WML deck that calls an external WMLScript function:

<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD
WML 1.1//EN"
"http://www.wapforum.org/DTD/wml_1.1.xml">
<wml>
<card id="page1" title="Execute Script">
<do type="options" label="GetNews">
<go href="go_mobile.wmls#surf('news')"/>
</do>
<do type="options" label="GetFlightStat">
<go href="go_mobile.wmls#
surf('flightstat')"/>
</do>
</card>
</wml>

The highlighted lines in the earlier example contain references to the external WMLScript to follow:

/*
* Filename: go_mobile.wmls
* Function: surf()
* Purpose : selectively surf the mobile web
*/
extern function surf(the_url)
{
if (the_url == "news")
{
WMLBrowser.go
("http://mobile.globeandmail.com");
}
else if (the_url == "flightstat")
{
WMLBrowser.go("http://mobile.aircanada.ca/
aircanada/flstatus.wml");
}
}

Parameter passing is fairly lax where type is not specified in the parameter list. The caller of the function is responsible for making sure that parameters passed to a function are in the expected format and sequence.

Reserved Words

access domain http struct
agent else if super
break equiv import switch
catch enum isvalid throw
class export meta try
const extends name typeof
continue extern path url
debugger finally private use
default for public user
div function return var
do header sizeof while

Reserved words cannot be used to name functions or variables.

Statements

WMLScript statements are as follows

access domain http
break for return
continue if/else while

Operators and Expressions

Arithmetic operators:

+ plus - minus
* multiply / divide
% remainder div perform integer division

Bitwise operators:

<< left shift >> right shift
& AND | OR
^ Exclusive OR >>> bitwise right shift with zero fill

Assignment operators:

= assignment += add and assign
-= subtract and assign *= multiply and assign
/= divide and assign div= integer divide and assign
%= remainder and assign <<= bitwise left shift and assign
>>= bitwise right shift and assign >>>= bitwise right shift zero fill and assign
&= bitwise AND and assign |= bitwise OR and assign
^= bitwise XOR and assign    

Unary operators:

+ plus - minus
-- post or pre-decrement ++ post or pre-increment
~ bitwise NOT    

Logical operators:

&& AND || OR
! NOT    

String operators:

+ concatenate += concatenate

Comparison operators:

< less than <= less than or equal
== equal > greater than
>= greater than or equal != not equal

Conditional operator

  • ?: Example: var IsOkay = ( Want == "Food" ) ? 1 : 0;

Other operators

WLMScript supports comma-operators:

for (el = 0, id = 100; el < 10; el++, id+=10)
// do something

While WMLScript is weakly typed, it does support boolean, integer, floating-point, string and invalid data types. The typeof operator will return an integer value that identifies the data type as shown below:

  1. integer
  2. floating-point
  3. string
  4. boolean
  5. invalid

Example:

var data = "Mares eat oats";
var result = typeof data; // result equals 2

An ‘isvalid’ operator is provided to safely test whether an expression is valid. It will return true if the passed expression is valid, else returns false. The syntax is as follows:

var IsOk_1 = isvalid (99/0); // false
var IsOk_2 = isvalid (99/1); // true

Libraries

The strength of WMLScript is largely contained with the function libraries. The libraries include functions to deal with numeric values, dialog and alerts, strings, relative and absolute URLs, and the browser.

Library: Lang

Lang contains the core library functions

abort isInt minInt
abs max parseInt
characterSet maxInt random
exit min seed

Lang.abort()

Description:

Aborts execution of WMLScript and returns passed string to caller.

Syntax:

Lang.abort(ErrorMessage);

Parameters:

An error message

Returns:

Does not return

Example:

Lang.abort("cript failure on line 123");

Lang.abs()

Description:

Returns the absolute value of the passed number.

Syntax:

Value = Lang.abs(Number);

Parameters:

An integer or float value

Returns:

The absolute value returned as an integer or float value

Example:

// will return positive 98765
var i_ret = Lang.abs(-98765);

// will return positive 987.65
var f_ret = Lang.abs(-987.65);

Lang.characterSet()

Description:

Syntax:

charset = Lang.characterSet();

Parameters:

void

Returns:

Numeric character-set identifier

Example:

// Assigned MIB enum Numbers
//-------------------------
//0-2 Reserved
//3-999 Set By Standards Organizations
//1000-1999 Unicode and ISO/IEC 10646
//2000-2999 Vendor
// for example, returns 3 for US-ASCII
var charset = Lang.characterSet();

Lang.exit()

Description:

Terminates script and returns passed message to caller.

Syntax:

Lang.exit(Message);

Parameters:

A message to pass back to the caller

Returns:

Does not return

Example:

Lang.exit("Exit stage left");

Lang.isInt()

Description:

Tests if the passed string can be converted into an integer value using parseInt()

Syntax:

isOkay = Lang.isInt(StringValue);

Parameters:

A string representation of an integer value.

Returns:

Boolean true if string will convert to integer form, else false.

Example:

isOkay1 = Lang.isInt("98765"); // true
isOkay2 = Lang.isInt("-98765"); // true
isOkay3 = Lang.isInt("9.8e2"); // true
isOkay4 = Lang.isInt("intni"); // false

Lang.max()

Description:

Determines the maximum value of two passed values in either integer or floating-point form.

Syntax:

maxValue = Lang.max(Value1, Value2);

Parameters:

Two integer or floating-point values to compare

Returns:

The highest value passed

Example:

// returns 13
var maxValue = Lang.max(12, 13);

Lang.maxInt()

Description:

Returns the maximum value of an integer.

Syntax:

theMax = Lang.maxInt();

Parameters:

void

Returns:

Maximum integer value

Example:

// returns 2147483647
var theMax = Lang.maxInt();

Lang.min()

Description:

Returns the minimum value of two passed values in either integer or floating-point form.

Syntax:

theMin = Lang.max(Value1, Value2);

Parameters:

Two integer or floating-point values to compare

Returns:

The smallest value passed

Example:

// returns 12
var theMin = Lang.max(12, 13);

Lang.minInt()

Description:

Returns the minimum value of an integer.

Syntax:

theMin = Lang.minInt();

Parameters:

void

Returns:

Minimum integer value

Example:

// returns -2147483648
var theMin = Lang.maxInt();

Lang.parseInt()

Description:

Converts a string into an integer value.

Syntax:

theInt = Lang.parseInt(StringInt);

Parameters:

Integer value in string form

Returns:

Integer value

Example:

// returns 9876
var theInt1 = Lang.parseInt("9876");

// returns 987
// stops parsing on first error
var theInt2 = Lang.parseInt("9876Hi!!");

Lang.random()

Description:

Returns a random number between 0 and the passed value

Syntax:

rndValue = Land.random(MaxRange);

Parameters:

Maximum integer value to draw from

Returns:

A random integer within the specified range

Example:

var rndValue = Land.random(9867);

Lang.seed()

Description:

Initializes the random number generator

Syntax:

ret = Lang.seed(SeedValue)

Parameters:

An integer seed value

Returns:

An empty string

Example:

var ret = Lang.seed(98765)

Library: Dialogs

Dialogs contains three dialog handlers:

alert confirm prompt

Dialogs.alert()

Description:

Displays passed message and waits for a response.

Syntax:

var ret = Dialogs.alert(Message);

Parameters:

Message to display

Returns:

An empty string

Example:

var ret = Dialogs.alert("Wake up now!");

Dialogs.confirm()

Description:

Displays passed message, waits for a response, then returns a boolean value that corresponds to the selected option.

Syntax:

var isOkay = Dialogs.confirm(Message, Okay, Cancel);

Parameters:

  • All parameters are string or string literals
    1. the confirmation message
    2. user option #1/2
    3. user option #2/2

Returns:

Boolean true if parameter 2 is selected else false

Example:

var isOkay = Dialogs.confirm("Exit", "Yes", "No");

Dialogs.prompt()

Description:

Displays passed message, waits for a response, then returns the user’s response, or the default response if nothing had been entered.

Syntax:

var gotIt = Dialogs.prompt(Message, Default);

Parameters:

  • All parameters are string or string literals
    1. the prompt message
    2. default response if nothing entered

Returns:

String response

Example:

var Age = Dialogs.prompt("Your age", "30");

Library: String

String contains 16 functions

charAt find length squeeze
compare format removeAt subString
elementAt insertAt replace toString
elements isEmpty replaceAt trim

String.charAt()

Description:

Returns a single character located at the passed offset position within the passed string

Syntax:

  • var theChar = String.charAt(Buffer,Offset);

Parameters:

  1. source string buffer
  2. offset position within source buffer

Returns:

A single character located at the offset position

Example:

Example:
// return "c"
var theChar1 = String.charAt("abcdef",3);

// returns ""
var theChar2 = String.charAt("abcdef",8);

String.compare()

Description:

String comparision where ranking is performed based on the ASCII value of each character within the string

Syntax:

var theRes = String.compare(String1, String2);

Parameters:

  1. first string to compare
  2. second string to compare

Returns:

  • 0 if the strings are identical
  • -1 if the first string is less than the second
  • 1 if the second string is less than the first

Example:

// return 0
var theRes1 = String.compare("ABC", "ABC");

// returns 1
var theRes2 = String.compare("abc", "ABC");

// returns -1
var theRes3 = String.compare("ABC", "abc");

String.elementAt()

Description:

Locates a single element within passed string buffer.

Syntax:

var Field = String.elementAt(Buffer, Element, Delim);

Parameters:

  1. string buffer containing delimited fields
  2. numeric value set to the desired field number
  3. character(s) used to delimit fields

Returns:

The requested field, or the first field if a negative element is passed, or the last field if the element exceeds the total number of fields.

Example:

// returns "transformation"
var Field = String.elementAt("In an extraordinary transformation
of heat to light, Gibbon rested.", 4, " ");

String.elements()

Description:

Counts how many times a delimiter occurs within a passed buffer

Syntax:

var howMany = String.elements(Buffer, Delimiter);

Parameters:

  1. string buffer
  2. field delimiter

Returns:

The total count of Delimiter within the Buffer

Example:

// returns 20
var howMany = String.elements("This descent from unity into multiplicity
recalled Constantine's timid policy of 'dividing whatever is united',
but its effects were far different", " ");

String.find()

Description:

Searches for the first occurrence of the passed substring with the passed buffer

Syntax:

var theFirst = String.find( Buffer, SubString );

Parameters:

  1. source string buffer
  2. substring to search for within passed buffer

Returns:

Offset value of first occurence of substring (0-n), or -1 if substring is not found

Example:

// returns 2
var theFirst = String.find( "Waterloo", "ter" );

String.format()

Description:

Formats the passed numeric value as a string

Syntax:

var looksNice = String.format( FormatString, Value );

Parameters:

  • #1: Formatting string configured as follows
    • "%[width][.precision] type" where "%" and type are mandatory
width minimum number of characters that must be returned in the string
.precision required decimal precision that is set based on the setting of "type"
type = ‘d’1 Source is treated as a positive or negative Integer value in the form of [-]9999 where 9999 is one or more decimal digits.

If ".precision" is set, then the output value is padded on the left side with up to the ".precision" number of zeroes.

type = ‘f’ Source is treated as a positive or negative Floating Point value in the form of [-]9999.9999 where 9999 is one or more decimal digits.

If ".precision" is set, then is used to set the number of digits after the decimal point, with at least one digit appearing before the decimal point. The default precision is 6. If a 0 or nothing has been specified after the ‘.’ then the decimal component is truncated.

type = ‘s’ Source is treated as a String.

The "width" argument can be used to set the minimum string size. The ".precision" argument can be used to set the maximum string size.

Returns:

A formatted string

Example:

// returns "9876"
var s1 = String.format("%8d", 9876);

// returns "009876"
var s2 = String.format("%8.6d", 9876);

// returns "9876.543"
var s3 = String.format("%8.3f", 9876.54321);

// returns "NCC-1701"
var s4 = String.format("NCC-%4d", 1701);

// returns "Hobbits rule!"
var s5 = String.format("Hobbits %s", "rule!");

// returns " 98.765%"
var s6 = String.format("%10.3F%%", 98.7654);

String.insertAt()

Description:

Creates a new string from the passed buffer that includes the passed field and field delimiter, inserted at the passed field element number.

Syntax:

var nStr = String.insertAt(Buff, Field, Element, Delim);

Parameters

  1. string buffer containing delimited fields
  2. string field to insert
  3. Numeric element (0-n) where the field is to be inserted. If less than 0 then is 0 is used. If greater than maximum number of elements, then the new field is appended to the buffer.
  4. Character delimited to insert after the Field

Returns:

Resulting string

Example:

// results: "1|99|2|"
var nStr = String.insertAt("1|2|","99",1,"|");

String.isEmpty()

Description:

Determines is the passed string is empty

Syntax:

var IsNULL = String.isEmpty(Buffer);

Parameters:

A string buffer

Returns:

Boolean true if the string is empty else false.

Example

// returns true
var NULLString = "";
var IsNULL = String.isEmpty(NULLString);

String.length()

Description:

Returns the length of a passed string

Syntax:

var theLength = String.length(Buffer);

Parameters:

A string buffer

Returns:

The string length (0-n)

Example:

// returns 6
var theLength = String.length("yellow");

// returns 0
var theLength = String.length("");

String.removeAt()

Description:

Removes a field from passed buffer at a specific element position.

Syntax:

var Res = String.removeAt(Buffer,Element,Delim);

Parameters:

  1. source string buffer
  2. field element to remove from buffer
  3. character delimiter used to separate fields

Returns:

String buffer without the requested element

Example:

// returns  "1|3|"
var Res = String.removeAt("1|2|3|",1,"|");

String.squeeze()

Description:

Creates a string where all repeat white spaces in the passed string buffer are reduced to single spaces.

Syntax:

var SqzMe = String.squeeze(Buffer);

Parameters:

A string buffer

Returns:

The string buffer with "squeezed" spaces

Example:

// return "Will B Good"
var SqzMe = String.squeeze("Will B Good");

String.subString()

Description:

Returns a portion of the passed string

Syntax:

var SS = String.subSTring(Buffer, Start, Size);

Parameters:

  1. source string buffer
  2. starting offset into the source string (0-n)
  3. the number of characters to extract

Returns:

The requested substring

Example:

// returns "ffe"
var SS = String.subString("Coffee", 2, 3);

String.toString()

Description:

Returns a string representation of the passed parameter.

Syntax:

var theString = String.toString(theValue);

Parameters:

Anything

Returns:

A string

Example:

Example:
var theString = String.toString(98.76);

String.trim()

Description:

Returns passed string without leading and trailing spaces

Syntax:

var isTrimmed = String.trim(Buffer);

Parameters:

A string buffer

Returns:

The string buffer without leading and trailing spaces

Example:

// returns "Well Padded"
var isTrimmed = String.trim(" Well Padded "

Library: URL

URL contains 14 functions:

escapeString getPath isValid
getBase getPort loadString
getFragment getQuery resolve
getHost getReferer unescapeString
getParameters getScheme  

URL.escapeString()

Description:

  • Returns a string where special characters are changed into hexadecimal escape sequences. The escaped characters are as follows:
    • Control Characters (ASCII %00 to %1F) and %7F
    • Space (ASCII %20)
    • Upper range (ASCII %8F to %FF)
  • Reserved Characters:
    ; / ? : @
    & = + $  
  • Not Recommended Characters
    { } |  
    ^ [ ]
  • Delimiters:
    < > # % "

Syntax:

var newStr = URL.escapeString(theURL);

Parameters:

String buffer containing unescaped URL

Returns:

String buffer containing escaped URL

Example:

// results: "http%3a%2f%2frim.com%2f"
URL.escapeString("http://rim.com/");

URL.getBase()

Description:

Returns the absolute URL (without fragment) of the current WMLScript

Syntax:

var absURL = URL.getBase();

Parameters:

void

Returns:

String of absolute URL

Example:

// if URL = "http://rim.com/script.wmls#frag"
// then returns "http://rim.com/script.wmls"
var absURL = URL.getBase();

URL.getFragment()

Description:

Returns the fragment portion of the passed URL

Syntax:

var theFrag = URL.getFragment(theURL)

Parameters:

An URL

Returns:

URL fragment

Example:

// returns "frag"
var theURL = "http://rim.com/script.wmls#frag"
var theFrag = URL.getFragment(theURL);

URL.getHost()

Description:

Returns the host specified within the passed URL

Syntax:

var theHost = URL.getHost(theURL);

Parameters:

An URL

Returns:

Host component

Example:

// returns "www.rim.com"
var theURL = "http://www.rim.com/script.wmls";
var theHost = URL.getHost(theURL);

// returns ""
theURL = "script.wmls";
theHost = URL.getHost(theURL);

URL.getParameters()

Description:

Returns the parameters within the last path segment of the passed URL.

Syntax:

var parms = URL.getParameters(theURL);

Parameters:

An URL

Returns:

The parameters

Example:

// returns "foo;bar"
var theURL = "http://rim.com/foo.php;foo;bar";
var parms = URL.getParameters(theURL);
// returns ""
theURL = "http://www.rim.com/script.wmls";
parms = URL.getParameters(theURL);

URL.getPath()

Description:

Returns the path specified within the passed URL

Syntax:

var thePath = URL.getPath(theURL);

Parameters:

An URL

Returns:

The path component

Example:

// returns "/foo/bar.php"
var theURL = "http://rim.com/foo/bar.php";
var thePath = URL.getPath(theURL);

// returns ""
theURL = "http://rim.com/";
thePath = URL.getPath(theURL);

URL.getPort()

Description:

Returns the port specified within the passed URL

Syntax:

var thePort = URL.getPort(theURL);

Parameters:

An URL

Returns:

The port component as a string

Example:

// returns "80"
var theURL = "http://www.rim.com:80";
var thePort = URL.getPort(theURL);

// returns ""
theURL = "http://www.rim.com";
thePort = URL.getPort(theURL);

URL.getQuery()

Description

Returns the query portion of the passed URL

Syntax

var theQ = URL.Query(theURL);

Parameters

An URL

Returns

The query

Example

// returns "bar"
var theURL = "http://rim.com/ok.php?foo=bar";
var theQ = URL.getQuery(theURL);

// returns ""
thePort = URL.getPort("http://www.rim.com");

URL.getReferer()

Description:

Returns the smallest relative URL for the page, deck or script that called the current script.

Syntax:

var whoCalled = URL.getReferer();

Parameters:

void

Returns:

The referer

Example:

// might return full URL
// or something relative such as "mydeck.wml"
// it will return "" if there is no referer
var whoCalled = URL.getReferer();

URL.getScheme()

Description:

Returns the scheme within the passed URL

Syntax:

var theScheme = URL.getScheme(theURL);

Parameters:

An URL

Returns:

The scheme

Example:

// returns "http"
var theURL = "http://www.rim.com/";
var theScheme = URL.getScheme(theURL);

// returns ""
var theURL = "www.rim.com/";
var theScheme = URL.getScheme(theURL);

URL.isValid()

Description:

Validates the syntax of the passed URL

Syntax:

var isOkay = URL.isValid(theURL);

Parameters:

An URL

Returns:

Boolean true if syntax is correct else returns false

Example:

// returns true
var theURL = "http://www.rim.com/";
var isOkay = URL.isValid(theURL);

// returns false
theURL = "http:/www.rim.com/";
isOkay = URL.isValid(theURL);

URL.loadString()

Description:

Returns the content referred by the passed absolute URL and content type

Syntax:

var theContent = URL.loadString(theURL, theCT);

Parameters:

  1. string containing an absolute
  2. string containing the Content Type that must prefix with "text/"

Returns:

A string buffer containing the requested page, deck or script.

Example:

// returns the page contents
var theURL = "http://www.rim.com/index.shtml";
var theCT = "text/plain" );
var theContent = URL.loadString(theURL, theCT);

URL.resolve()

Description:

Combines the passed base and relative URLs to return an absolute URL

Syntax:

var absURL = URL.resolve(baseURL, relURL);

Parameters:

  1. base URL (e.g. "http://www.rim.com/")
  2. relative URL (e.g. "index.shtml")

Returns:

The resulting absolute URL

Example:

// returns "http://www.rim.com/index.shtml"
var baseURL = "http://www.rim.com/";
var relURL = "index.shtml" );
var absURL = URL.resolve(baseURL, relURL);

URL.unescapeString()

Description:

Returns a string where escaped characters have been restored to original form

Syntax:

var newURL = URL.unescapeString(escURL);

Parameters:

An escaped URL

Returns:

An unescaped URL

Example:

// results: "http://rim.com/"
var escURL = "http%3a%2f%2frim.com%2f";
var newURL = URL.unescapeString(escURL);

Library: Browser

Browser contains 7 functions:

getCurrentCard prev
getVar refresh
go setVar
newContext  

Browser.getCurrentCard()

Description:

Returns the smallest relative URL of the current card being processed by the browser. If the current card has a different base than the current script, will return the absolute URL of the card.

Syntax:

var relURL = Browser.getCurrentCard();

Parameters:

void

Returns:

A relative or absolute URL

Example:

// results: e.g. "validate#doit"
var relURL = Browser.getCurrentCard();

Browser.getVar()

Description:

Returns the value of the passed variable name within the current browser context

Syntax:

var varVal = Browser.getVar(strName);

Parameters:

Variable name

Returns:

String value or invalid if not found

Example:

// results: e.g. "jdoe"
var varVal = Browser.getVar("userid");

Browser.go()

Description:

Navigates browser to an URL

Syntax:

var ret = Browser.go(navURL);

Parameters:

A relative or absolute URL

Returns:

An empty string

Example:

// relative navigation
var ret = Browser.go("newpage.wml");

// absolute navigation
var ret = Browser.go("http://www.xyzzy.com/");

Browser.newContext()

Description:

  • Resets browser context thus clearing all variables
  • Syntax:

  • var ret = Browser.newContext();

Parameters:

void

Returns:

An empty string

Example:

var ret = Browser.newContext();

Browser.prev()

Description:

Navigate to the previous card

Syntax:

  • var ret = Browser.prev();
  • Parameters

  • void

Returns:

An empty string

Example:

var ret = Browser.prev();

Browser.refresh()

Description:

Refreshes current page by pulling it from the server

Syntax:

var ret = Browser.refresh();

Parameters:

void

Returns

An empty string

Example

var ret = Browser.refresh();

Browser.setVar

Description:

Sets the value of a variable

Syntax:

var isSet = Browser.setVar(varName, varValue);

Parameters:

  1. variable name
  2. value to assign to variable

Returns:

Boolean true on success else false

Example:

var isSet = Browser.setVar("password", "plugh");