Syntax10.Scn.Fnt Syntax10i.Scn.Fnt`=IStampElemsAlloc20 Mar 989qInfoElemsAlloc#Syntax10.Scn.Fnt"Title": Form-Elements (FormElems) "Author": Stefan Aufischer "Abstract": Provides Textelements used in the Web-Browser of Oberon. Most elements are derived from the (Panel)Elems, some from the WebElems. "Keywords": Insert..., New... Form, Hidden, Image, SubmitButton, ResetButton, TextField, TextArea, CheckBox, RadioButton, PassWord, List. "Version": "From": 17.09.97 "Until": 17.03.98 "Changes": 8FoldElemsNew88Syntax10b.Scn.FntX:     a$88 8 8  88  8 E8o 8 8  8     , +8  8 38 8 88 8 88 88 88"&")38 FA  - 8"V W  <8  8 J8) 8   8 %8   "  Q8 @88 )8  (  " 8 ,8$  >&  8  8K * %8 8<' %8  8Q    8 "8 8     8 "82 8( -88$Syntax10i.Scn.FntAASubmit all form-elems between a beginning and an ending form-tag.W8  8@ TT  >(  )    >  7   #"#  $#)g'  5 ,# ' 8$Syntax10i.Scn.Fnt))Open result of submission in a new viewer88$Syntax10i.Scn.Fnt..Open result of submission in the active viewer8, N 8$Syntax10i.Scn.Fnt))Open result of submission in a new viewer 88$Syntax10i.Scn.Fnt..Open result of submission in the active viewer 8 88$Syntax10i.Scn.Fnt@@Reset all form-elems between a beginning and an ending form-tag.8  8S  `'+  2*V*   / 8!  8 (8  888 8  %")8 8  O88 88    8  ;8 8 8 8$ 8% 18 8!688$j8888   8"8 8& 8  M  8 ,8 8 $ 8#~H8 8R88^.8    "8 8  ,8  "8 $ 8! # 088#"8    !8 8 28  %8 I8&   8  8 ' 8!" 088 %8888   8 828 8"8$8  81 9 "8 !' & 3 3 + " 8 $8 &   8    8")  & $%0x88 (8(     8  8' 88 8"QS8 8# 88    88   }88 88 488"m$ I //H88#88":8 8  888 8  =8  8fH8 89788    88   w88 88 88Q  7 .F868 8( 88 8  !,8 891:88 f888 8   8"8  8 8   V  t888  8J8 8@8 8    88$ G .F8- 8(/!R8" 8G  8; 8  8W%%8  8 8  8 8  8, 8  8.8  8. 8  8,8 8/8  8.8  8.8 818  8.8  8* 8J    8Q  8  8D 8  8   #/ 8 8\ 8 &8  3!" "M8 '8 3  ""M8  *8  6 !!!#V8  <8'  4!!3v8  )8  5! #%8 ,8  !  "8!  #8  +82  6 !!!"#8*  8++/A8#Syntax10.Scn.Fntselection is marked by color(83<5+*q' '>(F 8 $8    &2%5 '& $' $:D'|" 8+  84+!$   9 8  8 18  8 *8 8068 80 58 80 F8 83: 8 80 28 80  5 8 80 E8  81'  88$Syntax10i.Scn.FntSet xDim and yDim|8  8/Z2185  8  !! 8C WMODULE FormElems; (** SA  *)  IMPORT  Files, Fonts, Display, Viewers, Texts, TextFrames, TextPrinter, Oberon, Web, WebElems, Elems, ButtonElems, CheckBoxElems, RadioButtonElems, TextFieldElems, TextAreaElems, ListElems, Strings, HTML; CONST  undef* = -1; left = 2; middle = 1; right = 0; cancel = {left, middle, right}; vLen = 1024; (* max. length of nondynamic string values in InputTag *) formCol* = 1; (* red *) hiddenCol* = 3; (* blue *) clickCol = 8; (* green *) pixel = LONG(TextFrames.Unit); elemH = 11 * pixel; formW = 14 * pixel; hiddenW = 11 * pixel; invisW = 1; (* width of an invisible element *) DUnit = TextFrames.Unit; TYPE  FormElem* = POINTER TO FormElemDesc;  FormElemDesc* = RECORD (WebElems.LinkElemDesc) method* : ARRAY 5 OF CHAR; encType* : ARRAY 64 OF CHAR END; HiddenElem* = POINTER TO HiddenElemDesc;  HiddenElemDesc* = RECORD (WebElems.ElemDesc); name* : ARRAY 64 OF CHAR; value* : Web.DynamicString END; ImageElem* = POINTER TO ImageElemDesc;  ImageElemDesc* = RECORD (WebElems.ImageElemDesc); x*, y* : INTEGER (* Coordinates of mouseclick, if SubmitForm is called by the elem *) END; (* Records containing variables for all attributes the input-, select-, option- and textarea-tags can have *) InputTag* = POINTER TO InputTagDesc;  InputTagDesc* = RECORD type*, value*, name*, align*, myValue* : ARRAY vLen OF CHAR; dynName*, dynValue*, src* : Web.DynamicString; size*, maxLen* : LONGINT; checked*, selected* : BOOLEAN END; Selection* = POINTER TO SelectionDesc;  SelectionDesc* = RECORD name* : ARRAY 64 OF CHAR; defaultSel* : ARRAY 256 OF CHAR; vertSize*, horizSize*, noOfOptions* : LONGINT; multiple*, popup*, done* : BOOLEAN; optionText*, (* Text to be displayed in ListElems.Elem *) valueText* : Texts.Text (* Text to be sent in case of submission *) END; Option* = POINTER TO OptionDesc;  OptionDesc* = RECORD text*, (* Text displayed in one line of ListElems.Elem *) value* : Web.DynamicString; selected* : BOOLEAN END; TextArea* = POINTER TO TextAreaDesc;  TextAreaDesc* = RECORD name* : ARRAY 64 OF CHAR; rows*, cols* : LONGINT END; TagMsg* = RECORD (Texts.ElemMsg)  name* : ARRAY 64 OF CHAR END;  SubmitMsg* = RECORD (Texts.ElemMsg)  rider* : Files.Rider; name* : ARRAY 64 OF CHAR; value* : ARRAY 1024 OF CHAR END;  ResetMsg* = RECORD (Texts.ElemMsg)  rider* : Files.Rider; name* : ARRAY 64 OF CHAR; value* : ARRAY 1024 OF CHAR END;  UpdateMsg* = RECORD (Texts.ElemMsg) END; AttrMsg* = RECORD (Elems.AttrMsg) END; VAR  fIcon, fClickIcon : ARRAY 2 OF Display.Pattern; (* x = 0, y = 3, w = 13, h = 8 *) hIcon, hClickIcon : Display.Pattern; (* x = 0, y = 3, w = 13, h = 8 *) w : Texts.Writer; cmdElem : ImageElem; (* ImageElem that initialized the latest command *) firstTime, (* TRUE when AppendEncoded is called from SubmitForm the first time *) newViewer : BOOLEAN; (* TRUE when ruibmission-result should appear in a new Viewer *) xDim, yDim : LONGINT; PROCEDURE ^ HandleForm* (e : Texts.Elem; VAR m : Texts.ElemMsg); (* Returns corresponding FormElem for "e" *) PROCEDURE (e: FormElem) Twin* () : WebElems.LinkElem;  VAR r: Texts.Reader; e1: FormElem; BEGIN e1 := NIL; IF e.side = WebElems.LeftSide THEN Texts.OpenReader(r, Texts.ElemBase(e), Texts.ElemPos(e)+1); Texts.ReadElem(r); WHILE (r.elem # NIL) & ~ (r.elem IS FormElem) DO Texts.ReadElem(r) END ELSE (* e.side = RightSide *) Texts.OpenReader(r, Texts.ElemBase(e), Texts.ElemPos(e)); Texts.ReadPrevElem(r); WHILE (r.elem # NIL) & ~ (r.elem IS FormElem) DO Texts.ReadPrevElem(r) END END; IF (r.elem # NIL) & (r.elem IS FormElem) & (r.elem(FormElem).side # e.side) THEN e1 := r.elem(FormElem) END; RETURN e1 END Twin; PROCEDURE GetDsr (f: Display.Frame; pos: LONGINT; fnt: Fonts.Font; VAR dsr: INTEGER);  VAR p: TextFrames.Parc; beg: LONGINT; BEGIN IF f = NIL THEN IF fnt = NIL THEN dsr := 0 ELSE dsr := - fnt.minY END ELSE TextFrames.ParcBefore(f(TextFrames.Frame).text, pos, p, beg); dsr := SHORT(p.dsr DIV DUnit) END END GetDsr; (* Help procedures for dynamic strings *) PROCEDURE CopyDynString (src : ARRAY OF CHAR; VAR dest : Web.DynamicString);  VAR len : INTEGER; BEGIN len := 0; WHILE src[len] # 0X DO INC(len) END; NEW(dest, len + 1); COPY(src, dest^) END CopyDynString;  PROCEDURE LoadDynString (VAR r : Files.Rider; VAR str : Web.DynamicString);  VAR pos : LONGINT; len : INTEGER; ch : CHAR; BEGIN pos := Files.Pos(r); len := 0; REPEAT Files.Read(r, ch); INC(len) UNTIL ch = 0X; IF len > 1 THEN NEW(str, len); Files.Set(r, Files.Base(r), pos); Files.ReadBytes(r, str^, len) ELSE str := NIL END END LoadDynString;  PROCEDURE StoreDynString (VAR r : Files.Rider; str : Web.DynamicString);  BEGIN IF str # NIL THEN Files.WriteString(r, str^) ELSE Files.Write(r, 0X) END END StoreDynString;  PROCEDURE ReadLine (VAR msg : WebElems.UpdateMsg; VAR str : ARRAY OF CHAR);  VAR i, len : INTEGER; ch : CHAR; BEGIN i := 0; len := SHORT(LEN(str)); REPEAT Texts.Read(msg.r, ch); str[i] := ch; INC(i) UNTIL (ch = 0X) OR (ch = 0DX) OR (i > len - 1); str[i-1] := 0X; WHILE (ch # 0X) & (ch # 0DX) DO Texts.Read(msg.r, ch) END (* skip to next line *) END ReadLine;  PROCEDURE ReadDynLine (VAR msg : WebElems.UpdateMsg; VAR str : Web.DynamicString);  VAR pos : LONGINT; i : INTEGER; ch : CHAR; BEGIN pos := Texts.Pos(msg.r); i := 0; REPEAT Texts.Read(msg.r, ch); INC(i) UNTIL (ch = 0X) OR (ch = 0DX); (* determine length of line *) IF i > 1 THEN NEW(str, i); Texts.OpenReader(msg.r, msg.text, pos); i := 0; REPEAT Texts.Read(msg.r, ch); str[i] := ch; INC(i) UNTIL (ch = 0X) OR (ch = 0DX); str[i-1] := 0X ELSE str := NIL END END ReadDynLine; (* Help-procedures for Texts *) PROCEDURE TextLineToString*(t : Texts.Text; VAR pos : LONGINT; VAR s : ARRAY OF CHAR; VAR col : SHORTINT) : BOOLEAN; VAR i : INTEGER; r: Texts.Reader; ch : CHAR; len : LONGINT; BEGIN i := 0; len := LEN(s); Texts.OpenReader(r, t, pos); Texts.Read(r, ch); IF r.eot THEN s[0]:=0X; pos := Texts.Pos(r); RETURN(FALSE) END; col := r.col; WHILE ~r.eot & (i < len - 1) & (ch # Elems.CR) DO IF ch # Texts.ElemChar THEN s[i] := ch; INC(i) END; Texts.Read(r, ch) END; s[i] := 0X; pos := Texts.Pos(r); RETURN(TRUE) END TextLineToString;  PROCEDURE TextLineToDynString*(t : Texts.Text; VAR pos : LONGINT; VAR s : Web.DynamicString; VAR col : SHORTINT) : BOOLEAN; VAR i : INTEGER; r: Texts.Reader; ch : CHAR; BEGIN i := 0; Texts.OpenReader(r, t, pos); Texts.Read(r, ch); IF r.eot THEN NEW(s, 1); s[0]:=0X; pos := Texts.Pos(r); RETURN(FALSE) END; col := r.col; WHILE ~r.eot & (ch # Elems.CR) DO IF ch # Texts.ElemChar THEN INC(i) END; Texts.Read(r, ch) END; NEW(s, i+1); RETURN(TextLineToString(t, pos, s^, col)); END TextLineToDynString;  PROCEDURE TextSizes*(t : Texts.Text; VAR cols, rows : LONGINT);  VAR i : INTEGER; r: Texts.Reader; ch : CHAR; BEGIN cols := 0; rows := 0; i := 0; Texts.OpenReader(r, t, 0); Texts.Read(r, ch); WHILE ~r.eot DO IF (ch = Elems.CR) THEN INC(rows); IF i>cols THEN cols := i END; i := 0 ELSIF ch # Texts.ElemChar THEN INC(i) END; Texts.Read(r, ch) END; IF (i>0) THEN INC(rows) END; IF i>cols THEN cols := i END; END TextSizes;  (* Encode name and value with Web.EncodeStr ("+" & SPACE are extra-encoded) Then append encoded strings to the Files.Rider "rid" --> ...&name=value *) PROCEDURE AppendEncoded* (VAR rid : Files.Rider; name, value : ARRAY OF CHAR);  PROCEDURE EncodeStr(VAR str : ARRAY OF CHAR);  VAR pos : INTEGER; BEGIN Web.EncodeStr(str, " "); pos := 0; WHILE str[pos] # 0X DO IF str[pos] = " " THEN str[pos] := "+" ELSIF str[pos] = "+" THEN str[pos] := "%"; Strings.Insert("2B", pos + 1, str); INC(pos, 2) END; INC(pos) END END EncodeStr;  PROCEDURE WriteString(VAR r : Files.Rider; VAR str : ARRAY OF CHAR);  BEGIN Files.WriteBytes(r, str, Strings.Length(str)) END WriteString; BEGIN EncodeStr(name); EncodeStr(value); IF ~firstTime THEN Files.Write(rid, "&") END; firstTime := FALSE; WriteString(rid, name); Files.Write(rid, "="); WriteString(rid, value) END AppendEncoded;  (* Is called by a submit-button, a textfield (when return is pressed), or an image-map between a beginning and an ending form-tag. All formular-elements that also belong to this formular are coded and sent to the URL specified by the action-attribute in the beginning formular-tag (of course according to "encType" and "method" of the form) *) PROCEDURE SubmitForm*;  VAR e : Texts.Elem; f : FormElem; r : Texts.Reader; queryStr : ARRAY 1024 OF CHAR; nameStr : ARRAY 1024 OF CHAR; error, (* TRUE when the submit-button is not between a beginning and an ending form-tag *) stop : BOOLEAN; body : Web.Body; file : Files.File; rid : Files.Rider; submitMsg : SubmitMsg; BEGIN firstTime := TRUE; error := FALSE; f := NIL; IF cmdElem = NIL THEN e := Elems.CmdElem ELSE e := cmdElem END; Texts.OpenReader(r, Texts.ElemBase(e), Texts.ElemPos(e)); (* Parse back to previous "FormTag" *) WHILE ~r.eot & (f=NIL) & ~error DO Texts.ReadPrevElem(r); e := r.elem; IF e#NIL THEN WITH e : FormElem DO IF e.side = WebElems.LeftSide THEN f:=e ELSE error := TRUE END ELSE END ELSE error := TRUE END END; file := Files.New(""); IF f # NIL THEN Strings.Cap(f.method) END; (* Check possible errors that prevent from sending the form *) IF (f=NIL) OR error THEN error := TRUE; Web.LogF("SubmitForm: Beginning Form-Tag expected! (pos #)$",Texts.Pos(r)+1) ELSIF (f.method # "GET") & (f.method # "POST") & (f.method # "") THEN error := TRUE; Web.LogStr("SubmitForm:$ unknown METHOD: '"); Web.LogStr(f.method); Web.LogF("' (pos #)$",Texts.Pos(r)+1) ELSIF (f.encType # "application/x-www-form-urlencoded") & (f.encType # "") THEN error := TRUE; Web.LogStr("SubmitForm:$ unknown ENCTYPE: '"); Web.LogStr(f.encType); Web.LogF("' (pos #)$",Texts.Pos(r)+1) END; IF ~error THEN Files.Set(submitMsg.rider, file, 0); (* Parse forward to ending "FormTag" and encode & append names and values of each formular-element *) Texts.ReadElem(r); stop := FALSE; WHILE ~r.eot & ~stop DO Texts.ReadElem(r); e := r.elem; IF e#NIL THEN WITH e : FormElem DO IF e.side = WebElems.LeftSide THEN error := TRUE; Web.LogF("SubmitForm: Ending Form-Tag expected! (pos #)$",Texts.Pos(r)+1) END; stop := TRUE; e:= NIL ELSE submitMsg.name := ""; r.elem.handle(r.elem, submitMsg) END END END END; IF ~error THEN (* Open Url specfied in form-tag *) IF f.method = "POST" THEN NEW(body); COPY(f.encType, body.type); body.coding := ""; body.file := file; IF newViewer THEN WebElems.FollowLink(f, "POST", "", NIL, NIL, body) ELSE WebElems.FollowLink(f, "POST", "", NIL, Texts.ElemBase(f), body) END ELSE Files.Set(rid, file, 0); queryStr := ""; WHILE ~rid.eof DO Files.ReadString(rid, nameStr); Strings.Append(nameStr, queryStr) END; IF newViewer THEN WebElems.FollowLink(f, "GET", queryStr, NIL, NIL, NIL) ELSE WebElems.FollowLink(f, "GET", queryStr, NIL, Texts.ElemBase(f), NIL) END END END; newViewer := FALSE; Files.Close(file) END SubmitForm; (* Is called by a reset-button between a beginning and an ending form-tag. All formular- elements that also belong to this formular are set to their default-values *) PROCEDURE ResetForm*;  VAR e : Texts.Elem; pos : LONGINT; r : Texts.Reader; error, (* TRUE when the reset-button is not between a beginning and an ending form-tag *) stop : BOOLEAN; resetMsg : ResetMsg; BEGIN error := FALSE; stop := FALSE; e := Elems.CmdElem; pos := Texts.ElemPos(e); Texts.OpenReader(r, Texts.ElemBase(e), pos); (* Parse back to previous "FormTag" *) WHILE ~r.eot & ~stop DO Texts.ReadPrevElem(r); e := r.elem; WITH e : FormElem DO stop := TRUE; IF e.side = WebElems.RightSide THEN error := TRUE END ELSE END END; IF ~stop OR error THEN Web.LogF("ResetForm: Beginning Form-Tag expected! (pos #)$", Texts.Pos(r)) ELSE Web.NeutralizeText(Texts.ElemBase(e)); (* Parse forward to ending "FormTag" and set formular-elements to default-values *) Texts.ReadElem(r); stop := FALSE; WHILE ~r.eot & ~stop DO Texts.ReadElem(r); e := r.elem; IF (e#NIL) THEN WITH e : FormElem DO IF e.side = WebElems.LeftSide THEN error := TRUE END; stop := TRUE ELSE e.handle(e, resetMsg) END ELSE END END END; IF error THEN Web.LogF("ResetForm: Ending Form-Tag expected! (pos #)$", Texts.Pos(r)) END END ResetForm; (* Handlers for all FormElems *) PROCEDURE HandleButton* (e: Texts.Elem; VAR m: Texts.ElemMsg);  VAR type, value : ARRAY vLen OF CHAR; PROCEDURE HandleAttrButton(e : ButtonElems.Elem; VAR m : AttrMsg); BEGIN Elems.Done := TRUE; IF m.id = Elems.enum THEN Elems.GetString(e, "Type", type); IF type = "SubmitButton" THEN m.enum("Name", Elems.String) END; m.enum("Value", Elems.String) ELSE ButtonElems.Handle(e, m) END END HandleAttrButton; BEGIN WITH e : ButtonElems.Elem DO WITH m : AttrMsg DO  HandleAttrButton(e, m) | m: SubmitMsg DO  Elems.GetString(e, "Type", type); IF (type = "SubmitButton") & (e = Elems.CmdElem) & (cmdElem = NIL) THEN Elems.GetString(e, "Name", m.name); Elems.GetString(e, "Value", m.value); IF m.name#"" THEN AppendEncoded(m.rider, m.name, m.value) END END | m: UpdateMsg DO  Elems.GetString(e, "Value", value); Elems.SetString(e, "Caption", value); e.W := DUnit * LONG(Strings.Length(value)) * xDim + DUnit * 10; e.H := DUnit * yDim + DUnit * 5 | m: TagMsg DO  Elems.GetString(e, "Type", type); IF type = "SubmitButton" THEN m.name := "" ELSIF type = "ResetButton" THEN m.name := "" ELSE m.name := "No FormElems.Button" END | m: Texts.IdentifyMsg DO  m.mod := "FormElems"; m.proc := "AllocButton" | m : Elems.ExecMsg DO newViewer := m.unload; ButtonElems.Handle(e, m) ELSE ButtonElems.Handle(e, m) END END END HandleButton;  PROCEDURE HandleAttrTextField* (e : TextFieldElems.Elem; VAR m : AttrMsg);  BEGIN Elems.Done := TRUE; IF m.id = Elems.enum THEN m.enum("Name", Elems.String); m.enum("Size", Elems.Int); m.enum("MaxLen", Elems.Int); m.enum("DefaultValue", Elems.String) ELSE TextFieldElems.Handle(e, m) END END HandleAttrTextField;  PROCEDURE HandleTextField* (e: Texts.Elem; VAR m: Texts.ElemMsg);  VAR inp : InputTag; BEGIN WITH e : TextFieldElems.Elem DO WITH m : AttrMsg DO HandleAttrTextField(e, m) | m: UpdateMsg DO  NEW(inp); Elems.GetInteger(e, "Size", inp.size); IF inp.size <= 0 THEN inp.size := 20; Elems.SetInteger(e, "Size", inp.size) END; e.W := DUnit * xDim * inp.size + DUnit * 10  | m: SubmitMsg DO  Elems.GetString(e, "Name", m.name); Elems.GetString(e, "Value", m.value); AppendEncoded(m.rider, m.name, m.value) | m: ResetMsg DO  NEW(inp); Elems.GetString(e, "DefaultValue", inp.value); Elems.SetString(e, "Value", inp.value); Texts.ChangeLooks(e.txt, 0, e.txt.len, {0}, HTML.fixedFont, 0, 0); Elems.UpdateElem(e) | m: TagMsg DO  m.name := "" | m: Texts.IdentifyMsg DO  m.mod := "FormElems"; m.proc := "AllocTextField" ELSE TextFieldElems.Handle(e, m) END END END HandleTextField;  PROCEDURE HandleTextArea* (e: Texts.Elem; VAR m: Texts.ElemMsg);  VAR ta : TextArea; txt : Texts.Text; PROCEDURE TextToString (t : Texts.Text; VAR str : ARRAY OF CHAR); VAR r : Texts.Reader; ch : CHAR; i, len : INTEGER; BEGIN len := SHORT(LEN(str)); i := 0; Texts.OpenReader(r, t, 0); Texts.Read(r, ch); WHILE ~r.eot & (i < len-1) DO WHILE ~r.eot & (ch = Texts.ElemChar) DO Texts.Read(r, ch) END; IF ~r.eot THEN str[i] := ch; INC(i); IF (ch=Elems.CR) & (i Called if Handler gets UpdateMsg *) PROCEDURE UpdateList (e : ListElems.Elem);  VAR sel : Selection; BEGIN NEW(sel); Elems.GetText(e, "ValueT", optT); Texts.ChangeLooks(optT, 0, optT.len, {0}, HTML.fixedFont, 0, 0); TextSizes(optT, sel.horizSize, sel.noOfOptions); Elems.SetText(e, "ValueT", optT); Elems.GetBoolean(e, "Multi", sel.multiple); Elems.GetInteger(e, "Size", sel.vertSize); IF sel.vertSize <= 1 THEN IF sel.multiple THEN sel.vertSize := 5 ELSE sel.vertSize := 1 END ELSIF sel.vertSize > sel.noOfOptions THEN sel.vertSize := sel.noOfOptions END; IF sel.vertSize < 1 THEN sel.vertSize := 1 END; Elems.SetInteger(e, "Size", sel.vertSize); IF sel.vertSize = 1 THEN Elems.SetBoolean(e, "Multi", FALSE); Elems.GetText(e, "ValueT", optT); Texts.ChangeLooks(optT, 0, optT.len, {1}, NIL, 15, 0); Elems.GetText(e, "Keywords", keyT); Texts.ChangeLooks(keyT, 0, keyT.len, {1}, NIL, 15, 0); END; Elems.SetBoolean(e, "Popup", sel.vertSize = 1); Elems.SetBoolean(e, "Combo", FALSE); Elems.SetBoolean(e, "Scrollbar", sel.vertSize < sel.noOfOptions); e.H := DUnit * yDim * sel.vertSize + DUnit * 10; e.W := DUnit * xDim * sel.horizSize + DUnit * 10; IF (sel.vertSize=1) OR (sel.vertSize < sel.noOfOptions) THEN e.W := e.W + DUnit * 18 END END UpdateList;  PROCEDURE HandleAttrList(e : ListElems.Elem; VAR m : AttrMsg); BEGIN Elems.Done := TRUE; IF m.id = Elems.enum THEN m.enum("Name", Elems.String); m.enum("Size", Elems.Int); m.enum("Multi", Elems.Bool); m.enum("ValueT", Elems.Text); Elems.GetBoolean(e, "Popup", popup); m.enum("Keywords", Elems.Text); IF popup THEN m.enum("DefaultValue", Elems.String) ELSE m.enum("DefaultValueT", Elems.Text) END ELSE ListElems.Handle(e, m) END END HandleAttrList; BEGIN WITH e : ListElems.Elem DO WITH m : AttrMsg DO HandleAttrList(e, m) | m: UpdateMsg DO UpdateList(e) | m: SubmitMsg DO  Elems.GetString(e, "Name", m.name); Elems.GetBoolean(e, "Popup", popup); Elems.GetText(e, "ValueT", optT); Elems.GetString(e, "Value", defaultValue); (* selected text in case of popup list *) Elems.GetText(e, "Keywords", keyT); (* textlines to be sent if selected *) keyPos := 0; optPos := 0; eoKeyT := ~TextLineToString(keyT, keyPos, key, col); eot := ~TextLineToString(optT, optPos, m.value, col); WHILE ~eot DO IF (popup & (m.value = defaultValue)) OR (~popup & (col = ListElems.SelCol)) THEN AppendEncoded(m.rider, m.name, key) END; eoKeyT := ~TextLineToString(keyT, keyPos, key, col); eot := ~TextLineToString(optT, optPos, m.value, col); END | m: ResetMsg DO  Elems.GetBoolean(e, "Popup", popup); IF popup THEN Elems.GetString(e, "DefaultValue", defaultValue); Elems.SetString(e, "Value", defaultValue) ELSE Elems.GetText(e, "DefaultValueT", optT); Elems.SetText(e, "ValueT", Elems.CopyText(optT)) END; Elems.UpdateElem(e) | m: TagMsg DO m.name := "" | m: Texts.IdentifyMsg DO m.mod := "FormElems"; m.proc := "AllocList" ELSE ListElems.Handle(e, m) END END END HandleList;  PROCEDURE HandleForm* (e: Texts.Elem; VAR m: Texts.ElemMsg);  VAR e1: FormElem; dsr: INTEGER; trackedMsg : WebElems.TrackedMsg; BEGIN WITH e: FormElem DO WITH m: TagMsg DO  m.name := "
...
"; | m: Texts.FileMsg DO  WebElems.HandleLink(e, m); IF m.id = Texts.load THEN IF e.side = WebElems.LeftSide THEN Files.ReadString(m.r, e.method); Files.ReadString(m.r, e.encType) END ELSE (* Texts.store *) IF e.side = WebElems.LeftSide THEN Files.WriteString(m.r, e.method); Files.WriteString(m.r, e.encType) END END | m: Texts.CopyMsg DO  IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(FormElem) END; WebElems.HandleLink(e, m); IF e1.side = WebElems.LeftSide THEN COPY(e.method, e1.method); COPY(e.encType, e1.encType); ELSE e1.method := ""; e1.encType := "" END | m: Texts.IdentifyMsg DO  m.mod := "FormElems"; m.proc := "AllocForm" | m: TextFrames.DisplayMsg DO  IF m.prepare THEN IF e.visible THEN e.W := formW ELSE e.W := invisW END ELSIF e.visible THEN GetDsr(m.frame, m.pos, m.fnt, dsr); Display.CopyPattern(formCol, fIcon[e.side], m.X0, m.Y0+dsr, Display.replace) END | m: TextPrinter.PrintMsg DO  IF m.prepare THEN e.W := invisW ELSE e.W := formW END | m: TextFrames.TrackMsg DO  IF middle IN m.keys THEN IF m.frame # NIL THEN GetDsr(m.frame, m.pos, m.fnt, dsr); Display.CopyPattern(clickCol, fClickIcon[e.side], m.X0, m.Y0+dsr, Display.paint); WebElems.TrackAndPopup(e, m); Display.CopyPattern(formCol, fIcon[e.side], m.X0, m.Y0+dsr, Display.replace) END; IF m.keys # cancel THEN trackedMsg.keys := m.keys; e.handle(e, trackedMsg) END END | m: WebElems.ContentMsg DO  WebElems.HandleLink(e, m); IF e.side = WebElems.LeftSide THEN Texts.WriteString(w, e.method); Texts.WriteLn(w); Texts.WriteString(w, e.encType); Texts.WriteLn(w); Texts.Append(m.text, w.buf); IF m.edInfo # NIL THEN Texts.Delete(m.edInfo, 0, m.edInfo.len); Texts.WriteString(w, "action URL"); Texts.WriteLn(w); Texts.WriteString(w, "send method (POST or GET)"); Texts.WriteLn(w); Texts.WriteString(w, "encryption type"); Texts.WriteLn(w); Texts.Append(m.edInfo, w.buf); m.name := "FormElems.FormElem" END END | m: WebElems.TrackedMsg DO  IF m.keys = {middle, right} THEN WebElems.HandleLink(e, m); END | m: WebElems.UpdateMsg DO  WebElems.HandleLink(e, m); IF e.side = WebElems.LeftSide THEN ReadLine(m, e.method); ReadLine(m, e.encType) END ELSE WebElems.HandleLink(e, m) END END END HandleForm;  PROCEDURE HandleHidden* (e: Texts.Elem; VAR m: Texts.ElemMsg);  VAR e1: HiddenElem; dsr: INTEGER; BEGIN WITH e: HiddenElem DO WITH m: TagMsg DO  m.name := "" | m: SubmitMsg DO  IF e.value # NIL THEN COPY(e.value^, m.value); AppendEncoded(m.rider, e.name, m.value) END | m: Texts.FileMsg DO  IF m.id = Texts.load THEN e.visible := e.W > invisW; Files.ReadString(m.r, e.name); LoadDynString(m.r, e.value) ELSE (* Texts.store *) Files.WriteString(m.r, e.name); StoreDynString(m.r, e.value) END | m: Texts.CopyMsg DO  IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(HiddenElem) END; Texts.CopyElem(e, e1); e1.visible := e.visible; COPY(e.name, e1.name); CopyDynString(e.value^, e1.value) | m: Texts.IdentifyMsg DO  m.mod := "FormElems"; m.proc := "AllocHidden" | m: TextFrames.DisplayMsg DO  IF m.prepare THEN IF e.visible THEN e.W := hiddenW ELSE e.W := invisW END ELSIF e.visible THEN GetDsr(m.frame, m.pos, m.fnt, dsr); Display.CopyPattern(hiddenCol, hIcon, m.X0, m.Y0+dsr, Display.replace) END | m: TextPrinter.PrintMsg DO  IF m.prepare THEN e.W := invisW ELSE e.W := hiddenW END | m: TextFrames.TrackMsg DO  IF middle IN m.keys THEN IF m.frame # NIL THEN GetDsr(m.frame, m.pos, m.fnt, dsr); Display.CopyPattern(clickCol, hClickIcon, m.X0, m.Y0+dsr, Display.paint); WebElems.TrackAndPopup(e, m); Display.CopyPattern(hiddenCol, hIcon, m.X0, m.Y0+dsr, Display.replace); END; IF ~(left IN m.keys) THEN WebElems.Handle(e, m) END; END | m: WebElems.ContentMsg DO  WebElems.Handle(e, m); Texts.WriteString(w, e.name); Texts.WriteLn(w); IF e.value # NIL THEN Texts.WriteString(w, e.value^) END; Texts.WriteLn(w); Texts.Append(m.text, w.buf); IF m.edInfo # NIL THEN Texts.WriteString(w, "name"); Texts.WriteLn(w); Texts.WriteString(w, "value"); Texts.WriteLn(w); Texts.Append(m.edInfo, w.buf); m.name := "FormElems.HiddenElem" END | m: WebElems.UpdateMsg DO ReadLine(m, e.name); ReadDynLine(m, e.value) ELSE END END END HandleHidden;  PROCEDURE HandlePassWord* (e: Texts.Elem; VAR m: Texts.ElemMsg);  VAR txt : TextFieldElems.PWText; col : SHORTINT; value : ARRAY vLen OF CHAR; size, pos : LONGINT; BEGIN WITH e : TextFieldElems.PWElem DO WITH m : AttrMsg DO  HandleAttrTextField(e, m) | m: UpdateMsg DO  Elems.GetInteger(e, "Size", size); IF size <= 0 THEN size := 20; Elems.SetInteger(e, "Size", size) END; e.W := DUnit * xDim * size + DUnit * 10 | m: SubmitMsg DO  txt := e.txt(TextFieldElems.PWText); pos := 0; IF TextLineToString(txt.hidden, pos, m.value, col) THEN Elems.GetString(e, "Name", m.name); AppendEncoded(m.rider, m.name, m.value) END | m: ResetMsg DO  Elems.GetString(e, "DefaultValue", value); Elems.SetString(e, "Value", value); Texts.ChangeLooks(e.txt, 0, e.txt.len, {0}, HTML.fixedFont, 0, 0); Elems.UpdateElem(e) | m: TagMsg DO  m.name := "" | m : Texts.IdentifyMsg DO  m.mod := "FormElems"; m.proc := "AllocPassWord" ELSE TextFieldElems.HandlePW(e, m) END END END HandlePassWord;  PROCEDURE HandleImage* (e: Texts.Elem; VAR m: Texts.ElemMsg);  VAR e1: ImageElem; BEGIN WITH e : ImageElem DO WITH m: SubmitMsg DO  IF e.x # undef THEN COPY(e.alt, m.name); IF m.name="" THEN m.name := "x" ELSE Strings.Append(".x", m.name) END; Web.Int2Str(e.x, m.value); AppendEncoded(m.rider, m.name, m.value); COPY(e.alt, m.name); IF m.name="" THEN m.name := "y" ELSE Strings.Append(".y", m.name) END; Web.Int2Str(e.y, m.value); AppendEncoded(m.rider, m.name, m.value); e.y := undef; e.x := undef END | m: TagMsg DO  m.name := "" | m : Texts.FileMsg DO  WebElems.HandleImage(e, m); e.x := undef; e.y := undef; e.isMap := FALSE | m: Texts.CopyMsg DO  IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(ImageElem) END; WebElems.HandleImage(e, m); e1.x := undef; e1.y := undef | m : Texts.IdentifyMsg DO  m.mod := "FormElems"; m.proc := "AllocImage" | m: WebElems.ContentMsg DO  e.isMap := FALSE; WebElems.HandleImage(e, m); IF m.edInfo # NIL THEN Texts.Delete(m.edInfo, 0, m.edInfo.len); Texts.WriteString(w, "source URL"); Texts.WriteLn(w); Texts.WriteString(w, "name"); Texts.WriteLn(w); Texts.Append(m.edInfo, w.buf); m.name := "FormElems.ImageElem" END | m: WebElems.UpdateMsg DO WebElems.HandleImage(e, m); e.isMap := FALSE | m : WebElems.TrackedMsg DO  IF (middle IN m.keys) & (m.keys # cancel) THEN newViewer := m.keys = {middle, left}; IF m.keys = {middle, right} THEN WebElems.HandleImage(e, m); ELSIF (m.keys = {middle, left}) OR (m.keys = {middle}) THEN e.x := m.x; e.y := m.y; cmdElem := e; SubmitForm; cmdElem := NIL END END ELSE WebElems.HandleImage(e, m) END END END HandleImage; (* Set default-values for input-, select-, option- or textarea-tags *) PROCEDURE InitInput* (inp : InputTag);  BEGIN inp.type := "noType"; inp.value := ""; inp.dynValue := NIL; inp.myValue := ""; inp.name := ""; inp.src := NIL; inp.maxLen:= undef; inp.size := undef; inp.checked := FALSE; inp.selected :=FALSE END InitInput;  PROCEDURE InitSelection* (sel : Selection);  BEGIN sel.name := ""; sel.vertSize := undef; sel.horizSize := undef; sel.noOfOptions := 0; sel.done := FALSE; sel.defaultSel := ""; sel.optionText := TextFrames.Text(""); sel.valueText := TextFrames.Text("") END InitSelection;  PROCEDURE InitOption* (opt : Option);  BEGIN opt.value := NIL; opt.selected := FALSE END InitOption;  PROCEDURE InitTextArea* (ta : TextArea);  BEGIN ta.name := "" END InitTextArea; (* Alloc FormElems *) PROCEDURE AllocForm*;  VAR e: FormElem; BEGIN NEW(e); e.handle := HandleForm; Texts.new := e END AllocForm;  PROCEDURE AllocHidden*;  VAR e: HiddenElem; BEGIN NEW(e); e.handle := HandleHidden; Texts.new := e END AllocHidden;  PROCEDURE AllocImage*;  VAR e: ImageElem; BEGIN NEW(e); e.handle := HandleImage; Texts.new := e END AllocImage;  PROCEDURE AllocButton*;  VAR e : Texts.Elem; BEGIN e := Elems.CreateElem("ButtonElems.New"); e.handle := HandleButton; Texts.new := e END AllocButton;  PROCEDURE AllocTextField*;  VAR e : Texts.Elem; BEGIN e := Elems.CreateElem ("TextFieldElems.New"); e.handle := HandleTextField; Texts.new := e END AllocTextField;  PROCEDURE AllocTextArea*;  VAR e : Texts.Elem; BEGIN e := Elems.CreateElem ("TextAreaElems.New"); e.handle := HandleTextArea; Texts.new := e END AllocTextArea;  PROCEDURE AllocCheckBox*;  VAR e : Texts.Elem; BEGIN e := Elems.CreateElem ("CheckBoxElems.New"); e.handle := HandleCheckBox; Texts.new := e END AllocCheckBox;  PROCEDURE AllocRadioButton*;  VAR e : Texts.Elem; BEGIN e := Elems.CreateElem ("RadioButtonElems.New"); e.handle := HandleRadioButton; Texts.new := e END AllocRadioButton;  PROCEDURE AllocPassWord*;  VAR e : Texts.Elem; BEGIN e := Elems.CreateElem ("TextFieldElems.NewPW"); e.handle := HandlePassWord; Texts.new := e END AllocPassWord;  PROCEDURE AllocList*;  VAR e : Texts.Elem; BEGIN e := Elems.CreateElem ("ListElems.New"); e.handle := HandleList; Texts.new := e END AllocList; (* Return FormElems with the values of InputTag, TextArea or Selection *) PROCEDURE NewForm* (side : INTEGER; visible : BOOLEAN): FormElem;  VAR e: FormElem; BEGIN NEW(e); WebElems.InitLink(e, side, visible); e.H := elemH; e.handle := HandleForm; IF visible THEN e.W := formW ELSE e.W := invisW END; e.method := ""; e.encType := ""; RETURN e END NewForm;  PROCEDURE NewNakedHidden* (visible : BOOLEAN): HiddenElem;  VAR e: HiddenElem; BEGIN NEW(e); e.H := elemH; e.handle := HandleHidden; e.visible := visible; IF visible THEN e.W := hiddenW ELSE e.W := invisW END; RETURN e END NewNakedHidden;  PROCEDURE NewHidden* (inp : InputTag; visible : BOOLEAN) : HiddenElem;  VAR e : HiddenElem; BEGIN IF inp.name = "" THEN Web.LogStr("Hidden: No NAME specified!$") END; IF inp.dynValue = NIL THEN Web.LogStr("Hidden: No VALUE specified!$") END; e := NewNakedHidden(visible); COPY(inp.name, e.name); e.value := inp.dynValue; RETURN e END NewHidden;  PROCEDURE NewImage* (): ImageElem;  VAR e: ImageElem; BEGIN NEW(e); WebElems.InitImage(e); e.x := undef; e.y := undef; e.handle := HandleImage; e.isMap := TRUE; RETURN e END NewImage;  PROCEDURE NewSubmitButton* (inp : InputTag) : ButtonElems.Elem;  VAR e : Texts.Elem; BEGIN IF inp.value = "" THEN inp.value := "Submit Query" END; e := Elems.CreateElem("ButtonElems.New"); e.handle := HandleButton; Elems.SetString(e, "Type", "SubmitButton"); Elems.SetString(e, "Name", inp.name); Elems.SetString(e, "Value", inp.value); Elems.SetString(e, "Caption", inp.value); Elems.SetString(e, "Cmd", "FormElems.SubmitForm"); Elems.SetBoolean(e, "Locked", TRUE); e.W := DUnit * xDim * LONG(Strings.Length(inp.value)) + DUnit * 10; e.H := DUnit * yDim + DUnit * 5; RETURN e(ButtonElems.Elem); END NewSubmitButton;  PROCEDURE NewResetButton* (inp : InputTag) : ButtonElems.Elem;  VAR e : Texts.Elem; BEGIN IF inp.value = "" THEN inp.value := "Reset" END; e := Elems.CreateElem ("ButtonElems.New"); e.handle := HandleButton; Elems.SetString(e, "Type", "ResetButton"); Elems.SetString(e, "Caption", inp.value); Elems.SetString(e, "Value", inp.value); Elems.SetString(e, "Cmd", "FormElems.ResetForm"); Elems.SetBoolean(e, "Locked", TRUE); e.W := DUnit * xDim * LONG(Strings.Length(inp.value)) + DUnit * 10; e.H := DUnit * yDim + DUnit * 5; RETURN e(ButtonElems.Elem) END NewResetButton;  PROCEDURE NewTextField* (inp : InputTag) : TextFieldElems.Elem;  VAR e : Texts.Elem; BEGIN IF inp.name = "" THEN Web.LogStr("TextField: No NAME specified$") END; e := Elems.CreateElem ("TextFieldElems.New"); e.handle := HandleTextField; Elems.SetString(e, "Caption", inp.name); Elems.SetString(e, "Name", inp.name); Elems.SetString(e, "Cmd", "FormElems.SubmitForm"); Elems.SetInteger(e, "MaxLen", inp.maxLen); IF inp.size=undef THEN inp.size := 20 END; Elems.SetInteger(e, "Size", inp.size); Elems.SetString(e, "Value", inp.value); Texts.ChangeLooks(e(TextFieldElems.Elem).txt, 0, e(TextFieldElems.Elem).txt.len, {0}, HTML.fixedFont, 0, 0); Elems.SetString(e, "DefaultValue", inp.value); Elems.SetBoolean(e, "Locked", TRUE); e.W := DUnit * xDim * inp.size + DUnit * 10; e.H := DUnit * yDim + DUnit * 5; RETURN e(TextFieldElems.Elem) END NewTextField;  PROCEDURE NewTextArea* (ta : TextArea; buf : Texts.Buffer) : TextAreaElems.Elem;  VAR txt : Texts.Text; e : Texts.Elem; BEGIN IF ta.name = "" THEN Web.LogStr("TextArea: No NAME specified$") END; e := Elems.CreateElem ("TextAreaElems.New"); e.handle := HandleTextArea; Elems.SetString(e, "Name", ta.name); Elems.SetBoolean(e, "Locked", TRUE); Elems.SetInteger(e, "Rows", ta.rows); Elems.SetInteger(e, "Cols", ta.cols); NEW(txt); txt := TextFrames.Text(""); Texts.Insert(txt, 0, buf); Elems.SetText(e, "ValueT", txt); Elems.SetText(e, "DefaultValueT", Elems.CopyText(txt)); e.H := DUnit * yDim * ta.rows + DUnit * 8; e.W := DUnit * xDim * ta.cols + DUnit * 28; RETURN e(TextAreaElems.Elem) END NewTextArea;  PROCEDURE NewCheckBox* (inp : InputTag) : CheckBoxElems.Elem;  VAR e : Texts.Elem; BEGIN IF inp.name = "" THEN Web.LogStr("CheckBox: No NAME specified$") END; e := Elems.CreateElem ("CheckBoxElems.New"); e.handle := HandleCheckBox; Elems.SetBoolean(e, "Locked", TRUE); Elems.SetString(e, "Name", inp.name); Elems.SetString(e, "ValueStr", inp.value); Elems.SetBoolean(e, "Value", inp.checked); Elems.SetBoolean(e, "DefaultValue", inp.checked); RETURN e(CheckBoxElems.Elem) END NewCheckBox;  PROCEDURE NewRadioButton* (inp : InputTag) : RadioButtonElems.Elem;  VAR e : Texts.Elem; BEGIN IF inp.name = "" THEN Web.LogStr("RadioButton: No NAME specified$") END; IF inp.value = "" THEN Web.LogStr("RadioButton: No VALUE specified$") END; e := Elems.CreateElem ("RadioButtonElems.New"); e.handle := HandleRadioButton; Elems.SetBoolean(e, "Locked", TRUE); Elems.SetString(e, "Name", inp.name); Elems.SetString(e, "MyValue", inp.value); IF inp.checked THEN Elems.SetString(e, "Value", inp.value); Elems.SetString(e, "DefaultValue", inp.value) ELSE Elems.SetString(e, "DefaultValue", ""); END; RETURN e(RadioButtonElems.Elem) END NewRadioButton;  PROCEDURE NewPassWord* (inp : InputTag) : TextFieldElems.PWElem;  VAR e : Texts.Elem; pwElem : TextFieldElems.PWElem; BEGIN IF inp.name = "" THEN Web.LogStr("PassWord: No NAME specified$") END; e := Elems.CreateElem ("TextFieldElems.NewPW"); e.handle := HandlePassWord; Elems.SetString(e, "Caption", inp.name); Elems.SetString(e, "Name", inp.name); Elems.SetString(e, "Cmd", "FormElems.SubmitForm"); Elems.SetInteger(e, "MaxLen", inp.maxLen); IF inp.size=undef THEN inp.size := 20 END; (* Defaultsize *) Elems.SetInteger(e, "Size", inp.size); Elems.SetString(e, "Value", inp.value); Elems.SetString(e, "DefaultValue", inp.value); Elems.SetBoolean(e, "Locked", TRUE); e.W := DUnit * xDim * inp.size + DUnit * 10; e.H := DUnit * yDim + DUnit * 5; pwElem := e(TextFieldElems.PWElem); Texts.ChangeLooks(pwElem.txt, 0, pwElem.txt.len, {0}, HTML.fixedFont, 0, 0); RETURN pwElem END NewPassWord;  (* Add option "opt" to selection "sel" *) PROCEDURE AddOption* (VAR options : Texts.Writer; VAR sel : Selection; VAR opt : Option);  BEGIN INC(sel.noOfOptions); (* adjust horizontal size of selection *) IF sel.horizSize < Strings.Length(opt.text^) THEN sel.horizSize := Strings.Length(opt.text^) END; (* decide whether to create a popup-list or a selection-list *) IF (sel.vertSize > 1) OR ((sel.vertSize = undef) & sel.multiple) THEN IF opt.selected & ~sel.done THEN Texts.SetColor(options, ListElems.SelCol); COPY(opt.text^, sel.defaultSel); sel.done := ~sel.multiple ELSE Texts.SetColor(options, ListElems.DefaultCol) END ELSIF opt.selected & ~sel.done THEN COPY(opt.text^, sel.defaultSel); sel.done := TRUE END; (* Add to optionText = displayed values *) Texts.WriteString(options, opt.text^); Texts.WriteLn(options); Texts.Append(sel.optionText, options.buf); (* Add to valueText = keyword values *) IF opt.value=NIL THEN Texts.WriteString(options, opt.text^) (* no value given -> keyword is the same as displayed value *) ELSE Texts.WriteString(options, opt.value^) END; Texts.WriteLn(options); Texts.Append(sel.valueText, options.buf) END AddOption;  PROCEDURE NewList* (VAR sel : Selection) : ListElems.Elem;  VAR e : Texts.Elem; col : SHORTINT; eot : BOOLEAN; pos : LONGINT; BEGIN IF sel.name = "" THEN Web.LogStr("List (SELECTION): No NAME specified$") END; e := Elems.CreateElem ("ListElems.New"); e.handle := HandleList; Elems.SetString(e, "Name", sel.name); Elems.SetText(e, "ValueT", sel.optionText); Elems.SetText(e, "DefaultValueT", Elems.CopyText(sel.optionText)); Elems.SetText(e, "Keywords", sel.valueText); Elems.SetBoolean(e, "Locked", TRUE); Elems.SetBoolean(e, "Combo", FALSE); Elems.SetBoolean(e, "Multi", sel.multiple); Elems.SetBoolean(e, "Scrollbar", sel.vertSize < sel.noOfOptions); (* Calculate vertical size of list *) IF sel.vertSize = undef THEN IF sel.multiple THEN sel.vertSize := 5 ELSE sel.vertSize := 1 END ELSIF sel.vertSize > sel.noOfOptions THEN sel.vertSize := sel.noOfOptions END; Elems.SetInteger(e, "Size", sel.vertSize); IF sel.vertSize = 1 THEN Elems.SetBoolean(e, "Popup", TRUE) END; (* necessary if selection is or will get a popup-list *) IF sel.defaultSel="" THEN eot := ~TextLineToString(sel.optionText, pos, sel.defaultSel, col) END; Elems.SetString(e, "Value", sel.defaultSel); Elems.SetString(e, "DefaultValue", sel.defaultSel); e.H := DUnit * yDim * sel.vertSize + DUnit * 10; e.W := DUnit * xDim * sel.horizSize + DUnit * 10; IF (sel.vertSize=1) OR (sel.vertSize < sel.noOfOptions) THEN e.W := e.W + DUnit * 18 END; RETURN e(ListElems.Elem) END NewList; (* Insert FormElems with default-values *) PROCEDURE InsertForm*;  VAR e: FormElem; t: Texts.Text; r: Texts.Reader; ch: CHAR; beg, end, time: LONGINT; BEGIN Oberon.GetSelection(t, beg, end, time); IF (time >= 0) & (t IS Texts.Text) THEN e := NewForm(WebElems.RightSide, TRUE); Texts.OpenReader(r, t, end - 1); Texts.Read(r, ch); Texts.SetFont(w, r.fnt); Texts.WriteElem(w, e); Texts.Insert(t, end, w.buf); e := NewForm(WebElems.LeftSide, TRUE); NEW(e.url, 12); COPY("ACTION(URL)", e.url^); COPY("METHOD", e.method); COPY("ENCTYPE (default = 'application/x-www-form-urlencoded')", e.encType); Texts.OpenReader(r, t, beg); Texts.Read(r, ch); Texts.SetFont(w, r.fnt); Texts.WriteElem(w, e); Texts.Insert(t, beg, w.buf); Texts.SetFont(w, Fonts.Default) END END InsertForm;  PROCEDURE InsertHidden*;  VAR m: TextFrames.InsertElemMsg; BEGIN m.e := NewNakedHidden(TRUE); COPY("NAME", m.e(HiddenElem).name); NEW(m.e(HiddenElem).value, 6); COPY("VALUE", m.e(HiddenElem).value^); Viewers.Broadcast(m) END InsertHidden;  PROCEDURE InsertImage*;  VAR m: TextFrames.InsertElemMsg; BEGIN m.e := NewImage(); Viewers.Broadcast(m) END InsertImage;  PROCEDURE InsertSubmitButton*;  VAR m: TextFrames.InsertElemMsg; inp : InputTag; BEGIN NEW(inp); inp.name := "SubmitButton"; inp.value := ""; m.e := NewSubmitButton(inp); Viewers.Broadcast(m) END InsertSubmitButton;  PROCEDURE InsertResetButton*;  VAR m: TextFrames.InsertElemMsg; inp : InputTag; BEGIN NEW(inp); inp.name := "ResetButton"; inp.value := ""; m.e := NewResetButton(inp); Viewers.Broadcast(m) END InsertResetButton;  PROCEDURE InsertTextField*;  VAR m: TextFrames.InsertElemMsg; inp : InputTag; BEGIN NEW(inp); inp.value := ""; inp.name := "TextField"; inp.size := undef; m.e := NewTextField(inp); Viewers.Broadcast(m) END InsertTextField;  PROCEDURE InsertTextArea*;  VAR m : TextFrames.InsertElemMsg; txt : Texts.Text; BEGIN m.e := Elems.CreateElem ("TextAreaElems.New"); m.e.handle := HandleTextArea; Elems.SetString(m.e, "Name", "TextArea"); Elems.SetBoolean(m.e, "Locked", TRUE); Elems.SetInteger(m.e, "Rows", 4); Elems.SetInteger(m.e, "Cols", 15); txt := TextFrames.Text(""); Elems.SetText(m.e, "ValueT", txt); Elems.SetText(m.e, "DefaultValueT", Elems.CopyText(txt)); m.e.H := DUnit * yDim * 4 + DUnit * 8; m.e.W := DUnit * xDim * 15 + DUnit * 28; Viewers.Broadcast(m) END InsertTextArea;  PROCEDURE InsertCheckBox*;  VAR m: TextFrames.InsertElemMsg; inp : InputTag; BEGIN NEW(inp); inp.name := "CheckBox"; inp.value := "Value"; inp.checked := FALSE; m.e := NewCheckBox(inp); Viewers.Broadcast(m) END InsertCheckBox;  PROCEDURE InsertRadioButton*;  VAR m: TextFrames.InsertElemMsg; inp : InputTag; BEGIN NEW(inp); inp.name := "RadioButton"; inp.value := "MyValue"; m.e := NewRadioButton(inp); Elems.SetString(m.e, "Value", "Group value"); Viewers.Broadcast(m) END InsertRadioButton;  PROCEDURE InsertPassWord*;  VAR m: TextFrames.InsertElemMsg; inp : InputTag; BEGIN NEW(inp); inp.name := "PassWord"; inp.value := ""; inp.size := undef; m.e := NewPassWord(inp); Viewers.Broadcast(m) END InsertPassWord;  PROCEDURE InsertList*;  VAR m: TextFrames.InsertElemMsg; sel : Selection; BEGIN NEW(sel); InitSelection(sel); sel.name := "Selection"; m.e := NewList(sel); m.e.H := DUnit * yDim * 5 + DUnit * 10; m.e.W := DUnit * xDim * 7 + DUnit * 10; m.e.W := m.e.W + DUnit * 18; Viewers.Broadcast(m) END InsertList; (* Sets the global variables xDim and yDim which stand for the width and the height of any character of the font "fnt". *) PROCEDURE SetDimensions* (fnt : Fonts.Font);  VAR dx, x, y, w, h: INTEGER; p : Display.Pattern; aboveBase, belowBase: INTEGER; BEGIN xDim := 9; yDim := 17; Display.GetChar(fnt.raster, 'X', dx, x, y, w, h, p); xDim := LONG(dx); yDim := LONG(h); belowBase := - SHORT(TextFrames.defParc.dsr DIV pixel); aboveBase := SHORT(TextFrames.defParc.lsp DIV pixel) + belowBase; IF belowBase > y THEN belowBase := y END; IF aboveBase < h + y THEN aboveBase := h + y END; IF yDim < aboveBase - belowBase THEN yDim := aboveBase - belowBase END END SetDimensions; (* Initializes the Icons for Form- and HiddenElem *) PROCEDURE InitIcons;  VAR line : ARRAY 9 OF SET; BEGIN (* Hidden icon *) line[8] := {2..8}; line[7] := {1, 9}; line[6] := {1, 3, 4, 6, 7, 9}; line[5] := {1, 3..7, 9}; line[4] := {1, 3..7, 9}; line[3] := {1, 3, 4, 6, 7, 9}; line[2] := {1, 9}; line[1] := {2..8}; hIcon:= Display.NewPattern(line, 11, 8); line[8] := {}; line[7] := {}; line[6] := {3, 4, 6, 7}; line[5] := {3..7}; line[4] := {3..7}; line[3] := {3, 4, 6, 7}; line[2] := {}; line[1] := {}; hClickIcon := Display.NewPattern(line, 11, 8); (* FormElem left icon *) line[8] := {4, 5, 7..11}; line[7] := {3, 4, 7..11}; line[6] := {2, 3, 7, 8}; line[5] := {1, 2, 7..10}; line[4] := {1, 2, 7..10}; line[3] := {2, 3, 7, 8}; line[2] := {3, 4, 7, 8}; line[1] := {4, 5, 7, 8}; fIcon[WebElems.LeftSide] := Display.NewPattern(line, 14, 8); (* FormElem clicked left icon *) line[8] := {7..11}; line[7] := {7..11}; line[6] := {7, 8}; line[5] := {7..10}; line[4] := {7..10}; line[3] := {7, 8}; line[2] := {7, 8}; line[1] := {7, 8}; fClickIcon[WebElems.LeftSide] := Display.NewPattern(line, 14, 8); (* FormElem right icon *) line[8] := {3..7, 9, 10}; line[7] := {3..7, 10, 11}; line[6] := {3, 4, 11, 12}; line[5] := {3..6, 12, 13}; line[4] := {3..6, 12, 13}; line[3] := {3, 4, 11, 12}; line[2] := {3, 4, 10, 11}; line[1] := {3, 4, 9, 10}; fIcon[WebElems.RightSide] := Display.NewPattern(line, 14, 8); (* FormElem clicked right icon *) line[8] := {3..7}; line[7] := {3..7}; line[6] := {3, 4}; line[5] := {3..6}; line[4] := {3..6}; line[3] := {3, 4}; line[2] := {3, 4}; line[1] := {3, 4}; fClickIcon[WebElems.RightSide] := Display.NewPattern(line, 14, 8) END InitIcons; BEGIN InitIcons; Texts.OpenWriter(w); SetDimensions(HTML.fixedFont) END FormElems.