pas2jsdsgn: open project url

This commit is contained in:
mattias 2022-04-11 00:36:22 +02:00
parent 539e3c4ab4
commit cf32cfa6ee
19 changed files with 174 additions and 1052 deletions

View File

@ -156,7 +156,6 @@ begin
else else
Result:=False; Result:=False;
end; end;
// Writeln('Reporting ',AIndex,' : ',Result);
end; end;
function TWebBrowserProjectOptionsForm.GetServerPort: Word; function TWebBrowserProjectOptionsForm.GetServerPort: Word;

View File

@ -1,188 +0,0 @@
object PasJSWebserverProcessesForm: TPasJSWebserverProcessesForm
Left = 560
Height = 245
Top = 270
Width = 644
Caption = 'Web server processes'
ClientHeight = 245
ClientWidth = 644
OnClose = FormClose
OnCreate = FormCreate
OnDestroy = FormDestroy
OnShow = FormShow
LCLVersion = '2.1.0.0'
object LCount: TLabel
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = Owner
Left = 6
Height = 15
Top = 6
Width = 171
BorderSpacing.Left = 6
BorderSpacing.Top = 6
Caption = 'Number of webserver processes:'
ParentColor = False
end
object LVProcesses: TListView
AnchorSideLeft.Control = Owner
AnchorSideTop.Control = SBrefresh
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
AnchorSideBottom.Control = Owner
AnchorSideBottom.Side = asrBottom
Left = 6
Height = 195
Top = 44
Width = 632
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Around = 6
Columns = <
item
Caption = 'Port'
end
item
Caption = 'Status'
Width = 80
end
item
Caption = 'Root Directory'
Width = 200
end
item
Caption = 'Project'
Width = 200
end
item
AutoSize = True
Caption = 'Additional info'
Width = 94
end>
SmallImages = ILProcesses
StateImages = ILProcesses
TabOrder = 0
ViewStyle = vsReport
end
object SBrefresh: TSpeedButton
AnchorSideTop.Control = Owner
AnchorSideRight.Control = Owner
AnchorSideRight.Side = asrBottom
Left = 606
Height = 32
Top = 6
Width = 32
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Around = 6
Constraints.MinHeight = 32
Constraints.MinWidth = 32
Glyph.Data = {
36040000424D3604000000000000360000002800000010000000100000000100
2000000000000004000064000000640000000000000000000000FFFFFF00A465
34A2A4653401FFFFFF00FFFFFF00A4653405A4653453A76A3ABEA66938E9A466
35FAA76A3AE4A76B3BAAA4653424FFFFFF00FFFFFF00FFFFFF00FFFFFF00A465
34FFA5673693FFFFFF00A4653454A66737EEB58055F3CEA684FFD8B697FFDBB9
99FFD3AC8AFFC2946DFCA66838F6A466355BFFFFFF00FFFFFF00FFFFFF00A567
37FEB7845BF7A56736D4B17A4EF4E3CAB4FFECDAC9FFE7D1BCFFE3C9B0FFDEBE
A0FFD2AB88FFCEA582FFD3AE8EFFA66838F5A465342AFFFFFF00FFFFFF00A668
38FDF1E4D8FFD4B295FEF4E9E0FFF3E8DDFFEDDCCCFFD2AD8FFEB0784CF5A566
35FBA66939FFA66939FEA96D3DFFB0784CFFA76A3AA8FFFFFF00FFFFFF00A567
37FDF6EEE6FFF5ECE3FFF5EDE4FFE6D2C1FFB0794DF5A66938CAA4653436FFFF
FF00A465346AA96B3CEDB67C4FFFA76A3AFEA56837FAFFFFFF00FFFFFF00A466
35FCF6EEE6FFEBD7C4FFEAD9C9FFA46534FEA465346AFFFFFF00FFFFFF00FFFF
FF00A465340BA56635E9C9956C8DB77F53C2A46534FFA4653405FFFFFF00A465
34FCF5EDE5FFF6EDE5FFF5ECE4FFD7B79CFDA66837E0A4653410FFFFFF00FFFF
FF00FFFFFF00FFFFFF00D5A47E1ACD997239A46534FCA465340CFFFFFF00A465
34F9A46534FEA46534FEA46534FDA46534FCA46534FBA46534B9A465341DA465
3418A4653418A4653418A4653418A4653418A465341CFFFFFF00FFFFFF00A465
340DFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00A46534A0A465
34FFAD7447F8AF774CF7AF774CF7AF784CF7A46534FFA4653408FFFFFF00A465
34FCB3794C7ECF9D762BBB835713A4653402FFFFFF00FFFFFF00A4653404A668
38C4D0AC8FFAF6EEE7FFF2E6DBFFF6EEE6FFA66A3AFBA4653409FFFFFF00A465
35FEA76A3AFBC791689DA56737E6A4653423FFFFFF00FFFFFF00FFFFFF00A465
3460A46635FFE9D7C7FFEBD8C6FFF5ECE3FFA66A3AFAA465340AFFFFFF00A668
38F3AB7041FFA96C3CFEA76A3AF5A4653475A4653419A4653445A66938CDB988
61F5EBDBCDFFF5EBE2FFF6EEE6FFF6EEE6FFA76A3AFAA465340BFFFFFF00A769
399BC09069FDC59872FFA86B3CFFA46635FFA76A3AFCB7855DF3D9BBA1FEF1E4
D8FFF2E6DBFFF3E8DDFFCEA788FDEAD8C8FFA76A3AF9A465340DFFFFFF00A465
3429A66939F5D3AD8CFFDCBD9DFFDDBEA1FFE5CBB4FFE9D3BFFFEEDDCCFFF0E2
D5FFE7D2BFFFAF774BF5A56736C0AB7143F7A46635FCA465340EFFFFFF00FFFF
FF00A4653550A66838F6C09068FAD3B08FFFDFC2A8FFDEC1A8FFD4B193FFB987
5FF4A56737F0A4653458FFFFFF00A4663566A46534FFA465340FFFFFFF00FFFF
FF00FFFFFF00A465341DA7693A9FA76A3ADEA56736F6A76939E5A76A3ABCA465
3453A4653405FFFFFF00FFFFFF00FFFFFF00A4653479A4653410
}
OnClick = SBrefreshClick
end
object ILProcesses: TImageList
left = 146
top = 107
Bitmap = {
4C69020000001000000010000000FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF003DBFEC033CBCEBD43ABAEAC339B8E803FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF003CBCEB9585D4F1FF82D1F0FF37B5E769FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF003CBCEB123ABAE9F2F1FAFDFFD5EFFAFF35B2E6ED33AFE412FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF003AB9E9B494D8F2FFF3FCFEFFE7FAFEFF8FD3F0FF31ACE396FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF003AB9
E93038B7E8FDF9FDFFFF94E9F9FF9EEBFAFFECFAFEFF2FA9E1FC2DA6E030FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0038B7
E8D4A9DFF4FFEDF9FDFF3EA3D6FF3EA3D6FFD4F5FCFFA2D7F1FF2BA3DEC3FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0038B6E85A71C8
EDFFF9FEFFFF5EDCF4FF3EA2D5FF3EA2D5FF5CD9F4FFEDFBFEFF68BBE5FF269C
DB5AFFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF0038B6E80C36B4E6ECC8EA
F7FFE6FAFDFF5DDAF4FF3DA1D5FF3DA1D5FF57D7F2FFC7F3FCFFC0E3F4FF2499
D9E42296D80CFFFFFF00FFFFFF00FFFFFF00FFFFFF0036B3E6AA8CD2F0FFEAFB
FEFF94E6F8FF5CDAF4FF47B1DDFF3DA1D5FF56D7F2FF5CDBF5FFDEF8FDFF7DC0
E7FF1D8ED487FFFFFF00FFFFFF00FFFFFF0036B3E62434B1E5FBF3FBFEFFC3F2
FBFF5CDCF6FF5CDAF4FF64DFF6FF57CBEBFF55D6F2FF54D9F5FF94E7F8FFE3F4
FBFF1787D0F91380CD24FFFFFF00FFFFFF0034B0E5CA9DD7F1FFE7F9FDFF8BE5
F8FF5ADBF6FF5BDAF4FF3DA1D5FF3DA1D5FF54D6F2FF52D8F5FF50D6F4FFD8F6
FCFF88BFE5FF0E79C9B4FFFFFF0034B0E54B62BFE8FFF4FCFEFFB5EFFAFF58DA
F5FF58DAF5FF57D8F3FF58D7F2FF58D6F2FF57D9F4FF51D8F5FF4ED7F4FF62DA
F6FFEAFBFEFF4493D2FF066DC34B31ADE3E3BEE3F5FFF4FCFEFFEFFBFEFFEEFB
FEFFEEFBFEFFEFFCFEFFEFFCFEFFEFFBFEFFEEFBFEFFEDFBFEFFEDFBFEFFECFB
FEFFF2FCFEFFABCEEBFF0368C1D82FAAE2A22DA7E0FF2BA4DFFF29A1DDFF279E
DCFF259BDAFF2398D9FF2093D6FF1B8CD3FF1685CFFF117ECCFF0D77C9FF0971
C6FF066CC3FF0368C1FF0064BFA2FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFFFF00FFFF
FF00FFFFFF00FFFFFF00FFFFFF00000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
000031D6FFFF52A5FFFF527BC6FF000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000031D6FFFF42DE
FFFF10D6FFFF5AA5FFFF527BC6FF000000000000000000000000000000000000
00000000000000000000000000000000000031D6FFFF00F7FFFF00EFFFFF00AD
FFFF00A5FFFF527BC6FF00000000000000000000000000000000000000000000
0000000000000000000031D6FFFF08F7FFFF00FFFFFF00F7FFFF00D6FFFF00B5
FFFF527BC6FF0000000000000000000000000000000000000000000000000000
000008C6FFFF39E7FFFF4AEFFFFF42F7FFFF18FFFFFF00FFFFFF00FFFFFF08FF
FFFF21FFFFFF527BC6FF000000000000000000000000000000000000000039A5
FFFF00C6FFFF00EFFFFF00F7FFFF00EFFFFF00DEFFFF00FFFFFF00FFFFFF39EF
FFFF08C6FFFF527BC6FF000000000000000000000000000000000000000029AD
FFFF00C6FFFF00EFFFFF00F7FFFF00F7FFFF00FFFFFF4AEFFFFF18CEFFFF00A5
FFFF527BC6FF000000000000000000000000000000000000000000000000527B
C6FF527BC6FF527BC6FF00C6FFFF08FFFFFF31F7FFFF10BDFFFF00ADFFFF527B
C6FF527BC6FF0000000000000000000000000000000000000000000000000000
0000000000000000000000B5FFFF08BDFFFF00ADFFFF009CFFFF527BC6FF0000
0000000000000000000000000000000000000000000000000000000000000000
00000000000000B5FFFF08C6FFFF009CFFFF009CFFFF527BC6FF000000000000
0000000000000000000000000000000000000000000000000000000000000000
000000B5FFFF008CFFFF0094FFFF527BC6FF527BC6FF00000000000000000000
000000000000000000000000000000000000000000000000000000000000009C
FFFF008CFFFF008CFFFF527BC6FF000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000397BE7FF007B
FFFF0073F7FF527BC6FF00000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000317BEFFF527B
C6FF296BC6FF0000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000527BC6FF0000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000
}
end
end

