123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008 |
- MODULE WebBrowserPanel; (** AUTHOR "Simon L. Keel"; PURPOSE "components for loading and displaying web-pages"; *)
- IMPORT
- HTMLScanner, HTMLParser, HTMLTransformer, WebBrowserComponents,
- WMComponents, WMProperties, WMTextView, WMStandardComponents, Texts, WMEvents, TextUtilities,
- Codecs, XML, XMLObjects, Strings, KernelLog, Messages := WMMessages;
- CONST
- verbose = TRUE;
- modeSourceCode = 0;
- modeParsedHtml = 1;
- modeBbtXml = 2;
- modeBbtText = 3;
- outputMode = modeBbtText;
- typePercent = 0;
- typeParts = 1;
- typeFix = 2;
- TYPE
- String = Strings.String;
- VisualComponent = WMComponents.VisualComponent;
- NotifyMsg* = POINTER TO RECORD
- url* : String;
- title* : String;
- loadID* : LONGINT;
- END;
- LoadedMsg* = POINTER TO RECORD
- vc : VisualComponent;
- url : String;
- title : String;
- END;
- FrameNode = POINTER TO RECORD
- next : FrameNode;
- name : String;
- scrolling : BOOLEAN;
- size : LONGINT;
- relative : BOOLEAN;
- panel : VisualComponent;
- isLast : BOOLEAN;
- END;
- FrameslotNode = POINTER TO RECORD
- next : FrameslotNode;
- size : LONGINT;
- type : LONGINT;
- END;
- FramesetNode = POINTER TO RECORD
- next : FramesetNode;
- frameset : XML.Element;
- src : String;
- name : String;
- scrolling : BOOLEAN;
- END;
- WebPanel* = OBJECT (VisualComponent)
- VAR
- url- : WMProperties.StringProperty;
- notify* : WMEvents.EventListener;
- openNewWindow* : PROCEDURE {DELEGATE} (url : String);
- loadLink* : WMEvents.EventListener;
- vc : VisualComponent;
- loadingText : WebBrowserComponents.ShortText;
- pending : BOOLEAN;
- loadID : LONGINT;
- PROCEDURE &Init*;
- VAR
- s : String;
- BEGIN
- Init^;
- takesFocus.Set(FALSE);
- NEW(url, NIL, Strings.NewString("WebPanel URL"), Strings.NewString("Stores the URL of a WebPanel"));
- s := Strings.NewString(" Loading...");
- NEW(loadingText, s^);
- pending := FALSE;
- END Init;
- PROCEDURE Load*(loadID : LONGINT);
- VAR
- cl : ContentLoader;
- BEGIN (*{EXCLUSIVE} ??*)
- IF ~pending THEN
- pending := TRUE;
- SELF.loadID := loadID;
- IF vc # NIL THEN
- RemoveContent(vc);
- END;
- AddContent(loadingText);
- Reset(SELF, NIL);
- AlignSubComponents();
- Invalidate();
- NEW(cl, SELF);
- END;
- END Load;
- PROCEDURE Loaded(sender, data : ANY);
- VAR
- msg : LoadedMsg;
- notifyMsg : NotifyMsg;
- BEGIN
- IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.Loaded, sender, data)
- ELSE
- RemoveContent(loadingText);
- msg := data(LoadedMsg);
- vc := msg.vc;
- AddContent(vc);
- NEW(notifyMsg);
- notifyMsg.url := msg.url;
- notifyMsg.title := msg.title;
- notifyMsg.loadID := loadID;
- notify(SELF, notifyMsg);
- Reset(SELF, NIL);
- AlignSubComponents();
- Invalidate();
- pending := FALSE;
- END;
- END Loaded;
- PROCEDURE LoadLink(sender, data : ANY);
- VAR
- link, target : String;
- targetLow : String;
- BEGIN
- IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.LoadLink, sender, data)
- ELSE
- DecodeLinkData(data, link, target);
- IF Strings.StartsWith2("#", link^) THEN
- (* TODO: notify WebBrowser.Window about new URL !! *)
- ELSE
- targetLow := Strings.LowerCaseInNew(target^);
- IF (target^ = "") OR (targetLow^ = "_self") OR (targetLow^ = "_top") OR (targetLow^ = "_parent") THEN
- IF loadLink # NIL THEN
- loadLink(SELF, data);
- ELSE
- url.Set(link);
- Load(-1);
- END;
- ELSE
- IF openNewWindow # NIL THEN
- openNewWindow(link);
- END;
- END;
- END;
- END;
- END LoadLink;
- END WebPanel;
- ContentLoader = OBJECT
- VAR
- webPanel : WebPanel;
- msg : LoadedMsg;
- vc : VisualComponent;
- url : String;
- title : String;
- encodedUrl: ARRAY 1024 OF CHAR;
- PROCEDURE &New*(webPanel : WebPanel);
- BEGIN
- SELF.webPanel := webPanel;
- END New;
- BEGIN {ACTIVE}
- NEW(msg);
- msg.url := webPanel.url.Get();
- IF verbose THEN KernelLog.String("ContentLoader: Loading: "); KernelLog.String(msg.url^); KernelLog.Ln; END;
- msg.vc := GetContent(msg.url, msg.title, webPanel.bounds.GetWidth(), webPanel.bounds.GetHeight(), TRUE, webPanel.LoadLink, NIL);
- webPanel.Loaded(SELF, msg);
- IF verbose THEN KernelLog.String("ContentLoader: Loading done."); KernelLog.Ln; END;
- END ContentLoader;
- HTMLPanel = OBJECT (VisualComponent)
- VAR
- rc : WebBrowserComponents.ResourceConnection;
- width : LONGINT;
- height : LONGINT;
- scrollbars : BOOLEAN;
- loadLink : WMEvents.EventListener;
- charset : String;
- frameName : String;
- firstResize : BOOLEAN;
- tv : WMTextView.TextView;
- text : Texts.Text;
- blankText : Texts.Text;
- vScrollbar : WMStandardComponents.Scrollbar;
- hScrollbar : WMStandardComponents.Scrollbar;
- scanner : HTMLScanner.Scanner;
- parser : HTMLParser.Parser;
- transformer : HTMLTransformer.Transformer;
- xmlDoc : XML.Document;
- textWriter : TextUtilities.TextWriter;
- bgImage : WebBrowserComponents.TileImagePanel;
- decoder : Codecs.TextDecoder;
- bbtDecoder : TextUtilities.BluebottleDecoder;
- encoder : Codecs.TextEncoder;
- res : WORD;
- contents: XMLObjects.Enumerator;
- content: ANY;
- framesetElem : XML.Element;
- frameset : FramesetPanel;
- titleElem : XML.Element;
- item : HTMLTransformer.EmbeddedObject;
- PROCEDURE &New*(VAR title : String; rc :WebBrowserComponents.ResourceConnection; width : LONGINT; height : LONGINT; scrollbars : BOOLEAN; loadLink : WMEvents.EventListener; charset : String; frameName : String);
- VAR
- sharpPos : SIZE;
- wrp : WMTextView.LinkWrapper;
- sequencer : Messages.MsgSequencer;
- BEGIN
- Init;
- NEW(sequencer, Handle);
- SetSequencer(sequencer);
- takesFocus.Set(FALSE);
- SELF.rc := rc;
- SELF.width := width;
- SELF.height := height;
- SELF.scrollbars := scrollbars;
- SELF.loadLink := loadLink;
- SELF.charset := charset;
- SELF.frameName := frameName;
- alignment.Set(WMComponents.AlignClient);
- firstResize := TRUE;
- Load(title);
- (* doesn't work... *)
- sharpPos := Strings.LastIndexOfByte2("#", rc.url^);
- IF sharpPos # -1 THEN
- NEW(wrp);
- wrp.link := Strings.Substring2(sharpPos, rc.url^);
- tv.LinkClicked(SELF, wrp);
- END;
- END New;
- PROCEDURE Load(VAR title : String);
- BEGIN
- IF verbose THEN KernelLog.String("---Loading HTMLPanel. Url: "); KernelLog.String(rc.url^); KernelLog.Ln(); END;
- IF outputMode = modeSourceCode THEN
- decoder := Codecs.GetTextDecoder("ISO8859-1");
- decoder.Open(rc.reader, res);
- NEW(text);
- NEW(textWriter, text);
- encoder := Codecs.GetTextEncoder("UTF-8");
- encoder.Open(textWriter);
- encoder.WriteText(decoder.GetText(), res);
- textWriter.Update;
- (* Show *)
- NEW(vScrollbar);
- vScrollbar.alignment.Set(WMComponents.AlignRight);
- AddContent(vScrollbar);
- NEW(hScrollbar);
- hScrollbar.alignment.Set(WMComponents.AlignBottom);
- hScrollbar.vertical.Set(FALSE);
- AddContent(hScrollbar);
- NEW(tv);
- tv.alignment.Set(WMComponents.AlignClient);
- AddContent(tv);
- tv.SetScrollbars(hScrollbar, vScrollbar);
- tv.SetText(text);
- tv.firstLine.Set(0);
- ELSIF outputMode = modeParsedHtml THEN
- (* Parse the page *)
- NEW(scanner, rc.reader);
- NEW(parser, scanner);
- IF verbose THEN KernelLog.String("-Parsing "); KernelLog.String(rc.url^); KernelLog.Ln(); END;
- xmlDoc := parser.Parse();
- IF verbose THEN KernelLog.String("-Parsing done."); KernelLog.Ln(); END;
- NEW(text);
- NEW(textWriter, text);
- xmlDoc.Write(textWriter, NIL, 0);
- textWriter.Update;
- (* Show *)
- NEW(vScrollbar);
- vScrollbar.alignment.Set(WMComponents.AlignRight);
- AddContent(vScrollbar);
- NEW(hScrollbar);
- hScrollbar.alignment.Set(WMComponents.AlignBottom);
- hScrollbar.vertical.Set(FALSE);
- AddContent(hScrollbar);
- NEW(tv);
- tv.alignment.Set(WMComponents.AlignClient);
- AddContent(tv);
- tv.SetScrollbars(hScrollbar, vScrollbar);
- tv.SetText(text);
- tv.firstLine.Set(0);
- ELSIF outputMode = modeBbtXml THEN
- (* Parse the page *)
- NEW(scanner, rc.reader);
- NEW(parser, scanner);
- IF verbose THEN KernelLog.String("--Parsing "); KernelLog.String(rc.url^); KernelLog.Ln(); END;
- xmlDoc := parser.Parse();
- IF verbose THEN KernelLog.String("--Parsing done."); KernelLog.Ln(); END;
- (* Transform the document *)
- NEW(transformer, xmlDoc, rc.url, width, NIL, charset, NIL);
- xmlDoc := transformer.Transform();
- NEW(text);
- NEW(textWriter, text);
- xmlDoc.Write(textWriter, NIL, 0);
- textWriter.Update;
- (* Show *)
- NEW(vScrollbar);
- vScrollbar.alignment.Set(WMComponents.AlignRight);
- AddContent(vScrollbar);
- NEW(hScrollbar);
- hScrollbar.alignment.Set(WMComponents.AlignBottom);
- hScrollbar.vertical.Set(FALSE);
- AddContent(hScrollbar);
- NEW(tv);
- tv.alignment.Set(WMComponents.AlignClient);
- AddContent(tv);
- tv.SetScrollbars(hScrollbar, vScrollbar);
- tv.SetText(text);
- tv.firstLine.Set(0);
- ELSE (* outputMode = modeBbtText *)
- (* Parse the page *)
- NEW(scanner, rc.reader);
- NEW(parser, scanner);
- IF verbose THEN KernelLog.String("---Parsing "); KernelLog.String(rc.url^); KernelLog.Ln(); END;
- xmlDoc := parser.Parse();
- IF verbose THEN KernelLog.String("---Parsing done."); KernelLog.Ln(); END;
- (* Check for FRAMESET *)
- contents := xmlDoc.GetContents();
- WHILE contents.HasMoreElements() & (framesetElem = NIL) DO
- content := contents.GetNext();
- IF content IS XML.Element THEN
- framesetElem := GetElement("FRAMESET", content(XML.Element));
- END;
- END;
- IF framesetElem = NIL THEN
- (* Transform the document *)
- NEW(transformer, xmlDoc, rc.url, width, loadLink, charset, frameName);
- xmlDoc := transformer.Transform();
- title := transformer.title;
- fillColor.Set(transformer.pageBgColor * 0100H + 0FFH);
- IF transformer.bgImage # NIL THEN
- NEW(bgImage, NIL, transformer.bgImage);
- AddContent(bgImage);
- END;
- NEW(bbtDecoder);
- bbtDecoder.OpenXML(xmlDoc);
- text := bbtDecoder.GetText();
- (* Show *)
- NEW(tv);
- tv.alignment.Set(WMComponents.AlignClient);
- tv.onLinkClicked.Add(loadLink);
- IF scrollbars THEN
- NEW(vScrollbar);
- vScrollbar.alignment.Set(WMComponents.AlignRight);
- AddContent(vScrollbar);
- NEW(hScrollbar);
- hScrollbar.alignment.Set(WMComponents.AlignBottom);
- hScrollbar.vertical.Set(FALSE);
- AddContent(hScrollbar);
- tv.SetScrollbars(hScrollbar, vScrollbar);
- END;
- AddContent(tv);
- tv.SetText(text);
- tv.firstLine.Set(0);
- ELSE
- NEW(frameset, framesetElem, rc.url, width, height, loadLink);
- AddContent(frameset);
- contents := xmlDoc.GetContents();
- WHILE contents.HasMoreElements() & (titleElem = NIL) DO
- content := contents.GetNext();
- IF content IS XML.Element THEN
- titleElem := GetElement("TITLE", content(XML.Element));
- END;
- END;
- IF titleElem # NIL THEN
- title := NIL;
- contents := titleElem.GetContents();
- WHILE contents.HasMoreElements() & (title = NIL) DO
- content := contents.GetNext();
- IF content IS XML.ArrayChars THEN
- title := content(XML.ArrayChars).GetStr();
- Strings.TrimWS(title^);
- title := HTMLTransformer.TransformCharEnt(title);
- END;
- END;
- END;
- END;
- END;
- rc.Release();
- END Load;
- PROCEDURE Resized*;
- VAR
- item : HTMLTransformer.EmbeddedObject;
- width : LONGINT;
- BEGIN
- Resized^;
- (* ignore first resize, because webPanel is not drawn for the first time yet! *)
- IF firstResize THEN firstResize := FALSE; RETURN END;
- IF transformer # NIL THEN
- width := bounds.GetWidth();
- item := transformer.embeddedObjectsList;
- WHILE item # NIL DO
- IF item.object IS WebBrowserComponents.HR THEN
- item.object(WebBrowserComponents.HR).ParentTvWidthChanged(width);
- ELSIF item.object IS HTMLTransformer.Table THEN
- item.object(HTMLTransformer.Table).ParentTvWidthChanged(width);
- END;
- item := item.prev;
- END;
- IF tv # NIL THEN
- (* Resets the TextView, such that all embedded objects are new aligned! *)
- tv.SetText(text);
- END;
- END;
- END Resized;
- END HTMLPanel;
- FramesetPanel = OBJECT (VisualComponent)
- VAR
- framesetElem : XML.Element;
- baseAddress : String;
- width : LONGINT;
- height : LONGINT;
- loadLink : WMEvents.EventListener;
- frameborderSize : LONGINT;
- totalFixSizes : LONGINT;
- nodeIsCol : BOOLEAN;
- firstFrame : FrameNode;
- PROCEDURE &New*(framesetElem : XML.Element; baseAddress : String; width : LONGINT; height : LONGINT; loadLink : WMEvents.EventListener);
- BEGIN
- Init;
- SELF.framesetElem := framesetElem;
- SELF.baseAddress := baseAddress;
- SELF.width := width;
- SELF.height := height;
- SELF.loadLink := loadLink;
- takesFocus.Set(FALSE);
- alignment.Set(WMComponents.AlignClient);
- BuildFrameList();
- AddFramesToPanel();
- END New;
- PROCEDURE BuildFrameList;
- VAR
- frameItem : FrameNode;
- framesetItem : FramesetNode;
- url, dummyTitle : String;
- frameSlots : FrameslotNode;
- framesets : FramesetNode;
- slotItem : FrameslotNode;
- framesetPanel : FramesetPanel;
- fWidth, fHeight : LONGINT;
- lastFrame : FrameNode;
- BEGIN
- ParseFramesetAttr(framesetElem, frameSlots, frameborderSize, totalFixSizes, nodeIsCol);
- ParseFramesetContent(framesetElem, framesets);
- (* add frames and framesets to frame-list *)
- framesetItem := framesets;
- slotItem := frameSlots;
- WHILE (slotItem # NIL) & (framesetItem # NIL) DO
- NEW(frameItem);
- frameItem.name := framesetItem.name;
- frameItem.scrolling := framesetItem.scrolling;
- frameItem.size := slotItem.size;
- IF slotItem.type = typeFix THEN
- frameItem.relative := FALSE;
- ELSE
- frameItem.relative := TRUE;
- END;
- fWidth := GetFrameWidth(frameItem);
- fHeight := GetFrameHeight(frameItem);
- (* new frame or frameset *)
- IF framesetItem.frameset # NIL THEN
- NEW(framesetPanel, framesetItem.frameset, baseAddress, fWidth, fHeight, LoadLink);
- frameItem.panel := framesetPanel;
- ELSE
- IF (frameItem.name = NIL) OR (frameItem.name^ = "") THEN
- frameItem.name := GetNewFrameName();
- END;
- url := HTMLTransformer.ResolveAddress(baseAddress, framesetItem.src);
- frameItem.panel := GetContent(url, dummyTitle, fWidth, fHeight, frameItem.scrolling, LoadLink, frameItem.name);
- END;
- frameItem.isLast := FALSE;
- IF lastFrame # NIL THEN
- lastFrame.next := frameItem;
- ELSE
- firstFrame := frameItem;
- END;
- lastFrame := frameItem;
- slotItem := slotItem.next;
- framesetItem := framesetItem.next;
- END;
- IF lastFrame # NIL THEN
- lastFrame.isLast := TRUE;
- END;
- (* set frame alignment *)
- frameItem := firstFrame;
- WHILE frameItem # NIL DO
- AlignFrame(frameItem);
- frameItem := frameItem.next;
- END;
- END BuildFrameList;
- PROCEDURE GetFrameWidth(frameItem : FrameNode) : LONGINT;
- VAR
- fWidth : LONGINT;
- BEGIN
- (* calculate frame-width *)
- IF nodeIsCol THEN
- IF frameItem.relative THEN
- fWidth := ENTIER((width-totalFixSizes) / 100 * frameItem.size) - frameborderSize;
- ELSE
- fWidth := frameItem.size - frameborderSize;
- END;
- ELSE
- fWidth := width;
- END;
- IF fWidth < 1 THEN fWidth := 1 END;
- RETURN fWidth;
- END GetFrameWidth;
- PROCEDURE GetFrameHeight(frameItem : FrameNode) : LONGINT;
- VAR
- fHeight : LONGINT;
- BEGIN
- (* calculate frame-height *)
- IF ~nodeIsCol THEN
- IF frameItem.relative THEN
- fHeight := ENTIER((height-totalFixSizes) / 100 * frameItem.size) - frameborderSize;
- ELSE
- fHeight := frameItem.size - frameborderSize;
- END;
- ELSE
- fHeight := height;
- END;
- IF fHeight < 1 THEN fHeight := 1 END;
- RETURN fHeight;
- END GetFrameHeight;
- PROCEDURE AlignFrame(frameItem : FrameNode);
- VAR
- resizer: WMStandardComponents.Resizer;
- BEGIN
- IF ~frameItem.isLast THEN
- (* add resizer and set its width *)
- NEW(resizer);
- frameItem.panel.AddContent(resizer);
- IF nodeIsCol THEN
- resizer.alignment.Set(WMComponents.AlignRight);
- resizer.bounds.SetWidth(frameborderSize);
- ELSE
- resizer.alignment.Set(WMComponents.AlignBottom);
- resizer.bounds.SetHeight(frameborderSize);
- END;
- (* set frame alignment *)
- IF nodeIsCol THEN
- frameItem.panel.alignment.Set(WMComponents.AlignLeft);
- ELSE
- frameItem.panel.alignment.Set(WMComponents.AlignTop);
- END;
- ELSE
- (* set frame alignment for last frame*)
- frameItem.panel.alignment.Set(WMComponents.AlignClient);
- END;
- END AlignFrame;
- PROCEDURE Resize;
- VAR
- frameItem : FrameNode;
- BEGIN
- frameItem := firstFrame;
- WHILE frameItem # NIL DO
- IF nodeIsCol THEN
- IF frameItem.relative THEN
- frameItem.panel.bounds.SetWidth(ENTIER((width-totalFixSizes) / 100 * frameItem.size));
- ELSE
- frameItem.panel.bounds.SetWidth(frameItem.size);
- END;
- ELSE
- IF frameItem.relative THEN
- frameItem.panel.bounds.SetHeight(ENTIER((height-totalFixSizes) / 100 * frameItem.size));
- ELSE
- frameItem.panel.bounds.SetHeight(frameItem.size);
- END;
- END;
- frameItem := frameItem.next;
- END;
- END Resize;
- PROCEDURE Resized*;
- BEGIN
- width := bounds.GetWidth();
- height := bounds.GetHeight();
- Resize;
- Resized^;
- END Resized;
- PROCEDURE RemoveFramesFromPanel;
- VAR
- frameItem : FrameNode;
- BEGIN
- frameItem := firstFrame;
- WHILE frameItem # NIL DO
- RemoveContent(frameItem.panel);
- frameItem := frameItem.next;
- END;
- END RemoveFramesFromPanel;
- PROCEDURE AddFramesToPanel;
- VAR
- frameItem : FrameNode;
- BEGIN
- frameItem := firstFrame;
- WHILE frameItem # NIL DO
- AddContent(frameItem.panel);
- frameItem := frameItem.next;
- END;
- Resize();
- END AddFramesToPanel;
- PROCEDURE LoadLink(sender, data : ANY);
- VAR
- link, target, targetLow : String;
- BEGIN
- IF ~IsCallFromSequencer() THEN sequencer.ScheduleEvent(SELF.LoadLink, sender, data)
- ELSE
- DecodeLinkData(data, link, target);
- IF ~Strings.StartsWith2("#", link^) THEN
- targetLow := Strings.LowerCaseInNew(target^);
- IF (targetLow^ = "_parent") OR (targetLow^ = "_top") OR (targetLow^ = "_blank") THEN
- loadLink(NIL, data);
- ELSIF ~FindAndReloadFrame(link, target) THEN
- loadLink(NIL, data);
- END;
- END;
- END;
- END LoadLink;
- PROCEDURE FindAndReloadFrame(link, target : String) : BOOLEAN;
- VAR
- frameItem : FrameNode;
- framesetPanel : FramesetPanel;
- targetLow : String;
- url, dummyTitle : String;
- fWidth, fHeight : LONGINT;
- BEGIN
- frameItem := firstFrame;
- WHILE frameItem # NIL DO
- IF frameItem.name = NIL THEN
- (* frameItem is a frameset *)
- framesetPanel := frameItem.panel(FramesetPanel);
- IF framesetPanel.FindAndReloadFrame(link, target) THEN
- RETURN TRUE;
- END;
- ELSE
- (* frameItem is a frame *)
- targetLow := Strings.LowerCaseInNew(target^);
- IF (target^ = frameItem.name^) OR (targetLow^ = "_self") THEN
- RemoveFramesFromPanel();
- fWidth := GetFrameWidth(frameItem);
- fHeight := GetFrameHeight(frameItem);
- url := HTMLTransformer.ResolveAddress(baseAddress, link);
- frameItem.panel := GetContent(url, dummyTitle, fWidth, fHeight, frameItem.scrolling, LoadLink, frameItem.name);
- AlignFrame(frameItem);
- AddFramesToPanel;
- Reset(SELF, NIL);
- AlignSubComponents();
- Invalidate();
- RETURN TRUE;
- END;
- END;
- frameItem := frameItem.next;
- END;
- RETURN FALSE;
- END FindAndReloadFrame;
- END FramesetPanel;
- VAR
- frameNameCount : LONGINT;
- PROCEDURE GetContent(VAR url : String; VAR title : String; initWidth : LONGINT; initHeight : LONGINT; scrollbars : BOOLEAN; loadLink : WMEvents.EventListener; frameName : String) : VisualComponent;
- VAR
- rc : WebBrowserComponents.ResourceConnection;
- panel : VisualComponent;
- errorText : WebBrowserComponents.ShortText;
- image : WebBrowserComponents.StretchImagePanel;
- htmlPanel : HTMLPanel;
- textPanel : WebBrowserComponents.TextPanel;
- s : String;
- charset : String;
- charsetPos : SIZE;
- BEGIN
- rc := WebBrowserComponents.GetResourceConnection(url);
- IF rc = NIL THEN
- IF verbose THEN KernelLog.String("Not found: "); KernelLog.String(url^); KernelLog.Ln; END;
- s := Strings.ConcatToNew(" Not found: ", url^);
- NEW(errorText, s^);
- panel := errorText;
- ELSE
- url := rc.url;
- IF Strings.StartsWith2("text/html", rc.mimeType^) OR (rc.mimeType^ = "") THEN
- s := Strings.LowerCaseInNew(rc.mimeType^);
- IF Strings.Pos("charset", s^) >= 0 THEN
- charsetPos := Strings.IndexOfByte('=', charsetPos, rc.mimeType^) + 1;
- IF (charsetPos >= 0) & (charsetPos < Strings.Length(rc.mimeType^)) THEN
- charset := Strings.Substring2(charsetPos, rc.mimeType^);
- Strings.TrimWS(charset^);
- END;
- END;
- NEW(htmlPanel, title, rc, initWidth, initHeight, scrollbars, loadLink, charset, frameName);
- panel := htmlPanel;
- ELSIF Strings.StartsWith2("text/plain", rc.mimeType^) OR Strings.StartsWith2("application/xml", rc.mimeType^) THEN
- NEW(textPanel, rc, NIL);
- panel := textPanel;
- ELSIF Strings.StartsWith2("image/", rc.mimeType^) THEN
- NEW(image, rc, NIL, -1, -1);
- panel := image;
- ELSE
- IF verbose THEN KernelLog.String("Unknown content type: "); KernelLog.String(rc.mimeType^); KernelLog.Ln; END;
- s := Strings.ConcatToNew(" Unknown content type: ", rc.mimeType^);
- NEW(errorText, s^);
- panel := errorText;
- rc.Stop();
- rc.Release();
- END;
- END;
- RETURN panel;
- END GetContent;
- PROCEDURE DecodeLinkData*(data : ANY; VAR link : String; VAR target : String);
- VAR
- linkValue : String;
- urlPos, len : SIZE;
- BEGIN
- linkValue := data(WMTextView.LinkWrapper).link;
- IF Strings.StartsWith2("#", linkValue^) THEN
- link := linkValue;
- target := Strings.NewString("_self");
- ELSE
- urlPos := Strings.Pos(";url=", linkValue^);
- target := Strings.Substring(7, urlPos, linkValue^);
- len := Strings.Length(linkValue^);
- IF len > (urlPos + 5) THEN
- link := Strings.Substring(urlPos + 5, len, linkValue^);
- ELSE
- link := Strings.NewString("");
- END;
- END;
- END DecodeLinkData;
- PROCEDURE GetElement(name : ARRAY OF CHAR; root : XML.Element) : XML.Element;
- VAR
- rootName : String;
- contents: XMLObjects.Enumerator;
- content: ANY;
- retElement: XML.Element;
- BEGIN
- IF root = NIL THEN RETURN NIL; END;
- rootName := root.GetName();
- IF rootName^ = name THEN RETURN root; END;
- contents := root.GetContents();
- WHILE contents.HasMoreElements() & (retElement = NIL) DO
- content := contents.GetNext();
- IF content IS XML.Element THEN
- retElement := GetElement(name, content(XML.Element));
- END;
- END;
- RETURN retElement;
- END GetElement;
- PROCEDURE ParseFramesetAttr(frameset : XML.Element; VAR frameSlots : FrameslotNode; VAR frameborderSize : LONGINT; VAR fixSizes : LONGINT; VAR nodeIsCol : BOOLEAN);
- VAR
- s : String;
- rowsNode : FrameslotNode;
- colsNode : FrameslotNode;
- rowsCount : LONGINT;
- colsCount : LONGINT;
- rowsfixSizes : LONGINT;
- colsfixSizes : LONGINT;
- BEGIN
- rowsCount := 0;
- colsCount := 0;
- s := HTMLTransformer.GetElemAttributeValue(frameset, "rows", FALSE);
- IF s # NIL THEN
- ParseFramesetRowsOrCols(s, rowsNode, rowsCount, rowsfixSizes);
- END;
- s := HTMLTransformer.GetElemAttributeValue(frameset, "cols", FALSE);
- IF s # NIL THEN
- ParseFramesetRowsOrCols(s, colsNode, colsCount, colsfixSizes);
- END;
- IF (rowsCount = 0) & (colsCount = 0) THEN
- NEW(frameSlots);
- fixSizes := 0;
- nodeIsCol := FALSE;
- frameSlots.size := 100;
- frameSlots.type := typePercent;
- ELSIF rowsCount >= colsCount THEN
- frameSlots := rowsNode;
- fixSizes := rowsfixSizes;
- nodeIsCol := FALSE;
- ELSE
- frameSlots := colsNode;
- fixSizes := colsfixSizes;
- nodeIsCol := TRUE;
- END;
- (* frameborder-width *)
- frameborderSize := 6;
- s := HTMLTransformer.GetElemAttributeValue(frameset, "frameborder", FALSE);
- IF s # NIL THEN
- Strings.TrimWS(s^);
- Strings.StrToInt(s^, frameborderSize);
- ELSE
- s := HTMLTransformer.GetElemAttributeValue(frameset, "border", FALSE);
- IF s # NIL THEN
- Strings.TrimWS(s^);
- Strings.StrToInt(s^, frameborderSize);
- END;
- END;
- END ParseFramesetAttr;
- PROCEDURE ParseFramesetRowsOrCols(attrValue : String; VAR firstSlot : FrameslotNode; VAR nodeCount : LONGINT; VAR fixSizes : LONGINT);
- VAR
- start : SIZE;
- comma : SIZE;
- s : String;
- sizeStr : String;
- size : LONGINT;
- type : LONGINT;
- slotItem : FrameslotNode;
- lastSlot : FrameslotNode;
- prevSlot : FrameslotNode;
- percents : LONGINT;
- parts : LONGINT;
- factor : REAL;
- onePart : LONGINT;
- BEGIN
- percents := 0;
- parts := 0;
- fixSizes := 0;
- firstSlot := NIL;
- start := 0;
- REPEAT
- comma := Strings.IndexOfByte(',', start, attrValue^);
- IF comma = -1 THEN
- s := Strings.Substring2(start, attrValue^);
- ELSE
- s := Strings.Substring(start, comma, attrValue^);
- start := comma+1;
- END;
- Strings.TrimWS(s^);
- IF Strings.EndsWith("%", s^) THEN
- sizeStr := Strings.Substring(0, Strings.Length(s^)-1, s^);
- Strings.StrToInt(sizeStr^, size);
- type := typePercent;
- ELSIF Strings.EndsWith("*", s^) THEN
- IF Strings.Length(s^) = 1 THEN
- size := 1;
- ELSE
- sizeStr := Strings.Substring(0, Strings.Length(s^)-1, s^);
- Strings.TrimWS(sizeStr^);
- Strings.StrToInt(sizeStr^, size);
- END;
- type := typeParts;
- ELSE
- Strings.StrToInt(s^, size);
- type := typeFix;
- END;
- IF size > 0 THEN
- NEW(slotItem);
- slotItem.size := size;
- slotItem.type := type;
- IF type = typePercent THEN
- percents := percents + size;
- ELSIF type = typeParts THEN
- parts := parts + size;
- ELSE
- fixSizes := fixSizes + size;
- END;
- IF lastSlot # NIL THEN
- lastSlot.next := slotItem;
- lastSlot := slotItem;
- ELSE
- firstSlot := slotItem;
- lastSlot := slotItem;
- END;
- END;
- UNTIL comma = -1;
- IF (percents > 100) OR (parts = 0) THEN
- IF percents > 0 THEN
- factor := 100 / percents;
- END;
- onePart := 0;
- ELSE
- factor := 1;
- onePart := ENTIER((100 - percents) / parts);
- END;
- nodeCount := 0;
- slotItem := firstSlot;
- prevSlot := NIL;
- WHILE slotItem # NIL DO
- IF slotItem.type = typePercent THEN
- slotItem.size := ENTIER(slotItem.size * factor);
- ELSIF slotItem.type = typeParts THEN
- slotItem.size := slotItem.size * onePart;
- END;
- IF slotItem.size = 0 THEN
- IF prevSlot # NIL THEN
- prevSlot.next := slotItem.next;
- ELSE
- (* prevSlot remains NIL *)
- firstSlot := slotItem.next;
- END;
- ELSE
- INC(nodeCount);
- prevSlot := slotItem;
- END;
- slotItem := slotItem.next;
- END;
- END ParseFramesetRowsOrCols;
- PROCEDURE ParseFramesetContent(frameset : XML.Element; VAR first : FramesetNode);
- VAR
- last : FramesetNode;
- node : FramesetNode;
- enum : XMLObjects.Enumerator;
- p : ANY;
- frame : XML.Element;
- name : String;
- s : String;
- BEGIN
- first := NIL;
- last := NIL;
- enum := frameset.GetContents();
- WHILE enum.HasMoreElements() DO
- p := enum.GetNext();
- IF p IS XML.Element THEN
- frame := p(XML.Element);
- name := frame.GetName();
- IF name^ = "FRAMESET" THEN
- NEW(node);
- node.frameset := frame;
- IF last # NIL THEN
- last.next := node;
- last := node;
- ELSE
- first := node;
- last := node;
- END;
- ELSIF name^ = "FRAME" THEN
- s := HTMLTransformer.GetElemAttributeValue(frame, "src", FALSE);
- IF s # NIL THEN
- Strings.TrimWS(s^);
- IF s^ # "" THEN
- NEW(node);
- node.src := s;
- s := HTMLTransformer.GetElemAttributeValue(frame, "name", FALSE);
- IF s # NIL THEN
- Strings.TrimWS(s^);
- node.name := s;
- END;
- node.scrolling := TRUE;
- s := HTMLTransformer.GetElemAttributeValue(frame, "scrolling", TRUE);
- IF s # NIL THEN
- Strings.TrimWS(s^);
- IF s^ = "no" THEN
- node.scrolling := FALSE;
- END;
- END;
- IF last # NIL THEN
- last.next := node;
- last := node;
- ELSE
- first := node;
- last := node;
- END;
- END;
- END;
- END;
- END;
- END;
- END ParseFramesetContent;
- PROCEDURE GetNewFrameName() : String;
- VAR
- id : ARRAY 28 OF CHAR;
- nr : ARRAY 8 OF CHAR;
- BEGIN {EXCLUSIVE}
- id := "BimBrowser-Frame-ID-";
- Strings.IntToStr(frameNameCount, nr);
- Strings.Append(id, nr);
- INC(frameNameCount);
- RETURN Strings.NewString(id);
- END GetNewFrameName;
- BEGIN
- frameNameCount := 0;
- END WebBrowserPanel.
|