bare-script 3.0.15 → 3.2.0
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/lib/bare.js +47 -4
- package/lib/include/args.mds +344 -0
- package/lib/include/forms.mds +79 -0
- package/lib/include/markdownUp.bare +466 -0
- package/lib/include/pager.mds +235 -0
- package/lib/include/unittest.mds +191 -0
- package/lib/include/unittestMock.mds +462 -0
- package/lib/value.js +20 -0
- package/package.json +2 -2
package/lib/bare.js
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
// Licensed under the MIT License
|
|
2
2
|
// https://github.com/craigahobbs/bare-script/blob/main/LICENSE
|
|
3
3
|
|
|
4
|
+
import {dirname, join} from 'path';
|
|
4
5
|
import {parseExpression, parseScript} from './parser.js';
|
|
5
6
|
import {evaluateExpression} from './runtime.js';
|
|
6
7
|
import {executeScriptAsync} from './runtimeAsync.js';
|
|
8
|
+
import {fileURLToPath} from 'url';
|
|
7
9
|
import {lintScript} from './model.js';
|
|
10
|
+
import {readFile} from 'fs/promises';
|
|
8
11
|
import {urlFileRelative} from './options.js';
|
|
9
12
|
import {valueBoolean} from './value.js';
|
|
10
13
|
|
|
@@ -51,8 +54,14 @@ export async function main(options) {
|
|
|
51
54
|
globals[varName] = evaluateExpression(parseExpression(varExpr));
|
|
52
55
|
}
|
|
53
56
|
|
|
57
|
+
// Get the scripts to run
|
|
58
|
+
let {scripts} = args;
|
|
59
|
+
if (args.markdownUp) {
|
|
60
|
+
scripts = [['code', 'include <markdownUp.bare>'], ...scripts];
|
|
61
|
+
}
|
|
62
|
+
|
|
54
63
|
// Parse and execute all source files in order
|
|
55
|
-
for (const [scriptType, scriptValue] of
|
|
64
|
+
for (const [scriptType, scriptValue] of scripts) {
|
|
56
65
|
// Get the script source
|
|
57
66
|
let scriptName;
|
|
58
67
|
let scriptSource;
|
|
@@ -103,12 +112,14 @@ export async function main(options) {
|
|
|
103
112
|
|
|
104
113
|
// Execute the script
|
|
105
114
|
const timeBegin = performance.now();
|
|
115
|
+
const {fetchFn} = options;
|
|
116
|
+
const fetchIncludeFn = (fetchURL, fetchOptions) => fetchInclude(fetchFn, fetchURL, fetchOptions);
|
|
106
117
|
const result = await executeScriptAsync(script, {
|
|
107
118
|
'debug': args.debug ?? false,
|
|
108
|
-
'fetchFn':
|
|
119
|
+
'fetchFn': fetchIncludeFn,
|
|
109
120
|
'globals': globals,
|
|
110
121
|
'logFn': options.logFn,
|
|
111
|
-
'systemPrefix':
|
|
122
|
+
'systemPrefix': fetchIncludePrefix,
|
|
112
123
|
'urlFn': scriptType === 'file' ? (url) => urlFileRelative(scriptName, url) : null
|
|
113
124
|
|
|
114
125
|
});
|
|
@@ -141,6 +152,35 @@ export async function main(options) {
|
|
|
141
152
|
}
|
|
142
153
|
|
|
143
154
|
|
|
155
|
+
function fetchInclude(fetchFn, url, options) {
|
|
156
|
+
// Is this a bare system include?
|
|
157
|
+
if (url.startsWith(fetchIncludePrefix)) {
|
|
158
|
+
const includePath = url.slice(fetchIncludePrefixPrefix.length);
|
|
159
|
+
|
|
160
|
+
// Get the include file path
|
|
161
|
+
const packageDir = dirname(fileURLToPath(import.meta.url));
|
|
162
|
+
const packagePath = join(packageDir, includePath);
|
|
163
|
+
|
|
164
|
+
// Return the include fetch-like promise
|
|
165
|
+
return new Promise((resolve) => {
|
|
166
|
+
const response = {
|
|
167
|
+
'ok': true,
|
|
168
|
+
'status': 200,
|
|
169
|
+
'statusText': 'OK',
|
|
170
|
+
'text': () => readFile(packagePath, 'utf8')
|
|
171
|
+
};
|
|
172
|
+
resolve(response);
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
return fetchFn(url, options);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
const fetchIncludePrefixPrefix = ':bare-include:/';
|
|
181
|
+
const fetchIncludePrefix = `${fetchIncludePrefixPrefix}include/`;
|
|
182
|
+
|
|
183
|
+
|
|
144
184
|
/**
|
|
145
185
|
* Parse the BareScript command-line interface (CLI) arguments
|
|
146
186
|
*
|
|
@@ -163,6 +203,8 @@ export function parseArgs(argv) {
|
|
|
163
203
|
args.debug = true;
|
|
164
204
|
} else if (arg === '-h' || arg === '--help') {
|
|
165
205
|
args.help = true;
|
|
206
|
+
} else if (arg === '-m' || arg === '--markdown-up') {
|
|
207
|
+
args.markdownUp = true;
|
|
166
208
|
} else if (arg === '-s' || arg === '--static') {
|
|
167
209
|
args.static = true;
|
|
168
210
|
} else if (arg === '-v' || arg === '--var') {
|
|
@@ -184,7 +226,7 @@ export function parseArgs(argv) {
|
|
|
184
226
|
|
|
185
227
|
// The command-line interface (CLI) help text
|
|
186
228
|
export const helpText = `\
|
|
187
|
-
usage: bare [-h] [-c CODE] [-d] [-s] [-v VAR EXPR] [file ...]
|
|
229
|
+
usage: bare [-h] [-c CODE] [-d] [-m] [-s] [-v VAR EXPR] [file ...]
|
|
188
230
|
|
|
189
231
|
The BareScript command-line interface
|
|
190
232
|
|
|
@@ -195,5 +237,6 @@ options:
|
|
|
195
237
|
-h, --help show this help message and exit
|
|
196
238
|
-c, --code CODE execute the BareScript code
|
|
197
239
|
-d, --debug enable debug mode
|
|
240
|
+
-m, --markdown-up run with MarkdownUp stubs
|
|
198
241
|
-s, --static perform static analysis
|
|
199
242
|
-v, --var VAR EXPR set a global variable to an expression value`;
|
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/markdown-up/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Include sentinel
|
|
6
|
+
if systemGlobalGet('argsSentinel'):
|
|
7
|
+
return
|
|
8
|
+
endif
|
|
9
|
+
argsSentinel = true
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# The URL arguments model
|
|
13
|
+
argsTypes = schemaParse( \
|
|
14
|
+
'group "Args"', \
|
|
15
|
+
'', \
|
|
16
|
+
'', \
|
|
17
|
+
'# An argument model list', \
|
|
18
|
+
'typedef ArgsArgument[len > 0] ArgsArguments', \
|
|
19
|
+
'', \
|
|
20
|
+
'', \
|
|
21
|
+
'# An argument model', \
|
|
22
|
+
'struct ArgsArgument', \
|
|
23
|
+
'', \
|
|
24
|
+
' # The argument name', \
|
|
25
|
+
' string(len > 0) name', \
|
|
26
|
+
'', \
|
|
27
|
+
' # The argument type', \
|
|
28
|
+
' optional ArgsType type', \
|
|
29
|
+
'', \
|
|
30
|
+
" # The argument's global variable name", \
|
|
31
|
+
' optional string(len > 0) global', \
|
|
32
|
+
'', \
|
|
33
|
+
' # If true, the argument is explicit.', \
|
|
34
|
+
' # An explicit argument is only included in the URL if it is in the arguments object.', \
|
|
35
|
+
' optional bool explicit', \
|
|
36
|
+
'', \
|
|
37
|
+
' # The default argument value', \
|
|
38
|
+
' optional object default', \
|
|
39
|
+
'', \
|
|
40
|
+
' # The argument description', \
|
|
41
|
+
' optional string(len > 0) description', \
|
|
42
|
+
'', \
|
|
43
|
+
'', \
|
|
44
|
+
'# An argument value type', \
|
|
45
|
+
'enum ArgsType', \
|
|
46
|
+
' bool', \
|
|
47
|
+
' date', \
|
|
48
|
+
' datetime', \
|
|
49
|
+
' float', \
|
|
50
|
+
' int', \
|
|
51
|
+
' string' \
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
# $function: argsValidate
|
|
56
|
+
# $group: args.mds
|
|
57
|
+
# $doc: Validate an arguments model
|
|
58
|
+
# $arg arguments: The [arguments model](includeModel.html#var.vName='ArgsArguments')
|
|
59
|
+
# $return: The validated [arguments model](includeModel.html#var.vName='ArgsArguments') or null if validation fails
|
|
60
|
+
function argsValidate(arguments):
|
|
61
|
+
validatedArguments = schemaValidate(argsTypes, 'ArgsArguments', arguments)
|
|
62
|
+
|
|
63
|
+
# Check for duplicate arguments
|
|
64
|
+
if validatedArguments != null:
|
|
65
|
+
argNames = objectNew()
|
|
66
|
+
for argument in arguments:
|
|
67
|
+
name = objectGet(argument, 'name')
|
|
68
|
+
if objectHas(argNames, name):
|
|
69
|
+
validatedArguments = null
|
|
70
|
+
systemLogDebug('MarkdownUp - args.mds: Duplicate argument "' + name + '"')
|
|
71
|
+
else:
|
|
72
|
+
objectSet(argNames, name, true)
|
|
73
|
+
endif
|
|
74
|
+
endfor
|
|
75
|
+
endif
|
|
76
|
+
|
|
77
|
+
return validatedArguments
|
|
78
|
+
endfunction
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
# $function: argsParse
|
|
82
|
+
# $group: args.mds
|
|
83
|
+
# $doc: Parse an [arguments model](includeModel.html#var.vName='ArgsArguments').
|
|
84
|
+
# $doc: Argument globals are validated and added to the arguments object using the argument name.
|
|
85
|
+
# $arg arguments: The [arguments model](includeModel.html#var.vName='ArgsArguments')
|
|
86
|
+
# $return: The arguments object
|
|
87
|
+
function argsParse(arguments):
|
|
88
|
+
# Create the arguments object
|
|
89
|
+
args = objectNew()
|
|
90
|
+
for argument in arguments:
|
|
91
|
+
# Get the argument value
|
|
92
|
+
global = argsGlobalName(argument)
|
|
93
|
+
value = argsValidateValue(systemGlobalGet(global), objectGet(argument, 'type'), global)
|
|
94
|
+
|
|
95
|
+
# Apply the default argument value, if any
|
|
96
|
+
if value == null:
|
|
97
|
+
value = objectGet(argument, 'default')
|
|
98
|
+
endif
|
|
99
|
+
|
|
100
|
+
# Set the argument value, if any
|
|
101
|
+
if value != null:
|
|
102
|
+
objectSet(args, objectGet(argument, 'name'), value)
|
|
103
|
+
endif
|
|
104
|
+
endfor
|
|
105
|
+
|
|
106
|
+
return args
|
|
107
|
+
endfunction
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
# $function: argsURL
|
|
111
|
+
# $group: args.mds
|
|
112
|
+
# $doc: Create a MarkdownUp application URL
|
|
113
|
+
# $arg arguments: The [arguments model](includeModel.html#var.vName='ArgsArguments')
|
|
114
|
+
# $arg args: Optional (default is null). The arguments object. Null argument values are excluded from the URL.
|
|
115
|
+
# $arg explicit: Optional (default is false). If true, arguments are only included in the URL if they are in the arguments object.
|
|
116
|
+
# $arg headerText: Optional (default is null). If non-null, the URL's header text.
|
|
117
|
+
# $arg headerText: The special "_top" header ID scrolls to the top of the page.
|
|
118
|
+
# $arg url: Optional (default is null). If non-null, the MarkdownUp URL hash parameter.
|
|
119
|
+
# $return: The MarkdownUp application URL
|
|
120
|
+
function argsURL(arguments, args, explicit, headerText, url):
|
|
121
|
+
# Get the URL variables
|
|
122
|
+
urlVars = arrayNew()
|
|
123
|
+
argNames = objectNew()
|
|
124
|
+
for argument in arguments:
|
|
125
|
+
name = objectGet(argument, 'name')
|
|
126
|
+
type = objectGet(argument, 'type')
|
|
127
|
+
global = argsGlobalName(argument)
|
|
128
|
+
default = objectGet(argument, 'default')
|
|
129
|
+
|
|
130
|
+
# Add the argument name (for unknown argument check below)
|
|
131
|
+
objectSet(argNames, name, null)
|
|
132
|
+
|
|
133
|
+
# Add the URL variable, if any
|
|
134
|
+
value = null
|
|
135
|
+
if args != null && objectHas(args, name):
|
|
136
|
+
value = argsValidateValue(objectGet(args, name), type, global)
|
|
137
|
+
elif !(explicit || objectGet(argument, 'explicit')):
|
|
138
|
+
value = argsValidateValue(systemGlobalGet(global), type, global, false)
|
|
139
|
+
endif
|
|
140
|
+
|
|
141
|
+
# Add the URL variable
|
|
142
|
+
if value != null && (default == null || !argsValuesEqual(value, default, type)):
|
|
143
|
+
arrayPush(urlVars, 'var.' + global + '=' + urlEncodeComponent(argsFormatValue(value, type)))
|
|
144
|
+
endif
|
|
145
|
+
endfor
|
|
146
|
+
|
|
147
|
+
# Sort the URL variables for general consistency
|
|
148
|
+
arraySort(urlVars)
|
|
149
|
+
|
|
150
|
+
# Check for unknown arguments
|
|
151
|
+
if args != null:
|
|
152
|
+
for name in objectKeys(args):
|
|
153
|
+
if !objectHas(argNames, name):
|
|
154
|
+
systemLogDebug('MarkdownUp - args.mds: Unknown argument "' + name + '"')
|
|
155
|
+
endif
|
|
156
|
+
endfor
|
|
157
|
+
endif
|
|
158
|
+
|
|
159
|
+
# Create the URL
|
|
160
|
+
return '#' + if(url != null, 'url=' + urlEncodeComponent(url) + '&', '') + \
|
|
161
|
+
if(arrayLength(urlVars), arrayJoin(urlVars, '&'), 'var=') + \
|
|
162
|
+
if(headerText != null, '&' + if(headerText == argsTopHeaderId, argsTopHeaderId, markdownHeaderId(headerText)), '')
|
|
163
|
+
endfunction
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
# The special "top" header ID
|
|
167
|
+
argsTopHeaderId = '_top'
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
# $function: argsLink
|
|
171
|
+
# $group: args.mds
|
|
172
|
+
# $doc: Create a Markdown link text to a MarkdownUp application URL
|
|
173
|
+
# $arg arguments: The [arguments model](includeModel.html#var.vName='ArgsArguments')
|
|
174
|
+
# $arg text: The link text
|
|
175
|
+
# $arg args: Optional (default is null). The arguments object.
|
|
176
|
+
# $arg explicit: Optional (default is false). If true, arguments are only included in the URL if they are in the arguments object.
|
|
177
|
+
# $arg headerText: Optional (default is null). If non-null, the URL's header text.
|
|
178
|
+
# $arg headerText: The special "_top" header ID scrolls to the top of the page.
|
|
179
|
+
# $arg url: Optional (default is null). If non-null, the MarkdownUp URL hash parameter.
|
|
180
|
+
# $return: The Markdown link text
|
|
181
|
+
function argsLink(arguments, text, args, explicit, headerText, url):
|
|
182
|
+
return '[' + markdownEscape(text) + '](' + argsURL(arguments, args, explicit, headerText, url) + ')'
|
|
183
|
+
endfunction
|
|
184
|
+
|
|
185
|
+
|
|
186
|
+
# $function: argsHelp
|
|
187
|
+
# $group: args.mds
|
|
188
|
+
# $doc: Output the [arguments model's](includeModel.html#var.vName='ArgsArguments') help
|
|
189
|
+
# $arg arguments: The [arguments model](includeModel.html#var.vName='ArgsArguments')
|
|
190
|
+
function argsHelp(arguments):
|
|
191
|
+
# Create the help data
|
|
192
|
+
helpData = arrayNew()
|
|
193
|
+
anyDefault = false
|
|
194
|
+
anyExplicit = false
|
|
195
|
+
anyDescription = false
|
|
196
|
+
for argument in arguments:
|
|
197
|
+
type = objectGet(argument, 'type', 'string')
|
|
198
|
+
default = objectGet(argument, 'default')
|
|
199
|
+
explicit = objectGet(argument, 'explicit')
|
|
200
|
+
description = objectGet(argument, 'description')
|
|
201
|
+
|
|
202
|
+
# Add the help data row
|
|
203
|
+
arrayPush(helpData, objectNew( \
|
|
204
|
+
'Variable', argsGlobalName(argument), \
|
|
205
|
+
'Type', type, \
|
|
206
|
+
'Default', argsFormatValue(default, type), \
|
|
207
|
+
'Explicit', if(explicit, 'Yes', ''), \
|
|
208
|
+
'Description', if(description != null, description, '') \
|
|
209
|
+
))
|
|
210
|
+
|
|
211
|
+
# Update the "any" field bools
|
|
212
|
+
anyDefault = anyDefault || (default != null)
|
|
213
|
+
anyExplicit = anyExplicit || explicit
|
|
214
|
+
anyDescription = anyDescription || (description != null)
|
|
215
|
+
endfor
|
|
216
|
+
|
|
217
|
+
# Render the help table
|
|
218
|
+
helpFields = arrayNew('Variable', 'Type')
|
|
219
|
+
if anyDefault:
|
|
220
|
+
arrayPush(helpFields, 'Default')
|
|
221
|
+
endif
|
|
222
|
+
if anyExplicit:
|
|
223
|
+
arrayPush(helpFields, 'Explicit')
|
|
224
|
+
endif
|
|
225
|
+
if anyDescription:
|
|
226
|
+
arrayPush(helpFields, 'Description')
|
|
227
|
+
endif
|
|
228
|
+
dataTable(helpData, objectNew('fields', helpFields))
|
|
229
|
+
endfunction
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
# Helper function to compute an argument's global name
|
|
233
|
+
function argsGlobalName(argument):
|
|
234
|
+
global = objectGet(argument, 'global')
|
|
235
|
+
if global == null:
|
|
236
|
+
name = objectGet(argument, 'name')
|
|
237
|
+
global = 'v' + stringUpper(stringSlice(name, 0, 1)) + stringSlice(name, 1)
|
|
238
|
+
endif
|
|
239
|
+
return global
|
|
240
|
+
endfunction
|
|
241
|
+
|
|
242
|
+
|
|
243
|
+
# Helper function to format an argument value
|
|
244
|
+
function argsFormatValue(value, type):
|
|
245
|
+
# No value?
|
|
246
|
+
if value == null:
|
|
247
|
+
return ''
|
|
248
|
+
endif
|
|
249
|
+
|
|
250
|
+
# Return the formatted value
|
|
251
|
+
if type == 'bool':
|
|
252
|
+
return if(value, 'true', 'false')
|
|
253
|
+
elif type == 'date':
|
|
254
|
+
return "'" + datetimeISOFormat(value, true) + "'"
|
|
255
|
+
elif type == 'datetime':
|
|
256
|
+
return "'" + datetimeISOFormat(value) + "'"
|
|
257
|
+
elif type == 'float':
|
|
258
|
+
return stringNew(value)
|
|
259
|
+
elif type == 'int':
|
|
260
|
+
return stringNew(value)
|
|
261
|
+
endif
|
|
262
|
+
|
|
263
|
+
# type == 'string'
|
|
264
|
+
return "'" + value + "'"
|
|
265
|
+
endfunction
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
# Helper function to validate an argument value's type
|
|
269
|
+
function argsValidateValue(value, type, global, warn):
|
|
270
|
+
# No value?
|
|
271
|
+
if value == null:
|
|
272
|
+
return null
|
|
273
|
+
endif
|
|
274
|
+
|
|
275
|
+
# Validate the value's type
|
|
276
|
+
valueType = systemType(value)
|
|
277
|
+
if type == 'bool':
|
|
278
|
+
if valueType == 'number' && (value == 0 || value == 1):
|
|
279
|
+
value = !!value
|
|
280
|
+
elif valueType != 'boolean':
|
|
281
|
+
if warn != false:
|
|
282
|
+
systemLogDebug('MarkdownUp - args.mds: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
283
|
+
endif
|
|
284
|
+
value = null
|
|
285
|
+
endif
|
|
286
|
+
elif type == 'date':
|
|
287
|
+
valueOrig = value
|
|
288
|
+
if valueType == 'string':
|
|
289
|
+
value = datetimeISOParse(value)
|
|
290
|
+
valueType = systemType(value)
|
|
291
|
+
endif
|
|
292
|
+
if valueType != 'datetime' || datetimeHour(value) != 0 || datetimeMinute(value) != 0 || datetimeSecond(value) != 0:
|
|
293
|
+
if warn != false:
|
|
294
|
+
systemLogDebug('MarkdownUp - args.mds: Invalid value ' + jsonStringify(valueOrig) + ' for URL argument "' + global + '"')
|
|
295
|
+
endif
|
|
296
|
+
value = null
|
|
297
|
+
endif
|
|
298
|
+
elif type == 'datetime':
|
|
299
|
+
valueOrig = value
|
|
300
|
+
if valueType == 'string':
|
|
301
|
+
value = datetimeISOParse(value)
|
|
302
|
+
valueType = systemType(value)
|
|
303
|
+
endif
|
|
304
|
+
if valueType != 'datetime':
|
|
305
|
+
if warn != false:
|
|
306
|
+
systemLogDebug('MarkdownUp - args.mds: Invalid value ' + jsonStringify(valueOrig) + ' for URL argument "' + global + '"')
|
|
307
|
+
endif
|
|
308
|
+
value = null
|
|
309
|
+
endif
|
|
310
|
+
elif type == 'float':
|
|
311
|
+
if valueType != 'number':
|
|
312
|
+
if warn != false:
|
|
313
|
+
systemLogDebug('MarkdownUp - args.mds: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
314
|
+
endif
|
|
315
|
+
value = null
|
|
316
|
+
endif
|
|
317
|
+
elif type == 'int':
|
|
318
|
+
if valueType != 'number' || value != mathFloor(value):
|
|
319
|
+
if warn != false:
|
|
320
|
+
systemLogDebug('MarkdownUp - args.mds: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
321
|
+
endif
|
|
322
|
+
value = null
|
|
323
|
+
endif
|
|
324
|
+
else:
|
|
325
|
+
# type == 'string'
|
|
326
|
+
if valueType != 'string':
|
|
327
|
+
if warn != false:
|
|
328
|
+
systemLogDebug('MarkdownUp - args.mds: Invalid value ' + jsonStringify(value) + ' for URL argument "' + global + '"')
|
|
329
|
+
endif
|
|
330
|
+
value = null
|
|
331
|
+
endif
|
|
332
|
+
endif
|
|
333
|
+
|
|
334
|
+
return value
|
|
335
|
+
endfunction
|
|
336
|
+
|
|
337
|
+
|
|
338
|
+
# Helper function to determine if two values are equal
|
|
339
|
+
function argsValuesEqual(value, valueOther, type):
|
|
340
|
+
if type == 'date' || type == 'datetime':
|
|
341
|
+
return (value - valueOther) == 0
|
|
342
|
+
endif
|
|
343
|
+
return value == valueOther
|
|
344
|
+
endfunction
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# Licensed under the MIT License
|
|
2
|
+
# https://github.com/craigahobbs/markdown-up/blob/main/LICENSE
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
# Include sentinel
|
|
6
|
+
if systemGlobalGet('formsSentinel'):
|
|
7
|
+
return
|
|
8
|
+
endif
|
|
9
|
+
formsSentinel = true
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
# $function: formsTextElements
|
|
13
|
+
# $group: forms.mds
|
|
14
|
+
# $doc: Create a text input [element model](https://github.com/craigahobbs/element-model#readme)
|
|
15
|
+
# $arg id: The text input element ID
|
|
16
|
+
# $arg text: The initial text of the text input element
|
|
17
|
+
# $arg size: Optional (default is null). The size, in characters, of the text input element
|
|
18
|
+
# $arg onEnter: Optional (default is null). The text input element on-enter event handler
|
|
19
|
+
# $return: The text input [element model](https://github.com/craigahobbs/element-model#readme)
|
|
20
|
+
function formsTextElements(id, text, size, onEnter):
|
|
21
|
+
return objectNew( \
|
|
22
|
+
'html', 'input', \
|
|
23
|
+
'attr', objectNew( \
|
|
24
|
+
'autocomplete', 'off', \
|
|
25
|
+
'id', id, \
|
|
26
|
+
'style', 'font-size: inherit; border: thin solid black; padding: 0.4em;', \
|
|
27
|
+
'type', 'text', \
|
|
28
|
+
'value', text, \
|
|
29
|
+
'size', size \
|
|
30
|
+
), \
|
|
31
|
+
'callback', if(onEnter != null, objectNew('keyup', systemPartial(formsTextOnKeyup, onEnter))) \
|
|
32
|
+
)
|
|
33
|
+
endfunction
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
async function formsTextOnKeyup(onEnter, keyCode):
|
|
37
|
+
if keyCode == 13:
|
|
38
|
+
onEnter()
|
|
39
|
+
endif
|
|
40
|
+
endfunction
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
# $function: formsLinkButtonElements
|
|
44
|
+
# $group: forms.mds
|
|
45
|
+
# $doc: Create a link button [element model](https://github.com/craigahobbs/element-model#readme)
|
|
46
|
+
# $arg text: The link button's text
|
|
47
|
+
# $arg onClick: The link button's click event handler
|
|
48
|
+
# $return: The link button [element model](https://github.com/craigahobbs/element-model#readme)
|
|
49
|
+
function formsLinkButtonElements(text, onClick):
|
|
50
|
+
return objectNew( \
|
|
51
|
+
'html', 'a', \
|
|
52
|
+
'attr', objectNew('style', 'cursor: pointer; user-select: none;'), \
|
|
53
|
+
'elem', objectNew('text', text), \
|
|
54
|
+
'callback', objectNew('click', onClick) \
|
|
55
|
+
)
|
|
56
|
+
endfunction
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# $function: formsLinkElements
|
|
60
|
+
# $group: forms.mds
|
|
61
|
+
# $doc: Create a link [element model](https://github.com/craigahobbs/element-model#readme)
|
|
62
|
+
# $arg text: The link's text
|
|
63
|
+
# $arg url: The link's URL. If null, the link is rendered as text.
|
|
64
|
+
# $return: The link [element model](https://github.com/craigahobbs/element-model#readme)
|
|
65
|
+
function formsLinkElements(text, url):
|
|
66
|
+
if url == null:
|
|
67
|
+
return objectNew( \
|
|
68
|
+
'html', 'span', \
|
|
69
|
+
'attr', objectNew('style', 'user-select: none;'), \
|
|
70
|
+
'elem', objectNew('text', text) \
|
|
71
|
+
)
|
|
72
|
+
endif
|
|
73
|
+
|
|
74
|
+
return objectNew( \
|
|
75
|
+
'html', 'a', \
|
|
76
|
+
'attr', objectNew('href', documentURL(url)), \
|
|
77
|
+
'elem', objectNew('text', text) \
|
|
78
|
+
)
|
|
79
|
+
endfunction
|