@nebularstreams/libmui 2.0.13 → 2.0.14

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.
@@ -0,0 +1,31 @@
1
+ import m from "mithril";
2
+
3
+ let
4
+ gTainted = false;
5
+
6
+ function taint() {
7
+ gTainted = true;
8
+ }
9
+
10
+ function taintRedraw() {
11
+ const r = gTainted;
12
+ gTainted = true;
13
+ // eslint-disable-next-line no-unused-expressions
14
+ r && m.redraw();
15
+ }
16
+
17
+ function isTainted() {
18
+ return gTainted;
19
+ }
20
+
21
+ function untaint() {
22
+ gTainted = false;
23
+ m.redraw();
24
+ }
25
+
26
+ export {
27
+ taint,
28
+ taintRedraw,
29
+ isTainted,
30
+ untaint
31
+ };
@@ -215,6 +215,11 @@ function tokenizeUrl(tokenizedUrl, parameters, options) {
215
215
  return message || "(not enough parameters)";
216
216
  }
217
217
  }
218
+ function sanitizeFilename(filename) {
219
+ return filename ? filename.trim()
220
+ .toLowerCase()
221
+ .replace(/[^0-9A-Z.-]+/gi, "") : null;
222
+ }
218
223
 
219
224
  export {
220
225
  tokenize,
@@ -223,5 +228,6 @@ export {
223
228
  tokenizeKeep,
224
229
  tokenizeWithDefault,
225
230
  tokenizeUrl,
226
- getPointedData
231
+ getPointedData,
232
+ sanitizeFilename
227
233
  };
@@ -0,0 +1,72 @@
1
+ import m from "mithril";
2
+ import {ButtonNew, defineWidget} from "./Basic";
3
+ import Separator from "./Separator"
4
+
5
+ const
6
+
7
+ /*
8
+ SizeChoices = {
9
+ "1080p": {width: 1920, height: 1080, value: "1080p"},
10
+ "720p": {width: 1280, height: 720, value: "720p"},
11
+ "Fluid": {width: null, height: null, value: "Fluid"},
12
+ "Custom": {value: ""}
13
+ }
14
+ */
15
+
16
+ ButtonChoiceWidget = defineWidget(
17
+ ({attrs}) => {
18
+
19
+ const
20
+ {value, field, toggle, element, emptyMessage, chooseKey, chooseDict} = attrs,
21
+ choose = (!attrs.choose && chooseKey && chooseDict) ? chooseDict[chooseKey] : attrs.choose,
22
+ choices = choose
23
+ ? choose.map((choice) => ({value: choice, caption: choice}))
24
+ : attrs.choices || {};
25
+
26
+ const
27
+ keys = Object.keys(choices),
28
+ has = keys.length,
29
+ clase = (attrs.class || "") + (attrs.subclass ? " " + attrs.subclass : " scaff scaff-b1");
30
+
31
+ return has || emptyMessage
32
+ ? [
33
+ ...attrs.label ? [m(Separator, {text: attrs.label, class: attrs.labelClass || ""})] : [],
34
+ m(
35
+ (element || "div") + ".buttonchoice.flexrow.ohidden",
36
+ {
37
+ class: clase + (attrs.icon ? " withicon fa-" + attrs.icon : ""),
38
+ title: attrs.title
39
+ },
40
+ m(
41
+ ".flexrow.grows.ohidden.wrap" + (attrs.icon ? " scaff-left" : ""),
42
+ keys.length
43
+ ? keys.map((choicekey) => {
44
+
45
+ const
46
+ choice = choices[choicekey],
47
+ choicevalue = attrs.raw && field ? choice : choice.value,
48
+ finalchoicevalue = field ? choicevalue[field] : choicevalue,
49
+ current = finalchoicevalue === value;
50
+
51
+ // noinspection EqualityComparisonWithCoercionJS
52
+ return m(ButtonNew, {
53
+
54
+ icon: choice.icon || undefined,
55
+ class: "grows scaff-b0 " + (attrs.buttonClass ? attrs.buttonClass + " " : "rectbutton unitheightsmall ") + (choice.class ? choice.class + " " : "") + (current ? "accent" : ""),
56
+ title: choice.current ? choice.titleOn || choice.title : choice.titleOff || choice.title,
57
+ onClick: (e) => {
58
+ attrs.onchange(toggle ? current ? undefined : choice : choice, choicekey, e);
59
+ m.redraw();
60
+ }
61
+ }, attrs.render ? attrs.render(choice) : choice.caption || choicekey);
62
+ })
63
+ : [m(".emptychoice.grows.al-center.align-self-center.unitheightsmall", attrs.emptyMessage)]
64
+ )
65
+ )
66
+ ]
67
+ : [];
68
+ }
69
+ );
70
+
71
+ export default ButtonChoiceWidget;
72
+
@@ -0,0 +1,144 @@
1
+ import m from "mithril";
2
+ import defineWidget from "../util/widgets.utils";
3
+ import {popupMessage} from "../util/widgets"
4
+
5
+ const
6
+ colorjoe = require("colorjoe");
7
+ // TODO
8
+ // ColorProbeButton = require("ColorProbeButton");
9
+
10
+ const
11
+ ColorJoe = defineWidget(
12
+ () => m(".colorjoe-frame.absolute"),
13
+ null,
14
+ ({attrs, dom}) => {
15
+
16
+ window.SCALE = 1;
17
+
18
+ attrs.state.joe = (attrs.hsl ? colorjoe.hsl : colorjoe.rgb)(
19
+ dom,
20
+ attrs.color,
21
+ attrs.noalpha
22
+ ? []
23
+ : [
24
+ // "currentColor",
25
+ "alpha"
26
+ ]
27
+ );
28
+
29
+ attrs.state.joe.on("change", (c) => {
30
+ attrs.onColor(attrs.noalpha ? c.css() : c.cssa(), c);
31
+ })
32
+ .update();
33
+ }
34
+ ),
35
+ FAVORITES = [],
36
+ ColorJoeWrapper = defineWidget(
37
+ ({attrs, state, children}) => m(".colorjoe-popper.flexcol", {
38
+ class: attrs.noalpha ? "no-alpha" : ""
39
+ }, [
40
+ m(ColorJoe, {...attrs, state}),
41
+ ...children,
42
+ m(".flexrow.extended.w-100.scaff-top.pad-2.wrap", [
43
+
44
+ [0, 1, 2, 3, 4, 5, 6, 7, 8].map((i) => m("button.scaff.scaff-b1.marg-1.unitheightsmall.grows", {
45
+ class: FAVORITES[i] ? "" : "chequered",
46
+ style: {
47
+ ...FAVORITES[i] && {backgroundColor: FAVORITES[i]}
48
+ },
49
+ onclick: (e) => {
50
+ if (e.shiftKey) {
51
+ FAVORITES[i] = state.joe.get()
52
+ .css();
53
+ } else {
54
+ if (FAVORITES[i]) state.joe.set(FAVORITES[i]);
55
+ }
56
+ if (attrs.onRedraw) attrs.onRedraw(); else m.redraw();
57
+ }
58
+ })),
59
+ m(".flexbreak"),
60
+ /* TODO ELECTRON
61
+ m(ColorProbeButton, {
62
+ class: "grows marg-1 scaff scaff-b1 unitheightsmall",
63
+ icon: "magic",
64
+ title: "Pick a color from the scene",
65
+ onColor: (color) => state.joe.set(color)
66
+ }),
67
+ */
68
+ ...attrs.onRemove ? [m("button.scaff.scaff-b1.unitheightsmall.marg-1.pad-2.pad-h.grows.fabf.transp.bg-accent.fa-trash", {
69
+ onclick: () => attrs.onRemove(state.joe.get())
70
+ })] : []
71
+ ])
72
+ ])
73
+ ),
74
+ popupColor = (vnode) => popupMessage(
75
+ () => m(ColorJoeWrapper, {
76
+ noalpha: vnode.attrs.noalpha,
77
+ color: vnode.state.color,
78
+ hsl: vnode.attrs.hsl,
79
+ onColor: (parsedColor, colorObject) => {
80
+ vnode.state.color = parsedColor;
81
+ if (vnode.attrs.onchange) vnode.attrs.onchange(parsedColor, colorObject);
82
+ m.redraw();
83
+ },
84
+ onRemove: () => {
85
+ if (vnode.attrs.onchange) vnode.attrs.onchange(null, null);
86
+ popupMessage(null);
87
+ },
88
+ onRedraw: () => {
89
+ popupMessage.redraw();
90
+ m.redraw();
91
+ }
92
+ }, vnode.children),
93
+
94
+ () => {
95
+ },
96
+
97
+ ".modal-content-popper"
98
+ );
99
+
100
+ const ColorJoeWidget = defineWidget(
101
+ (vnode) => {
102
+ const {attrs, state} = vnode;
103
+ return [
104
+ m(
105
+ ".colorjoe-cell.chequered",
106
+ {
107
+ class: (attrs.class || "") + (state.shown ? " open" : ""),
108
+ title: attrs.title,
109
+ ...attrs.style && {style: attrs.style}
110
+ },
111
+ [
112
+ m(".inset", {
113
+ style: {
114
+ backgroundColor: state.color
115
+ },
116
+ ...attrs.caption && {"data-caption": attrs.caption, class: "titled"},
117
+ onclick: (e) => {
118
+ if (attrs.onshiftclick && (e.shiftKey || e.ctrlKey)) {
119
+ attrs.onshiftclick();
120
+ } else {
121
+ popupColor(vnode);
122
+ }
123
+ }
124
+ })
125
+ ])
126
+ ];
127
+ },
128
+ ({attrs, state}) => {
129
+ state.original = attrs.color;
130
+ state.color = state.original || "rgba(0,0,0,0)";
131
+ },
132
+ null,
133
+ null,
134
+ ({attrs, state}) => {
135
+ if (state.original !== attrs.color) {
136
+ state.original = attrs.color;
137
+ state.color = state.original || "rgba(0,0,0,0)";
138
+ m.redraw();
139
+ }
140
+ }
141
+ );
142
+
143
+
144
+ export default ColorJoeWidget;
@@ -0,0 +1,155 @@
1
+ import m from "mithril";
2
+
3
+ const
4
+ PropGroup = {
5
+ view: ({attrs}) => attrs.items.map(({name}, index) => m(
6
+ "option",
7
+ {
8
+ ...(attrs.state.index === index + (attrs.offset || 0)) && {selected: true}
9
+ },
10
+ name
11
+ ))
12
+ };
13
+
14
+ let
15
+ __timer;
16
+
17
+ function parseGroups(attrs, state) {
18
+
19
+ if (attrs.groups) {
20
+
21
+ state.groups = {};
22
+ state.allItems = [];
23
+
24
+ attrs.parsed = true;
25
+
26
+ const
27
+ groupKeys = Object.keys(attrs.groups);
28
+
29
+ groupKeys.forEach((groupKey) => {
30
+ state.groups[groupKey] = {
31
+ label: groupKey,
32
+ len: attrs.groups[groupKey].length,
33
+ items: attrs.groups[groupKey]
34
+ };
35
+ });
36
+
37
+ const
38
+ groupValues = Object.values(state.groups);
39
+
40
+ groupValues
41
+ .forEach((group, index) => {
42
+
43
+ if (attrs.value) {
44
+ state.index = 0;
45
+ }
46
+
47
+ group.offset = index ? groupValues[index - 1].offset + groupValues[index - 1].len : 0;
48
+ state.allItems = state.allItems.concat(group.items);
49
+ if (attrs.value) {
50
+
51
+ group.items.forEach((item, itemIndex) => {
52
+ const
53
+ itemValue = item.value,
54
+ parsedValue = attrs.parser ? attrs.parser(itemValue) : itemValue;
55
+ if (parsedValue === attrs.value) {
56
+ state.index = itemIndex + group.offset;
57
+ }
58
+ });
59
+ }
60
+ });
61
+ } else if (attrs.items) {
62
+ state.index = 0;
63
+ for (let i = 0, l = attrs.items.length; i < l; i++) {
64
+ const
65
+ itemValue = attrs.items[i].value,
66
+ parsedValue = attrs.parser ? attrs.parser(itemValue) : itemValue;
67
+ if (parsedValue === attrs.value) {
68
+ state.index = i;
69
+ break;
70
+ }
71
+ }
72
+ state.allItems = attrs.items;
73
+ } else {
74
+ state.allItems = [];
75
+ }
76
+
77
+ }
78
+
79
+ const ComboWidget = {
80
+
81
+ /**
82
+ * Creates the Widget View
83
+ * @param vnode
84
+ * @param {SelectAttrs} vnode.attrs
85
+ * @param {Object} vnode.state
86
+ * @return {*}
87
+ * @private
88
+ */
89
+
90
+
91
+ view: ({attrs, state}) => {
92
+ const {groups} = state;
93
+ return m(
94
+ "select",
95
+ {
96
+ "aria-label": attrs.caption,
97
+ class: attrs.class,
98
+ oninput: (ev) => {
99
+
100
+ // el desincronismo es si se camian los items y el state no se entera
101
+ // esto asegura que estan synchro
102
+ parseGroups(attrs, state);
103
+
104
+ const
105
+ index = state.index = ev.target.selectedIndex,
106
+ item = index >= 0 ? state.allItems[index] : null;
107
+
108
+ if (attrs.onchange && item) {
109
+ attrs.onchange(item.value, item, index);
110
+ }
111
+
112
+ m.redraw();
113
+ }
114
+ },
115
+ groups
116
+ ? Object.values(groups)
117
+ .map((group) => m("optgroup", {label: group.label}, m(PropGroup, {
118
+ items: group.items,
119
+ offset: group.offset,
120
+ state
121
+ })))
122
+ : m(PropGroup, {items: (attrs.items != null ? attrs.items : []), state}));
123
+ },
124
+
125
+ oninit: ({attrs, state}) => {
126
+ Object.assign(state, {
127
+ index: attrs.index || 0,
128
+ initial: attrs.value
129
+ });
130
+ parseGroups(attrs, state);
131
+ },
132
+
133
+ oncreate: () => {
134
+ },
135
+
136
+ onupdate: ({attrs, state}) => {
137
+
138
+ const refresh = (attrs.value !== undefined && state.initial !== attrs.value);
139
+
140
+ if (!state.groups && !state.allItems || refresh) {
141
+
142
+ // sets index from attrs.value
143
+ parseGroups(attrs, state);
144
+
145
+ if (refresh) {
146
+ state.initial = attrs.value;
147
+ clearTimeout(__timer);
148
+ __timer = setTimeout(() => m.redraw(), 50);
149
+ }
150
+ }
151
+
152
+ }
153
+ };
154
+
155
+ export default ComboWidget;
@@ -0,0 +1,36 @@
1
+ import m from "mithril";
2
+ import {defineWidget, ButtonNew} from "./Basic";
3
+
4
+ const
5
+ // TODO
6
+ FontSelectorButton = defineWidget(
7
+ ({attrs}) => {
8
+ const {fontFamily, state, onchange} = attrs;
9
+ return m(".flexrow.grows.fontgroup", {class: attrs.class}, [
10
+ ...fontFamily && !attrs.nodelete
11
+ ? [
12
+ m(ButtonNew, {
13
+ class: "scaff-right unitsize",
14
+ icon: "trash",
15
+ onClick: () => {
16
+ onchange(undefined);
17
+ state.setTransState();
18
+ }
19
+ })
20
+ ]
21
+ : [],
22
+ m(ButtonNew, {
23
+ class: "grows transp font-125 ohidden",
24
+ text: fontFamily || "default",
25
+ icon: "font",
26
+ onClick: () => state.setTransState("fontsel", (selected) => {
27
+ onchange(selected);
28
+ state.setTransState();
29
+ })
30
+ }),
31
+
32
+ ]);
33
+ }
34
+ );
35
+
36
+ export default FontSelectorButton;
@@ -0,0 +1,55 @@
1
+ import m from "mithril";
2
+ import {ButtonNew, defineWidget} from "./Basic";
3
+
4
+ const
5
+ PlusMinus = defineWidget(
6
+ ({attrs}) => {
7
+ return m(".flexrow.wrap.grows",
8
+ {
9
+ ...attrs.label && {"aria-label": attrs.label},
10
+ class: (attrs.label ? "witharia" : "") + " " + (attrs.class || ""),
11
+ title: attrs.title || ""
12
+ },
13
+ [
14
+ m(ButtonNew, {
15
+ icon: "minus",
16
+ class: "unitsizesmall transp",
17
+ title: attrs.title ? "decrease the " + attrs.title : "",
18
+ onClick: () => {
19
+ const {
20
+ step = 1,
21
+ min = 0
22
+ } = attrs;
23
+ let v = attrs.value || 0;
24
+ if (Number.isNaN(v)) v = 0;
25
+ v -= step;
26
+ if (v < min) v = min;
27
+ attrs.onchange(v);
28
+ m.redraw();
29
+ }
30
+ }),
31
+ m(".currentvalue.al-center.grows.unitheightsmall", {
32
+ title: attrs.title
33
+ }, String(attrs.value || 0)),
34
+ m(ButtonNew, {
35
+ icon: "plus",
36
+ class: "unitsizesmall transp",
37
+ title: attrs.title ? "decrease the " + attrs.title : "",
38
+ onClick: () => {
39
+ const {
40
+ step = 1,
41
+ max = 0
42
+ } = attrs;
43
+
44
+ let v = attrs.value || 0;
45
+ if (max && v === max) return;
46
+ v += step;
47
+ attrs.onchange(v);
48
+ m.redraw();
49
+ }
50
+ })
51
+ ]);
52
+ }
53
+ );
54
+
55
+ export default PlusMinus;