(* * <COPYRIGHT> * Copyright 2002 Joachim Schrod Network and Publication Consultance GmbH, Gerd Stolpmann * * <GPL> * This file is part of WDialog. * * WDialog is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * WDialog is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with WDialog; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * </> *) (* $Id: wd_interactor.mli,v 3.7 2005-12-09 20:02:40 stolpmann Exp $ * ---------------------------------------------------------------------- * *) (** This module provides a data type for containers of interactor descriptions. *) (** The background of the module is that interactors (such as input elements, * hyperlinks, buttons) are referred to by two different naming schemes. On * the one hand, the interactor elements in the ui file have a name and * and optionally an index; e.g. * {[<ui:button label="Press here" name="my_button" index="1"/>]} * or * {[<ui:text variable="x" index="5"/>]} * Often the name/index pair is actually a variable/index pair because the * interactor is bound to a certain instance variable of the uiobject. * \- On the other hand, the interactors are transformed to HTML code, and * the HTML/CGI name is different. For example the following HTML output * might have been generated: * {[<input type="button" name="xbutton_25" value="Press here">]} * or * {[<input type="text" name="var_12" value="...">]} * Obviously, the HTML/CGI names are automatically chosen. Of course, there * is a bijective mapping from the internal names to the HTML/CGI names, * and the task of the Interactor.t type is to manage these mappings. * * A value of type Interactor.t contains the following: * - A list of name/index pairs * - The corresponding HTML/CGI identifiers. Only the identifier * after the prefix (such as "var_" or "xbutton_") is stored. * - The bijection which name/index pair corresponds to which identifier. * - For every name/index pair (or every identifier) there may be another * arbitrary value which can store additional information related to * the interactor * * {b Example} * * {[let ia = create();; (* : unit Interactor.t *) * ... * let id = add ia "my_button" "1" None ();; (* = "25" *)]} * * Note that the "25" is an automatically created identifier (just the next * free number), and that the HTML/CGI name will be composed of a prefix * indicating the type of the interactor and the identifier, e.g. * "xbutton_25". * * If we try to add the same name/index pair a second time, the add operation * raises an exception: * * {[add ia "my_button" "1" None ();;]} * ==> raises [Element_exists "25"] * * When the incoming CGI parameters are analyzed, it must be possible to * look up the name/index pair for a given identifier. For example: * * {[let (name,index,value) = lookup ia "25";; (* = ("my_button", "1", () *)]} * * There is no reverse lookup operation. However, it is at least possible * to test the existence of a given name/index pair: * * [exists ia "my_button" "1"] yields [true] * * As a last resort, it is possible to iterate over all members of the * ia value: * * {[let print id name index value = * printf "ID=%s name=%s index=%s\n" id name index * in * iter print ia]} * * {b Selecting the identifier manually} * * If the ui element contains the [cgi="keep"] attribute, and there is no * index component, the CGI name retains the orignal name. For example: * {[<ui:button label="Press here" name="press" cgi="keep"/>]} * The generated HTML code: * {[<input type="button" name="button_press" value="Press here">]} * * Such an interactor would be added as follows: * {[let id = add ia "press" "" (Some "press") ();; (* = "press" *)]} * * I.e. you can determine the identifier by passing it as fourth argument. * Of course, in this case it is checked whether the identifier is still * free; and [add] fails if the identifier was already previously used. * * {b Representation} * * Note that the representation of [Interactor.t] is optimized for efficient * serialization (using the Marshal module). Especially, if there are many * name/index pairs differing only in the index component, the name component * is stored only once. * * {b Further information} * * See {!Wd_types.interactors} *) open Wd_serialize_types type 'value_type t;; (** The type of interactors *) type id = string;; (** Interactors are identified by strings *) exception Element_exists of id;; (** Raised by some functions if there is already a component with the ID *) val create : 'value_type -> 'value_type t (** [create x]: Creates a new interactor manager. The value [x] must only * be passed because of typing restrictions. *) val clear : 'value_type t -> unit (** [clear ia]: Removes all entries from the interactor. The sequence * generator for the automatic IDs is not reset, however. *) val add : 'value_type t -> string -> string -> id option -> 'value_type -> id (** [add ia name index opt_id value]: adds the triple [(name,index,value)] to * [ia]; if [opt_id] is [None], the triple gets an automatically selected * numerical ID; if [opt_id] is [Some id], the triple has the ID [id]. * The function returns the ID. * * Fails with [Element_exists] if the pair [(name,index)] is already * contained. The argument of this exception is the ID. *) val lookup : 'value_type t -> id -> (string * string * 'value_type) (** [lookup ia id]: looks up the triple [(name,index,value)] for the ID [id] * within [ia]. * * Fails with "Interactor.lookup" if the id cannot be associated. *) val exists : 'value_type t -> string -> string -> bool (** [exists ia name index]: returns whether the pair [(name,index)] exists * in [ia]. *) val iter : (id -> string -> string -> 'value_type -> 'a) -> 'value_type t -> unit (** [iter f ia]: iterates over the elements of [ia] and invoke the function * [f] for every element by [f id name index value]. *) val serialize : ('value_type -> string) -> Buffer.t -> 'value_type t -> unit (** [serialize f b ia]: Writes the serialization of [ia] to buffer [b]. * Contained values are serialized by calling [f]. *) val unserialize : (('u,'d,'e) poly_ds_buf -> 'value_type) -> ('u,'d,'e) poly_ds_buf -> 'value_type t (** [unserialize f buf]: Reads the serialized string from [buf] and reconstructs * the interactors. Values are read by calling [f]. *) val lock : 'value_type t -> bool -> unit (** Sets the locking flag. If this flag is [true], it is not allowed to [add] * new interactors. * * After [create], [clear], and [unserialize] this flags is implicitly * set to [false]. *) (**/**) val revision_interactor : string (* Returns the CVS revision string. It is part of the hash value * that goes into the serialized objects *) (* ====================================================================== * History: * * $Log: wd_interactor.mli,v $ * Revision 3.7 2005-12-09 20:02:40 stolpmann * Fix in Wd_interactor.unserialize. * * The [interactors] are now locked in the "handle" stage of processing. * Any trial will fail. * * Revision 3.6 2005/06/11 14:24:14 stolpmann * Extension of bracket expressions: many new functions. * Functions in bracket expressions may now lazily evaluate their arguments. * ui:if and ui:ifvar may refer to any functions defined for bracket * expressions. * New: ui:ifexpr * Parsing of bracket expressions is now done with ulex. Private interfaces * of PXP are no longer used for this purpose. * Serialization has been rewritten, and it is now safe. * Fix: In ui:context there may now be macro references at any location. * Also documented all these changes. * * Revision 3.5 2002/04/10 21:27:52 stolpmann * New scheme for automatically generated interactor IDs. There * are now two parts: <base>_<seq> where <base> is the base number * (currently derived from the system clock), and where <seq> is the * sequence number. Sequence numbers are no longer reset to 0 after * "handle". (The reason for the new ID scheme are buggy browsers that * try to remember old form values. It is now very unlikely that a * name for a form field is reused before the page expires.) * * Revision 3.4 2002/04/10 20:03:14 stolpmann * The CVS revision number is exported. * * Revision 3.3 2002/02/16 17:29:45 stolpmann * mostly ocamldoc. * * Revision 3.2 2002/02/14 16:15:21 stolpmann * Added copyright notice. * * Revision 3.1 2002/02/12 20:29:23 stolpmann * Initial release at sourceforge. * * Revision 1.3 2000/12/04 11:58:54 gerd * Added documentation. * * Revision 1.2 2000/05/08 17:56:22 gerd * Changed such that arbitrary strings can be used as interactor * IDs as well as automatically generated numbers. * * Revision 1.1 2000/04/13 17:42:57 gerd * Initial revision. * * *)