diff --git a/components/pas2js/frmpas2jsbrowserprojectoptions.lfm b/components/pas2js/frmpas2jsbrowserprojectoptions.lfm
index b083865c7b..37561d6704 100644
--- a/components/pas2js/frmpas2jsbrowserprojectoptions.lfm
+++ b/components/pas2js/frmpas2jsbrowserprojectoptions.lfm
@@ -16,7 +16,7 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
Left = 6
Height = 23
Top = 6
- Width = 173
+ Width = 160
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Caption = 'Create initial HTML page'
@@ -32,7 +32,7 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
Left = 6
Height = 23
Top = 122
- Width = 213
+ Width = 198
BorderSpacing.Top = 6
Caption = 'Use Browser Application object'
OnChange = CBUseBrowserAppChange
@@ -44,16 +44,16 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
AnchorSideTop.Side = asrBottom
Left = 6
Height = 23
- Top = 213
- Width = 341
+ Top = 216
+ Width = 313
BorderSpacing.Top = 6
Caption = 'Use Browser Console unit to display writeln() output'
TabOrder = 2
end
object BPHelpOptions: TButtonPanel
Left = 6
- Height = 38
- Top = 494
+ Height = 40
+ Top = 492
Width = 623
OKButton.Name = 'OKButton'
OKButton.DefaultCaption = True
@@ -67,13 +67,14 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
ShowButtons = [pbOK, pbCancel]
end
object SEPort: TSpinEdit
- AnchorSideLeft.Control = edtWasmProgram
+ AnchorSideLeft.Control = RBStartServerAt
AnchorSideTop.Control = RBStartServerAt
AnchorSideTop.Side = asrBottom
Left = 70
- Height = 27
- Top = 300
+ Height = 30
+ Top = 303
Width = 128
+ BorderSpacing.Left = 32
BorderSpacing.Top = 6
MaxValue = 65354
MinValue = 1024
@@ -86,8 +87,8 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
AnchorSideTop.Side = asrBottom
Left = 6
Height = 23
- Top = 242
- Width = 194
+ Top = 245
+ Width = 182
BorderSpacing.Top = 6
Caption = 'Project needs a HTTP Server'
OnChange = CBUseHTTPServerChange
@@ -99,8 +100,8 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
AnchorSideTop.Side = asrBottom
Left = 38
Height = 23
- Top = 271
- Width = 180
+ Top = 274
+ Width = 168
BorderSpacing.Left = 32
BorderSpacing.Top = 6
Caption = 'Start HTTP Server on port'
@@ -114,23 +115,24 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
AnchorSideTop.Side = asrBottom
Left = 38
Height = 23
- Top = 329
- Width = 173
+ Top = 335
+ Width = 161
BorderSpacing.Top = 2
Caption = 'Use this URL to start app'
TabOrder = 7
end
object CBServerURL: TComboBox
- AnchorSideLeft.Control = edtWasmProgram
+ AnchorSideLeft.Control = RBUseURL
AnchorSideTop.Control = RBUseURL
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = edtWasmProgram
AnchorSideRight.Side = asrBottom
Left = 70
- Height = 27
- Top = 358
+ Height = 30
+ Top = 364
Width = 559
Anchors = [akTop, akLeft, akRight]
+ BorderSpacing.Left = 32
BorderSpacing.Top = 6
BorderSpacing.Bottom = 6
ItemHeight = 0
@@ -143,7 +145,7 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
Left = 6
Height = 23
Top = 35
- Width = 151
+ Width = 137
BorderSpacing.Top = 6
Caption = 'Maintain HTML Page'
TabOrder = 9
@@ -155,7 +157,7 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
Left = 6
Height = 23
Top = 64
- Width = 313
+ Width = 287
BorderSpacing.Top = 6
Caption = 'Run rtl when all page resources are fully loaded'
TabOrder = 10
@@ -167,7 +169,7 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
Left = 6
Height = 23
Top = 93
- Width = 226
+ Width = 209
BorderSpacing.Top = 6
Caption = 'Let rtl show uncaught exceptions'
TabOrder = 11
@@ -179,7 +181,7 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
Left = 38
Height = 23
Top = 151
- Width = 193
+ Width = 176
BorderSpacing.Left = 32
BorderSpacing.Top = 6
Caption = 'Host webassembly program'
@@ -193,7 +195,7 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 70
- Height = 27
+ Height = 30
Top = 180
Width = 559
Anchors = [akTop, akLeft, akRight]
@@ -210,8 +212,8 @@ object WebBrowserProjectOptionsForm: TWebBrowserProjectOptionsForm
AnchorSideTop.Side = asrBottom
Left = 6
Height = 23
- Top = 391
- Width = 293
+ Top = 400
+ Width = 272
BorderSpacing.Top = 6
Caption = 'Create a javascript module instead of a script'
OnChange = CBUseHTTPServerChange
diff --git a/components/pas2js/frmpas2jsbrowserprojectoptions.pp b/components/pas2js/frmpas2jsbrowserprojectoptions.pp
index b491485f7c..05e5b35959 100644
--- a/components/pas2js/frmpas2jsbrowserprojectoptions.pp
+++ b/components/pas2js/frmpas2jsbrowserprojectoptions.pp
@@ -44,6 +44,8 @@ type
procedure SetURL(AValue: String);
procedure SetWasmProgramURL(AValue: String);
public
+ procedure HideWASM; virtual;
+ procedure HideModule; virtual;
property CreateHTML : Boolean Index 0 read GetB Write SetB;
property MaintainHTML : Boolean Index 1 read GetB Write SetB;
property UseBrowserApp : Boolean Index 2 read GetB Write SetB;
@@ -217,5 +219,16 @@ begin
edtWasmProgram.Text:=aValue;
end;
+procedure TWebBrowserProjectOptionsForm.HideWASM;
+begin
+ CBUseWASI.Visible:=false;
+ edtWasmProgram.Visible:=false;
+end;
+
+procedure TWebBrowserProjectOptionsForm.HideModule;
+begin
+ CBUseModule.Visible:=false;
+end;
+
end.
diff --git a/components/pas2js/pjscontroller.pp b/components/pas2js/pjscontroller.pp
index 6f5c5b57bb..06e7c2f237 100644
--- a/components/pas2js/pjscontroller.pp
+++ b/components/pas2js/pjscontroller.pp
@@ -89,6 +89,7 @@ Const
PJSIsProjectHTMLFile = 'PasJSIsProjectHTMLFile';
PJSProjectMaintainHTML = 'MaintainHTML';
PJSProjectManifestFile = 'PasJSManifestFile';
+ PJSProjectCSSFile = 'PasJSCSSFile';
PJSProjectUseBrowserConsole = 'BrowserConsole';
PJSProjectRunAtReady = 'RunAtReady';
PJSProjectPort = 'PasJSPort';
diff --git a/components/pas2js/pjsdsgnregister.pas b/components/pas2js/pjsdsgnregister.pas
index f3fd2db785..f43f89db9c 100644
--- a/components/pas2js/pjsdsgnregister.pas
+++ b/components/pas2js/pjsdsgnregister.pas
@@ -5,7 +5,7 @@ unit PJSDsgnRegister;
interface
uses
- Classes, SysUtils, fpjson,
+ Classes, SysUtils, Types, fpjson,
// LCL
Forms, Controls, Dialogs,
// LazUtils
@@ -18,7 +18,7 @@ uses
idehtml2class, PJSDsgnOptions, PJSDsgnOptsFrame, idedtstopas,
frmpas2jswebservers, frmpas2jsnodejsprojectoptions,
frmpas2jsbrowserprojectoptions, pjsprojectoptions, idehtmltools,
- frmhtmltoform, pjscontroller, strpas2jsdesign;
+ frmhtmltoform, pjscontroller, strpas2jsdesign, CodeToolManager, CodeCache;
const
@@ -30,6 +30,8 @@ const
FileDescNameClassFromHTMLFile = 'Class definition from HTML file';
SMessageViewHTMLToForm = 'HTML To Class conversion';
+ DefaultIconSizes: array[0..7] of word = (72,96,128,144,152,192,384,512);
+
type
{ TProjectPas2JSWebApp }
@@ -59,6 +61,7 @@ type
function GetMainSrcFileName: string;
function GetMainSrcName: string;
protected
+ procedure AddHTMLHead(Src: TStringList); virtual;
function CreateHTMLFile(AProject: TLazProject; AFileName: String
): TLazProjectFile; virtual;
function CreateProjectSource: String; virtual;
@@ -68,6 +71,7 @@ type
function ShowModalOptions(Frm: TWebBrowserProjectOptionsForm): TModalResult; virtual;
public
constructor Create; override;
+ procedure Clear; virtual;
function GetLocalizedName: string; override;
function GetLocalizedDescription: string; override;
function InitProject(AProject: TLazProject): TModalResult; override;
@@ -97,28 +101,37 @@ type
TProjectPas2JSProgressiveWebApp = class(TProjectPas2JSWebApp)
private
- FCSSDir: string;
+ FCSSStyleFilename: string;
+ FIconSizes: TWordDynArray;
FImagesDir: string;
FManifestFilename: string;
FProjectDir: string;
FServiceWorkerLPR: string;
FWebDir: string;
protected
+ procedure AddHTMLHead(Src: TStringList); override;
function ShowModalOptions(Frm: TWebBrowserProjectOptionsForm
): TModalResult; override;
function CreateManifestFile(AProject: TLazProject; AFileName: String
): TLazProjectFile; virtual;
+ function CreateCSSStyle(AProject: TLazProject; AFileName: String
+ ): TLazProjectFile; virtual;
+ function ForceDir(Dir: string; AutoDelete: boolean): boolean; virtual;
+ function SaveFile(aFilename: string): boolean; virtual;
public
constructor Create; override;
+ procedure Clear; override;
function GetLocalizedName: string; override;
function GetLocalizedDescription: string; override;
function InitProject(AProject: TLazProject): TModalResult; override;
+ function CreateStartFiles(AProject: TLazProject): TModalResult; override;
property ProjectDir: string read FProjectDir write FProjectDir;
property ServiceWorkerLPR: string read FServiceWorkerLPR write FServiceWorkerLPR;
- property CSSDir: string read FCSSDir write FCSSDir;
- property ImagesDir: string read FImagesDir write FImagesDir;
+ property CSSStyleFilename: string read FCSSStyleFilename write FCSSStyleFilename; // without path (WebDir)
+ property ImagesDir: string read FImagesDir write FImagesDir; // without path (WebDir)
property WebDir: string read FWebDir write FWebDir;
- property ManifestFilename: string read FManifestFilename write FManifestFilename;
+ property ManifestFilename: string read FManifestFilename write FManifestFilename; // without path (WebDir)
+ property IconSizes: TWordDynArray read FIconSizes write FIconSizes;
end;
{ TProjectPas2JSNodeJSApp }
@@ -250,6 +263,7 @@ begin
TPJSController.Instance.Hook;
// register new-project items
RegisterProjectDescriptor(TProjectPas2JSWebApp.Create);
+ RegisterProjectDescriptor(TProjectPas2JSProgressiveWebApp.Create);
RegisterProjectDescriptor(TProjectPas2JSServiceWorker.Create);
RegisterProjectDescriptor(TProjectPas2JSNodeJSApp.Create);
RegisterProjectDescriptor(TProjectPas2JSModuleApp.Create);
@@ -284,10 +298,28 @@ end;
{ TProjectPas2JSProgressiveWebApp }
+procedure TProjectPas2JSProgressiveWebApp.AddHTMLHead(Src: TStringList);
+var
+ i: Integer;
+ h, CurImgDir: String;
+begin
+ inherited AddHTMLHead(Src);
+ Src.Add(' ');
+ Src.Add(' ');
+ Src.Add(' ');
+ Src.Add(' ');
+ CurImgDir:=ChompPathDelim(ImagesDir);
+ for i:=0 to high(IconSizes) do
+ begin
+ h:=IntToStr(IconSizes[i]);
+ Src.Add(' ');
+ end;
+end;
+
function TProjectPas2JSProgressiveWebApp.ShowModalOptions(
Frm: TWebBrowserProjectOptionsForm): TModalResult;
var
- CurProjDir, LPRFilename: String;
+ CurProjDir, LPRFilename, CurWebDir: String;
Overwrites: TStringList;
function CheckOverwriteFile(aFilename: string): string;
@@ -306,6 +338,10 @@ var
end;
begin
+ // hide unsupported options
+ Frm.HideWASM;
+ Frm.HideModule;
+
Result:=inherited ShowModalOptions(Frm);
if Result<>mrOk then exit;
@@ -322,13 +358,12 @@ begin
ServiceWorkerLPR:=CheckOverwriteFile(ProjectDir+ServiceWorkerLPR);
CheckOverwriteFile(ChangeFileExt(ServiceWorkerLPR,'.lpi'));
- WebDir:=CheckOverwriteDir(CurProjDir+WebDir);
+ CurWebDir:=CheckOverwriteDir(CurProjDir+WebDir);
+ CheckOverwriteDir(CurWebDir+ImagesDir);
- HTMLFilename:=CheckOverwriteFile(WebDir+HTMLFilename);
- ManifestFilename:=CheckOverwriteFile(WebDir+ManifestFilename);
-
- CSSDir:=CheckOverwriteDir(WebDir+CSSDir);
- ImagesDir:=CheckOverwriteDir(WebDir+ImagesDir);
+ CheckOverwriteFile(CurWebDir+HTMLFilename);
+ CheckOverwriteFile(CurWebDir+ManifestFilename);
+ CheckOverwriteFile(CurWebDir+CSSStyleFilename);
if Overwrites.Count>0 then
begin
@@ -348,8 +383,6 @@ end;
function TProjectPas2JSProgressiveWebApp.CreateManifestFile(
AProject: TLazProject; AFileName: String): TLazProjectFile;
-const
- IconSizes: array[1..8] of word = (72,96,128,144,152,192,384,512);
var
Src: TStringList;
i: Integer;
@@ -357,7 +390,7 @@ var
begin
Result:=AProject.CreateProjectFile(AFileName);
Result.IsPartOfProject:=true;
- AProject.CustomData.Values[PJSProjectManifestFile]:=Result.Filename;
+ AProject.CustomData.Values[PJSProjectManifestFile]:=CreateRelativePath(ProjectDir,Result.Filename);
AProject.AddFile(Result,false);
Src:=TStringList.Create;
try
@@ -370,12 +403,12 @@ begin
Src.Add(' "theme_color": "#d04030",');
Src.Add(' "orientation": "portrait-primary",');
Src.Add(' "icons": [');
- for i:=low(IconSizes) to high(IconSizes) do
+ for i:=0 to high(IconSizes) do
begin
h:=IntToStr(IconSizes[i]);
h:=h+'x'+h;
Src.Add(' {');
- Src.Add(' "src": "/'+ExtractFileNameOnly(ChompPathDelim(ImagesDir))+'/icon-'+h+'.png",');
+ Src.Add(' "src": "/'+ChompPathDelim(ImagesDir)+'/icon-'+h+'.png",');
Src.Add(' "type": "image/png", "sizes": "'+h+'"');
h:=' }';
if imrOk then exit;
@@ -470,19 +557,26 @@ begin
end;
CurProjDir:=AppendPathDelim(CurProjDir);
+ CurWebDir:=AppendPathDelim(CurProjDir+WebDir);
+ CurImagesDir:=AppendPathDelim(CurWebDir+ImagesDir);
- if not CheckDir(WebDir,true) then exit;
- if not CheckDir(CSSDir,true) then exit;
- if not CheckDir(ImagesDir,true) then exit;
+ if not ForceDir(WebDir,true) then exit;
+ if not ForceDir(ImagesDir,true) then exit;
- // index.html
- if LazarusIDE.DoSaveEditorFile(HTMLFilename,[sfProjectSaving])<>mrOk then exit;
+ // index.html (created in inherited InitProject)
+ CurHTMLFilename:=CurWebDir+HTMLFilename;
+ SaveFile(CurHTMLFilename);
// manifest.json
- CreateManifestFile(AProject,ManifestFilename);
- if LazarusIDE.DoSaveEditorFile(ManifestFilename,[sfProjectSaving])<>mrOk then exit;
+ CurManifestFilename:=CurWebDir+ManifestFilename;
+ CreateManifestFile(AProject,CurManifestFilename);
+ SaveFile(CurManifestFilename);
+
+ // style.css
+ CurCSSStyleFilename:=CurWebDir+CSSStyleFilename;
+ CreateCSSStyle(AProject,CurCSSStyleFilename);
+ SaveFile(CurCSSStyleFilename);
- // css/style.css
// favicon.ico
// images/icon-.png
@@ -494,6 +588,12 @@ begin
Result:=mrOk;
end;
+function TProjectPas2JSProgressiveWebApp.CreateStartFiles(AProject: TLazProject
+ ): TModalResult;
+begin
+ Result:=inherited CreateStartFiles(AProject);
+end;
+
{ TProjectPas2JSServiceWorker }
function TProjectPas2JSServiceWorker.CreateProjectSource: String;
@@ -1110,6 +1210,14 @@ begin
FMainSrcName:='Project1';
end;
+procedure TProjectPas2JSWebApp.Clear;
+begin
+ // Reset options
+ FOptions:=[baoCreateHtml,baoMaintainHTML];
+ ProjectPort:=0;
+ ProjectURL:='';
+end;
+
function TProjectPas2JSWebApp.GetNextPort : Word;
begin
@@ -1199,10 +1307,7 @@ end;
function TProjectPas2JSWebApp.DoInitDescriptor: TModalResult;
begin
- // Reset options
- FOptions:=[baoCreateHtml,baoMaintainHTML];
- ProjectPort:=0;
- ProjectURL:='';
+ Clear;
Result:=ShowOptionsDialog;
end;
@@ -1237,31 +1342,20 @@ begin
Result:=FMainSrcName;
end;
+procedure TProjectPas2JSWebApp.AddHTMLHead(Src: TStringList);
+begin
+ if Src=nil then ;
+end;
+
function TProjectPas2JSWebApp.CreateHTMLFile(AProject: TLazProject;
AFileName: String): TLazProjectFile;
Const
ConsoleDiv = ''+LineEnding;
- TemplateHTMLSource =
- ''+LineEnding
- +''+LineEnding
- +''+LineEnding
- +' '+LineEnding
- +' '+LineEnding
- +' %s'+LineEnding
- +' '+LineEnding
- +''+LineEnding
- +''+LineEnding
- +' %s'+LineEnding
- +' %s'+LineEnding
- +''+LineEnding
- +''+LineEnding;
-
-
Var
HTMLFile : TLazProjectFile;
- HTMLSource : String;
ScriptType, RunScript,Content : String;
+ Src: TStringList;
begin
HTMLFile:=AProject.CreateProjectFile(HTMLFilename);
@@ -1288,11 +1382,29 @@ begin
else
RunScript:=Runscript+'rtl.run();'+LineEnding;
RunScript:=' '+LineEnding
+ +' '+RunScript
+ +' '+LineEnding
end;
- HTMLSource:=Format(TemplateHTMLSource,[MainSrcName,ScriptType,aFileName,RunScript,Content]);
- HTMLFile.SetSourceText(HTMLSource);
+ Src:=TStringList.Create;
+ try
+ Src.Add('');
+ Src.Add('');
+ Src.Add('');
+ Src.Add(' ');
+ Src.Add(' ');
+ Src.Add(' '+MainSrcName+'');
+ Src.Add(' ');
+ AddHTMLHead(Src);
+ Src.Add('');
+ Src.Add('');
+ Src.Add(' '+RunScript);
+ Src.Add(' '+Content);
+ Src.Add('');
+ Src.Add('');
+ HTMLFile.SetSourceText(Src.Text);
+ finally
+ Src.Free;
+ end;
Result:=HTMLFile;
end;