home *** CD-ROM | disk | FTP | other *** search
/ QBasic & Borland Pascal & C / Delphi5.iso / Runimage / Delphi50 / Source / Internet / MIDPROD.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1999-08-11  |  23.0 KB  |  760 lines

  1.  
  2. {*******************************************************}
  3. {                                                       }
  4. {       Borland Delphi Visual Component Library         }
  5. {                                                       }
  6. {       Copyright (c) 1999 Inprise Corporation          }
  7. {                                                       }
  8. {*******************************************************}
  9.  
  10. unit MidProd;
  11.  
  12. interface
  13.  
  14. uses Classes, Messages, ImgList, HTTPApp, PagItems, XMLBrokr,
  15.   CompProd, WebComp, SysUtils;
  16.  
  17. type
  18.  
  19.   TXMLDataEvent = procedure (Sender: TObject; Request: TWebRequest; XMLBroker: TXMLBroker; var OwnerData: OleVariant) of object;
  20.  
  21.   TMidasPageElements = class(TObject)
  22.   public
  23.     IncludesContent: string;
  24.     StylesContent: string;
  25.     FormsContent: string;
  26.     ScriptContent: string;
  27.     WarningsContent: string;
  28.     function BodyContent: string; virtual;
  29.   end;
  30.  
  31.   TStdInclude = (jsDom, jsDB, jsDisp, jsBind, jsErrDisp, jsShow);
  32.   TStdIncludes = set of TStdInclude;
  33.  
  34.   TCustomMidasPageProducer = class(TPageItemsProducer, IWebContent, IWebComponentEditor,
  35.     IScriptProducer)
  36.   private
  37.     FPageElements: TMidasPageElements;
  38.     FStyles: TStrings;
  39.     FEnableXMLIslands: Boolean;
  40.     FIncludePathURL: string;
  41.     FScriptManager: IScriptManager;
  42.     FBeforeGetXMLData: TXMLDataEvent;
  43.     FAfterGetXMLData: TXMLDataEvent;
  44.     FStylesFile: TFileName;
  45.     FBeforeGetContent: TNotifyEvent;
  46.     FAfterGetContent: TNotifyEvent;
  47.   protected
  48.     { IWebComponentEditor }
  49.     function CanAddClass(AParent: TComponent; AClass: TClass): Boolean;
  50.     function ImplCanAddClass(AParent: TComponent; AClass: TClass): Boolean; virtual;
  51.  
  52.     procedure DoBeforeGetXMLData(XMLBroker: TXMLBroker; var OwnerData: OleVariant);
  53.     procedure DoAfterGetXMLData(XMLBroker: TXMLBroker; var OwnerData: OleVariant);
  54.     procedure DoBeforeGetContent;
  55.     procedure DoAfterGetContent;
  56.     procedure GeneratePageElements; virtual;
  57.     procedure DoTagEvent(Tag: TTag; const TagString: string; TagParams: TStrings;
  58.       var ReplaceText: string); override;
  59.     function GetContentOptions(var Owned: Boolean): TWebContentOptions; override;
  60.     { IWebContent }
  61.     function IWebContent.Content = WebContent;
  62.     function WebContent(Options: TWebContentOptions; Layout: TLayout): string;
  63.     { IScriptProducer }
  64.     function GetScriptManager: IScriptManager;
  65.     function GetXMLDelta(XMLBroker: TXMLBroker): string;
  66.     function GetXMLErrors(XMLBroker: TXMLBroker): string;
  67.     function GetDefaultTemplate: string; virtual;
  68.     function GetUseXMLIslands: Boolean; virtual;
  69.     function DeclareRowSets: string; virtual;
  70.     function DeclareXMLDocuments: string; virtual;
  71.     function DeclareXMLIslands: string; virtual;
  72.     function DeclareIncludes: string; virtual;
  73.     function DeclareStyles: string; virtual;
  74.     function DeclareFunctions: string; virtual;
  75.     function DeclareWarnings(Warnings: TStrings): string; virtual;
  76.     function DeclareScript(XMLIslands: Boolean): string; virtual;
  77.     procedure AddScriptComponents; virtual;
  78.     procedure AddIncludes; virtual;
  79.     function CreateScriptManager(Options: TWebContentOptions): TObject; virtual;
  80.     function CreatePageElements: TMidasPageElements; virtual;
  81.     property ScriptManager: IScriptManager read GetScriptManager;
  82.     property PageElements: TMidasPageElements read FPageElements;
  83.   public
  84.     constructor Create(AComponent: TComponent); override;
  85.     destructor Destroy; override;
  86.     function FindXMLBroker(TagParams: TStrings): TXMLBroker; virtual;
  87.     function FindXMLBrokerName(TagParams: TStrings): string;  virtual;
  88.     function GetXMLData(XMLBroker: TXMLBroker; XMLOptions: TXMLOptions): string; virtual;
  89.     function Content: string; override;
  90.     procedure SetIncludePathURL(const Value: string);
  91.     procedure SetStyles(Value: TStrings);
  92.     procedure SetStylesFile(const Value: TFileName);
  93.     property IncludePathURL: string read FIncludePathURL write SetIncludePathURL;
  94.     property OnBeforeGetXMLData: TXMLDataEvent read FBeforeGetXMLData write FBeforeGetXMLData;
  95.     property OnAfterGetXMLData: TXMLDataEvent read FAfterGetXMLData write FAfterGetXMLData;
  96.     property OnBeforeGetContent: TNotifyEvent read FBeforeGetContent write FBeforeGetContent;
  97.     property OnAfterGetContent: TNotifyEvent read FAfterGetContent write FAfterGetContent;
  98.     property Styles: TStrings read FStyles write SetStyles;
  99.     property StylesFile: TFileName read FStylesFile write SetStylesFile;
  100.     property EnableXMLIslands: Boolean read FEnableXMLIslands write FEnableXMLIslands default true;
  101.   end;
  102.  
  103.   TMidasPageProducer = class(TCustomMidasPageProducer)
  104.   published
  105.     property IncludePathURL;
  106.     property OnBeforeGetXMLData;
  107.     property OnAfterGetXMLData;
  108.     property OnBeforeGetContent;
  109.     property OnAfterGetContent;
  110.     property Styles;
  111.     property StylesFile;
  112.     property WebPageItems;
  113.     property EnableXMLIslands;
  114.   end;
  115.  
  116. const
  117.   sXMLBroker = 'XMLBROKER';
  118.   sXMLReadyVar = 'xml_ready';
  119.  
  120. procedure AddStdIncludes(StdIncludes: TStdIncludes; AddIntf: IAddScriptElements);
  121. function PathInfoToRelativePath(const PathInfo: string): string;
  122.  
  123. implementation
  124.  
  125. uses Forms, Menus, Consts, Graphics, Controls, WebConst,
  126.   Db, DbClient, ScrptMgr, MidItems, WbmConst;
  127.  
  128. { TCustomMidasPageProducer }
  129.  
  130. const
  131.   sDataPacketTag = 'DATAPACKET';
  132.   sQuoteXMLAttribute = 'QUOTE';
  133.   sQuoteXML = sQuoteXMLAttribute + '="True"'; // Do not localize
  134.   sScriptTag = 'SCRIPT';
  135.   sStylesTag = 'STYLES';
  136.   sFormsTag = 'FORMS';
  137.   sIncludesTag = 'INCLUDES';
  138.   sBodyTag = 'BODYELEMENTS';
  139.   sWarningsTag = 'WARNINGS';
  140.  
  141. function TCustomMidasPageProducer.FindXMLBrokerName(TagParams: TStrings): string;
  142. begin
  143.   Result := TagParams.Values[sXMLBroker];
  144. end;
  145.  
  146. function TCustomMidasPageProducer.FindXMLBroker(TagParams: TStrings): TXMLBroker;
  147. var
  148.   XMLBrokerName: string;
  149.   Component: TComponent;
  150. begin
  151.   XMLBrokerName := FindXMLBrokerName(TagParams);
  152.   if XMLBrokerName <> '' then
  153.     if Owner <> nil then
  154.     begin
  155.       Component := Owner.FindComponent(XMLBrokerName);
  156.       if Assigned(Component) and (Component is TXMLBroker) then
  157.       begin
  158.         Result := TXMLBroker(Component);
  159.         Exit;
  160.       end;
  161.     end;
  162.   Result := nil;
  163. end;
  164.  
  165. function TCustomMidasPageProducer.GetXMLDelta(XMLBroker: TXMLBroker): string;
  166. begin
  167.   if Dispatcher <> nil then
  168.     Result := XMLBroker.GetDelta(Dispatcher.Request)
  169.   else
  170.     Result := '';
  171. end;
  172.  
  173. function TCustomMidasPageProducer.GetXMLErrors(XMLBroker: TXMLBroker): string;
  174. begin
  175.   Result := XMLBroker.GetErrors;
  176. end;
  177.  
  178. function TCustomMidasPageProducer.GetUseXMLIslands: Boolean;
  179. var
  180.   Request: TWebRequest;
  181.   P: Integer;
  182. begin
  183.   Result := False;
  184.   if EnableXMLIslands then
  185.   begin
  186.     if (csDesigning in ComponentState) then
  187.       Result := True
  188.     else
  189.     begin
  190.       if Dispatcher <> nil then
  191.         Request := Dispatcher.Request
  192.       else
  193.         Request := nil;
  194.       if Assigned(Request) then
  195.       begin
  196.         P := Pos('MSIE', Request.UserAgent);
  197.         Result := (P > 0) and (Copy(Request.UserAgent, P + 5, 1) >= '5');
  198.       end;
  199.     end;
  200.   end;
  201. end;
  202.  
  203. function TCustomMidasPageProducer.GetXMLData(XMLBroker: TXMLBroker;
  204.   XMLOptions: TXMLOptions): string;
  205. var
  206.   OwnerData: OleVariant;
  207.   Request: TWebRequest;
  208.   RecCount: Integer;    
  209. begin
  210.   if Dispatcher <> nil then
  211.     Request := Dispatcher.Request
  212.   else
  213.     Request := nil;
  214.   DoBeforeGetXMLData(XMLBroker, OwnerData);
  215.   Result := XMLBroker.RequestRecords(Self, Request, RecCount, OwnerData, XMLOptions);
  216.   DoAfterGetXMLData(XMLBroker, OwnerData);
  217. end;
  218.  
  219. procedure TCustomMidasPageProducer.DoTagEvent(Tag: TTag; const TagString: string;
  220.   TagParams: TStrings; var ReplaceText: string);
  221. var
  222.   XMLBroker: TXMLBroker;
  223.   XMLOptions: TXMLOptions;
  224.   I: Integer;
  225. begin
  226.   if not (csDesigning in ComponentState) then
  227.     if (Tag = tgCustom) and (CompareText(TagString, sDataPacketTag) = 0) then
  228.     begin
  229.       XMLBroker := FindXMLBroker(TagParams);
  230.       XMLOptions := [];
  231.       if CompareText(TagParams.Values[sQuoteXMLAttribute], 'True') = 0 then
  232.         XMLOptions := XMLOptions + [xoQuote];
  233.       if Assigned(XMLBroker) then
  234.         ReplaceText := GetXMLData(XMLBroker, XMLOptions);
  235.       Exit;
  236.     end;
  237.  
  238.   if (Tag = tgCustom) and (CompareText(TagString, sScriptTag) = 0) then
  239.   begin
  240.     if Assigned(PageElements) then
  241.       ReplaceText := PageElements.ScriptContent;
  242.     Exit;
  243.   end
  244.   else if (Tag = tgCustom) and (CompareText(TagString, sIncludesTag) = 0) then
  245.   begin
  246.     if Assigned(PageElements) then
  247.       ReplaceText := PageElements.IncludesContent;
  248.     Exit;
  249.   end
  250.   else if (Tag = tgCustom) and (CompareText(TagString, sWarningsTag) = 0) then
  251.   begin
  252.     if Assigned(PageElements) then
  253.       ReplaceText := PageElements.WarningsContent;
  254.     Exit;
  255.   end
  256.   else if (Tag = tgCustom) and (CompareText(TagString, sFormsTag) = 0) then
  257.   begin
  258.     if Assigned(PageElements) then
  259.       ReplaceText := PageElements.FormsContent;
  260.     Exit;
  261.   end
  262.   else if (Tag = tgCustom) and (CompareText(TagString, sStylesTag) = 0) then
  263.   begin
  264.     if Assigned(PageElements) then
  265.       ReplaceText := PageElements.StylesContent;
  266.     Exit;
  267.   end
  268.   else if (Tag = tgCustom) and (CompareText(TagString, sBodyTag) = 0) then
  269.   begin
  270.     if Assigned(PageElements) then
  271.       ReplaceText := PageElements.BodyContent;
  272.     Exit;
  273.   end;
  274.   inherited DoTagEvent(Tag, TagString, TagParams, ReplaceText);
  275.   if (csDesigning in ComponentState) and (ReplaceText = '') and
  276.     Assigned(ScriptManager) and not (coNoScript in ScriptManager.Options.Flags) then
  277.     begin
  278.       // Preserve custom tag when viewing HTML
  279.       for I := 0 to TagParams.Count - 1 do
  280.         ReplaceText := ReplaceText + ' ' + TagParams[I];
  281.       ReplaceText := Format('<#%s%s>', [TagString, ReplaceText]);
  282.     end;
  283. end;
  284.  
  285. function TCustomMidasPageProducer.CreateScriptManager(Options: TWebContentOptions): TObject;
  286. begin
  287.   Result := TScriptManager.Create(Options);
  288. end;
  289.  
  290. function TCustomMidasPageProducer.CreatePageElements: TMidasPageElements;
  291. begin
  292.   Result := TMidasPageElements.Create;
  293. end;
  294.  
  295. function TCustomMidasPageProducer.DeclareRowSets: string;
  296. var
  297.   I, J: Integer;
  298.   Names: TStrings;
  299.   S: string;
  300.   XMLDocument: IXMLDocument;
  301.   XMLRowSet: IXMLRowSet;
  302. begin
  303.   Result := '';
  304.   Names := TStringList.Create;
  305.   try
  306.     for I := 0 to ScriptManager.XMLDocuments.Count - 1 do
  307.     begin
  308.       XMLDocument := ScriptManager.XMLDocuments.Items[I];
  309.       for J := 0 to XMLDocument.RowSets.Count - 1 do
  310.       begin
  311.         XMLRowSet := XMLDocument.RowSets.Items[J];
  312.         S := XMLRowSet.GetRowSetVarName;
  313.         if Names.IndexOf(S) = -1 then
  314.         begin
  315.           Names.Add(S);
  316.           Result := Result + Format('var %0:s = new xmlRowSet(%1:s, %2:s, %3:s);'#13#10,
  317.             [S, XMLDocument.DocumentVarName, XMLRowSet.MasterRowSetVarName,
  318.               XMLRowSet.MasterDataSetFieldName]);
  319.         end;
  320.       end;
  321.     end;
  322.   finally
  323.     Names.Free;
  324.   end;
  325. end;
  326.  
  327. function TCustomMidasPageProducer.DeclareXMLDocuments: string;
  328. var
  329.   I: Integer;
  330.   XMLDocument: IXMLDocument;
  331.   XMLBroker: TXMLBroker;
  332.   XMLOptions: TXMLOptions;
  333. begin
  334.   XMLOptions := [xoQuote];
  335.   Result := '';
  336.   for I := 0 to ScriptManager.XMLDocuments.Count - 1 do
  337.   begin
  338.     XMLDocument := ScriptManager.XMLDocuments.Items[I];
  339.     if XMLDocument.RowSets.Count > 0 then
  340.     begin
  341.       XMLBroker := XMLDocument.Component as TXMLBroker;
  342.       Result := Format('%svar %s = '#13#10, [Result, XMLDocument.XMLVarName]);
  343.       if csDesigning in ComponentState then
  344.         Result := Format('%s<#%s %s=%s %s>;'#13#10,
  345.           [Result, sDataPacketTag, sXMLBroker, XMLBroker.Name, sQuoteXML])
  346.       else
  347.         Result := Format('%s%s;'#13#10, [Result, GetXMLData(XMLBroker, XMLOptions)]);;
  348.       Result := Format('%svar %s = new Document(%s);'#13#10,
  349.        [Result, XMLDocument.DocumentVarName, XMLDocument.XMLVarName]);
  350.     end;
  351.   end;
  352. end;
  353.  
  354. function TCustomMidasPageProducer.DeclareXMLIslands: string;
  355. var
  356.   I: Integer;
  357.   XMLDocument: IXMLDocument;
  358.   XMLBroker: TXMLBroker;
  359.   XMLOptions: TXMLOptions;
  360. begin
  361.   if (not (coNoScript in ScriptManager.Options.Flags)) then
  362.   begin
  363.     XMLOptions := [];
  364.     Result := #13#10;
  365.     for I := 0 to ScriptManager.XMLDocuments.Count - 1 do
  366.     begin
  367.       XMLDocument := ScriptManager.XMLDocuments.Items[I];
  368.       if XMLDocument.RowSets.Count > 0 then
  369.       begin
  370.         XMLBroker := XMLDocument.Component as TXMLBroker;
  371.  
  372.         Result := Format('%s<XML ID=%s>'#13#10, [Result, XMLDocument.DocumentVarName]);
  373.         if csDesigning in ComponentState then
  374.           Result := Format('%s<#%s %s=%s>'#13#10,
  375.             [Result, sDataPacketTag, sXMLBroker, XMLBroker.Name])
  376.         else
  377.           Result := Format('%s%s', [Result, GetXMLData(XMLBroker, XMLOptions)]);
  378.         Result := Result + #13#10'</XML>'#13#10;
  379.       end;
  380.     end;
  381.   end;
  382. end;
  383.  
  384. function TCustomMidasPageProducer.DeclareIncludes: string;
  385.   function FormatInclude(const FileName, Path: string): string;
  386.   begin
  387.     Result := Format('<SCRIPT language=JavaScript type="text/javascript" SRC="%s"></SCRIPT>'#13#10,
  388.       [Path + FileName]);
  389.   end;
  390. var
  391.   Path: string;
  392.   IncludeFile: IIncludeFile;
  393.   I: Integer;
  394. begin
  395.   Result := '';
  396.   Path := IncludePathURL;
  397.   // Make default path refer to root.  
  398.   if Path = '' then
  399.     if Assigned(Dispatcher) and Assigned(Dispatcher.Request) then
  400.       Path := PathInfoToRelativePath(Dispatcher.Request.PathInfo);
  401.   for I := 0 to ScriptManager.IncludeFiles.Count - 1 do
  402.   begin
  403.     IncludeFile := ScriptManager.IncludeFiles.Items[I];
  404.     Result := Result + FormatInclude(IncludeFile.FileName, Path);
  405.   end;
  406. end;
  407.  
  408. function TCustomMidasPageProducer.DeclareStyles: string;
  409.   function FormatStyles(const S: string): string;
  410.   begin
  411.     if S <> '' then
  412.       Result := Format('<STYLE TYPE="text/css">'#13#10'%0:s'#13#10'</STYLE>'#13#10,
  413.         [S])
  414.     else
  415.       Result := '';
  416.   end;
  417. var
  418.   InStream: TFileStream;
  419.   S: string;
  420. begin
  421.   if StylesFile <> '' then
  422.   begin
  423.     InStream := TFileStream.Create(StylesFile, fmOpenRead + fmShareDenyWrite);
  424.     try
  425.       SetLength(S, InStream.Size);
  426.       SetLength(S, InStream.Read(PChar(S)[0], Instream.Size));
  427.       Result := FormatStyles(S);
  428.     finally
  429.       Instream.Free;
  430.     end;
  431.   end
  432.   else
  433.     Result := FormatStyles(Styles.Text);
  434. end;
  435.  
  436. function TCustomMidasPageProducer.DeclareFunctions: string;
  437. var
  438.   F: IFunction;
  439.   I: Integer;
  440. begin
  441.   Result := '';
  442.   for I := 0 to ScriptManager.Functions.Count - 1 do
  443.   begin
  444.     F := ScriptManager.Functions.Items[I];
  445.     Result := Result + F.Body;
  446.   end;
  447. end;
  448.  
  449. function TCustomMidasPageProducer.DeclareWarnings(Warnings: TStrings): string;
  450. var
  451.   I: Integer;
  452. begin
  453.   Result := '';
  454.   if Warnings.Count > 0 then
  455.   begin
  456.     for I := 0 to Warnings.Count - 1 do
  457.       Result := Format('%s  <LI>%s'#13#10, [Result, Warnings[I]]);
  458.     Result := Format('<UL>'#13#10 +
  459.                      '%s' +
  460.                      '</UL>'#13#10, [Result]);
  461.     Result := Format(sWarningsBody, [Result]);
  462.   end;
  463. end;
  464.  
  465. function TCustomMidasPageProducer.DeclareScript(XMLIslands: Boolean): string;
  466. var
  467.   ScriptBlocks: IScriptBlocks;
  468.   I: Integer;
  469.   Vars: IVars;
  470. begin
  471.   Result := '';
  472.   if (not (coNoScript in ScriptManager.Options.Flags)) then
  473.   begin
  474.     if not XMLIslands then
  475.       Result := Result + DeclareXMLDocuments;
  476.     Result := Result + DeclareRowSets;
  477.     Result := Result + DeclareFunctions;
  478.     ScriptBlocks := ScriptManager.ScriptBlocks;
  479.     for I := 0 to ScriptBlocks.Count - 1 do
  480.       Result := Result + ScriptBlocks.Items[I].Script;
  481.     Vars := ScriptManager.Vars;
  482.     for I := 0 to Vars.Count - 1 do
  483.       Result := Result + Vars.Items[I].Script;
  484.     Result :=
  485.       Format(#13#10'<SCRIPT language=JavaScript type="text/javascript">'#13#10 +
  486.              '%s</SCRIPT>'#13#10,
  487.         [Result]);
  488.   end;
  489. end;
  490.  
  491. procedure TCustomMidasPageProducer.AddScriptComponents;
  492. begin
  493.   ScriptManager.GetAddElementsIntf.AddScriptComponents(WebPageItems);
  494.   AddIncludes;
  495.   if ScriptManager.XMLDocuments.Count > 0 then
  496.     ScriptManager.GetAddElementsIntf.AddVar(sXMLReadyVar,
  497.       Format('%s=true;'#13#10, [sXMLReadyVar]));
  498. end;
  499.  
  500. procedure TCustomMidasPageProducer.AddIncludes;
  501. var
  502.   StdIncludes: TStdIncludes;
  503. begin
  504.   if ScriptManager.XMLDocuments.Count > 0 then
  505.   begin
  506.     StdIncludes := [jsDb, jsDisp];
  507.     if not GetUseXMLIslands then
  508.       StdIncludes := StdIncludes + [jsDom];
  509.     AddStdIncludes(StdIncludes, ScriptManager.GetAddElementsIntf);
  510.   end;
  511. end;
  512.  
  513. function PathInfoToRelativePath(const PathInfo: string): string;
  514. var
  515.   P, P2: PChar;
  516. begin
  517.   Result := '';
  518.   P := PChar(PathInfo);
  519.   P2 := P;
  520.   repeat
  521.     P2 := StrPos(P2, '/');
  522.     if Assigned(P2) and
  523.       IsDelimiter('/', PathInfo, P2 - P + 1) then
  524.     begin
  525.       Result := Result + '../';
  526.       Inc(P2);
  527.     end;
  528.   until P2 = nil;
  529. end;
  530.  
  531. procedure AddStdIncludes(StdIncludes: TStdIncludes;
  532.   AddIntf: IAddScriptElements);
  533. begin
  534.   Assert(Assigned(AddIntf), 'AddIntf not found');
  535.   if jsDom in StdIncludes then
  536.     AddIntf.AddIncludeFile('xmldom.js');
  537.   if jsDb in StdIncludes then
  538.     AddIntf.AddIncludeFile('xmldb.js');
  539.   if jsDisp in StdIncludes then
  540.     AddIntf.AddIncludeFile('xmldisp.js');
  541.   if jsErrDisp in StdIncludes then
  542.     AddIntf.AddIncludeFile('xmlerrdisp.js');
  543.   if jsShow in StdIncludes then
  544.     AddIntf.AddIncludeFile('xmlshow.js');
  545. end;
  546.  
  547. procedure TCustomMidasPageProducer.GeneratePageElements;
  548. var
  549.   I: Integer;
  550.   WebContent: IWebContent;
  551.   XMLIslands: Boolean;
  552.   HTMLBlocks: IHTMLBlocks;
  553. begin
  554.   AddScriptComponents;
  555.   for I := 0 to WebPageItems.Count - 1 do
  556.     if WebPageItems[I].GetInterface(IWebContent, WebContent) then
  557.       PageElements.FormsContent := PageElements.FormsContent + WebContent.Content(ScriptManager.Options, nil);
  558.  
  559.   HTMLBlocks := ScriptManager.HTMLBlocks;
  560.   for I := 0 to HTMLBlocks.Count - 1 do
  561.     PageElements.ScriptContent := PageElements.ScriptContent + HTMLBlocks.Items[I].HTML;
  562.   XMLIslands := GetUseXMLIslands;
  563.   if XMLIslands then
  564.     PageElements.ScriptContent := PageElements.ScriptContent + DeclareXMLIslands;
  565.   PageElements.ScriptContent := PageElements.ScriptContent + DeclareScript(XMLIslands);
  566.  
  567.   if not (coNoScript in ScriptManager.Options.Flags) then
  568.     PageElements.IncludesContent := DeclareIncludes;
  569.  
  570.   PageElements.StylesContent := DeclareStyles;
  571.  
  572.   if csDesigning in ComponentState then
  573.     PageElements.WarningsContent := DeclareWarnings(FScriptManager.Warnings);
  574. end;
  575.  
  576. constructor TCustomMidasPageProducer.Create(AComponent: TComponent);
  577. begin
  578.   inherited;
  579.   FStyles := TStringList.Create;
  580.   HTMLDoc.Text := GetDefaultTemplate;
  581.   FEnableXMLIslands := True;
  582. end;
  583.  
  584. destructor TCustomMidasPageProducer.Destroy;
  585. begin
  586.   inherited;
  587. end;
  588.  
  589. function TCustomMidasPageProducer.GetScriptManager: IScriptManager;
  590. begin
  591.   Result := FScriptManager;
  592. end;
  593.  
  594. function TCustomMidasPageProducer.WebContent(
  595.   Options: TWebContentOptions; Layout: TLayout): string;
  596. var
  597.   M: TScriptManager;
  598.   InStream: TStream;
  599.   S: string;
  600. begin
  601.   Assert(FScriptManager = nil, 'Unexpected value');
  602.   M := CreateScriptManager(Options) as TScriptManager;
  603.   FScriptManager := M;
  604.   DoBeforeGetContent;
  605.   try
  606.     if not Assigned(Dispatcher) or not Assigned(Dispatcher.Response) or not
  607.       Dispatcher.Response.Sent then
  608.     begin
  609.       Assert(FPageElements = nil, 'Unexpected value');
  610.       FPageElements := CreatePageElements;
  611.       try
  612.         GeneratePageElements;
  613.         Result := '';
  614.         if HTMLFile <> '' then
  615.           InStream := TFileStream.Create(HTMLFile, fmOpenRead + fmShareDenyWrite)
  616.         else
  617.         begin
  618.           S := HTMLDoc.Text;
  619.           if Trim(S) = '' then
  620.             S := GetDefaultTemplate;
  621.           InStream := TStringStream.Create(S);
  622.         end;
  623.         if InStream <> nil then
  624.         try
  625.           Result := ContentFromStream(InStream);
  626.         finally
  627.           InStream.Free;
  628.         end;
  629.       finally
  630.         FreeAndNil(FPageElements);
  631.       end;
  632.     end;
  633.   finally
  634.     DoAfterGetContent;
  635.     FScriptManager := nil;
  636.   end;
  637. end;
  638.  
  639. function TCustomMidasPageProducer.GetDefaultTemplate: string;
  640. begin
  641.   Result := Format('<HTML>'#13#10 +
  642.              '<HEAD>'#13#10 +
  643.              '</HEAD>'#13#10 +
  644.              '<BODY>'#13#10 +
  645.              '<#%0:s><#%1:s><#%2:s><#%3:s><#%4:s>'#13#10 +
  646.              '</BODY>'#13#10 +
  647.              '</HTML>'#13#10, [sIncludesTag, sStylesTag,
  648.                sWarningsTag, sFormsTag, sScriptTag]);
  649. end;
  650.  
  651. function TCustomMidasPageProducer.Content: string;
  652. var
  653.   Options: TWebContentOptions;
  654.   Owned: Boolean;
  655. begin
  656.   Options := GetContentOptions(Owned);
  657.   try
  658.     Result := WebContent(Options, nil);
  659.   finally
  660.     if Owned then
  661.       Options.Free;
  662.   end;
  663. end;
  664.  
  665. procedure TCustomMidasPageProducer.DoAfterGetXMLData(XMLBroker: TXMLBroker; var OwnerData: OleVariant);
  666. begin
  667.   if Assigned(FAfterGetXMLData) and Assigned(Dispatcher) then
  668.     FAfterGetXMLData(Self, Dispatcher.Request, XMLBroker, OwnerData);
  669. end;
  670.  
  671. procedure TCustomMidasPageProducer.DoBeforeGetXMLData(XMLBroker: TXMLBroker; var OwnerData: OleVariant);
  672. begin
  673.   if Assigned(FBeforeGetXMLData) and Assigned(Dispatcher) then
  674.     FBeforeGetXMLData(Self, Dispatcher.Request, XMLBroker, OwnerData);
  675. end;
  676.  
  677. procedure TCustomMidasPageProducer.SetIncludePathURL(const Value: string);
  678. var
  679.   NewValue: string;
  680. begin
  681.   if Value <> '' then
  682.   begin
  683.     NewValue := DosPathToUnixPath(Value);
  684.     if not IsDelimiter('/', NewValue, Length(NewValue)) then
  685.       NewValue := NewValue + '/';
  686.   end;
  687.   if AnsiCompareText(FIncludePathURL, NewValue) <> 0 then
  688.   begin
  689.     FIncludePathURL := NewValue;
  690.   end;
  691. end;
  692.  
  693. function TCustomMidasPageProducer.CanAddClass(AParent: TComponent; AClass: TClass): Boolean;
  694. begin
  695.   Result := ImplCanAddClass(AParent, AClass);
  696. end;
  697.  
  698. function TCustomMidasPageProducer.ImplCanAddClass(AParent: TComponent; AClass: TClass): Boolean;
  699. begin
  700.   Result := AClass.InheritsFrom(TWebForm) or
  701.     AClass.InheritsFrom(TCustomLayoutGroup);
  702. end;
  703.  
  704. procedure TCustomMidasPageProducer.SetStyles(Value: TStrings);
  705. begin
  706.   FStyles.Assign(Value);
  707.   FStylesFile := '';
  708. end;
  709.  
  710. procedure TCustomMidasPageProducer.SetStylesFile(const Value: TFileName);
  711. begin
  712.   if CompareText(FStylesFile, Value) <> 0 then
  713.   begin
  714.     FStyles.Clear;
  715.     FStylesFile := Value;
  716.   end;
  717. end;
  718.  
  719. procedure TCustomMidasPageProducer.DoAfterGetContent;
  720. begin
  721.   if Assigned(FAfterGetContent) then
  722.     FAfterGetContent(Self);
  723. end;
  724.  
  725. procedure TCustomMidasPageProducer.DoBeforeGetContent;
  726. begin
  727.   if Assigned(FBeforeGetContent) then
  728.     FBeforeGetContent(Self);
  729. end;
  730.  
  731. function TCustomMidasPageProducer.GetContentOptions(
  732.   var Owned: Boolean): TWebContentOptions;
  733. begin
  734.   if Assigned(ScriptManager) then
  735.   begin
  736.     Owned := False;
  737.     Result := ScriptManager.Options;
  738.   end
  739.   else
  740.   begin
  741.     Owned := True;
  742.     Result := TWebContentOptions.Create([]);
  743.   end;
  744. end;
  745.  
  746. { TMidasPageElements }
  747.  
  748. function TMidasPageElements.BodyContent: string;
  749. begin
  750.   Result :=
  751.       IncludesContent +
  752.       StylesContent +
  753.       WarningsContent +
  754.       FormsContent +
  755.       ScriptContent;
  756. end;
  757.  
  758. end.
  759.  
  760.