View File

@ -1,167 +0,0 @@
unit frmpas2jswebservers;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls,
ComCtrls, Buttons, pjscontroller;
type
{ TPasJSWebserverProcessesForm }
TPasJSWebserverProcessesForm = class(TForm)
ILProcesses: TImageList;
LCount: TLabel;
LVProcesses: TListView;
SBrefresh: TSpeedButton;
procedure FormClose(Sender: TObject; var CloseAction: TCloseAction);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure SBrefreshClick(Sender: TObject);
private
Class Var
TheForm : TPasJSWebserverProcessesForm;
procedure DoControllerRefresh(Sender: TObject);
procedure Localize;
procedure ServerInstanceToListItem(LI: TListItem; SI: TServerInstance);
public
Class Function Instance : TPasJSWebserverProcessesForm;
Procedure RefreshList;
end;
implementation
uses strpas2jsdesign;
{$R *.lfm}
Const
iiStopped = 0;
iiRunning = 1;
{ TPasJSWebserverProcessesForm }
procedure TPasJSWebserverProcessesForm.FormShow(Sender: TObject);
begin
TPJSController.Instance.OnRefresh:=@DoControllerRefresh;
RefreshList;
end;
procedure TPasJSWebserverProcessesForm.SBrefreshClick(Sender: TObject);
begin
RefreshList;
end;
procedure TPasJSWebserverProcessesForm.FormClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
CloseAction:=caFree;
end;
procedure TPasJSWebserverProcessesForm.FormCreate(Sender: TObject);
begin
Localize;
end;
procedure TPasJSWebserverProcessesForm.Localize;
begin
LCount.Caption:=SafeFormat(SWebserversCount, ['0']);
Caption:=SWebserversCaption;
With LVProcesses do
begin
Column[0].Caption:=SWebserversPort;
Column[1].Caption:=SWebserversStatus;
Column[2].Caption:=SWebserversBaseDir;
Column[3].Caption:=SWebserversProject;
Column[4].Caption:=SWebserversExtra;
end;
end;
procedure TPasJSWebserverProcessesForm.FormDestroy(Sender: TObject);
begin
TPJSController.Instance.OnRefresh:=Nil;
if (Self=TheForm) then
TheForm:=Nil;
end;
procedure TPasJSWebserverProcessesForm.ServerInstanceToListItem(LI : TListItem;SI : TServerInstance);
Var
S,SError : String;
begin
LI.Caption:=IntToStr(SI.Port);
If SI.Running then
begin
LI.ImageIndex:=iiRunning;
S:=SStatusRunning;
end
else if (SI.RunError<>'') then
begin
S:=SStatusError;
SError:=SI.RunError;
end
else
begin
LI.ImageIndex:=iiStopped;
S:=SStatusStopped;
end;
LI.SubItems.Add(S);
LI.SubItems.Add(SI.BaseDir);
LI.SubItems.Add(SI.LastProject);
LI.SubItems.Add(SError);
LI.Data:=SI;
end;
procedure TPasJSWebserverProcessesForm.DoControllerRefresh(Sender: TObject);
begin
RefreshList;
end;
class function TPasJSWebserverProcessesForm.Instance: TPasJSWebserverProcessesForm;
begin
if TheForm=Nil then
TheForm:=TPasJSWebserverProcessesForm.Create(Application);
Result:=TheForm;
end;
procedure TPasJSWebserverProcessesForm.RefreshList;
Var
C : TPJSController;
I : integer;
LI : TListItem;
SI : TServerInstance;
begin
C:=TPJSController.Instance;
if (C=Nil) or (C.ServerInstances=Nil) or (C.ServerInstances.Count=0) then
begin
LVProcesses.Items.Clear;
LCount.Caption:=SafeFormat(SWebserversCount, ['0']);
exit;
end;
LCount.Caption:=SafeFormat(SWebserversCount, [IntToStr(C.ServerInstances.Count)]);
With LVProcesses.Items do
try
BeginUpdate;
Clear;
For I:=0 to C.ServerInstances.Count-1 do
begin
SI:=C.ServerInstances[i];
LI:=Add;
ServerInstanceToListItem(LI,SI);
end;
finally
EndUpdate;
end;
end;
end.

View File

@ -331,49 +331,3 @@ msgstr ""
msgid "HTML request to service URL %s failed: %s" msgid "HTML request to service URL %s failed: %s"
msgstr "" msgstr ""
#: strpas2jsdesign.spasjswebservercaption
msgctxt "strpas2jsdesign.spasjswebservercaption"
msgid "Pas2JS WebServers"
msgstr "WebServers Pas2JS"
#: strpas2jsdesign.sstatuserror
msgid "Error starting"
msgstr "Erreur au démarrage"
#: strpas2jsdesign.sstatusrunning
msgid "Running"
msgstr "Processus en cours"
#: strpas2jsdesign.sstatusstopped
msgid "Stopped"
msgstr "Exécution interrompue"
#: strpas2jsdesign.swebserversbasedir
msgid "Root directory"
msgstr "Répertoire racine"
#: strpas2jsdesign.swebserverscaption
msgid "Web server processes"
msgstr "Processus serveur Web"
#: strpas2jsdesign.swebserverscount
#, object-pascal-format
msgid "Number of webserver processes: %s"
msgstr "Nombre de processus serveur Web : %s"
#: strpas2jsdesign.swebserversextra
msgid "Additional info"
msgstr "Informations supplémentaires"
#: strpas2jsdesign.swebserversport
msgid "Port"
msgstr "Port"
#: strpas2jsdesign.swebserversproject
msgid "Project"
msgstr "Projet"
#: strpas2jsdesign.swebserversstatus
msgid "Status"
msgstr "Statut"

View File

@ -335,49 +335,3 @@ msgstr ""
msgid "HTML request to service URL %s failed: %s" msgid "HTML request to service URL %s failed: %s"
msgstr "" msgstr ""
#: strpas2jsdesign.spasjswebservercaption
msgctxt "strpas2jsdesign.spasjswebservercaption"
msgid "Pas2JS WebServers"
msgstr "Pas2JS webkiszolgálók"
#: strpas2jsdesign.sstatuserror
msgid "Error starting"
msgstr "Hiba az indításkor"
#: strpas2jsdesign.sstatusrunning
msgid "Running"
msgstr "Fut"
#: strpas2jsdesign.sstatusstopped
msgid "Stopped"
msgstr "Leállítva"
#: strpas2jsdesign.swebserversbasedir
msgid "Root directory"
msgstr "Gyökérkönyvtár"
#: strpas2jsdesign.swebserverscaption
msgid "Web server processes"
msgstr "Webkiszolgáló folyamatai"
#: strpas2jsdesign.swebserverscount
#, object-pascal-format
msgid "Number of webserver processes: %s"
msgstr "Webkiszolgáló folyamatainak száma: %s"
#: strpas2jsdesign.swebserversextra
msgid "Additional info"
msgstr "További infó"
#: strpas2jsdesign.swebserversport
msgid "Port"
msgstr "Port"
#: strpas2jsdesign.swebserversproject
msgid "Project"
msgstr "Projekt"
#: strpas2jsdesign.swebserversstatus
msgid "Status"
msgstr "Állapot"

