lazarus-ccr/components/thtmlport/package/frambrwz.pas

3245 lines
94 KiB
ObjectPascal

{Version 9.45}
{*********************************************************}
{* FRAMBRWZ.PAS *}
{*********************************************************}
{
Copyright (c) 1995-2008 by L. David Baldwin
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Note that the source modules, HTMLGIF1.PAS, PNGZLIB1.PAS, DITHERUNIT.PAS, and
URLCON.PAS are covered by separate copyright notices located in those modules.
}
{$i htmlcons.inc}
unit FramBrwz;
interface
uses
SysUtils, Classes,
{$IFNDEF LCL}
WinTypes, WinProcs, Messages,
{$ELSE}
LclIntf, LMessages, Types, LclType, HtmlMisc,
{$ENDIF}
Graphics, Controls,
Forms, Dialogs, StdCtrls, ExtCtrls, Menus,
htmlsubs, htmlview, htmlun2, readHTML, FramView;
type
TGetPostRequestEvent = procedure(Sender: TObject; IsGet: boolean; const URL, Query: string;
Reload: boolean; var NewURL: string; var DocType: ThtmlFileType;
var Stream: TMemoryStream) of Object;
TGetPostRequestExEvent = procedure(Sender: TObject; IsGet: boolean;
const URL, Query, EncType, Referer: string;
Reload: boolean; var NewURL: string; var DocType: ThtmlFileType;
var Stream: TMemoryStream) of Object;
TbrFormSubmitEvent = procedure(Sender: TObject; Viewer: ThtmlViewer;
const Action, Target, EncType, Method: string;
Results: TStringList; var Handled: boolean) of Object;
TbrFrameSet = class;
TbrSubFrameSet = class;
TbrFrameBase = class(TCustomPanel) {base class for other classes}
MasterSet: TbrFrameSet; {Points to top (master) TbrFrameSet}
private
URLBase: string;
UnLoaded: boolean;
procedure UpdateFrameList; virtual; abstract;
protected
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
LocalCharSet: TFontCharset;
{$endif}
procedure FVMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); virtual; abstract;
procedure FVMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer); virtual; abstract;
procedure FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); virtual; abstract;
function CheckNoResize(var Lower, Upper: boolean): boolean; virtual; abstract;
procedure LoadBrzFiles; virtual; abstract;
procedure ReLoadFiles(APosition: LongInt); virtual; abstract;
procedure UnloadFiles; virtual; abstract;
public
LOwner: TbrSubFrameSet;
procedure InitializeDimensions(X, Y, Wid, Ht: integer); virtual; abstract;
end;
TbrFrame = class(TbrFrameBase) {TbrFrame holds a ThtmlViewer or TbrSubFrameSet}
protected
NoScroll: boolean;
brMarginHeight, brMarginWidth: integer;
frHistory: TStringList;
frPositionHistory: TFreeList;
frHistoryIndex: integer;
RefreshTimer: TTimer;
NextFile: string;
procedure CreateViewer;
procedure frBumpHistory(const NewName: string; NewPos, OldPos: LongInt;
OldFormData: TFreeList);
procedure frBumpHistory1(const NewName: string; Pos: LongInt);
procedure frSetHistoryIndex(Value: integer);
procedure UpdateFrameList; override;
procedure RefreshEvent(Sender: TObject; Delay: integer; const URL: string);
procedure RefreshTimerTimer(Sender: TObject);
protected
procedure FVMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure FVMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer); override;
procedure FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
function CheckNoResize(var Lower, Upper: boolean): boolean; override;
procedure ReLoadFiles(APosition: LongInt); override;
procedure UnloadFiles; override;
procedure LoadBrzFiles; override;
procedure frLoadFromBrzFile(const URL, Dest, Query, EncType, Referer: string;
Bump, IsGet, Reload: boolean);
procedure ReloadFile(const FName: string; APosition: LongInt);
procedure URLExpandName(Sender: TObject; const SRC: string; var Rslt: string);
public
Viewer: ThtmlViewer; {the ThtmlViewer it holds if any}
ViewerPosition: LongInt;
ViewerFormData: TFreeList;
FrameSet: TbrSubFrameSet; {or the TbrSubFrameSet it holds}
Source, {Dos filename or URL for this frame}
OrigSource, {Original Source name}
Destination: String; {Destination offset for this frame}
TheStream: TMemoryStream;
TheStreamType: ThtmlFileType;
WinName: String; {window name, if any, for this frame}
NoReSize: boolean;
constructor CreateIt(AOwner: TComponent; L: TAttributeList;
Master: TbrFrameSet; const Path: string);
destructor Destroy; override;
procedure InitializeDimensions(X, Y, Wid, Ht: integer); override;
procedure Repaint; override;
procedure SetBounds(ALeft, ATop, AWidth, AHeight: Integer); override;
end;
TbrSubFrameSet = class(TbrFrameBase) {can contain one or more TbrFrames and/or TSubFrameSets}
protected
FBase: String;
FBaseTarget: String;
OuterBorder: integer;
BorderSize: integer;
FRefreshURL: string;
FRefreshDelay: integer;
RefreshTimer: TTimer;
NextFile: string;
procedure ClearFrameNames;
procedure AddFrameNames;
procedure UpdateFrameList; override;
procedure HandleMeta(Sender: TObject; const HttpEq, Name, Content: string);
procedure SetRefreshTimer;
procedure RefreshTimerTimer(Sender: Tobject); virtual;
protected
OldRect: TRect;
function GetRect: TRect;
procedure FVMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure FVMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer); override;
procedure FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer); override;
procedure FindLineAndCursor(Sender: TObject; X, Y: integer);
function NearBoundary(X, Y: integer): boolean;
function CheckNoResize(var Lower, Upper: boolean): boolean; override;
procedure Clear; virtual;
public
First: boolean; {First time thru}
Rows: boolean; {set if row frameset, else column frameset}
List: TFreeList; {list of TbrFrames and TSubFrameSets in this TbrSubFrameSet}
Dim, {col width or row height as read. Blanks may have been added}
DimF, {col width or row height in pixels as calculated and displayed}
Lines {pixel pos of lines, Lines[1]=0, Lines[DimCount]=width|height}
: array[0..20] of SmallInt;
Fixed {true if line not allowed to be dragged}
: array[0..20] of boolean;
DimCount: integer;
DimFTot: integer;
LineIndex: integer;
constructor CreateIt(AOwner: TComponent; Master: TbrFrameSet);
destructor Destroy; override;
function AddFrame(Attr: TAttributeList; const FName: string): TbrFrame;
procedure EndFrameSet; virtual;
procedure DoAttributes(L: TAttributeList);
procedure LoadBrzFiles; override;
procedure ReLoadFiles(APosition: LongInt); override;
procedure UnloadFiles; override;
procedure InitializeDimensions(X, Y, Wid, Ht: integer); override;
procedure CalcSizes(Sender: TObject);
end;
TFrameBrowser = class;
TbrFrameSet = class(TbrSubFrameSet) {only one of these showing, others may be held as History}
protected
FTitle: String;
FCurrentFile: String;
FrameNames: TStringList; {list of Window names and their TFrames}
Viewers: TList; {list of all ThtmlViewer pointers}
Frames: TList; {list of all the Frames contained herein}
HotSet: TbrFrameBase; {owner of line we're moving}
OldWidth, OldHeight: integer;
NestLevel: integer;
FActive: ThtmlViewer; {the most recently active viewer}
procedure ClearForwards;
procedure UpdateFrameList; override;
procedure RefreshTimerTimer(Sender: Tobject); override;
protected
procedure FVMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer); override;
procedure CheckActive(Sender: TObject);
function GetActive: ThtmlViewer;
public
FrameViewer: TFrameBrowser;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure EndFrameSet; override;
procedure LoadFromBrzFile(Stream: TMemoryStream; StreamType: ThtmlFileType;
const URL, Dest: string);
procedure Clear; override;
procedure CalcSizes(Sender: TObject);
procedure Repaint; override;
end;
TFrameBrowser = class(TFVBase)
protected
FPosition: TList;
FHistoryIndex: integer;
FOnGetPostRequest: TGetPostRequestEvent;
FOnGetPostRequestEx: TGetPostRequestExEvent;
FOnImageRequest: TGetImageEvent;
FOptions: TFrameViewerOptions;
FOnViewerClear: TNotifyEvent;
InFormSubmit: boolean;
FOnFormSubmit: TbrFormSubmitEvent;
FEncodePostArgs: boolean;
FOnProgress: ThtProgressEvent;
FBaseEx: String;
function GetBase: string;
procedure SetBase(Value: string);
function GetBaseTarget: string;
function GetTitle: string;
function GetCurrentFile: string;
procedure HotSpotCovered(Sender: TObject; const SRC: string);
procedure SetHistoryIndex(Value: integer);
procedure ChkFree(Obj: TObject);
function GetActiveTarget: string;
function GetFwdButtonEnabled: boolean;
function GetBackButtonEnabled: boolean;
procedure SetOnImageRequest(const Value: TGetImageEvent);
procedure SetOptions(Value: TFrameViewerOptions);
procedure fvDragDrop(Sender, Source: TObject; X, Y: Integer);
procedure fvDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
procedure SetDragDrop(const Value: TDragDropEvent);
procedure SetDragOver(const Value: TDragOverEvent);
function GetViewers: TStrings; override;
procedure SetOnProgress(Handler: ThtProgressEvent);
protected
CurbrFrameSet: TbrFrameSet; {the TbrFrameSet being displayed}
function GetCurViewerCount: integer; override;
function GetCurViewer(I: integer): ThtmlViewer; override;
function GetActiveViewer: ThtmlViewer; override;
procedure BumpHistory(OldFrameSet: TbrFrameSet; OldPos: LongInt);
procedure BumpHistory1(const FileName, Title: string;
OldPos: LongInt; ft: ThtmlFileType);
procedure BumpHistory2(OldPos: LongInt);
function HotSpotClickHandled(const FullUrl: string): boolean;
procedure AddFrame(FrameSet: TObject; Attr: TAttributeList; const FName: string); override;
function CreateSubFrameSet(FrameSet: TObject): TObject; override;
procedure DoAttributes(FrameSet: TObject; Attr: TAttributeList); override;
procedure EndFrameSet(FrameSet: TObject); override;
procedure AddVisitedLink(const S: string);
procedure CheckVisitedLinks;
procedure LoadURLInternal(const URL, Query, EncType, Referer: string; IsGet,
Reload: boolean);
procedure DoFormSubmitEvent(Sender: TObject; const Action, Target, EncType,
Method: string; Results: TStringList);
procedure DoURLRequest(Sender: TObject; const SRC: string; var Stream: TMemoryStream);
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Reload;
procedure Clear;
procedure HotSpotClick(Sender: TObject; const AnURL: string;
var Handled: boolean);
procedure ClearHistory; override;
function ViewerFromTarget(const Target: string): ThtmlViewer;
procedure GoBack;
procedure GoFwd;
procedure Repaint; override;
procedure GetPostQuery(const URL, Query, EncType: string; IsGet: boolean);
procedure LoadURL(const URL: string);
function GetViewerUrlBase(Viewer: ThtmlViewer): string;
property Base: string read GetBase write SetBase;
property BaseTarget: string read GetBaseTarget;
property DocumentTitle: string read GetTitle;
property CurrentFile: string read GetCurrentFile;
property HistoryIndex: integer read FHistoryIndex write SetHistoryIndex;
property EncodePostArgs: boolean read FEncodePostArgs write FEncodePostArgs;
published
property FwdButtonEnabled: boolean read GetFwdButtonEnabled;
property BackButtonEnabled: boolean read GetBackButtonEnabled;
property OnGetPostRequest: TGetPostRequestEvent read FOnGetPostRequest write FOnGetPostRequest;
property OnGetPostRequestEx: TGetPostRequestExEvent read FOnGetPostRequestEx write FOnGetPostRequestEx;
property OnImageRequest: TGetImageEvent read FOnImageRequest
write SetOnImageRequest;
property fvOptions: TFrameViewerOptions read FOptions write SetOptions
default [fvPrintTableBackground, fvPrintMonochromeBlack];
property OnViewerClear: TNotifyEvent read FOnViewerClear write FOnViewerClear;
property OnDragDrop: TDragDropEvent read FOnDragDrop write SetDragDrop;
property OnDragOver: TDragOverEvent read FOnDragOver write SetDragOver;
property OnFormSubmit: TbrFormSubmitEvent read FOnFormSubmit write FOnFormSubmit;
property OnProgress: ThtProgressEvent read FOnProgress write SetOnProgress;
end;
implementation
uses
UrlSubs;
const
Sequence: integer = 10;
type
PositionObj = class(TObject)
Pos: LongInt;
Seq: integer;
FormData: TFreeList;
destructor Destroy; override;
end;
function StreamToString(Stream: TStream): string;
var
SL: TStringList;
begin
Result := '';
try
SL := TStringList.Create;
try
SL.LoadFromStream(Stream);
Result := SL.Text;
finally
Stream.Position := 0;
SL.Free;
end;
except
end;
end;
{----------------SplitURL}
procedure SplitURL(const Src: string; var FName, Dest: string);
{Split an URL into filename and Destination}
var
I: integer;
begin
I := Pos('#', Src);
if I >= 1 then
begin
Dest := System.Copy(Src, I, Length(Src)-I+1); {local destination}
FName := System.Copy(Src, 1, I-1); {the file name}
end
else
begin
FName := Src;
Dest := ''; {no local destination}
end;
end;
function ConvDosToHTML(const Name: string): string; forward;
{----------------TbrFrame.CreateIt}
constructor TbrFrame.CreateIt(AOwner: TComponent; L: TAttributeList;
Master: TbrFrameSet; const Path: string);
var
I: integer;
S: string;
begin
inherited Create(AOwner);
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
if AOwner is TbrSubFrameSet then
LocalCharSet := TbrSubFrameset(AOwner).LocalCharSet;
{$endif}
LOwner := AOwner as TbrSubFrameSet;
MasterSet := Master;
BevelInner := bvNone;
brMarginWidth := MasterSet.FrameViewer.MarginWidth;
brMarginHeight := MasterSet.FrameViewer.MarginHeight;
if LOwner.BorderSize = 0 then
BevelOuter := bvNone
else
begin
BevelOuter := bvLowered;
BevelWidth := LOwner.BorderSize;
end;
ParentColor := True;
if Assigned(L) then
for I := 0 to L.Count-1 do
with TAttribute(L[I]) do
case Which of
SrcSy:
begin
SplitUrl(Trim(Name), S, Destination);
S := ConvDosToHTML(S);
if Pos(':/', S) <> 0 then
URLBase := URLSubs.GetBase(S) {get new base}
else if ReadHTML.Base <> '' then
begin
S := Combine(ReadHTML.Base, S);
URLBase := ReadHTML.Base;
end
else
begin
URLBase := LOwner.URLBase;
S := Combine(URLBase, S);
end;
Source := S;
OrigSource := S;
end;
NameSy: WinName := Name;
NoResizeSy: NoResize := True;
ScrollingSy:
if CompareText(Name, 'NO') = 0 then {auto and yes work the same}
NoScroll := True;
MarginWidthSy: brMarginWidth := Value;
MarginHeightSy: brMarginHeight := Value;
end;
if WinName <> '' then {add it to the Window name list}
(AOwner as TbrSubFrameSet).MasterSet.FrameNames.AddObject(Uppercase(WinName), Self);
OnMouseDown := FVMouseDown;
OnMouseMove := FVMouseMove;
OnMouseUp := FVMouseUp;
frHistory := TStringList.Create;
frPositionHistory := TFreeList.Create;
end;
{----------------TbrFrame.Destroy}
destructor TbrFrame.Destroy;
var
I: integer;
begin
if Assigned(MasterSet) then
begin
if (WinName <> '')
and Assigned(MasterSet.FrameNames) and MasterSet.FrameNames.Find(WinName, I)
and (MasterSet.FrameNames.Objects[I] = Self) then
MasterSet.FrameNames.Delete(I);
if Assigned(Viewer) then
begin
if Assigned(MasterSet.Viewers) then
MasterSet.Viewers.Remove(Viewer);
if Assigned(MasterSet.Frames) then
MasterSet.Frames.Remove(Self);
if Viewer = MasterSet.FActive then MasterSet.FActive := Nil;
end;
end;
if Assigned(Viewer) then
begin
Viewer.Free;
Viewer := Nil;
end
else if Assigned(FrameSet) then
begin
FrameSet.Free;
FrameSet := Nil;
end;
frHistory.Free; frHistory := Nil;
frPositionHistory.Free; frPositionHistory := Nil;
ViewerFormData.Free;
RefreshTimer.Free;
inherited Destroy;
end;
procedure TbrFrame.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
begin
inherited;
{in most cases, SetBounds results in a call to CalcSizes. However, to make sure
for case where there is no actual change in the bounds.... }
if Assigned(FrameSet) then
FrameSet.CalcSizes(Nil);
end;
procedure TbrFrame.RefreshEvent(Sender: TObject; Delay: integer; const URL: string);
var
Ext: string;
begin
if not (fvMetaRefresh in MasterSet.FrameViewer.FOptions) then
Exit;
Ext := Lowercase(GetURLExtension(URL));
if (Ext = 'exe') or (Ext = 'zip') then Exit;
if URL = '' then
NextFile := Source
else if not IsFullURL(URL) then
NextFile := Combine(URLBase, URL) //URLBase + URL
else
NextFile := URL;
if not Assigned(RefreshTimer) then
RefreshTimer := TTimer.Create(Self);
RefreshTimer.OnTimer := RefreshTimerTimer;
RefreshTimer.Interval := Delay*1000;
RefreshTimer.Enabled := True;
end;
procedure TbrFrame.RefreshTimerTimer(Sender: TObject);
var
S, D: string;
begin
RefreshTimer.Enabled := False;
if Unloaded then Exit;
if not IsFullUrl(NextFile) then
NextFile := Combine(UrlBase, NextFile);
if (MasterSet.Viewers.Count = 1) then {load a new FrameSet}
MasterSet.FrameViewer.LoadURLInternal(NextFile, '', '', '', True, True)
else
begin
SplitURL(NextFile, S, D);
frLoadFromBrzFile(S, D, '', '', '', True, True, True);
end;
end;
procedure TbrFrame.RePaint;
begin
if Assigned(Viewer) then Viewer.RePaint
else if Assigned(FrameSet) then FrameSet.RePaint;
inherited RePaint;
end;
{----------------TbrFrame.FVMouseDown}
procedure TbrFrame.FVMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
(Parent as TbrSubFrameSet).FVMouseDown(Sender, Button, Shift, X+Left, Y+Top);
end;
{----------------TbrFrame.FVMouseMove}
procedure TbrFrame.FVMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if not NoResize then
(Parent as TbrSubFrameSet).FVMouseMove(Sender, Shift, X+Left, Y+Top);
end;
{----------------TbrFrame.FVMouseUp}
procedure TbrFrame.FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
begin
(Parent as TbrSubFrameSet).FVMouseUp(Sender, Button, Shift, X+Left, Y+Top);
end;
{----------------TbrFrame.CheckNoResize}
function TbrFrame.CheckNoResize(var Lower, Upper: boolean): boolean;
begin
Result := NoResize;
Lower := NoResize;
Upper := NoResize;
end;
{----------------TbrFrame.InitializeDimensions}
procedure TbrFrame.InitializeDimensions(X, Y, Wid, Ht: integer);
begin
if Assigned(FrameSet) then
FrameSet.InitializeDimensions(X, Y, Wid, Ht);
end;
{----------------TbrFrame.CreateViewer}
procedure TbrFrame.CreateViewer;
begin
Viewer := ThtmlViewer.Create(Self); {the Viewer for the frame}
Viewer.FrameOwner := Self;
Viewer.Width := ClientWidth;
Viewer.Height := ClientHeight;
Viewer.Align := alClient;
if (MasterSet.BorderSize = 0) or (fvNoFocusRect in MasterSet.FrameViewer.fvOptions) then
Viewer.BorderStyle := htNone;
Viewer.OnHotspotClick := LOwner.MasterSet.FrameViewer.HotSpotClick;
Viewer.OnHotspotCovered := LOwner.MasterSet.FrameViewer.HotSpotCovered;
if NoScroll then
Viewer.Scrollbars := ssNone;
Viewer.DefBackground := MasterSet.FrameViewer.FBackground;
Viewer.Visible := False;
InsertControl(Viewer);
Viewer.SendToBack;
Viewer.Visible := True;
Viewer.Tabstop := True;
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
Viewer.CharSet := LocalCharset;
{$endif}
MasterSet.Viewers.Add(Viewer);
with MasterSet.FrameViewer do
begin
Viewer.ViewImages := FViewImages;
Viewer.SetStringBitmapList(FBitmapList);
Viewer.ImageCacheCount := FImageCacheCount;
Viewer.NoSelect := FNoSelect;
Viewer.DefFontColor := FFontColor;
Viewer.DefHotSpotColor := FHotSpotColor;
Viewer.DefVisitedLinkColor := FVisitedColor;
Viewer.DefOverLinkColor := FOverColor;
Viewer.DefFontSize := FFontSize;
Viewer.DefFontName := FFontName;
Viewer.DefPreFontName := FPreFontName;
Viewer.OnBitmapRequest := FOnBitmapRequest;
if fvOverLinksActive in FOptions then
Viewer.htOptions := Viewer.htOptions + [htOverLinksActive];
if fvNoLinkUnderline in FOptions then
Viewer.htOptions := Viewer.htOptions + [htNoLinkUnderline];
if not (fvPrintTableBackground in FOptions) then
Viewer.htOptions := Viewer.htOptions - [htPrintTableBackground];
if (fvPrintBackground in FOptions) then
Viewer.htOptions := Viewer.htOptions + [htPrintBackground];
if not (fvPrintMonochromeBlack in FOptions) then
Viewer.htOptions := Viewer.htOptions - [htPrintMonochromeBlack];
if fvShowVScroll in FOptions then
Viewer.htOptions := Viewer.htOptions + [htShowVScroll];
if fvNoWheelMouse in FOptions then
Viewer.htOptions := Viewer.htOptions + [htNoWheelMouse];
if Assigned(FOnImageRequest) then
Viewer.OnImageRequest := FOnImageRequest;
if fvNoLinkHilite in FOptions then
Viewer.htOptions := Viewer.htOptions + [htNoLinkHilite];
Viewer.OnFormSubmit := DoFormSubmitEvent;
Viewer.OnLink := FOnLink;
Viewer.OnMeta := FOnMeta;
Viewer.OnMetaRefresh := RefreshEvent;
Viewer.OnRightClick := FOnRightClick;
Viewer.OnProcessing := CheckProcessing;
Viewer.OnMouseDown := OnMouseDown;
Viewer.OnMouseMove := OnMouseMove;
Viewer.OnMouseUp := OnMouseUp;
Viewer.OnKeyDown := OnKeyDown;
Viewer.OnKeyUp := OnKeyUp;
Viewer.OnKeyPress := OnKeyPress;
Viewer.Cursor := Cursor;
Viewer.HistoryMaxCount := FHistoryMaxCount;
Viewer.OnScript := FOnScript;
Viewer.PrintMarginLeft := FPrintMarginLeft;
Viewer.PrintMarginRight := FPrintMarginRight;
Viewer.PrintMarginTop := FPrintMarginTop;
Viewer.PrintMarginBottom := FPrintMarginBottom;
Viewer.PrintScale := FPrintScale;
Viewer.OnPrintHeader := FOnPrintHeader;
Viewer.OnPrintFooter := FOnPrintFooter;
Viewer.OnPrintHtmlHeader := FOnPrintHtmlHeader;
Viewer.OnPrintHtmlFooter := FOnPrintHtmlFooter;
Viewer.OnInclude := FOnInclude;
Viewer.OnSoundRequest := FOnSoundRequest;
Viewer.OnImageOver := FOnImageOver;
Viewer.OnImageClick := FOnImageClick;
Viewer.OnFileBrowse := FOnFileBrowse;
Viewer.OnObjectClick := FOnObjectClick;
Viewer.OnObjectFocus := FOnObjectFocus;
Viewer.OnObjectBlur := FOnObjectBlur;
Viewer.OnObjectChange := FOnObjectChange;
Viewer.ServerRoot := ServerRoot;
Viewer.OnMouseDouble := FOnMouseDouble;
Viewer.OnPanelCreate := FOnPanelCreate;
Viewer.OnPanelDestroy := FOnPanelDestroy;
Viewer.OnPanelPrint := FOnPanelPrint;
Viewer.OnDragDrop := fvDragDrop;
Viewer.OnDragOver := fvDragOver;
Viewer.OnParseBegin := FOnParseBegin;
Viewer.OnParseEnd := FOnParseEnd;
Viewer.OnProgress := FOnProgress;
Viewer.OnObjectTag := OnObjectTag;
Viewer.OnhtStreamRequest := DoURLRequest;
end;
Viewer.MarginWidth := brMarginWidth;
Viewer.MarginHeight := brMarginHeight;
Viewer.OnEnter := MasterSet.CheckActive;
Viewer.OnExpandName := UrlExpandName;
end;
{----------------TbrFrame.LoadBrzFiles}
procedure TbrFrame.LoadBrzFiles;
var
Item: TbrFrameBase;
I: integer;
Upper, Lower: boolean;
Msg: string[255];
NewURL: string;
TheString: string;
begin
if (Source <> '') and (MasterSet.NestLevel < 4) then
begin
if not Assigned(TheStream) then
begin
NewURL := '';
if Assigned(MasterSet.FrameViewer.FOnGetPostRequestEx) then
MasterSet.FrameViewer.FOnGetPostRequestEX(Self, True, Source, '', '', '', False, NewURL, TheStreamType, TheStream)
else
MasterSet.FrameViewer.FOnGetPostRequest(Self, True, Source, '', False, NewURL, TheStreamType, TheStream);
if NewURL <> '' then
Source := NewURL;
end;
URLBase := GetBase(Source);
Inc(MasterSet.NestLevel);
try
TheString := StreamToString(TheStream);
if (TheStreamType = HTMLType) and IsFrameString(LsString, '', TheString,
MasterSet.FrameViewer) then
begin
FrameSet := TbrSubFrameSet.CreateIt(Self, MasterSet);
FrameSet.Align := alClient;
FrameSet.Visible := False;
InsertControl(FrameSet);
FrameSet.SendToBack;
FrameSet.Visible := True;
FrameParseString(MasterSet.FrameViewer, FrameSet, lsString, '', TheString, FrameSet.HandleMeta);
Self.BevelOuter := bvNone;
frBumpHistory1(Source, 0);
with FrameSet do
begin
for I := 0 to List.Count-1 do
Begin
Item := TbrFrameBase(List.Items[I]);
Item.LoadBrzFiles;
end;
CheckNoresize(Lower, Upper);
if FRefreshDelay > 0 then
SetRefreshTimer;
end;
end
else
begin
CreateViewer;
Viewer.Base := MasterSet.FBase;
Viewer.LoadStream(Source, TheStream, TheStreamType);
Viewer.PositionTo(Destination);
frBumpHistory1(Source, Viewer.Position);
end;
except
if not Assigned(Viewer) then
CreateViewer;
if Assigned(FrameSet) then
begin
FrameSet.Free;
FrameSet := Nil;
end;
Msg := '<p><img src="qw%&.bmp" alt="Error"> Can''t load '+Source;
Viewer.LoadFromBuffer(@Msg[1], Length(Msg), ''); {load an error message}
end;
Dec(MasterSet.NestLevel);
end
else
begin {so blank area will perform like the TFrameBrowser}
OnMouseDown := MasterSet.FrameViewer.OnMouseDown;
OnMouseMove := MasterSet.FrameViewer.OnMouseMove;
OnMouseUp := MasterSet.FrameViewer.OnMouseUp;
end;
end;
{----------------TbrFrame.ReloadFiles}
procedure TbrFrame.ReloadFiles(APosition: LongInt);
var
Item: TbrFrameBase;
I: integer;
Upper, Lower: boolean;
Dummy: string;
procedure DoError;
var
Msg: string;
begin
Msg := '<p><img src="qw%&.bmp" alt="Error"> Can''t load '+Source;
Viewer.LoadFromBuffer(@Msg[1], Length(Msg), ''); {load an error message}
end;
begin
if Source <> '' then
if Assigned(FrameSet) then
begin
with FrameSet do
begin
for I := 0 to List.Count-1 do
Begin
Item := TbrFrameBase(List.Items[I]);
Item.ReloadFiles(APosition);
end;
CheckNoresize(Lower, Upper);
end;
end
else if Assigned(Viewer) then
begin
Viewer.Base := MasterSet.FBase; {only effective if no Base to be read}
try
if Assigned(MasterSet.FrameViewer.FOnGetPostRequestEx) then
MasterSet.FrameViewer.FOnGetPostRequestEx(Self, True, Source, '', '', '',False,
Dummy, TheStreamType, TheStream)
else
MasterSet.FrameViewer.FOnGetPostRequest(Self, True, Source, '', False,
Dummy, TheStreamType, TheStream);
Viewer.LoadStream(Source, TheStream, TheStreamType);
if APosition < 0 then
Viewer.Position := ViewerPosition
else Viewer.Position := APosition; {its History Position}
Viewer.FormData := ViewerFormData;
ViewerFormData.Free;
ViewerFormData := Nil;
except
DoError;
end;
end;
Unloaded := False;
end;
{----------------TbrFrame.UnloadFiles}
procedure TbrFrame.UnloadFiles;
var
Item: TbrFrameBase;
I: integer;
begin
if Assigned(RefreshTimer) then
RefreshTimer.Enabled := False;
if Assigned(FrameSet) then
begin
with FrameSet do
begin
for I := 0 to List.Count-1 do
Begin
Item := TbrFrameBase(List.Items[I]);
Item.UnloadFiles;
end;
end;
end
else if Assigned(Viewer) then
begin
ViewerPosition := Viewer.Position;
ViewerFormData := Viewer.FormData;
if Assigned(MasterSet.FrameViewer.FOnViewerClear) then
MasterSet.FrameViewer.FOnViewerClear(Viewer);
Viewer.Clear;
if MasterSet.FActive = Viewer then
MasterSet.FActive := Nil;
Viewer.OnSoundRequest := Nil;
end;
Unloaded := True;
end;
{----------------TbrFrame.frLoadFromBrzFile}
procedure TbrFrame.frLoadFromBrzFile(const URL, Dest, Query, EncType, Referer: string; Bump, IsGet, Reload: boolean);
{URL is full URL here, has been seperated from Destination}
var
OldPos: LongInt;
HS, S, S1, OldTitle, OldName, OldBase: string;
OldFormData: TFreeList;
SameName: boolean;
OldViewer: ThtmlViewer;
OldFrameSet: TbrSubFrameSet;
TheString: string;
Upper, Lower, FrameFile: boolean;
Item: TbrFrameBase;
I: integer;
begin
if Assigned(RefreshTimer) then RefreshTimer.Enabled := False;
OldName := Source;
OldBase := URLBase;
S := URL;
if S = '' then S := OldName
else URLBase := URLSubs.GetBase(S); {get new base}
HS := S;
SameName := CompareText(S, OldName)= 0;
{if SameName, will not have to reload anything unless Reload set}
if not SameName or Reload then
begin
if Assigned(Viewer) and Assigned(MasterSet.FrameViewer.FOnViewerClear) then
MasterSet.FrameViewer.FOnViewerClear(Viewer);
S1 := '';
if Assigned(MasterSet.FrameViewer.FOnGetPostRequestEx) then
MasterSet.FrameViewer.FOnGetPostRequestEx(Self, IsGet, S, Query, EncType, Referer, Reload, S1, TheStreamType, TheStream)
else
MasterSet.FrameViewer.FOnGetPostRequest(Self, IsGet, S, Query, Reload, S1, TheStreamType, TheStream);
if S1 <> '' then
begin
S := S1;
URLBase := GetBase(S);
end;
end;
Source := S;
try
TheString := StreamToString(TheStream);
if not SameName then
try
FrameFile := (TheStreamType = HTMLType) and
IsFrameString(lsString, '', TheString, MasterSet.FrameViewer);
except
Raise(EfvLoadError.Create('Can''t load: '+URL));
end
else FrameFile := not Assigned(Viewer);
if SameName and not Reload then
if Assigned(Viewer) then
begin
OldPos := Viewer.Position;
Viewer.PositionTo(Dest);
MasterSet.FrameViewer.AddVisitedLink(URL+Dest);
if Bump and (Viewer.Position <> OldPos) then
{Viewer to Viewer}
frBumpHistory(HS, Viewer.Position, OldPos, Nil);
end
else
begin
with FrameSet do
for I := 0 to List.Count-1 do
Begin
Item := TbrFrameBase(List.Items[I]);
if (Item is TbrFrame) then
with TbrFrame(Item) do
if CompareText(Source, OrigSource) <> 0 then
frLoadFromBrzFile(OrigSource, '', '', '', '', True, True, False);
end;
Exit;
end
else if Assigned(Viewer) and not FrameFile then {not samename or samename and reload}
begin {Viewer already assigned and it's not a Frame file}
OldPos := Viewer.Position;
OldTitle := Viewer.DocumentTitle;
if Bump and not SameName and (MasterSet.Viewers.Count > 1) then
OldFormData := Viewer.FormData
else OldFormData := Nil;
try
Viewer.Base := MasterSet.FBase;
Viewer.LoadStream(Source, TheStream, TheStreamType);
if (Dest <> '') then
Viewer.PositionTo(Dest);
MasterSet.FrameViewer.AddVisitedLink(URL+Dest);
if not samename then
begin {don't bump history on a forced reload}
if MasterSet.Viewers.Count > 1 then
begin
if Bump then
{Viewer to Viewer}
frBumpHistory(HS, Viewer.Position, OldPos, OldFormData)
else OldFormData.Free;
end
else if (MasterSet.Viewers.Count = 1) and Bump then
{a single viewer situation, bump the history here}
with MasterSet do
begin
FCurrentFile := Source;
FTitle := Viewer.DocumentTitle;
FBase := Viewer.Base;
FBaseTarget := Viewer.BaseTarget;
FrameViewer.BumpHistory1(OldName, OldTitle, OldPos, HTMLType);
end;
end;
except
OldFormData.Free;
Raise;
end;
end
else
begin {Viewer is not assigned or it is a Frame File}
{keep the old viewer or frameset around (free later) to minimize blink}
OldViewer := Viewer; Viewer := Nil;
OldFrameSet := FrameSet; FrameSet := Nil;
if OldFrameSet <> Nil then OldFrameSet.ClearFrameNames;
if FrameFile then
begin {it's a frame file}
FrameSet := TbrSubFrameSet.CreateIt(Self, MasterSet);
FrameSet.URLBase := URLBase;
FrameSet.Align := alClient;
FrameSet.Visible := False;
InsertControl(FrameSet);
FrameSet.SendToBack; {to prevent blink}
FrameSet.Visible := True;
FrameParseString(MasterSet.FrameViewer, FrameSet, lsString, '', TheString, FrameSet.HandleMeta);
MasterSet.FrameViewer.AddVisitedLink(URL);
Self.BevelOuter := bvNone;
with FrameSet do
begin
for I := 0 to List.Count-1 do
Begin
Item := TbrFrameBase(List.Items[I]);
Item.LoadBrzFiles;
end;
CheckNoresize(Lower, Upper);
if FRefreshDelay > 0 then
SetRefreshTimer;
end;
if Assigned(OldViewer) then
frBumpHistory(HS, 0, OldViewer.Position, OldViewer.FormData)
else frBumpHistory(S, 0, 0, Nil);
end
else
begin {not a frame file but needs a viewer}
CreateViewer;
Viewer.Base := MasterSet.FBase;
Viewer.LoadStream(Source, TheStream, TheStreamType);
Viewer.PositionTo(Dest);
MasterSet.FrameViewer.AddVisitedLink(URL+Dest);
{FrameSet to Viewer}
frBumpHistory(HS, Viewer.Position, 0, Nil);
end;
if Assigned(FrameSet) then
with FrameSet do
begin
with ClientRect do
InitializeDimensions(Left, Top, Right-Left, Bottom-Top);
CalcSizes(Nil);
end;
if Assigned(Viewer) then
begin
if MasterSet.BorderSize = 0 then
BevelOuter := bvNone
else
begin
BevelOuter := bvLowered;
BevelWidth := MasterSet.BorderSize;
end;
if (Dest <> '') then
Viewer.PositionTo(Dest);
end;
if Assigned(OldViewer) then
begin
MasterSet.Viewers.Remove(OldViewer);
if MasterSet.FActive = OldViewer then
MasterSet.FActive := Nil;
OldViewer.Free;
end
else if Assigned(OldFrameSet) then
begin
OldFrameSet.UnloadFiles;
OldFrameSet.Visible := False;
end;
RePaint;
end;
except
Source := OldName;
URLBase := OldBase;
Raise;
end;
end;
{----------------TbrFrame.ReloadFile}
procedure TbrFrame.ReloadFile(const FName: string; APosition: LongInt);
{It's known that there is only a single viewer, the file is not being changed,
only the position}
begin
Viewer.Position := APosition;
end;
function ConvDosToHTML(const Name: string): string;
{if Name is a Dos filename, convert it to HTML. Add the file:// if it is
a full pathe filename}
begin
Result := Name;
if Pos('\', Result) > 0 then
begin
Result := DosToHTML(Result);
if (Pos('|', Result) > 0) then {was something like c:\....}
Result := 'file:///'+Result;
end;
end;
{----------------TbrFrame.URLExpandName}
procedure TbrFrame.URLExpandName(Sender: TObject; const SRC: string; var Rslt: string);
var
S: string;
Viewer: ThtmlViewer;
begin
S := ConvDosToHTML(SRC);
if not IsFullUrl(S) then
begin
Viewer := Sender as ThtmlViewer;
if Viewer.Base <> '' then
Rslt := Combine(GetBase(ConvDosToHTML(Viewer.Base)), S)
else Rslt := Combine(UrlBase, S);
end
else Rslt := S;
end;
{----------------TbrFrame.frBumpHistory}
procedure TbrFrame.frBumpHistory(const NewName: string;
NewPos, OldPos: LongInt; OldFormData: TFreeList);
{applies to TFrames which hold a ThtmlViewer}{Viewer to Viewer}
var
PO: PositionObj;
begin
with frHistory do
begin
if (Count > 0) then
begin
PositionObj(frPositionHistory[frHistoryIndex]).Pos := OldPos;
if frHistory[frHistoryIndex] <> NewName then
PositionObj(frPositionHistory[frHistoryIndex]).FormData := OldFormData
else OldFormData.Free;
end
else OldFormData.Free;
MasterSet.ClearForwards; {clear the history list forwards}
frHistoryIndex := 0;
InsertObject(0, NewName, FrameSet); {FrameSet may be Nil here}
PO := PositionObj.Create;
PO.Pos := NewPos;
PO.Seq := Sequence;
Inc(Sequence);
frPositionHistory.Insert(0, PO);
MasterSet.UpdateFrameList;
with MasterSet.FrameViewer do
if Assigned(FOnHistoryChange) then
FOnHistoryChange(MasterSet.FrameViewer);
end;
end;
{----------------TbrFrame.frBumpHistory1}
procedure TbrFrame.frBumpHistory1(const NewName: string; Pos: LongInt);
{called from a fresh TbrFrame. History list is empty}
var
PO: PositionObj;
begin
with frHistory do
begin
frHistoryIndex := 0;
InsertObject(0, NewName, FrameSet); {FrameSet may be Nil here}
PO := PositionObj.Create;
PO.Pos := Pos;
PO.Seq := Sequence;
Inc(Sequence);
frPositionHistory.Insert(0, PO);
MasterSet.UpdateFrameList;
with MasterSet.FrameViewer do
if Assigned(FOnHistoryChange) then
FOnHistoryChange(MasterSet.FrameViewer);
end;
end;
{----------------TbrFrame.frSetHistoryIndex}
procedure TbrFrame.frSetHistoryIndex(Value: integer);
begin
with frHistory do
if (Value <> frHistoryIndex) and (Value >= 0) and (Value < Count) then
begin
if Assigned(RefreshTimer) then
RefreshTimer.Enabled := False; {cut off any timing underway}
if Assigned(Viewer) then {current is Viewer}
with PositionObj(frPositionHistory[frHistoryIndex]) do
begin
Pos := Viewer.Position; {save the old position}
{note that frHistoryIndex can only change by 1}
PositionObj(frPositionHistory[frHistoryIndex]).FormData := Viewer.FormData;
end
else
begin {Current is FrameSet}
FrameSet.UnloadFiles;
FrameSet.DestroyHandle;
FrameSet.ClearFrameNames;
FrameSet.Visible := False;
FrameSet := Nil; {it's not destroyed,though}
end;
if Objects[Value] is TbrSubFrameSet then
begin
FrameSet := TbrSubFrameSet(Objects[Value]);
FrameSet.Visible := True;
FrameSet.ReloadFiles(-1);
FrameSet.AddFrameNames;
if Assigned(Viewer) then
begin
if Assigned(MasterSet.Viewers) then
MasterSet.Viewers.Remove(Viewer);
if MasterSet.FActive = Viewer then
MasterSet.FActive := Nil;
Viewer.Free;
Viewer := Nil;
end;
end
else
begin
if not Assigned(Viewer) then
CreateViewer;
with PositionObj(frPositionHistory[Value]) do
begin
if (Source <> Strings[Value]) then
frLoadFromBrzFile(Strings[Value], '', '', '', '', False, True, False);
Viewer.FormData := FormData;
FormData.Free;
FormData := Nil;
Viewer.Position := Pos;
end;
end;
Source := Strings[Value];
frHistoryIndex := Value;
MasterSet.UpdateFrameList;
with MasterSet.FrameViewer do
if Assigned(FOnHistoryChange) then
FOnHistoryChange(MasterSet.FrameViewer);
MasterSet.FrameViewer.CheckVisitedLinks;
end;
end;
{----------------TbrFrame.UpdateFrameList}
procedure TbrFrame.UpdateFrameList;
begin
MasterSet.Frames.Add(Self);
if Assigned(FrameSet) then
FrameSet.UpdateFrameList;
end;
{----------------TbrSubFrameSet.CreateIt}
constructor TbrSubFrameSet.CreateIt(AOwner: TComponent; Master: TbrFrameSet);
begin
inherited Create(AOwner);
MasterSet := Master;
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
if AOwner is TbrFrameBase then
LocalCharSet := TbrSubFrameset(AOwner).LocalCharSet;
{$endif}
OuterBorder := 0; {no border for subframesets}
if Self <> Master then
BorderSize := Master.BorderSize;
First := True;
List := TFreeList.Create;
FBase := '';
FBaseTarget := '';
OnResize := CalcSizes;
OnMouseDown := FVMouseDown;
OnMouseMove := FVMouseMove;
OnMouseUp := FVMouseUp;
{$ifdef delphi7_plus}
{$IFNDEF LCL}
ParentBackground := False;
{$ENDIF}
{$endif}
ParentColor := True;
if (AOwner is TbrFrameBase) then
URLBase := TbrFrameBase(AOwner).URLBase;
end;
{----------------TbrSubFrameSet.ClearFrameNames}
procedure TbrSubFrameSet.ClearFrameNames;
var
I, J: integer;
begin
for J := 0 to List.Count-1 do
if (TbrFrameBase(List[J]) is TbrFrame) then
begin
with TbrFrame(List[J]) do
if Assigned(MasterSet) and (WinName <> '')
and Assigned(MasterSet.FrameNames)
and MasterSet.FrameNames.Find(WinName, I) then
MasterSet.FrameNames.Delete(I);
end
else if (TbrFrameBase(List[J]) is TbrSubFrameSet) then
TbrSubFrameSet(List[J]).ClearFrameNames;
end;
{----------------TbrSubFrameSet.AddFrameNames}
procedure TbrSubFrameSet.AddFrameNames;
var
J: integer;
Frame: TbrFrame;
begin
for J := 0 to List.Count-1 do
if (TbrFrameBase(List[J]) is TbrFrame) then
begin
Frame := TbrFrame(List[J]);
with Frame do
if Assigned(MasterSet) and (WinName <> '')
and Assigned(MasterSet.FrameNames) then
begin
MasterSet.FrameNames.AddObject(Uppercase(WinName), Frame);
end;
end
else if (TbrFrameBase(List[J]) is TbrSubFrameSet) then
TbrSubFrameSet(List[J]).AddFrameNames;
end;
{----------------TbrSubFrameSet.Destroy}
destructor TbrSubFrameSet.Destroy;
begin
List.Free;
List := Nil;
RefreshTimer.Free;
inherited Destroy;
end;
{----------------TbrSubFrameSet.AddFrame}
function TbrSubFrameSet.AddFrame(Attr: TAttributeList; const FName: string): TbrFrame;
{called by the parser when <Frame> is encountered within the <Frameset>
definition}
begin
Result := TbrFrame.CreateIt(Self, Attr, MasterSet, ExtractFilePath(FName));
List.Add(Result);
Result.SetBounds(OuterBorder, OuterBorder, Width-2*OuterBorder, Height-2*OuterBorder);
InsertControl(Result);
end;
{----------------TbrSubFrameSet.DoAttributes}
procedure TbrSubFrameSet.DoAttributes(L: TAttributeList);
{called by the parser to process the <Frameset> attributes}
var
T: TAttribute;
S: string;
Numb: string[20];
procedure GetDims;
const
EOL = ^M;
var
Ch: char;
I, N: integer;
procedure GetCh;
begin
if I > Length(S) then Ch := EOL
else
begin
Ch := S[I];
Inc(I);
end;
end;
begin
if Name = '' then S := T.Name
else Exit;
I := 1; DimCount := 0;
repeat
Inc(DimCount);
Numb := '';
GetCh;
while not (Ch in ['0'..'9', '*', EOL, ',']) do GetCh;
if Ch in ['0'..'9'] then
begin
while Ch in ['0'..'9'] do
begin
Numb := Numb+Ch;
GetCh;
end;
N := IntMax(1, StrToInt(Numb)); {no zeros}
while not (Ch in ['*', '%', ',', EOL]) do GetCh;
if ch = '*' then
begin
Dim[DimCount] := -IntMin(99, N);{store '*' relatives as negative, -1..-99}
GetCh;
end
else if Ch = '%' then
begin {%'s stored as -(100 + %), i.e. -110 is 10% }
Dim[DimCount] := -IntMin(1000, N+100); {limit to 900%}
GetCh;
end
else Dim[DimCount] := IntMin(N, 5000); {limit absolute to 5000}
end
else if Ch in ['*', ',', EOL] then
begin
Dim[DimCount] := -1;
if Ch = '*' then GetCh;
end;
while not (Ch in [',', EOL]) do GetCh;
until (Ch = EOL) or (DimCount = 20);
end;
begin
{read the row or column widths into the Dim array}
If L.Find(RowsSy, T) then
begin
Rows := True;
GetDims;
end;
if L.Find(ColsSy, T) and (DimCount <=1) then
begin
Rows := False;
DimCount := 0;
GetDims;
end;
if (Self = MasterSet) and not (fvNoBorder in MasterSet.FrameViewer.FOptions) then
{BorderSize already defined as 0}
if L.Find(BorderSy, T) or L.Find(FrameBorderSy, T)then
begin
BorderSize := T.Value;
OuterBorder := IntMax(2-BorderSize, 0);
if OuterBorder >= 1 then
begin
BevelWidth := OuterBorder;
BevelOuter := bvLowered;
end;
end
else BorderSize := 2;
end;
{----------------TbrSubFrameSet.LoadBrzFiles}
procedure TbrSubFrameSet.LoadBrzFiles;
var
I: integer;
Item: TbrFrameBase;
begin
for I := 0 to List.Count-1 do
begin
Item := TbrFrameBase(List.Items[I]);
Item.LoadBrzFiles;
end;
end;
{----------------TbrSubFrameSet.ReloadFiles}
procedure TbrSubFrameSet.ReloadFiles(APosition: LongInt);
var
I: integer;
Item: TbrFrameBase;
begin
for I := 0 to List.Count-1 do
begin
Item := TbrFrameBase(List.Items[I]);
Item.ReloadFiles(APosition);
end;
if (FRefreshDelay > 0) and Assigned(RefreshTimer) then
SetRefreshTimer;
Unloaded := False;
end;
{----------------TbrSubFrameSet.UnloadFiles}
procedure TbrSubFrameSet.UnloadFiles;
var
I: integer;
Item: TbrFrameBase;
begin
if Assigned(RefreshTimer) then
RefreshTimer.Enabled := False;
for I := 0 to List.Count-1 do
begin
Item := TbrFrameBase(List.Items[I]);
Item.UnloadFiles;
end;
if Assigned(MasterSet.FrameViewer.FOnSoundRequest) then
MasterSet.FrameViewer.FOnSoundRequest(MasterSet, '', 0, True);
Unloaded := True;
end;
{----------------TbrSubFrameSet.EndFrameSet}
procedure TbrSubFrameSet.EndFrameSet;
{called by the parser when </FrameSet> is encountered}
var
I: integer;
begin
if List.Count > DimCount then {a value left out}
begin {fill in any blanks in Dim array}
for I := DimCount+1 to List.Count do
begin
Dim[I] := -1; {1 relative unit}
Inc(DimCount);
end;
end
else while DimCount > List.Count do {or add Frames if more Dims than Count}
AddFrame(Nil, '');
if ReadHTML.Base <> '' then
FBase := ReadHTML.Base
else FBase := MasterSet.FrameViewer.FBaseEx;
FBaseTarget := ReadHTML.BaseTarget;
end;
{----------------TbrSubFrameSet.InitializeDimensions}
procedure TbrSubFrameSet.InitializeDimensions(X, Y, Wid, Ht: integer);
var
I, Total, PixTot, PctTot, RelTot, Rel, Sum,
Remainder, PixDesired, PixActual: integer;
begin
if Rows then
Total := Ht
else Total := Wid;
PixTot := 0; RelTot := 0; PctTot := 0; DimFTot := 0;
for I := 1 to DimCount do {count up the total pixels, %'s and relatives}
if Dim[I] >= 0 then
PixTot := PixTot + Dim[I]
else if Dim[I] <= -100 then
PctTot := PctTot + (-Dim[I]-100)
else RelTot := RelTot - Dim[I];
Remainder := Total - PixTot;
if Remainder <= 0 then
begin {% and Relative are 0, must scale absolutes}
for I := 1 to DimCount do
begin
if Dim[I] >= 0 then
DimF[I] := MulDiv(Dim[I], Total, PixTot) {reduce to fit}
else DimF[I] := 0;
Inc(DimFTot, DimF[I]);
end;
end
else {some remainder left for % and relative}
begin
PixDesired := MulDiv(Total, PctTot, 100);
if PixDesired > Remainder then
PixActual := Remainder
else PixActual := PixDesired;
Dec(Remainder, PixActual); {Remainder will be >= 0}
if RelTot > 0 then
Rel := Remainder div RelTot {calc each relative unit}
else Rel := 0;
for I := 1 to DimCount do {calc the actual pixel widths (heights) in DimF}
begin
if Dim[I] >= 0 then
DimF[I] := Dim[I]
else if Dim[I] <= -100 then
DimF[I] := MulDiv(-Dim[I]-100, PixActual, PctTot)
else DimF[I] := -Dim[I] * Rel;
Inc(DimFTot, DimF[I]);
end;
end;
Sum := 0;
for I := 0 to List.Count-1 do {intialize the dimensions of contained items}
begin
if Rows then
TbrFrameBase(List.Items[I]).InitializeDimensions(X, Y+Sum, Wid, DimF[I+1])
else
TbrFrameBase(List.Items[I]).InitializeDimensions(X+Sum, Y, DimF[I+1], Ht);
Sum := Sum+DimF[I+1];
end;
end;
{----------------TbrSubFrameSet.CalcSizes}
{OnResize event comes here}
procedure TbrSubFrameSet.CalcSizes(Sender: TObject);
var
I, Step, Sum, ThisTotal: integer;
ARect: TRect;
begin
{Note: this method gets called during Destroy as it's in the OnResize event.
Hence List may be Nil.}
if Assigned(List) and (List.Count > 0) then
begin
ARect := ClientRect;
InflateRect(ARect, -OuterBorder, -OuterBorder);
Sum := 0;
if Rows then ThisTotal := ARect.Bottom - ARect.Top
else ThisTotal := ARect.Right-ARect.Left;
for I := 0 to List.Count-1 do
begin
Step := MulDiv(DimF[I+1], ThisTotal, DimFTot);
if Rows then
TbrFrameBase(List.Items[I]).SetBounds(ARect.Left, ARect.Top+Sum, ARect.Right-ARect.Left, Step)
else
TbrFrameBase(List.Items[I]).SetBounds(ARect.Left+Sum, ARect.Top, Step, ARect.Bottom-Arect.Top);
Sum := Sum+Step;
Lines[I+1] := Sum;
end;
end;
end;
{----------------TbrSubFrameSet.NearBoundary}
function TbrSubFrameSet.NearBoundary(X, Y: integer): boolean;
begin
Result := (Abs(X) < 4) or (Abs(X - Width) < 4) or
(Abs(Y) < 4) or (Abs(Y-Height) < 4);
end;
{----------------TbrSubFrameSet.GetRect}
function TbrSubFrameSet.GetRect: TRect;
{finds the FocusRect to draw when draging boundaries}
var
Pt, Pt1, Pt2: TPoint;
begin
Pt1 := Point(0, 0);
Pt1 := ClientToScreen(Pt1);
Pt2 := Point(ClientWidth, ClientHeight);
Pt2 := ClientToScreen(Pt2);
GetCursorPos(Pt);
if Rows then
Result := Rect(Pt1.X, Pt.Y-1, Pt2.X, Pt.Y+1)
else
Result := Rect(Pt.X-1, Pt1.Y, Pt.X+1, Pt2.Y);
OldRect := Result;
end;
{----------------DrawRect}
procedure DrawRect(ARect: TRect);
{Draws a Focus Rect}
var
DC: HDC;
begin
DC := GetDC(0);
DrawFocusRect(DC, ARect);
ReleaseDC(0, DC);
end;
{----------------TbrSubFrameSet.FVMouseDown}
procedure TbrSubFrameSet.FVMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
var
ACursor: TCursor;
RP: record
case boolean of
True: (P1, P2: TPoint);
False:(R: TRect);
end;
begin
if Button <> mbLeft then Exit;
if NearBoundary(X, Y) then
begin
if Parent is TbrFrameBase then
(Parent as TbrFrameBase).FVMouseDown(Sender, Button, Shift, X+Left, Y+Top)
else
Exit;
end
else
begin
ACursor := (Sender as TbrFrameBase).Cursor;
if (ACursor = crVSplit) or(ACursor = crHSplit) then
begin
MasterSet.HotSet := Self;
with RP do
begin {restrict cursor to lines on both sides}
if Rows then
R := Rect(0, Lines[LineIndex-1]+1, ClientWidth, Lines[LineIndex+1]-1)
else
R := Rect(Lines[LineIndex-1]+1, 0, Lines[LineIndex+1]-1, ClientHeight);
P1 := ClientToScreen(P1);
P2 := ClientToScreen(P2);
ClipCursor(@R);
end;
DrawRect(GetRect);
end;
end;
end;
{----------------TbrSubFrameSet.FindLineAndCursor}
procedure TbrSubFrameSet.FindLineAndCursor(Sender: TObject; X, Y: integer);
var
ACursor: TCursor;
Gap, ThisGap, Line, I: integer;
begin
if not Assigned(MasterSet.HotSet) then
begin {here we change the cursor as mouse moves over lines,button up or down}
if Rows then Line := Y else Line := X;
Gap := 9999;
for I := 1 to DimCount-1 do
begin
ThisGap := Line-Lines[I];
if Abs(ThisGap) < Abs(Gap) then
begin
Gap := Line - Lines[I];
LineIndex := I;
end
else if Abs(ThisGap) = Abs(Gap) then {happens if 2 lines in same spot}
if ThisGap >= 0 then {if Pos, pick the one on right (bottom)}
LineIndex := I;
end;
if (Abs(Gap) <= 4) and not Fixed[LineIndex] then
begin
if Rows then
ACursor := crVSplit
else ACursor := crHSplit;
(Sender as TbrFrameBase).Cursor := ACursor;
end
else (Sender as TbrFrameBase).Cursor := MasterSet.FrameViewer.Cursor;
end
else
with TbrSubFrameSet(MasterSet.HotSet) do
begin
DrawRect(OldRect);
DrawRect(GetRect);
end;
end;
{----------------TbrSubFrameSet.FVMouseMove}
procedure TbrSubFrameSet.FVMouseMove(Sender: TObject; Shift: TShiftState; X,
Y: Integer);
begin
if NearBoundary(X, Y) then
(Parent as TbrFrameBase).FVMouseMove(Sender, Shift, X+Left, Y+Top)
else
FindLineAndCursor(Sender, X, Y);
end;
{----------------TbrSubFrameSet.FVMouseUp}
procedure TbrSubFrameSet.FVMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState;
X, Y: Integer);
var
I: integer;
begin
if Button <> mbLeft then Exit;
if MasterSet.HotSet = Self then
begin
MasterSet.HotSet := Nil;
DrawRect(OldRect);
ClipCursor(Nil);
if Rows then
Lines[LineIndex] := Y else Lines[LineIndex] := X;
for I := 1 to DimCount do
if I = 1 then DimF[1] := MulDiv(Lines[1], DimFTot, Lines[DimCount])
else DimF[I] := MulDiv((Lines[I] - Lines[I-1]), DimFTot, Lines[DimCount]);
CalcSizes(Self);
Invalidate;
end
else if (Parent is TbrFrameBase) then
(Parent as TbrFrameBase).FVMouseUp(Sender, Button, Shift, X+Left, Y+Top);
end;
{----------------TbrSubFrameSet.CheckNoResize}
function TbrSubFrameSet.CheckNoResize(var Lower, Upper: boolean): boolean;
var
Lw, Up: boolean;
I: integer;
begin
Result := False; Lower := False; Upper := False;
for I := 0 to List.Count-1 do
with TbrFrameBase(List[I]) do
if CheckNoResize(Lw, Up) then
begin
Result := True; {sides are fixed}
Fixed[I] := True; {these edges are fixed}
Fixed[I+1] := True;
If Lw and (I = 0) then Lower := True;
If Up and (I = List.Count-1) then Upper := True;
end;
end;
{----------------TbrSubFrameSet.Clear}
procedure TbrSubFrameSet.Clear;
var
I: integer;
X: TbrFrameBase;
begin
for I := List.Count-1 downto 0 do
begin
X := List.Items[I];
List.Delete(I);
RemoveControl(X);
X.Free;
end;
DimCount := 0;
First := True;
Rows := False;
FillChar(Fixed, Sizeof(Fixed), 0);
FillChar(Lines, Sizeof(Lines), 0);
FBase := '';
FBaseTarget := '';
end;
{----------------TbrSubFrameSet.UpdateFrameList}
procedure TbrSubFrameSet.UpdateFrameList;
var
I: integer;
begin
for I := 0 to List.Count-1 do
TbrFrameBase(List[I]).UpdateFrameList;
end;
{----------------TbrSubFrameSet.HandleMeta}
procedure TbrSubFrameSet.HandleMeta(Sender: TObject; const HttpEq, Name, Content: string);
var
DelTime, I: integer;
begin
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
if CompareText(HttpEq, 'content-type') = 0 then
TranslateCharset(Content, LocalCharset);
{$endif}
with MasterSet.FrameViewer do
begin
if Assigned(FOnMeta) then FOnMeta(Sender, HttpEq, Name, Content);
if not (fvMetaRefresh in FOptions) then Exit;
end;
if CompareText(Lowercase(HttpEq), 'refresh') = 0 then
begin
I := Pos(';', Content);
if I > 0 then
DelTime := StrToIntDef(copy(Content, 1, I-1), -1)
else DelTime := StrToIntDef(Content, -1);
if DelTime < 0 then Exit
else if DelTime = 0 then DelTime := 1;
I := Pos('url=', Lowercase(Content));
if I > 0 then
FRefreshURL := Copy(Content, I+4, Length(Content)-I-3)
else FRefreshURL := '';
FRefreshDelay := DelTime;
end;
end;
{----------------TbrSubFrameSet.SetRefreshTimer}
procedure TbrSubFrameSet.SetRefreshTimer;
begin
NextFile := FRefreshURL;
if not Assigned(RefreshTimer) then
RefreshTimer := TTimer.Create(Self);
RefreshTimer.OnTimer := RefreshTimerTimer;
RefreshTimer.Interval := FRefreshDelay*1000;
RefreshTimer.Enabled := True;
end;
{----------------TbrSubFrameSet.RefreshTimerTimer}
procedure TbrSubFrameSet.RefreshTimerTimer(Sender: Tobject);
var
S, D: string;
begin
RefreshTimer.Enabled := False;
if Unloaded then Exit;
if Owner is TbrFrame then
begin
SplitURL(NextFile, S, D);
TbrFrame(Owner).frLoadFromBrzFile(S, D, '', '', '', True, True, True)
end;
end;
{----------------TbrFrameSet.Create}
constructor TbrFrameSet.Create(AOwner: TComponent);
begin
inherited CreateIt(AOwner, Self);
FrameViewer := AOwner as TFrameBrowser;
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
LocalCharSet := FrameViewer.FCharset;
{$endif}
if fvNoBorder in FrameViewer.FOptions then
BorderSize := 0
else
BorderSize := 2;
BevelOuter := bvNone;
FTitle := '';
FrameNames := TStringList.Create;
FrameNames.Sorted := True;
Viewers := TList.Create;
Frames := TList.Create;
OnResize := CalcSizes;
end;
{----------------TbrFrameSet.Destroy}
destructor TbrFrameSet.Destroy;
begin
FrameNames.Free;
FrameNames := Nil; {is tested later}
Viewers.Free;
Viewers := Nil;
Frames.Free;
Frames := Nil;
inherited Destroy;
end;
{----------------TbrFrameSet.Clear}
procedure TbrFrameSet.Clear;
begin
inherited Clear;
FrameNames.Clear;
Viewers.Clear;
Frames.Clear;
HotSet := Nil;
FTitle := '';
FCurrentFile:= '';
OldHeight := 0;
OldWidth := 0;
FActive := Nil;
end;
procedure TbrFrameSet.RePaint;
var
I: integer;
begin
if Assigned(Frames) then
for I := 0 to Frames.Count-1 do
{$IFNDEF LCL}
TWinControl(Frames[I]).RePaint;
{$ELSE}
TCustomControl(Frames[I]).RePaint;
{$ENDIF}
inherited;
end;
{----------------TbrFrameSet.EndFrameSet}
procedure TbrFrameSet.EndFrameSet;
begin
FTitle := ReadHTML.Title;
inherited EndFrameSet;
with ClientRect do
InitializeDimensions(Left, Top, Right-Left, Bottom-Top);
end;
{----------------TbrFrameSet.CalcSizes}
{OnResize event comes here}
procedure TbrFrameSet.CalcSizes(Sender: TObject);
var
ARect: TRect;
begin
ARect := ClientRect;
InflateRect(ARect, -OuterBorder, -OuterBorder);
with ARect do
begin
if (OldWidth <> Right-Left) or (OldHeight <> Bottom-Top) then
begin
InitializeDimensions(Left, Top, Right-Left, Bottom-Top);
inherited CalcSizes(Sender);
end;
OldWidth := Right-Left;
OldHeight := Bottom-Top;
end;
end;
{----------------TbrFrameSet.CheckActive}
procedure TbrFrameSet.CheckActive(Sender: TObject);
begin
if Sender is ThtmlViewer then
FActive := ThtmlViewer(Sender);
end;
{----------------TbrFrameSet.GetActive}
function TbrFrameSet.GetActive: ThtmlViewer;
begin
if Viewers.Count = 1 then
Result := ThtmlViewer(Viewers[0])
else
try
if FActive is ThtmlViewer then Result := FActive
else Result := Nil;
except
Result := Nil;
end;
end;
{----------------TbrFrameSet.FVMouseMove}
procedure TbrFrameSet.FVMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
begin
FindLineAndCursor(Sender, X, Y);
if (LineIndex = 0) or (LineIndex = DimCount) then
begin {picked up the outer boundary}
(Sender as TbrFrameBase).Cursor := MasterSet.FrameViewer.Cursor;
Cursor := MasterSet.FrameViewer.Cursor;
end;
end;
procedure TbrFrameSet.RefreshTimerTimer(Sender: Tobject);
begin
RefreshTimer.Enabled := False;
if (Self = MasterSet.FrameViewer.CurbrFrameSet) then
FrameViewer.LoadURLInternal(NextFile, '', '', '', True, True)
end;
{----------------TbrFrameSet.LoadFromBrzFile}
procedure TbrFrameSet.LoadFromBrzFile(Stream: TMemoryStream; StreamType: ThtmlFileType;
const URL, Dest: string);
var
I: integer;
Item: TbrFrameBase;
Frame: TbrFrame;
Lower, Upper: boolean;
TheString: string;
begin
Clear;
NestLevel := 0;
FCurrentFile := URL;
TheString := StreamToString(Stream);
if (StreamType = HTMLType) and
IsFrameString(lsString, '', TheString, MasterSet.FrameViewer) then
begin {it's a Frameset html file}
FrameParseString(FrameViewer, Self, lsString, '', TheString, HandleMeta);
for I := 0 to List.Count-1 do
Begin
Item := TbrFrameBase(List.Items[I]);
TbrFrameBase(Item).LoadBrzFiles;
end;
CalcSizes(Self);
CheckNoresize(Lower, Upper);
if FRefreshDelay > 0 then
SetRefreshTimer;
end
else
begin {it's a non frame file}
Frame := AddFrame(Nil, '');
Frame.Source := URL;
Frame.TheStream := Stream;
Frame.TheStreamType := StreamType;
Frame.Destination := Dest;
EndFrameSet;
CalcSizes(Self);
Frame.LoadBrzFiles;
FTitle := ReadHTML.Title;
FBase := ReadHTML.Base;
FBaseTarget := ReadHTML.BaseTarget;
end;
end;
{----------------TbrFrameSet.ClearForwards}
procedure TbrFrameSet.ClearForwards;
{clear all the forward items in the history lists}
var
I, J: integer;
Frame: TbrFrame;
AList: TList;
Obj: TObject;
begin
AList := TList.Create;
for J := 0 to Frames.Count-1 do
begin
Frame := TbrFrame(Frames[J]);
with Frame do
begin
for I := 0 to frHistoryIndex-1 do
begin
Obj := frHistory.Objects[0];
if Assigned(Obj) and (AList.IndexOf(Obj) < 0) then
AList.Add(Obj);
frHistory.Delete(0);
PositionObj(frPositionHistory[0]).Free;
frPositionHistory.Delete(0);
end;
frHistoryIndex := 0;
end;
end;
for J := 0 to Frames.Count-1 do {now see which Objects are no longer used}
begin
Frame := TbrFrame(Frames[J]);
with Frame do
begin
for I := 0 to frHistory.Count-1 do
begin
Obj := frHistory.Objects[I];
if Assigned(Obj) and (AList.IndexOf(Obj) > -1) then
AList.Remove(Obj); {remove it if it's there}
end;
end;
end;
for I := 0 to AList.Count-1 do {destroy what's left}
TObject(AList[I]).Free;
AList.Free;
end;
{----------------TbrFrameSet.UpdateFrameList}
procedure TbrFrameSet.UpdateFrameList;
{Fill Frames with a list of all current TFrames}
begin
Frames.Clear;
inherited UpdateFrameList;
end;
{----------------TFrameBrowser.Create}
constructor TFrameBrowser.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Height := 150;
Width := 150;
ProcessList := TList.Create;
FLinkAttributes := TStringList.Create;
FViewImages := True;
FBitmapList := TStringBitmapList.Create;
FImageCacheCount := 5;
FHistory := TStringList.Create;
FPosition := TList.Create;
FTitleHistory := TStringList.Create;
FBackground := clBtnFace;
FFontColor := clBtnText;
FHotSpotColor := clBlue;
FVisitedColor := clPurple;
FOverColor := clBlue;
FVisitedMaxCount := 50;
FFontSize := 12;
FFontName := 'Times New Roman';
FPreFontName := 'Courier New';
FCursor := crIBeam;
FDither := True;
TabStop := False;
FPrintMarginLeft := 2.0;
FPrintMarginRight := 2.0;
FPrintMarginTop := 2.0;
FPrintMarginBottom := 2.0;
FPrintScale := 1.0;
FMarginWidth := 10;
FMarginHeight := 5;
FOptions := [fvPrintTableBackground, fvPrintMonochromeBlack];
{$ifdef ver100_plus} {Delphi 3,4,5, C++Builder 3, 4}
FCharset := DEFAULT_CHARSET;
{$endif}
Visited := TStringList.Create;
FEncodePostArgs := True;
CurbrFrameSet := TbrFrameSet.Create(Self);
if fvNoBorder in FOptions then
begin
CurbrFrameSet.OuterBorder := 0;
CurbrFrameSet.BevelOuter := bvNone;
end
else
begin
CurbrFrameSet.OuterBorder := 2;
CurbrFrameSet.BevelWidth := 2;
CurbrFrameSet.BevelOuter := bvLowered;
end;
CurbrFrameSet.Align := alClient;
InsertControl(CurbrFrameSet);
end;
{----------------TFrameBrowser.Destroy}
destructor TFrameBrowser.Destroy;
begin
ProcessList.Free;
FLinkAttributes.Free;
FHistory.Free;
FPosition.Free;
FTitleHistory.Free;
Visited.Free;
FViewerList.Free;
inherited Destroy;
FBitmapList.Free;
end;
{----------------TFrameBrowser.Clear}
procedure TFrameBrowser.Clear;
var
I: integer;
Obj: TObject;
begin
if not Processing then
begin
for I := 0 to FHistory.Count-1 do
with FHistory do
begin
Obj := Objects[0];
Delete(0);
if Obj <> CurbrFrameSet then
ChkFree(Obj);
end;
with CurbrFrameSet do
begin
Clear;
BevelOuter := bvLowered;
BevelWidth := 2;
end;
FBitmapList.Clear;
FURL := '';
FTarget := '';
FBaseEx := '';
FHistoryIndex := 0;
FPosition.Clear;
FTitleHistory.Clear;
if Assigned(FOnHistoryChange) then
FOnHistoryChange(Self);
Visited.Clear;
if Assigned(FViewerList) then
FViewerList.Clear;
end;
end;
{----------------TFrameBrowser.LoadURL}
procedure TFrameBrowser.LoadURL(const URL: string);
begin
if not Processing then
begin
LoadURLInternal(Normalize(URL), '', '', '', True, False);
end;
end;
{----------------TFrameBrowser.GetPostQuery}
procedure TFrameBrowser.GetPostQuery(const URL, Query, EncType: string; IsGet: boolean);
begin
if not Processing then
LoadURLInternal(Normalize(URL), Query, EncType, '', IsGet, True);
end;
{----------------TFrameBrowser.LoadURLInternal}
procedure TFrameBrowser.LoadURLInternal(const URL, Query, EncType, Referer: string;
IsGet, Reload: boolean);
var
OldFrameSet: TbrFrameSet;
OldFile, S, Dest, S1: string;
OldPos: LongInt;
Tmp: TObject;
SameName: boolean;
{$ifdef Windows}
Dummy: integer;
{$endif}
Stream: TMemoryStream;
StreamType: ThtmlFileType;
I: integer;
begin
if not Assigned(FOnGetPostRequest) and not Assigned(FOnGetPostRequestEx) then
Raise(Exception.Create('No OnGetPostRequest or OnGetPostRequestEx event defined'));
FProcessing := True;
if Assigned(FOnProcessing) then
FOnProcessing(Self, True);
{$ifdef windows}
Dummy :=
{$endif}
IOResult; {remove any pending file errors}
SplitURL(URL, S, Dest);
try
OldFile := CurbrFrameSet.FCurrentFile;
ProcessList.Clear;
if Assigned(FOnSoundRequest) then
FOnSoundRequest(Self, '', 0, True);
SameName := CompareText(OldFile, S) = 0;
if not SameName then
begin
if Assigned(FOnViewerClear) then
for I := 0 to CurbrFrameSet.Viewers.Count-1 do
FOnViewerClear(CurbrFrameSet.Viewers[I]);
OldFrameSet := CurbrFrameSet;
CurbrFrameSet := TbrFrameSet.Create(Self);
CurbrFrameSet.Align := alClient;
CurbrFrameSet.visible := False;
InsertControl(CurbrFrameSet);
CurbrFrameSet.SendToBack;
CurbrFrameSet.Visible := True;
try
S1 := '';
if Assigned(FOnGetPostRequestEx) then
FOnGetPostRequestEx(Self, IsGet, S, Query, EncType, Referer, Reload, S1, StreamType, Stream)
else
FOnGetPostRequest(Self, IsGet, S, Query, Reload, S1, StreamType, Stream);
if not Assigned(Stream) then
Raise(EfvLoadError.Create('Can''t load: '+S));
if S1 <> '' then
S := S1;
if Pos(':', S) <> 0 then
CurbrFrameSet.URLBase := URLSubs.GetBase(S)
else
begin
CurbrFrameSet.URLBase := OldFrameSet.URLBase;
S := Combine(CurbrFrameSet.URLBase, S);
end;
(CurbrFrameSet as TbrFrameSet).LoadFromBrzFile(Stream, StreamType, S, Dest);
except
RemoveControl(CurbrFrameSet);
CurbrFrameSet.Free;
CurbrFrameSet := OldFrameSet;
Raise;
end;
OldPos := 0;
if (OldFrameSet.Viewers.Count = 1) then
begin
Tmp := OldFrameSet.Viewers[0];
if Tmp is ThtmlViewer then
OldPos := ThtmlViewer(Tmp).Position;
end;
OldFrameSet.UnloadFiles;
CurbrFrameSet.Visible := True;
if Visible then
begin
SendMessage(Handle, wm_SetRedraw, 0, 0);
try
CurbrFrameSet.BringToFront;
finally
SendMessage(Handle, wm_SetRedraw, 1, 0);
Repaint;
end;
CurbrFrameSet.Repaint;
end;
RemoveControl(OldFrameSet);
BumpHistory(OldFrameSet, OldPos);
end
else
begin {Same name}
OldPos := 0;
if (CurbrFrameSet.Viewers.Count = 1) then
begin
Tmp := CurbrFrameSet.Viewers[0];
if Tmp is ThtmlViewer then
OldPos := ThtmlViewer(Tmp).Position;
end;
if Assigned(FOnGetPostRequestEx) then
FOnGetPostRequestEx(Self, IsGet, S, Query, EncType, Referer, Reload, S1, StreamType, Stream)
else
FOnGetPostRequest(Self, IsGet, S, Query, Reload, S1, StreamType, Stream);
if not Assigned(Stream) then
Raise(EfvLoadError.Create('Can''t locate cache file: '+S));
if S1 <> '' then
begin
S := S1;
if Pos(':', S) <> 0 then
CurbrFrameSet.URLBase := URLSubs.GetBase(S);
end;
(CurbrFrameSet as TbrFrameSet).LoadFromBrzFile(Stream, StreamType, S, Dest);
BumpHistory2(OldPos); {not executed if exception occurs}
end;
AddVisitedLink(URL);
finally
FProcessing := False;
if Assigned(FOnProcessing) then
FOnProcessing(Self, False);
end;
end;
{----------------TFrameBrowser.Reload}
procedure TFrameBrowser.Reload;
begin
FProcessing := True;
if Assigned(FOnProcessing) then
FOnProcessing(Self, True);
try
ProcessList.Clear;
SendMessage(Self.handle, wm_SetRedraw, 0, 0);
try
CurbrFrameSet.UnloadFiles;
CurbrFrameSet.ReloadFiles(-1);
finally
SendMessage(Self.handle, wm_SetRedraw, 1, 0);
end;
CheckVisitedLinks;
finally
FProcessing := False;
if Assigned(FOnProcessing) then
FOnProcessing(Self, False);
end;
end;
{----------------TFrameBrowser.GetFwdButtonEnabled}
function TFrameBrowser.GetFwdButtonEnabled: boolean;
var
I: integer;
Frame: TbrFrame;
begin
Result := fHistoryIndex >= 1;
if not Result then
for I := 0 to CurbrFrameSet.Frames.Count-1 do
begin
Frame := TbrFrame(CurbrFrameSet.Frames[I]);
with Frame do
if frHistoryIndex >= 1 then
begin
Result := True;
Exit;
end;
end;
end;
{----------------TFrameBrowser.GetBackButtonEnabled}
function TFrameBrowser.GetBackButtonEnabled: boolean;
var
I: integer;
Frame: TbrFrame;
begin
Result := fHistoryIndex <= fHistory.Count-2;
if not Result then
for I := 0 to CurbrFrameSet.Frames.Count-1 do
begin
Frame := TbrFrame(CurbrFrameSet.Frames[I]);
with Frame do
if frHistoryIndex <= frHistory.Count-2 then
begin
Result := True;
Exit;
end;
end;
end;
procedure TFrameBrowser.GoFwd;
var
I, Smallest, Index: integer;
Frame, TheFrame: TbrFrame;
begin
Smallest := 9999;
Index := 0; TheFrame := Nil; {to quiet the warnings}
for I := 0 to CurbrFrameSet.Frames.Count-1 do
begin
Frame := TbrFrame(CurbrFrameSet.Frames[I]);
with Frame do
if frHistoryIndex >= 1 then
with PositionObj(frPositionHistory[frHistoryIndex-1]) do
if Seq < Smallest then
begin
Smallest := Seq;
TheFrame := Frame;
Index := frHistoryIndex;
end;
end;
if Smallest < 9999 then
TheFrame.frSetHistoryIndex(Index - 1)
else SetHistoryIndex(fHistoryIndex - 1);
if Assigned(FOnSoundRequest) then
FOnSoundRequest(Self, '', 0, True);
end;
procedure TFrameBrowser.GoBack;
var
I, Largest, Index: integer;
Frame, TheFrame: TbrFrame;
begin
Largest := -1;
Index := 0; TheFrame := Nil; {to quiet the warnings}
for I := 0 to CurbrFrameSet.Frames.Count-1 do
begin
Frame := TbrFrame(CurbrFrameSet.Frames[I]);
with Frame do
if frHistoryIndex <= frHistory.Count-2 then
with PositionObj(frPositionHistory[frHistoryIndex]) do
if Seq > Largest then
begin
Largest := Seq;
TheFrame := Frame;
Index := frHistoryIndex;
end;
end;
if Largest >= 0 then
TheFrame.frSetHistoryIndex(Index + 1)
else
SetHistoryIndex(fHistoryIndex+1);
if Assigned(FOnSoundRequest) then
FOnSoundRequest(Self, '', 0, True);
end;
{----------------TFrameBrowser.HotSpotClickHandled:}
function TFrameBrowser.HotSpotClickHandled(const FullUrl: string): boolean;
var
Handled: boolean;
begin
Handled := False;
if Assigned(FOnHotSpotTargetClick) then
FOnHotSpotTargetClick(Self, FTarget, FullUrl, Handled);
Result := Handled;
end;
{----------------TFrameBrowser.HotSpotClick}
procedure TFrameBrowser.HotSpotClick(Sender: TObject; const AnURL: string;
var Handled: boolean);
var
I: integer;
Viewer: ThtmlViewer;
FrameTarget: TbrFrameBase;
S, Dest, FullUrl: string;
begin
if Processing then
begin
Handled := True;
Exit;
end;
Viewer := (Sender as ThtmlViewer);
FURL := AnURL;
FTarget := GetActiveTarget;
FLinkAttributes.Text := Viewer.LinkAttributes.Text;
FLinkText := Viewer.LinkText;
SplitUrl(AnUrl, S, Dest);
S := ConvDosToHTML(S);
if S = '' then
FullUrl := (Viewer.FrameOwner as TbrFrame).Source
else if IsFullURL(S) then
FullUrl := S
else if Viewer.Base <> '' then
FullUrl := Combine(UrlSubs.GetBase(ConvDosToHTML(Viewer.Base)), S)
else
FullUrl := Combine((Viewer.FrameOwner as TbrFrame).URLBase, S);
Handled := HotSpotClickHandled(FullUrl + Dest);
if not Handled then
begin
Handled := True;
if (FTarget = '') or (CompareText(FTarget, '_self') = 0) then {no target or _self target}
begin
FrameTarget := Viewer.FrameOwner as TbrFrame;
if not Assigned(FrameTarget) then Exit;
end
else if CurbrFrameSet.FrameNames.Find(FTarget, I) then
FrameTarget := (CurbrFrameSet.FrameNames.Objects[I] as TbrFrame)
else if CompareText(FTarget, '_top') = 0 then
FrameTarget := CurbrFrameSet
else if CompareText(FTarget, '_parent') = 0 then
begin
FrameTarget := (Viewer.FrameOwner as TbrFrame).Owner as TbrFrameBase;
while Assigned(FrameTarget) and not (FrameTarget is TbrFrame)
and not (FrameTarget is TbrFrameSet) do
FrameTarget := FrameTarget.Owner as TbrFrameBase;
end
else
begin
if Assigned(FOnBlankWindowRequest) then
begin
AddVisitedLink(FullUrl + Dest);
CheckVisitedLinks;
FOnBlankWindowRequest(Self, FTarget, FullUrl + Dest);
Handled := True;
end
else Handled := FTarget <> ''; {true if can't find target window}
Exit;
end;
FProcessing := True;
if Assigned(FOnProcessing) then
FOnProcessing(Self, True);
if (FrameTarget is TbrFrame) and (CurbrFrameSet.Viewers.Count = 1) and (S <> '')
and (CompareText(S, CurbrFrameSet.FCurrentFile) <> 0) then
FrameTarget := CurbrFrameSet; {force a new FrameSet on name change}
try
if FrameTarget is TbrFrame then
TbrFrame(FrameTarget).frLoadFromBrzFile(FullUrl, Dest, '', '', Viewer.CurrentFile, True, True, False)
else if FrameTarget is TbrFrameSet then
Self.LoadURLInternal(FullUrl + Dest, '', '', Viewer.CurrentFile, True, False);
CheckVisitedLinks;
finally
FProcessing := False; {changed position}
if Assigned(FOnProcessing) then
FOnProcessing(Self, False);
end;
end;
end;
function TFrameBrowser.GetCurViewerCount: integer;
begin
Result := CurbrFrameSet.Viewers.Count;
end;
function TFrameBrowser.GetCurViewer(I: integer): ThtmlViewer;
begin
Result := CurbrFrameSet.Viewers[I];
end;
{----------------TFrameBrowser.HotSpotCovered}
procedure TFrameBrowser.HotSpotCovered(Sender: TObject; const SRC: string);
var
S, Dest, FullUrl: string;
Viewer: ThtmlViewer;
begin
if Assigned(FOnHotSpotTargetCovered) then
begin
Viewer := Sender as ThtmlViewer;
SplitUrl(SRC, S, Dest);
S := ConvDosToHTML(S); {convert DOS names}
if IsFullURL(S) or (Src = '') then
FullUrl := S
else
begin
if Viewer.Base <> '' then
FullUrl := Combine(UrlSubs.GetBase(ConvDosToHTML(Viewer.Base)), S)
else
FullUrl := Combine((Viewer.FrameOwner as TbrFrame).URLBase, S);
end;
FLinkText := Viewer.LinkText;
FLinkAttributes.Text := Viewer.LinkAttributes.Text;
FOnHotSpotTargetCovered(Sender, (Sender as ThtmlViewer).Target, FullUrl+Dest);
end;
end;
{----------------TFrameBrowser.GetActiveTarget}
function TFrameBrowser.GetActiveTarget: string;
var
Vw: ThtmlViewer;
Done: boolean;
FSet: TbrSubFrameSet;
begin
Result := '';
Vw := GetActiveViewer;
if Assigned(Vw) then
begin
Result := Vw.Target;
if Result = '' then Result := Vw.BaseTarget;
Done := False;
FSet := TbrFrame(Vw.FrameOwner).LOwner;
while (Result = '') and Assigned(FSet) and not Done do
begin
Result := FSet.FBaseTarget;
Done := FSet = CurbrFrameSet;
if not Done then FSet := FSet.LOwner;
end;
end;
end;
function TFrameBrowser.GetBase: string;
begin
Result := CurbrFrameSet.FBase;
end;
procedure TFrameBrowser.SetBase(Value: string);
begin
CurbrFrameSet.FBase := Value;
FBaseEx := Value;
end;
function TFrameBrowser.GetBaseTarget: string;
begin
Result := CurbrFrameSet.FBaseTarget;
end;
function TFrameBrowser.GetTitle: string;
begin
Result := CurbrFrameSet.FTitle;
end;
function TFrameBrowser.GetCurrentFile: string;
begin
Result := CurbrFrameSet.FCurrentFile;
end;
{----------------TFrameBrowser.GetActiveViewer}
function TFrameBrowser.GetActiveViewer: ThtmlViewer;
begin
Result := CurbrFrameSet.GetActive;
end;
{----------------TFrameBrowser.BumpHistory}
procedure TFrameBrowser.BumpHistory(OldFrameSet: TbrFrameSet; OldPos: LongInt);
{OldFrameSet never equals CurbrFrameSet when this method called}
var
I: integer;
Obj: TObject;
begin
if (FHistoryMaxCount > 0) and (CurbrFrameSet.FCurrentFile <> '') then
with FHistory do
begin
if (Count > 0) then
begin
Strings[FHistoryIndex] := OldFrameSet.FCurrentFile;
Objects[FHistoryIndex] := OldFrameSet;
FTitleHistory[FHistoryIndex] := OldFrameSet.FTitle;
FPosition[FHistoryIndex] := TObject(OldPos);
OldFrameSet.ClearForwards;
end
else OldFrameSet.Free;
for I := 0 to FHistoryIndex-1 do
begin
Obj := Objects[0];
Delete(0);
ChkFree(Obj);
FTitleHistory.Delete(0);
FPosition.Delete(0);
end;
FHistoryIndex := 0;
Insert(0, CurbrFrameSet.FCurrentFile);
Objects[0] := CurbrFrameSet;
FTitleHistory.Insert(0, CurbrFrameSet.FTitle);
FPosition.Insert(0, Nil);
if Count > FHistoryMaxCount then
begin
Obj := Objects[FHistoryMaxCount];
Delete(FHistoryMaxCount);
ChkFree(Obj);
FTitleHistory.Delete(FHistoryMaxCount);
FPosition.Delete(FHistoryMaxCount);
end;
if Assigned(FOnHistoryChange) then FOnHistoryChange(Self);
end
else OldFrameSet.Free;
end;
{----------------TFrameBrowser.BumpHistory1}
procedure TFrameBrowser.BumpHistory1(const FileName, Title: string;
OldPos: LongInt; ft: ThtmlFileType);
{This variation called when CurbrFrameSet contains only a single viewer before
and after the change}
var
I: integer;
Obj: TObject;
begin
if (FHistoryMaxCount > 0) and (Filename <> '') then
with FHistory do
begin
if (Count > 0) then
begin
Strings[FHistoryIndex] := Filename;
Objects[FHistoryIndex] := CurbrFrameSet;
FTitleHistory[FHistoryIndex] := Title;
FPosition[FHistoryIndex] := TObject(OldPos);
end;
for I := 0 to FHistoryIndex-1 do
begin
Obj := Objects[0];
Delete(0);
ChkFree(Obj);
FTitleHistory.Delete(0);
FPosition.Delete(0);
end;
FHistoryIndex := 0;
Insert(0, CurbrFrameSet.FCurrentFile);
Objects[0] := CurbrFrameSet;
FTitleHistory.Insert(0, CurbrFrameSet.FTitle);
FPosition.Insert(0, Nil);
if Count > FHistoryMaxCount then
begin
Obj := Objects[FHistoryMaxCount];
Delete(FHistoryMaxCount);
ChkFree(Obj);
FTitleHistory.Delete(FHistoryMaxCount);
FPosition.Delete(FHistoryMaxCount);
end;
if Assigned(FOnHistoryChange) then FOnHistoryChange(Self);
end;
end;
{----------------TFrameBrowser.BumpHistory2}
procedure TFrameBrowser.BumpHistory2(OldPos: LongInt);
{CurbrFrameSet has not changed when this method called}
var
I: integer;
Obj: TObject;
begin
if (FHistoryMaxCount > 0) and (CurbrFrameSet.FCurrentFile <> '') then
with FHistory do
begin
if (Count > 0) then
begin
Strings[FHistoryIndex] := CurbrFrameSet.FCurrentFile;
Objects[FHistoryIndex] := CurbrFrameSet;
FTitleHistory[FHistoryIndex] := CurbrFrameSet.FTitle;
FPosition[FHistoryIndex] := TObject(OldPos);
end;
for I := 0 to FHistoryIndex-1 do
begin
Obj := Objects[0];
Delete(0);
ChkFree(Obj);
FTitleHistory.Delete(0);
FPosition.Delete(0);
end;
FHistoryIndex := 0;
Insert(0, CurbrFrameSet.FCurrentFile);
Objects[0] := CurbrFrameSet;
FTitleHistory.Insert(0, CurbrFrameSet.FTitle);
FPosition.Insert(0, Nil);
if Count > FHistoryMaxCount then
begin
Obj := Objects[FHistoryMaxCount];
Delete(FHistoryMaxCount);
ChkFree(Obj);
FTitleHistory.Delete(FHistoryMaxCount);
FPosition.Delete(FHistoryMaxCount);
end;
if Assigned(FOnHistoryChange) then FOnHistoryChange(Self);
end;
end;
{----------------TFrameBrowser.SetHistoryIndex}
procedure TFrameBrowser.SetHistoryIndex(Value: integer);
var
FrameSet, FrameSet1: TbrFrameSet;
Tmp: TObject;
begin
with CurbrFrameSet, FHistory do
if (Value <> FHistoryIndex) and (Value >= 0) and (Value < Count)
and not Processing then
begin
if CurbrFrameSet.Viewers.Count > 0 then
Tmp := CurbrFrameSet.Viewers[0]
else Tmp := Nil;
if FCurrentFile <> '' then
begin
{Objects[FHistoryIndex] should have CurbrFrameSet here}
FTitleHistory[FHistoryIndex] := CurbrFrameSet.FTitle;
if (Tmp is ThtmlViewer) then
FPosition[FHistoryIndex] := TObject((Tmp as ThtmlViewer).Position)
else FPosition[FHistoryIndex] := Nil;
end;
FrameSet := Objects[Value] as TbrFrameSet;
if FrameSet <> CurbrFrameSet then
begin
FrameSet1 := CurbrFrameSet; {swap framesets}
CurbrFrameSet := FrameSet;
CurbrFrameSet.OldWidth := 0; {encourage recalc of internal layout}
CurbrFrameSet.Visible := False;
Self.InsertControl(CurbrFrameSet);
if CurbrFrameSet.Viewers.Count = 1 then
CurbrFrameSet.ReloadFiles(LongInt(FPosition[Value]))
else
CurbrFrameSet.ReloadFiles(-1);
SendMessage(Self.handle, wm_SetRedraw, 0, 0);
CurbrFrameSet.Visible := True;
SendMessage(Self.handle, wm_SetRedraw, 1, 0);
CurbrFrameSet.Repaint;
FrameSet1.Unloadfiles;
Self.RemoveControl(FrameSet1);
end
else
begin
if (Tmp is ThtmlViewer) then
TbrFrame(ThtmlViewer(Tmp).FrameOwner).ReloadFile(FHistory[Value],
LongInt(FPosition[Value]));
end;
FHistoryIndex := Value;
if Assigned(FOnHistoryChange) then FOnHistoryChange(Self);
CheckVisitedLinks;
end;
end;
{----------------TFrameBrowser.ChkFree}
procedure TFrameBrowser.ChkFree(Obj: TObject);
{Frees a TbrFrameSet only if it no longer exists in FHistory}
var
I: integer;
begin
for I := 0 to FHistory.Count-1 do
if Obj = FHistory.Objects[I] then Exit;
(Obj as TbrFrameSet).Free;
end;
{----------------TFrameBrowser.ClearHistory}
procedure TFrameBrowser.ClearHistory;
var
I: integer;
Obj: TObject;
DidSomething: boolean;
begin
DidSomething := FHistory.Count > 0;
for I := FHistory.Count-1 downto 0 do
begin
Obj := FHistory.Objects[I];
FHistory.Delete(I);
if Obj <> CurbrFrameSet then
ChkFree(Obj);
end;
if Assigned(CurbrFrameSet) then
for I := 0 to CurbrFrameSet.Frames.Count-1 do
with TbrFrame(CurbrFrameSet.Frames[I]) do
begin
DidSomething := DidSomething or (frHistory.Count > 0);
frHistoryIndex := 0;
frHistory.Clear;
frPositionHistory.Clear;
end;
FHistory.Clear;
FTitleHistory.Clear;
FPosition.Clear;
FHistoryIndex := 0;
if DidSomething and Assigned(FOnHistoryChange) then
FOnHistoryChange(Self);
end;
function TFrameBrowser.ViewerFromTarget(const Target: string): ThtmlViewer;
var
I: integer;
begin
if Assigned(CurbrFrameSet) and Assigned(CurbrFrameSet.FrameNames)
and CurbrFrameSet.FrameNames.Find(Target, I)
and (CurbrFrameSet.FrameNames.Objects[I] <> Nil)
and Assigned((CurbrFrameSet.FrameNames.Objects[I] as TbrFrame).Viewer) then
Result := TbrFrame(CurbrFrameSet.FrameNames.Objects[I]).Viewer as ThtmlViewer
else Result := Nil;
end;
procedure TFrameBrowser.RePaint;
begin
if Assigned(CurbrFrameSet) then
CurbrFrameSet.RePaint;
end;
procedure TFrameBrowser.SetOptions(Value: TFrameViewerOptions);
var
I: integer;
begin
if (fvNoBorder in FOptions) <> (fvNoBorder in Value) then
if fvNoBorder in Value then
begin
CurbrFrameSet.OuterBorder := 0;
CurbrFrameSet.BevelOuter := bvNone;
end
else
begin
CurbrFrameSet.OuterBorder := 2;
CurbrFrameSet.BevelWidth := 2;
CurbrFrameSet.BevelOuter := bvLowered;
end;
for I := 0 to CurbrFrameSet.Viewers.Count-1 do
with ThtmlViewer(CurbrFrameSet.Viewers[I]) do
begin
if (fvOverLinksActive in Value) then
htOptions := htOptions + [htOverLinksActive]
else htOptions := htOptions - [htOverLinksActive];
if (fvNoLinkUnderline in Value) then
htOptions := htOptions + [htNoLinkUnderline]
else htOptions := htOptions - [htNoLinkUnderline];
if (fvPrintTableBackground in Value) then
htOptions := htOptions + [htPrintTableBackground]
else htOptions := htOptions - [htPrintTableBackground];
if (fvPrintBackground in Value) then
htOptions := htOptions + [htPrintBackground]
else htOptions := htOptions - [htPrintBackground];
if (fvPrintMonochromeBlack in Value) then
htOptions := htOptions + [htPrintMonochromeBlack]
else htOptions := htOptions - [htPrintMonochromeBlack];
if (fvShowVScroll in Value) then
htOptions := htOptions + [htShowVScroll]
else htOptions := htOptions - [htShowVScroll];
if (fvNoWheelMouse in Value) then
htOptions := htOptions + [htNoWheelMouse]
else htOptions := htOptions - [htNoWheelMouse];
if (fvNoLinkHilite in Value) then
htOptions := htOptions + [htNoLinkHilite]
else htOptions := htOptions - [htNoLinkHilite];
if (fvNoFocusRect in Value) or (fvNoBorder in Value) then
BorderStyle := htNone
else BorderStyle := htFocused;
end;
FOptions := Value;
end;
procedure TFrameBrowser.AddFrame(FrameSet: TObject; Attr: TAttributeList; const FName: string);
begin
(FrameSet as TbrSubFrameSet).AddFrame(Attr, FName);
end;
function TFrameBrowser.CreateSubFrameSet(FrameSet: TObject): TObject;
var
NewFrameSet, FS: TbrSubFrameSet;
begin
FS := (FrameSet as TbrSubFrameSet);
NewFrameSet := TbrSubFrameSet.CreateIt(FS, CurbrFrameSet);
FS.List.Add(NewFrameSet);
FS.InsertControl(NewFrameSet);
Result := NewFrameSet;
end;
procedure TFrameBrowser.DoAttributes(FrameSet: TObject; Attr: TAttributeList);
begin
(FrameSet as TbrSubFrameSet).DoAttributes(Attr);
end;
procedure TFrameBrowser.EndFrameSet(FrameSet: TObject);
begin
(FrameSet as TbrSubFrameSet).EndFrameSet;
end;
procedure TFrameBrowser.SetOnProgress(Handler: ThtProgressEvent);
var
I: integer;
begin
FOnProgress := Handler;
with CurbrFrameSet do
for I := 0 to Viewers.Count-1 do
with ThtmlViewer(Viewers[I]) do
OnProgress := Handler;
end;
procedure TFrameBrowser.SetDragDrop(const Value: TDragDropEvent);
var
I: integer;
begin
FOnDragDrop := Value;
if Assigned(CurbrFrameSet) then
if Assigned(Value) then
CurbrFrameSet.OnDragDrop := fvDragDrop
else CurbrFrameSet.OnDragDrop := Nil;
for I := 0 to GetCurViewerCount-1 do
if Assigned(Value) then
CurViewer[I].OnDragDrop := fvDragDrop
else CurViewer[I].OnDragDrop := Nil;
end;
procedure TFrameBrowser.fvDragDrop(Sender, Source: TObject; X, Y: Integer);
begin
if Assigned(FOnDragDrop) then
FOnDragDrop(Self, Source, X, Y);
end;
procedure TFrameBrowser.SetDragOver(const Value: TDragOverEvent);
var
I: integer;
begin
FOnDragOver := Value;
if Assigned(CurbrFrameSet) then
if Assigned(Value) then
CurbrFrameSet.OnDragOver := fvDragOver
else CurbrFrameSet.OnDragOver := Nil;
for I := 0 to GetCurViewerCount-1 do
if Assigned(Value) then
CurViewer[I].OnDragOver := fvDragOver
else CurViewer[I].OnDragOver := Nil;
end;
procedure TFrameBrowser.fvDragOver(Sender, Source: TObject; X, Y: Integer;
State: TDragState; var Accept: Boolean);
begin
if Assigned(FOnDragOver) then
FOnDragOver(Self, Source, X, Y, State, Accept);
end;
{----------------TFrameBrowser.SetOnImageRequest}
procedure TFrameBrowser.SetOnImageRequest(const Value: TGetImageEvent);
var
I: integer;
begin
FOnImageRequest := Value;
with CurbrFrameSet do
for I := 0 to Viewers.Count-1 do
with ThtmlViewer(Viewers[I]) do
OnImageRequest := Value;
end;
{----------------TFrameBrowser.DoFormSubmitEvent}
procedure TFrameBrowser.DoFormSubmitEvent(Sender: TObject; const Action, Target, EncType,
Method: string; Results: TStringList);
var
S, Dest, Query: string;
FrameTarget: TbrFrameBase;
I: integer;
Viewer: ThtmlViewer;
UserHandled, IsGet: boolean;
function AssembleQuery: string;
var
S1: string;
I, J: integer;
function Encode(const S: string): string;
var
Ch: char;
I: integer;
begin {convert odd chars into %xx -- does not handle the '=' sign yet}
Result := '';
for I := 1 to Length(S) do
begin
Ch := S[I];
if Ch = ' ' then Result := Result+'+'
else if not (Ch in ['a'..'z', 'A'..'Z', '0'..'9', '=', '_','-','.','*','@']) then
Result := Result+'%'+IntToHex(ord(Ch),2)
else Result := Result+Ch;
end;
end;
begin
Result := '';
for I := 0 to Results.Count-1 do
begin
if FEncodePostArgs then
begin {form a string from the TStringList using '+' for spaces and '&' for separaters}
S1 := Encode(Results[I]);
J := Pos(' ', S1);
while J > 0 do
begin
S1[J] := '+';
J := Pos(' ', S1);
end;
end
else S1 := Trim(Results[I]); {No encoding done}
if I <> 0 then
Result := Result + '&';
Result := Result + S1;
end;
Results.Free;
end;
begin
if InFormSubmit then
Exit;
InFormSubmit := True;
try
{see if the application wants to handle this event}
UserHandled := false;
Viewer := (Sender as ThtmlViewer);
if Assigned(FOnFormSubmit) then
FOnFormSubmit(Self, Viewer, Action, Target, EncType, Method, Results, UserHandled);
if not UserHandled then
begin
Query := AssembleQuery;
if (Target = '') or (CompareText(Target, '_self') = 0) then {no target or _self target}
FrameTarget := Viewer.FrameOwner as TbrFrame
else if CurbrFrameSet.FrameNames.Find(Target, I) then
FrameTarget := (CurbrFrameSet.FrameNames.Objects[I] as TbrFrame)
else if CompareText(Target, '_top') = 0 then
FrameTarget := CurbrFrameSet
else if CompareText(Target, '_parent') = 0 then
begin
FrameTarget := (Viewer.FrameOwner as TbrFrame).Owner as TbrFrameBase;
while Assigned(FrameTarget) and not (FrameTarget is TbrFrame)
and not (FrameTarget is TbrFrameSet) do
FrameTarget := FrameTarget.Owner as TbrFrameBase;
end
else
begin
if Assigned(FOnBlankWindowRequest) then
FOnBlankWindowRequest(Self, Target, Action+'?'+Query);
Exit;
end;
S := Action;
I := Pos('#', S);
if I >= 1 then
begin
Dest := System.Copy(S, I, Length(S)-I+1); {local destination}
S := System.Copy(S, 1, I-1); {the file name}
end
else
Dest := ''; {no local destination}
FProcessing := True;
if Assigned(FOnProcessing) then
FOnProcessing(Self, True);
if (FrameTarget is TbrFrame) and (CurbrFrameSet.Viewers.Count = 1) and (S <> '')
and (CompareText(S, CurbrFrameSet.FCurrentFile) <> 0) then
FrameTarget := CurbrFrameSet; {force a new FrameSet on name change}
try
if S = '' then
S := (Viewer.FrameOwner as TbrFrame).Source
else if not IsFullURL(S) then
S := Combine((Viewer.FrameOwner as TbrFrame).URLBase, S);
IsGet := CompareText(Method, 'get') = 0;
if FrameTarget is TbrFrame then
TbrFrame(FrameTarget).frLoadFromBrzFile(S, Dest, Query, EncType,
Viewer.CurrentFile, True, IsGet, True)
else if FrameTarget is TbrFrameSet then
Self.LoadURLInternal(S + Dest, Query, EncType, Viewer.CurrentFile, IsGet, True);
finally
FProcessing := False;
if Assigned(FOnProcessing) then
FOnProcessing(Self, False);
end;
end;
finally
InFormSubmit := False;
end;
end;
procedure TFrameBrowser.DoURLRequest(Sender: TObject; const SRC: string; var Stream: TMemoryStream);
var
NewURL: string;
DocType: ThtmlFileType;
begin
if Assigned(FOnGetPostRequestEx) then
FOnGetPostRequestEx(Sender, True, SRC, '', '', '', False, NewURL, DocType, Stream)
else if Assigned(FOnGetPostRequest) then
FOnGetPostRequest(Sender, True, SRC, '', False, NewURL, DocType, Stream);
end;
{----------------TFrameBrowser.GetViewerUrlBase}
function TFrameBrowser.GetViewerUrlBase(Viewer: ThtmlViewer): string;
var
Frame: TbrFrame;
begin
try
Frame := (Viewer as ThtmlViewer).FrameOwner as TbrFrame;
Result := Frame.UrlBase;
except
Result := '';
end;
end;
{----------------TFrameBrowser.AddVisitedLink}
procedure TFrameBrowser.AddVisitedLink(const S: string);
var
I: integer;
begin
if (FVisitedMaxCount = 0) then
Exit;
I := Visited.IndexOf(S);
if I = 0 then
Exit
else if I > 0 then
Visited.Delete(I); {thus moving it to the top}
Visited.Insert(0, S);
for I := Visited.Count-1 downto FVisitedMaxCount do
Visited.Delete(I);
end;
{----------------TFrameBrowser.CheckVisitedLinks}
procedure TFrameBrowser.CheckVisitedLinks;
var
I, J, K: integer;
S, S1: string;
Viewer: ThtmlViewer;
begin
if FVisitedMaxCount = 0 then
Exit;
for K := 0 to CurbrFrameSet.Viewers.Count-1 do
begin
Viewer := ThtmlViewer(CurbrFrameSet.Viewers[K]);
for I := 0 to Visited.Count-1 do
begin
S := Visited[I];
for J := 0 to Viewer.LinkList.Count-1 do
with TFontObj(Viewer.LinkList[J]) do
begin
if Url <> '' then
begin
if IsFullURL(Url) then
S1 := Url
else if Url[1] = '#' then
S1 := TbrFrame(Viewer.FrameOwner).Source+Url
else S1 := Combine(TbrFrame(Viewer.FrameOwner).UrlBase, Url);
if CompareText(S, S1) = 0 then
Visited := True;
end;
end;
end;
Viewer.Invalidate;
end;
end;
{----------------TFrameBrowser.GetViewers}
function TFrameBrowser.GetViewers: TStrings;
var
I: integer;
S: string;
AFrame: TbrFrame;
Viewer: ThtmlViewer;
Pt1, Pt2: TPoint;
begin
if not Assigned(FViewerList) then
FViewerList := TStringList.Create
else FViewerList.Clear;
for I := 0 to CurbrFrameSet.Viewers.Count-1 do
begin
Viewer := CurbrFrameSet.Viewers[I];
if Viewer.SectionList.Count > 0 then
begin
S := '';
AFrame := TbrFrame(Viewer.FrameOwner);
Pt1 := AFrame.ClientToScreen(Point(0,0));
Pt2 := CurbrFrameSet.ClientToScreen(Point(0,0));
if Pt1.X <= Pt2.X +2 then
S := S+'l';
if Pt1.Y <= Pt2.Y +2 then
S := S+'t';
Pt1 := AFrame.ClientToScreen(Point(AFrame.ClientWidth, AFrame.ClientHeight));
Pt2 := CurbrFrameSet.ClientToScreen(Point(CurbrFrameSet.ClientWidth, CurbrFrameSet.ClientHeight));
if Pt1.X >= Pt2.X -2 then
S := S+'r';
if Pt1.Y >= Pt2.Y -2 then
S := S+'b';
FViewerList.AddObject(S, Viewer);
end;
end;
Result := FViewerList;
end;
{----------------PositionObj}
destructor PositionObj.Destroy;
begin
FormData.Free;
inherited;
end;
end.