@nebularstreams/libmui 3.1.0 → 4.0.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/dist/libmui.esm.js +3 -0
- package/package.json +6 -2
- package/readme.md +48 -0
- package/dist/libui.esm.js +0 -3
- package/rollup.config.js +0 -20
- package/src/app/MainState.js +0 -22
- package/src/app/app.js +0 -9
- package/src/css/a-measures.css +0 -6
- package/src/css/b-colors.css +0 -12
- package/src/css/b-root-bootstrap-ext.css +0 -81
- package/src/css/b-root-bootstrap.css +0 -178
- package/src/css/b-root-semantic-flex.css +0 -87
- package/src/css/b-root-semantic-size-new.css +0 -37
- package/src/css/b-root-semantic-size.css +0 -75
- package/src/css/b-root-semantic-skin.css +0 -48
- package/src/css/b-root-semantic.css +0 -111
- package/src/css/b-root.css +0 -3
- package/src/css/cardie.css +0 -6
- package/src/css/flex.css +0 -46
- package/src/css/fontawesome/brands.min.css +0 -16
- package/src/css/fontawesome/fontawesome-ext.css +0 -7
- package/src/css/fontawesome/fontawesome-solid.css +0 -17
- package/src/css/fontawesome/fontawesome.css +0 -4359
- package/src/css/ui.notifications.css +0 -23
- package/src/css/ui.popup.css +0 -127
- package/src/css/ui.witharia.css +0 -25
- package/src/index.js +0 -112
- package/src/meta/InputTemplates.js +0 -3
- package/src/style.js +0 -37
- package/src/util/colorjoe.js +0 -1370
- package/src/util/filepath.js +0 -10
- package/src/util/fuckingconfirm.js +0 -28
- package/src/util/mithril-range.js +0 -445
- package/src/util/tainter.js +0 -39
- package/src/util/util.clone.js +0 -8
- package/src/util/util.tokenizer.js +0 -266
- package/src/util/widgets.core.js +0 -314
- package/src/util/widgets.js +0 -79
- package/src/util/widgets.utils.js +0 -10
- package/src/widgets/Basic.js +0 -352
- package/src/widgets/ButtonChoiceWidget.js +0 -72
- package/src/widgets/CardieWidget.js +0 -168
- package/src/widgets/ColorJoePack.js +0 -108
- package/src/widgets/ColorJoeWidget.js +0 -140
- package/src/widgets/ComboPrompt.js +0 -112
- package/src/widgets/ComboWidget.js +0 -156
- package/src/widgets/CoolContentTicker.js +0 -244
- package/src/widgets/CoolerEmpty.js +0 -37
- package/src/widgets/EmptyButton.js +0 -36
- package/src/widgets/FontSelectorButton.js +0 -37
- package/src/widgets/InputWidget.js +0 -254
- package/src/widgets/NoticeWidget.js +0 -31
- package/src/widgets/OverflowUtils.js +0 -449
- package/src/widgets/PlusMinusWidget.js +0 -55
- package/src/widgets/RangeWidget.js +0 -200
- package/src/widgets/SelectFileMiniButton.js +0 -170
- package/src/widgets/Separator.js +0 -21
- package/src/widgets/SmileysButton.js +0 -19
- package/src/widgets/SwitchWidget.js +0 -42
- package/src/widgets/TemplatedInputWidget.js +0 -1395
- package/src/widgets/TitleBarWidget.js +0 -71
- package/src/widgets/css/buttonchoice.css +0 -62
- package/src/widgets/css/buttonchoice.toggle.css +0 -37
- package/src/widgets/css/choicer.css +0 -24
- package/src/widgets/css/colorjoe.css +0 -230
- package/src/widgets/css/colorjoewidget.css +0 -105
- package/src/widgets/css/combo-ellipsis.css +0 -29
- package/src/widgets/css/fileminibutton.css +0 -12
- package/src/widgets/css/input.css +0 -35
- package/src/widgets/css/mithril-range.css +0 -69
- package/src/widgets/css/progressstrip.css +0 -31
- package/src/widgets/css/range-anims.css +0 -23
- package/src/widgets/css/separator.css +0 -21
- package/src/widgets/css/smileys.css +0 -85
- package/src/widgets/css/templatedinput.css +0 -67
- package/src/widgets/css/ui.titlebar.css +0 -44
- package/src/widgets/css/uploadfile.css +0 -5
- /package/dist/{libui.css → libmui.css} +0 -0
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
/* eslint-disable */
|
|
2
|
-
/**
|
|
3
|
-
*
|
|
4
|
-
* String Tokenizer functions
|
|
5
|
-
*
|
|
6
|
-
* Substitutes parameters inside strings
|
|
7
|
-
* Parameters are separated by $ at the beggining and end: $PARAM$, $PARAM1$
|
|
8
|
-
* Parameters can navigate source object like $object/very/deep$
|
|
9
|
-
* Parameters can include VERY SIMPLE default values like $object/very/deep=myvalue$
|
|
10
|
-
*
|
|
11
|
-
* Note that default values cannot contain conflicting regexp symbols. This is a side functionality
|
|
12
|
-
* and never meant to support any default value use case, but alpha chars and numbers
|
|
13
|
-
*
|
|
14
|
-
* (c) Rodolfo LP 2001 - Public Domain
|
|
15
|
-
*
|
|
16
|
-
* @typedef {{ id:string,url:string}} UrlDefinition
|
|
17
|
-
* @typedef {{ message:string, getTitle:boolean=false, defaultTitle:string="url" }} ResolveUrlOptions
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
/* eslint-disable no-use-before-define,no-unused-vars,prefer-destructuring,no-param-reassign,no-prototype-builtins */
|
|
21
|
-
|
|
22
|
-
// eslint-disable-next-line no-useless-escape
|
|
23
|
-
// noinspection RegExpRedundantEscape
|
|
24
|
-
const
|
|
25
|
-
TAG = "[TOKENIZER]",
|
|
26
|
-
TOK_EXPR = /\$([A-Za-z0-9_\/\:\=]+)\$/g,
|
|
27
|
-
|
|
28
|
-
tokenize = (str, obj, isEncode) => tokenizeCore(str, obj, {
|
|
29
|
-
encode: isEncode,
|
|
30
|
-
defvalue: ""
|
|
31
|
-
}),
|
|
32
|
-
tokenizeKeep = (str, obj, isEncode) => tokenizeCore(str, obj, {encode: isEncode}),
|
|
33
|
-
tokenizeWithDefault = (str, obj, defaultValue) => tokenizeCore(str, obj, defaultValue == null ? null : {defvalue: defaultValue}),
|
|
34
|
-
tokenizeStrict = (str, obj, isEncode, isUnescape) => tokenizeCore(str, obj, {
|
|
35
|
-
encode: isEncode,
|
|
36
|
-
unescape: isUnescape,
|
|
37
|
-
dothrow: true
|
|
38
|
-
}),
|
|
39
|
-
|
|
40
|
-
Parsers = {
|
|
41
|
-
daterel: epoch => new Date(epoch).toISOString()
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
function tokenizeCore(str, obj, options) {
|
|
45
|
-
|
|
46
|
-
if (!str) return "";
|
|
47
|
-
if (typeof (str) !== "string") return str;
|
|
48
|
-
|
|
49
|
-
// eslint-disable-next-line no-param-reassign
|
|
50
|
-
options = options || {};
|
|
51
|
-
obj = obj || {};
|
|
52
|
-
|
|
53
|
-
let ckey;
|
|
54
|
-
|
|
55
|
-
return str.replace(TOK_EXPR, (match, complexkey) => {
|
|
56
|
-
|
|
57
|
-
let defval = null,
|
|
58
|
-
isFreak = false;
|
|
59
|
-
|
|
60
|
-
if (complexkey.indexOf("=") > 0) {
|
|
61
|
-
ckey = complexkey.split("=");
|
|
62
|
-
complexkey = ckey[0];
|
|
63
|
-
isFreak = (ckey.length === 3);
|
|
64
|
-
// eslint-disable-next-line no-nested-ternary
|
|
65
|
-
defval = isFreak
|
|
66
|
-
? options.dothrow ? ckey[2] : null
|
|
67
|
-
: ckey[1];
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const typed = complexkey.split(":"),
|
|
71
|
-
key = typed[0],
|
|
72
|
-
keytype = typed[1] || null,
|
|
73
|
-
|
|
74
|
-
keys = key.split("/"),
|
|
75
|
-
root = keys.shift();
|
|
76
|
-
|
|
77
|
-
let
|
|
78
|
-
data = obj[root];
|
|
79
|
-
|
|
80
|
-
if (typeof (data) === "number") data = "" + data;
|
|
81
|
-
|
|
82
|
-
let fdata = (keys.length ? getPointedData(data, keys.join("/")) : data) || defval;
|
|
83
|
-
|
|
84
|
-
if (fdata == null && options.dothrow) {
|
|
85
|
-
throw new Error("Parameter " + root + (keys.length ? "/" + keys.join("/") : "") + " is required");
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
if (fdata == null) {
|
|
89
|
-
fdata = options.hasOwnProperty("defvalue")
|
|
90
|
-
? options.defvalue
|
|
91
|
-
: "$" + key + (isFreak ? "==" + ckey[2] : "") + "$";
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
if (keytype && Parsers[keytype]) {
|
|
95
|
-
fdata = Parsers[keytype](fdata);
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (options.unescape) {
|
|
99
|
-
fdata = unescape(fdata);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
return (options.encode ? escape(fdata) : fdata);
|
|
103
|
-
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Resolves a pointer into a JSON data structure
|
|
109
|
-
* @param {Object} data JSON Data
|
|
110
|
-
* @param {String} pointer Pointer expression
|
|
111
|
-
* @return {Object | null} resolved data
|
|
112
|
-
*/
|
|
113
|
-
|
|
114
|
-
const getPointedData = function (data, pointer) {
|
|
115
|
-
if (!pointer) return data;
|
|
116
|
-
try {
|
|
117
|
-
const ps = pointer.split("/");
|
|
118
|
-
let d = data;
|
|
119
|
-
// eslint-disable-next-line guard-for-in
|
|
120
|
-
for (const l in ps) {
|
|
121
|
-
d = d[ps[l]];
|
|
122
|
-
if (!d) {
|
|
123
|
-
d = null;
|
|
124
|
-
break;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
return d;
|
|
128
|
-
} catch (e) {
|
|
129
|
-
return null;
|
|
130
|
-
}
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Tokenizes one object with another
|
|
135
|
-
* @param {object} source
|
|
136
|
-
* @param {object} tokenizeValues
|
|
137
|
-
* @param strict Whether to require all templates to be resolved
|
|
138
|
-
* @retuen {object} source
|
|
139
|
-
*/
|
|
140
|
-
|
|
141
|
-
function tokenizeObject(source, tokenizeValues, strict, asNewObject) {
|
|
142
|
-
|
|
143
|
-
const tokenizer = strict ? tokenizeStrict : tokenizeKeep;
|
|
144
|
-
const retObject = asNewObject ? {} : source;
|
|
145
|
-
|
|
146
|
-
if (typeof source === "string") {
|
|
147
|
-
return tokenizer(source, tokenizeValues);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (typeof source === "object") {
|
|
151
|
-
|
|
152
|
-
if (source.length) {
|
|
153
|
-
// root is an array
|
|
154
|
-
// an array
|
|
155
|
-
const arr = [];
|
|
156
|
-
for (const item of source) {
|
|
157
|
-
arr.push(tokenizeObject(item, tokenizeValues, strict, true));
|
|
158
|
-
}
|
|
159
|
-
return arr;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
for (const prop of Object.keys(source)) {
|
|
163
|
-
const value = source[prop];
|
|
164
|
-
if (typeof value === "object") {
|
|
165
|
-
retObject[prop] = tokenizeObject(value, tokenizeValues, strict, true);
|
|
166
|
-
} else if (typeof value === "string") {
|
|
167
|
-
retObject[prop] = tokenizer(source[prop], tokenizeValues);
|
|
168
|
-
} else {
|
|
169
|
-
retObject[prop] = value;
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
return retObject;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* Resolves a playout URL
|
|
178
|
-
* @param {string|UrlDefinition} tokenizedUrl The URL to parse
|
|
179
|
-
* @param {Object=} parameters Parameters to tokenize the URL with
|
|
180
|
-
* @param {ResolveUrlOptions=} options Miscellaneous options for this call
|
|
181
|
-
* @return string
|
|
182
|
-
*/
|
|
183
|
-
|
|
184
|
-
function tokenizeUrl(tokenizedUrl, parameters, options) {
|
|
185
|
-
|
|
186
|
-
options = options || {};
|
|
187
|
-
|
|
188
|
-
const
|
|
189
|
-
{message, getTitle, defaultTitle} = options,
|
|
190
|
-
finalDefaultTitle = defaultTitle || "Url",
|
|
191
|
-
title = typeof tokenizedUrl === "string"
|
|
192
|
-
? defaultTitle
|
|
193
|
-
: (typeof tokenizedUrl === "object" && tokenizedUrl.id ? tokenizedUrl.id || finalDefaultTitle : finalDefaultTitle);
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
// just return the title of an URL
|
|
197
|
-
if (getTitle) {
|
|
198
|
-
return title;
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// return the url itself
|
|
202
|
-
const
|
|
203
|
-
url = typeof tokenizedUrl === "string"
|
|
204
|
-
? tokenizedUrl
|
|
205
|
-
: (typeof tokenizedUrl === "object" && tokenizedUrl.url ? tokenizedUrl.url : null);
|
|
206
|
-
|
|
207
|
-
try {
|
|
208
|
-
return tokenizeStrict(
|
|
209
|
-
url,
|
|
210
|
-
parameters || {},
|
|
211
|
-
"..."
|
|
212
|
-
);
|
|
213
|
-
} catch (e) {
|
|
214
|
-
console.log(TAG, e.message);
|
|
215
|
-
return message || "(not enough parameters)";
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
const
|
|
220
|
-
REGEX_DOTS = /[^0-9A-Z._\-]+/gi,
|
|
221
|
-
REGEX_NODOTS = /[^0-9A-Z_\-]+/gi;
|
|
222
|
-
|
|
223
|
-
function sanitizeFilename(filename, withDots = true) {
|
|
224
|
-
// EDGE CASE -> NO DOT AT THE END
|
|
225
|
-
withDots = withDots && !filename?.endsWith(".");
|
|
226
|
-
return filename ? filename.trim()
|
|
227
|
-
.toLowerCase()
|
|
228
|
-
.replace(withDots ? REGEX_DOTS : REGEX_NODOTS, "") : null;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
const generateFilename = (url, prefix = undefined) => {
|
|
233
|
-
|
|
234
|
-
const
|
|
235
|
-
dateCode = parseInt(md5(url)
|
|
236
|
-
.substring(24), 16)
|
|
237
|
-
.toString(32);
|
|
238
|
-
|
|
239
|
-
return (prefix ? sanitizeFilename(prefix) + "-" : "") + dateCode;
|
|
240
|
-
|
|
241
|
-
}; // 2025 --- 24 years layer i'm 50 ! I wonder about my past self ...
|
|
242
|
-
|
|
243
|
-
const Tokenizer = {
|
|
244
|
-
tokenize,
|
|
245
|
-
tokenizeStrict,
|
|
246
|
-
tokenizeObject,
|
|
247
|
-
tokenizeKeep,
|
|
248
|
-
tokenizeWithDefault,
|
|
249
|
-
tokenizeUrl,
|
|
250
|
-
getPointedData,
|
|
251
|
-
sanitizeFilename,
|
|
252
|
-
generateFilename
|
|
253
|
-
};
|
|
254
|
-
|
|
255
|
-
export default Tokenizer;
|
|
256
|
-
export {
|
|
257
|
-
tokenize,
|
|
258
|
-
tokenizeStrict,
|
|
259
|
-
tokenizeObject,
|
|
260
|
-
tokenizeKeep,
|
|
261
|
-
tokenizeWithDefault,
|
|
262
|
-
tokenizeUrl,
|
|
263
|
-
getPointedData,
|
|
264
|
-
sanitizeFilename,
|
|
265
|
-
generateFilename
|
|
266
|
-
};
|
package/src/util/widgets.core.js
DELETED
|
@@ -1,314 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-nested-ternary */
|
|
2
|
-
/**
|
|
3
|
-
* Basic Mithril Widget functions
|
|
4
|
-
* Provides some utilities and basic UI functions like an Alert or a Confirmation dialog
|
|
5
|
-
*
|
|
6
|
-
* @author Rodolfo Lopez Pintor, 2020 <rlp@nebular.tv>
|
|
7
|
-
* @module apps.widgets.basic
|
|
8
|
-
*
|
|
9
|
-
*/
|
|
10
|
-
import m from "mithril";
|
|
11
|
-
import * as widget from "./widgets";
|
|
12
|
-
import * as Tokenizer from "./util.tokenizer";
|
|
13
|
-
import {Button, Empty} from "../widgets/Basic";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* Computes a Class String
|
|
18
|
-
*
|
|
19
|
-
* @param {string} initials INitial CSS Classes
|
|
20
|
-
* @param {Object<string, boolean>} clases New classes dictionary
|
|
21
|
-
* @return {string} The CSS Class expression like .class1.class2.class3
|
|
22
|
-
* @public
|
|
23
|
-
* @static
|
|
24
|
-
*/
|
|
25
|
-
|
|
26
|
-
const packClassString = (initials, clases) => {
|
|
27
|
-
const finals = [];
|
|
28
|
-
if (clases) for (const cla of Object.keys(clases)) if (clases[cla]) finals.push("." + cla);
|
|
29
|
-
return (initials || "") + finals.join("");
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const packClass = (initials, clases) => {
|
|
34
|
-
const finals = initials ? [initials] : [];
|
|
35
|
-
if (clases) for (const cla of Object.keys(clases)) if (clases[cla]) finals.push(cla);
|
|
36
|
-
return finals.join(" ");
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Shows a modal confirm dialog
|
|
41
|
-
* @param {string} title The dialog title
|
|
42
|
-
* @param {string} message The dialog message
|
|
43
|
-
* @param {Array} buttons Buttons to display
|
|
44
|
-
* @param {Object=} options noCancel: dialog is uncanellable
|
|
45
|
-
* @public
|
|
46
|
-
* @static
|
|
47
|
-
*/
|
|
48
|
-
|
|
49
|
-
function Confirm(title, message,
|
|
50
|
-
buttons = ["CANCEL", "OK"], options = {}
|
|
51
|
-
) {
|
|
52
|
-
widget.popupMessage(
|
|
53
|
-
m(
|
|
54
|
-
{
|
|
55
|
-
view: () => [
|
|
56
|
-
...title ? [m("h3", title)] : [],
|
|
57
|
-
...message ? [m("h4", message)] : [],
|
|
58
|
-
m(".container",
|
|
59
|
-
buttons.map(
|
|
60
|
-
option => m(
|
|
61
|
-
"button",
|
|
62
|
-
{
|
|
63
|
-
onclick: () => {
|
|
64
|
-
document.getElementById("modal-container").style.display = "none";
|
|
65
|
-
if (option.onclick) option.onclick(option.caption);
|
|
66
|
-
}
|
|
67
|
-
},
|
|
68
|
-
option.caption || "OK"
|
|
69
|
-
)
|
|
70
|
-
))
|
|
71
|
-
]
|
|
72
|
-
},
|
|
73
|
-
{}
|
|
74
|
-
),
|
|
75
|
-
options.onCancel || !options.noCancel
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function ConfirmPromise(title, message, actions, isModal = false) {
|
|
80
|
-
|
|
81
|
-
let onCancel = undefined;
|
|
82
|
-
|
|
83
|
-
if (typeof isModal === "function") {
|
|
84
|
-
onCancel = isModal;
|
|
85
|
-
isModal = false;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return new Promise((resolve) => {
|
|
89
|
-
|
|
90
|
-
const opts = actions.map((name, idx) => ({
|
|
91
|
-
caption: name,
|
|
92
|
-
onclick: () => resolve({
|
|
93
|
-
idx,
|
|
94
|
-
name
|
|
95
|
-
})
|
|
96
|
-
}));
|
|
97
|
-
|
|
98
|
-
Confirm(title, message, opts, {
|
|
99
|
-
onCancel,
|
|
100
|
-
noCancel: isModal
|
|
101
|
-
});
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Shows An Alert Modal Dialog
|
|
107
|
-
* @param {string} title Dialog Title
|
|
108
|
-
* @param {string} message Dialog Message
|
|
109
|
-
* @param {string?} caption Button caption
|
|
110
|
-
* @param {function?} onclick On press handler
|
|
111
|
-
* @public
|
|
112
|
-
* @static
|
|
113
|
-
*/
|
|
114
|
-
|
|
115
|
-
function Alert(title, message, caption, onclick) {
|
|
116
|
-
return Confirm(title, message, [{caption, onclick}]);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
function OverflowMenu(domItem, item, actions, options) {
|
|
121
|
-
|
|
122
|
-
return new Promise((resolve) => {
|
|
123
|
-
|
|
124
|
-
options = options || {};
|
|
125
|
-
|
|
126
|
-
function closeResolve(value) {
|
|
127
|
-
widget.popupMessage(null);
|
|
128
|
-
try {
|
|
129
|
-
resolve(value);
|
|
130
|
-
} catch (e) {
|
|
131
|
-
//
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
classes = packClassString(".popup.flexcol", {
|
|
137
|
-
".favlist": options.favlist,
|
|
138
|
-
".isfav": domItem && domItem.classList.contains("isfav"),
|
|
139
|
-
".isplay": domItem && domItem.classList.contains("selected")
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
widget.popupMessage(
|
|
143
|
-
m({
|
|
144
|
-
view: () => m(
|
|
145
|
-
classes,
|
|
146
|
-
{
|
|
147
|
-
onclick: (event) => {
|
|
148
|
-
|
|
149
|
-
if (event.target.nodeName === "INPUT") {
|
|
150
|
-
return;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
const
|
|
154
|
-
action = event.target.getAttribute("data-action");
|
|
155
|
-
|
|
156
|
-
if (action) {
|
|
157
|
-
closeResolve({
|
|
158
|
-
domItem,
|
|
159
|
-
item,
|
|
160
|
-
action
|
|
161
|
-
});
|
|
162
|
-
} else {
|
|
163
|
-
widget.popupMessage(null);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
[
|
|
168
|
-
...item.title ? [m("h3", {id: "modaltitle"}, item.title)] : [],
|
|
169
|
-
...actions.map(action => (action.type === "text"
|
|
170
|
-
? m(
|
|
171
|
-
"input.action",
|
|
172
|
-
{
|
|
173
|
-
value: action.value || "",
|
|
174
|
-
type: "text",
|
|
175
|
-
placeholder: action.hint || "",
|
|
176
|
-
oncreate: ({dom}) => dom.focus(),
|
|
177
|
-
onkeyup: (ev) => {
|
|
178
|
-
if (ev.keyCode === 27) {
|
|
179
|
-
closeResolve({domItem, item, action});
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
onchange: (ev) => {
|
|
183
|
-
ev.target.blur();
|
|
184
|
-
closeResolve({
|
|
185
|
-
domItem,
|
|
186
|
-
item,
|
|
187
|
-
action,
|
|
188
|
-
value: ev.target.value
|
|
189
|
-
});
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
)
|
|
193
|
-
: m(
|
|
194
|
-
Button,
|
|
195
|
-
{
|
|
196
|
-
...action,
|
|
197
|
-
onclick: () => closeResolve({
|
|
198
|
-
domItem,
|
|
199
|
-
item,
|
|
200
|
-
action
|
|
201
|
-
})
|
|
202
|
-
},
|
|
203
|
-
action.caption
|
|
204
|
-
)))
|
|
205
|
-
]
|
|
206
|
-
)
|
|
207
|
-
}),
|
|
208
|
-
true
|
|
209
|
-
);
|
|
210
|
-
});
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
/**
|
|
214
|
-
* Creates an HTML UL/LI structure with the object properties
|
|
215
|
-
* @param {Object} object An object to render
|
|
216
|
-
* @param {RenderOptions?} options
|
|
217
|
-
* @param {Object[]} children additional vnodes
|
|
218
|
-
* @param {string} recurse parent key
|
|
219
|
-
* @param isArrayChild
|
|
220
|
-
* @return {m} The rendered view
|
|
221
|
-
* @public
|
|
222
|
-
* @static
|
|
223
|
-
*/
|
|
224
|
-
|
|
225
|
-
function RenderObject(object, options, children, recurse, isArrayChild = false) {
|
|
226
|
-
|
|
227
|
-
// noinspection JSValidateTypes
|
|
228
|
-
options = options || {};
|
|
229
|
-
const {arrayClass = "isarray", arrayChildClass = "ischildren", objectClass = "isobject"} = options;
|
|
230
|
-
|
|
231
|
-
return m(
|
|
232
|
-
"ul",
|
|
233
|
-
{
|
|
234
|
-
...(options.attrs || {}),
|
|
235
|
-
class: options.class
|
|
236
|
-
},
|
|
237
|
-
object
|
|
238
|
-
? [
|
|
239
|
-
...(options.keys || Object.keys(object))
|
|
240
|
-
.map((key) => {
|
|
241
|
-
|
|
242
|
-
const
|
|
243
|
-
value = object[key] || null,
|
|
244
|
-
isObject = value !== null && (typeof value === "object"),
|
|
245
|
-
isArray = isObject && value.length,
|
|
246
|
-
fullkey = (recurse ? recurse + "_" : "") + key;
|
|
247
|
-
|
|
248
|
-
return m(
|
|
249
|
-
"li.field_" + (options.start || "") + fullkey,
|
|
250
|
-
{
|
|
251
|
-
class: (isArray ? arrayClass : isObject ? (objectClass + " ") : "") + (isArrayChild ? arrayChildClass : ""),
|
|
252
|
-
"data-title": options.titles ? options.titles[key] || key : key,
|
|
253
|
-
...(options.itemAttrs || {})
|
|
254
|
-
},
|
|
255
|
-
// eslint-disable-next-line
|
|
256
|
-
isObject
|
|
257
|
-
? [
|
|
258
|
-
m(".subvalues",
|
|
259
|
-
RenderObject(
|
|
260
|
-
value,
|
|
261
|
-
{
|
|
262
|
-
...options,
|
|
263
|
-
keys: null
|
|
264
|
-
},
|
|
265
|
-
null,
|
|
266
|
-
(recurse ? recurse + "_" : "") + key,
|
|
267
|
-
isArray
|
|
268
|
-
))]
|
|
269
|
-
: (
|
|
270
|
-
(options.renderer && options.renderer[fullkey])
|
|
271
|
-
? options.renderer[fullkey](value)
|
|
272
|
-
: m("span.value", object[key])
|
|
273
|
-
)
|
|
274
|
-
);
|
|
275
|
-
}),
|
|
276
|
-
...children || []
|
|
277
|
-
]
|
|
278
|
-
: [
|
|
279
|
-
m(".empty", {})
|
|
280
|
-
]
|
|
281
|
-
);
|
|
282
|
-
|
|
283
|
-
}
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
const
|
|
287
|
-
JSONWidget = {
|
|
288
|
-
view:
|
|
289
|
-
({attrs, children}) => {
|
|
290
|
-
let object;
|
|
291
|
-
try {
|
|
292
|
-
object = attrs.pointer
|
|
293
|
-
? Tokenizer.getPointedData(attrs.object, attrs.pointer)
|
|
294
|
-
: attrs.object;
|
|
295
|
-
} catch (e) {
|
|
296
|
-
return m(Empty, {message: e.message, ...attrs});
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
return object
|
|
300
|
-
? RenderObject(object, attrs, children)
|
|
301
|
-
: m(Empty, attrs);
|
|
302
|
-
}
|
|
303
|
-
};
|
|
304
|
-
|
|
305
|
-
// noinspection JSUnusedGlobalSymbols
|
|
306
|
-
export {
|
|
307
|
-
Alert,
|
|
308
|
-
Confirm,
|
|
309
|
-
ConfirmPromise,
|
|
310
|
-
RenderObject,
|
|
311
|
-
OverflowMenu,
|
|
312
|
-
JSONWidget,
|
|
313
|
-
packClass
|
|
314
|
-
}
|
package/src/util/widgets.js
DELETED
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import m from "mithril";
|
|
2
|
-
|
|
3
|
-
let
|
|
4
|
-
mCurrentCancelable;
|
|
5
|
-
|
|
6
|
-
function runCancelable(container) {
|
|
7
|
-
if (typeof mCurrentCancelable === "function") {
|
|
8
|
-
mCurrentCancelable();
|
|
9
|
-
mCurrentCancelable = undefined;
|
|
10
|
-
}
|
|
11
|
-
if (popupMessage.redraw) {
|
|
12
|
-
popupMessage.redraw(true);
|
|
13
|
-
delete popupMessage.redraw;
|
|
14
|
-
}
|
|
15
|
-
container.style.display = "none";
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
// There are ways of doing this inside m.route but it is probably
|
|
20
|
-
// cleaner and faster when kept outside of the main auto
|
|
21
|
-
// rendering system
|
|
22
|
-
|
|
23
|
-
function popupMessage(message, cancelable = false, contentClass = ".modal-content") {
|
|
24
|
-
|
|
25
|
-
const container = document.getElementById("modal-container");
|
|
26
|
-
container.classList.toggle("iscustom", contentClass !== ".modal-content");
|
|
27
|
-
|
|
28
|
-
if (cancelable) {
|
|
29
|
-
|
|
30
|
-
mCurrentCancelable = cancelable;
|
|
31
|
-
|
|
32
|
-
container.onclick = (event) => {
|
|
33
|
-
if (event.target.id === "modal-container") {
|
|
34
|
-
runCancelable(container);
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
if (!message) {
|
|
40
|
-
|
|
41
|
-
if (popupMessage.redraw) {
|
|
42
|
-
popupMessage.redraw(true);
|
|
43
|
-
delete popupMessage.redraw;
|
|
44
|
-
}
|
|
45
|
-
if (message === null)
|
|
46
|
-
container.style.display = "none";
|
|
47
|
-
else
|
|
48
|
-
runCancelable(container);
|
|
49
|
-
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
container.style.display = "flex";
|
|
54
|
-
|
|
55
|
-
popupMessage.redraw = (remove) => {
|
|
56
|
-
m.render(
|
|
57
|
-
container,
|
|
58
|
-
m(contentClass, {
|
|
59
|
-
role: "alertdialog",
|
|
60
|
-
"aria-labelledby": "modaltitle",
|
|
61
|
-
"aria-modal": true
|
|
62
|
-
}, remove || !message ? [] : [
|
|
63
|
-
typeof message === "function" ? message() : message
|
|
64
|
-
])
|
|
65
|
-
);
|
|
66
|
-
};
|
|
67
|
-
popupMessage.redraw();
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function clearModal() {
|
|
71
|
-
const container = document.getElementById("modal-container");
|
|
72
|
-
if (container.style.display !== "none") {
|
|
73
|
-
runCancelable(container);
|
|
74
|
-
return true;
|
|
75
|
-
}
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export {popupMessage, clearModal};
|