Skip to content

Commit 0671839

Browse files
committed
API update
1 parent 5767105 commit 0671839

File tree

7 files changed

+83
-100
lines changed

7 files changed

+83
-100
lines changed

README.md

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,17 @@ These are the basic steps for building your first PEB-based application:
4848

4949
* **4.** Connect your Perl scripts using a link to ``name-of-script-configuration-object.settings``.
5050

51-
Note that PEB is created to work from any folder without installation and all files and directories used by PEB are relational to the directory where the PEB binary is located. All your local HTML files and Perl scripts must be located inside the ``{PEB_binary_directory}/resources/app`` directory.
51+
Note that PEB is created to work from any folder without installation and all your local HTML files and Perl scripts should be located inside the ``{PEB_binary_directory}/resources/app`` directory.
5252

5353
## Design Objectives
54-
* **1. Fast and easy graphical user interface for Perl 5 desktop applications:**
55-
use Perl 5, JavaScript, HTML and CSS to create beautiful desktop applications
56-
57-
* **2. Zero installation:**
58-
run from any folder
59-
60-
* **3. Cross-platform availability:**
61-
usable on every platform where Perl 5 and Qt 5 are available
62-
63-
* **4. Secure serverless solution:**
64-
no server of any kind is installed or started
65-
54+
* **1. Fast and easy and beautiful graphical user interface for Perl 5 desktop applications**
55+
* **2. Zero installation**
56+
* **3. Cross-platform availability**
57+
* **4. Secure serverless solution**
6658
* **5. Maximal reuse of existing web technologies and standards**
6759

