pas2jsresources.pp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. unit pas2jsresources;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. {$IFDEF pas2js}
  7. web,
  8. {$ELSE}
  9. base64,
  10. {$ENDIF}
  11. pas2jsfs, jsTree;
  12. Type
  13. TResourceScopeMode = (rmProgram,rmUnit);
  14. { TPas2jsResourceHandler }
  15. TResourceOutputMode = (romNone,romJS,romFile,romExtraJS);
  16. TPas2jsResourceHandler = class(TObject)
  17. private
  18. FCurrentUnitName: String;
  19. FFS: TPas2JSFS;
  20. Protected
  21. // Must be overridden
  22. function GetResourceCount: Integer; virtual; abstract;
  23. // Content of file, if file based.
  24. function GetAsString: String; virtual; abstract;
  25. // Detect some common formats
  26. Function GetFormat(const aFileName : string; aOptions : TStrings) : string; virtual;
  27. Public
  28. Constructor Create(aFS : TPas2JSFS); virtual;
  29. // Called for every found resource
  30. Procedure HandleResource (aFileName : string; Options : TStrings); virtual; abstract;
  31. // Extension of output file, if file based
  32. Class Function OutputFileExtension : String; virtual;
  33. // True if output is file based (i.e. written to separate file)
  34. Class Function OutputMode : TResourceOutputMode; virtual; abstract;
  35. // Load resource file. Can be used in descendents
  36. Function LoadFile(aFileName : string) : TPas2jsFile;
  37. // Load resource file and encode as base64 string. Can be used in descendents
  38. Function GetFileAsBase64(aFileName : string) : string;
  39. // This is called for every unit.
  40. Procedure StartUnit(Const aUnitName : String); virtual;
  41. // This is called at the start of every unit if OutputIsUnitBased is true.
  42. Procedure ClearUnit; virtual;
  43. // This is called at the end of every unit if OutputIsUnitBased is true. Only once if not.
  44. Procedure DoneUnit(isMainFile : Boolean); virtual;
  45. // This is called when Javascript is written for a unit
  46. Function WriteJS(const aUnitName : String; aModule : TJSElement) : TJSElement; virtual;
  47. // Current unit.
  48. Property CurrentUnitName : String Read FCurrentUnitName;
  49. // Passed at create
  50. property FS : TPas2JSFS Read FFS;
  51. // Return file content for writing to file if IsFileBased
  52. Property AsString : String Read GetAsString;
  53. // Number of resources
  54. Property ResourceCount : Integer Read GetResourceCount;
  55. end;
  56. { TNoResources }
  57. TNoResources = Class(TPas2jsResourceHandler)
  58. Public
  59. Procedure HandleResource (aFileName : string; Options : TStrings); override;
  60. Class Function OutputMode : TResourceOutputMode; override;
  61. function GetResourceCount: Integer; override;
  62. function GetAsString: String; override;
  63. end;
  64. implementation
  65. { TNoResources }
  66. procedure TNoResources.HandleResource(aFileName: string; Options: TStrings);
  67. begin
  68. // Do nothing
  69. if aFileName='' then ;
  70. if Options=nil then ;
  71. end;
  72. class function TNoResources.OutputMode: TResourceOutputMode;
  73. begin
  74. result:=romNone;
  75. end;
  76. function TNoResources.GetResourceCount: Integer;
  77. begin
  78. Result:=0;
  79. end;
  80. function TNoResources.GetAsString: String;
  81. begin
  82. Result:='';
  83. end;
  84. { TPas2jsResourceHandler }
  85. function TPas2jsResourceHandler.GetFormat(const aFileName: string; aOptions: TStrings): string;
  86. Var
  87. E : String;
  88. begin
  89. Result:=aOptions.Values['format'];
  90. if Result='' then
  91. begin
  92. E:=ExtractFileExt(aFileName);
  93. if (E<>'') and (E[1]='.') then
  94. E:=Copy(E,2,Length(E)-1);
  95. if Pos(LowerCase(E),';png;jpg;jpeg;bmp;ico;')>0 then
  96. Result:='image/'+E
  97. else if Pos(LowerCase(E),';htm;html;')>0 then
  98. Result:='text/html'
  99. else if Pos(LowerCase(E),';txt;lpr;pas;pp;')>0 then
  100. Result:='text/text'
  101. else if Pos(LowerCase(E),';js;')>0 then
  102. Result:='application/javascript'
  103. else if Pos(LowerCase(E),';json;')>0 then
  104. Result:='application/javascript'
  105. else
  106. Result:='application/octet-stream';
  107. end;
  108. end;
  109. constructor TPas2jsResourceHandler.Create(aFS: TPas2JSFS);
  110. begin
  111. FFS:=aFS;
  112. end;
  113. class function TPas2jsResourceHandler.OutputFileExtension: String;
  114. begin
  115. Result:='';
  116. end;
  117. function TPas2jsResourceHandler.LoadFile(aFileName: string): TPas2jsFile;
  118. begin
  119. Result:=FS.LoadFile(aFileName,True);
  120. end;
  121. function TPas2jsResourceHandler.GetFileAsBase64(aFileName: string): string;
  122. Var
  123. F : TPas2JSFile;
  124. begin
  125. F:=LoadFile(aFileName);
  126. {$IFDEF pas2js}
  127. Result:=window.atob(F.Source);
  128. {$ELSE}
  129. Result:=EncodeStringBase64(F.Source);
  130. {$ENDIF}
  131. // Do not release, FS will release all files
  132. end;
  133. procedure TPas2jsResourceHandler.ClearUnit;
  134. begin
  135. FCurrentUnitName:='';
  136. end;
  137. procedure TPas2jsResourceHandler.StartUnit(const aUnitName: String);
  138. begin
  139. FCurrentUnitName:=aUnitName;
  140. end;
  141. procedure TPas2jsResourceHandler.DoneUnit(isMainFile: Boolean);
  142. begin
  143. if not isMainFile then
  144. ClearUnit;
  145. end;
  146. function TPas2jsResourceHandler.WriteJS(const aUnitName: String; aModule: TJSElement): TJSElement;
  147. begin
  148. Result:=aModule;
  149. if aUnitName='' then ;
  150. end;
  151. end.