View File

@ -321,49 +321,3 @@ msgstr ""
msgid "HTML request to service URL %s failed: %s" msgid "HTML request to service URL %s failed: %s"
msgstr "" msgstr ""
#: strpas2jsdesign.spasjswebservercaption
msgctxt "strpas2jsdesign.spasjswebservercaption"
msgid "Pas2JS WebServers"
msgstr ""
#: strpas2jsdesign.sstatuserror
msgid "Error starting"
msgstr ""
#: strpas2jsdesign.sstatusrunning
msgid "Running"
msgstr ""
#: strpas2jsdesign.sstatusstopped
msgid "Stopped"
msgstr ""
#: strpas2jsdesign.swebserversbasedir
msgid "Root directory"
msgstr ""
#: strpas2jsdesign.swebserverscaption
msgid "Web server processes"
msgstr ""
#: strpas2jsdesign.swebserverscount
#, object-pascal-format
msgid "Number of webserver processes: %s"
msgstr ""
#: strpas2jsdesign.swebserversextra
msgid "Additional info"
msgstr ""
#: strpas2jsdesign.swebserversport
msgid "Port"
msgstr ""
#: strpas2jsdesign.swebserversproject
msgid "Project"
msgstr ""
#: strpas2jsdesign.swebserversstatus
msgid "Status"
msgstr ""

View File

@ -334,49 +334,3 @@ msgstr ""
msgid "HTML request to service URL %s failed: %s" msgid "HTML request to service URL %s failed: %s"
msgstr "" msgstr ""
#: strpas2jsdesign.spasjswebservercaption
msgctxt "strpas2jsdesign.spasjswebservercaption"
msgid "Pas2JS WebServers"
msgstr "Servidores web Pas2JS"
#: strpas2jsdesign.sstatuserror
msgid "Error starting"
msgstr "Erro ao iniciar"
#: strpas2jsdesign.sstatusrunning
msgid "Running"
msgstr "Executando"
#: strpas2jsdesign.sstatusstopped
msgid "Stopped"
msgstr "Parado"
#: strpas2jsdesign.swebserversbasedir
msgid "Root directory"
msgstr "Diretório raiz"
#: strpas2jsdesign.swebserverscaption
msgid "Web server processes"
msgstr "Processos servidores web"
#: strpas2jsdesign.swebserverscount
#, object-pascal-format
msgid "Number of webserver processes: %s"
msgstr "Número de processos servidores web: %s"
#: strpas2jsdesign.swebserversextra
msgid "Additional info"
msgstr "Info adicional"
#: strpas2jsdesign.swebserversport
msgid "Port"
msgstr "Porta"
#: strpas2jsdesign.swebserversproject
msgid "Project"
msgstr "Projeto"
#: strpas2jsdesign.swebserversstatus
msgid "Status"
msgstr "Estado"

View File

@ -334,49 +334,3 @@ msgstr "Средство DTS2pas не создало файл вывода."
msgid "HTML request to service URL %s failed: %s" msgid "HTML request to service URL %s failed: %s"
msgstr "Запрос HTML по адресу сервиса %s завершился с ошибкой: %s" msgstr "Запрос HTML по адресу сервиса %s завершился с ошибкой: %s"
#: strpas2jsdesign.spasjswebservercaption
msgctxt "strpas2jsdesign.spasjswebservercaption"
msgid "Pas2JS WebServers"
msgstr "Веб-серверы Pas2JS"
#: strpas2jsdesign.sstatuserror
msgid "Error starting"
msgstr "Ошибка запуска"
#: strpas2jsdesign.sstatusrunning
msgid "Running"
msgstr "Запущен"
#: strpas2jsdesign.sstatusstopped
msgid "Stopped"
msgstr "Остановлен"
#: strpas2jsdesign.swebserversbasedir
msgid "Root directory"
msgstr "Корневой каталог"
#: strpas2jsdesign.swebserverscaption
msgid "Web server processes"
msgstr "Процессы веб-серверов"
#: strpas2jsdesign.swebserverscount
#, object-pascal-format
msgid "Number of webserver processes: %s"
msgstr "Количество процессов веб-серверов: %s"
#: strpas2jsdesign.swebserversextra
msgid "Additional info"
msgstr "Дополнительные сведения"
#: strpas2jsdesign.swebserversport
msgid "Port"
msgstr "Порт"
#: strpas2jsdesign.swebserversproject
msgid "Project"
msgstr "Проект"
#: strpas2jsdesign.swebserversstatus
msgid "Status"
msgstr "Состояние"

View File

@ -335,51 +335,3 @@ msgstr ""
msgid "HTML request to service URL %s failed: %s" msgid "HTML request to service URL %s failed: %s"
msgstr "" msgstr ""
#: strpas2jsdesign.spasjswebservercaption
#, fuzzy
msgctxt "strpas2jsdesign.spasjswebservercaption"
msgid "Pas2JS WebServers"
msgstr "Pas2JS Web Sunucuları"
#: strpas2jsdesign.sstatuserror
msgid "Error starting"
msgstr "Başlarken hata"
#: strpas2jsdesign.sstatusrunning
msgid "Running"
msgstr "Çalışıyor"
#: strpas2jsdesign.sstatusstopped
msgid "Stopped"
msgstr "Durduruldu"
#: strpas2jsdesign.swebserversbasedir
msgid "Root directory"
msgstr "Kök dizini"
#: strpas2jsdesign.swebserverscaption
msgid "Web server processes"
msgstr "Web sunucusu işlemleri"
#: strpas2jsdesign.swebserverscount
#, object-pascal-format, fuzzy, badformat
#| msgid "Number of webserver processes:"
msgid "Number of webserver processes: %s"
msgstr "Web sunucusu işlemlerinin sayısı:"
#: strpas2jsdesign.swebserversextra
msgid "Additional info"
msgstr "İlave bilgi"
#: strpas2jsdesign.swebserversport
msgid "Port"
msgstr "Port"
#: strpas2jsdesign.swebserversproject
msgid "Project"
msgstr "Proje"
#: strpas2jsdesign.swebserversstatus
msgid "Status"
msgstr "Durum"

View File

@ -333,49 +333,3 @@ msgstr ""
msgid "HTML request to service URL %s failed: %s" msgid "HTML request to service URL %s failed: %s"
msgstr "" msgstr ""
#: strpas2jsdesign.spasjswebservercaption
msgctxt "strpas2jsdesign.spasjswebservercaption"
msgid "Pas2JS WebServers"
msgstr "Веб-сервери Pas2JS"
#: strpas2jsdesign.sstatuserror
msgid "Error starting"
msgstr "Помилка запуску"
#: strpas2jsdesign.sstatusrunning
msgid "Running"
msgstr "Запущено"
#: strpas2jsdesign.sstatusstopped
msgid "Stopped"
msgstr "Зупинено"
#: strpas2jsdesign.swebserversbasedir
msgid "Root directory"
msgstr "Корневий каталог"
#: strpas2jsdesign.swebserverscaption
msgid "Web server processes"
msgstr "Процеси веб-серверів"
#: strpas2jsdesign.swebserverscount
#, object-pascal-format
msgid "Number of webserver processes: %s"
msgstr "Кількість процесів веб-серверів: %s"
#: strpas2jsdesign.swebserversextra
msgid "Additional info"
msgstr "Додаткові відомості"
#: strpas2jsdesign.swebserversport
msgid "Port"
msgstr "Порт"
#: strpas2jsdesign.swebserversproject
msgid "Project"
msgstr "Проєкт"
#: strpas2jsdesign.swebserversstatus
msgid "Status"
msgstr "Стан"

View File

@ -336,51 +336,3 @@ msgstr ""
msgid "HTML request to service URL %s failed: %s" msgid "HTML request to service URL %s failed: %s"
msgstr "" msgstr ""
#: strpas2jsdesign.spasjswebservercaption
#, fuzzy
msgctxt "strpas2jsdesign.spasjswebservercaption"
msgid "Pas2JS WebServers"
msgstr "Pas2JS Web服务器(WebServers)"
#: strpas2jsdesign.sstatuserror
msgid "Error starting"
msgstr "错误开始(starting)"
#: strpas2jsdesign.sstatusrunning
msgid "Running"
msgstr "运行"
#: strpas2jsdesign.sstatusstopped
msgid "Stopped"
msgstr "停止"
#: strpas2jsdesign.swebserversbasedir
msgid "Root directory"
msgstr "Root目录"
#: strpas2jsdesign.swebserverscaption
msgid "Web server processes"
msgstr "Web服务器进程(server processes)"
#: strpas2jsdesign.swebserverscount
#, object-pascal-format, fuzzy, badformat
#| msgid "Number of webserver processes:"
msgid "Number of webserver processes: %s"
msgstr "Web服务器进程(server processes)的数量"
#: strpas2jsdesign.swebserversextra
msgid "Additional info"
msgstr "附加信息"
#: strpas2jsdesign.swebserversport
msgid "Port"
msgstr "端口"
#: strpas2jsdesign.swebserversproject
msgid "Project"
msgstr "工程"
#: strpas2jsdesign.swebserversstatus
msgid "Status"
msgstr "状态"