6860
## Features
69-
* [Perl script output is seamlessly inserted into the calling local page.](#perl-scripts-api)
61+
* [Perl script output is seamlessly inserted in any local page.](#perl-scripts-api)
7062
* [Perl scripts with STDIN event loops can be repeatedly fed with data.](#interactive-perl-scripts)
7163
* [Any version of Perl 5 can be used.](#runtime-requirements)
7264
* PEB can be started from any folder.
@@ -78,6 +70,7 @@ Note that PEB is created to work from any folder without installation and all fi
7870

7971
## Security
8072
* PEB does not need administrative privileges, but does not refuse to use them if needed.
73+
* PEB does not install or start any kind of server.
8174
* PEB executes with no sandbox only local Perl 5 scripts and
8275
users have full access to their local files.
8376
* Cross-origin requests and cross-site scripting are disabled.
@@ -142,26 +135,32 @@ Sometimes it is important to minimize the size of the relocatable (or portable)
142135
``compactor.pl`` relies on ``Module::ScanDeps`` and ``File::Copy::Recursive`` CPAN modules, which are located in the ``{PEB_binary_directory}/sdk/lib`` folder.
143136

144137
## Perl Scripts API
145-
Every Perl script run by PEB is called by clicking a link or submitting a form to a pseudo filename composed from the name of the JavaScript object with the settings of the Perl script and a ``.settings`` extension. Perl data output is seamlessly inserted into the HTML DOM of the local page using JavaScript.
138+
Every Perl script run by PEB is called by clicking a link or submitting a form to a pseudo filename composed from the name of the JavaScript object with the settings of the Perl script and a ``.settings`` extension.
139+
140+
A minimal example of a Perl script settings object and a starting link:
146141

147-
A minimal example of a Perl script settings object:
142+
```html
143+
<a href="perl_test.settings">Start Perl script</a>
144+
```
148145

149146
```javascript
150-
var perlScriptObject = {};
151-
perlScriptObject.path = '{app}/perl/test.pl';
152-
perlScriptObject.stdout = function (stdout) {
147+
var perl_test = {};
148+
perl_test.scriptFullPath = '{app}/perl/test.pl';
149+
perl_test.stdoutFunction = function (stdout) {
153150
var container = document.getElementById('tests');
154151
container.innerHTML = stdout;
155152
}
156153
```
157154

158-
* ``path``
155+
* ``scriptFullPath``
159156
This is the path of the Perl script that is going to be executed.
160157
The keyword ``{app}`` will be replaced by the the full path of the application directory.
158+
PEB does not check the file name extension or the shebang line of the supplied Perl script.
159+
Scripts without a file name extension can also be used.
161160
*This object property is mandatory.*
162161

163-
* ``stdout``
164-
The ``stdout`` object property must be a JavaScript function. Every piece of script output is passed to this function as its only argument.
162+
* ``stdoutFunction``
163+
The ``stdoutFunction`` object property must be a JavaScript function. Every piece of script output is passed to this function as its only argument.
165164
*This object property is mandatory.*
166165

167166
* ``requestMethod``
@@ -191,16 +190,16 @@ perlScriptObject.stdout = function (stdout) {
191190
}
192191
```
193192

194-
* ``close_command``
195-
The ``close_command`` object property designates the command used to gracefully shut down an interactive script when the containing PEB window is going to be closed. Upon receiving it, the interactive script must start its shutdown procedure.
193+
* ``scriptExitCommand``
194+
The ``scriptExitCommand`` object property designates the command used to gracefully shut down an interactive script when PEB is going to be closed. Upon receiving it, the interactive script must start its shutdown procedure.
196195

197-
* ``close_confirmation``
198-
Just before exiting an interactive script must print on STDOUT its ``close_confirmation`` to signal PEB that it completed its shutdown. All interactive scripts must exit in 3 seconds after ``close_command`` is given or any unresponsive scripts will be killed and PEB will exit.
196+
* ``scriptExitConfirmation``
197+
Just before exiting an interactive script must print on STDOUT its ``scriptExitConfirmation`` to signal PEB that it completed its shutdown. All interactive scripts must exit in 3 seconds after ``scriptExitCommand`` is given or any unresponsive scripts will be killed and PEB will exit.
199198

200199
Perl scripts running for a long time should have ``$|=1;`` among their first lines to disable the built-in buffering of the Perl interpreter. Some builds of Perl may not give any output until the script is finished when buffering is enabled.
201200

202201
## Interactive Perl Scripts
203-
Each PEB interactive Perl script must have its own event loop waiting constantly for new data on STDIN for a bidirectional connection with PEB. Many interactive scripts can be started simultaneously in one browser window. One script may be started in many instances provided that it has an unique JavaScript settings object with and unique ``stdout`` object property. Interactive scripts should also have the ``close_command`` and ``close_confirmation`` object properties.
202+
Each PEB interactive Perl script must have its own event loop waiting constantly for new data on STDIN for a bidirectional connection with PEB. Many interactive scripts can be started simultaneously in one browser window. One script may be started in many instances provided that it has an unique JavaScript settings object with and unique ``stdoutFunction`` object property. Interactive scripts should also have the ``scriptExitCommand`` and ``scriptExitConfirmation`` object properties.
204203

205204
The following code shows how to start an interactive Perl script right after a local page is loaded:
206205

@@ -217,14 +216,17 @@ The following code shows how to start an interactive Perl script right after a l
217216
pebSettings.autoStartScripts = ['interactive_script'];
218217
219218
var interactive_script = {};
220-
interactive_script.path = '{app}/perl/interactive.pl';
221-
interactive_script.stdout = 'interactive-script-output';
219+
interactive_script.scriptFullPath = '{app}/perl/interactive.pl';
222220
interactive_script.requestMethod = 'POST';
223221
interactive_script.inputDataHarvester = function() {
224222
return document.getElementById('interactive-script-input').value;
225223
}
226-
interactive_script.closeCommand = '_close_';
227-
interactive_script.closeConfirmation = '_closed_';
224+
interactive_script.stdoutFunction = function (stdout) {
225+
var container = document.getElementById('interactive-script-output');
226+
container.innerHTML = stdout;
227+
}
228+
interactive_script.scriptExitCommand = '_close_';
229+
interactive_script.scriptExitConfirmation = '_closed_';
228230
</script>
229231
</head>
230232

@@ -242,7 +244,7 @@ The following code shows how to start an interactive Perl script right after a l
242244
The ``index.htm`` file of the demo package demonstrates how to start one script in two instances immediately after a page is loaded.
243245

244246
## Selecting Files and Folders
245-
Selecting files or folders with their full paths is performed by clicking a link to a pseudo filename composed from the name of the JavaScript object with the settings of the wanted dialog and a ``.dialog`` extension. Selected files or folders are seamlessly inserted in any local page using the ``target`` object property. ``target`` must be a JavaScript function which receives all selected files or folders as its only argument.
247+
Selecting files or folders with their full paths is performed by clicking a link to a pseudo filename composed from the name of the JavaScript object with the settings of the wanted dialog and a ``.dialog`` extension. Selected files or folders are seamlessly inserted in any local page by the ``receiverFunction`` taking all selected files or folders as its only argument.
246248

247249
```html
248250
<a href="select_file.dialog">Select existing file</a>
@@ -253,9 +255,9 @@ var select_file = {};
253255
// Type of the dialog, one of the following:
254256
// 'single-file', 'multiple-files', 'new-file-name' or 'directory'.
255257
select_file.type = 'single-file';
256-
select_file.target = function (stdout) {
257-
var container = document.getElementById('tests');
258-
container.innerHTML = stdout;
258+
select_file.receiverFunction = function (file) {
259+
var container = document.getElementById('single-file-test');
260+
container.innerHTML = file;
259261
}
260262
```
261263

@@ -298,7 +300,7 @@ my $data_directory = "$current_working_directory/resources/data";
298300
```
299301

300302
## Log Files
301-
If log files are needed for debugging of PEB or a PEB-based application, they can easily be turned on by manually creating ``{PEB_binary_directory}/logs``. If this directory is found during application startup, the browser assumes that logging is required and a separate log file is created for every browser session following the naming convention: ``{application_name}-started-at-{four_digit_year}-{month}-{day}--{hour}-{minute}-{second}.log``. PEB will not create ``{PEB_binary_directory}/logs`` on its own and if this directory is missing and no logs will be written. Please note that log files can grow rapidly and if disc space is an issue, writing log files can be turned off by simply removing or renaming ``{PEB_binary_directory}/logs``.
303+
If log files are needed for debugging of PEB or a PEB-based application, they can easily be turned on by manually creating ``{PEB_binary_directory}/logs``. If this directory is found during application startup, the browser assumes that logging is required and a separate log file is created for every browser session following the naming convention: ``{application_name}-started-at-{four_digit_year}-{month}-{day}--{hour}-{minute}-{second}.log``. PEB will not create ``{PEB_binary_directory}/logs`` on its own and if this directory is missing no logs will be written.
302304

303305
## Page Settings
304306

@@ -322,7 +324,7 @@ pebSettings.closeConfirmation =
322324
These are Perl scripts that are started immediately after a local page is loaded.
323325

324326
* ``closeConfirmation``
325-
This is the text displayed when user has pressed the close button, but unsaved data in local HTML forms is detected. If no warning text is found, PEB assumes that no warning has to be displayed and exits immediately.
327+
This text is displayed when the close button is pressed, but unsaved data in local HTML forms is detected. If no warning text is found, PEB exits immediately.
326328

327329
## Functional Pseudo Filenames
328330
* **About PEB dialog:** ``about-browser.function``

resources/app/index.html

Lines changed: 26 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -25,74 +25,67 @@
2525

2626
// Settings objects for the Perl scripts:
2727
var interactive_one = {};
28-
interactive_one.path = '{app}/perl/interactive.pl';
29-
interactive_one.stdout = function (stdout) {
30-
var target = document.getElementById('instance-one-output');
31-
target.innerHTML = stdout;
32-
}
28+
interactive_one.scriptFullPath = '{app}/perl/interactive.pl';
3329
interactive_one.requestMethod = 'POST';
34-
interactive_one.closeCommand = '_close_';
35-
interactive_one.closeConfirmation = '_closed_';
3630
interactive_one.inputDataHarvester = function() {
3731
var data = $('#form-one').serialize();
3832
$('#form-one').trigger('reset');
3933
return data;
4034
}
41-
42-
var interactive_two = {};
43-
interactive_two.path = '{app}/perl/interactive.pl';
44-
interactive_two.stdout = function (stdout) {
45-
var target = document.getElementById('instance-two-output');
35+
interactive_one.stdoutFunction = function (stdout) {
36+
var target = document.getElementById('instance-one-output');
4637
target.innerHTML = stdout;
4738
}
39+
interactive_one.scriptExitCommand = '_close_';
40+
interactive_one.scriptExitConfirmation = '_closed_';
41+
42+
var interactive_two = {};
43+
interactive_two.scriptFullPath = '{app}/perl/interactive.pl';
4844
interactive_two.requestMethod = 'POST';
49-
interactive_two.closeCommand = '_close_';
50-
interactive_two.closeConfirmation = '_closed_';
5145
interactive_two.inputDataHarvester = function() {
5246
var data = $('#form-two').serialize();
5347
$('#form-two').trigger('reset');
5448
return data;
5549
}
50+
interactive_two.stdoutFunction = function (stdout) {
51+
var target = document.getElementById('instance-two-output');
52+
target.innerHTML = stdout;
53+
}
54+
interactive_two.scriptExitCommand = '_close_';
55+
interactive_two.scriptExitConfirmation = '_closed_';
5656

5757
var get_test = {};
58-
get_test.path = '{app}/perl/get-post-test.pl';
59-
get_test.stdout = 'tests';
60-
get_test.stdout = function (stdout) {
58+
get_test.scriptFullPath = '{app}/perl/get-post-test.pl';
59+
get_test.stdoutFunction = function (stdout) {
6160
displayTestResult(stdout);
6261
}
6362
get_test.requestMethod = 'GET';
6463
get_test.inputData = 'name=Mickey&species=mouse';
6564

6665
var post_test = {};
67-
post_test.path = '{app}/perl/get-post-test.pl';
68-
post_test.stdout = function (stdout) {
66+
post_test.scriptFullPath = '{app}/perl/get-post-test.pl';
67+
post_test.stdoutFunction = function (stdout) {
6968
displayTestResult(stdout);
7069
}
7170
post_test.requestMethod = 'POST';
7271
post_test.inputData = 'name=Geoffrey&species=giraffe';
7372

7473
var perl_info = {};
75-
perl_info.path = '{app}/perl/perl-info.pl';
76-
perl_info.stdout = function (stdout) {
77-
displayTestResult(stdout);
78-
}
79-
80-
var extensionless = {};
81-
extensionless.path = '{app}/perl/extensionless';
82-
extensionless.stdout = function (stdout) {
74+
perl_info.scriptFullPath = '{app}/perl/perl-info.pl';
75+
perl_info.stdoutFunction = function (stdout) {
8376
displayTestResult(stdout);
8477
}
8578

8679
var sqlite = {};
87-
sqlite.path = '{app}/perl/sqlite.pl';
88-
sqlite.stdout = function (stdout) {
80+
sqlite.scriptFullPath = '{app}/perl/sqlite.pl';
81+
sqlite.stdoutFunction = function (stdout) {
8982
displayTestResult(stdout);
9083
}
9184

9285
// Filesystem dilog boxes configuration objects:
9386
var select_file = {};
9487
select_file.type = 'single-file';
95-
select_file.target = function (fileName) {
88+
select_file.receiverFunction = function (fileName) {
9689
clearTargetElement();
9790
var pre = document.createElement("pre");
9891
pre.innerHTML = 'Selected existing file: ' + fileName;
@@ -101,7 +94,7 @@
10194

10295
var new_file_name = {};
10396
new_file_name.type = 'new-file-name';
104-
new_file_name.target = function (fileName) {
97+
new_file_name.receiverFunction = function (fileName) {
10598
clearTargetElement();
10699
var pre = document.createElement("pre");
107100
pre.innerHTML = 'Selected new file name: ' + fileName;
@@ -110,7 +103,7 @@
110103

111104
var select_files = {};
112105
select_files.type = 'multiple-files';
113-
select_files.target = function (fileNames) {
106+
select_files.receiverFunction = function (fileNames) {
114107
clearTargetElement();
115108
var pre = document.createElement("pre");
116109
fileNames = fileNames.replace(/;/g, "<br>");
@@ -120,7 +113,7 @@
120113

121114
var select_directory = {};
122115
select_directory.type = 'directory';
123-
select_directory.target = function (directoryName) {
116+
select_directory.receiverFunction = function (directoryName) {
124117
clearTargetElement();
125118
var pre = document.createElement("pre");
126119
pre.innerHTML = 'Selected directory: ' + directoryName;
@@ -230,10 +223,6 @@
230223
<a href="perl_info.settings">Perl Basic information</a>
231224
</li>
232225

233-
<li>
234-
<a href="extensionless.settings">Extensionless Script</a>
235-
</li>
236-
237226
<li>
238227
<a href="sqlite.settings">SQLite Test</a>
239228
</li>

resources/app/perl/extensionless

Lines changed: 0 additions & 6 deletions
This file was deleted.

src/script-handler.cpp

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,15 @@
2626
QScriptHandler::QScriptHandler(QJsonObject scriptJsonObject)
2727
: QObject(0)
2828
{
29-
if (scriptJsonObject.length() == 0) {
30-
qDebug() << "Script settings are empty!";
29+
if (scriptJsonObject.length() == 1) {
30+
qDebug() << "No script settings!";
3131
return;
3232
}
3333

3434
scriptId = scriptJsonObject["id"].toString();
3535

36-
if (scriptJsonObject["path"].toString().length() > 0) {
37-
scriptFullFilePath = scriptJsonObject["path"].toString();
36+
if (scriptJsonObject["scriptFullPath"].toString().length() > 0) {
37+
scriptFullFilePath = scriptJsonObject["scriptFullPath"].toString();
3838
scriptFullFilePath.replace("{app}",
3939
qApp->property("application").toString());
4040
scriptFullFilePath = QDir::toNativeSeparators(scriptFullFilePath);
@@ -56,13 +56,13 @@ QScriptHandler::QScriptHandler(QJsonObject scriptJsonObject)
5656
inputData = scriptJsonObject["inputData"].toString();
5757
}
5858

59-
if (scriptJsonObject["closeCommand"].toString().length() > 0) {
60-
scriptCloseCommand = scriptJsonObject["closeCommand"].toString();
59+
if (scriptJsonObject["scriptExitCommand"].toString().length() > 0) {
60+
scriptExitCommand = scriptJsonObject["scriptExitCommand"].toString();
6161
}
6262

63-
if (scriptJsonObject["closeConfirmation"].toString().length() > 0) {
64-
scriptCloseConfirmation =
65-
scriptJsonObject["closeConfirmation"].toString();
63+
if (scriptJsonObject["scriptExitConfirmation"].toString().length() > 0) {
64+
scriptExitConfirmation =
65+
scriptJsonObject["scriptExitConfirmation"].toString();
6666
}
6767

6868
// Signals and slots for local long running Perl scripts:

src/script-handler.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ public slots:
4242
QString output = scriptProcess.readAllStandardOutput();
4343
scriptAccumulatedOutput.append(output);
4444

45-
if (output == scriptCloseConfirmation) {
45+
if (output == scriptExitConfirmation) {
4646
qDebug() << "Interactive script is exiting normally:"
4747
<< scriptFullFilePath;
4848
} else {
@@ -76,8 +76,8 @@ public slots:
7676
QString scriptStdout;
7777
QString scriptAccumulatedOutput;
7878
QString scriptAccumulatedErrors;
79-
QString scriptCloseCommand;
80-
QString scriptCloseConfirmation;
79+
QString scriptExitCommand;
80+
QString scriptExitConfirmation;
8181
};
8282

8383
#endif // SCRIPTHANDLER_H

0 commit comments

Comments
 (0)