(*
* <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.6 2005-06-11 14:24:14 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 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.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.
*
*
*)