View File

@ -9,11 +9,11 @@ interface
uses uses
PJSDsgnRegister, PJSDsgnOptsFrame, frmpas2jsbrowserprojectoptions, PJSDsgnRegister, PJSDsgnOptsFrame, frmpas2jsbrowserprojectoptions,
PJSDsgnOptions, frmpas2jsnodejsprojectoptions, pjscontroller, PJSDsgnOptions, frmpas2jsnodejsprojectoptions, PJSController,
frmpas2jswebservers, strpas2jsdesign, pjsprojectoptions, StrPas2JSDesign, PJSProjectOptions, frmPas2jsAtomPackageSettings,
frmPas2jsAtomPackageSettings, regpas2jsatom, regpas2jsvscode, regpas2jsatom, regpas2jsvscode, frmPas2jsVSCodeExtensionSettings,
frmPas2jsVSCodeExtensionSettings, frmhtmltoform, idehtml2class, frmdtstopas, frmhtmltoform, idehtml2class, frmdtstopas, idedtstopas, idehtmltools,
idedtstopas, idehtmltools, LazarusPackageIntf; LazarusPackageIntf;
implementation implementation

View File

@ -1,4 +1,4 @@
unit pjscontroller; unit PJSController;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}
@ -9,7 +9,7 @@ uses
// LazUtils // LazUtils
LazLoggerBase, LazUtilities, FileUtil, LazFileUtils, LazLoggerBase, LazUtilities, FileUtil, LazFileUtils,
// LCL // LCL
Forms, Controls, Forms, Controls, LazHelpIntf,
// IdeIntf // IdeIntf
MacroIntf, MacroDefIntf, ProjectIntf, CompOptsIntf, LazIDEIntf, MacroIntf, MacroDefIntf, ProjectIntf, CompOptsIntf, LazIDEIntf,
// pas2js // pas2js
@ -18,49 +18,11 @@ uses
Type Type
{ TServerInstance }
TServerInstance = Class(TCollectionItem)
private
FlastProject: String;
FPort: Word;
FProcess: TProcess;
FRunError: String;
FServerName: String;
FString: String;
function GetRunning: Boolean;
Protected
Property Process : TProcess Read FProcess;
Public
Destructor Destroy; override;
Procedure StartServer;
Procedure StopServer;
Property Port : Word Read FPort Write FPort;
Property BaseDir : String Read FString Write FString;
Property ServerName : String Read FServerName Write FServerName;
Property Running : Boolean Read GetRunning;
Property RunError : String Read FRunError;
Property LastProject : String Read FlastProject Write Flastproject;
end;
{ TServerInstanceList }
TServerInstanceList = Class(TCollection)
private
function GetInstance(AIndex : Integer): TServerInstance;
Public
Function IndexOfPort(APort: Word) : integer;
Function FindByPort(Aindex : Integer) : TServerInstance;
Function AddInstance(aPort : Word; Const ABaseURL, aServerName : String) : TServerInstance;
Property Instances [AIndex : Integer] : TServerInstance Read GetInstance; default;
end;
{ TPJSController } { TPJSController }
TPJSController = Class TPJSController = Class
Private Private
FOnRefresh: TNotifyEvent; FOnRefresh: TNotifyEvent;
FServerInstances: TServerInstanceList;
function GetPas2JSPath(const s: string; const {%H-}Data: PtrInt; var Abort: boolean): string; function GetPas2JSPath(const s: string; const {%H-}Data: PtrInt; var Abort: boolean): string;
function GetPas2JSWebServerPath(const s: string; const {%H-}Data: PtrInt; var Abort: boolean): string; function GetPas2JSWebServerPath(const s: string; const {%H-}Data: PtrInt; var Abort: boolean): string;
function GetPas2JSWebServerPort(const s: string; const {%H-}Data: PtrInt; var Abort: boolean): string; function GetPas2JSWebServerPort(const s: string; const {%H-}Data: PtrInt; var Abort: boolean): string;
@ -71,8 +33,6 @@ Type
function OnRunDebugInit(Sender: TObject; var Handled: boolean function OnRunDebugInit(Sender: TObject; var Handled: boolean
): TModalResult; ): TModalResult;
function OnRunWithoutDebugInit(Sender: TObject; var Handled: boolean): TModalResult; function OnRunWithoutDebugInit(Sender: TObject; var Handled: boolean): TModalResult;
function GetHTMLFilename(aProject: TLazProject; UseTestDir: boolean): string;
function GetWebDir(aProject: TLazProject): string;
function RunProject(Sender: TObject; WithDebug: boolean; var Handled: boolean): TModalResult; function RunProject(Sender: TObject; WithDebug: boolean; var Handled: boolean): TModalResult;
function SaveHTMLFileToTestDir(aProject: TLazProject): boolean; function SaveHTMLFileToTestDir(aProject: TLazProject): boolean;
Public Public
@ -82,8 +42,9 @@ Type
Class Function instance : TPJSController; Class Function instance : TPJSController;
Procedure Hook; virtual; Procedure Hook; virtual;
Procedure UnHook; virtual; Procedure UnHook; virtual;
Procedure RefreshView; function GetHTMLFilename(aProject: TLazProject; UseTestDir: boolean): string; virtual;
Property ServerInstances : TServerInstanceList Read FServerInstances; function GetWebDir(aProject: TLazProject): string; virtual;
function GetProjectURL(aProject: TLazProject): string; virtual;
Property OnRefresh : TNotifyEvent Read FOnRefresh Write FonRefresh; Property OnRefresh : TNotifyEvent Read FOnRefresh Write FonRefresh;
end; end;
@ -112,109 +73,20 @@ implementation
Var Var
ctrl : TPJSController; ctrl : TPJSController;
{ TServerInstanceList } { TPJSController }
function TServerInstanceList.GetInstance(AIndex : Integer): TServerInstance;
begin
Result:=Items[AIndex] as TServerInstance;
end;
function TServerInstanceList.IndexOfPort(APort: Word): integer;
begin
Result:=Count-1;
While (Result>=0) and (GetInstance(Result).Port<>APort) do Dec(Result);
end;
function TServerInstanceList.FindByPort(Aindex: Integer): TServerInstance;
Var
I : Integer;
begin
I:=IndexOfPort(Aindex);
If I=-1 then
Result:=nil
else
Result:=GetInstance(I);
end;
function TServerInstanceList.AddInstance(aPort: Word; const ABaseURL,
aServerName: String): TServerInstance;
begin
Result:=Add as TServerInstance;
Result.Port:=aPort;
Result.BaseDir:=ABaseURL;
Result.ServerName:=aServerName;
end;
{ TServerInstance }
function TServerInstance.GetRunning: Boolean;
begin
Result:=Assigned(FProcess);
if Result then
Result:=Process.Running;
end;
destructor TServerInstance.Destroy;
begin
StopServer;
FreeAndNil(FProcess);
inherited;
end;
procedure TServerInstance.StartServer;
begin
if Running then
exit;
If not Assigned(FProcess) then
FProcess:=TProcess.Create(Nil);
FProcess.Executable:=ServerName;
FProcess.Parameters.Add('-q');
FProcess.Parameters.Add('-p');
FProcess.Parameters.Add(IntToStr(Port));
FProcess.Parameters.AddStrings(PJSOptions.HTTPServerOpts);
{$IFDEF WINDOWS}
FProcess.Options:=[poNoConsole];
{$ENDIF}
if ConsoleVerbosity>=0 then
DebugLN(['Starting server from Directory : ',BaseDir]);
FProcess.CurrentDirectory:=BaseDir;
try
FProcess.Execute;
except
On E : Exception do
begin
FRunError:=E.Message;
Raise;
end;
end;
TPJSController.Instance.RefreshView;
end;
procedure TServerInstance.StopServer;
begin
if Running then
FProcess.Terminate(0);
TPJSController.Instance.RefreshView;
end;
class procedure TPJSController.DoneInstance; class procedure TPJSController.DoneInstance;
begin begin
FreeAndNil(Ctrl) FreeAndNil(Ctrl)
end; end;
class function TPJSController.instance: TPJSController; class function TPJSController.instance: TPJSController;
begin begin
if ctrl=Nil then if Ctrl=Nil then
Ctrl:=TPJSController.Create; Ctrl:=TPJSController.Create;
Result:=Ctrl; Result:=Ctrl;
end; end;
{ TPJSController }
function TPJSController.GetPas2JSPath(const s: string; const Data: PtrInt; function TPJSController.GetPas2JSPath(const s: string; const Data: PtrInt;
var Abort: boolean): string; var Abort: boolean): string;
begin begin
@ -271,39 +143,21 @@ begin
end; end;
function TPJSController.GetPas2jsProjectURL(const s: string; const Data: PtrInt; var Abort: boolean): string; function TPJSController.GetPas2jsProjectURL(const s: string; const Data: PtrInt; var Abort: boolean): string;
Var Var
FN : String; aProject: TLazProject;
begin begin
if (s<>'') and (ConsoleVerbosity>=0) then if (s<>'') and (ConsoleVerbosity>=0) then
debugln(['Hint: (lazarus) [TPJSController.GetPas2jsProjectURL] ignoring macro Pas2JSProjectURL parameter "',s,'"']); debugln(['Hint: (lazarus) [TPJSController.GetPas2jsProjectURL] ignoring macro Pas2JSProjectURL parameter "',s,'"']);
aProject:=LazarusIDE.ActiveProject;
if ConsoleVerbosity>0 then if ConsoleVerbosity>0 then
DebugLN(['LazarusIDE.ActiveProject.CustomData[PJSProjectWebBrowser]: ',LazarusIDE.ActiveProject.CustomData[PJSProjectWebBrowser]]); DebugLN(['LazarusIDE.ActiveProject.CustomData[PJSProjectWebBrowser]: ',aProject.CustomData[PJSProjectWebBrowser]]);
Abort:=LazarusIDE.ActiveProject.CustomData[PJSProjectWebBrowser]<>'1'; Abort:=aProject.CustomData[PJSProjectWebBrowser]<>'1';
if Abort then if Abort then
exit; exit;
if ConsoleVerbosity>0 then if ConsoleVerbosity>0 then
DebugLN(['LazarusIDE.ActiveProject.CustomData[PJSProjectURL]: ',LazarusIDE.ActiveProject.CustomData[PJSProjectURL]]); DebugLN(['LazarusIDE.ActiveProject.CustomData[PJSProjectURL]: ',aProject.CustomData[PJSProjectURL]]);
Result:=LazarusIDE.ActiveProject.CustomData[PJSProjectURL]; Result:=GetProjectURL(aProject);
if (Result='') then
begin
FN:=LazarusIDE.ActiveProject.CustomData[PJSProjectHTMLFile];
if ConsoleVerbosity>0 then
DebugLN(['LazarusIDE.ActiveProject.CustomData[PJSProjectHTMLFile]: ',LazarusIDE.ActiveProject.CustomData[PJSProjectHTMLFile]]);
if (FN='') then
FN:=ChangeFileExt(ExtractFileName(LazarusIDE.ActiveProject.ProjectInfoFile),'.html');
Result:=LazarusIDE.ActiveProject.CustomData[PJSProjectPort];
if (Result<>'') and (Result<>'0') then
Result:=Format('http://localhost:%s/%s',[Result,FN])
else
{$IFDEF WINDOWS}
Result:=Format('file:///%s',[ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile)+FN]);
{$ELSE}
Result:=Format('file://%s',[ExtractFilePath(LazarusIDE.ActiveProject.ProjectInfoFile)+FN]);
{$ENDIF}
end;
Abort:=(Result=''); Abort:=(Result='');
if ConsoleVerbosity>0 then if ConsoleVerbosity>0 then
DebugLN(['GetPas2jsProjectURL : ',Result]); DebugLN(['GetPas2jsProjectURL : ',Result]);
@ -315,7 +169,6 @@ var
begin begin
Result:=mrOk; Result:=mrOk;
aProject:=LazarusIDE.ActiveProject; aProject:=LazarusIDE.ActiveProject;
debugln(['AAA1 TPJSController.OnProjectBuilding ']);
if aProject=nil then exit; if aProject=nil then exit;
if aProject.IsVirtual then if aProject.IsVirtual then
begin begin
@ -327,58 +180,12 @@ end;
function TPJSController.OnRunDebugInit(Sender: TObject; var Handled: boolean function TPJSController.OnRunDebugInit(Sender: TObject; var Handled: boolean
): TModalResult; ): TModalResult;
begin begin
debugln(['AAA2 TPJSController.OnRunDebugInit ']);
Result:=RunProject(Sender,true,Handled); Result:=RunProject(Sender,true,Handled);
end; end;
function TPJSController.OnRunWithoutDebugInit(Sender: TObject; var Handled: boolean): TModalResult; function TPJSController.OnRunWithoutDebugInit(Sender: TObject; var Handled: boolean): TModalResult;
Var
ServerPort : Word;
WebProject : Boolean;
BaseDir : String;
aInstance : TServerInstance;
begin begin
debugln(['AAA3 TPJSController.OnRunWithoutDebugInit ']); Result:=RunProject(Sender,false,Handled);
Result:=mrOK;
With LazarusIDE.ActiveProject do
begin
if ConsoleVerbosity>=0 then
begin
DebugLn(['Info: WebProject=',CustomData[PJSProjectWebBrowser]]);
DebugLn(['Info: ServerPort=',CustomData[PJSProjectPort]]);
DebugLn(['Info: BaseDir=',ProjectInfoFile]);
end;
WebProject:=CustomData[PJSProjectWebBrowser]='1';
ServerPort:=StrToIntDef(CustomData[PJSProjectPort],0);
BaseDir:=ExtractFilePath(ProjectInfoFile);
end;
// Exit if we don't need to do anything
if Not (WebProject and (ServerPort>0)) then
Exit;
aInstance:=ServerInstances.FindByPort(ServerPort);
If Ainstance<>Nil then
begin
if ConsoleVerbosity>=0 then
DebugLn(['Info: Have instance running on port ',ServerPort]);
if Not SameFileName(BaseDir,aInstance.BaseDir) then
begin
if ConsoleVerbosity>=0 then
DebugLN(['Info: Instance on port ',ServerPort,' serves different directory: ',aInstance.BaseDir]);
// We should ask the user what to do ?
If aInstance.Running then
aInstance.StopServer;
end;
end
else
begin
Debugln(['Info: No instance running on port ',ServerPort, 'allocating it']);
aInstance:=ServerInstances.AddInstance(ServerPort,BaseDir,PJSOptions.GetParsedWebServerFilename);
end;
aInstance.LastProject:=LazarusIDE.ActiveProject.ProjectInfoFile;
aInstance.StartServer;
Handled:=False;
end; end;
function TPJSController.GetHTMLFilename(aProject: TLazProject; function TPJSController.GetHTMLFilename(aProject: TLazProject;
@ -425,33 +232,78 @@ begin
Result:=ExtractFilePath(aProject.ProjectInfoFile); Result:=ExtractFilePath(aProject.ProjectInfoFile);
end; end;
function TPJSController.GetProjectURL(aProject: TLazProject): string;
Var
HTMLFilename, WebDir: String;
Port: LongInt;
begin
if aProject=nil then
exit('');
Result:=aProject.CustomData[PJSProjectURL];
if Result<>'' then
IDEMacros.SubstituteMacros(Result);
if Result='' then
begin
Port:=StrToIntDef(aProject.CustomData[PJSProjectPort],-1);
HTMLFilename:=GetHTMLFilename(aProject,true);
if HTMLFilename='' then
begin
if Port<=0 then
HTMLFilename:=ChangeFileExt(aProject.ProjectInfoFile,'.html')
else
HTMLFilename:=ExtractFileNameOnly(aProject.ProjectInfoFile)+'.html';
end
else if Port>0 then
begin
WebDir:=GetWebDir(aProject);
HTMLFilename:=CreateRelativePath(HTMLFilename,WebDir);
end;
HTMLFilename:=FilenameToURLPath(HTMLFilename);
if Port<=0 then
Result:='file://'+HTMLFilename
else
Result:='http://127.0.0.1:'+IntToStr(Port)+'/'+HTMLFilename;
end;
end;
function TPJSController.RunProject(Sender: TObject; WithDebug: boolean; function TPJSController.RunProject(Sender: TObject; WithDebug: boolean;
var Handled: boolean): TModalResult; var Handled: boolean): TModalResult;
var var
aProject: TLazProject; aProject: TLazProject;
IsWebProject: Boolean; IsWebProject: Boolean;
ServerPort: Integer; ServerPort: Integer;
WebDir, HTMLFilename: String; WebDir, HTMLFilename, URL, WorkDir: String;
aServer: TSWSInstance; aServer: TSWSInstance;
begin begin
Result:=mrOk; Result:=mrOk;
if Sender=nil then ; if Sender=nil then ;
if WithDebug then ;
aProject:=LazarusIDE.ActiveProject; aProject:=LazarusIDE.ActiveProject;
if aProject=nil then exit; if aProject=nil then exit;
if not WithDebug then
exit; // compile normally and run the run parameters
IsWebProject:=aProject.CustomData[PJSProjectWebBrowser]='1'; IsWebProject:=aProject.CustomData[PJSProjectWebBrowser]='1';
ServerPort:=StrToIntDef(aProject.CustomData[PJSProjectPort],-1); if not IsWebProject then
if not IsWebProject or (ServerPort<0) then
exit; exit;
ServerPort:=StrToIntDef(aProject.CustomData[PJSProjectPort],-1);
URL:=aProject.CustomData[PJSProjectURL];
if (ServerPort<0) and (URL='') then
exit;
// Run webproject with Debug: build, start webserver, open browser
Handled:=true; Handled:=true;
// compile // compile
Result:=LazarusIDE.DoBuildProject(crRun,[]); Result:=LazarusIDE.DoBuildProject(crRun,[]);
if Result<>mrOk then exit; if Result<>mrOk then exit;
if ServerPort>=0 then
begin
// start web server // start web server
WebDir:=GetWebDir(aProject); WebDir:=GetWebDir(aProject);
if WebDir='' then if WebDir='' then
@ -472,6 +324,19 @@ begin
end; end;
if not SimpleWebServerController.OpenBrowserWithServer(aServer,HTMLFilename) then if not SimpleWebServerController.OpenBrowserWithServer(aServer,HTMLFilename) then
exit(mrCancel); exit(mrCancel);
end
else
begin
// start browser with user URL
URL:=GetProjectURL(aProject);
if aProject.IsVirtual then
WorkDir:=LazarusIDE.GetTestBuildDirectory
else
WorkDir:=ExtractFilePath(aProject.ProjectInfoFile);
if not SimpleWebServerController.OpenBrowserWithURL(URL,WorkDir) then
exit(mrCancel);
end;
end; end;
function TPJSController.SaveHTMLFileToTestDir(aProject: TLazProject): boolean; function TPJSController.SaveHTMLFileToTestDir(aProject: TLazProject): boolean;
@ -483,7 +348,6 @@ begin
// if project has a pas2js html filename, save it to the test directory // if project has a pas2js html filename, save it to the test directory
Result:=false; Result:=false;
HTMLFilename:=aProject.CustomData.Values[PJSProjectHTMLFile]; HTMLFilename:=aProject.CustomData.Values[PJSProjectHTMLFile];
debugln(['AAA7 TPJSController.SaveHTMLFileToTestDir ',HTMLFilename]);
if (HTMLFilename='') then if (HTMLFilename='') then
exit(true); exit(true);
if FilenameIsAbsolute(HTMLFilename) then if FilenameIsAbsolute(HTMLFilename) then
@ -519,13 +383,11 @@ end;
constructor TPJSController.Create; constructor TPJSController.Create;
begin begin
// Nothing for the moment // Nothing for the moment
FServerInstances:=TServerInstanceList.Create(TServerInstance);
end; end;
destructor TPJSController.Destroy; destructor TPJSController.Destroy;
begin begin
Unhook; Unhook;
FreeAndNil(FServerInstances);
inherited Destroy; inherited Destroy;
end; end;
@ -553,12 +415,6 @@ begin
// Nothing for the moment // Nothing for the moment
end; end;
procedure TPJSController.RefreshView;
begin
If Assigned(FOnRefresh) then
FOnRefresh(Self);
end;
finalization finalization
TPJSController.DoneInstance; TPJSController.DoneInstance;
end. end.

View File

@ -13,14 +13,14 @@ uses
// codetools // codetools
CodeToolManager, CodeCache, CodeToolManager, CodeCache,
// IdeIntf // IdeIntf
IDECommands, ToolbarIntf, MenuIntf, ProjectIntf, CompOptsIntf, LazIDEIntf, IDECommands, MenuIntf, ProjectIntf, CompOptsIntf, LazIDEIntf,
IDEOptionsIntf, IDEOptEditorIntf, ComponentEditors, SrcEditorIntf, IDEMsgIntf, IDEOptionsIntf, IDEOptEditorIntf, ComponentEditors, SrcEditorIntf, IDEMsgIntf,
IDEDialogs, IDEExternToolIntf, MacroIntf, PackageIntf, IDEDialogs, IDEExternToolIntf, MacroIntf, PackageIntf,
// Pas2js // Pas2js
idehtml2class, PJSDsgnOptions, PJSDsgnOptsFrame, idedtstopas, idehtml2class, PJSDsgnOptions, PJSDsgnOptsFrame, idedtstopas,
frmpas2jswebservers, frmpas2jsnodejsprojectoptions, frmpas2jsnodejsprojectoptions,
frmpas2jsbrowserprojectoptions, pjsprojectoptions, idehtmltools, frmpas2jsbrowserprojectoptions, PJSProjectOptions, idehtmltools,
frmhtmltoform, pjscontroller, StrPas2JSDesign; frmhtmltoform, PJSController, StrPas2JSDesign;
const const
ProjDescNamePas2JSWebApp = 'Web Application'; ProjDescNamePas2JSWebApp = 'Web Application';
@ -231,12 +231,6 @@ implementation
Var Var
SrcMnuItem,PrjMnuItem,PrjMnuItemAll : TIDEmenuCommand; SrcMnuItem,PrjMnuItem,PrjMnuItemAll : TIDEmenuCommand;
procedure ShowServerDialog(Sender: TObject);
begin
TPasJSWebserverProcessesForm.Instance.Show;
TPasJSWebserverProcessesForm.Instance.BringToFront;
end;
Type Type
{ TPas2JSHandler } { TPas2JSHandler }
@ -254,22 +248,15 @@ Type
Procedure OnPrjInspPopup(Sender : TObject); virtual; Procedure OnPrjInspPopup(Sender : TObject); virtual;
end; end;
Const
sPas2JSWebserverName = 'Pas2JSWebservers';
Var Var
Pas2JSHTMLClassDef : TPas2JSHTMLClassDef; Pas2JSHTMLClassDef : TPas2JSHTMLClassDef;
Pas2JSDTSToPasUnitDef : TPas2JSDTSToPasUnitDef; Pas2JSDTSToPasUnitDef : TPas2JSDTSToPasUnitDef;
Pas2JSHandler : TPas2JSHandler; Pas2JSHandler : TPas2JSHandler;
procedure Register; procedure Register;
Var Var
ViewCategory : TIDECommandCategory;
IDECommand : TIDECommand;
SrvWorker: TProjectPas2JSServiceWorker; SrvWorker: TProjectPas2JSServiceWorker;
PWA: TProjectPas2JSProgressiveWebApp; PWA: TProjectPas2JSProgressiveWebApp;
begin begin
Pas2JSHandler:=TPas2JSHandler.Create; Pas2JSHandler:=TPas2JSHandler.Create;
if Assigned(Pas2JSHandler) then; // Silence compiler warning if Assigned(Pas2JSHandler) then; // Silence compiler warning
@ -294,15 +281,6 @@ begin
// add IDE options frame // add IDE options frame
PJSOptionsFrameID:=RegisterIDEOptionsEditor(GroupEnvironment,TPas2jsOptionsFrame, PJSOptionsFrameID:=RegisterIDEOptionsEditor(GroupEnvironment,TPas2jsOptionsFrame,
PJSOptionsFrameID)^.Index; PJSOptionsFrameID)^.Index;
ViewCategory := IDECommandList.FindCategoryByName(CommandCategoryViewName);
if ViewCategory <> nil then
begin
IDECommand := RegisterIDECommand(ViewCategory,sPas2JSWebserverName,SPasJSWebserverCaption,
CleanIDEShortCut,CleanIDEShortCut,Nil,@ShowServerDialog);
if IDECommand <> nil then
RegisterIDEButtonCommand(IDECommand);
end;
RegisterIdeMenuCommand(itmViewDebugWindows,sPas2JSWebserverName,SPasJSWebserverCaption,nil,@ShowServerDialog);
// Add project options frame // Add project options frame
RegisterIDEOptionsEditor(GroupProject,TPas2JSProjectOptionsFrame, Pas2JSOptionsIndex); RegisterIDEOptionsEditor(GroupProject,TPas2JSProjectOptionsFrame, Pas2JSOptionsIndex);
@ -1438,12 +1416,11 @@ begin
SO(ShowUncaughtExceptions,baoShowException); SO(ShowUncaughtExceptions,baoShowException);
SO(UseWASI,baoUseWASI); SO(UseWASI,baoUseWASI);
SO(UseModule,baoUseModule); SO(UseModule,baoUseModule);
SO(StartHTTPServer,baoStartServer);
Self.ProjectPort:=ServerPort; Self.ProjectPort:=ServerPort;
SO(UseURL,baoUseURL); SO(UseURL,baoUseURL);
if baoStartServer in FOptions then if baoStartServer in FOptions then
begin begin
DebugLN(['Info: Start server port: ', Self.ProjectPort,'from: ',ServerPort]); DebugLN(['Info: Start server port: ', Self.ProjectPort,' from: ',ServerPort]);
end end
else else
begin begin

View File

@ -1,4 +1,4 @@
unit pjsprojectoptions; unit PJSProjectOptions;
{$mode objfpc}{$H+} {$mode objfpc}{$H+}

View File

@ -23,23 +23,6 @@ Resourcestring
pjsdNewVSCodeExtension = 'Visual Studio Code extension'; pjsdNewVSCodeExtension = 'Visual Studio Code extension';
pjsdNewVSCodeExtensionDescr = 'A pas2js program running as Visual Studio Code extension.'; pjsdNewVSCodeExtensionDescr = 'A pas2js program running as Visual Studio Code extension.';
// menu item
SPasJSWebserverCaption = 'Pas2JS WebServers';
// Static texts webservers form
SWebserversStatus = 'Status';
SWebserversPort = 'Port';
SWebserversBaseDir = 'Root directory';
SWebserversProject = 'Project';
SWebserversExtra = 'Additional info';
SWebserversCount = 'Number of webserver processes: %s';
SWebserversCaption = 'Web server processes';
// Dynamic texts webservers form
SStatusRunning = 'Running';
SStatusStopped = 'Stopped';
SStatusError = 'Error starting';
// IDE options frame // IDE options frame
pjsdSelectPas2jsExecutable = 'Select pas2js executable'; pjsdSelectPas2jsExecutable = 'Select pas2js executable';
pjsdSelectXExecutable = 'Select %s executable'; pjsdSelectXExecutable = 'Select %s executable';

View File

@ -364,7 +364,7 @@ begin
end; end;
if (p=0) and ResolvePort0 then if (p=0) and ResolvePort0 then
p:=Controller.FindFreePort(Interactive); p:=Controller.FindFreePort(Interactive,false);
aPort:=IntToStr(p); aPort:=IntToStr(p);

View File

@ -42,7 +42,7 @@ unit SimpleWebSrvController;
interface interface
uses uses
Math, Classes, SysUtils, process, Pipes, Contnrs, fpjson, fphttpclient, Math, Types, Classes, SysUtils, process, Pipes, Contnrs, fpjson, fphttpclient,
Sockets, Sockets,
// lazutils // lazutils
LazLoggerBase, FileUtil, LazUTF8, LazFileUtils, LazMethodList, LazUtilities, LazLoggerBase, FileUtil, LazUTF8, LazFileUtils, LazMethodList, LazUtilities,
@ -238,13 +238,14 @@ type
Path: string; Interactive: boolean): TSWSInstance; virtual; Path: string; Interactive: boolean): TSWSInstance; virtual;
function FindServerWithPort(Port: word): TSWSInstance; virtual; function FindServerWithPort(Port: word): TSWSInstance; virtual;
function FindServerWithOrigin(Origin: string): TSWSInstance; virtual; function FindServerWithOrigin(Origin: string): TSWSInstance; virtual;
function FindFreePort(Interactive: boolean; aStartPort: word = 0): word; virtual; function FindFreePort(Interactive, CheckServers: boolean; aStartPort: word = 0): word; virtual;
function StopServer(Instance: TSWSInstance; Interactive: boolean): boolean; virtual; function StopServer(Instance: TSWSInstance; Interactive: boolean): boolean; virtual;
function SubstitutePortMacro(aValue, aPort: string): string; function SubstitutePortMacro(aValue, aPort: string): string;
function SubstituteURLMacro(aValue, AnURL: string): string; function SubstituteURLMacro(aValue, AnURL: string): string;
function GetDefaultServerExe: string; virtual; function GetDefaultServerExe: string; virtual;
// browser // browser
function GetURLWithServer(aServer: TSWSInstance; HTMLFilename: string): string; virtual; function GetURLWithServer(aServer: TSWSInstance; HTMLFilename: string): string; virtual;
function OpenBrowserWithURL(URL, WorkDir: string): boolean; virtual;
function OpenBrowserWithServer(aServer: TSWSInstance; HTMLFilename: string): boolean; virtual; function OpenBrowserWithServer(aServer: TSWSInstance; HTMLFilename: string): boolean; virtual;
function FindBrowserFile(ShortFilename: string): string; virtual; function FindBrowserFile(ShortFilename: string): string; virtual;
function FindBrowserPath(Filenames: array of string; URL: string; Params: TStrings): string; virtual; function FindBrowserPath(Filenames: array of string; URL: string; Params: TStrings): string; virtual;
@ -497,7 +498,7 @@ begin
exit; exit;
mrRetry: mrRetry:
begin begin
NewPort:=FindFreePort(true); NewPort:=FindFreePort(true,false);
if NewPort=0 then if NewPort=0 then
NewPort:=GetNextIPPort(MainSrvInstance.Port); NewPort:=GetNextIPPort(MainSrvInstance.Port);
FMainSrvInstance.Port:=NewPort; FMainSrvInstance.Port:=NewPort;
@ -1537,7 +1538,7 @@ begin
Result:=nil; Result:=nil;
try try
if Port=0 then if Port=0 then
Port:=FindFreePort(Interactive); Port:=FindFreePort(Interactive,true);
if FindServerWithPort(Port)<>nil then if FindServerWithPort(Port)<>nil then
raise ESimpleWebServerException.Create('port '+IntToStr(Port)+' already in use'); raise ESimpleWebServerException.Create('port '+IntToStr(Port)+' already in use');
@ -1580,6 +1581,7 @@ var
var var
Exe, Origin: String; Exe, Origin: String;
Params: TStringList; Params: TStringList;
ConflictServer: TSWSInstance;
begin begin
Result:=nil; Result:=nil;
@ -1589,6 +1591,9 @@ begin
Origin:=aProject.ProjectInfoFile; Origin:=aProject.ProjectInfoFile;
aServer:=FindServerWithOrigin(Origin); aServer:=FindServerWithOrigin(Origin);
if (aServer=nil) and not aProject.IsVirtual then
aServer:=FindServerWithOrigin(SWSTestprojectOrigin);
if (aServer<>nil) and (aServer.Path<>Path) then if (aServer<>nil) and (aServer.Path<>Path) then
if not StopOldServer(20220410145323,'Path changed') then exit; if not StopOldServer(20220410145323,'Path changed') then exit;
@ -1604,7 +1609,11 @@ begin
if aServer<>nil then if aServer<>nil then
Port:=aServer.Port // keep port Port:=aServer.Port // keep port
else else
Port:=FindFreePort(Interactive); Port:=FindFreePort(Interactive,true);
end else begin
ConflictServer:=FindServerWithPort(Port);
if (ConflictServer<>aServer) then
Port:=FindFreePort(Interactive,true);
end; end;
Params:=TStringList.Create; Params:=TStringList.Create;
@ -1618,7 +1627,10 @@ begin
if not StopOldServer(20220410145559,'Params changed') then exit; if not StopOldServer(20220410145559,'Params changed') then exit;
if aServer<>nil then if aServer<>nil then
begin
aServer.Origin:=Origin;
exit(aServer); exit(aServer);
end;
Result:=AddServer(Port,Exe,Params,Path,Origin,false,Interactive); Result:=AddServer(Port,Exe,Params,Path,Origin,false,Interactive);
finally finally
@ -1647,12 +1659,23 @@ begin
Result:=nil; Result:=nil;
end; end;
function TSimpleWebServerController.FindFreePort(Interactive: boolean; function TSimpleWebServerController.FindFreePort(Interactive,
aStartPort: word): word; CheckServers: boolean; aStartPort: word): word;
var
AvoidPorts: TWordDynArray;
i: Integer;
begin begin
if aStartPort=0 then if aStartPort=0 then
aStartPort:=MainSrvPort; aStartPort:=MainSrvPort;
Result:=FUtility.FindFreePort(aStartPort,Interactive); if CheckServers then
begin
Setlength(AvoidPorts,ServerCount);
for i:=0 to ServerCount-1 do
AvoidPorts[i]:=Servers[i].Port;
end else
AvoidPorts:=nil;
Result:=FUtility.FindFreePort(aStartPort,Interactive,AvoidPorts);
end; end;
function TSimpleWebServerController.StopServer(Instance: TSWSInstance; function TSimpleWebServerController.StopServer(Instance: TSWSInstance;
@ -1711,20 +1734,13 @@ begin
Result:='http://127.0.0.1:'+IntToStr(aServer.Port)+'/'+Result; Result:='http://127.0.0.1:'+IntToStr(aServer.Port)+'/'+Result;
end; end;
function TSimpleWebServerController.OpenBrowserWithServer( function TSimpleWebServerController.OpenBrowserWithURL(URL, WorkDir: string
aServer: TSWSInstance; HTMLFilename: string): boolean; ): boolean;
var var
URL, Cmd, Exe: String;
Params: TStringList; Params: TStringList;
Cmd, Exe: String;
Tool: TIDEExternalToolOptions; Tool: TIDEExternalToolOptions;
begin begin
if aServer=nil then
raise Exception.Create('TSimpleWebServerController.OpenBrowserWithServer 20220410185207');
if not FilenameIsAbsolute(HTMLFilename) then
raise Exception.Create('TSimpleWebServerController.OpenBrowserWithServer 20220410185208');
URL:=GetURLWithServer(aServer,HTMLFilename);
Params:=TStringList.Create; Params:=TStringList.Create;
try try
case Options.BrowserKind of case Options.BrowserKind of
@ -1770,7 +1786,7 @@ begin
Tool.Title:='Browser('+ExtractFileName(Exe)+')'; Tool.Title:='Browser('+ExtractFileName(Exe)+')';
Tool.Executable:=Exe; Tool.Executable:=Exe;
Tool.CmdLineParams:=MergeCmdLineParams(Params); Tool.CmdLineParams:=MergeCmdLineParams(Params);
Tool.WorkingDirectory:=ExtractFilePath(HTMLFilename); Tool.WorkingDirectory:=WorkDir;
Tool.MaxIdleInMS:=1000; Tool.MaxIdleInMS:=1000;
Result:=RunExternalTool(Tool); Result:=RunExternalTool(Tool);
finally finally
@ -1778,6 +1794,21 @@ begin
end; end;
end; end;
function TSimpleWebServerController.OpenBrowserWithServer(
aServer: TSWSInstance; HTMLFilename: string): boolean;
var
URL: String;
begin
if aServer=nil then
raise Exception.Create('TSimpleWebServerController.OpenBrowserWithServer 20220410185207');
if not FilenameIsAbsolute(HTMLFilename) then
raise Exception.Create('TSimpleWebServerController.OpenBrowserWithServer 20220410185208');
URL:=GetURLWithServer(aServer,HTMLFilename);
Result:=OpenBrowserWithURL(URL,ExtractFilePath(HTMLFilename));
end;
function TSimpleWebServerController.FindBrowserFile(ShortFilename: string function TSimpleWebServerController.FindBrowserFile(ShortFilename: string
): string; ): string;
begin begin

View File

@ -16,7 +16,7 @@ uses
{$IFDEF Unix} {$IFDEF Unix}
BaseUnix, Errors, BaseUnix, Errors,
{$ENDIF} {$ENDIF}
Classes, SysUtils, Sockets, Process, Classes, SysUtils, Types, Sockets, Process,
LazLoggerBase, FileUtil, LazLoggerBase, FileUtil,
Dialogs, Dialogs,
IDEDialogs; IDEDialogs;
@ -31,22 +31,22 @@ type
{$IFDEF Darwin} {$IFDEF Darwin}
function FindProcessListeningOnPortMac(const IPAddr: in_addr; aPort: word; out aDesc: string; out aPID: integer): boolean; function FindProcessListeningOnPortMac(const IPAddr: in_addr; aPort: word; out aDesc: string; out aPID: integer): boolean;
function KillProcessMac(aPID: integer): boolean; function KillProcessMac(aPID: integer): boolean;
function FindFreePortMac(aStartPort: word): word; function FindFreePortMac(aStartPort: word; AvoidPorts: TWordDynArray): word;
{$ENDIF} {$ENDIF}
{$IFDEF Linux} {$IFDEF Linux}
function FindProcessListeningOnPortLinux(const IPAddr: in_addr; aPort: word; out aDesc: string; out aPID: integer): boolean; function FindProcessListeningOnPortLinux(const IPAddr: in_addr; aPort: word; out aDesc: string; out aPID: integer): boolean;
function KillProcessLinux(aPID: integer): boolean; function KillProcessLinux(aPID: integer): boolean;
function FindFreePortLinux(aStartPort: word): word; function FindFreePortLinux(aStartPort: word; AvoidPorts: TWordDynArray): word;
{$ENDIF} {$ENDIF}
{$IFDEF MSWindows} {$IFDEF MSWindows}
function FindProcessListeningOnPortWin(const IPAddr: in_addr; aPort: word; out aDesc: string; out aPID: integer): boolean; function FindProcessListeningOnPortWin(const IPAddr: in_addr; aPort: word; out aDesc: string; out aPID: integer): boolean;
function KillProcessWin(aPID: integer): boolean; function KillProcessWin(aPID: integer): boolean;
function FindFreePortWin(aStartPort: word): word; function FindFreePortWin(aStartPort: word; AvoidPorts: TWordDynArray): word;
{$ENDIF} {$ENDIF}
public public
function FindProcessListeningOnPort(const IPAddr: in_addr; aPort: word; out aDesc: string; out aPID: integer): boolean; function FindProcessListeningOnPort(const IPAddr: in_addr; aPort: word; out aDesc: string; out aPID: integer): boolean;
function KillProcess(aPID: integer): boolean; function KillProcess(aPID: integer): boolean;
function FindFreePort(aStartPort: word; Interactive: boolean): word; function FindFreePort(aStartPort: word; Interactive: boolean; AvoidPorts: TWordDynArray): word;
function SameInAddr(const A,B: in_addr): boolean; function SameInAddr(const A,B: in_addr): boolean;
property ViewCaption: string read FViewCaption write FViewCaption; property ViewCaption: string read FViewCaption write FViewCaption;
end; end;
@ -165,18 +165,18 @@ begin
end; end;
function TSimpleWebServerUtility.FindFreePort(aStartPort: word; function TSimpleWebServerUtility.FindFreePort(aStartPort: word;
Interactive: boolean): word; Interactive: boolean; AvoidPorts: TWordDynArray): word;
begin begin
Result:=0; Result:=0;
try try
{$IFDEF Darwin} {$IFDEF Darwin}
Result:=FindFreePortMac(aStartPort); Result:=FindFreePortMac(aStartPort,AvoidPorts);
{$ENDIF} {$ENDIF}
{$IFDEF Linux} {$IFDEF Linux}
Result:=FindFreePortLinux(aStartPort); Result:=FindFreePortLinux(aStartPort,AvoidPorts);
{$ENDIF} {$ENDIF}
{$IFDEF MSWindows} {$IFDEF MSWindows}
Result:=FindFreePortWin(aStartPort); Result:=FindFreePortWin(aStartPort,AvoidPorts);
{$ENDIF} {$ENDIF}
except except
on E: Exception do begin on E: Exception do begin
@ -367,7 +367,8 @@ begin
Result:=false; Result:=false;
end; end;
function TSimpleWebServerUtility.FindFreePortMac(aStartPort: word): word; function TSimpleWebServerUtility.FindFreePortMac(aStartPort: word;
AvoidPorts: TWordDynArray): word;
const const
lsofparams = '-nPi4'; lsofparams = '-nPi4';
var var
@ -396,7 +397,7 @@ begin
exit; exit;
end; end;
Ports:=[]; Ports:=copy(AvoidPorts);
sl:=TStringList.Create; sl:=TStringList.Create;
try try
sl.Text:=OutStr; sl.Text:=OutStr;
@ -576,7 +577,8 @@ begin
Result:=false; Result:=false;
end; end;
function TSimpleWebServerUtility.FindFreePortLinux(aStartPort: word): word; function TSimpleWebServerUtility.FindFreePortLinux(aStartPort: word;
AvoidPorts: TWordDynArray): word;
const NetstatParams = '-nlptu4'; const NetstatParams = '-nlptu4';
var var
ExePath, OutStr, Line, CurLocalAddr: String; ExePath, OutStr, Line, CurLocalAddr: String;
@ -584,7 +586,7 @@ var
i: Integer; i: Integer;
LocalAddrPos, ForeignAddrPos, p, l: SizeInt; LocalAddrPos, ForeignAddrPos, p, l: SizeInt;
CurPort: LongInt; CurPort: LongInt;
Ports: array of word; Ports: TWordDynArray;
begin begin
Result:=0; Result:=0;
// query netstat to find the IPv4 tcp/udp ports // query netstat to find the IPv4 tcp/udp ports
@ -606,7 +608,7 @@ begin
exit; exit;
end; end;
Ports:=[]; Ports:=copy(AvoidPorts);
sl:=TStringList.Create; sl:=TStringList.Create;
try try
sl.Text:=OutStr; sl.Text:=OutStr;
@ -733,7 +735,8 @@ begin
end; end;
end; end;
function TSimpleWebServerUtility.FindFreePortWin(aStartPort: word): word; function TSimpleWebServerUtility.FindFreePortWin(aStartPort: word;
AvoidPorts: TWordDynArray): word;
var var
pTCPTable: PMIB_TCPTABLE2; pTCPTable: PMIB_TCPTABLE2;
aSize, r: DWord; aSize, r: DWord;
@ -757,8 +760,8 @@ begin
r:=GetTcpTable2(pTCPTable,aSize,true); r:=GetTcpTable2(pTCPTable,aSize,true);
if r<>NO_ERROR then exit; if r<>NO_ERROR then exit;
Ports:=copy(AvoidPorts);
{$R-} {$R-}
Ports:=[];
for i:=0 to pTCPTable^.dwNumEntries-1 do for i:=0 to pTCPTable^.dwNumEntries-1 do
begin begin
LocalPort:=NToHs(word(pTCPTable^.table[i].dwLocalPort)); LocalPort:=NToHs(word(pTCPTable^.table[i].dwLocalPort));