MODULE WebBrowser; (** AUTHOR "Simon L. Keel"; PURPOSE "Simple Web Browser GUI"; *) IMPORT WebBrowserPanel, Strings, KernelLog, WMGraphics, WMComponents, WMStandardComponents, WMWindowManager, WMEditors, Modules, WMRestorable, XML, WMRectangles, WMMessages, Commands, Files; CONST HomePage = "http://bluebottle.ethz.ch"; BrowserTitle = "BimBrowser"; BookmarkPage = "file://bookmarks.html"; (* This URL is loaded when pressing the "Bookmarks"-button *) BookmarkFile = "bookmarks.html"; (* New bookmarks are appended to this file *) loadingNew = 0; loadingOld = 1; loadingNone = 2; TYPE String = Strings.String; URLNode = POINTER TO RECORD url, title : String; back, forward : URLNode; END; KillerMsg = OBJECT END KillerMsg; Window* = OBJECT (WMComponents.FormWindow) VAR webPanel : WebBrowserPanel.WebPanel; topToolbar : WMStandardComponents.Panel; urlEdit : WMEditors.Editor; back, forward, reload, home, bookm, addBM, go : WMStandardComponents.Button; loadID : LONGINT; actualURL : URLNode; PROCEDURE CreateForm() : WMComponents.VisualComponent; VAR panel : WMStandardComponents.Panel; BEGIN NEW(topToolbar); topToolbar.bounds.SetHeight(20); topToolbar.alignment.Set(WMComponents.AlignTop); NEW(panel); panel.bounds.SetExtents(1000, 650); panel.fillColor.Set(0FFFFFFFFH); panel.takesFocus.Set(TRUE); NEW(topToolbar); topToolbar.bounds.SetHeight(20); topToolbar.alignment.Set(WMComponents.AlignTop); panel.AddContent(topToolbar); NEW(back); back.caption.SetAOC("Back"); back.alignment.Set(WMComponents.AlignLeft); back.onClick.Add(Back); topToolbar.AddContent(back); NEW(forward); forward.caption.SetAOC("Forward"); forward.alignment.Set(WMComponents.AlignLeft); forward.onClick.Add(Forward); topToolbar.AddContent(forward); NEW(reload); reload.caption.SetAOC("Reload"); reload.alignment.Set(WMComponents.AlignLeft); reload.onClick.Add(Reload); topToolbar.AddContent(reload); NEW(home); home.caption.SetAOC("Home"); home.alignment.Set(WMComponents.AlignLeft); home.onClick.Add(Home); topToolbar.AddContent(home); NEW(bookm); bookm.caption.SetAOC("Bookmarks"); bookm.alignment.Set(WMComponents.AlignLeft); bookm.bounds.SetWidth(77); bookm.onClick.Add(Bookmarks); topToolbar.AddContent(bookm); NEW(addBM); addBM.caption.SetAOC("Add Bookmark"); addBM.alignment.Set(WMComponents.AlignLeft); addBM.bounds.SetWidth(97); addBM.onClick.Add(AddBookmark); topToolbar.AddContent(addBM); NEW(go); go.caption.SetAOC("Go"); go.alignment.Set(WMComponents.AlignRight); go.onClick.Add(Go); topToolbar.AddContent(go); NEW(urlEdit); urlEdit.alignment.Set(WMComponents.AlignClient); urlEdit.tv.textAlignV.Set(WMGraphics.AlignCenter); urlEdit.multiLine.Set(FALSE); urlEdit.bounds.SetWidth(500); topToolbar.AddContent(urlEdit); urlEdit.fillColor.Set(0FFFFFFFFH); urlEdit.tv.showBorder.Set(TRUE); urlEdit.tv.borders.Set(WMRectangles.MakeRect(3,3,1,1)); urlEdit.onEnter.Add(Go); NEW(webPanel); webPanel.alignment.Set(WMComponents.AlignClient); panel.AddContent(webPanel); webPanel.notify := Notify; webPanel.openNewWindow := OpenLinkFromString; webPanel.loadLink := LoadExternal; RETURN panel END CreateForm; PROCEDURE &New*(c : WMRestorable.Context; url : String); VAR vc : WMComponents.VisualComponent; xml : XML.Element; m : WMWindowManager.WindowManager; indent : LONGINT; BEGIN IncCount; loadID := 0; vc := CreateForm(); Init(vc.bounds.GetWidth(), vc.bounds.GetHeight(), FALSE); SetContent(vc); SetIcon(WMGraphics.LoadImage("WMIcons.tar://WebBrowser.png", TRUE)); IF c # NIL THEN (* restore the desktop *) WMRestorable.AddByContext(SELF, c); IF c.appData # NIL THEN xml := c.appData(XML.Element); url := xml.GetAttributeValue("url"); Resized(GetWidth(), GetHeight()) END ELSE WMWindowManager.DefaultAddWindow(SELF); indent := leftW.bounds.r; IF topW.bounds.b > indent THEN indent := topW.bounds.b; END; m := GetManager(); m.SetWindowPos(SELF, (nofWindows-1) * indent + leftW.bounds.r, (nofWindows-1) * indent + topW.bounds.b); END; IF url = NIL THEN url := Strings.NewString(HomePage); END; NEW(actualURL); actualURL.url := Strings.NewString(url^); Load(); END New; PROCEDURE Load; VAR s : String; BEGIN urlEdit.SetAsString(actualURL.url^); IF actualURL.title = NIL THEN SetTitle(Strings.NewString(BrowserTitle)); ELSE s := Strings.ConcatToNew(actualURL.title^, " - "); s := Strings.ConcatToNew(s^, BrowserTitle); SetTitle(s); END; webPanel.url.Set(actualURL.url); webPanel.Load(loadID); loadID := (loadID + 1) MOD (MAX(LONGINT)); END Load; PROCEDURE Go(sender, data : ANY); VAR urlNode : URLNode; urlAOC : ARRAY 1024 OF CHAR; i: SIZE; BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Go, sender, data) ELSE NEW(urlNode); urlEdit.GetAsString(urlAOC); i := Strings.Pos("://", urlAOC); IF i = -1 THEN urlNode.url := Strings.ConcatToNew("http://", urlAOC); ELSE urlNode.url := Strings.NewString(urlAOC); END; actualURL.forward := urlNode; urlNode.back := actualURL; actualURL := urlNode; Load(); END; END Go; PROCEDURE Back(sender, data : ANY); BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Back, sender, data) ELSE IF actualURL.back # NIL THEN actualURL := actualURL.back; Load(); END; END; END Back; PROCEDURE Forward(sender, data : ANY); BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Forward, sender, data) ELSE IF actualURL.forward # NIL THEN actualURL := actualURL.forward; Load(); END; END; END Forward; PROCEDURE Reload(sender, data : ANY); BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Reload, sender, data) ELSE Load(); END; END Reload; PROCEDURE Home(sender, data : ANY); VAR urlNode : URLNode; BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Home, sender, data) ELSE NEW(urlNode); urlNode.url := Strings.NewString(HomePage); actualURL.forward := urlNode; urlNode.back := actualURL; actualURL := urlNode; Load(); END; END Home; PROCEDURE Bookmarks(sender, data : ANY); VAR urlNode : URLNode; BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Bookmarks, sender, data) ELSE NEW(urlNode); urlNode.url := Strings.NewString(BookmarkPage); actualURL.forward := urlNode; urlNode.back := actualURL; actualURL := urlNode; Load(); END; END Bookmarks; PROCEDURE LoadExternal*(sender, data : ANY); VAR link, target : String; urlNode : URLNode; BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.LoadExternal, sender, data) ELSE WebBrowserPanel.DecodeLinkData(data, link, target); NEW(urlNode); urlNode.url := Strings.NewString(link^); actualURL.forward := urlNode; urlNode.back := actualURL; actualURL := urlNode; Load(); END; END LoadExternal; PROCEDURE Notify(sender, data : ANY); VAR msg : WebBrowserPanel.NotifyMsg; s : String; BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Notify, sender, data) ELSE IF loadID # SELF.loadID THEN RETURN END; msg := data(WebBrowserPanel.NotifyMsg); IF msg.url # NIL THEN actualURL.url := Strings.NewString(msg.url^); urlEdit.SetAsString(actualURL.url^); END; IF (msg.title # NIL) & (msg.title^ # "") THEN actualURL.title := Strings.NewString(msg.title^); s := Strings.ConcatToNew(actualURL.title^, " - "); s := Strings.ConcatToNew(s^, BrowserTitle); SetTitle(s); END; END; END Notify; PROCEDURE AddBookmark(sender, data : ANY); BEGIN IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.AddBookmark, sender, data) ELSE IF actualURL.title # NIL THEN AddBookmarkToFile(actualURL.url^, actualURL.title^); ELSE AddBookmarkToFile(actualURL.url^, actualURL.url^); END; END; END AddBookmark; PROCEDURE Close*; BEGIN webPanel.notify := NIL; webPanel.openNewWindow := NIL; webPanel.loadLink := NIL; Close^; DecCount END Close; PROCEDURE Handle*(VAR x: WMMessages.Message); VAR data : XML.Element; a : XML.Attribute; n : ARRAY 16 OF CHAR; BEGIN IF (x.msgType = WMMessages.MsgExt) & (x.ext # NIL) THEN IF (x.ext IS KillerMsg) THEN Close ELSIF (x.ext IS WMRestorable.Storage) THEN NEW(data); n := "WebBrowserData"; data.SetName(n); NEW(a); n := "url"; a.SetName(n); a.SetValue(actualURL.url^); data.AddAttribute(a); x.ext(WMRestorable.Storage).Add("WebBrowser", "WebBrowser.Restore", SELF, data) ELSE Handle^(x) END ELSE Handle^(x) END END Handle; END Window; VAR nofWindows : LONGINT; PROCEDURE AddBookmarkToFile(CONST link : ARRAY OF CHAR; title : ARRAY OF CHAR); VAR file : Files.File; w : Files.Writer; BEGIN Strings.TrimWS(title); file := Files.Old(BookmarkFile); IF file = NIL THEN file := Files.New(BookmarkFile); IF file = NIL THEN KernelLog.String("Writing "); KernelLog.String(BookmarkFile); KernelLog.String(" failed."); KernelLog.Ln; RETURN; END; Files.OpenWriter(w, file, 0); w.String(''); w.Ln(); w.String("
"); w.Ln(); ELSE Files.OpenWriter(w, file, file.Length()); END; w.String('