*Project* The Anubis Project
*Title* Producing HTML/Javascript code.
*Copyright* Copyright (c) Alain Prouté 2001.
read tools/basis.anubis
read system/string.anubis
*** Managing Web Arguments.
When a client submits a form, he sends informations to the server. This information is
transformed by the server into a list of data of type 'Web_arg'. This is the reason why
a 'web page' operation always has a unique argument of type 'List(Web_arg)'.
The type 'Web_arg' is defined in 'web/common.anubis' as follows:
public type Web_arg:
web_arg(String name,
String value),
upload (String name,
String value,
String temp_file_path).
read CXM_common.anubis
In other words, a 'web argument' is just a pair made of the name of the argument, and
the value of the argument, and both are character strings. 'upload' will be explained
later.
The next variable is a multipurpose counter (used to generate unique names).
variable Int web_count = 0.
define Int
new_web_count
=
web_count <- *web_count+1;
*web_count.
Names for Web colors.
public type Web_color_name:
aliceblue,
antiquewhite1,
antiquewhite2,
antiquewhite3,
antiquewhite4,
aquamarine1,
aquamarine2,
aquamarine3,
aquamarine4,
azure1,
azure2,
azure3,
azure4,
yellow.
and so on ... (see below why I did not do more).
Web colors.
public type Web_color:
rgb(Word8,Word8,Word8), /* give the color by its components */
_(Web_color_name). /* or by its name */
The following produces '' tags, which are put in the head of the document.
public type WebMeta:
keywords(List(String)),
refresh(String url, Int delay), // in seconds
meta(String name, String content),
http_equiv(String name, String content).
*******************************************************
* Web items *
* (the many kinds of things one may put in a page) *
*******************************************************
public type Web_item:
[ ], /* empty (invisible) item */
... this is a cross recursive type.
Options for web page body.
public type LayerDisposition:
horizontal,
vertical.
public type FollowPathCommand: // this type is used by the Web_body_option 'follow_path'.
pos(Int x, // x coordinate of position
Int y, // y coordinate of position
Int image_number, // the image to display at that position
Int delay). // wait that milliseconds before leaving this position
public type Web_body_option:
background_color(Web_color), /* color for the background */
//
// 'psychedelic_background' produces a background color which is continuously changing.
// 'average' is the average luminosity of the color. 'amplitude' is the maximal variation
// the luminosity around the average. 'delay' is the number of milliseconds between two
// color changes. For example, you may try 'psychedelic_background(200,50,1000)', which
// produces a background whose color changes very slowly (this is not tiring) among rather
// light pastel colors.
//
psychedelic_background(Int average, /* average light (0 to 255) */
Int amplitude, /* amplitude of variation of light */
Int delay), /* in milliseconds */
background_image(String file_name), /* name of image file for the background */
//
// 'scrolling_layer' produces a layer above the page which is scrolling continuously either
// vertically or horizontally. The 'content' is indefinitly repeated.
//
scrolling_layer(LayerDisposition,
Int steps, /* number of pixels of each move */
Int margin, /* measured from left or top in pixels */
Int delay, /* milliseconds for one move */
Web_item content, /* content of layer (will be repeated) */
Int period), /* number of pixels between two instances of 'content' */
//
// 'bounce' shows its content above the page and let it move and bounce on the edges of a rectangle.
// The rectangle is determined by the last 4 arguments.
//
bounce(Web_item content,
Int left,
Int right,
Int top,
Int bottom),
//
// put something over the page in any position you want:
//
over(Web_item content,
Int left,
Int top),
//
// follow_path: let a changing image follow a path on the screen. This gadget shows
// an image following a polygonal path on the screen. The image may change at regular
// intervals, thus providing extra animation. The images are displayed in the order
// they are given in the first argument. When the last image has been displayed, the
// first image is displayed again, and so on. The path is a sequence of absolute positions
// on screen (actually in the browser's window or frame), which is followed in the
// order given in the 'path' argument. If 'loop' is true, the path is followed again and again.
// Otherwise, it is followed only once. If you want to make a closed loop, the last
// position must be the same as the first one. 'steps' is the number of pixels of distance
// between two successive positions of the image, and 'delay' the number of milliseconds
// between two successive positions. 'change_every' is the number of steps (a 'step' is
// passing from one position to the next one) after which the displayed image is replaced
// by the next image.
//
// Each position 'pos(x,y,i,d)' has 4 parameters. 'x' and 'y' are the coordinates of the
// position in the browser's window or frame. 'i' is the number of the image to display
// at this position (i.e. the rank of the image in the list 'filename'. The first one has
// rank 0). 'd' is the delay in milliseconds to wait before leaving that position.
//
follow_path(List(String) filenames, /* the changing images which follows the path */
Int change_every, /* number of steps betwen two changes */
List(FollowPathCommand) path, /* the polygonal path and commands */
Bool loop, /* if true do it repeatedly, otherwise only once */
Int steps, /* approximative distance (in pixels) between two
successive positions */
Int delay), /* milliseconds between two successive positions */
load_image(String name), /* load an image (for next page), which is not displayed */
left_margin(Int), /* left margin for document */
top_margin(Int), /* top margin for document */
margin_width(Int),
margin_height(Int),
reload_frame(String name, /* name of target frame */
String url), /* url to load in this frame */
onload(String function_name). /* nom de la fonction javascript (sans les '()') */
public type BodyOnload:
reload_frame(String name, String url).
variable List(BodyOnload) body_onloads = [ ].
define One
add_body_onload
(
BodyOnload item
) =
body_onloads <- [item . *body_onloads].
define Printable_tree
format
(
BodyOnload item
) =
if item is
{
reload_frame(name,url) then (Printable_tree)
[ " window.open('",url,"','",name,"');" ]
}.
define Printable_tree
format
(
List(BodyOnload) l
) =
if l is
{
[ ] then (Printable_tree)[ ],
[h . t] then (Printable_tree)
[format(h) . format(t)]
}.
---- Body of a web page. --------------------------------------------
public type Page_body:
body(List(Web_body_option), /* list of body options */
Web_item content). /* the content of the page */
public type VFrame:
frame(Int height,
Printable_tree url,
String name).
---- Web pages. -----------------------------------------------------
public type Web_page:
web_page(String title, /* title appearing on top of browser */
List(WebMeta) meta_tags,
Printable_tree head_scripts, /* scripts à placer dans la balise head */
Page_body body), /* body of page */
standard_frameset(String title,
List(WebMeta) meta_tags,
Int height, /* height of 'top menu' (pixels) */
Int width, /* width of 'left menu' (pixels) */
Printable_tree main). /* url for main */
+---------+--------------------------+
| | ^ |
|<-width->| top height |
| | v |
| left +--------------------------+
| | |
| | main |
| | |
| | |
| | |
+---------+--------------------------+
Note: top and left frames must be loaded through the Web_body_option 'reload_frame'.
public define Web_page
web_page
(
String title,
Page_body body
) =
web_page(title,[],[], body).
public define Web_page
web_page
(
String title,
List(WebMeta) meta_tags,
Page_body body
) =
web_page(title, meta_tags, [], body).
public define Web_page
web_page
(
String title,
Printable_tree head_scripts,
Page_body body
) =
web_page(title, [], head_scripts, body).
public define Web_page
standard_frameset
(
String title,
Int height,
Int width,
Printable_tree main
) =
standard_frameset(title, [], height, width, main).
variable Printable_tree scripts = [].
define One
add_script
(
Printable_tree script
) =
scripts <- [*scripts . script].
---- Non empty web items. -------------------------------------------
We have already seen the empty web item. Together with the following one, it enables to
make (pseudo-)lists of web items, which will be presented one after the other (from
left to right) in the browser's window.
public type Web_item:
[Web_item . Web_item],...
A web item may be a simple string or a simple integer:
public type Web_item:
text(String),
text_pt(Printable_tree),
text_nowrap(String),
text_nowrap_pt(Printable_tree),
par(String),
preformated_text(String text),
integer(Int),
float(Float,Int),...
You may want to center a web item in a page. Just enclose it into
'center(...)':
public type Web_item:
center(Web_item),...
You may want to write characters of a given item with a big font:
public type Web_item:
bigger(Int,Web_item),
smaller(Int,Web_item),
bold(Web_item),
italic(Web_item),
big(Web_item),
very_big(Web_item),...
Most of the previous are subsumed by 'style':
public type WebStyle:
background_image(String file_name),
background_color(Web_color color),
background_transparent,
background_repeat_horizontal, // repeat the background image only horizontally
background_repeat_vertical,
background_no_repeat,
color(Web_color color),
float_to_left, // the web item will float to the left and text will wrap around
float_to_right,
font_family(String font_name), // "verdana" "helvetica" "times" etc...
font_size(Int size),
italic,
oblique,
small_capitals,
bold,
bolder,
lighter,
line_height(Int height),
text_center,
text_left,
text_right,
text_justify,
text_underline,
text_blink,
text_line_through,
width(Int n).
public type Web_item:
style(List(WebStyle) styles, Web_item content),...
public type Web_item:
spacer(Int width, Int height),
image(String file_name), /* image */
image_d(String file_name, String description),
image_pt(Printable_tree file_name),
on_image(String file_name, Web_item content),
turning_images(NonEmptyList(String) filenames, Int millisecs),...
A 'rollover' has the same role as a submit button or link, but it is prettier. It is
made of two images. The first one 'image_on' determines the aspect of the button when
the mouse cursor is on it. The other one 'image_off' determines the aspect of the
button when the mouse cursor is anywhere else. The two images should be of the same
size, otherwise bad effects may occur. The last operand 'description' is a small text
which describes the role of the button. It appears in a bubble in the browser's window.
public type Web_item:
rollover(List(String) preload_images, // images to preload before the rollover is effective
String url, // URL with possible web arguments
String target,
String image_on, // file name of 'highlighted' image
String image_off, // file name of 'non highlighted' image
String description), // short behavior description
rollover(List(String) preload_images,
String url,
String target,
String image_on,
String image_off,
Int width,
Int height,
String description), ...
Mouse sensitive images are images with predefined zones which are clickable. When
clicking in a zone, the specified corresponding URL is loaded by the browser. If two
zones overlap, the first one (in the order they are defined) is selected.
Zones are of 3 sorts: rectangles, circles and polygons. Point's coordinates are
specified as pairs of integers (of anonymous agglomeration type (Int,Int)). The
first coordinate counts pixels from the left of the image. The second coordinate counts
pixels from the top of the image. With polygons, you can construct zones which are
almost as complicated as you want. You may also construct a zone as the overlapping of
several zones with the same URL.
public type Mouse_Sensitive_Zone:
rectangle
(
(Int,Int) left_top,
(Int,Int) right_bottom,
String url
),
circle
(
(Int,Int) center,
Int radius,
String url
),
polygon
(
List((Int,Int)) vertices,
String url
).
public type Web_item:
mouse_sensitive_image(String image_file_name, // the image itself
List(Mouse_Sensitive_Zone) zones),...
In project: mouse sensitive images, whose zones behave like submission buttons (to be
used within a form).
public type Web_item:
background_sound(String sound_file_name,
Bool loop),...
*************************
* FORMS *
*************************
Use 'forms' in order to get informations back from the client. The constructor 'form'
take 2 arguments:
- the name of the form, which must be the name of an Anubis web
page. Indeed, when the user will submit the form, this page will
be sent to him.
- the content of the form, which may be any web item, but which
normally (amongh other things) contains input fields and a
submit button.
public type Web_item:
form(Printable_tree name,
Web_item content),
form_target(Printable_tree name,
Web_item content,
String target),
form(Printable_tree name,
String label_name,
Web_item content),
form_name(String form_name, // option name de form
Web_item content),...
public define Web_item
form
(
Printable_tree name,
Web_item content
) =
form("", name, content).
Within a form, you may put 'text input fields', that the client may
edit. The constructor 'text_input' has the following arguments:
- name of input field. This will be the name of the correponding
web argument in the Anubis web page referred to by the form.
- size of field (as it appears on client screen),
- initial value of field (the text that appears in the field, when
the client downloads the page).
public type Text_Input_Option
public type Web_item:
text_input(String name, /* text field to be documented by user */
Int size,
String initial_value),...
public define Web_item
text_input
(
String name,
Int size,
String initial_value
) =
text_input( (List(Text_Input_Option)) [], name, size, initial_value).
public type Web_item:
password_input(String name,
Int size),
text_area(String name,
Int columns,
Int rows,
String initial_text),
upload(String name, Int size),...
public type Web_item:
submit(String button_text), /* submit button with text on it */
submit_pt(Printable_tree button_text),
submit(String name, String text),
submit_close(String name, String text),
submit_pt2(String name, Printable_tree text),
image_submit(String name, String image_file_name),
image_submit(String name, String value, String image_file, Web_item content),
hl_image_submit(String action_name,
String value,
String image_name,
String image_file,
String hl_image_file),
text_submit(String name, String value, String text),
web_submit(String web_args, Web_item content),
button(String name, String text, String on_click_fonction, Int width, Int height),...
public type Web_item: /* mark the form with an information */
mark(String name, String value),
mark_pt(String name, Printable_tree value),...
public type Web_item:
close_button, /* button that closes the window */
close_button(String image_file_name), ...
*********************************
* LABELS *
*********************************
A 'label' is just a name that you may give to a position in a document. Use the
following invisible Web_item 'label' to this end. Now, you can also create links in
the same document, which, when clicked by the user, scroll the document, so that the
position whose name is the given label is shown just at the top of the browser's
window.
public type Web_item:
label(String label_name), /* give a name to a position in the page */
go_to_label(String label_name, /* a link for jumping to a label */
Web_item content),...
********************************
* TABLES *
********************************
A web item may be a table. A table is produced by the constructor
'table' from the type 'Web_item'. This constructor takes 2
arguments:
- a list of 'table options',
- a list of 'table rows'.
Of course, you use as many options as you want, including
none (if you do not want any option, put the empty list '[ ]' as
this argument). Some options have precedence over others. For example
a background image will hide the background color.
Table options are defined below:
public type Table_option:
/* use a color as a background for the table, if you want it to
be different from the background of the page */
background_color(Web_color),
/* or use an image as the background of the table */
background_image(String file_name),
/* draw a border line around the table (and around each cell in
the table). You may also specify a geometry (in pixels) for the
border. This makes the 'in relief' part of the border appear
more or less wide. You may also specify a color for the border. */
border,
nude, /* equivalent to 'border(0,0,0)' (below) */
border(Int, /* width of exterior (pixels) */
Int, /* width of top */
Int), /* width of interior */
border_color(Web_color),
absolute_width(Int).
A 'table row' is made of a list of 'row options', and a list of
'cells'. A 'cell' itself has a list of 'cell options', and a web item,
which is its content. We begin by the description of options.
public type Row_option:
/* following concerns the horizontal positions of items within the
cells of the row */
left,
h_center,
right,
/* the following concerns the vertical positions of items, within
the cells of the row */
top,
v_center,
bottom,
absolute_height(Int),
base_line,
/* set the background color of all cells in the row */
background_color(Web_color).
public type Cell_option:
/* all row options are available for individual cells, and apply
here only to one cell. */
left,
h_center,
right,
top,
v_center,
bottom,
base_line,
background_color(Web_color),
/* you can set the width of the cell either absolutely (in pixels)
or as a percentage of the width of the table. */
background_image(String file_name),
absolute_width(Int),
relative_width(Int),
absolute_height(Int),
relative_height(Int),
/* a cell may span over several columns or rows in the table */
columns(Int),
rows(Int),
nowrap.
public type Cell:
cell(List(Cell_option),
Web_item).
public type Table_row:
row(List(Row_option),
List(Cell)).
public define Table_row row(Web_item i) = row([],[cell([],i)]).
public define Table_row row(Cell c) = row([],[c]).
public define Table_row row(List(Cell) l) = row([],l).
public type Web_item:
table(List(Table_option),
List(Table_row)),...
public type Web_item:
list(List(Web_item)),...
public type Web_item:
link(String name, Web_item),
link(String name, String target, Web_item),...
public type Web_item:
link_for_download(String filename, Web_item),... // the filename is relative to the public directory
public type Web_item:
mail_to(String addr, Web_item),...
public type Web_item:
select(String name,
Int size,
List(String) choices),
select(String name,
Int size,
List(String) choices,
String selected),
immediate_select(String name, // selection will immediately submit the form
Int size,
List(String) choices),...
public type Web_item:
radio_button (Printable_tree name, String value),
checked_radio_button (Printable_tree name, String value),
check_box (Printable_tree name, String value),
checked_box (Printable_tree name, String value),...
public type Web_item:
link_to_window(Printable_tree name, Web_item),
link_to_window(Printable_tree name, String window_name, Web_item),
link_to_window_with_ticket(String name,
String web_args,
String window_name,
Web_item content,
Int width,
Int height),
link_to_window_with_ticket_and_scroll
(String name,
String web_args,
String window_name,
Web_item content,
Int width,
Int height),
link_to_window_with_ticket_and_scroll
(String name,
String label_name,
String web_args,
String window_name,
Web_item content,
Int width,
Int height),
link_to_frame (Printable_tree name, String frame_name, Web_item).
---- Formating operations (Anubis --> HTML/Javascript) ---------------------------
Stupid operation formating a web color name.
public define String
format
(
Web_color_name n
) =
if n is
{
aliceblue then "aliceblue",
antiquewhite1 then "antiquewhite1",
antiquewhite2 then "antiquewhite2",
antiquewhite3 then "antiquewhite3",
antiquewhite4 then "antiquewhite4",
aquamarine1 then "aquamarine1",
aquamarine2 then "aquamarine2",
aquamarine3 then "aquamarine3",
aquamarine4 then "aquamarine4",
azure1 then "azure1",
azure2 then "azure2",
azure3 then "azure3",
azure4 then "azure4",
yellow then "yellow",
}.
Anubis really needs some system of 'macros' to avoid this...
Formating a web color.
public define String
format
(
Web_color wc
) =
if wc is
{
rgb(r,g,b) then "\"#" + to_hexa(r) + to_hexa(g) + to_hexa(b) + "\"",
_(c) then format(c)
}.
public define String
format_without_quotes
(
Web_color wc
) =
if wc is
{
rgb(r,g,b) then "#" + to_hexa(r) + to_hexa(g) + to_hexa(b) + "",
_(c) then format(c)
}.
define Printable_tree
format
(
Web_color c
) = [(String)format(c)].
public define String
format_without_sharp
(
Web_color wc
) =
if wc is
{
rgb(r,g,b) then "" + to_hexa(r) + to_hexa(g) + to_hexa(b) + "",
_(c) then format(c)
}.
define Printable_tree
format_without_sharp
(
Web_color c
) = [(String)format_without_sharp(c)].
define Printable_tree
[Word32 x . Printable_tree t]
=
[to_Int(x) . t].
define Printable_tree
psychedelic_bg
(
Int average,
Int amplitude,
Int delay
) =
with ampl = if amplitude >= 120 then 120 else
if amplitude =< 1 then 1 else amplitude,
with aver = if average+ampl >= 254 then 254-ampl
else if average-ampl =< 1 then 1+ampl else average,
[ ""].
define List(Web_body_option)
replace_background_init
(
List(Web_body_option) l,
Int average,
Int amplitude,
Int delay
) =
if l is
{
[ ] then [ ],
[h . t] then
if h is background_color(_)
then [background_color(rgb(truncate_to_Word8(average+amplitude),
truncate_to_Word8(average),
truncate_to_Word8(average-amplitude)))
. replace_background_init(t,average,amplitude,delay)]
else [h . replace_background_init(t,average,amplitude,delay)]
}.
define Maybe((Int,Int,Int))
get_psy
(
List(Web_body_option) l
) =
if l is
{
[ ] then failure,
[h . t] then
if h is psychedelic_background(a,f,d)
then success((a,f,d))
else get_psy(t)
}.
define List(Web_body_option)
prepare
(
List(Web_body_option) l
) =
if get_psy(l) is
{
failure then l,
success(op) then if op is (a,f,d) then
replace_background_init(l,a,f,d)
}.
public define Printable_tree
format
(
String c_ticket,
String s_ticket,
Web_item i
).
define Printable_tree
move_layer_command
(
String property,
Int n,
Int num,
Int i,
Int period
) =
if i >= num then [ ] else
[" if (document.layers)",
" { document.nslay",n,"_",i,".",property,"=layp",n,"+(",((i-1)),"); } ",
" else ",
" { ielay",n,"_",i,".style.",property,"=layp",n,"+(",(i-1)*period,"); } "
. move_layer_command(property,n,num,i+1,period)].
define Printable_tree
format_layers
(
LayerDisposition disp,
Int margin,
Web_item content,
Int n,
Int num,
Int i,
Int period
) =
if i >= num then [ ] else
["",
"