Software Development Documentation Development Overview WCTL Template Language WCTL Commands WCJS Server-side JavaScript WCMS Development Chat Development Standard Templates & URL Codes Operator Documentation

Visit the

  • Developer Center,
  • WebX Harbor, and the
  • Web Crossing Conference
    to find a wealth of WebX info and a community of WebX experts on the Web!
  • Web Crossing Server-side JavaScript (WCJS)

    Table of Contents

    Overview

    Processing an HTTP Request

    Object-Oriented Database


    » Overview

    Web Crossing supports built-in server-side JavaScript 1.5. You can use JavaScript to totally customize Web Crossing, to write your own dynamic Web pages, and to process Web-based forms.

    Web Crossing's JavaScript environment is specifically designed to build Web pages. Each request from a Web browser can be served by a combination of HTML text and JavaScript functions.

    Special objects are provided to access the incoming request, work with input form variables, and produce a response page. You have total control over the response, including the ability to easily forward to another location, set cookies, and so on.

    Web Crossing's JavaScript environment is nicely coupled to its built-in database, giving you access to a user directory and to hierarchical, extensible, object-oriented data items. (If you prefer, you can use external services for persistent storage. You are never required to exclusively use the tools built into Web Crossing.)

    » JavaScript function library

    You can pre-load any number of JavaScript functions, so they are immediately available for processing any request. This allows you to build your own function library of JavaScript objects, and to initialize these objects. It provides very high performance by caching pre-compiled scripts and objects.

    Pre-loaded JavaScript functions can be used to process Web-Crossing-specific requests, or to define your own dynamic pages.

    A file named webx.tpl is used for pre-loaded JavaScript functions. This file can include any number of function definitions and initialization functions.

    The syntax for JavaScript functions in the webx.tpl file is

    %% command name(args...){...} %% -or-
    %% function name(args...){...} %%
    A "command" or "function" statement in a webx.tpl file results in a JavaScript function being pre-compiled for later use. A command can be used in a URL, while a function can only be called internally. (You can have any number of commands or functions, and any number of lines of code, between the %%...%% delimiters.)

    For example, here is the classic "Hello world" application written in JavaScript for Web Crossing:

    %%
    command hello(){
        + "Hello world!";
    }
    %%
    (Note that this uses command instead of function, so that this JavaScript function can be used directly to process incoming URLs.) You would get to this function by issuing a URL in your Web browser:

    ...webx?hello
    where "...webx" is the URL to access your Web Crossing server, "hello" is the command for Web Crossing to execute (our "Hello world" function).

    » JavaScript reserved words

    Certain words are reserved for internal usage and may not be used as variable, method, property, or objects names. The reserved words are:

    » Including server-side JavaScript files

    You can include files into webx.tpl by using the following directive:

    <!--#Include File="filename"-->

    where filename is the file to include. You must use this syntax exactly: spaces, capitalization, and all.

    It is often convenient to use separate files for each new JavaScript object or set of related functionality.

    » Shorthand for appending to the response page

    When you are using server-side JavaScript, you often need to append text to the response page. Web Crossing provides a shorthand notation for doing this.

    Any JavaScript statement that starts with a plus sign (+) is evaluated as an expression and then appended to the response page. That is, the statement

    +"Hello world"; // or
    + "Hello world";
    is the same as writing
    response.append( "Hello world" );

    » Mixing HTML and JavaScript code

    In Web Crossing, you can embed HTML text directly into JavaScript functions, by just enclosing this text between %% delimiters (as %%...HTML text...%%). Embedded text is automatically translated into the appropriate JavaScript calls to append the text to the response page. For example,

    %% command test() {
        %%This is a test function that just puts text into the response page.%%
    } %%
    is evaluated as if it was

    %% command test {
        response.append( "This is a test function that just puts text into the
    response page." );
    } %%
    All embedded text is automatically escaped and quoted correctly for JavaScript compilation.

    In addition, you can use the \ character to suppress the end-of-line characters, so you can break up long HTML lines into smaller pieces for readability. Leading tabs are stripped from text lines, again so you can write readable HTML. For example, the text

    %% Hello \
        there%%
    would evaluate to a single line of text in the output, just as if you had written this as

    response.append( "Hello there" );
    In large, complex pages, it is very convenient to be able to define the page as a JavaScript function, and then drop in the specific server-side JavaScript as needed. For example, something like the following:

    %% command processRequest(){
        %% many lines of html ... %%
        if( form.accept == "true" ){
          %% You have accepted the software license. %%
        } else {
          %% You have chosen to decline the software license. %%
        }
        %% many more lines of html ... <img
    src="%%site.imagesUrl%%/example5.gif"> ... %%
    } %%
    This function inserts conditional text depending on the value of the form's "accept" field, and uses another JavaScript function to insert the correct location for a gif image.

    » Initialization and pre-defined classes

    The normal sequence for loading template files is as follows.

  • Load the webx.tpl file, and replace all includes with their text, to any level. This defines all of the JavaScript functions/command and Web Crossing Template Language (WCTL) macros to be evaluated.
  • Evaluate all of the JavaScript functions/commands and WCTL macros, in the order defined.
  • Execute all init init functions, in the order defined. Any function name starting with "init_" is run after all of the webx.tpl functions have been compiled.
  • This means that you can use an init_ function to pre-build an object class, adding functions and data constants to the constructor's prototype. For example,

    %% function Def(...){
        ...
    }
    
    function init_Def() {
        /* Define Def class */
        a = new Def(...); /* Results in a prototype for Def constructor */
        Def.prototype.Value1 = 12345; /* Assign prototype values, etc */
        ...
        function Def_checkIt() {
        ...
        }
        Def.prototype.checkIt = Def_checkIt;
    } %%
    Init_ functions are evaluated in the order they are defined.

    A global propery named libraryGlobal is available to reference the global context that is copied to become the intial global object for each incoming request.

    » Variable scope

    Variables are resolved in the same manner in Web Crossing's JavaScript environment as they are in client-side JavaScript, with one significant difference: Web Crossing always resolves variables in the current global scope, instead of the global scope where the function was defined. This automatically gives each request its own private set of variables, so that multiple requests can be processed in parallel.

    In practice, this means that you can use global variables as desired, and each request will have its own set of gobals.

    The following table shows a more detailed outline of variable resolution in Web Crossing, compared to client-side usage.
    Resolution steps Web Crossing usage (server-side) Browser usage (client-side)
    First If the variable is defined in a var statement, it is local to the current execution of the function and is read/write. Same.
    Second Lookup the variable as a property of the current function. Same.
    Third Lookup the variable in the current request's global scope. These variables are read-write. Lookup the variable in the window in which the function was defined. These variables are read-write.

    » Grouped JavaScript functions

    In the Web Crossing Template Language, you can create nested macros, and then specify the top-level macro as the customization template for a folder or discussion. For example,

    %% macro style1 %%
        %% macro folder %%
          ... folder layout for style1
        %% endmacro %%
    
        %% macro discussion %%
          ... discussion layout for style1
        %% endmacro %%
    %% endmacro %%
    In effect, the top-level style1 macro just groups together some nested macros and functions that are used when this style is applied to a folder or discussion.

    With JavaScript functions, you can use the same structure:

    %% macro style1 %%
        %% command folder {
          ... folder layout for style1
        } %%
    
        %% command discussion {
          ... discussion layout for style1
        } %%
    %% endmacro %%
    With this format, if the "style1" macro is applied to a folder, its style1.folder() and style1.discussion() functions will be used to lay out that folder and its items.

    Functions grouped in this manner are placed into JavaScript container objects that correspond to the macro grouping. In the example above, the full names of the functions would be

    style1.folder and
    style1.discussion

    » Mixing JavaScript and WCTL

    You can mix JavaScript and WCTL: you can call JavaScript functions from WCTL, and you can call WCTL macros from JavaScript, per the following sections.

    JavaScript and WCTL can both set properties of stored objects, and pass data to each other this way. However, WCTL cannot reference any JavaScript types except strings. In other words, if WCTL accesses a path.var that was stored by a JavaScript "node.var = value;" statement, the WCTL program will get the correct value if it is a string, but will get the empty string as the value for any other JavaScript type.

    You can access WCTL variables from JavaScript by using wctlVar( variable ) and setWctlVar( variable, value ).

    » Calling JavaScript from WCTL

    To call JavaScript functions from the Web Crossing Template Language, use

    string.jsEval
    to evaluate a JavaScript script. For example,

    %% "1+2".jsEval %%
    will call JavaScript and evaluate to "3". All JavaScript results are converted to strings by jsEval. If jsEval is terminated by a JavaScript error, then the evaluation will return the empty string. You can use

    %% jsError %%
    to get any error message. If you want to evaluate a JavaScript expression and get either the result or any JavaScript error message, use

    string.jsEvalOrError

    » Calling WCTL from JavaScript

    To call WCTL from JavaScript, use

    wctlEval( expression ) or
    wctlEvalTemplate( template )
    For example,

    wctlEval( "1+2" ) will return "3",
    wctlEvalTemplate( "xxxx %" + "% 1+2 %" + "%" ) will return "xxxx 3"
    Note that you cannot say

    wctlEval( "xxxx %% 1+2 %%" )
    directly because the "%%" in the string will be evaluated as switching mode between JavaScript and HTML text.

    » Debugging

    The initial parse of the webx.tpl file will append any errors to the webx.log file.

    Run-time errors will return the page to the point of the error, followed by the error message and a stack trace. You sometimes need to do a "View as source" in order to see the error messages.


    » Processing an HTTP Request

    Incoming URLs can call a JavaScript function directly, or can be processed by a JavaScript function indirectly during Web Crossing's evaluation of the URL command.

    A JavaScript function must be enabled to respond to incoming URLs.

    Each incoming request is run in its own private global context. The global properties are:

    request top-level object, default scope for variables. For example, "request.certificate" is the same as "certificate"
    top during initialization, top is the same as libraryGlobal. During request processing, top is the same as request.
    response ByteBuffer accumulating the response page to return to the browser
    cgi object with a string property for each CGI variable
    form object with a string property for each input-form field
    user user for current session (read/write variable)
    location the Node object specified in the location parameter of the URL, or null if none (read/write variable)
    locationArray array of parents for the location object, with location as the last element. (read/write variable)
    site current global site settings
    topLevelFolder top-level folder for the site
    session object with read/write property strings for the current user's persistent session information
    certificate certificate string for the current user/session (read/write variable)
    error some methods indicate errors by setting this error message. It is the error from last such command, or null for no error

    » Enabling JavaScript functions to serve URLs

    JavaScript functions cannot normally serve URLs. In order to have a JavaScript command serve URLs, you must either:
  • set the property urlEnable to true. For example,
  • function myLookup(){
    ...
    }
    function init_myLookup(){
        myLookup.urlEnable = true; // Enable URL processing
    }
  • or use the keyword command instead of function. command is exactly the same as function, except that it also sets name.urlEnable. For example,
  • command myLookup(){
    ...
    }
    enables myLookup to serve incoming URL-based commands.

    » URL syntax

    For direct execution of a JavaScript command, the syntax of the URL is

    .../webx...?functionName@certificate@location!formName=value&...
    where

    .../webx...? directs the URL to the Web Crossing server, however this is configured.
    functionName is the name of the JavaScript function or method
    certificate is the optional certificate for this session (WCTL automatically keeps track of user and per-session variables, see the following discussion of the "session" object.)
    location is an optional location in the WCTL object-oriented database (OODB)
    formName=value is an optional list of input fields. Each formName and value must be URL quoted.

    If the location has a method with the specified functionName, then that method is called. This is the same as

    var n = Node.lookup( "location" );
    n.functionName();
    If there is no location, or it does not have a matching method, then the function is called.

    If there is no method or function with the right name, then an error message is displayed.

    » request

    The request object is the same as the top-level global scope. It provides a way to reference top-level variables from any function, regardless of local variables.

    For example, request.certificate is the same as certificate unless there is a local variable named "certificate".

    » response

    The response object is used to build the response Web page. The response is a ByteBuffer, which means that it is a modifiable, variable-length array of bytes.

    To add HTML text to the response page, just use

    response.append( text );
    You can also append text to the response by just inserting it into your JavaScript program inside %%...%% pairs, as

    javascript code...;
    %% text %%
    more javascript code...;

    You can also append text to the response by putting a plus sign as the first character of a JavaScript statement, as

    + "hello there " + user.userName + ".<br>";
    All of the ByteBuffer methods and properties work with the response page, so you can clear the output and start over, search or modify text already placed into response, etc.

    To embed URLs for Web Crossing functions, see the built-in command makeUrl.

    The final response value will direct Web Crossing to take appropriate action:
    response page action
    non-empty response, not starting with HTTP/ This is a normal HTML page, and Web Crossing will automatically generate the HTTP header for the response. (Responses to a Web browser are an HTTP header, a blank line, then the page itself. So if you provide the page, Web Crossing will provide the HTTP header and blank line.)
    response starting with HTTP/ Whenever a response page evaluates to text starting with HTTP/, that page is returned as is, without adding the standard HTTP response heading. For example, the following function forwards the incoming request to <http://mysite.com/test.html>. 
      %% function forward {
          response.append( "HTTP/1.0 302 Redirect" );
          response.crlf();
          response.append( "Location: http://mysite.com/test.html" );
          response.crlf();
          response.crlf();
      } %%
    This is because HTTP/1.0 302 Redirect has a response code of 302, which asks the browser to temporarily forward the original URL to a new location.

    Note that the forwarding response must end with a final blank line, because this blank line marks the end of the response HTTP header. The page itself, following this blank line, is empty.

    empty response page Web Crossing assumes that the user needs to login before this function can run correctly, and will return a login page. After the user successfully logs in, the current function will be reexecuted with the same input-form values.

    » cgi

    The cgi object is a read-only list of properties from the incoming request. "cgi" stands for "Common Gateway Interface" -- this is the standard interface between a Web server (Web Crossing) and the program that is processing the request.

    You can enumerate the available properties. For example, the following function will show a list of cgi properties:

    Typical cgi properties and their use are:
    cgi property use
    query_string The query string from the incoming URL, the portion following the first question mark in the URL.

    This string is URL-quoted, so the query string from the request "http://test.webcrossing.com/webx?showCgi@@" becomes a cgi.query_string of "showCgi%40%40".

    To remove the URL-quoting, use cgi.query_string.fromUrl().

    script_name Incoming request, following the server domain and before any question mark and query string.

    For example, the request "http://test.webcrossing.com/webx?showCgi@@" has a cgi.script_name of "/webx".

    https Set to "on" if the request is via a secure SSL connection, otherwise is not defined.
    http_Referer The URL of the page that contained the link to the current request
    http_User_Agent Type of client browser, such as "Mozilla/4.05 (Macintosh; U; PPC, Nav)"
    http_Connection Type of connection, such as "Keep-Alive"
    http_Host Domain name or IP address of the host serving this request, such as "www.webcrossing.com" 
    http_Accept The mime-types that the browser will accept, such as "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, image/png, */*"
    http_Accept_Language Languages that the browser will accept, such as "en" for English
    http_Accept_Charset Charsets that the browser will accept, such as "iso-8859-1,*,utf-8"
    request_method Request type, "GET" or "POST"
    remote_addr IP address of the client Web browser, such as "1.2.3.4".
    server_name Domain name or IP address of this server, such as "test.webcrossing.com".
    url_scheme If you need to know whether a request came in over a secure SSL connection or not, use cgi.url_scheme. In direct web-service mode, this will be "https" for a secure connection, or "http" for a non-secure connection. For FastCGI mode, this will be set per the originating server, so may be missing or null; instead of url_scheme, Apache servers set https if the request was over an SSL connection. In CGI mode, no information is available.

    Note that cgi properties starting with "http_" are fields from the incoming HTTP heading. So "http_xxxx" properties are whatever the client browser has sent. Properties without an "http_" prefix are provided by the server and are known to be valid.

    » form

    The form object is a read-only list of form input fields. There is one property for each form input variable or named value in the incoming URL.

    For example, if the incoming URL is

    then You can enumerate the properties of the form to list all of the input fields.

    If the same field is input more than once, form.inputField is the last one. Using the last value allows you to set defaults using hidden fields, as in

    This usage will always provide a value for form.myCheckBox. If the checkbox is checked, then both myCheckBox=false and myCheckBox=true will be sent by the browser, which will result in a "true" value from form.myCheckBox. If the checkbox is not checked, then only myCheckBox=false is sent by the browser, which will result in a "false" value from form.myCheckBox.

    When a post is done in multipart MIME format, you can access the header component of each value through the Mime.formHeader() function.

    » user

    This is the current user for the request. It is a User object, and has all the information about the current user.

    » newMessages

    The NewMessages object has information about locations of new messages for the user. This is a NewMessages object.

    » location

    This is the location in the Web Crossing database from the incoming request, or null. See the discussion of Node objects.

    » locationArray

    This is an array of parent Nodes for location, or null if location is null.
    locationArray[0] Same as topLevelFolder
    locationArray[...] Intermediate parents
    locationArray[locationArray.length-1] Same as location

    » site

    The site object has information about the Web Crossing site, including settings and global site variables. This is a Site object.

    » topLevelFolder

    The topLevelFolder object is a Folder object, the top-most Folder for the site.

    » session

    The session object is a read-write set of properties that are preserved across requests from the same browser. This object provides a convenient way to manange state information for an ongoing session.

    The properties of a session can only have string values. You can enumerate over these properties.

    In order for an incoming request to have the same session as an earlier request, the certificate component of the URL must be the same as for the earlier request. This means that you should dynamically generate all session-linked URLs as

    » certificate

    The certificate object is a string that is the certificate for the current session. Use this certificate in all links in order to have the current user and session preserved across requests.

    » error

    Some commands, such as new Folder( parent, title ) will return a null object if there was an error. The error message is saved in this global error string. If there is no error, then erroris set to null.


    » Object-Oriented Database (OODB)

    Web Crossing includes an object-oriented database. This database is organized into a hierarchy of named Folders, each containing nested Folders, Discussions, Chat rooms, and Links. Any object that can be added to a Folder is a "Node" object.

    Discussions contain Messages, which are accessible as either a chronological conversation or a hierarchy of threaded messages.

    At the lowest level, there are primitive Stored objects. These are the same as a JavaScript Object, except that they are stored into the database.

    All objects stored in the OODB can be accessed through JavaScript objects. Setting new property values for stored objects stores the values into the OODB and saves them on disk. Fetching values from stored objects loads them from disk automatically.

    You can create your own kinds of objects derived from the built-in classes, giving you an extremely powerful tool for extending and customizing Web Crossing.

    » Defining New Classes of Objects

    You can derive your own classes from any Stored object class.

    For example, suppose you wanted to define an "auction item". You decide to derive this from the built-in Node object, because you want auction items to be listed in a folder. So, just define an AuctionItem constructor and its init logic:

    function AuctionItem( folder, title, ...){
        // Constructor function for AuctionItem
        // AuctionItem objects inherit from Node
        ...init a new auction-item object as appropriate
    }
    
    function init_AuctionItem(){
        // Initialization for the AuctionItem class
        // (called one time at startup because its name starts with "init")
    
        // AuctionItem objects inherit from Node, accomplished
        // by setting AuctionItem.prototype to be a
        // newUnattached Node object:
        AuctionItem.prototype = Node.newUnattached();
        
        // Set up AuctionItem so that you can derive new object types from it
        AuctionItem.newUnattached = Stored.newUnattached();
    
        // Other inits for AuctionItem.prototype:
        ...attach default properties and methods to AuctionItem.prototype;
    }
    Now you can create new AuctionItem objects by

    var obj = new AuctionItem( folder, title, ... );

    Now new AuctionItem objects can use all of the built-in Node and Stored methods and properties, plus all of the default properties and methods that you assign to AuctionItem.prototype.

    When a previously created AuctionItem object is referenced, it is automatically loaded from the OODB as necessary, with the correct class.

    You can use the same technique to define your own object classes based on any built-in object class: Stored, Node, Folder, Discussion, Message, Chat, Link, or User, as well as the new classes you have defined.

    This is an extremely powerful technique for creating new kinds of objects and extending the Web Crossing environment.

    » Stored Object

    Stored objects are the primitive building blocks for making your own objects and classes of objects. The Stored class is the foundation for all persistent objects. Its properties and methods are inherited by all stored objects.

    A Stored object can hold any primitive JavaScript data-type: null, strings, numbers, booleans, and Dates, and can also hold other stored objects. (Storing any other kind of object will generate a run-time error.) For example,

    var s = new Stored();
    s.date = new Date();
    s.reminder = form.reminder;
    user.reminder = s;

    This code will create a new Stored object, save the current date/time and a "reminder" from the input form, and save this into the current user's record. All of this information is available later:

    if( user.reminder != null ){
        // Now user.reminder.date is the date the reminder was created
        // And user.reminder.reminder is the reminder message text
        ...process reminder;
    }

    By default, all non-built-in property values are automatically stored into the OODB. You can specify that some properties are local (not stored at all) or transactional (stored by storedCommit).
    Properties and methods Usage
    Stored.lookup( id ) Looks up an existing Stored object and returns it.

    id is a string which is either a pathname in the OODB folder hierarchy, or the s.storedUniqueId label for some object.

    This method will return an object with the same type that it was created with, as long as that type is available in your current JavaScript templates. (If the correct type is not available, then the type will be the underlying type of the original object, such as Folder, Node, Stored, etc.)

    If the object could not be located in the OODB, then returns null and sets error.

    Stored.newUnattached() Returns a new unattached Stored object, suitable for deriving new classes from Stored.
    storedIsAttached Returns true if the stored object is attached to the OODB
    storedUniqueId Returns the uniqueId string for a stored object. This can be used in a later Stored.lookup( id ).
    storedDetach() detaches a JavaScript Stored object from the OODB.
    storedConstructor (read-only) the name of the constructor for the class (from the OODB, so if this class does not exist in the current run-time, then the default base constructor was used)
    storedSetConstructor( newType ) Changes the type of an object in the OODB. newType is a string that is the name of the constructor function for the new class. Detaches the old object, and returns an object of the new type.
    storedIsLocal( propName ) Returns true if propName is for a local property (e.g. not stored into the OODB).
    storedIsTransact( propName ) Returns true if propName is for a transaction-type property (e.g. stored into the OODB on command).
    storedIsAuto( propName ) Returns true if propName is for an auto-stored property (e.g. stored into the OODB).
    storedMakeLocal( propName ) Makes the specified property to be local
    storedMakeTransact( propName ) Makes the specified property to be transaction-oriented
    storedMakeAuto( propName ) Makes the specified property to be auto-stored
    storedCommit() Saves all modified transaction-oriented properties into the OODB
    storedRollback() Reverts all transaction-oriented properties to the old value from the OODB
    storedIsFolder Returns true if the stored object is also a Folder
    storedIsDiscussion Returns true if the stored object is also a Discussion
    storedIsMessage Returns true if the stored object is also a Message
    storedIsNode Returns true if the stored object is also a Node
    storedIsChat Returns true if the stored object is also a Chat
    storedIsDocument Returns true if the stored object is also a Document
    storedIsLink Returns true if the stored object is also a Link
    storedIsUser Returns true if the stored object is also a User
    storedIsStoredArray Returns true if the stored object is also a StoredArray
    OTHERS all other property names are user-defined, and are stored in the Web Crossing database (except when specified as local)

    » StoredArray Object

    StoredArray objects are similar to standard JavaScript Array objects, except that they are stored in the Web Crossing object-oriented database. Note that StoredArray objects do not provide all of the methods available with the standard JavaScript Array, so for example you cannot use the normal sort() function to sort a StoredArray object. StoredArrays are based on the Stored object, so they inherit all the methods and properties of Stored objects.

    A StoredArray object is an array of any primitive JavaScript data-type: null, strings, numbers, booleans, and Dates, and can also hold other Stored objects. (Storing any other kind of object into a StoredArray will convert it to a string and store the string.) For example,

    var s = new StoredArray();
    s[0] = new Date();
    s[1] = form.reminder;
    user.tracking = s;

    This code will create a new StoredArray object, save the current date/time and a "reminder" from the input form, and save this into the current user's record.

    » Node Object

    Every location in the Web Crossing pathname hierarchy is derived from the Node class. So all of the following properties and methods are available for Folders, Discussions, Messages, Chat rooms, and Links.

    You can create Node objects and place them into Folders, and you can derive your own classes from the Node class.
    Properties and methods Usage
        -- Static Functions --
    new Node( parentFolder, title ) creates a new node with the specified title. parentFolder can be a Folder object or a pathname string.
    Node.lookup( pathname ) returns the object located by the specified pathname. Same as Stored.lookup( id ).
    Node.lookupArray( pathname ) returns an array of parents of the specified pathname, with the specified item the last one in the array. The first item in the returned array is always the top-level folder.
    Node.lookupMessageId( id ) returns Message object specified by id.
    Node.newUnattached() returns a new unattached Node object, suitable for use as a prototype in a class definition.
        -- Properties and Methods--
    nodeAuthor user who posted this location
    nodeBackground background for non-message items (if "", then inherited from its parent) (deprecated - see nodeBodyTag)
    nodeBanner same as nodeHeader. 
    nodeBodyTag Background for non-message items (if "", then inherited from its parent). The following path variables are now automatically tied into nodeBodyTag:

    path.wrap_Background
    path.wrap_BgColor
    path.wrap_TextColor
    path.wrap_LinkColor
    path.wrap_ALinkColor
    path.wrap_VLinkcolor
    path.wrap_BgOther for other kw=value... items

    All of these path variables are just the value, except for path.wrap_BgOther, which is a series of keyword=value settings, added into nodeBodyTag exactly as is. For example:

    path.wrap_BgColor = "#000000"
    path.wrap_BgOther = "onload='...'"

    will result in a nodeBodyTag of

    "BGCOLOR=#000000 onload='...'
    nodeChildren (not implemented) Array of child nodes
    nodeClearCounts() clears hits and posts counts for node and all nested items (not for Message).
    nodeContentType content type.
    nodeDateCreated date this location was created
    nodeDateModified date this location was modified
    nodeExport(fileName) export node to fileName (which can be any expression). Will append to an existing file. 
    Not for Message Item. 
    nodeFolderItemOther additional html text following the node's title in a folder listing
    nodeFooter footer (if "", then inherited from its parent)
    nodeHeader banner (if "", then inherited from its parent)
    nodeHier(fieldName) returns user defined node property. Checks all parents.
    fieldName is a user defined property name.
    nodeHits hits count, not for Message location (read only).
    nodeHitsDec() decrement hits count (calling this function for Message will decrement hits count for its Discussion).
    nodeHitsInc() increment hits count (calling this function for Message will increment hits count for its Discussion).
    nodeHostDir() get/set the host directory mapping for a folder .
    nodeHttpDownloads true iff the node supports Web-based downloads.
    nodeHttpDownloadsLocal true iff Web-based attachments can be downloaded, not for Message object.
    nodeHttpUploads true iff the node supports Web-based downloads.
    nodeHttpUploadsLocal true iff Web-based attachments can be downloaded, not for Message object.
    nodeInheritsAttachments true iff node inherits attachments (not for Message object).
    nodeIsTop true iff node is top level folder (read only).
    nodeName the name of an item in its parent Folder, must be unique in that Folder. Changing this name changes the static-style URL used to reference this object. The default (initial) name for a folder is the same as its title. The default (initial) name for any other kind of folder item is a unique integer.
    The property is read only for a Message.
    nodeNameFullUri name URI (read only).
    nodeNestedHits nested hits count, not for Message object (read only).
    nodeNestedPosts nested posts count, not for Message object (read only).
    nodeNetHasObjectionable true if node has an objectionable word list or is checking for phone numbers in posts, not for Message object (read only).
    nodeNetObjectionable actual objectionable-word list used for node, not for Message object (read only).
    nodeNetObjectionablePhone true if node is checking for phone numbers, not for Message object (read only).
    nodeObjectionable objectionable word list for the node in the pathname hierarchy, not for Message object.
    nodeOwnerDocument Top-level folder node
    nodeParent parent Folder, or parent Discusson for a Message, or null for the top-level Folder object
    nodeParentTitle(level) parent title at specified level.
    nodeParentTitleUrl(level) URL quoted parent title at specified level.
    nodeParentUrl(certificate, level) parent URL at specified level.
    certificate is a string that is the certificate for the current
    user/session.
    nodePathname Full pathname for this node. Each component of the pathname is URL-quoted, separated by "/" delimiters.
    nodePosts posts count, not for Message object (read only).
    nodePostsDec() decrement posts count (calling this function for Message will decrement posts count for its Discussion).
    nodePostsInc() increment posts count (calling this function for Message will increment posts count for its Discussion).
    nodeShowAuthor true to show the author of this location
    nodeTemplate template envelope for this location, not for Message object.
    nodeTitle title of the item. The title is the same as nodeName for Folders. Because a Folder's title must be unique, setting nodeTitle for a folder may not work. For all other Node objects, setting nodeTitle will always work.
    nodeTitleUrl URL quoted (blanks as %20, etc.) title of the item.
    nodeUrl URL for this location, using current session certificate, etc
    nodeValue data for folder/discussion heading, or message body
    nodeVirtualArea true if the node is a virtual area (e.g. backpaths stop with this node)
    OTHERS all other property names are user-defined, and are stored in the Web Crossing database (except when specified as local)
        -- Display --
    nodeDestroy() destroys an open folder, discussion, message, chat, or link
    nodeDisplay() constructs the display page for a node. Only used for actual Node objects and user-defined objects derived from Node. The built-in method just calls this.nodeDisplayHeader, this.nodeDisplayContent, and this.nodeDisplayFooter
    nodeDisplayHeader(showBanner, showTitle ) constructs the header for a display page for a node. Only used for actual Node objects and user-defined objects derived from Node. The built-in method puts up the initial <HTML> tag and heading, a <BODY> tag, and the standard banner for the page, the title and backpath. showBanner and showToolbar are optional and default to true. If set to false, then the page banner and node title are not displayed. 
    nodeDisplayContent() constructs the content area for a display page for a node. Only used for actual Node objects and user-defined objects derived from Node. The built-in method doesn't display anything. 
    nodeDisplayFooter( showToolbar ) constructs the footer for a display page for a node. Only used for actual Node objects and user-defined objects derived from Node. The built-in method displays <p> followed by the standard footing and closing BODY and HTML tags. 

    showToolbar is optional and defaults to true. If set to false, then the default toolbar is not added by nodeDisplayFooter. 

    nodeIcon( extra ) <img...> tag for the default icon for this location. An optional parameter can be specified which is additional text to add to the <img...> tag.
    nodeIconFilename Returns the filename of the icon to use in a folder listing. This is the same icon as returned by nodeIcon, but nodeIcon returns the full <img...> tag.
    nodeListItems true iff node items are to be listed.
    nodeMarkAsRead(userObj) mark node as having been read.
    userObj parameter is a User object.
    nodeMarkAsReadAll(userObj) mark node and all of its children as having been read.
    userObj parameter is a User object.
    nodeSortSeq sort sequence in the item's parent folder. Higher numbers are sorted to the top. Not for Message object.
        -- Structure --
    nodeMoveTo( toFolder ) moves any non-Message object to a new Folder. Returns null if no error, or an error message string.
    nodeMoveTreeTo(destFolder) Move entire node-tree to another Folder. Not for Message item.
    destFolder is a Folder object where the tree will be moved.
    nodeInsertBefore( newChild, refSibling ) (not implemented)
    nodeReplaceChild( newChild, oldChild ) (not implemented)
    nodeRemoveChild( child ) (not implemented)
    nodeAppendChild( newChild ) (not implemented)
    nodeHasChildren() (not implemented)
    nodeFirstChild() (not implemented)
    nodeLastChild() (not implemented)
    nodePreviousSibling() (not implemented)
    nodeNextSibling() (not implemented)
    nodeAttachments list of node's attachments.
    nodeAddAttachment( attachment ) Add an attachment to a node object; return value is the attachment object. The parameter attachment may be a document object, the storedUniqueId of a document object, or a MIME container using CRLF line delimiters. Using a storedUniqueId as the parameter permits attaching the same object to more than one node.

    A MIME container starts with a partial heading that must Content-Type and Content-Transfer-Encoding, and may include other header lines.

    The heading is followed by a blank line, followed by the data.

    For example, the following is a short text file attachement:

    Content-Type: text/plain; name="test.doc"
    Content-Transfer-Encoding: 8bit
    
    This is a text file attachement example body.
    
    The following example will take an uploaded file and add it as an attachment to the current location.
    %% macro showUpload %%
        %% nop // Display an upload form to add an attachment to the
    current location %%
        %% if !location %%
          No location to upload to.
          %% return %%
        %% endif %%
        Test enclosure uploads. This form will add an attachment to the
    current location.
        <p>
        <FORM name=addDiscussionForm METHOD="POST"
    enctype="multipart/form-data" %%nop %%
          ACTION="%% urlBase %%processUpload@%% certificate %%@%% location
    %%">%%nop%%
        Attachment: <input type=file name=attachment size=30>
        <p>
        <input type=submit value=" Add Attachment ">
        </FORM>
    %% endmacro %%
    
    %% command processUpload(){
        // Process an upload to add an attachment to the current location
        if( location == null ){
          + "No location for the attachment";
          return;
        }
        if( location == topLevelFolder ){
          + "Cannot add the attachment to the top-level folder";
          return;
        }
        var h = Mime.formHeader( "attachment" );
        if( h == null || h.indexOf( 'filename=""' ) > 0 ){
          + "No attachment";
          return;
        }
        var attach = new ByteBuffer();
        attach.append( h );
        attach.crlf();
        attach.crlf()
        attach.append( form.attachment );
        location.nodeAddAttachment( attach );
        + "Attachment added";
    } %%
    
    nodeRemoveAttachment(attID) removes attachment.
        -- Access Control --
    nodeClearAccess() clears node's access list.
    nodeHasAccess returns true if the node has its own access list. Set this property to true to create an access list if there isn't one already, or to false to remove any existing access list.
    nodeHostIds Host users Ids list (read only property).
    nodeHosts(delim) returns list of Host users names separated by delim
    nodeModeratedUserIds Moderated users Ids list (read only property).
    nodeModeratedUsers(delim) returns list of Moderated users names separated by delim
    nodeNoAccessUserIds No Access users Ids list  (read only property).
    nodeNoAccessUsers(delim) returns list of No Access users names separated by delim
    nodeParticipantIds Participant users Ids list  (read only property).
    nodeParticipants(delim) returns list of Participant users names separated by delim
    nodeReadOnlyUserIds Read Only users Ids list  (read only property).
    nodeReadOnlyUsers(delim) returns list of Read Only users names separated by delim
    nodeUserAccess( user ) returns the user access to a node. The returned access is "host", "participant", "moderated", "readOnly", or "none". If the node does not have its own access list, then the parent's access list is used.
    nodeSetUserAccess( user, mode ) sets the user access to a node. The access mode can be "host", "participant", "moderated", "readOnly", or "none". If the node does not have its own access list, one is added automatically.
    nodeUserCanView( user ) returns true if the user can view this location.
    nodeUserCanPost( user ) returns true if the user can post to this location (this will return true even if the user posts are moderated).
    nodeUserIsModerated( user ) returns true if the user posts are moderated at this location.
    nodeUserIsHost( user ) returns true if the user is a host for this location.

    » Folder Object

    The Folder object can use all of the properties/methods of a Node object, plus the following.
    Properties and methods Usage
    new Folder( parentFolder, title ) creates a new folder with the specified title. parentFolder can be a Folder object or a pathname string.
    folderAddBtree("name sortspec") adds a new btree to the folder. 
    The name must be unique. This function will ignore a previously defined name. 
    The sortspec is exactly the same spec that you can pass to WCTL pathSort command, including URL quoting.
    folderAddDiscussions true if discussions may be added to this folder.
    folderAddLinks true if links may be added to this folder.
    folderAddSubfolders true if Folders may be added to this folder (read only see folderSetAddSubfolders() function).
    folderAddSubfoldersOnce true iff only Folders may be added to this folder, but they may only contain Discussions (read only see folderSetAddSubfoldersOnce() function).
    folderArchiveDays the number of days before a discussions contained in the Folder expire. 
    folderArchiveFolder If disposition for an elapsed discussion is to move to a
    folder, then this is the unique ID of the destination folder (see folderArchiveType property).
    folderArchiveType disposition of an elapsed discussion: move to a folder,
    delete, or purge. 
    folderBtreeKey(name) returns the sort key for the folder, in a parent btree. 
    name is a Stirng containing Btree name.
    folderBtreeList folder Btree names list (read only).
    folderBtreeSpec(name) returns the sortSpec for the specified btree. 
    name is a String containing Btree name.
    folderChatCount number of Chat rooms in the folder (read only).
    folderChatCreate(authorObj, newChatName) adds a Chat room to the folder.
    authorObj is a User object.
    newChatName is a String containinig new Chat room name.
    folderChild( ix ) returns folder nested objects by index (ix is [0..folderChildCount-1]). Returns null if there is no such child or ix is >= folderChildCount.
    folderChildCount the number of children in the folder (read only).
    folderDiscussionCount the number of Discussions in the folder (read only).
    folderDiscussionCreate(authorObj, newDiscussionName) adds a Discussion to the folder.
    authorObj is a User object.
    newDiscussionName is a String containinig new Discussion name.
    folderEmailFrom specifies From value for messages forwarded to the list, or blank to use the user's e-mail address.
    folderEmailMirror specifies Mailbox from which to read e-mail list messages.
    folderEmailPostsOk true if mail post-through is allowed into a folder.
    folderEmailPostThru true if messages posted to this Folder are forwarded to the e-mail list.
    folderEmailPostTo specifies email address to forward all messages posted to this Folder.
    folderEmailPW specifies password for folderEmailMirror mailbox.
    folderEmailReplyTo specifies address to which to send messages posted directly this folder.
    folderEmailStripSig specifies signature to strip from tail of incoming messages.
    folderFolderCount the number of Folders in the folder (read only).
    folderFolderCreate( authorObj, newFolderName ) adds a Folder to the folder.
    authorObj is a User object.
    newFolderName is a String containinig new Folder name.
    folderHasBtree(name) true if folder has Btree with specified name.
    name is a String containing Btree name.
    folderHasDiscussions true if folder has discussions (read only).
    folderHasFolders true if folder has folders  (read only).
    folderHasItems true if folder has items (read only).
    folderHasMessages(userObj) true if folder has messages.
    userObj is a User object.
    folderHasNewMessages(userObj) true if folder has new messages.
    userObj is a User object.
    folderHasOneDiscussion true if folder has one discussion (read only).
    folderHasOneFolder true if folder has one folder (read only).
    folderHasOneMessage(userObj) true if folder has one message.
    userObj is a User object.
    folderHasOneNewMessage(userObj) true if folder has one new message.
    userObj is a User object.
    folderImport(fileName) import from filename into the the folder.
    fileName is a String containinig a file name to import.
    folderInheritsByUserPreferences true if folder inherits its threading settings from its parent location.
    folderItems (userObj, Cert) displays items in a folder in standard format. The display stops when the user's limits on message count or total size are reached. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    folderItemsAll (userObj, Cert) displays all items in a folder in standard format. Ignores user's limits on message count and total size. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    folderItemsInContext (userObj, Cert) displays items in a folder in standard format, and includes one or more previous messages to show context. The display stops when the user's limits on message count or total size are reached.
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    folderItemsPrevious (userObj, Cert) displays items in a folder in standard format, showing previous items. The display stops when the user's limits on message count or total size are reached. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    folderLinkCount the number of Links in the folder (read only).
    folderLinkCreate(authorObj, newLinkName) adds a Link to the folder.
    authorObj is a User object.
    newLinkName is a String containinig new Link name.
    folderMessageCount(userObj) count of nested messages for the folder and specified user. This count does not include any moved messages, or any deleted-and-not-showing messages for the specified user.
    userObj is a User object.
    folderNetMessageTitle true if net effect of all settings is to request a title for all messages.
    folderNetReplyTo true if net effect of all settings is to show a Reply button with each message.
    folderNetSummaryButton true if net effect of all settings is to show an Outline button next to discussions in their folder listing.
    folderNetTreeView true if net effect of path hierarchy settings (ignoring user settings) is to show as threaded messages.
    folderNewMessageCount(userObj) count of new messages for the folder and the specified user.
    userObj is a User object.
    folderNewsGetFrom the external server for mirroring to get new messages from. Value is a ip address and optional port, such as "206.52.123.1:119" 
    folderNewsGetFromMode the mode for getting messages from an external news server.
    This value can be "pull" or "pushed" to pull new messages from the external server, or to have new messages pushed from the external server. 
    folderNewsGetPassword login username for mirroring when pulling new messages. 
    folderNewsGetUsername login password for mirroring when pulling new messages.
    folderNewsgroup newgroup name, also used as email username for email posts
    folderNewsMode controls the mirrorring a Web Crossing folder/newsgroup with external servers. This value can be "none," "site," or "custom," for no mirroring, use site defaults for mirroring, or use custom settings for this folder for mirroring. 
    folderNewsSendPassword login username for mirroring, when sending new messages. 
    folderNewsSendTo This is the external server for mirroring, for  sending new messages to. This value is a ip address and optional port, such as "206.52.123.1:119." 
    folderNewsSendUsername login username for mirroring when sending new messages. 
    folderNntpPostsOk true if allowed to post through nntp client without logging in.
    folderNoSubfolders true if no folders may be added to this folder (read only see folderSetNoSubfolders() function).
    folderRemoveBtree(name) removes a specified Btree from the folder.
    name is a Stirng containing Btree name.
    folderSelect(userObj, spec) select items from the folder.
    userObj is a User object, whose access permissions will be checked; a null parameter for the user is treated as an unknown user
    spec is an optional blank-delimited list of selection criteria, and defaults to all items.
    folderSetAddSubfolders() sets folderAddSubfolders property to true. Also
    sets properties folderAddSubfoldersOnce and folderNoSubfolders  to false.
    folderSetAddSubfoldersOnce() sets folderAddSubfoldersOnce property to true. Also
    sets properties folderAddSubfolders and folderNoSubfolders to false.
    folderSetNoSubfolders() sets folderNoSubfolders property to true. Also
    sets properties folderAddSubfoldersOnce and folderAddSubfolders to false.
    folderShowByUserPreferences true if threading display is from user preferences.
    folderShowsLinkToParentLocal true if folder shows link to parent.
    folderShowsLinkToPreviousLocal true if folder shows link to previous.
    folderShowsReplyToLocal true if folder local setting is to show a Reply button with each message.
    folderGetShowsReplyTo (userObj) true if folder shows a Reply button with each message.
    userObj is a user object.
    folderSetShowsReplyTo (flag) set the folder local show a Reply button with each message setting.
    flag can be set to 0 (no Reply button), 1 (Reply button), or -1 to inherit this setting from the parent location.
    folderShowsSummaryButtonLocal true if folder local setting is to show an Outline button next to discussions in their folder listing.
    folderGetShowsSummaryButton (userObj) true if folder shows an Outline button next to discussions in their folder listing.
    folderSetShowsSummaryButton (flag) set the folder local show an Outline button next to discussions in their folder listing setting.
    flag can be set to 0 (no Outline button), 1 (Outline button), or -1 to inherit this setting from the parent location.
    folderShowsThreadedLocal true if folder local setting is to show path hierarchy as threaded messages.
    folderGetShowsThreaded (userObj) true if folder shows path hierarchy as threaded messages.
    folderSetShowsThreaded (flag) set the folder local show path hierarchy as threaded messages setting.
    flag can be set to 0 (not threaded), 1 (threaded), or -1 to inherit this setting from the parent location.
    folderShowsTitleLocal true if folder local setting is to show titles for all messages.
    folderGetShowsTitle (userObj) true if folder shows titles for all messages.
    folderSetShowsTitle (flag) set the folder local show titles for all messages.setting.
    flag can be set to 0 (no title), 1 (title), or -1 to inherit this setting from the parent location.
    folderStandardHeading (userObj, Cert) shows standard heading for top-level or folder. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.

    » Discussion

    The Discussion object can use all of the properties/methods of a Node object, plus the following.
    Properties and methods Usage
    new Discussion( parentFolder, title ) creates a new discussion
    discussionAddBtree("name sortspec") add a new btree to the discussion. 
    The name must be unique. This function will ignore a previously defined name. 
    The sortspec is exactly the same spec that you can pass to WCTL pathSort command, including URL quoting.
    discussionBtreeKey(name) returns the sort key for the discussion, in a parent btree. 
    name is a String containing Btree name.
    discussionBtreeList discussion Btree names list (read only).
    discussionBtreeSpec(name) returns the sortSpec for the specified btree. 
    name is a String containing Btree name.
    discussionChildCount the number of message slots in the discussion, including any deleted or moved messages (read only).
    discussionEmailFrom specifies parent Folder From value for messages forwarded to the list, or blank to use the user's e-mail address.
    Read only property.
    See folderEmailFrom.
    discussionEmailMirror specifies parent Folder Mailbox from which to read e-mail list messages.
    Read only property.
    See folderEmailMirror.
    discussionEmailPostThru true if messages posted to parent Folder are forwarded to the e-mail list.
    Read only property.
    See folderEmailPostThru.
    discussionEmailPostTo specifies email address to forward all messages posted to paren Folder.
    Read only property.
    See folderEmailPostTo.
    discussionEmailPW specifies parent Folder password for discussionEmailMirror mailbox.
    Read only property.
    See folderEmailPW.
    discussionEmailReplyTo specifies address to which to send messages posted directly parent Folder.
    Read only property.
    See folderEmailReplyTo.
    discussionEmailStripSig specifies signature to strip from tail of incoming messages, in the parent Folder.
    Read only property.
    See folderEmailStripSig.
    discussionChild( ix ) returns nested messages by index (ix is [0..discussionChildCount-1]). Returns null if there is no such child or ix is >= discussionChildCount.
    discussionHasBtree(name) true if discussion has Btree with specified name.
    name is a String containing Btree name.
    discussionHasMessages(userObj) true if discussion has messages.
    userObj is a User object.
    discussionHasNewMessages(userObj) true if discussion has new messages.
    userObj is a User object.
    discussionHasOneMessage(userObj) true if discussion has one message.
    userObj is a User object.
    discussionHasOneNewMessage(userObj) true if discussion has one new message.
    userObj is a User object.
    discussionInheritsByUserPreferences true if discussion inherits its threading settings from its parent location.
    discussionNetMessageTitle true if net effect of all settings is to request a title for all messages.
    discussionNetReplyTo true if net effect of all settings is to show a Reply button with each message.
    discussionNetTreeView true if net effect of path hierarchy settings (ignoring user settings) is to show as threaded messages.
    discussionIsNew(userObj) true if discussion is new for the specified user.
    userObj is a User object.
    discussionIsPermanent true if iscussion is permanent, i.e. never expires. 
    discussionItemNumber the item number for a discussion. This number is assigned when the discussion is first created and never changes. You can use this number in a pathname URL to the item. 
    Read only property.
    discussionItems (userObj, Cert) displays items in a discussion in standard format. The display stops when the user's limits on message count or total size are reached. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    discussionItemsAll (userObj, Cert) displays all items in a discussion in standard format. Ignores user's limits on message count and total size. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    discussionItemsInContext (userObj, Cert) displays items in a discussion in standard format, and includes one or more previous messages to show context. The display stops when the user's limits on message count or total size are reached.
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    discussionItemsPrevious (userObj, Cert) displays items in a discussion in standard format, showing previous items. The display stops when the user's limits on message count or total size are reached. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    discussionMessageCount(userObj) count of nested messages for the discussion and specified user. This count does not include any moved messages, or any deleted-and-not-showing messages for the specified user.
    userObj is a User object.
    discussionMessageCreate(userObj, msgTitle) adds a message to the discussion.
    authorObj is a User object.
    msgTitle is a String containinig new message name.
    discussionMessageId message Id of the discussion.
    discussionMessageTotal total number of messages in a discussion, including all deleted and moved messages.
    discussionMimeFrom the "From" header for incoming MIME-formatted messages.
    discussionMimeOther other heading fields/values for incoming MIME-formatted messages. From/To are kept separately, all other header values are in other, including Reply-To. (discussionMimeReplyTo is a convenience property to extract the Reply-To value from the discussionMimeOther values.)
    discussionMimeReplyTo the "Reply-To" header for incoming MIME-formatted messages (read only).
    discussionMimeReplyToNet same as discussionMimeReplyTo, except that discussionMimeFrom is returned if
    there is no reply-to address. Read only property.
    discussionMimeTo the "To" header for incoming MIME-formatted messages.
    discussionNewMessageCount(userObj) Count of new messages for the discussion and the specified user.
    userObj is a User object.
    discussionNntpMessageId the explicit message ID string (from an NNTP post or email post) if present, or the empty string if not.
    discussionRemoveBtree(name) removes a specified Btree from the discussion.
    name is a Stirng containing Btree name.
    discussionSelect(userObj, spec) select items from the discussion.
    userObj is a User object, whose access permissions will be checked.
    spec is an optional blank-delimited list of selection criteria, and defaults to all items.
    discussionSource returns the source of a discussion: 
        http -- posted through a web browser
        stmp -- posted to an inbox from an incoming smtp
    email message
        pop3 -- from a mirrored email list, pulled from
    the list's pop3 mailbox
        imap -- posted to an imap folder via an imap client
        nntp -- posted via a news client
        local -- created by WCTL or JavaScript scripts 
        direct -- created by a direct-access-protocol request
    discussionShowByUserPreferences true if threading display is from user preferences.
    discussionShowsLinkToParentLocal true if discussion shows link to parent.
    discussionShowsLinkToPreviousLocal true if discussion shows link to previous.
    discussionShowsReplyToLocal true if discussion local setting is to show a Reply button with each message.
    discussionGetShowsReplyTo (userObj) true if discussion shows a Reply button with each message.
    userObj is a user object.
    discussionSetShowsReplyTo (flag) set the discussion local show a Reply button with each message setting.
    flag can be set to 0 (no Reply button), 1 (Reply button), or -1 to inherit this setting from the parent location.
    discussionShowsThreadedLocal true if discussion local setting is to show path hierarchy as threaded messages.
    discussionGetShowsThreaded (userObj) true if discussion shows path hierarchy as threaded messages.
    discussionSetShowsThreaded (flag) set the discussion local show path hierarchy as threaded messages setting.
    flag can be set to 0 (not threaded), 1 (threaded), or -1 to inherit this setting from the parent location.
    discussionShowsTitleLocal true if discussion local setting is to show titles for all messages.
    discussionGetShowsTitle (userObj) true if discussion shows titles for all messages.
    discussionSetShowsTitle (flag) set the discussion local show titles for all messages.setting.
    flag can be set to 0 (no title), 1 (title), or -1 to inherit this setting from the parent location.
    discussionStandardHeading (userObj, cert) shows standard heading for a discussion. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    emailNotify() will send emails to subscribed users and any external email list to which we post-through.
    messageIx always returns -1 for a discussion (read only)
    treeIx always returns -1 for a discussion (read only)
    treeChildCount the number of messages in the discussion, not counting deleted or moved messages (read only)
    treeChild( treeIx ) returns nested messages in threaded-message order by index (ix is [0..treeChildCount-1]). Returns null if there is no such child or ix is >= treeChildCount.
    treeParentIx always returns -1 for a discussion (read only)
    treeNextSibIx always returns -1 for a discussion (read only)
    treePrevSibIx always returns -1 for a discussion (read only)
    treeDepth always returns -1 for a discussion (read only)

    » Message Object

    The Message object can use all of the properties/methods of a Node object (except where noted), plus the following.
    Properties and methods Usage
    new Message( parentDiscussion[, title] ) appends a new message to parentDiscussion
    new Message( parentMessage[, title] ) makes a new hierarchical message under parentMessage
    emailNotify() will send emails to subscribed users and any external email list to which we post-through.
    messageDepth the nesting depth in the hierarchical threaded message tree (read only).
    messageEmailFrom specifies parent Folder From value for messages forwarded to the list, or blank to use the user's e-mail address.
    Read only property.
    See folderEmailFrom.
    messageEmailMirror specifies parent Folder Mailbox from which to read e-mail list messages.
    Read only property.
    See folderEmailMirror.
    messageEmailPostThru true if messages posted to parent Folder are forwarded to the e-mail list.
    Read only property.
    See folderEmailPostThru.
    messageEmailPostTo specifies email address to forward all messages posted to paren Folder.
    Read only property.
    See folderEmailPostTo.
    messageEmailPW specifies parent Folder password for messageEmailMirror mailbox.
    Read only property.
    See folderEmailPW.
    messageEmailReplyTo specifies address to which to send messages posted directly parent Folder.
    Read only property.
    See folderEmailReplyTo.
    messageEmailStripSig specifies signature to strip from tail of incoming messages, in the parent Folder.
    Read only property.
    See folderEmailStripSig.
    messageExists tells whether a message exists or not (deleted or moved message return false). Setting this property to false will delete a message. Once deleted, the message cannot be "undeleted".
    messageHasMessages(userObj) true if message has any child messages (replies) in the hierarchical threaded message tree.
    userObj is a User object.
    messageHasNewMessages(userObj) true if message has any new child messages (replies) in the hierarchical threaded message tree.
    userObj is a User object.
    messageHasOneMessage(userObj) true if message has one child message (reply) in the hierarchical threaded message tree.
    userObj is a User object.
    messageHasOneNewMessage(userObj) true if message has one new child message (reply) in the hierarchical threaded message tree.
    userObj is a User object.
    messageIsDeleted true if a message has been deleted (read only). 
    messageIsNew (userObj) is new for the specified user.
    userObj is a User object.
    messageItemNumber the item number for a message. This number is assigned when the discussion is first created and never changes. You can use this number in a pathname URL to the item. 
    Read only property.
    messageItems (userObj, Cert) displays items in a message in standard format. The display stops when the user's limits on message count or total size are reached. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    messageItemsAll (userObj, Cert) displays all items in a message in standard format. Ignores user's limits on message count and total size. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    messageItemsInContext (userObj, Cert) displays items in a message in standard format, and includes one or more previous messages to show context. The display stops when the user's limits on message count or total size are reached.
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    messageItemsPrevious (userObj, Cert) displays items in a message in standard format, showing previous items. The display stops when the user's limits on message count or total size are reached. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    messageIx returns the message index in conversational order, 0 origin (read only)
    messageListItem (userObj, cert, links, threaded) displays a message without "Mark", "Reply", "Edit", "Delete", "Move" links.
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    links and threaded parameters are optional and default to false.
    messageListItemLinks (userObj, cert) displays a message with "Mark", "Reply", "Edit", "Delete", "Move" links.
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    messageMessageCount(userObj) count of child messages for the message.
    userObj is a User object.
    messageMessageCreate(userObj, msgTitle) makes a new hierarchical message under message.
    authorObj is a User object.
    msgTitle is a String containinig new message name.
    messageMessageId Id of the message.
    messageMimeFrom the "From" header for incoming MIME-formatted messages.
    messageMimeOther other heading fields/values for incoming MIME-formatted messages. From/To are kept separately, all other header values are in other, including Reply-To. (messageMimeReplyTo is a convenience property to extract the Reply-To value from the messageMimeOther values.)
    messageMimeReplyTo the "Reply-To" header for incoming MIME-formatted messages (read only).
    messageMimeReplyToNet same as messageMimeReplyTo, except that messageMimeFrom is returned if
    there is no reply-to address. Read only property.
    messageMimeTo the "To" header for incoming MIME-formatted messages.
    messageNewMessageCount(userObj) count of new child messages for the message and the specified user.
    userObj is a User object.
    messageNntpMessageId the explicit message ID string (from an NNTP post or email post) if present, or the empty string if not.
    messageSelect(userObj, spec) select items from the threaded messages tree.
    userObj is a User object, whose access permissions will be checked.
    spec is an optional blank-delimited list of selection criteria, and defaults to all items.
    messageSource returns the source of the message:
       http -- posted through a web browser
       stmp -- posted to an inbox from an incoming smtp email message
       pop3 -- from a mirrored email list, pulled from the
    list's pop3 mailbox
       imap -- posted to an imap folder via an imap client
       nntp -- posted via a news client
       local -- created by WCTL or JavaScript scripts
       direct -- created by a direct-access-protocol request
    messageStandardHeading (userObj, Cert) shows standard heading for a discussion. 
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    messageText message body. 
    messageTreeLabel returns label for a nested item, 1 origin, e.g. "3.2.1.5".
    messageTreeTitle returns the title of a message.
    threadedMessageListItem (userObj, certificate, depth) displays a message in threaded format without "Mark", "Reply", "Edit", "Delete", "Move" links.
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    depth is the nesting depth in the hierarchical threaded tree.
    threadedMessageListItemLinks (userObj, certificate, depth) displays a message in threaded format with "Mark", "Reply", "Edit", "Delete", "Move" links.
    userObj is a User object.
    cert is a string that is the certificate for the current user/session.
    depth is the nesting depth in the hierarchical threaded tree.
    treeIx the message index in threaded-message order, 0 origin (read only).
    treeChildCount the total number of nested messages in threaded-message order, not including any deleted or moved messages (read only).
    treeChild( treeIx ) returns nested messages in threaded-message order by tree-index in the discussion (ix is [0..discussion.treeChildCount-1]). Returns null if there is no such child or ix is >= discussion.treeChildCount.
    treeParentIx the tree-index of the parent message in threaded-message order, 0 origin (read only).
    treeNextSibIx the tree-index of the next sibling in threaded-message order, 0 origin, or -1 if no next sibling (read only).
    treePrevSibIx the tree-index of the previous sibling in threaded-message order, 0 origin, or -1 if no next sibling (read only).
    treeDepth the nesting depth of this message in threaded-message order, 0 for top-level messages (read only).

    » Chat Object

    The Chat room object can use all of the properties/methods of a Node object, plus the following.
    Properties and methods Usage
    new Chat( parentFolder, title ) creates a new chat room
    chatHasTables true if chat has mulitple tables (read only).
    chatIsAnonymous true if the chat room allows anonymous users
    chatIsPlayLoopback true if recorder file will play continuously in loopback mode.
    chatMainRoom common room for a chat table. 
    chatMaxUsers maximum users for a chat table. When this number is reached, an overflow table will be started automatically.
    chatPlayFile playback file name for a chat table.
    chatPlayMillisecs total playback time in milliseconds for a chat table. 
    chatRecordFile recording file name for a chat table.
    chatTables list of tables in a room (includes self). Read only property.

    » Link Object

    The Link object can use all of the properties/methods of a Node object, plus the following.
    Properties and methods Usage
    new Link( parentFolder, title ) creates a new link
    linkDescription descriptive text for the link.
    linkShowDescription true if the link description (nodeValue) is show in the folder listing
    linkTo Node object the link points to. If there's no such object, null is returned.
    linkUrl location in the current site or URL to another site

    » Document Object

    The Document object can use all of the properties/methods of a Stored object, plus the following.
    nodeAddAttachment.
    documentData returns the document data (header and data) as a ByteBuffer using an 8-bit (binary) content type.
    documentDataAsMimeBinary returns the document data (header and data) as a ByteBuffer using an 8-bit (binary) content type.  (deprecated - use documentData)
    documentDataAsMimeQuoted returns the document data (header and data) as a ByteBuffer using a quoted content type if appropriate for the data. 
    documentDataBinary returns the contents of an attachment as a ByteBuffer in binary with no MIME header.
    documentImgHeight returns the image height in pixels of a document or attachment that is an image, or 0 for a non-image
    documentImgWidth returns the image width in pixels of a document or attachment that is an image, or 0 for a non-image
    documentImgWidthHeight Returns the string 'width="ww" height="hh"' where ww is the width and hh the height in pixels of a document or attachment that is an image, or the empty string for a non-image.
    documentIsImage returns true if the Content-Type is an image 
    documentIsText returns true if the Content-Type is text 
    documentName returns the name of the attachment, from the Content-Disposition header if present, or else from the Content-Type header. If the header does not specify a name, then this is the empty string. 
    documentSize returns the size of the attachment file (header and body using default encoding) 
    documentSizeBinary returns the size of the attachment file in binary, without the header

    » User Object

    The User object is derived from the Stored object, so all of the Stored methods and built-in properties are available.
    Properties and methods Usage
    new User( name ) creates a new user with the specified name.

    If there is an error, null is returned, and error is set to an error message.

    User.setUser( user ) Changes the current logged-in user as specified. Also installs a new certificate for the user, or switches to the previously assigned one if present and current. Sets error to indicate results of the switch.
    User.open( userId ) Returns the User object for the user with the specified id.

    Opens the user from either its u.userId string, which is the same as a WCTL user-id, or from its u.storedUniqueId string.

    If there is an error, null is returned, and error is set to the error message.

    Note that the WCTL/u.userId userId values are different from the u.storedUniqueId strings.

    User.openWctl( userId ) Open a user by WCTL ID. Returns JS User object.
    userId is a WCTL user ID.
    User.lookup( username ) Returns the User object for the user with the specified name.

    If there is an error, null is returned, and error is set to the error message.

    User.loggedIn( only, exclude, sort, max, getRemoteAddr ) Get information about currently logged-in usrs. Returns an object containing a property "users". This property is an array object that is a list of logged in User objects.

    only : an optional user, or an array of users, or a string of userIds, that are the only ones to return. Default is all logged in users.
    exclude : an optional user, or an array of users, or a string of userIds, to exclude from the returned list. Default is to exclude no users.
    sort : an optional string specifying the sort sequence. This can be "user.userFirst", "user.userLast", or "none". Defaults to "user.userFirst".
    max : maxium number of users to return, default is unlimited
    getRemoteAddr : true to add remoteAddress, an array of strings, to the returned object. This is useful in deciding whether a login is a duplicate or not (if from a different IP, then it is a duplicate login) 

    User.login( name, password ) Checks if a user's login with the specified username/password is valid. 

    Returns the User object for the user, if the user's login with the specified user's name and password is successful.

    name is a string containing a user's name to attempt to log in.
    password is a string containing a user's password to attempt to log in.

    User.guest Returns the user ID for a guest user. You can use this ID for setting and checking user access to a particular location.
    User.other Returns the user ID for "other registered users". You can use this ID for setting and checking user access to a particular location.
    addUserToGroup( group ) Adds the user to a group with the specified group's name. If the user is successfully added to the group, true is returned. false is returned, if the user is already added to the group, the group does not exist, or an error occurs.

    group is any string expression containing the group's name.

    removeUserFromGroup( group ) Removes the user from a group with the specified group's name. If the user is successfully removed from the group, true is returned. false is returned, if the user is already removed from the group, the group does not exist, or an error occurs.
     

    group is any string expression containing the group's name.

    storedXxx all of the Stored properties and methods are available for User objects
    getUserPathAccess( location ) Returns the user's access to the specific location. This can be "host", "participant", "moderated", "readOnly", or "none". If the user is not added to the access list of the specific location, returns undefined.

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    getUserPicture( pictureProperties ) URL to user's picture (i.e. the HTML element type IMG and its attributes such as image source, align, width, height, border, and others).
    If the user hasn't supplied his/her own picture, the function returns URL to the default user's picture.

    pictureProperties is a string containing image properties (attributes). This can be "height=150", "width=200", etc. The pictureProperties argument is optional.

    setUserPicture (picture) Set a user's picture. picture is a string containing the binary image. This must be a valid jpeg or gif image, or the empty string. 
    setUserPathAccess( location, access ) Sets a user's access to the specific location (i.e. makes the user host, participant, moderated, read-only at the specific location, removes the user's access to the specific location or removes the user from the explicit access list pathClearAccess to clear the access list of the specific location).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    access is a string containing the user's access to the current location. This can be "host", "participant", "moderated", "readOnly", "none", or "default".
    "default" access removes the user from the explicit access list pathClearAccess to clear the access list.

    user2ndLine second line of info
    userAddSubscriptions
    ( location, subscriptionTypes )
    Subscribes the user to the specific location (folder or discussion) by the specified subscription types (i.e. allowing the user to receive new messages by web, by e-mail, and to receive digests of new messages by e-mail).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    subscriptionTypes is a string containing the literals that define the subscription type:
    "m" - allows the user to receive new messages by web;
    "e" - allows the user to receive new messages by e-mail;
    "d" - allows the user to receive digests of new messages by e-mail.

    userAlias e-mail alias for the user (i.e. the user's real name added to the user's e-mail address for outgoing mail)
    userApop user APOP password (stored as clear text)
    userAuthenticate( passwd ) returns true if passwd is the correct clear-text password for a user
    userAwayHours number of hours user has been away for a user ID (e.g. the number of hours between the current login and the prior login). If the user has been away less than one hour, 0 is returned.
    userBio user bio
    userBouncedEmail returns true if the user has bounced e-mail (i.e. no messages will be sent to the user, until his/her next login and check/confirm his/her e-mail address). If the e-mail is not stopped sending to the user, false is returned.
    userCanAddDiscussions( location ) (read-only) true if the user can add discussions to the specific location (i.e. folder). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userCanAddFolders( location ) (read-only) true if the user can add folders to the specific location (i.e. folder). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userCanAddLinks( location ) (read-only) true if the user can add links to the specific location (i.e. folder or discussion). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userCanAddMessages( location ) (read-only) true if the user can add messages to the specific location (i.e. discussion). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userCanDelete( location ) (read-only) true if the user can delete the specific location (i.e. folder, discussion, message, chat room and link). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userCanEdit( location ) (read-only) true if the user can edit the specific location (i.e. folder, discussion, message, chat room and link). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userCanView( location ) (read-only) true if the user can view the specific location (i.e. folder, discussion, message, chat room and link). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userChatPreference type of chat service used in a chat room for user. This can be "JavaApplet" or "HTML".
    userCheckChangePassword if true, the user is asked to change his/her password the next time he/she logs in.
    userCheckRemoteAddr flag for checking that user certificate is from the same IP address as originally.
    userClearMarks() clears all highwater marks for a user -- it makes it just
    as if the user had just registered in terms of what will be considered "new material".
    userClearSubscriptions() Clears a user's entire subscription list (i.e. cancels all user's subscriptions).
    userDate date/time a user was created
    userDefaultDomain default domain name of the server used to provide e-mail boxes for the registered Web Crossing users.
    userDigestTimes returns a String containing the list of e-mail digest mailing times for the user.
    userEmail email address for user
    userEmailAliases user's e-mail aliases (i.e. multiple different e-mail addresses for the same user), or "" if the user doesn't have e-mail aliases set in his or her preferences.

    Sysop can allow users to set their own e-mail aliases. If the users are not allowed to set their own e-mail aliases, then only the sysop or superhosts can set e-mail aliases for users.

    The new e-mail alias is not set for the user, if it is duplicate alias, or already in use for someone else.

    userEmailCode email code for user validation
    userFolderSortBy sort sequence used to list folders for the user. This can be "oldestCreated", "newestModified", "default", "newestCreated", or "alphabetically".
    userForwardTo email address to foward mail to, or "" for no forwarding
    userFullEmail flag for sending URL notification or full messages in e-mail for user's e-mail subscriptions.
    userGroups list of user group unique IDs the user belongs to, or "" if the user doesn't belong to any user group.
    userHasCookie true if user was validated by a webxUser cookie (read only).
    userHasImap true if the user has an IMAP access to his or her e-mail account.
    userHasNewEmail returns true if the user has any new (unread) e-mail messages (i.e. the user is subscribed to any folder or discussion by e-mail and he has received new e-mail messages). Otherwise, returns false.
    userHasNoAccess( location ) (read-only) true if the user has no access to the specific location (i.e. if the user has no access, he does not even see the location area at all -- its link is not present in its parent folder for this user).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userHasPicture returns true if the user's picture is provided in the user's preferences. Otherwise, returns false.
    userHasPop3 true if the user has a POP3 e-mail account.
    userHasRespBodySize (read-only) true if the user has specified a font size for the user's message bodies.
    userHasRespInfoSize (read-only) true if the user has specified a font size for the secondary information in messages.
    userHasRespNameSize (read-only) true if the user has specified a font size for the user names in a message.
    userHasSubscriptions returns true if the user has any subscriptions to folders or discussions (i.e. the user has any subscriptions in the subscriptions list in the user's preferences page). Returns false  if the user doesn't have anything in his subscription list.
    userHomepage user's home page URL
    userHasWebEmail true if the user has a Web e-mail account. Read-only property.
    userImapIsSpecific Checks whether the default site settings are used, or whether the user property (userImapSpecific) is used to determine if the user has the IMAP e-mail service enabled or not.
    If true  - the user property (userImapSpecific) is used.
    userImapSpecific user specific property telling if the IMAP e-mail service is enabled for this user.
    userImportMailSpool(data) Import Unix mail spool data as email messages for a user.
    userInboxIsFull (read-only) true if a number of messages in the user's Inbox is greater or equal to the limit set in the user preferences or in the sysop control panel.
    userInboxOpen() returns user Inbox Folder object.
    userIsCgiUser (read-only) true if the user is sysop/superhost or is a member of the cgiUsers group
    userIsGuest (read-only) true if the user is a guest (i.e. the user has not logged in and has posted a message as a guest user)
    userIsHost( location ) (read-only) true if the user is a host for the location (i.e. folder, discussion, message, chat room and link). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userIsHttpBasic( certificate )

    (read-only) true if the current user was authenticated through HTTP Basic.

    certificate is a string that is the certificate for the current user/session.

    userIsMember( group ) Checks for the user's membership in a group

    Returns true if the user is a member of the group with the specified name. Returns false if the user is not a member of the group. The result of this property is undefined if there is no group with the specified name.

    group : is any string expression containing the group's name.

    userIsModerated( location ) (read-only) true if the user is moderated at the specific location (i.e. folder, discussion, message, chat room and link).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userIsParticipant( location ) (read-only) true if the user is a participant at the specific location (i.e. folder, discussion, message, chat room and link).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userIsWctlUser (read-only) true if the user is sysop/superhost or is a member of the wctlUsers group
    userPickedEmailBox true if the user has chosen whether to receive e-mail to a local mailbox or to have it forwarded to an external mailbox.
    userPop3IsSpecific Checks whether the default site settings are used, or whether the user property (userPop3Specific) is used to determine if the user has the POP3 e-mail service enabled or not.
    If true  - the user property (userPop3Specific) is used.
    userPop3Specific user specific property telling if the POP3 e-mail service is enabled for this user.
    userIsProvisional returns true if the user is provisional or host user for the current location (i.e. users have a provisional status while their email address is being validated).
    userIsReadOnly( location ) (read-only) true if the user is a read-only at the specific location (i.e. the user can browse and read but is not allowed to add new messages, discussions, folders or links).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userIsRegistered (read-only) true if the user is registered (i.e. is not a special user ID such as User.other, and is not a guest user)
    userIsSubscribed( location ) returns true if the user is subscribed to the specific location (i.e. folder or discussion). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userIsSubscribedDigest( location ) returns true if the user is subscribed to keep track of new messages posted to the specific location (i.e. folder or discussion) and he has checked the Email Digest option (i.e. the user gets an email digest of new messages, sent to the user on a regular basis).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userIsSubscribedEmail( location ) returns true if the user is subscribed to keep track of new messages posted to the specific location (i.e. folder or discussion) and he has checked the Email option (i.e. the user gets an email message every time a new message is posted).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userIsSubscribedMsgs( location ) returns true if the user is subscribed to keep track of new messages posted to the specific location and he has checked the Check Messages option (i.e. the user sees new messages when he clicks on Check Messages, and sees new messages in his Message Center page).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userIsSuperhost (read-only) true if the user is a superhost (i.e. the user has basically sysop-level privileges except he can't change site service IPs, ports, etc. settings)
    userIsSysop (read-only) true if the user has sysop priviledges
    userIsUnknown (read-only) true if the user is an unknown user (i.e. the user has neither logged in nor posted as a guest)
    userLastLogin( date ) returns true if the last login date for a user ID is before a specific date

    date is the standard JavaScript Date object.

    userLastLoginValue returns the Date object with the prior login date/time before the last (or current) login for the user ID. null is returned, if the user has not been logged in Web Crossing yet.
    userLogoutTime user's logout time in minutes.
    userMailbox local e-mail address for a user (i.e. versus userEmail, which is the external e-mail address). 

    By default, every registered user is provided with the local e-mail address, this can be: UserName@EmailDomain.

    userMarkCurrent() Marks a user's subscription list as current (i.e. marks all user's subscribed-to folders and discussions "as read" if there are numerous messages she or he doesn't wish to read).
    userMaxData maximum number of data bytes in a list of user's messages.
    userMaxEmailMessages maximum number of e-mail messages allowed in the user's inbox. Returns 0 if the maximum number of e-mail messages is not specified in the user preferences. 

    If the maximum number of e-mail messages is not specified for the user, the site defaults set in the sysop control panel is used.

    userMaxMessages maximum number of messages to show in a list of messages for a user. Returns 0 if the maximum number of messages is not specified by the user.
    userName user's name, as First Last
    userNextDigest returns the Date object with the scheduled date/time when the next digest of messages will be sent for the user by e-mail (if any).
    Read-only property.
    userNextDigestCount returns a number of messages queued for e-mail digest to be sent for the user (read-only).
    userNextDigestList returns a list of messages queued for e-mail digest as message location unique IDs (read-only).
    userNewMessages( currentlocation, maxMessages, 
    skip, location )
    Returns the NewMessages object for the user.

    currentlocation is the unique id of the current folder or discussion.
    maxMessages is optional and defaults to all messages (-1).
    skip is optional and defaults to 0.
    location is the unique id of the folder or discussion and defaults to a top-level folder node.

    userOutsideEmail outside e-mail address for a user (i.e. the user's contact e-mail address).

    If the outside e-mail address for the user is empty, or the user has forwarding e-mail address, the property returns user's forward e-mail address to. "" is returned if no contact e-mail address and no forwarding e-mail address is set in the user's e-mail preferences.

    userPassword user's password. Set in clear text, read as MD5 hash
    userPictBorder returns true if the flag for showing the border around user pictures is turned on for the user. Otherwise, returns false.
    userPostCount Returns a number of posts tracked for a user if the option Track user posts is enabled. 0 is returned if the user hasn't posted any message or the option Track user posts is disabled.
    userPosts( userObj, count ) Returns a list of most recent posts by a current user as location unique IDs, if the option Track user posts is enabled and the user specified in the user argument has access permissions to the locations of the current user's posts.

    user is a User object of the user whose access permissions to the locations of the current user's posts is checked.
    count is a number of most recent posts by a user to display. count is optional and defaults to the 5 most recent messages.

    userRemoveSubscriptions
    ( location, subscriptionTypes )
    Cancels the user's subscription methods (i.e. allowing the user to receive new messages by web, by e-mail, and to receive digests of new messages by e-mail) to the current location (folder or discussion).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    subscriptionTypes is a string containing the literals that define the subscription type:
    "m" - allows the user to receive new messages by web;
    "e" - allows the user to receive new messages by e-mail;
    "d" - allows the user to receive digests of new messages by e-mail.

    userReplyTo returns true if the user preference to show a Reply button with each message is set. Otherwise, returns false.
    userRespBodySize font size for the user's message bodies (0 if not specified by the user.) The font size can be 1 through 6.
    userRespBodySizeNet font size for the user's message bodies. If user setting userRespBodySize is not specified, site default setting is returned.
    Read only property.
    userRespInfoSize font size for secondary information in a message (0 if not specified by the user.) The font size can be 1 through 6.
    userRespInfoSizeNet font size for for secondary information in a message. If user setting userRespInfoSize is not specified, site default setting is returned.
    Read only property.
    userRespNameSize font size for user names in a message (0 if not specified by the user.) The font size can be 1 through 6.
    userRespNameSizeNet font size for user names in a message. If user setting userRespNameSize is not specified, site default setting is returned.
    Read only property.
    setUserAllCurrent(date) set user as current for the whole site as of the specified date (defaults to now).
    date is a JS Date object.
    userShowPictures returns true if the flag for showing user pictures with messages is turned on for the user. Otherwise, returns false.
    userShowPrepared returns true if the flag for showing the "Page prepared for..." line for a user at the top of each conference page is turned on. Otherwise, returns false.
    userSpellCheckIgnores returns a list of personal spelling words for the user.
    userSubscribe( location ) Subscribes the user to the specific location, e.g.: folder or discussion (i.e. the Check Messages option is checked in the Set Subscriptions page of the specific location). 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userSubscribeDigest( location ) Subscribes the user to the specific location (folder or discussion) and allows him to receive digests of new messages by e-mail (i.e. the Email Digest option is checked in the Set Subscriptions page of the specific location).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userSubscribeEmail( location ) Subscribes the user to the specific location (folder or discussion) and allows him to receive new messages by e-mail (i.e. the Email option is checked in the Set Subscriptions page of the specific location).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userSubscribeMsgs( location ) Subscribes the user to the specific location (folder or discussion) and allows him to find new messages by logging in to the site and clicking on Check Messages, or through the Message Center page (i.e. the Check Messages option is checked in the Set Subscriptions page of the specific location).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userSubscriptionList( certificate ) user's subscription list, as displayed in the user's preferences page (i.e. the user's list of subscribed-to folders and discussions and subscription methods), or "" if the user doesn't have anything in his subscription list.

    certificate is a string that is the certificate for the current user/session.

    userSubscriptions list of locations for a user and whether they are subscribed to or not (i.e. a pathname of each location followed by a space and a flag whether the location is subscribed to or not), or "" if the user doesn't have anything in his subscription list.
    userSummaryButton returns true if the user preference to see an Outline button next to discussions listed in a folder is set. Otherwise, returns false.
    userThisLogin returns the Date object with the last (current) login date/time for the user ID. null is returned, if the user has not been logged in Web Crossing yet.
    userThreading returns true if the user prefers to view discussions as threaded messages, and returns false if the user prefers to view discussions as conversations.
    userThreadingBySite returns true if the user uses site preferences for viewing discussions. Otherwise, returns false.
    toString() convert a user object to a string. The username is returned.
    userUnsubscribe( location ) Cancels the user's subscription to the specific location, e.g.: folder or discussion. 

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userUnsubscribeDigest( location ) Cancels the user's subscription method to the specific location (folder or discussion) allowing the user to receive digests of new messages by e-mail  (i.e. the Email Digest option is unchecked in the Set Subscriptions page of the specific location).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userUnsubscribeEmail( location ) Cancels the user's subscription method to the specific location (folder or discussion) allowing the user to receive new messages by e-mail  (i.e. the Email option is unchecked in the Set Subscriptions page of the specific location).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userUnsubscribeMsgs( location ) Cancels the user's subscription method to the specific location (folder or discussion) by logging in to the site and clicking on Check Messages, or through the Message Center page (i.e. the Check Messages option is unchecked in the Set Subscriptions page of the specific location).

    location is a string containing the unique id of the Node object (i.e. location area), or the Node object itself.

    userUrls formatted URL list for the user (i.e. a comment of each URL as a link, one per line), or "" if the list of user's favorite URLs is empty.
    userUrlsRaw unformatted URL list for the user (i.e. one URL per line followed by a space and a comment) , or "" if the list of user's favorite URLs is empty.
    userUseCookies returns true if the flag for using cookies to keep track of username and password after user's login is enabled in the user's preferences. Otherwise, returns false.
    userWebEmailIsSpecific Check whether the default site settings are used, or whether the user property (userWebEmailSpecific) is used to determine if the user has the Web e-mail service enabled or not.
    If true  - the user property (userWebEmailSpecific) is used.
    userWebEmailSpecific user specific property telling if the Web e-mail service is enabled for this user.
    userId unique WCTL user-id string to use in a WebX URL or as a parameter to User.openWctl. (This is because the original WCTL unique-id-space for users is different than the Stored.storedUniqueId. So Stored.lookup( user.storedUniqueId ) will return the user object, just as User.openWctl( user.userId ) will return the same user. But user.storedUniqueId is not the same as user.userId.)
    userDestroy() destroys the user, removing it from the member directory and all user groups. Existing messages created by this user will still reference the deleted user record.
    OTHERS all other property names are user-defined, and are stored in the Web Crossing database (except when specified as local)

    » NewMessages Object

    The NewMessages object is a set of properties that are used to get information about locations of new messages for the user. The NewMessages object has the following read-only properties.
     
    Properties 
    and methods
    Usage
    messageList blank-delimited list of locations that have new messages for the Userobject.
    mostRecent returns the Date object with the date/time of the most recent new message from the last messageList for the User object.
    firstLocal location of the first local new message after messageList for the User object.

    » Site Object

    Properties and methods Usage
    siteCalendar base URL for calendar files, such as "http://your.site/Images/calendar". Does not include a final slash (/).
    siteDecryptList returns a comma-space delimited list of code numbers that are decrypted by this site .
    siteDocs base URL for sysop documentation, such as "http://your.site/Images/docs". Does not include a final slash (/).
    siteEmoticons base URL for emoticon graphics, such as "http://your.site/Images/e". Does not include a final slash (/).
    siteHelp base URL for user help files, such as "http://your.site/Images/help". Does not include a final slash (/).
    siteIcons base URL for icon graphics, such as "http://your.site/Images/i1". Does not include a final slash (/).
    siteImages base URL for image graphics, such as "http://your.site/Images/b5". Does not include a final slash (/).
    siteInstallCerts( certs ) returns ByteBuffer -- installs or replaces certificates. The certificates are a CR and/or LF delimited list of certificates. Any usage/traffic certificate replaces the prior usage/traffic certificate. Any plugin certificate replaces a prior plugin certificate for the same plugin code, or is added to the list of plugin certificates. The returned ByteBuffer is a list of error messages, or is null if there are no errors. Installing a plugin certificate with an organization name of "x" (e.g. the certificate is x#...) will remove that decryption code certificate
    siteIsDecrypted( n ) returns Boolean, evaluates to true iff n is a code number that is decrypted by this site
    siteMisc base URL for miscellaneous graphics and other files, such as "http://your.site/Images/m". Does not include a final slash (/).
    sitePictSizeButton width and height for standard-sized buttons, such as "WIDTH=68 HEIGHT=30"
    siteUsePop3 true if POP3 service is enabled
    siteUrlBase Relative URL base for Web Crossing commands with script name only such as "/WebX?".
    siteUrlBaseFull Full URL base for Web Crossing commands with script name such as "http://your.site/WebX?".
    siteUrlBaseSlash Relative URL base "/".
    siteUrlBaseSlashFull Full URL base such as "http://your.site/".
    OTHERS all other property names are user-defined, and are stored in the Web Crossing database (except when specified as local)


    » Global Functions and Properties

    Global Functions and Properties Usage
    allowDeny( ip, allowDenySpec, maxMsecs ) returns boolean, true if the ip is allowed.

    ip may be either a domain name or an absolute IP in dotted format, such as 123.4.5.6. Note that actual IP addresses are used, so if the incoming domain name cannot be resolved, this function will return false even though the input domain-name-string would appear to match the allowDeny spec.

    allowDenySpec is a list of patterns separated by commas or white space. Each entry in the list has the format

      a=allowPattern  -or-
        d=denyPattern
    where pattern is an IP address with optional "*" wildcards. For example, "a=*" will allow all IP addresses; "d=*" will deny all addresses, and "a=127.22.33.*" will allow all address with the specified first three bytes.

    The allow-deny list is processed in order, attempting to match the calling IP address. The first entry matching the calling IP is used to either accept or deny the connection. Denied connections are shut down without any notice.

    If the last entry in the allow-deny list is an allow, then there is an implicit d=* added to the end; if the last entry is a deny, then there is an implicit a=* added. If the list is empty, it is the same as "a=*"

    If any allow-deny entries include alphabetic characters, and the reverse-DNS lookup of the IP address is available, then the reverse-DNS will be checked against the patterns as well.

    maxMsecs is the maximum time to delay while doing domain-name and/or reverse-domain-name lookups, it defaults to 2 seconds. 

    libraryGlobal this is the "library" object copied to become the initial global object for each request.
    top during initialization, top is the same as libraryGlobal. During request processing, top is the same as request.
    wctlVar( varname ) returns a WCTL variable value, either as a string or an integer depending on the type of the variable. For example, wctlVar( "myVar" ).
    setWctlVar( varname, value ) set a WCTL variable. If the value is an integer-valued number, then the WCTL variable is set to an integer, otherwise it is set to a string. For example, setWctlVar( "myVar", 100 ).
    makeUrl( command, parameter ) returns a Web Crossing URL for command. This command is a shorthand for
    (site.siteUrlBase+"abc@"+certificate+"@"+parameter)
    If parameter is omitted, then it defaults to the normal "show" command for the current location. For example,
    makeUrl( "abc" )
    is the same as;
    (site.siteUrlBase+"abc@"+certificate+"@"+location)
    
    Returns normal URLs when they are short enough and the optional params argument is omitted.
    makeUrlFull( command [, paramString ]) returns a Web Crossing URL for command, where the current location is used to get the domain name (and location if paramString is omitted). Returns normal URLs when they are short enough and the optional params argument is omitted.
    email( rcptList, message, return ) sends an email message to a recipients list.

    Note that the email sent does not go though the EmailHandler filters; if this email is for a local user, it will be delivered regardless of any EmailHandlers.

    rcptList is a list of <username@domain>,....

    message is a fully-composed email message with a header, body, and CR-LF linebreaks. The To header in the message is totally independent of the rcptList of destinations -- To: can be anything, it is not actually used to deliver the message.

    return is the email return address, the address that undeliverable mail is sent to (the MAIL FROM: SMTP parameter). If this is not specified, then it is taken from the message From: header field. Messages must have a return address; if you don't specify it in the email call, and there is no From: field in the message header, then the email will not be sent. Specifying the return address allows you to use Email functions to automate handing of bounced messages.

    emailFilterDigest Filter called for all outgoing digest messages. emailFilterDigest may be used in a template envelope so that different locations can use different filters. The global variables for this function are filterMessage (the message constructed by the built-in code), filterMessagePaths (a blank-delimited list of the locations in the digest, in the same order as the digest), and filterUser (the storedUniqueId of the user for which this digest has been constructed). Changing filterMessage will result in the modified message being sent to the user.
    emailFilterIncoming Filter called for all incoming email messages. emailFilterIncoming may be used in a template envelope so that different locations can use different filters. The global variables for this function are:

    filterMessagePath -- the unique path to the just-posted message

    filterUserId -- identifies the user receiving the message

    emailFilterIndividual emailFilterIncoming can adjust individual email notifications; it may be used in a template envelope so that different locations can use different filters.

    It has the following global variables defined:

    filterMessagePath -- the location of the message for which the notification is being sent.

    filterMessageFull -- the normal full-text notification message

    filterMessageUrl -- the normal url-only notification message

    filterMessageUser -- the user who is being notified

    filterMessageRcpt -- read/write email address to send the notification to. It is set to the normal email address for this user, but can be modified by the filter. Use

    	filterMessageRcpt.length = 0;
    	filterMessageRcpt.append( newValue );
    
    to modify this.

    filterMessageIndividual -- writable new message to send to the user. This is empty when the filter is called, but can be set to the full email to be sent to this user. For example,
    	filterMessageIndividual.append( filterMessageFull ).crlf().append( footer );
    
    will append a custom footer to the filterMessageFull message. NOTE: if a custom filterMessageIndividual message is created, then the user's highwater mark for this location is NOT updated automatically (as it would be if the user is configured for full-text notification). So the filter must update the highwater mark if so desired. Here is a sample filter, showing how to see/use the various globals:
    	% % function emailFilterIndividual(){
    		line = new ByteBuffer( "" );
    		line.crlf().append( "--emailFilterIndividual--" ).crlf();
    		fileAppend( "testLog", line );
    		line.length = 0;
    		line.append( "--filterMessagePath:" );
    		line.append( filterMessagePath ).crlf();
    		fileAppend( "testLog", line );
    		line.length = 0;
    		line.append( "--filterMessageFull:" ).crlf();
    		line.append( filterMessageFull ).crlf();	
    		fileAppend( "testLog", line );	
    		line.length = 0;	
    		line.append( "--filterMessageUrl:" ).crlf();
    		line.append( filterMessageUrl ).crlf();	
    		fileAppend( "testLog", line );	
    		line.length = 0;	
    		line.append( "--filterMessageIndividual:" );
    		line.append( filterMessageIndividual ).crlf();	
    		fileAppend( "testLog", line );	
    		line.length = 0;	
    		var u = Stored.lookup( filterMessageUser );	
    		line.append( "--filterMessageUser:" )
    		line.append( filterMessageUser );
    		line.append( " name:" );
    		line.append( u.userName ).crlf();	
    		fileAppend( "testLog", line );	
    		line.length = 0;	
    		line.append( "--filterMessagePath:" );
    		line.append( filterMessagePath ).crlf();	
    		fileAppend( "testLog", line );	
    		line.length = 0;	
    		filterMessageIndividual.append( filterMessageFull ).crlf();
    		filterMessageIndividual.append( "this is a test" ).crlf();	
    	} % % 
    
    
    
    emailFilterNotify Filter called whenever email notifications are formatted for delivery; may be used in a template envelope so that different locations can use different filters. When it runs there are three global variables available:

    filterMessagePath -- the unique path to the just-posted message

    filterMessageFull -- the outgoing full message notification

    filterMessageUrl -- the outgoing url notification

    The filter can modify or replace the filterMessageFull/Url ByteBuffers as desired.
    emailFilterPosted Filter called after all incoming email posts to discussions. emailFilterPosted may be used in a template envelope so that different locations can use different filters. It uses a single global variable, filterLocation, to pass the location of the new message.
    EmailHandler Allows SSJS functions to handle incoming email. SSJS functions are email-enabled by storing them into the global EmailHandler object. For example,
      EmailHandler.support = MySupportEmailHandler;
          // Handles all email sent to "support" and "support.xxxx"
    Basically, you can attach a SSJS function to an email address prefix, so that incoming email with a matching address is handled by calling this function. For example, you could email-enable a function named "support" and have all incoming email addressed to "support" or "support.otherstuff" be processed by your email handler. Mail is delivered in the following manner:

    (1) Incoming email is first handled by checking for an email filter. The EmailHandler properties are checked for an all-lower-case property matching the incoming name. The longest match up to but not including a period in the incoming name is used. Note that you have to use

      EmailHandler["support.abc"] = function; 
    Due to a period in mailbox name and that the property string must be lower-case. For example:
      incoming         matches
        ---------        -----------------
        Support@         support (but not supportx or support_abc)
    
        support.abc@     support or support.abc (but not support.abcd)
                         If both support and support.abc are present, it
                         matches support.abc

    (2)If there is an EmailHandler.All, this function is called unconditionally to handle all other email.
    (3) The user database is checked. If there is a match, then that user receives the mail.
    (4) If there is an EmailHandler.Unknown property (with upper-case "U"), then it is used to process the mail.
    (5) Otherwise, the mail is rejected as being undeliverable.

    Email handler functions

    An email handler is called as

    handler( rcptArray, message, from )
    where
    rcptArray is an array of recipients for the message (from the SMTP RCPT commands for this message)
    message is the actual message (from the SMTP DATA, with period-style escapes removed). The message is the full header and body. Use the Mime function to parse/manipulate the message.
    from is the "from" address (from the SMTP MAIL FROM: command). This is the address to which returned mail is sent.
    fileAppend( filename, data, offset ) appends data to a file. If the file does not exist it is created. offset defaults to end of file.
    fileImgWidthHeight( pathname ) returns the string 'width="ww" height="hh"' for image files.
    fileRename( pathname, newName ) renames a file.
    executeLimit( count ) This function sets the limit on the number of low-level JS instructions that will execute by the current thread before halting with a suspected infinite loop. The default is 10 million instructions, which is several seconds on a typical current processor.

    Use executeLimit(0) to set the current execution context to have no limit.

    Note that this limit is per-thread, so you must call this early on in the execution of any function that needs more than the default setting.

    httpFilterRaw () Filter for raw HTML requests. If present, this filter is run for all requests (except the live services /webx?9999@@ URI). The filter can either allow the request to continue without modification, can modify any of the request values, can forward to a different location, can return an error, or can return a full dynamically-generated page. The filter name is httpFilterRaw, and it has access to global variables as follows:

    * filterUri -- the URI from the request line. This variable can be modified as desired.

    * filterHeaders -- the headers of the mime request. Each line has a trailing CRLF delimiter. This variable can be modified as desired.

    * filterBody -- the body of the request, if any, can be modified as desired.

    * filterLocalIp -- the local IP address

    * filterRemoteIp -- the remote IP address

    * filterResponse -- the response action, if any. This can be set to either "code parameter" or a full response page starting with "HTTP/...". If it is "301 url", then a permanent forwarding response is returned and is counted as a static page; if it is "302 url" then a temporary forwarding response is returned and counted as a static page; if it is some other code number then that code is sent back with the parameter as the message and counted as a static page; if it is a full page, then that page is returned and counted as a dynamic (webx) page.
    httpReq( url, request, timeoutSecs, returnHeaders ) returns ByteBuffer. If request is missing or empty, a default GET request is made. If timeoutSecs is missing, a 30 second timeout is used. If returnHeaders is true, then the full response including headers is returned, otherwise only the data (body) s returned. If an error is detected, the returned ByteBuffer starts with an asterisk (e.g. "* error-message").
    loginNotify () Filter that allows keeping track of currently logged-in users, used in conjunction with logoutNotify(). If there is a loginNotify() function it is called with global variables for the userId and certificate at the time a user is attached to a certificate. You can use User.lookup( loginUserId ) to get the user. For example,
    %% function loginNotify(){ 
    var line = new ByteBuffer(), d = new Date(); 
    line.append( d ).append( " login  " );
    line.append( loginUserId ).append( " " );
    line.append( loginCertificate ).crlf(); 
    fileAppend( "testLog", line ); 
    }%% 
    logoutNotify () Filter that allows keeping track of users logging out, used in conjunction with loginNotify(). If there is a logoutNotify() function it is called with global variables for the userId and certificate at the time a user logs out. You can use User.lookup( loginUserId ) to get the user. For example,
    %%function logoutNotify(){ 
    var line = new ByteBuffer(), d = new Date(); 
    line.append( d ).append( " logout " );
    line.append( logoutUserId ).append( " " );
    line.append( logoutCertificate ).crlf(); 
    fileAppend( "testLog", line ); } 
    %% 
    memoryUsage() Returns total memory allocated at any point in time (in 8-byte units). This function can be useful for checking for memory usage during some JavaScript operation.
    memoryReclaim() Performs an immediate JavaScript memory reclaim (garbage collect). This function can be useful for keeping total memory usage down while running JavaScript operations that use large/transient amounts of memory.
    nntpFilterPost Filter called before all NNTP posts. The function has access to two global ByteBuffer variables:

    filterMessage -- this is the NNTP message, including the header and all attachments, etc. The filter can modify this as desired. Setting this to empty will suppress the normal NNTP post; modifying this message will cause the post to use the modified data

    filterNewsgroup -- if this is the empty string, then the first newsgroup in the filterMessage "newsgroups" header is used. If this is not the empty string, then it is the name of the newsgroup to which the message will be posted.

    nntpFilterPosted Filter called after all NNTP posts. nntpFilterPosted may be used in a template envelope so that different locations can use different filters.
    The function has access to one global ByteBuffer variable:

    filterLocation -- this string is the location of the posted message.

    objectToXml( obj ) Returns a string that is the XML representation of the object. The object can be RAM-based or Stored. Any nested objects are included in the XML, except that references to Node, User, or Document objects are references (e.g. unique IDs, not copies of the referenced object).
    queue( function, msecsOrDate, params... ) queues a JS funtion for later execution. The msecsOrDate parameter can be either a delay in milliseconds or a Date object that specifies the absolute time to run the queued function. The default for msecsOrDate is 0, to run the queued function as soon as possible.

    The parameters can be any JS value. Note that parameters are passed using normal JS rules. If you pass an object, and modify the object prior to the queued function being run, the function will see the modified object. Any number of parameters may be passed.

    queueWctl( macro, msecs-or-date, param0, param1, user ) queues a WCTL macro for later execution. Returns a string ID for this queued entry, that can be used to kill the queued function. For example,
    id = queueWctl( "myFunction", 1000 )
    will queue myFunction to run in 1 second.

    macro is the name of a WCTL macro.

    msecs-or-date is either a delay in milliseconds or an absolute Date() object that specifies when to run the queued macro. If ommitted, the queued macro is run as soon as possible.

    Note that the millisecond delays are not extremely accurate, so it is a good idea to delay for shorter periods, perhaps every hour, then delay one last time for the remaining period (less than 60 minutes) before an event trigger, or to use an exact Date() specification.

    param0, param1 are optional parameters. These values are converted to strings and are available as queueWctlParam( 0 ) and queueWctlParam( 1 ).

    user if specified, the queued macro will be run for this user. Otherwise, the queued function will be run with no user installed.

    You can call a JavaScript function from WCTL. For example,

    %% function testQueueStart(){
        // queue testQueueWctl to run in 1 second
        queueWctl( "testQueueWctl", 1000, "abc" );
    } %%
    
    %% macro testQueueWctl %%
        %% // queue WCTL macro, just calls a JS function %%
        %% "testQueue".jsEval %%
    %% endmacro %%
    
    %% function testQueue(){
        // Just appends the first parameter to testFile
        fileAppend( "testFile", queueWctlParam( 0 ) );
    } %%
    queueWctlParam( ix ) returns queued function parameter strings, 0/1 for param0/param1.
    queueWctlKill( ID ) kills the queued function, no effect if this function is no longer queued (either because it has run or has been killed previously).
    smtpMsgInFilter If present, called to check/modify all outgoing messages. This function has three global variables available: filterMsg is the default message, filterFrom is the from value if any, and filterRcpt is the recipient list (comma space delimited) if any. If filterMsg is modified, the new value is used.
    templatesReset() Queue a reset of the template files.
    wctlEval( str ) returns result of evaluating "str" as an expression in WCTL
    wctlEvalTemplate( str ) returns result of evaluating "str" as a template in WCTL
    xmlToObject( string ) Returns the object that the XML string represents. The returned object will be either RAM-based or Stored depending on the original object converted via objectToXml. If any Node, User, or Document objects referenced in the XML string cannot be found, their value will be set to NULL. When a JS object is either imported or converted by xmlToObject, and its prototype has a routine named xmlInFinalize, then that method is called after all of its properties have been imported or converted, so that any other data structures can be updated as required. For example, if an object has to be added to some btree or hash table, it could be done at this time.


    » Helper Objects

    The Web Crossing JavaScript environment provides a number of standard objects to help in customizing a Web Crossing site, serving dynamic pages, and processing input forms.

    There are also some extensions to standard JavaScript objects to assist with server-side operations.

    » ByteBuffer Object

    A ByteBuffer implements a modifiable array of bytes (instead of JavaScript's Unicode strings). Using a byte array means that a output page can be constructed exactly as it will be served, without any translation between Unicode and the byte stream required for Web pages.

    A ByteBuffer is used for the output response buffer, but these objects can also be created and used for other purposes. The ByteBuffer object only uses one byte per character in the output string and allows you to append to the buffer object. By contrast, the standard JavaScript string object catenates strings and thus requires a memory allocation for each catenation. The ByteBuffer allocates a larger buffer and simply adds characters to it, doing a reallocation only when the buffer space overflows. As a result ByteBuffers are dramatically more memory- and performance-effective and thus preferred for significant string-handling operations.
    Properties and methods Usage
        -- new ByteBuffers --
    new ByteBuffer() Creates a new empty ByteBuffer
    new ByteBuffer( initialValue ) Creates a new ByteBuffer whose initial value is as specified.
        -- length --
    length (read/write) the current length of the ByteBuffer
        -- string compares, NOT case sensitive --
    eqNc( obj ) returns true if the obj string of ByteBuffer is equal
    ltNc( obj ) returns true if the obj string of ByteBuffer is less-than obj
    leNc( obj ) returns true if the obj string of ByteBuffer is less-than-or-equal obj
    gtNc( obj ) returns true if the obj string of ByteBuffer is greater-than obj
    geNc( obj ) returns true if the obj string of ByteBuffer is greater-than-or-equal obj
    neNc( obj ) returns true if the obj string of ByteBuffer is not-equal obj
        -- string compares, case sensitive --
    eq( obj ) returns true if the obj string of ByteBuffer is equal
    lt( obj ) returns true if the obj string of ByteBuffer is less-than obj
    le( obj ) returns true if the obj string of ByteBuffer is less-than-or-equal obj
    gt( obj ) returns true if the obj string of ByteBuffer is greater-than obj
    ge( obj ) returns true if the obj string of ByteBuffer is greater-than-or-equal obj
    ne( obj ) returns true if the obj string of ByteBuffer is not-equal obj
        -- access --
    byteAt( ix ) number
    charAt( ix ) string
    substring( ix [, count] ) string
    subString( ix [, count] ) same as substring
    subBuffer( ix [, count] ) ByteBuffer
    duplicate() returns a copy of the ByteBuffer
        -- modify/parse --
    append( data, ix, count ) appends a string to the ByteBuffer, and returns the modified ByteBuffer. ix and count are optional and pick a substring of the data. ix defaults to 0, count defaults to the rest of the input data.
    appendByte( number ) appends a character where "number" is the numeric value of the character, and returns the modified ByteBuffer
    emailGetAddress( ) returns returns the email address portion of an email list entry (see emailHead()). For example:

    "Test User ".emailGetAddress() --> "test@test.com"

    emailGetUsername( ) returns returns the username portion of an email list entry (see emailHead()). For example:

    "Test User ".emailGetUsername() --> "Test User"

    emailHead( ) returns the next full entry from a list of email addresses (as in the From and CC fields of an email message) and removes it from the ByteBuffer
    head( [delimiter] ) returns ByteBuffer to left of delim (default is space), removes the head and delimiter from the buffer
    insert( ix, obj ) inserts obj.toString() at "ix", sliding the character at "ix" and all following characters down to make room, and returns the modified ByteBuffer
    insertByte( ix, number ) insterts a single character at "ix", and returns the modified ByteBuffer, slides down following bytes
    newValue( obj ) sets the ByteBuffer to a new value, and returns the modified ByteBuffer
    none() returns NULL (used to have a series of appends, etc evaluate to NULL
    popKeyword() finds the first keyword in the byteBuffer, returns it as a string, and removes the keyword and its trailing delimiter. Delimiters between keywords are commas, semicolons, and white space. Leading/trailing whitespace is skipped. For example, if the byteBuffer is " key1, key2", the call to popKeyword() will return the string "key1" and set the byteBuffer to "key2".
    remove( ix [, count] ) removes characters from ix through ix+count-1, and slides the following characters up. Returns the modified ByteBuffer
    set( ix, obj ) sets the character at "ix", and returns the modified ByteBuffer. Uses first character of obj.toString(), or is a no-op if obj is a 0-length string
    setByte( ix, number ) sets the character at "ix" where "number" is the numeric value of the character to store, and returns the modified ByteBuffer
    stripEdges() removes leading and trailing whitespace and control characters and returns the modified ByteBuffer
    tail( [delimiter] ) returns ByteBuffer to right of delim (default is space), removes the tail and delimiter from the buffer
    toLowerCase() converts ByteBuffer to all lower-case, returns the modified buffer
    toUpperCase() converts ByteBuffeer to all upper-case, returns the modified buffer
    translate( mapByteBuffer ) remaps ByteBuffer, each char in ByteBuffer is replaced by mapByteBuffer( byteAt[ix] )
        -- URL and SGML quoting --
    toUrl() converts the ByteBuffer to be URL-quoted and returns the modified buffer
    fromUrl() converts the ByteBuffer to be URL-dequoted and returns the modified buffer
    toSgml() converts the ByteBuffer to be SGML-quoted and returns the modified buffer
    fromSgml() converts the ByteBuffer to be SGML-dequoted and returns the modified buffer
        -- hashing --
    toMD5() calculates the MD5 hash of the ByteBuffer and returns the modified buffer
        -- character appends --
    crlf() append carriage return, line-feed characters (CR/LF are the standard Internet end-of-line)
    cr() append a CR character
    lf() append a LF
    newline() append a host-specific end-of-line (for writing local files)
        -- lookup --
    indexOfNc( obj [, ix [, count]] ) not case sensitive, returns start index or -1
    indexOf( obj [, ix [, count]] ) case sensitive, returns start index or -1
    lastIndexOfNc( obj[, ix [, count]] ) not case sensitive, returns last start index or -1
    lastIndexOf( obj[, ix [, count]] ) case sensitive, returns last start index or -1

    » Date Object

    The following methods have been added to the standard JavaScript Date object.
    Properties and methods Usage
    format( formatSpec ) formats the JS Date per a WCTL time/date format string (as local time). See below for formatSpec syntax.
    formatUtc( formatSpec ) same as format() except as UTC/GMT

    For example,

    date.format("Www, D2 Mmm Y4 H4:I2:S2 G$MTtoutc")
    will return something like
    "Tue, 16 Feb 1999 13:06:05 GMT-0700"
    The date "formatSpec" is as follows. (Characters which are not format specifiers are copied into the output as literals.)

    » String Object

    The following methods have been added to the standard JavaScript String object.
    Properties and methods Usage
    htmlToPlainText() returns plain text string. All SGML-escaped characters are converted. HTML-formatted white space is converted to plain-text. <P>, <BR>, and <PRE> are converted to similar-looking newlines. <LI> is converted to an asterisk and a space. &nbsp; is converted to a normal space. </TABLE> and </TR> are converted to newlines, and </TD> is converted to a space.
    toSgml() returns string converted to SGML quotes
    fromSgml() returns string converted from SGML quotes
    toUrl() returns string converted to URL quotes
    fromUrl() returns string converted from URL quotes

    » MIME Processing

    The build-in Mime object provides a collection of useful routines for dealing with MIME (Multipurpose Internet Mail Extensions) envelopes. For Mime object methods that take a string parameter, string may be the entire MIME envelope or just the header.
    Mime.formHeader( "name" ) returns the header for a form variable from a POST in multi-part MIME format, the same as the WCTL function formHeader. If the post was not in MIME format, or there is no form variable by this name, then returns null.
    Mime.getHeader( string ) returns the header portion of a message in a MIME envelope (e.g. from a header, blank line, and body envelope)
    Mime.getBody( string ) returns the body portion of a message in a MIME envelope
    Mime.unpackBody( string, boundary ) unpacks a multi-part MIME body into an array of objects. The [0] element of the array is the data before the first boundary.
    Mime.getHeaderValue( string, name ) Gets the value of a single header keyword
    Mime.unpackHeader( string ) unpacks a MIME header, and returns an object with one property for each header keyword:value pair; the keyword is converted to lower case, and its value is the unfolded value from the header. Also, minus and underscore in the header names are exchanged, so that "Content-Type: text/html" becomes "content_type" with a value of "text/html".
    Mime.unpackValue( string ) unpacks a MIME value (from a keyword:value header entry), and returns an object with one property for each value attribute. Attribute names are converted to lower case. The main value is stored into a property named "Value", with an upper-case "V". Also, minus and underscore in attribute names are exchanged, so that "x-application=abc" becomes the property name "x_application" with a value of "abc".
    Mime.packValue( obj ) packs a header value-object back up.
    Mime.packHeader( obj ) packs a header-object back up
    Mime.makeBoundary( obj ) returns a unique boundary string for the body parts in the input array object
    Mime.packBody( obj, boundary ) packs a multi-part MIME body back up from an array of part-messages and a boundary string
    Mime.packMessage( header, body ) packs a header and body into a message


    » Remote Procedure Calls

    Web Crossing supports XML-based remote procedure calls, as defined by Www.XmlRpc.Com. This allows you to share resources from your Web Crossing server, and to let your Web Crossing server access shared resources from other servers.

    Note: in order to support XML-RPC, Web Crossing must be providing direct Web service. You can not pass XML-RPC calls through CGI or FastCGI interfaces.

    Remote procedure calls (RPCs) allow client programs to make calls to your Web Crossing server, with your server using the appropriate JavaScript functions to process these calls.

    You can also make remote procedure calls from Web Crossing's server-side JavaScript to any RPC-based server.

    This remote-procedure-call mechanism uses normal HTTP requests and responses, with special XML-based formatting of the body of the message to pass parameters and receive the returned value. All of the XML-RPC machinery is handled by Web Crossing, so you don't need to know the format of these calls to use it in Web Crossing.

    » Calling Remote Procedures

    To call a remote procedure, use

    rpc( url, function, p1, p2... ) -or-
    rpcTimeout( url, function, p1, p2..., timeoutSecs )

    where:

    url is the URL of the server that is going to process the procedure call. This can be a server address only (e.g. webcrossing.com), or it can be a full URL, including the remote pathname (e.g. http://webcrossing.com/RPC2).

    If the remote pathname is omitted, then /RPC2 is used, so specifying just a server address is the same as http://serveraddress/RPC2.

    To use SSL for the RPC connection, you must be running an SSL-enabled Web Crossing server, and specify https in the URL. For example, https://webcrossing.com/RPC2 would use HTTPS instead of HTTP. The default port for HTTPS is 443 and the default port for HTTP is 80.

    The default timeout to receive a response from the server is 10 seconds. Use rpcTimeout to specify some other timeout.

    function is the name of the remote function, such as mainResponder.discuss.newMessage.
    p1, p2... are optional parameters. Primitive values (strings, numbers, Dates) are passed exactly, except that null is passed as an empty string. ByteBuffers are passed as strings. Arrays are passed as arrays of values.

    All other objects are passed as primitive Objects, with all their enumerable properties passed to the remote procedure.

    returns the object passed back from the remote procedure. Returned values use the same rules as for sending parameters to the remote procedure. So returned values can be primitive values, or can be JavaScript Arrays or Objects.

    Any error in the call, or in the remote processing, will return a Fault object. This object has properties faultCode, a numeric error code, and faultString, a descriptive error message.

    » Processing Remote Procedure Calls

    You can process RPCs from any client by providing a JavaScript function and enabling that function for RPC handling. The parameters from the client are passed to your function, and the return value from your function is passed back to the client.

    To enable a function for RPC processing, just set

    myFunction.rpcEnable = true;

    The rpcEnable property can be either a boolean or a function. If this property is a function, then this rpcEnable function is called prior to executing the XML-RPC function, with the first parameter the function name and the following parameters the same as the XML-RPC function. The rpcEnable function can return one of the following:
    true then the normal XML-RPC processing is done
    false a "not enabled" fault is returned
    other returned to the caller instead of calling the normal XML-RPC function (e.g. "short-circuits" the normal XML-RPC call)

    You can return a Fault object if you detect some error in the request or during processing. To return a fault, just use

    return new Fault( errCode, errMsg );

    where errCode is a numeric error code (there is no standard, you just make them up for your usage), and errMsg is a descriptive error message.

    Checking the incoming request

    Sometimes you need to check that the incoming request is from a specific server, or is over a secure SSL connection. The JavaScript routine that processes the request can check the cgi built-in object as needed, this object is available during XML-RPC call processing just as it is for any incoming HTTP request.

    » Examples

    Here is a sample RPC function that will be served from Web Crossing, and a sample test call to it. In this case, both the client making the RPC request, and the server processing it, are the same Web Crossing server -- Web Crossing is calling itself via the RPC mechanism. (This is much less efficient than just making a local call, but does illustrate how to use the machinery.)

    %%
    function testAdd( a, b){
        // The RPC function: it just adds two numbers and returns the result
        return a + b;
    }
    command testRpc(){
        // The test function: it makes a remote procedure call to testAdd()
        var ret = rpc( cgi.http_Host/*self*/, "testAdd", 1, 2 );
    	if( ret == "[object Fault]") {
    		+ ret.faultString;
    	} else {
       		+ "Should say 3: " + ret;
       	}
    }
    function init_testAdd(){
        // An init function: it enables testAdd to process RPC calls
        testAdd.rpcEnable = true;
    }
    %%

    To invoke the test function, copy this to your standard.tpl file, reset the webx.tpl cache, and use the URL

    ...webx?testRpc

    where ...webx is the access to your Web Crossing server.

    A Second XML-RPC Example - Checking a User's Existence at a Remote Site

    This XML-RPC example queries another Web Crossing site to see if a user with the same user name as the current user exists there or not.

    The results are shown here (a folder at the Web Crossing Education Center). Try it! If you are logged in to the Education Center and also registered at WebX Harbor (under the same userName) then the folder header will report that a user with the same name as you is also at WebX Harbor. Otherwise it will report that your name was not found at the remote server.

    Contents of the Folder Header

    The folder header contains a call to a local WCJS function, remoteUserQuery(): %% "remoteUserQuery()".jsEval %%

    This function calls a function at WebX Harbor. That remote function returns the boolean value true or false depending on whether or not the user is there.

    remoteUserQuery

    The function remoteUserQuery() (see below) uses the WCJS rpc command to call the function remoteUserRespond() at WebX Harbor.

    The current user's name is passed as a parameter to remoteUserRespond.

    remoteUserRespond

    Meanwhile, on the WebX Harbor site, the function remoteUserRespond (below) receives the remote procedure call and checks to see if the user exists or not. If the user exists, true is returned. Otherwise false is returned. In either case, a record of the rpc call is logged to a file, logxmlrpc.

    Note that init_remoteUserRespond sets the .rpcEnable property of the remoteUserRespond function - otherwise it would not be able to receive XML-RPC calls.

    The Results

    When user doug visits the folder he sees this result, because he (or at least somebody with his name) is registered at WebX Harbor.

    However, when Pia Zadora takes a break from her singing career to visit the same folder, she is told that no user with her name exists at WebX Harbor.

    Meanwhile, at WebX Harbor, this log is retained to keep track of the remote calls to remoteUserRespond().



    Third Example - A Form-based XML-RPC Client

    Web Crossing can act as both an XML-RPC server and client. The code sample here can be used to create your own handy XML-RPC Client with a form interface. This is useful for testing XML-RPC functions on various servers.

    Calling rpcClient

    You can "rpcClient".jsEval or call the command from a URL, using the standard Web Crossing URL command syntax. The Client looks like this (with some sample data):

    You can have any number of arguments, separated by commas.

    What rcpClient Returns

    Here is what rpcClient returns using the sample data in the previous message.

    The returned value's typeOf and value are given.Return values of boolean, string, number, Array and any Object are reported. Arrays of Object types are also supported.

    The Source Code for rpcClient

    Here is the source code. A few notes:



    » External Databases (Oracle, etc.)

    Web Crossing supports access to external relational databases through server-side JavaScript objects and methods. You must install a version of Web Crossing that provides support for the desired database, and configure the Web Crossing server and external database as required. For information about which databases are supported on which platforms, please see our download area at ftp.webcrossing.com, or contact sales@webcrossing.com or support@webcrossing.com.

    Using an external database requires a working knowledge of SQL, which is not covered in this document. If you need to learn SQL, get a copy of Sql in a Nutshell by Kline and Kline, which is a good introduction and covers most common usage.

    » db Object

    All access to external databases is through the db object (when the appropriate version of Web Crossing is installed and configured).

    You start by creating a new db object and using connect to open a connection to the external database. You can check to see whether a db is connected by using the connected method.

    To access/update the db, use execute to execute arbitrary SQL statements, insert to insert rows, delrow to delete rows, and update to update database rows. You can use rowsprocessed to tell how many rows were affected by these operations.

    The db supports a cursor to access the results of database SELECT operations. Use cursoropen to create a new cursor control structure, cursor to issue a SELECT statement to fill the cursor with row data, columns to find out how many colums are in the current selection, nextrow to iterate over selected rows, nextcol to iterate over columns in the currently selected row, and cursorclose to close the cursor control structure when you are through with it. You can get information about the columns in a cursor through colnumforselect to get the number of columns that will be returned by a SELECT operation and colname to iterate over column names for a select operation.

    You can get information about the database through colnum to get the number of columns in a table, colname to iterate over column names in a table, and colattr to iterate over column attributes for a table.

    To control transactions and rollback, use begintrans to start a transaction, endtrans to end a transaction, and either commit to make the changes in the previous transaction or rollback to cancel it. You can also use autocommit to control autocommit mode (normally off).

    Error checking is done through errorcode to get the error code for the most recent operation, errormessage to get the error message, errorsqlstatement to get the most recent SQL statement, and errorvarinfo to get the most recent SQL variable information (if supported by the external database).

    When you are through with a database connection, use disconnect to close the connection.

    Methods Usage
    new db Creates a new db object.
    mydb.autocommit() Turns on autocommit mode. Using this function will automatically commit every transaction within the scope of the running JS script. autocommit is turned off by default.

    Generally speaking, you don't want to commit transactions, especially a large group of transactions, if one those transactions happens to fail. If autocommit is called, it will nullify the functionality of begintrans/endtrans. Typically, transactions are committed explicitly, thus allowing for rollback in the event of an error or undesired transaction result.

    Returns true on success, false on failure.

    mydb.begintrans() Starts a transaction, a series of related operations on the external database. You must call mydb.endtrans() to end the transaction.
    mydb.colattr( table, columName, attrType ) Returns the attribute description for a column in a table. attrType can be 0 or 1.
    mydb.colname( tableOrSqlSelectStatement ) Returns column names for a table or select operation, in order until all columns have been returned, then returns the empty string. For example,
      employeesNames = new Object;
      for( i = 0; i < mydb.colnum( "employees" ); i++ ){
          employeesNames[i] = mydb.colname( "employees" );
      }
    mydb.colnum( table ) Returns the number of columns in a table.
    mydb.colnumforselect( sqlSelectStatement ) Returns the number of columns that will be returned by a SELECT statement. For example,
      cols = mydb.colnumforselect( "select * from employees" );
    mydb.columns() Returns the number of columns in the current cursor selection.
    mydb.commit() Commits changes from the previous transaction to the database. Returns true if committed successfully, false if not.
    mydb.connect( "connectionString" ) Connect to the database. For example,
      if( !mydb.connect( "scott/tiger" ) ){
          + "database connection failed: " + mydb.errormessage();
          return false;
      }

    Returns true on success, false on failure.

    mydb.connected() Returns true if connected, false if not.
    mydb.cursor( sqlSelectStatement ) Fills in a cursor data structure with the results of a select statement. For example,
      mydb.cursor( "Select * from employees" );
    Returns true if the select was successful, false if not.
    mydb.cursorclose() Closes a cursor and releases the memory allocated for it. Returns true if the cursor close was successful, false if not.
    mydb.cursoropen() Allocates a cursor data structure for subsequent cursor operations. Returns true if the cursor open was successful, false if not.
    mydb.delrow( sqlDeleteStatement ) Deletes rows of data from a database. For example,
      mydb.delrow( "delete from employees where empno > 85" );
    Returns true if updated successfully, false if not.
    mydb.disconnect() Disconnect from the database. Returns true on success, false on failure.
    mydb.endtrans() Turns on autocommit mode. Ends a transaction. You must call commit or rollback after you call endtrans.
    mydb.errorcode() Returns the error code for the last operation.
    mydb.errormessage() Returns the error message for the last operation. If an empty string is returned, then the last operation executed correctly.
    mydb.errorsqlstatement() Returns the last SQL statement executed.
    mydb.errorvarinfo() Returns the variable information for the last SQL statement. This function is db-vendor dependent, and is not usually implemented by the vendor.
    mydb.execute( sqlStatement ) Execute an SQL statement. For example,
      mydb.execute( "drop table whatever" );
    Returns true if the statement was executed successfully, false if not.
    mydb.insert( table, columnNames..., values... ) Inserts a row of data into a table. For example,
      mybd.insert( "employees", "empno", "ename", "job", 200,
      "john smith", "freelance" );
    Returns true if inserted successfully, false if not.
    mydb.nextcol() Returns the value of the next column in the current row in the current cursor selection.
    mydb.nextrow() Advances to the next row in the current cursor selection. Retuns true if another row was available, or false if not.
    mydb.rollback() Explicitly discards changes from the previous transaction. Returns true if rolled back successfully, false if not.
    mydb.rowsprocessed() Returns the number of rows affected by the previous SQL operation.
    mydb.update( sqlUpdateStatement ) Updates rows of data. Returns true if updated successfully, false if not.

    » Example

    This is a driver program written in very simple Javascript, written to test/demonstrate Javascript interacting with an Oracle database. Create a new JS object to perform all database operations with.
    // Create a new database object
    print ("creating new db object");
    var my_db = new db;
    Test to see if even connected to the database. No point in trying to database stuff if not connected.
    my_db.connected();
    Try and connect with a bad login on purpose and then see some of the error trapping that comes back.
    // try and connect with a bad login
    
    my_db.connect("bad/login");
    
    // see what errors came from a bad connection
    
    my_db.errorcode();
    my_db.errormessage();
    my_db.errorsqlstatement();
    As per previous comments, autocommit is TURNED off by default. However, the autocommit() function can be used as shown in this example.
    // automatically commit every db transaction - by DEFAULT
    transactions must be committed explicitly
    // NOTE turning this on autocommits everything!! for the duration of
    the JS script running
    // and nullifies the functionality of
    // begintrans() and endtrans() with explicit commit and rollback,
    similar to SQL*Plus
    // hence the reason it is TURNED OFF by default and must be
    explicitly turned on
    
    if (my_db.autocommit())
         print ("autocommit set ");
    Finally got around to connecting to the database. Check for errors, but shouldn't get anything back.
    my_db.connect("scott/tiger");
    if (my_db.connected())
          print("scott/tiger connected");
    
    my_db.errorcode();
    my_db.errormessage();
    my_db.errorsqlstatement();
    Shows the execution of a regular SQL statement and some error checking.
    my_db.execute("drop table whatever");
    
    my_db.errorcode();
    my_db.errormessage();
    my_db.errorsqlstatement();
    Execute any single SQL statement, even a table create type statement.
    my_db.execute("create table whatever (f1 number, f2
    varchar2(60), f3 varchar2(255), f4 varchar2(10))");
    A couple of functions were done to count columns. This is especially useful when executing statements when the number columns may drive a loop for a given SELECT statement and the column count isn't known prior to the execution of that statement.

    In this example, pass in the name of the table:

    my_db.colnum("whatever");
    In this example, return the number of columns for the SELECT where the columns are known - kind of a dumb example, but contrast it to the next example where the number of columns isn't known or implied by the SELECT example ("select * from employees").
    my_db.colnumforselect("select f2,f3 from whatever");
    my_db.colnumforselect("select * from whatever");
    An SQL delete statement (i.e. delete rows from table based on a particular criteria uses the delrow function. The SQL delete statement is the argument. In this example, all data is being deleted from the table "bob" where the column F1 has a value greater than 85. Do some error checking after deleting.
    my_db.delrow("delete from bob where f1 > 85");
    my_db.errorcode();
    my_db.errormessage();
    my_db.errorsqlstatement();
    But wouldn't you know it, the code suddenly changed it's mind and doesn't want to delete. Maybe there was an error. Either way roll-it back.
    my_db.rollback();
    An important but potentially subtle point about deleting rows and error checking. A delrow() call can return true even though no rows were deleted. It's a valid sql statement and no error is returned, but not data was deleted because the criteria of the sql where clause was not met, there just wasn't any data to delete that met the criteria of the delete. However, there is a function to account for this. The rowsprocessed() will tell you how many rows were processed (i.e. deleted).
    my_db.delrow("delete from data_types where col5_int > 85");
    my_db.errorcode();
    my_db.errormessage();
    my_db.errorsqlstatement();
    However, there is a function to account for this. The rowsprocessed() will tell you how many rows were processed (i.e. deleted).
    my_db.rowsprocessed();
    This next example shows a couple of different ways to get at column names when on the table name is known. The name of a column is a column attribute that can returned.
    // Step through the column names via a loop
    
    print ("columns from table emp with a loop");
    print ("======================");
    for (i=0; i <= my_db.colnum("emp"); i++)
    {
        mycol=my_db.colname("emp");
        // print(my_db.colattrib("EMP", mycol, 0));
        print ("my col = "+mycol);
    }
    
    // Step through the column names on single lines
    
    print ("columns from table emp with single calls");
    print ("======================");
    print(my_db.colname("emp"));
    print(my_db.colname("emp"));
    print(my_db.colname("emp"));
    print(my_db.colname("emp"));
    print(my_db.colname("emp"));
    print(my_db.colname("emp"));
    print(my_db.colname("emp"));
    print(my_db.colname("emp"));
    print("");
    Column attributes can vary greatly depending on the underlying database. In these examples, 2 somewhat "generic" attribute can be returned, the size and type of the column, passing in either a 0 or 1.
    my_db.colattrib("EMP", "EMPNO", 0);
    my_db.colattrib("EMP", "EMPNO", 1);
    Cursors or selecting data is very common operation. In this example, a cursor is set up and executed, however the SELECT statement is bad and this example shows how to do some error handling associated with a bad SELECT statement.
    my_db.cursoropen();
    my_db.cursor("Select bad_column from emp");
    
    if (my_db.errorcode() == 0)
    {
         print("in cursor select ");
         print(my_db.columns());
    // my_db.nextrow()
    
         my_db.cursorclose();
    }
    print ("error messages from bad cursor")
    print(my_db.errorcode())
    print(my_db.errormessage())
    This is a good cursor and completely demonstrates cursor handling.
    my_db.cursoropen();
    my_db.cursor("Select * from emp");
    
    print(my_db.errorcode())
    if (my_db.errorcode() == 0)
    {
         print("Column Names");
         for (i=0; i <= my_db.columns(); i++)
         {
            mycol=my_db.colname("emp");
            print (mycol);
         }
    
         while (db.nextrow())
         {
            for (i=0; i <= my_db.columns(); i++)
            {
               mycol=my_db.nextcol(i);
               print (mycol);
            }
         }
         my_db.cursorclose();
    }
    At any time, an active connection can be disconnected. For example, say a connection was made and autocommit was turned on. To turn off the autocommit, the script would disconnect and then reconnect (autocommit is turned off by default).
    my_db.disconnect();
    
    my_db.connect("scott/tiger");
    if (my_db.connected())
          print("scott/tiger connected");
    Explicit transaction control, i.e. wrap a set of transactions within a rollback/commit block is done with the begintrans and endtrans statements. At the endtrans all the encapsulated insert statements are rolled back.
    my_db.begintrans();
    
          my_db.insert("emp","empno","ename","job",200,"jeff kent","freelanc");
          my_db.insert("emp","empno","ename","job",200,"rod kent","coder");
          my_db.insert("emp","empno","ename","job",200,"davejones","manager")
    
    my_db.endtrans();
    
    my_db.rollback();
    A sample insert.
    // my_db.insert("emp","empno","ename","job",200,"jeff
    kent","freelance");
    // print(my_db.errorcode())
    // print(my_db.errormessage())
    
    // bad insert - will generate an error
    
         my_db.insert("bad_table","empno","ename","job",20000,"Tim Lundeen","CEO");
         print(my_db.errorcode())
         print(my_db.errormessage())
    
    // the errorcode since it will be the errorcode from the last db transaction
    // in a loop you'd want to do this programmatically, i.e. after every db
    // transaction, check error code, if it err'd and you were using begin/end
    // then you'd roll back  and immediately exit the loop
    
    my_db.endtrans();
    my_db.rollback();  // rollback all the inserts
    A generic type insert, inserting strings and numbers.
    // insert data in to a row in a loop - hacked JS interpreter
    doesnt handle it correctly
    // only iterates through the loop 1X
    for (i=0; i <= 10; i++)
    {
         my_db.insert("emp","empno","ename","job","mgr",200,"johndoe","geek",100);
         print(my_db.errorcode());
         print(my_db.errormessage());
    }
    my_db.commit();
    Return the row count of a particular table.
    print ("number of rows in table emp");
    print ("===========================");
    my_db.rownum("emp");

    Copyright © 1996-2003 by Web Crossing, Inc., San Francisco, California.