pict 1.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.babelrc +3 -0
- package/.browserslistrc +1 -0
- package/.browserslistrc_compatible +1 -0
- package/.browserslistrc_default +1 -0
- package/.config/code-server/config.yaml +4 -0
- package/.config/configstore/update-notifier-npm-check-updates.json +4 -0
- package/.config/configstore/update-notifier-npm.json +4 -0
- package/.config/installation/UI-Requirements.md +32 -0
- package/.config/installation/install_luxury_code.js +105 -0
- package/.config/installation/install_luxury_default_configuration.json +45 -0
- package/.config/installation/install_luxury_interaction.json +3 -0
- package/.config/installation/precedent.1.0.5.js +339 -0
- package/.config/luxury-extras/.vscode/launch.json +46 -0
- package/.config/luxury-extras/Dockerfile_LUXURYCode +39 -0
- package/.config/luxury-extras/MySQL/Dockerfile_LUXURYCODE_MySQL +65 -0
- package/.config/luxury-extras/MySQL/MySQL-Laden-Entry.sh +17 -0
- package/.config/luxury-extras/MySQL/MySQL-Security.sql +5 -0
- package/.travis.yml +14 -0
- package/.vscode/launch.json +46 -0
- package/Dockerfile_LUXURYCode +39 -0
- package/LICENSE +22 -0
- package/README.md +79 -0
- package/bower.json +25 -0
- package/debug/Harness.js +35 -0
- package/debug/examples/informary/Harness.js +19 -0
- package/debug/examples/informary/README.md +43 -0
- package/debug/examples/informary/bootstrap/css/bootstrap.css +10259 -0
- package/debug/examples/informary/bootstrap/js/bootstrap.min.js +7 -0
- package/debug/examples/informary/index.html +379 -0
- package/debug/examples/simpleApp/index.html +66 -0
- package/dist/pict.compatible.js +5705 -0
- package/dist/pict.compatible.min.js +246 -0
- package/dist/pict.compatible.min.js.map +1 -0
- package/dist/pict.js +5705 -0
- package/dist/pict.min.js +238 -0
- package/dist/pict.min.js.map +1 -0
- package/gulpfile-config.json +11 -0
- package/gulpfile-config_compatible.json +11 -0
- package/gulpfile-config_default.json +11 -0
- package/gulpfile.js +164 -0
- package/package.json +66 -0
- package/site_prototype/index.html +23 -0
- package/source/Pict-Browser-Shim.js +15 -0
- package/source/Pict-Fable-Service-Elucidator.js +17 -0
- package/source/Pict-Fable-Service-Informary.js +17 -0
- package/source/Pict-Fable-Service-Manyfest.js +24 -0
- package/source/Pict-Template-Provider.js +105 -0
- package/source/Pict.js +141 -0
- package/test/Pict_tests.js +139 -0
- package/test/data/SampleRecord-Quantity.json +13 -0
package/gulpfile.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
After hours of reading and trying various ways of using gulp-env, environment variables
|
|
5
|
+
and babel browesrslistrc / package.json environments it is clear that the state of using
|
|
6
|
+
these tools is a mess. There are ways of getting it to work but none of them feel like
|
|
7
|
+
they will work well in the long term (all of the examples seem to be in bands of about
|
|
8
|
+
a year or two of working before the pattern changes entirely).
|
|
9
|
+
|
|
10
|
+
WHY did we need such a crazy compatible version? wkhtmltopdf is why. It uses a very
|
|
11
|
+
old incompatible version of the QT browser.
|
|
12
|
+
|
|
13
|
+
Therefore, we will use a very old and simple method.
|
|
14
|
+
|
|
15
|
+
1) There is a config file (gulpfile-config.json), documented here, describing the inputs and outputs for the build operation.
|
|
16
|
+
|
|
17
|
+
const _CONFIG = (
|
|
18
|
+
{
|
|
19
|
+
// The input source file that should be passed to browserify:
|
|
20
|
+
// (if you need to auto-instantiate an object, for instance)
|
|
21
|
+
EntrypointInputSourceFile: `${__dirname}/source/Fable-Browser-Shim.js`,
|
|
22
|
+
|
|
23
|
+
// The name of the packaged object to be passed to browserify:
|
|
24
|
+
// (browserify sets this to global scope and window.SOMEOBJECTNAMEHERE where SOMEOBJECTNAMEHERE is the string below)
|
|
25
|
+
LibraryObjectName: `Fable`,
|
|
26
|
+
|
|
27
|
+
// The folder to write the library files and maps out to:
|
|
28
|
+
LibraryOutputFolder: `${__dirname}/dist/`,
|
|
29
|
+
|
|
30
|
+
// The name of the unminified version of the packaged library, for easy debugging:
|
|
31
|
+
LibraryUniminifiedFileName: `fable.js`,
|
|
32
|
+
|
|
33
|
+
// The name of the minified version of the packaged library, for production release:
|
|
34
|
+
LibraryMinifiedFileName: `fable.min.js`
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
2) We are using a .browserslistrc file... this is what tells gulp-babel, through the
|
|
38
|
+
magic of the @babel/preset-env library, how to transpile the library into a compatible
|
|
39
|
+
enough format for our targets.
|
|
40
|
+
|
|
41
|
+
For example as of writing this, there are two targets we want:
|
|
42
|
+
|
|
43
|
+
* Modern browsers in the last five years, expressed as a .browserslistrc with the string "since 2018"
|
|
44
|
+
* Very old janky browsers expressed as a .browserslistrc with the string "> 0.01%"
|
|
45
|
+
... which is interpreted as anything more than 0.01% of browsers in existence or something like that
|
|
46
|
+
|
|
47
|
+
3) Because we want multiple outputs, and, the tools do fine if we want one output but some of
|
|
48
|
+
the toolchain doesn't like making different targets well, we're just going to have multiple
|
|
49
|
+
configurations and .browserslistrc files. So if our spec above says we need a ".browserslistrc"
|
|
50
|
+
file and a "gulpfile-config.json", we're going to make the following two sets of configuration:
|
|
51
|
+
|
|
52
|
+
* .browserslistrc_default, .gulpfile-config_default.json
|
|
53
|
+
* .browserslistrc_compatible, .gulpfile-config_compatible.json
|
|
54
|
+
|
|
55
|
+
4) We will copy, synchronously, these files to where the rest of our toolchain expects
|
|
56
|
+
them, before we begin the build. This will be done by looking at the GULP_CUSTOM_BUILD_TARGET
|
|
57
|
+
environment variable. This allows us to create new targets to experiment by copying a couple files,
|
|
58
|
+
jimmying the settings and setting an environment variable before running the pipeline.
|
|
59
|
+
|
|
60
|
+
5) We will run the toolchain and it will happily think it's just doing a single build and kinda work.
|
|
61
|
+
|
|
62
|
+
*/
|
|
63
|
+
// BEGINNING OF STEP 3 and STEP 4 ABOVE
|
|
64
|
+
const libFS = require('fs');
|
|
65
|
+
const _GULP_CUSTOM_BUILD_TARGET = (typeof(process.env.GULP_CUSTOM_BUILD_TARGET) == 'undefined') ? 'default' : process.env.GULP_CUSTOM_BUILD_TARGET;
|
|
66
|
+
console.log(`--> Gulp custom build target set to: [${_GULP_CUSTOM_BUILD_TARGET}]`);
|
|
67
|
+
const _GULP_CONFIG = `./gulpfile-config_${_GULP_CUSTOM_BUILD_TARGET}.json`;
|
|
68
|
+
const _GULP_CONFIG_TARGET = `./gulpfile-config.json`;
|
|
69
|
+
console.log(` : Environment set gulp config [${_GULP_CONFIG}] will be copied to [${_GULP_CONFIG_TARGET}]`);
|
|
70
|
+
if (!libFS.existsSync(`./${_GULP_CONFIG}`))
|
|
71
|
+
{
|
|
72
|
+
console.log(`!!!> Enviromnent set gulp config doesn't exist!`);
|
|
73
|
+
process.exit(1);
|
|
74
|
+
}
|
|
75
|
+
else
|
|
76
|
+
{
|
|
77
|
+
libFS.copyFileSync(_GULP_CONFIG, _GULP_CONFIG_TARGET);
|
|
78
|
+
console.log(` > Environment Gulp Config copied`);
|
|
79
|
+
}
|
|
80
|
+
const _BROWSERSLISTRC = `./.browserslistrc_${_GULP_CUSTOM_BUILD_TARGET}`;
|
|
81
|
+
const _BROWSERSLISTRC_TARGET = `./.browserslistrc`;
|
|
82
|
+
console.log(` : Environment set browserslistrc [${_BROWSERSLISTRC}] will be copied to [${_BROWSERSLISTRC_TARGET}]`);
|
|
83
|
+
if (!libFS.existsSync(`./${_GULP_CONFIG}`))
|
|
84
|
+
{
|
|
85
|
+
console.log(`!!!> Enviromnent set browserslistrc doesn't exist!`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
else
|
|
89
|
+
{
|
|
90
|
+
libFS.copyFileSync(_BROWSERSLISTRC, _BROWSERSLISTRC_TARGET);
|
|
91
|
+
console.log(` > Environment Gulp Config copied`);
|
|
92
|
+
}
|
|
93
|
+
console.log(`---> The browserslistrc compatibility set is: ${libFS.readFileSync(_BROWSERSLISTRC_TARGET, 'utf8')}`);
|
|
94
|
+
// END OF STEP 3 and STEP 4 ABOVE
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
// ---> Now load the config and get on with building <--- \\
|
|
98
|
+
console.log(``);
|
|
99
|
+
console.log(`---> Loading the gulp config...`);
|
|
100
|
+
const _CONFIG = require('./gulpfile-config.json');
|
|
101
|
+
console.log(` > Building to [${_CONFIG.LibraryUniminifiedFileName}] and [${_CONFIG.LibraryMinifiedFileName}]`)
|
|
102
|
+
|
|
103
|
+
// ---> Boilerplate Browser Uglification and Packaging <--- \\
|
|
104
|
+
console.log(``);
|
|
105
|
+
console.log(`--> Gulp is taking over!`);
|
|
106
|
+
|
|
107
|
+
const libBrowserify = require('browserify');
|
|
108
|
+
const libGulp = require('gulp');
|
|
109
|
+
|
|
110
|
+
const libVinylSourceStream = require('vinyl-source-stream');
|
|
111
|
+
const libVinylBuffer = require('vinyl-buffer');
|
|
112
|
+
|
|
113
|
+
const libSourcemaps = require('gulp-sourcemaps');
|
|
114
|
+
const libGulpUtil = require('gulp-util');
|
|
115
|
+
const libBabel = require('gulp-babel');
|
|
116
|
+
const libTerser = require('gulp-terser');
|
|
117
|
+
|
|
118
|
+
// Build the module for the browser
|
|
119
|
+
libGulp.task('minified',
|
|
120
|
+
() => {
|
|
121
|
+
// set up the custom browserify instance for this task
|
|
122
|
+
var tmpBrowserify = libBrowserify(
|
|
123
|
+
{
|
|
124
|
+
entries: _CONFIG.EntrypointInputSourceFile,
|
|
125
|
+
standalone: _CONFIG.LibraryObjectName,
|
|
126
|
+
debug: true
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
return tmpBrowserify.bundle()
|
|
130
|
+
.pipe(libVinylSourceStream(_CONFIG.LibraryMinifiedFileName))
|
|
131
|
+
.pipe(libVinylBuffer())
|
|
132
|
+
.pipe(libSourcemaps.init({loadMaps: true}))
|
|
133
|
+
// Add transformation tasks to the pipeline here.
|
|
134
|
+
.pipe(libBabel())
|
|
135
|
+
.pipe(libTerser())
|
|
136
|
+
.on('error', libGulpUtil.log)
|
|
137
|
+
.pipe(libSourcemaps.write('./'))
|
|
138
|
+
.pipe(libGulp.dest(_CONFIG.LibraryOutputFolder));
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
// Build the module for the browser
|
|
142
|
+
libGulp.task('debug',
|
|
143
|
+
() => {
|
|
144
|
+
// set up the custom browserify instance for this task
|
|
145
|
+
var tmpBrowserify = libBrowserify(
|
|
146
|
+
{
|
|
147
|
+
entries: _CONFIG.EntrypointInputSourceFile,
|
|
148
|
+
standalone: _CONFIG.LibraryObjectName,
|
|
149
|
+
debug: true
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
return tmpBrowserify.bundle()
|
|
153
|
+
.pipe(libVinylSourceStream(_CONFIG.LibraryUniminifiedFileName))
|
|
154
|
+
.pipe(libVinylBuffer())
|
|
155
|
+
.pipe(libBabel())
|
|
156
|
+
.on('error', libGulpUtil.log)
|
|
157
|
+
.pipe(libGulp.dest(_CONFIG.LibraryOutputFolder));
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
libGulp.task
|
|
161
|
+
(
|
|
162
|
+
'build',
|
|
163
|
+
libGulp.series('debug', 'minified')
|
|
164
|
+
);
|
package/package.json
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "pict",
|
|
3
|
+
"version": "1.0.7",
|
|
4
|
+
"description": "Pict browser library.",
|
|
5
|
+
"main": "source/Pict.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node source/Pict.js",
|
|
8
|
+
"coverage": "./node_modules/.bin/nyc --reporter=lcov --reporter=text-lcov ./node_modules/mocha/bin/_mocha -- -u tdd -R spec",
|
|
9
|
+
"test": "./node_modules/.bin/mocha -u tdd -R spec",
|
|
10
|
+
"build": "./node_modules/.bin/gulp build",
|
|
11
|
+
"build-compatible": "GULP_CUSTOM_BUILD_TARGET=compatible ./node_modules/.bin/gulp build"
|
|
12
|
+
},
|
|
13
|
+
"mocha": {
|
|
14
|
+
"diff": true,
|
|
15
|
+
"extension": [
|
|
16
|
+
"js"
|
|
17
|
+
],
|
|
18
|
+
"package": "./package.json",
|
|
19
|
+
"reporter": "spec",
|
|
20
|
+
"slow": "75",
|
|
21
|
+
"timeout": "5000",
|
|
22
|
+
"ui": "tdd",
|
|
23
|
+
"watch-files": [
|
|
24
|
+
"source/**/*.js",
|
|
25
|
+
"test/**/*.js"
|
|
26
|
+
],
|
|
27
|
+
"watch-ignore": [
|
|
28
|
+
"lib/vendor"
|
|
29
|
+
]
|
|
30
|
+
},
|
|
31
|
+
"repository": {
|
|
32
|
+
"type": "git",
|
|
33
|
+
"url": "git+https://stevenvelozo@github.com/stevenvelozo/pict.git"
|
|
34
|
+
},
|
|
35
|
+
"author": "steven velozo <steven@velozo.com>",
|
|
36
|
+
"license": "MIT",
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/stevenvelozo/pict/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/stevenvelozo/pict#readme",
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@babel/core": "^7.21.5",
|
|
43
|
+
"@babel/preset-env": "^7.21.5",
|
|
44
|
+
"browserify": "^17.0.0",
|
|
45
|
+
"chai": "4.3.7",
|
|
46
|
+
"gulp": "^4.0.2",
|
|
47
|
+
"gulp-babel": "^8.0.0",
|
|
48
|
+
"gulp-env": "^0.4.0",
|
|
49
|
+
"gulp-sourcemaps": "^3.0.0",
|
|
50
|
+
"gulp-strip-comments": "^2.5.2",
|
|
51
|
+
"gulp-terser": "^2.1.0",
|
|
52
|
+
"gulp-util": "^3.0.8",
|
|
53
|
+
"jsdom": "^21.1.2",
|
|
54
|
+
"mocha": "10.2.0",
|
|
55
|
+
"nyc": "^15.1.0",
|
|
56
|
+
"vinyl-buffer": "^1.0.1",
|
|
57
|
+
"vinyl-source-stream": "^2.0.0"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"elucidator": "^1.0.7",
|
|
61
|
+
"fable": "^3.0.26",
|
|
62
|
+
"informary": "^2.0.20",
|
|
63
|
+
"manyfest": "^1.0.19",
|
|
64
|
+
"mousetrap": "^1.6.5"
|
|
65
|
+
}
|
|
66
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
|
|
3
|
+
<html lang="en">
|
|
4
|
+
<head>
|
|
5
|
+
<!-- Use correct character set. -->
|
|
6
|
+
<meta charset="utf-8">
|
|
7
|
+
<title>Pict Application</title>
|
|
8
|
+
</head>
|
|
9
|
+
|
|
10
|
+
<body>
|
|
11
|
+
<!-- A container for the Navigation to be displayed in. -->
|
|
12
|
+
<div id="applicationNavigation"></div>
|
|
13
|
+
|
|
14
|
+
<!-- A container for the Application to live in. -->
|
|
15
|
+
<div id="applicationContainer"></div>
|
|
16
|
+
|
|
17
|
+
<!-- A container for the Side Panel to be displayed in. -->
|
|
18
|
+
<div id="applicationSidePanel"></div>
|
|
19
|
+
|
|
20
|
+
<!-- Pict Library -->
|
|
21
|
+
<script src="../dist/pict.js"></script>
|
|
22
|
+
</body>
|
|
23
|
+
</html>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pict browser shim loader
|
|
3
|
+
* @license MIT
|
|
4
|
+
* @author <steven@velozo.com>
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Load the pict module into the browser global automatically.
|
|
8
|
+
const libPict = require('./Pict.js');
|
|
9
|
+
|
|
10
|
+
if (typeof(window) === 'object')
|
|
11
|
+
{
|
|
12
|
+
window.Pict = libPict;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
module.exports = libPict;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const libFableServiceBase = require('fable').ServiceProviderBase;
|
|
2
|
+
|
|
3
|
+
const libElucidator = require('elucidator');
|
|
4
|
+
|
|
5
|
+
class FableServiceElucidator extends libFableServiceBase
|
|
6
|
+
{
|
|
7
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
8
|
+
{
|
|
9
|
+
super(pFable, pOptions, pServiceHash);
|
|
10
|
+
|
|
11
|
+
this.serviceType = 'Solver';
|
|
12
|
+
|
|
13
|
+
this.solver = new libElucidator(this.options);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = FableServiceElucidator;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
const libFableServiceBase = require('fable').ServiceProviderBase;
|
|
2
|
+
|
|
3
|
+
const libInformary = require('informary');
|
|
4
|
+
|
|
5
|
+
class FableServiceInformary extends libFableServiceBase
|
|
6
|
+
{
|
|
7
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
8
|
+
{
|
|
9
|
+
super(pFable, pOptions, pServiceHash);
|
|
10
|
+
|
|
11
|
+
this.serviceType = 'Informary';
|
|
12
|
+
|
|
13
|
+
this.informary = new libInformary(this.options.Settings, this.options.Context, this.options.ContextGUID);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
module.exports = FableServiceInformary;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const libFableServiceBase = require('fable').ServiceProviderBase;
|
|
2
|
+
|
|
3
|
+
const libManyfest = require('manyfest');
|
|
4
|
+
|
|
5
|
+
class FableServiceManyfest extends libFableServiceBase
|
|
6
|
+
{
|
|
7
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
8
|
+
{
|
|
9
|
+
super(pFable, pOptions, pServiceHash);
|
|
10
|
+
|
|
11
|
+
this.serviceType = 'Manifest';
|
|
12
|
+
|
|
13
|
+
if (JSON.stringify(this.options) == '{}')
|
|
14
|
+
{
|
|
15
|
+
this.options = { Scope:'PictDefault', Descriptors: {} };
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
this.manyfest = new libManyfest(this.options);
|
|
19
|
+
// Kinda the same thing, yo
|
|
20
|
+
this.manifest = this.manyfest;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
module.exports = FableServiceManyfest;
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
const libFableServiceBase = require('fable').ServiceProviderBase;
|
|
2
|
+
|
|
3
|
+
class PictTemplateProvider extends libFableServiceBase
|
|
4
|
+
{
|
|
5
|
+
constructor(pFable, pOptions, pServiceHash)
|
|
6
|
+
{
|
|
7
|
+
super(pFable, pOptions, pServiceHash);
|
|
8
|
+
|
|
9
|
+
this.serviceType = 'PictTemplateProvider';
|
|
10
|
+
|
|
11
|
+
this.templates = {};
|
|
12
|
+
|
|
13
|
+
// Default templates are stored by prefix.
|
|
14
|
+
// The longest prefix match is used.
|
|
15
|
+
// Case sensitive.
|
|
16
|
+
this.defaultTemplates = {};
|
|
17
|
+
// Sorted list of default templates by length.
|
|
18
|
+
// Since this is a sorted list of case sensitive keys by length, it shouldn't be possible to have collisions.
|
|
19
|
+
this.defaultTemplateHashes = [];
|
|
20
|
+
|
|
21
|
+
// This function can be overloaded to load templates from a database, in a page or other source.
|
|
22
|
+
this.loadTemplateFunction = (pTemplateHash) => { return false; };
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
addTemplate(pTemplateHash, pTemplate)
|
|
26
|
+
{
|
|
27
|
+
this.templates[pTemplateHash] = pTemplate;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
addDefaultTemplate(pTemplateHash, pTemplate)
|
|
31
|
+
{
|
|
32
|
+
if (typeof(pTemplate) != 'string')
|
|
33
|
+
{
|
|
34
|
+
this.log.error('PictTemplateProvider.addDefaultTemplate: pTemplate is not a string.');
|
|
35
|
+
}
|
|
36
|
+
this.defaultTemplates[pTemplateHash] = pTemplate;
|
|
37
|
+
this.defaultTemplateHashes = Object.keys(this.defaultTemplates).sort((a, b) => b.length - a.length);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
checkDefaultTemplateHash(pTemplateHash)
|
|
41
|
+
{
|
|
42
|
+
/*
|
|
43
|
+
* Default templates are managed by postfix. The use case is things like titles, headers, list wrappers, rows, etc.
|
|
44
|
+
*
|
|
45
|
+
* So we might have a default template for a list wrapper and it should expect "-ListWrap" as the postfix.
|
|
46
|
+
* And we might have a default template for a list row and it should expect "-ListRow" as the postfix.
|
|
47
|
+
* The list might have a "-ListTitle", or we might have shared titles and it would just be "-Title".
|
|
48
|
+
*
|
|
49
|
+
* The idea is to allow fallbacks on defaults.
|
|
50
|
+
*/
|
|
51
|
+
let tmpTemplateHashLength = pTemplateHash.length;
|
|
52
|
+
|
|
53
|
+
for (let i = 0; i < this.defaultTemplateHashes.length; i++)
|
|
54
|
+
{
|
|
55
|
+
// TODO: This is a bad way to check for a postfix.
|
|
56
|
+
// TODO: Is it a good idea to set the template so next time we don't have to check the defaults?
|
|
57
|
+
// * Pros: Faster.
|
|
58
|
+
// * Cons: If we later add another default template with a closer match, it won't get looked up.
|
|
59
|
+
// Faster wins for now.
|
|
60
|
+
if (pTemplateHash.indexOf(this.defaultTemplateHashes[i]) == tmpTemplateHashLength - this.defaultTemplateHashes[i].length)
|
|
61
|
+
{
|
|
62
|
+
this.templates[pTemplateHash] = this.defaultTemplates[this.defaultTemplateHashes[i]];
|
|
63
|
+
return this.templates[pTemplateHash];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
getTemplate(pTemplateHash)
|
|
70
|
+
{
|
|
71
|
+
// TODO: Optimize this.
|
|
72
|
+
// If the template doesn't exist, try to load it with the loading function
|
|
73
|
+
if (!this.templates.hasOwnProperty(pTemplateHash))
|
|
74
|
+
{
|
|
75
|
+
this.loadTemplate(pTemplateHash);
|
|
76
|
+
}
|
|
77
|
+
// If the loading function fails, try to load it from the default templates
|
|
78
|
+
if (!this.templates.hasOwnProperty(pTemplateHash))
|
|
79
|
+
{
|
|
80
|
+
this.checkDefaultTemplateHash(pTemplateHash);
|
|
81
|
+
}
|
|
82
|
+
if (this.templates.hasOwnProperty(pTemplateHash))
|
|
83
|
+
{
|
|
84
|
+
return this.templates[pTemplateHash];
|
|
85
|
+
}
|
|
86
|
+
else
|
|
87
|
+
{
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
loadTemplate(pTemplateHash)
|
|
93
|
+
{
|
|
94
|
+
let tmpTemplate = this.loadTemplateFunction(pTemplateHash);
|
|
95
|
+
|
|
96
|
+
if (tmpTemplate)
|
|
97
|
+
{
|
|
98
|
+
this.templates[pTemplateHash] = tmpTemplate;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return tmpTemplate;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
module.exports = PictTemplateProvider;
|
package/source/Pict.js
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license MIT
|
|
3
|
+
* @author <steven@velozo.com>
|
|
4
|
+
*/
|
|
5
|
+
const libFable = require('fable');
|
|
6
|
+
|
|
7
|
+
// Pict Services
|
|
8
|
+
const libPictTemplateProvider = require('./Pict-Template-Provider.js');
|
|
9
|
+
|
|
10
|
+
// External Library Services
|
|
11
|
+
const libFableServiceManyfest = require('./Pict-Fable-Service-Manyfest.js');
|
|
12
|
+
const libFableServiceElucidator = require('./Pict-Fable-Service-Elucidator.js');
|
|
13
|
+
const libFableServiceInformary = require('./Pict-Fable-Service-Informary.js');
|
|
14
|
+
|
|
15
|
+
const libMouseTrap = require('mousetrap');
|
|
16
|
+
|
|
17
|
+
class Pict
|
|
18
|
+
{
|
|
19
|
+
constructor(pOptions)
|
|
20
|
+
{
|
|
21
|
+
this.fable = new libFable(pOptions);
|
|
22
|
+
|
|
23
|
+
this.log = this.fable.log;
|
|
24
|
+
this.settings = this.fable.settings;
|
|
25
|
+
|
|
26
|
+
this.serviceManager = this.fable.serviceManager;
|
|
27
|
+
|
|
28
|
+
this.fable.serviceManager.addServiceType('TemplateProvider', libPictTemplateProvider);
|
|
29
|
+
|
|
30
|
+
this.fable.serviceManager.addServiceType('Manifest', libFableServiceManyfest);
|
|
31
|
+
this.fable.serviceManager.addServiceType('Solver', libFableServiceElucidator);
|
|
32
|
+
this.fable.serviceManager.addServiceType('Informary', libFableServiceInformary);
|
|
33
|
+
|
|
34
|
+
// Register the services
|
|
35
|
+
|
|
36
|
+
// The templateProvider provides a basic key->template mapping with default fallback capabilities
|
|
37
|
+
this.templateProvider = this.fable.serviceManager.instantiateServiceProvider('TemplateProvider', {}, 'defaultTemplateProvider');
|
|
38
|
+
|
|
39
|
+
this.defaultTemplateProcessor = this.fable.serviceManager.instantiateServiceProvider('MetaTemplate', {}, 'defaultTemplateProcessor');
|
|
40
|
+
this._DefaultTemplateMethodsInitialized = false;
|
|
41
|
+
|
|
42
|
+
this.manifestServiceProvider = this.fable.serviceManager.instantiateServiceProvider('Manifest', {}, 'defaultManifest');
|
|
43
|
+
this.manifest = this.manifestServiceProvider.manifest;
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
this.appData = {};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
initializeTemplateMethods(fExtraTemplateMethods)
|
|
50
|
+
{
|
|
51
|
+
/*
|
|
52
|
+
*
|
|
53
|
+
* To stave off madness, these are inefficient for now. The wkhtmltopdf renderer leaves much to be desired
|
|
54
|
+
* in the way of feedback with regards to javascript compatibility.
|
|
55
|
+
*
|
|
56
|
+
*/
|
|
57
|
+
if (!this._DefaultTemplateMethodsInitialized)
|
|
58
|
+
{
|
|
59
|
+
this.defaultTemplateProcessor.addPattern('{~Data:', '~}',
|
|
60
|
+
(pHash, pData)=>
|
|
61
|
+
{
|
|
62
|
+
let tmpHash = pHash.trim();
|
|
63
|
+
let tmpValue = this.manifest.getValueAtAddress({AppData: this.appData, Record: pData}, tmpHash);
|
|
64
|
+
|
|
65
|
+
if ((tmpValue == null) || (tmpValue == 'undefined') || (typeof(tmpValue) == 'undefined'))
|
|
66
|
+
{
|
|
67
|
+
//console.log('undefined!');
|
|
68
|
+
return '';
|
|
69
|
+
}
|
|
70
|
+
return tmpValue;
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
this.defaultTemplateProcessor.addPattern('{~Dollars:', '~}',
|
|
74
|
+
(pHash, pData)=>
|
|
75
|
+
{
|
|
76
|
+
let tmpHash = pHash.trim();
|
|
77
|
+
let tmpColumnData = this.manifest.getValueAtAddress({AppData: this.appData, Record: pData}, tmpHash);
|
|
78
|
+
|
|
79
|
+
let tmpValue = this.fable.DataArithmatic.formatterDollars(tmpColumnData);
|
|
80
|
+
|
|
81
|
+
return tmpValue;
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
this.defaultTemplateProcessor.addPattern('{~Digits:', '~}',
|
|
85
|
+
(pHash, pData)=>
|
|
86
|
+
{
|
|
87
|
+
let tmpHash = pHash.trim();
|
|
88
|
+
let tmpColumnData = this.manifest.getValueAtAddress({AppData: this.appData, Record: pData}, tmpHash);
|
|
89
|
+
|
|
90
|
+
let tmpValue = this.fable.DataArithmatic.formatterAddCommasToNumber(this.fable.DataArithmatic.formatterRoundNumber(tmpColumnData, 2));
|
|
91
|
+
|
|
92
|
+
return tmpValue;
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
this.defaultTemplateProcessor.addPattern('{~NotEmpty:', '~}',
|
|
96
|
+
(pHash, pData)=>
|
|
97
|
+
{
|
|
98
|
+
let tmpHash = pHash.trim();
|
|
99
|
+
let tmpHashParts = tmpHash.split('|');
|
|
100
|
+
|
|
101
|
+
if (tmpHashParts.length != 2)
|
|
102
|
+
{
|
|
103
|
+
return '';
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
let tmpTruthiness = this.manifest.getValueAtAddress({AppData: this.appData, Record: pData}, tmpHashParts[0]);
|
|
107
|
+
|
|
108
|
+
let tmpValue = '';
|
|
109
|
+
|
|
110
|
+
// For now just check truthiness
|
|
111
|
+
if (tmpTruthiness)
|
|
112
|
+
{
|
|
113
|
+
tmpValue = tmpHashParts[1];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
return tmpValue;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
this._DefaultTemplateMethodsInitialized = true;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
parseTemplate (pTemplateString, pData)
|
|
124
|
+
{
|
|
125
|
+
return this.defaultTemplateProcessor.parseString(pTemplateString, pData);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
parseTemplateByHash (pTemplateHash, pData)
|
|
129
|
+
{
|
|
130
|
+
let tmpTemplateString = this.templateProvider.getTemplate(pTemplateHash);
|
|
131
|
+
|
|
132
|
+
// TODO: Unsure if returning empty is always the right behavior -- if it isn't we will use config to set the behavior
|
|
133
|
+
if (!tmpTemplateString)
|
|
134
|
+
{
|
|
135
|
+
return '';
|
|
136
|
+
}
|
|
137
|
+
return this.parseTemplate(tmpTemplateString, pData);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
module.exports = Pict;
|