LSyntax10.Scn.FntqInfoElemsAllocUSyntax10.Scn.FntStampElemsAlloc6 Jan 990 "Title": WebElems "Author": Andreas Krumenacker "Abstract": WebElems is a part of the Oberon-Web-Browser. "Keywords": links, fragment-identifiers, tags, images, pictures "Version": no version "From": 8 Dez 97 "Until":  "Changes": no changes so far "Hints": no hints )8FoldElemsNewSyntax10.Scn.FnthqBalloonElemsAlloc#Syntax10.Scn.Fntuu"WebElems" WebElems is a part of the Oberon-Web-Browser. "LeftSide" WebElems.LeftSide "RightSide" WebElems.RightSide "clickCol" WebElems.clickCol "linkCol" WebElems.linkCol "tagCol" WebElems.tagCol "Elem" WebElems.Elem "ImageElem" WebElems.ImageElem "LinkElem" WebElems.LinkElem "MakeAbsMsg" WebElems.MakeAbsMsg "MarkElem" WebElems.MarkElem "TagElem" WebElems.TagElem "TrackedMsg" WebElems.TrackedMsg "ConvertToAbs" WebElems.ConvertToAbs "Elems" WebElems.Elems "ExchangePic" WebElems.ExchangePic "FollowLink" WebElems.FollowLink "HandleImage" WebElems.HandleImage "HandleLink" WebElems.HandleLink "HandleMark" WebElems.HandleMark "HandleTag" WebElems.HandleTag "InitImage" WebElems.InitImage "InitLink" WebElems.InitLink "InitMark" WebElems.InitMark "InitTag" WebElems.InitTag "InsertImage" WebElems.InsertImage "InsertLink" WebElems.InsertLink "InsertMark" WebElems.InsertMark "InsertTag" WebElems.InsertTag "LoadAllImages" WebElems.LoadAllImages "LoadImages" WebElems.LoadImages "NewImage" WebElems.NewImage "NewLink" WebElems.NewLink "NewMark" WebElems.NewMark "NewTag" WebElems.NewTag "SetLoadResult" WebElems.SetLoadResult "SetSource" WebElems.SetSource "ShowAbsUrl" WebElems.ShowAbsUrl "ShowImage" WebElems.ShowImage "StoreAllImages" WebElems.StoreAllImages "StoreImage" WebElems.StoreImage "Twin" e(WebElems.LinkElem).Twin "Update" WebElems.Update 8upVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables+Syntax10i.Scn.Fnt(* No Tables *)Syntax10i.Scn.FntpVersionElemsAllocEndp#Syntax10.Scn.FntTables NoTablesTablesTables NoTables 4p 8qSyntax10.Scn.FntfSyntax10b.Scn.Fnt Syntax10i.Scn.Fnt left = 2; middle = 1; right = 0; cancel = {left, middle, right}; uLen = Web.maxUrlLen; nLen = 32; LeftSide* = 0; RightSide* = 1; pixel = LONG(TextFrames.Unit); elemH = 11 * pixel; linkW = 10 * pixel; markW = 11 * pixel; tagW = 15 * pixel; invisW = 1; (* width of an invisible element *) map = "ISMAP"; editUrlMenu = "System.Close WebElems.ShowAbsUrl WebElems.Update "; editMenu = "System.Close WebElems.Update "; editLinkInfo = "link URL"; editMarkInfo = "fragment identifier"; editTagInfo = "tag content without brakets"; editImageInfo1 = "source URL"; editImageInfo2 = "alternative name"; editImageInfo3 = "'ISMAP' or blank"; editSep = "---------- each line is matched to an item in the following order:"; 8B8 Syntax10.Scn.FntSyntax10b.Scn.Fnt 8FoldElemsNewCSyntax10.Scn.FntSyntax10b.Scn.Fnt& urlStr* : ARRAY uLen OF CHAR; END;8 N8mSyntax10.Scn.FntSyntax10b.Scn.FntF frame* : TextFrames.Frame; x*, y* : INTEGER; keys* : SET; END;8 78mSyntax10.Scn.FntSyntax10b.Scn.Fnt] text*, edInfo* : Texts.Text; name* : ARRAY 32 OF CHAR; menu* : ARRAY 96 OF CHAR; END;8 8QSyntax10.Scn.FntSyntax10b.Scn.Fnt1 r* : Texts.Reader; text* : Texts.Text; END;8 8mSyntax10.Scn.FntSyntax10b.Scn.Fnt & ImageElemDesc* = RECORD (PElems.ElemDesc) src- : Web.DynamicString; alt* : ARRAY nLen OF CHAR; isMap* : BOOLEAN; loaded : BOOLEAN; END;8,8#Syntax10.Scn.FntJJ ListedImageDesc = RECORD img : ImageElem; next : ListedImage; END;80}8#Syntax10.Scn.Fntaa InsertedImageDesc = RECORD (ListedImageDesc) src : Web.DynamicString; load : BOOLEAN; END;88#Syntax10.Scn.FntZZ TaskDesc = RECORD (Oberon.TaskDesc) first : ListedImage; last : InsertedImage; END;8o8QSyntax10.Scn.FntSyntax10b.Scn.Fnt A ElemDesc* = RECORD (Texts.ElemDesc) visible* : BOOLEAN; END;8J8_Syntax10.Scn.FntSyntax10b.Scn.Fnt X LinkElemDesc* = RECORD (ElemDesc) url* : Web.DynamicString; side- : INTEGER; END;8n8QSyntax10.Scn.FntSyntax10b.Scn.Fnt B MarkElemDesc* = RECORD (ElemDesc) name*: Web.FragmentId; END;8!8qSyntax10.Scn.FntSyntax10b.Scn.Fnt Syntax10i.Scn.Fnt$ o TagElemDesc* = RECORD (ElemDesc) str* : Web.DynamicString; (* full tag with possible tag-end-slash *) END;8 8#Syntax10.Scn.FntCC FrameDesc = RECORD (TextFrames.FrameDesc) e : Texts.Elem; END;8WpVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.Fnt55 CheckProc = PROCEDURE (e : Texts.Elem) : BOOLEAN; pVersionElemsAllocEnd MakeAbsMsg* = RECORD (Texts.ElemMsg)  TrackedMsg* = RECORD (Texts.ElemMsg)  ContentMsg* = RECORD (Texts.ElemMsg)  UpdateMsg* = RECORD (Texts.ElemMsg)  ImageElem* = POINTER TO ImageElemDesc;  ListedImage = POINTER TO ListedImageDesc;  InsertedImage = POINTER TO InsertedImageDesc;  Task = POINTER TO TaskDesc;  Elem* = POINTER TO ElemDesc;  LinkElem* = POINTER TO LinkElemDesc;  MarkElem* = POINTER TO MarkElemDesc;  TagElem* = POINTER TO TagElemDesc;  Frame = POINTER TO FrameDesc;   88Syntax10.Scn.FntSyntax10b.Scn.FntSyntax10i.Scn.Fnt!.$BE%GC7--\pVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables pVersionElemsAllocEnd linkCol*, tagCol*, clickCol* : SHORTINT; defImg* : Pictures.Picture; (* default image for unloaded images *) loadImgs* : BOOLEAN; (* load images always (TRUE) or on demand (FALSE) *) searchKey : Web.FragmentId; (* key of mark element searched in ScrolledToMark; used in CheckMark *) searchUrl : Web.Url; (* source of image element searched in SetSource; used in CheckImageUrl *) searchPic : Pictures.Picture; (* picture of image element searched in SetLoadResult; used in CheckImage *) twinBase : LinkElem; (* linkelem for which a twin is searched; used for backcheck facility *) lIcon, lClickIcon : ARRAY 2 OF Display.Pattern; (* x = 0, y = 3, w = 9, h = 8 *) mIcon, mClickIcon : Display.Pattern; (* x = 0, y = 3, w = 10, h = 8 *) tIcon, tClickIcon : Display.Pattern; (* x = 0, y = 3, w = 14, h = 8 *) SuperHandle : Display.Handler; infoFnt : Fonts.Font; w : Texts.Writer; tsk : Task;  show: BOOLEAN;  8\8#Syntax10.Scn.Fnt 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 TextFrames.Unit) END END GetDsr;8OX8#Syntax10.Scn.Fnt VAR len : INTEGER; BEGIN len := 0; WHILE src[len] # 0X DO INC(len) END; NEW(dest, len + 1); COPY(src, dest^); END CopyDynString;8N8#Syntax10.Scn.Fnt 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;8Ky8#Syntax10.Scn.Fntee BEGIN IF str # NIL THEN Files.WriteString(r, str^) ELSE Files.Write(r, 0X) END END StoreDynString;8E8CSyntax10.Scn.FntSyntax10i.Scn.Fnt# 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); str[i-1] := 0X; WHILE (ch # 0X) & (ch # 0DX) DO Texts.Read(msg.r, ch) END (* skip to next line *) END ReadLine;8Ld8#Syntax10.Scn.Fntzz 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); 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;8p#Syntax10.Scn.FntTables NoTablesTablesTables NoTablesUSyntax10.Scn.Fnt_8FoldElemsNew#Syntax10.Scn.Fnt VAR r : Texts.Reader; BEGIN IF t # NIL THEN Texts.OpenReader(r, t, pos); Texts.ReadElem(r); WHILE (r.elem # NIL) & ~ check(r.elem) DO Texts.ReadElem(r) END; elem := r.elem ELSE elem := NIL END END FindElem;8b PROCEDURE FindElem (t : Texts.Text; pos : LONGINT; check : CheckProc; VAR elem : Texts.Elem);  pSyntax10b.Scn.Fnt8QSyntax10.Scn.FntSyntax10i.Scn.Fntiq VAR r : Texts.Reader; twin : LinkElem; BEGIN twin := NIL; IF e.side = LeftSide THEN Texts.OpenReader(r, Texts.ElemBase(e), Texts.ElemPos(e)+1); Texts.ReadElem(r); WHILE (r.elem # NIL) & ~ (r.elem IS LinkElem) 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 LinkElem) DO Texts.ReadPrevElem(r) END; END; IF (r.elem # NIL) & (r.elem IS LinkElem) & (r.elem(LinkElem).side # e.side) THEN twin := r.elem(LinkElem); IF twinBase # NIL THEN IF twin # twinBase THEN twin := NIL END ELSE (* backcheck twin *) twinBase := e; IF twin.Twin() # e THEN twin := NIL END END END; twinBase := NIL; RETURN twin END Twin;828#Syntax10.Scn.FntNN BEGIN RETURN (e IS MarkElem) & (e(MarkElem).name = searchKey) END CheckMark;8\8Syntax10.Scn.FntSyntax10i.Scn.Fnt.pVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTablesCSyntax10.Scn.Fnt)Syntax10i.Scn.Fnt-^ FindElem(t, 0, CheckMark, mark); (* one might use FoldElems.FindElem(...) instead *) 4-pVersionElemsAllocEnd VAR done : BOOLEAN; mark : Texts.Elem; cUrl : Web.Url; cRes : INTEGER; BEGIN done := FALSE; IF (f # NIL) & (f.text = t) THEN (* check for fragID and Scroll to proper position *) IF t IS Web.Text THEN cUrl := t(Web.Text).act.url ELSE cUrl := Web.EmptyUrl() END; Web.CompareUrls(url, cUrl, cRes); IF cRes # Web.different THEN IF url.frag # "" THEN COPY(url.frag, searchKey);  TableTools.FindElem(t, 0, CheckMark, mark); (* one might use FoldElems.FindElem(...) instead *)  IF mark # NIL THEN TextFrames.Show(f, Texts.ElemPos(mark)) END ELSE TextFrames.Show(f, 0) END; done := TRUE; END END; RETURN done END ScrolledToMark;8E(8#Syntax10.Scn.Fnt BEGIN IF uStr # "" THEN IF (t # NIL) & (t IS Web.Text) THEN RETURN Web.ResolvedUrl(uStr, t(Web.Text)) ELSE RETURN Web.Str2Url(uStr) END ELSE RETURN NIL END END AbsUrl;8A8#Syntax10.Scn.Fnt VAR s2 : ARRAY 8 OF CHAR; i, j : INTEGER; BEGIN Web.Int2Str(x, s); Web.Int2Str(y, s2); i := 0; WHILE s[i] # 0X DO INC(i) END; s[i] := ","; j := -1; REPEAT INC(i); INC(j); s[i] := s2[j] UNTIL s2[j] = 0X END CreateQuery;8  dr8.Syntax10.Scn.FntJOpVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.Fnt== Web.OpenUrl(meth, urlStr, t, NIL, ent, Web.default) pVersionElemsAllocEnd"a VAR e1 : LinkElem; urlStr : ARRAY uLen OF CHAR; url : Web.Url; base : Texts.Text; temp : Web.DynamicString; i, j : INTEGER; BEGIN IF (e # NIL) & (e.side = RightSide) THEN e1 := e.Twin() ELSE e1 := e END; IF (e1 # NIL) & (e1.url # NIL) THEN base := Texts.ElemBase(e1); IF base = NIL THEN base := t END; url := AbsUrl(e1.url^, base); IF url # NIL THEN IF query # "" THEN j := 0; WHILE query[j] # 0X DO INC(j) END; IF url.query = NIL THEN NEW(url.query, j + 1); COPY (query, url.query^) ELSE i := 1; WHILE url.query[i] # 0X DO INC(i) END; NEW(temp, i + j + 2); COPY(url.query^, temp^); url.query := temp; url.query[i] := "&"; INC(i); WHILE j >= 0 DO url.query[i + j] := query[j]; DEC(j); END END END; IF ~ ScrolledToMark(url, f, t) THEN Web.Url2Str(url, urlStr);  IF (t = NIL) OR ~ (t IS WebCellElems.Text) THEN Web.OpenUrl(meth, urlStr, t, NIL, ent, Web.default) ELSE Web.OpenUrl(meth, urlStr, WebCellElems.FindOutmostText(t(WebCellElems.Text)), NIL, ent, Web.default) END  END END END END FollowLink;8Z 8#Syntax10.Scn.Fnt VAR r : Texts.Reader; BEGIN IF tf # NIL THEN Texts.OpenReader(r, tf.text, pos + 1); Texts.ReadPrevElem(r); IF (Texts.Pos(r) = pos) & (r.elem # NIL) & (r.elem IS LinkElem) & (r.elem(LinkElem).side = RightSide) THEN Texts.ReadPrevElem(r) END; WHILE (r.elem # NIL) & ~ (r.elem IS LinkElem) DO Texts.ReadPrevElem(r) END; IF r.elem # NIL THEN e := r.elem(LinkElem); RETURN e.side = LeftSide ELSE RETURN FALSE END ELSE RETURN FALSE END END LinkFound;8*I8CSyntax10.Scn.FntSyntax10i.Scn.Fntu BEGIN e.loaded := FALSE; IF e.src = NIL THEN e.pic := NIL ELSE NEW(e.pic); e.pic.Init(1, 1, 1); IF e.pic.depth = 0 THEN (* error allocating picture *) Web.LogStr("WebElems: failed to allocate memory for image$"); IF Texts.ElemBase(e) # NIL THEN Web.LogF(" (pos=#)$", Texts.ElemPos(e)) END; e.pic := NIL END END END SetToDefault;8-_8#Syntax10.Scn.Fnt BEGIN IF (e.pic = NIL) OR ((e.pic.width = 1) & (e.pic.height = 1) & ~ e.loaded) THEN e.pic := defImg END END SubstituteImage;8'8Syntax10.Scn.FntpVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables pVersionElemsAllocEndp#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.Fntmm IF (e.src # NIL) & (e.pic # NIL) THEN Web.OpenUrl("", e.src^, Texts.ElemBase(e), e, NIL, Web.default) END p   VAR t : Texts.Text;  BEGIN  t := Texts.ElemBase(e); IF t IS WebCellElems.Text THEN t := WebCellElems.FindOutmostText(t(WebCellElems.Text)); END; IF (e.src # NIL) & (e.pic # NIL) THEN Web.OpenUrl("", e.src^, t, e, NIL, Web.default) END  END LoadImage;868#Syntax10.Scn.Fnt VAR t : Texts.Text; cRes : INTEGER; BEGIN IF (e IS ImageElem) & (e(ImageElem).src # NIL) THEN t := Texts.ElemBase(e); Web.CompareUrls(searchUrl, AbsUrl(e(ImageElem).src^, t), cRes); RETURN cRes = Web.ident ELSE RETURN FALSE END END CheckImageUrl;8b8TSyntax10.Scn.Fnt/pVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables pVersionElemsAllocEnd Syntax10i.Scn.Fnt p#Syntax10.Scn.FntTables NoTablesTablesTables NoTablesCSyntax10.Scn.Fnt.Syntax10i.Scn.Fnt-a FindElem(txt, 0, CheckImageUrl, image); (* one might use FoldElems.FindElem(...) instead *) *wp:V VAR image : Texts.Elem; pos : LONGINT; temp: Texts.Text; BEGIN (* assert: txt # NIL *) pos := Texts.ElemPos(e); IF src = NIL THEN IF e.src # NIL THEN SetToDefault(e); e.src := NIL; txt.notify(txt, TextFrames.replace, pos, pos + 1) END ELSE searchUrl := AbsUrl(src^, txt);  temp := txt; IF temp IS WebCellElems.Text THEN temp := WebCellElems.FindOutmostText(temp(WebCellElems.Text)); END; TableTools.FindElem(temp, 0, CheckImageUrl, image); (* two might use FoldElems.FindElem(...) instead *) IF (temp # txt) & (image = NIL) THEN TableTools.FindElemTable(WebTables.table, CheckImageUrl, image) END;  searchUrl := NIL; e.src := src; IF image # e THEN (* source has changed *) IF image # NIL THEN (* same image found *) e.pic := image(ImageElem).pic; e.loaded := image(ImageElem).loaded ELSE (* no such image found *) SetToDefault(e); IF load & loadImgs THEN LoadImage(e) END END; txt.notify(txt, TextFrames.replace, pos, pos + 1) END END END LinkImage;8U8#Syntax10.Scn.Fnt** VAR act : InsertedImage; BEGIN IF tsk.last = NIL THEN NEW(tsk.last); IF tsk.first = NIL THEN tsk.first := tsk.last; Oberon.Install(tsk) END ELSE NEW(act); tsk.last.next := act; tsk.last := act END; tsk.last.img := e; tsk.last.src := src; tsk.last.load := load END PrepImgLinking;8R8Syntax10.Scn.Fnt+pVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables pVersionElemsAllocEndwHp#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.FntDD LinkImage(act.img, Texts.ElemBase(act.img), act.src, act.load) Syntax10i.Scn.Fntp9 VAR t : Task; act : InsertedImage; text: Texts.Text; BEGIN t := Oberon.CurTask(Task); WHILE t.first # NIL DO act := t.first(InsertedImage); t.first := t.first.next;  text := Texts.ElemBase(act.img); IF (text # NIL) & (text IS WebCellElems.Text) THEN text := WebCellElems.text (*WebCellElems.FindOutmostText(text(WebCellElems.Text))*) END; LinkImage(act.img, text, act.src, act.load)  END; t.last := NIL; Oberon.Remove(t) END ImageLinker;8  88Syntax10.Scn.FntVpVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables oSyntax10i.Scn.FntpVersionElemsAllocEndR VAR t : Texts.Text; newSrc : Web.DynamicString; BEGIN t := Texts.ElemBase(e);  IF (t # NIL) & (t IS WebCellElems.Text) THEN t := WebCellElems.FindOutmostText(t(WebCellElems.Text)) END;  CopyDynString(src, newSrc); IF t # NIL THEN LinkImage(e, t, newSrc, load) ELSE PrepImgLinking(e, newSrc, load) END END SetSource;838#Syntax10.Scn.FntPP BEGIN RETURN (e IS ImageElem) & (e(ImageElem).pic = searchPic) END CheckImage;8  %8NSyntax10.Scn.FntpVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables jpVersionElemsAllocEndp#Syntax10.Scn.FntTables NoTablesTablesTables NoTablesCSyntax10.Scn.Fnt*Syntax10i.Scn.Fnt-^ FindElem(t, 0, CheckImage, image); (* one might use FoldElems.FindElem(...) instead *) 5Syntax10i.Scn.Fnt-pep#Syntax10.Scn.FntTables NoTablesTablesTables NoTablesCSyntax10.Scn.Fnt0Syntax10i.Scn.Fnt-e FindElem(t, pos + 1, CheckImage, image) (* one might use FoldElems.FindElem(...) instead *) ;-p  VAR t : Texts.Text; image : Texts.Elem; pos : LONGINT; BEGIN IF e.loaded # loaded THEN e.loaded := loaded; IF e.pic # NIL THEN t := Texts.ElemBase(e);  IF t IS WebCellElems.Text THEN t := WebCellElems.FindOutmostText(t(WebCellElems.Text)) END;  searchPic := e.pic;  TableTools.FindElem(t, 0, CheckImage, image); (* one might use FoldElems.FindElem(...) instead *)  WHILE image # NIL DO image(ImageElem).loaded := loaded; pos := Texts.ElemPos(image);  TableTools.FindElem(t, pos + 1, CheckImage, image) (* one might use FoldElems.FindElem(...) instead *)  END END; IF (e.pic.width = 1) & (e.pic.height = 1) & loaded THEN e.pic.Update(NIL, 0, 0, 1, 1) END; searchPic := NIL END END SetLoadResult;8  +8Syntax10.Scn.FntSyntax10i.Scn.Fntd pVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTablesCSyntax10.Scn.Fnt)Syntax10i.Scn.Fnt-\ FindElem(t, 0, CheckImage, image); (* one might use FoldElems.FindElem(...) instead *) -pVersionElemsAllocEnd p#Syntax10.Scn.FntTables NoTablesTablesTables NoTablesCSyntax10.Scn.Fnt/Syntax10i.Scn.Fnt-c FindElem(t, pos + 1, CheckImage, image) (* one might use FoldElems.FindElem(...) instead *) 70p0u (* only the picture is exchanged; loaded is set to FALSE, when pic = NIL; other fields remain untouched *) VAR t : Texts.Text; image : Texts.Elem; pos : LONGINT; default : BOOLEAN; BEGIN IF e.pic # pic THEN searchPic := e.pic; default := pic = NIL; IF default THEN SetToDefault(e); pic := e.pic ELSE e.pic := pic END; t := Texts.ElemBase(e);  IF t IS WebCellElems.Text THEN t := WebCellElems.FindOutmostText(t(WebCellElems.Text)) END; TableTools.FindElem(t, 0, CheckImage, image); (* one might use FoldElems.FindElem(...) instead *)  WHILE image # NIL DO image(ImageElem).pic := pic; IF default THEN image(ImageElem).loaded := FALSE END; pos := Texts.ElemPos(image);  TableTools.FindElem(t, pos + 1, CheckImage, image) (* one might use FoldElems.FindElem(...) instead *)  END; searchPic := NIL END END ExchangePic;848QSyntax10.Scn.FntSyntax10i.Scn.Fnt |p VAR r : Texts.Reader; ch : CHAR; end : LONGINT; BEGIN end := t.len; Texts.OpenReader(r, t, 0); Texts.Read(r, ch); WHILE ~ r.eot DO WHILE ~ r.eot & (ch # 0DX) DO Texts.Read(r, ch) END; (* skip to CR *) IF ~ r.eot THEN end := Texts.Pos(r); Texts.Read(r, ch) END; WHILE ~ r.eot & (ch = 0DX) DO Texts.Read(r, ch) END; (* skip CRs *) IF ~ r.eot THEN end := t.len; Texts.Read(r, ch) END END; BalloonElems.Popup(t, 0, end, keys); END Popup;86 18CSyntax10.Scn.FntSyntax10i.Scn.Fnt+ VAR msg : ContentMsg; keys : SET; time : LONGINT; BEGIN time := 0; REPEAT Input.Mouse(keys, m.X, m.Y); m.keys := m.keys + keys; IF (m.keys = {middle, right}) & (keys = m.keys) THEN IF time = 0 THEN time := Input.Time() ELSIF Input.Time() - time > 250 THEN (* keys pressed at least a quarter of a second *) msg.text := TextFrames.Text(""); e.handle(e, msg); Popup(msg.text); m.keys := cancel END END UNTIL keys = {} END TrackAndPopup;8 18#Syntax10.Scn.Fnt55 VAR msg : ContentMsg; keys : SET; BEGIN REPEAT Input.Mouse(keys, m.X, m.Y); m.keys := m.keys + keys; IF m.keys = {middle, right} THEN msg.text := TextFrames.Text(""); e.handle(e, msg); Popup(msg.text, keys); m.keys := m.keys + keys; keys := {} END UNTIL keys = {} END TrackAndPopup;8#8#Syntax10.Scn.Fnt VAR msg : ContentMsg; v : MenuViewers.Viewer; f : Frame; menuF : TextFrames.Frame; x, y : INTEGER; BEGIN IF e # NIL THEN msg.text := TextFrames.Text(""); msg.edInfo := TextFrames.Text(""); e.handle(e, msg); Texts.WriteLn(w); Texts.WriteLn(w); Texts.Append(msg.text, w.buf); Texts.WriteString(w, editSep); Texts.WriteLn(w); Texts.Insert(msg.edInfo, 0, w.buf); Texts.ChangeLooks(msg.edInfo, 0, msg.edInfo.len, {0}, infoFnt, 0, 0); Texts.Save(msg.edInfo, 0, msg.edInfo.len, w.buf); Texts.Append(msg.text, w.buf); NEW(f); f.e := e; TextFrames.Open(f, msg.text, 0); Oberon.AllocateUserViewer(0, x, y); menuF := TextFrames.NewMenu(msg.name, msg.menu); v := MenuViewers.New(menuF, f, TextFrames.menuH, x, y) END END Edit;8 +r8Syntax10.Scn.Fnt6Syntax10b.Scn.Fnt O 133s x VAR e1 : Elem; BEGIN WITH e : Elem DO WITH m : Texts.FileMsg DO IF m.id = Texts.load THEN e.visible := e.W > invisW; END | m : Texts.CopyMsg DO IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(Elem) END; Texts.CopyElem(e, e1); e1.visible := e.visible | m : Texts.IdentifyMsg DO m.mod := "WebElems"; m.proc := "" | m : TextFrames.DisplayMsg DO IF m.prepare THEN e.W := invisW END | m : TextPrinter.PrintMsg DO IF m.prepare THEN e.W := invisW END | m : TextFrames.TrackMsg DO IF middle IN m.keys THEN TrackAndPopup(e, m); IF ~ (left IN m.keys) THEN Edit(e) END END | m : ContentMsg DO IF m.edInfo # NIL THEN m.name := "WebElems.Elem"; m.menu := editMenu END ELSE END END END Handle;8  +8Syntax10.Scn.FntSyntax10b.Scn.Fnt Syntax10i.Scn.Fnt z :E     l VAR e1 : LinkElem; click : TrackedMsg; dsr : INTEGER; str : ARRAY 16 OF CHAR; BEGIN WITH e : LinkElem DO WITH m : Texts.FileMsg DO IF m.id = Texts.load THEN Files.ReadInt(m.r, e.side); e.visible := e.W > invisW; IF e.side = LeftSide THEN LoadDynString(m.r, e.url) END ELSE (* Texts.store *) Files.WriteInt(m.r, e.side); IF e.side = LeftSide THEN StoreDynString(m.r, e.url) END END | m : Texts.CopyMsg DO IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(LinkElem) END; Texts.CopyElem(e, e1); e1.visible := e.visible; e1.side := e.side; IF (e1.side = LeftSide) & (e.url # NIL) THEN CopyDynString(e.url^, e1.url) ELSE e1.url := NIL END | m : Texts.IdentifyMsg DO m.mod := "WebElems"; m.proc := "AllocLink" | m : TextFrames.DisplayMsg DO IF m.prepare THEN IF e.visible THEN e.W := linkW ELSE e.W := invisW END ELSIF e.visible THEN GetDsr(m.frame, m.pos, m.fnt, dsr); Display.CopyPattern(linkCol, lIcon[e.side], m.X0, m.Y0+dsr, Display.paint) END | m : TextPrinter.PrintMsg DO IF m.prepare THEN e.W := invisW ELSE e.W := linkW 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, lClickIcon[e.side], m.X0, m.Y0+dsr, Display.paint); TrackAndPopup(e, m); Display.CopyPattern(linkCol, lIcon[e.side], m.X0, m.Y0+dsr, Display.paint); IF m.frame IS TextFrames.Frame THEN click.frame := m.frame(TextFrames.Frame) ELSE click.frame := NIL END END; IF m.keys # cancel THEN click.x := -1; click.y := -1; click.keys := m.keys; e.handle(e, click) END END | m : TrackedMsg DO IF (middle IN m.keys) & (m.keys # cancel) THEN IF m.keys = {middle, right} THEN IF e.side = LeftSide THEN Edit(e) ELSE Edit(e.Twin()) END ELSE IF (m.x >= 0) & (m.y >= 0) THEN CreateQuery(str, m.x, m.y) ELSE str := "" END; IF m.keys = {middle} THEN FollowLink(e, "", str, m.frame, Texts.ElemBase(e), NIL) ELSE FollowLink(e, "", str, m.frame, NIL, NIL) END END END | m : MakeAbsMsg DO IF (e.side = LeftSide) & (e.url # NIL) THEN Web.Url2Str(AbsUrl(e.url^, Texts.ElemBase(e)), m.urlStr); CopyDynString(m.urlStr, e.url) END | m : ContentMsg DO IF e.side = LeftSide THEN IF e.url # NIL THEN Texts.WriteString(w, e.url^) END; Texts.WriteLn(w); Texts.Append(m.text, w.buf); IF m.edInfo # NIL THEN Texts.WriteString(w, editLinkInfo); Texts.WriteLn(w); Texts.Append(m.edInfo, w.buf); m.name := "WebElems.LinkElem"; m.menu := editUrlMenu END ELSE e1 := e.Twin(); IF e1 # NIL THEN e1.handle(e1, m) END END | m : UpdateMsg DO IF e.side = LeftSide THEN ReadDynLine(m, e.url) ELSE e1 := e.Twin(); IF e1 # NIL THEN e1.handle(e1, m) END END ELSE END END END HandleLink;8  +8Syntax10.Scn.FntOSyntax10b.Scn.Fnt iSyntax10i.Scn.Fnt 6 :EW  <  VAR e1 : MarkElem; dsr : INTEGER; BEGIN WITH e : MarkElem DO WITH m : Texts.FileMsg DO IF m.id = Texts.load THEN e.visible := e.W > invisW; Files.ReadString(m.r, e.name) ELSE (* Texts.store *) Files.WriteString(m.r, e.name) END | m : Texts.CopyMsg DO IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(MarkElem) END; Texts.CopyElem(e, e1); e1.visible := e.visible; COPY(e.name, e1.name) | m : Texts.IdentifyMsg DO m.mod := "WebElems"; m.proc := "AllocMark" | m : TextFrames.DisplayMsg DO IF m.prepare THEN IF e.visible THEN e.W := markW ELSE e.W := invisW END ELSIF e.visible THEN GetDsr(m.frame, m.pos, m.fnt, dsr); Display.CopyPattern(linkCol, mIcon, m.X0, m.Y0+dsr, Display.paint) END | m : TextPrinter.PrintMsg DO IF m.prepare THEN e.W := invisW ELSE e.W := markW 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, mClickIcon, m.X0, m.Y0+dsr, Display.paint); TrackAndPopup(e, m); Display.CopyPattern(linkCol, mIcon, m.X0, m.Y0+dsr, Display.paint) END; IF ~ (left IN m.keys) THEN Edit(e) END END | m : ContentMsg DO Texts.WriteString(w, e.name); Texts.WriteLn(w); Texts.Append(m.text, w.buf); IF m.edInfo # NIL THEN Texts.WriteString(w, editMarkInfo); Texts.WriteLn(w); Texts.Append(m.edInfo, w.buf); m.name := "WebElems.MarkElem"; m.menu := editMenu END | m : UpdateMsg DO ReadLine(m, e.name) ELSE END END END HandleMark;8  +8Syntax10.Scn.FntSyntax10b.Scn.Fnt (Syntax10i.Scn.Fnt  ;   # CF VAR e1 : ImageElem; l : LinkElem; click : TrackedMsg; actPic : Pictures.Picture; newSrc : Web.DynamicString; i : INTEGER; name : ARRAY 8 OF CHAR; BEGIN WITH e : ImageElem DO actPic := e.pic; WITH m : Texts.FileMsg DO IF m.id = Texts.load THEN PElems.Handler(e, m); LoadDynString(m.r, e.src); Files.ReadString(m.r, e.alt); Files.ReadBool(m.r, e.isMap); Files.ReadBool(m.r, e.loaded); IF e.src # NIL THEN actPic := e.pic; PrepImgLinking(e, e.src, FALSE) ELSE actPic := NIL END ELSE (* Texts.store *) IF e.pic = NIL THEN e.pic := defImg END; PElems.Handler(e, m); StoreDynString(m.r, e.src); Files.WriteString(m.r, e.alt); Files.WriteBool(m.r, e.isMap); Files.WriteBool(m.r, e.loaded) END | m : Texts.CopyMsg DO IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(ImageElem) END; PElems.Handler(e, m); IF e.src # NIL THEN CopyDynString(e.src^, e1.src) ELSE e1.src := NIL END; COPY(e.alt, e1.alt); e1.loaded := e.loaded | m : Texts.IdentifyMsg DO m.mod := "WebElems"; m.proc := "AllocImage" | m : TextFrames.TrackMsg DO SubstituteImage(e); IF middle IN m.keys THEN TrackAndPopup(e, m); IF m.keys # cancel THEN click.x := m.X; click.y := m.Y; click.keys := m.keys; IF m.frame IS TextFrames.Frame THEN click.frame := m.frame(TextFrames.Frame) ELSE click.frame := NIL END; IF (m.keys = {middle, right}) OR e.loaded THEN DEC(click.x, m.X0); DEC(click.y, m.Y0); IF click.x < 0 THEN click.x := 0 ELSIF click.x >= e.pic.width THEN click.x := e.pic.width - 1 END; IF click.y < 0 THEN click.y := 0 ELSIF click.y >= e.pic.height THEN click.y := e.pic.height - 1 END; click.y := ABS(click.y - e.pic.height + 1); e.handle(e, click) ELSE LoadImage(e) END END ELSE PElems.Handler(e, m) END | m : TrackedMsg DO IF (middle IN m.keys) & (m.keys # cancel) THEN IF m.keys = {middle, right} THEN Edit(e) ELSIF LinkFound(m.frame, Texts.ElemPos(e), l) THEN IF ~ e.isMap THEN m.x := -1; m.y := -1 END; l.handle(l, m) END END | m : MakeAbsMsg DO IF e.src # NIL THEN Web.Url2Str(AbsUrl(e.src^, Texts.ElemBase(e)), m.urlStr); CopyDynString(m.urlStr, e.src) END | m : ContentMsg DO IF e.src # NIL THEN Texts.WriteString(w, e.src^) END; Texts.WriteLn(w); Texts.WriteString(w, e.alt); Texts.WriteLn(w); IF e.isMap THEN Texts.WriteString(w, map) END; Texts.WriteLn(w); Texts.Append(m.text, w.buf); IF m.edInfo # NIL THEN Texts.WriteString(w, editImageInfo1); Texts.WriteLn(w); Texts.WriteString(w, editImageInfo2); Texts.WriteLn(w); Texts.WriteString(w, editImageInfo3); Texts.WriteLn(w); Texts.Append(m.edInfo, w.buf); m.name := "WebElems.ImageElem"; m.menu := editUrlMenu END | m : UpdateMsg DO ReadDynLine(m, newSrc); ReadLine(m, e.alt); ReadLine(m, name); i := 0; WHILE name[i] # 0X DO name[i] := CAP(name[i]); INC(i) END; e.isMap := name = map; SetSource(e, newSrc^, TRUE); actPic := e.pic ELSE SubstituteImage(e); PElems.Handler(e, m) END; e.pic := actPic END END HandleImage;8  +8Syntax10.Scn.FntMSyntax10b.Scn.Fnt iSyntax10i.Scn.Fnt 2 9DY - =f VAR e1 : TagElem; dsr : INTEGER; BEGIN WITH e : TagElem DO WITH m : Texts.FileMsg DO IF m.id = Texts.load THEN e.visible := e.W > invisW; LoadDynString(m.r, e.str) ELSE (* Texts.store *) StoreDynString(m.r, e.str) END | m : Texts.CopyMsg DO IF m.e = NIL THEN NEW(e1); m.e := e1 ELSE e1 := m.e(TagElem) END; Texts.CopyElem(e, e1); e1.visible := e.visible; IF e.str # NIL THEN CopyDynString(e.str^, e1.str) ELSE e1.str := NIL END | m : Texts.IdentifyMsg DO m.mod := "WebElems"; m.proc := "AllocTag" | m : TextFrames.DisplayMsg DO IF m.prepare THEN IF e.visible THEN e.W := tagW ELSE e.W := invisW END ELSIF e.visible THEN GetDsr(m.frame, m.pos, m.fnt, dsr); Display.CopyPattern(tagCol, tIcon, m.X0, m.Y0+dsr, Display.replace) END | m : TextPrinter.PrintMsg DO IF m.prepare THEN e.W := invisW ELSE e.W := tagW 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, tClickIcon, m.X0, m.Y0+dsr, Display.paint); TrackAndPopup(e, m); Display.CopyPattern(tagCol, tIcon, m.X0, m.Y0+dsr, Display.replace); END; IF ~ (left IN m.keys) THEN Edit(e) END END | m : ContentMsg DO IF e.str # NIL THEN Texts.WriteString(w, e.str^) END; Texts.WriteLn(w); Texts.Append(m.text, w.buf); IF m.edInfo # NIL THEN Texts.WriteString(w, editTagInfo); Texts.WriteLn(w); Texts.Append(m.edInfo, w.buf); m.name := "WebElems.TagElem"; m.menu := editMenu END | m : UpdateMsg DO ReadDynLine(m, e.str) ELSE END END END HandleTag;8  8#Syntax10.Scn.FntZZ VAR e : LinkElem; BEGIN NEW(e); e.handle := HandleLink; Texts.new := e END AllocLink;8  8#Syntax10.Scn.FntZZ VAR e : MarkElem; BEGIN NEW(e); e.handle := HandleMark; Texts.new := e END AllocMark;8  8#Syntax10.Scn.Fnt]] VAR e : ImageElem; BEGIN NEW(e); e.handle := HandleImage; Texts.new := e END AllocImage;8 8#Syntax10.Scn.FntWW VAR e : TagElem; BEGIN NEW(e); e.handle := HandleTag; Texts.new := e END AllocTag;8 598#Syntax10.Scn.Fnt BEGIN e.H := elemH; e.handle := HandleLink; e.visible := visible; e.side := side; IF visible THEN e.W := linkW ELSE e.W := invisW END; e.url := NIL END InitLink;8 %38#Syntax10.Scn.Fnt BEGIN e.H := elemH; e.handle := HandleMark; e.visible := visible; Web.Int2Str(Oberon.Time(), e.name); IF visible THEN e.W := markW ELSE e.W := invisW END END InitMark;8  8#Syntax10.Scn.FntQQ BEGIN e.handle := HandleImage; e.isMap := FALSE; SetToDefault(e) END InitImage;8 $[8#Syntax10.Scn.Fnt BEGIN e.H := elemH; e.handle := HandleTag; e.visible := visible; IF visible THEN e.W := tagW ELSE e.W := invisW END END InitTag;8 28#Syntax10.Scn.FntVV VAR e : LinkElem; BEGIN NEW(e); InitLink(e, side, visible); RETURN e END NewLink;8 "8#Syntax10.Scn.FntPP VAR e : MarkElem; BEGIN NEW(e); InitMark(e, visible); RETURN e END NewMark;8 8#Syntax10.Scn.FntJJ VAR e : ImageElem; BEGIN NEW(e); InitImage(e); RETURN e END NewImage;8 !8#Syntax10.Scn.FntMM VAR e : TagElem; BEGIN NEW(e); InitTag(e, visible); RETURN e END NewTag;8R8#Syntax10.Scn.Fnt VAR right : LinkElem; r : Texts.Reader; ch : CHAR; BEGIN right := NewLink(RightSide, left.visible); Texts.OpenReader(r, t, end - 1); Texts.Read(r, ch); Texts.SetFont(w, r.fnt); Texts.WriteElem(w, right); Texts.Insert(t, end, w.buf); Texts.OpenReader(r, t, beg); Texts.Read(r, ch); Texts.SetFont(w, r.fnt); Texts.WriteElem(w, left); Texts.Insert(t, beg, w.buf); Texts.ChangeLooks(t, beg, end + 1, {1}, NIL, linkCol, 0); Texts.SetFont(w, Fonts.Default) END InsertThisLink;8)8#Syntax10.Scn.Fnt VAR insert : TextFrames.InsertElemMsg; t : Texts.Text; pos : LONGINT; r : Texts.Reader; ch : CHAR; BEGIN insert.e := e; Oberon.FocusViewer.handle(Oberon.FocusViewer, insert); t := Texts.ElemBase(e); IF t # NIL THEN pos := Texts.ElemPos(e); Texts.OpenReader(r, t, pos + 1); Texts.Read(r, ch); IF (pos >= t.len) OR (ch = 0DX) THEN Texts.OpenReader(r, t, pos - 1); Texts.Read(r, ch) END; Texts.ChangeLooks(t, pos, pos + 1, {0}, r.fnt, 0, 0); END END InsertThis;8   8#Syntax10.Scn.Fnt VAR t : Texts.Text; beg, end, time : LONGINT; BEGIN Oberon.GetSelection(t, beg, end, time); IF time >= 0 THEN InsertThisLink(NewLink(LeftSide, TRUE), t, beg, end) END END InsertLink;8  8#Syntax10.Scn.Fnt11 BEGIN InsertThis(NewMark(TRUE)) END InsertMark;8 Y8#Syntax10.Scn.Fnt VAR link : LinkElem; mark : MarkElem; lT, mT : Texts.Text; lBeg, lEnd, mPos, time : LONGINT; url : Web.Url; urlStr : ARRAY uLen OF CHAR; r : Texts.Reader; ch : CHAR; res : INTEGER; BEGIN Oberon.GetSelection(lT, lBeg, lEnd, time); IF time > 0 THEN mark := NewMark(TRUE); InsertThis(mark); mT := Texts.ElemBase(mark); END; IF mT # NIL THEN mPos := Texts.ElemPos(mark); Texts.OpenReader(r, mT, mPos + 1); Texts.Read(r, ch); IF (r.elem # NIL) & (r.elem IS MarkElem) THEN mark := r.elem(MarkElem); Texts.Delete(mT, mPos, mPos + 1) ELSIF (lT = mT) & (mPos < lEnd) THEN INC(lEnd); IF mPos <= lBeg THEN INC(lBeg) END END; link := NewLink(LeftSide, TRUE); InsertThisLink(link, lT, lBeg, lEnd); IF (mT IS Web.Text) & (mT(Web.Text).act # NIL) & (mT(Web.Text).act.url # NIL) THEN IF (lT IS Web.Text) THEN IF lT(Web.Text).base # NIL THEN url := lT(Web.Text).base ELSIF (lT(Web.Text).act # NIL) & (lT(Web.Text).act.url # NIL) THEN url := lT(Web.Text).act.url END; Web.CompareUrls(url, mT(Web.Text).act.url, res); IF res = Web.different THEN NEW(url); url^ := mT(Web.Text).act.url^ ELSE url := NIL END ELSE NEW(url); url^ := mT(Web.Text).act.url^ END END; IF url = NIL THEN url := Web.EmptyUrl() END; COPY(mark.name, url.frag); Web.Url2Str(url, urlStr); CopyDynString(urlStr, link.url) END END InsertLinkToMark;8  8#Syntax10.Scn.Fnt// BEGIN InsertThis(NewImage()) END InsertImage;8  8#Syntax10.Scn.Fnt// BEGIN InsertThis(NewTag(TRUE)) END InsertTag;8(A8#Syntax10.Scn.Fnt VAR f : Display.Frame; v : Viewers.Viewer; BEGIN f := NIL; v := Oberon.Par.vwr; IF (Oberon.Par.frame IS TextFrames.Frame) & (Oberon.Par.frame = v.dsc) THEN f := v.dsc.next ELSE v := Oberon.MarkedViewer(); IF (v # NIL) & (v.dsc # NIL) & (v.dsc.next # NIL) THEN f := v.dsc.next END END; IF (f # NIL) & (f IS TextFrames.Frame) THEN RETURN f(TextFrames.Frame).text ELSE RETURN NIL END END TargetText;8Rp#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.Fnt::PROCEDURE ChangeLooks (t : Texts.Text; visible : BOOLEAN);SpT8Syntax10.Scn.Fnt9bpVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.Fnt** t.notify(t, Texts.replace, 0, t.len) ApVersionElemsAllocEnd VAR r : Texts.Reader; resize : TextFrames.DisplayMsg; BEGIN IF t # NIL THEN resize.prepare := TRUE; Texts.OpenReader(r, t, 0); Texts.ReadElem(r); WHILE r.elem # NIL DO IF r.elem IS Elem THEN r.elem(Elem).visible := visible; r.elem.handle(r.elem, resize) END; Texts.ReadElem(r) END;  IF notify # NIL THEN notify(t, Texts.replace, 0, t.len) END  END END ChangeLooks;8p#Syntax10.Scn.FntTables NoTablesTablesTables NoTables >p8#Syntax10.Scn.Fntnn BEGIN ChangeLooks(frag.txt, NIL, show); WebCellElems.notify(frag, FALSE); RETURN TRUE END ChangeLookAction;8p 8Syntax10.Scn.FntSyntax10i.Scn.Fnt'pVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables )pVersionElemsAllocEnd#Sp#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.Fnt99 ChangeLooks(TargetText(), In.Done & (switch = "on")); p K (* default value is "off" *) VAR switch : ARRAY 8 OF CHAR;  text: Texts.Text; dummy: BOOLEAN;  BEGIN In.Open; In.Name(switch);  text := TargetText(); show := In.Done & (switch = "on"); dummy := TableTools.ForAllFragments(text, 0, text.len, ChangeLookAction); ChangeLooks(text, text.notify, show);  END Elems;8  $8CSyntax10.Scn.FntSyntax10i.Scn.Fnt (* default value is "on" *) VAR switch : ARRAY 8 OF CHAR; BEGIN In.Open; In.Name(switch); loadImgs := ~ (In.Done & (switch = "off")) END LoadImages;8*48#Syntax10.Scn.Fnt VAR t : Texts.Text; r : Texts.Reader; beg, end, time : LONGINT; BEGIN Oberon.GetSelection(t, beg, end, time); IF time > 0 THEN Texts.OpenReader(r, t, beg); Texts.ReadElem(r); IF (r.elem # NIL) & (Texts.ElemPos(r.elem) <= end) & (r.elem IS ImageElem) & (r.elem(ImageElem).pic # NIL) & (r.elem(ImageElem).src # NIL) THEN Web.OpenUrl("", r.elem(ImageElem).src^, t, NIL, NIL, action) END END END GetImage;8  h8CSyntax10.Scn.FntSyntax10i.Scn.Fnt&,V (* load the selected image and display it *) BEGIN GetImage(Web.show) END ShowImage;8  h8CSyntax10.Scn.FntSyntax10i.Scn.Fnt$.V (* load the selected image and store it *) BEGIN GetImage(Web.store) END StoreImage;88n8Syntax10.Scn.FnttpVersionElemsAllocBeg#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.Fnt Texts.ReadElem(r); pVersionElemsAllocEndSyntax10i.Scn.Fntdrp#Syntax10.Scn.FntTables NoTablesTablesTables NoTables#Syntax10.Scn.Fnt Texts.ReadElem(r); p( VAR txt : Texts.Text; r : Texts.Reader; first, act : ListedImage; BEGIN txt := TargetText(); IF (txt # NIL) & (txt IS Web.Text) THEN t := txt(Web.Text); Texts.OpenReader(r, t, 0);  TableTools.ReadElem(r);  WHILE r.elem # NIL DO IF (r.elem IS ImageElem) & (r.elem(ImageElem).pic # NIL) & (r.elem(ImageElem).src # NIL) THEN act := first; WHILE (act # NIL) & (act.img.pic # r.elem(ImageElem).pic) DO act := act.next END; IF act = NIL THEN (* image not yet listed *) NEW(act); act.img := r.elem(ImageElem); act.next := first; first := act END END;  TableTools.ReadElem(r);  END END; RETURN first END AllImages;8 8#Syntax10.Scn.Fnt VAR t : Web.Text; act : ListedImage; urlStr : ARRAY uLen OF CHAR; BEGIN act := AllImages(t); WHILE act # NIL DO Web.Url2Str(AbsUrl(act.img.src^, t), urlStr); IF urlStr # "" THEN Web.OpenUrl("", urlStr, t, NIL, NIL, Web.store) END; act := act.next END END StoreAllImages;8  8#Syntax10.Scn.Fnt VAR t : Web.Text; act : ListedImage; BEGIN act := AllImages(t); WHILE act # NIL DO IF ~ act.img.loaded THEN Web.OpenUrl("", act.img.src^, t, act.img, NIL, Web.default) END; act := act.next END END LoadAllImages;8  8#Syntax10.Scn.Fnt VAR r : Texts.Reader; t : Texts.Text; m : MakeAbsMsg; BEGIN t := TargetText(); IF (t # NIL) & (t IS Web.Text) THEN Texts.OpenReader(r, t, 0); Texts.ReadElem(r); WHILE r.elem # NIL DO r.elem.handle(r.elem, m); Texts.ReadElem(r) END END END ConvertToAbs;8  8#Syntax10.Scn.Fnt VAR f : Frame; m : UpdateMsg; urlStr : Web.DynamicString; BEGIN IF (Oberon.Par.frame = Oberon.Par.vwr.dsc) & (Oberon.Par.frame.next IS Frame) THEN f := Oberon.Par.frame.next(Frame); IF (f.e # NIL) & ((f.e IS LinkElem) OR (f.e IS ImageElem)) THEN m.text := f.text; Texts.OpenReader(m.r, m.text, 0); ReadDynLine(m, urlStr); m.text := Texts.ElemBase(f.e); Web.LogUrl(AbsUrl(urlStr^, m.text), FALSE) END END END ShowAbsUrl;8 8#Syntax10.Scn.Fnt VAR f : Frame; t : Texts.Text; e : Texts.Elem; ch : CHAR; m : UpdateMsg; BEGIN IF (Oberon.Par.frame = Oberon.Par.vwr.dsc) & (Oberon.Par.frame.next IS Frame) THEN f := Oberon.Par.frame.next(Frame); IF f.e # NIL THEN e := f.e; m.text := f.text; Texts.OpenReader(m.r, m.text, 0); e.handle(e, m); t := Oberon.Par.frame(TextFrames.Frame).text; Texts.OpenReader(m.r, t, t.len-1); Texts.Read(m.r, ch); IF ch = "!" THEN Texts.Delete(t, t.len-1, t.len) END END END END Update;8I)8#Syntax10.Scn.Fnt VAR r : Texts.Reader; ch : CHAR; BEGIN Texts.OpenReader(r, tf.text, TextFrames.Pos(tf, x, y)); Texts.Read(r, ch); RETURN (r.elem = NIL) & (x > tf.X + tf.barW) END CanBeWord;8lq8#Syntax10.Scn.Fntmm VAR mouse, end : TextFrames.Location; twin : LinkElem; t : Texts.Text; r : Texts.Reader; ch : CHAR; BEGIN TextFrames.LocateChar(f, x, y, mouse); TextFrames.LocatePos(f, Texts.ElemPos(e), loc); IF mouse.org > loc.org THEN TextFrames.LocatePos(f, mouse.org, loc) END; twin := e.Twin(); IF twin # NIL THEN TextFrames.LocatePos(f, Texts.ElemPos(twin), end); WHILE mouse.org < end.org DO TextFrames.LocatePos(f, end.org - 1, end); END ELSE TextFrames.LocatePos(f, mouse.pos - 1, end) END; t := Texts.ElemBase(e); Texts.OpenReader(r, t, end.pos); Texts.Read(r, ch); WHILE (end.pos > loc.pos) & ((ch = 0DX) OR (ch = 20X)) DO DEC(end.pos); Texts.OpenReader(r, t, end.pos); Texts.Read(r, ch) END; TextFrames.LocatePos(f, end.pos, end); IF loc.pos < end.pos THEN loc.dx := end.x + end.dx - loc.x ELSIF loc.dx = 0 THEN loc.dx := 5 END END LocateLink;8=S8QSyntax10.Scn.Fnt]Syntax10i.Scn.Fnt] VAR bm : Bitmaps.Bitmap; i, limit : INTEGER; BEGIN bm := Bitmaps.New(w, h); Bitmaps.CopyBlock(Bitmaps.Disp, bm, 0, 0, 1, 1, 0, 1, Display.replace); Display.Dot(col, 0, 0, Display.replace); Bitmaps.CopyBlock(Bitmaps.Disp, bm, 0, 0, 1, 1, 0, 0, Display.replace); Bitmaps.CopyBlock(bm, Bitmaps.Disp, 0, 1, 1, 1, 0, 0, Display.replace); (* copy dot to line *) i := 1; limit := w DIV 2; WHILE i <= limit DO Bitmaps.CopyBlock(bm, bm, 0, 0, i, 1, i, 0, Display.replace); i := i * 2 END; IF i < w THEN Bitmaps.CopyBlock(bm, bm, 0, 0, w - i, 1, i, 0, Display.replace); END; (* copy line to array *) i := 1; limit := h DIV 2; WHILE i <= limit DO Bitmaps.CopyBlock(bm, bm, 0, 0, w, i, 0, i, Display.replace); i := i * 2 END; IF i < h THEN Bitmaps.CopyBlock(bm, bm, 0, 0, w, h - i, 0, i, Display.replace); END; RETURN bm END NewBitmap;8Z8CSyntax10.Scn.FntSyntax10i.Scn.Fnt(*clips to right frame margin*) BEGIN IF x + w > f.X + f.W - f.right THEN w := f.X + f.W - f.right - x END ; Bitmaps.CopyBlock(map, Bitmaps.Disp, 0, 0, w, h, x, y, Display.invert) END InvertRect;8e8#Syntax10.Scn.Fnt   CONST height = 2; VAR keys : SET; new, old : TextFrames.Location; line : Bitmaps.Bitmap; track1 : Web.TrackMsg; track2 : TextFrames.TrackMsg; click : TrackedMsg; BEGIN line := NewBitmap(f.W, height, linkCol); LocateLink(f, x, y, e, old); InvertRect(f, old.x, old.y, old.dx, height, line); new := old; REPEAT Input.Mouse(keys, x, y); keysum := keysum + keys; IF LinkFound(f, TextFrames.Pos(f, x, y), e) THEN LocateLink(f, x, y, e, new); IF (new.pos # old.pos) OR (new.dx # old.dx) THEN InvertRect(f, old.x, old.y, old.dx, height, line); InvertRect(f, new.x, new.y, new.dx, height, line); old := new END END UNTIL (keys = {}) OR (right IN keysum); IF keysum = cancel THEN REPEAT Input.Mouse(keys, x, y) UNTIL keys = {}; InvertRect(f, new.x, new.y, new.dx, height, line) ELSE SuperHandle(f, track1); IF keys = {} THEN InvertRect(f, new.x, new.y, new.dx, height, line); click.frame := f; click.x := -1; click.y := -1; click.keys := keysum; e.handle(e, click) ELSE track2.X := x; track2.Y := y; track2.keys := keysum; track2.pos := Texts.ElemPos(e); track2.frame := f; track2.X0 := Display.Width; track2.Y0 := Display.Height; e.handle(e, track2); InvertRect(f, new.x, new.y, new.dx, height, line) END END END TrackLink;8or8CSyntax10.Scn.FntSyntax10i.Scn.Fnt.L (*clips to right frame margin*) BEGIN IF x + w > f.X + f.W - f.right THEN w := f.X + f.W - f.right - x END ; IF draw THEN Bitmaps.CopyBlock(Bitmaps.Disp, map, x, y, w, h, 0, 0, 0); Display.ReplConst(linkCol, x, y, w, h, Display.replace) ELSE Bitmaps.CopyBlock(map, Bitmaps.Disp, 0, 0, w, h, x, y, 0) END END ReplaceRect;8f8#Syntax10.Scn.Fnt CONST height = 2; VAR keys : SET; link : LinkElem; new, old : TextFrames.Location; save : Bitmaps.Bitmap; v : Viewers.Viewer; track1 : Web.TrackMsg; track2 : TextFrames.TrackMsg; click : TrackedMsg; BEGIN save := Bitmaps.New(f.W, height); LocateLink(f, x, y, e, old); ReplaceRect(f, old.x, old.y, old.dx, height, save, TRUE); new := old; REPEAT Input.Mouse(keys, x, y); keysum := keysum + keys; IF LinkFound(f, TextFrames.Pos(f, x, y), link) THEN e := link; LocateLink(f, x, y, e, new); IF (new.pos # old.pos) OR (new.dx # old.dx) THEN ReplaceRect(f, old.x, old.y, old.dx, height, save, FALSE); ReplaceRect(f, new.x, new.y, new.dx, height, save, TRUE); old := new END END UNTIL (keys = {}) OR (right IN keysum); IF keysum = cancel THEN REPEAT Input.Mouse(keys, x, y) UNTIL keys = {}; ReplaceRect(f, new.x, new.y, new.dx, height, save, FALSE) ELSE SuperHandle(f, track1); IF keys = {} THEN ReplaceRect(f, new.x, new.y, new.dx, height, save, FALSE); click.frame := f; click.x := -1; click.y := -1; click.keys := keysum; e.handle(e, click) ELSE track2.X := x; track2.Y := y; track2.keys := keysum; track2.pos := Texts.ElemPos(e); track2.frame := f; track2.X0 := Display.Width; track2.Y0 := Display.Height; v := Viewers.This(new.x, new.y); e.handle(e, track2); IF v = Viewers.This(new.x, new.y) THEN ReplaceRect(f, new.x, new.y, new.dx, height, save, FALSE) END END END END TrackLink;8Gq8#Syntax10.Scn.Fntmm VAR e : LinkElem; BEGIN WITH f : TextFrames.Frame DO WITH m : Oberon.InputMsg DO IF (m.id = Oberon.track) & (middle IN m.keys) & CanBeWord(f, m.X, m.Y) & LinkFound(f, TextFrames.Pos(f, m.X, m.Y), e) THEN TrackLink(f, m.X, m.Y, e, m.keys) ELSE SuperHandle(f, m) END ELSE SuperHandle(f, m) END ELSE SuperHandle(f, m) END END FrameHandle;88#Syntax10.Scn.Fnt++ VAR line, line1 : ARRAY 9 OF SET; BEGIN line[8] := {4}; line[7] := {3..5}; line[6] := {2..6}; line[5] := {1..7}; line[4] := {3..5}; line1 := line; line[3] := {3..7}; line[2] := {3..7}; line[1] := {3..7}; lIcon[LeftSide] := Display.NewPattern(line, 9, 8); line1[3] := {1..5}; line1[2] := {1..5}; line1[1] := {1..5}; lIcon[RightSide] := Display.NewPattern(line1, 9, 8); line[8] := {}; line[7] := {4}; line[6] := {3..5}; line[5] := {4}; line[4] := {4}; line[3] := {4}; line[1] := {}; line1 := line; line[2] := {4..6}; lClickIcon[LeftSide] := Display.NewPattern(line, 9, 8); line1[2] := {2..4}; lClickIcon[RightSide] := Display.NewPattern(line1, 9, 8); line[8] := {4, 8}; line[7] := {3..5, 7, 8}; line[6] := {2..8}; line[5] := {1..8}; line[4] := {2..8}; line[3] := {3..8}; line[2] := {2..8}; line[1] := {1..8}; mIcon := Display.NewPattern(line, 10, 8); line[8] := {}; line[7] := {4}; line[6] := {3..5, 7}; line[5] := {2..7}; line[4] := {3..7}; line[3] := {4..7}; line[2] := {3..7}; line[1] := {}; mClickIcon := Display.NewPattern(line, 10, 8); line[8] := {5..8}; line[7] := {5..8}; line[6] := {3, 4, 6, 7, 9, 10}; line[5] := {2, 3, 6, 7, 10, 11}; line[4] := {1, 2, 6, 7, 11, 12}; line[3] := {2, 3, 10, 11}; line[2] := {3, 4, 9, 10}; line[1] := {4, 5, 8, 9}; tIcon := Display.NewPattern(line, 14, 8); line[8] := {}; line[7] := {}; line[6] := {5, 8}; line[5] := {4, 5, 8, 9}; line[4] := {3..5, 8..10}; line[3] := {4..9}; line[2] := {5..8}; line[1] := {6, 7}; tClickIcon := Display.NewPattern(line, 14, 8) END InitIcons;8 8#Syntax10.Scn.Fnt// VAR f : Files.File; r : Files.Rider; res : INTEGER; BEGIN NEW(defImg); f := Files.Old("Web.Bmp"); IF f # NIL THEN Files.Set(r, f, 0); defImg.Load(r, res) ELSE res := Pictures.error END; IF res # Pictures.done THEN defImg.Init(35, 35, 4); ASSERT(defImg.depth # 0); defImg.SetColorRGB(255, 0, 0); defImg.ReplConst(0, 0, 35, 35, Display.replace); defImg.SetColorRGB(0, 255, 0); defImg.ReplConst(7, 7, 21, 21, Display.replace); defImg.SetColorRGB(0, 0, 255); defImg.ReplConst(14, 14, 7, 7, Display.replace); END END LoadDefaultPicture;88QSyntax10.Scn.FntSyntax10i.Scn.Fnt R  VAR i, j : INTEGER; name : ARRAY 32 OF CHAR; BEGIN COPY(Fonts.Default.name, name); i := 0; WHILE (name[i] # 0X) & ((name[i] < "0") OR (name[i] > "9")) DO INC(i) END; (* skip family *) WHILE (name[i] # 0X) & (name[i] >= "0") & (name[i] <= "9") DO INC(i) END; (* skip size *) IF name[i] = "." THEN j := i + 1; WHILE name[j] # 0X DO INC(j) END; WHILE j >= i DO name[j+1] := name[j]; DEC(j) END END; name[i] := "i"; infoFnt := Fonts.This(name) END SetInfoFont;8l8_Syntax10.Scn.FntESyntax10i.Scn.Fnt6 InitIcons; LoadDefaultPicture; loadImgs := TRUE; linkCol := 3; (* blue *) tagCol := 8; (* green *) clickCol := 1; (* red *) HandlerElems.SetHandler("WebElems.FrameHandle", FrameHandle, SuperHandle); SetInfoFont; Texts.OpenWriter(w); NEW(tsk); tsk.safe := TRUE; tsk.time := 0; tsk.handle := ImageLinker8 MODULE WebElems;   (* With Tables *) IMPORT Files, Fonts, Display, Bitmaps, Input, Viewers, MenuViewers, Texts, TextFrames, TextPrinter, Oberon, Web, HandlerElems, Pictures, PElems, BalloonElems, In , TableTools, WebCellElems, WebPanelElems, WebTables; CONST  TYPE  VAR  PROCEDURE GetDsr (f : Display.Frame; pos : LONGINT; fnt : Fonts.Font; VAR dsr : INTEGER);  PROCEDURE CopyDynString (src : ARRAY OF CHAR; VAR dest : Web.DynamicString);  PROCEDURE LoadDynString (VAR r : Files.Rider; VAR str : Web.DynamicString);  PROCEDURE StoreDynString (VAR r : Files.Rider; str : Web.DynamicString);  PROCEDURE ReadLine (VAR msg : UpdateMsg; VAR str : ARRAY OF CHAR);  PROCEDURE ReadDynLine (VAR msg : UpdateMsg; VAR str : Web.DynamicString);   PROCEDURE (e : LinkElem) Twin* () : LinkElem;  PROCEDURE CheckMark (e : Texts.Elem) : BOOLEAN;  PROCEDURE ScrolledToMark (url : Web.Url; f : TextFrames.Frame; t : Texts.Text) : BOOLEAN;  PROCEDURE AbsUrl (uStr : ARRAY OF CHAR; t : Texts.Text) : Web.Url;  PROCEDURE CreateQuery (VAR s : ARRAY OF CHAR; x, y : INTEGER);  PROCEDURE FollowLink* (e : LinkElem; meth, query : ARRAY OF CHAR; f : TextFrames.Frame; t : Texts.Text; ent : Web.Body);  PROCEDURE LinkFound (tf : TextFrames.Frame; pos : LONGINT; VAR e : LinkElem) : BOOLEAN;  PROCEDURE SetToDefault (e : ImageElem);  PROCEDURE SubstituteImage (e : ImageElem);  PROCEDURE LoadImage (e : ImageElem);  PROCEDURE CheckImageUrl (e: Texts.Elem) : BOOLEAN;  PROCEDURE LinkImage (e : ImageElem; txt : Texts.Text; src : Web.DynamicString; load : BOOLEAN);  PROCEDURE PrepImgLinking (e : ImageElem; src : Web.DynamicString; load : BOOLEAN);  PROCEDURE ImageLinker;  PROCEDURE SetSource* (e : ImageElem; src : ARRAY OF CHAR; load : BOOLEAN);  PROCEDURE CheckImage (e : Texts.Elem) : BOOLEAN;  PROCEDURE SetLoadResult* (e : ImageElem; loaded : BOOLEAN);  PROCEDURE ExchangePic* (e : ImageElem; pic : Pictures.Picture);  PROCEDURE Popup (t : Texts.Text; VAR keys : SET);  (* before changes in Module BalloonElems: PROCEDURE TrackAndPopup* (e : Texts.Elem; VAR m : TextFrames.TrackMsg);  *) PROCEDURE TrackAndPopup* (e : Texts.Elem; VAR m : TextFrames.TrackMsg);  PROCEDURE Edit (e : Texts.Elem);  PROCEDURE Handle* (e : Texts.Elem; VAR m : Texts.ElemMsg);  PROCEDURE HandleLink* (e : Texts.Elem; VAR m : Texts.ElemMsg);  PROCEDURE HandleMark* (e : Texts.Elem; VAR m : Texts.ElemMsg);  PROCEDURE HandleImage* (e : Texts.Elem; VAR m : Texts.ElemMsg);  PROCEDURE HandleTag* (e : Texts.Elem; VAR m : Texts.ElemMsg);  PROCEDURE AllocLink*;  PROCEDURE AllocMark*;  PROCEDURE AllocImage*;  PROCEDURE AllocTag*;  PROCEDURE InitLink* (e : LinkElem; side : INTEGER; visible : BOOLEAN);  PROCEDURE InitMark* (e : MarkElem; visible : BOOLEAN);  PROCEDURE InitImage* (e : ImageElem);  PROCEDURE InitTag* (e : TagElem; visible : BOOLEAN);  PROCEDURE NewLink* (side : INTEGER; visible : BOOLEAN) : LinkElem;  PROCEDURE NewMark* (visible : BOOLEAN) : MarkElem;  PROCEDURE NewImage* () : ImageElem;  PROCEDURE NewTag* (visible : BOOLEAN) : TagElem;  PROCEDURE InsertThisLink (left : LinkElem; t : Texts.Text; beg, end : LONGINT);  PROCEDURE InsertThis (e : Texts.Elem);  PROCEDURE InsertLink*;  PROCEDURE InsertMark*;  PROCEDURE InsertLinkToMark*;  PROCEDURE InsertImage*;  PROCEDURE InsertTag*;  PROCEDURE TargetText () : Texts.Text;  PROCEDURE ChangeLooks (t : Texts.Text; notify : Texts.Notifier; visible : BOOLEAN);  PROCEDURE ChangeLookAction(frag: WebCellElems.Elem): BOOLEAN;  PROCEDURE Elems*; (* on / off *)  PROCEDURE LoadImages*; (* on / off *)  PROCEDURE GetImage (action : SHORTINT);  PROCEDURE ShowImage*;  PROCEDURE StoreImage*;  PROCEDURE AllImages (VAR t : Web.Text) : ListedImage;  PROCEDURE StoreAllImages*;  PROCEDURE LoadAllImages*;  PROCEDURE ConvertToAbs*;  PROCEDURE ShowAbsUrl*;  PROCEDURE Update*;  PROCEDURE CanBeWord (tf : TextFrames.Frame; x, y : INTEGER) : BOOLEAN;  PROCEDURE LocateLink (f : TextFrames.Frame; x, y : INTEGER; e : LinkElem; VAR loc : TextFrames.Location);  (* only works on Macs: PROCEDURE NewBitmap (w, h, col : INTEGER) : Bitmaps.Bitmap;  PROCEDURE InvertRect (f : TextFrames.Frame; x, y, w, h : INTEGER; map : Bitmaps.Bitmap);  PROCEDURE TrackLink (f : TextFrames.Frame; VAR x, y : INTEGER; VAR e : LinkElem; VAR keysum : SET);  *) PROCEDURE ReplaceRect (f : TextFrames.Frame; x, y, w, h : INTEGER; map : Bitmaps.Bitmap; draw : BOOLEAN);  PROCEDURE TrackLink (f : TextFrames.Frame; VAR x, y : INTEGER; VAR e : LinkElem; VAR keysum : SET);  PROCEDURE FrameHandle (f : Display.Frame; VAR m : Display.FrameMsg);  PROCEDURE InitIcons;  PROCEDURE LoadDefaultPicture;  PROCEDURE SetInfoFont;  BEGIN  END WebElems.