@phin-tech/dottie 0.6.2 → 0.7.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/PARITY.md +5 -0
- package/README.md +8 -3
- package/dist/compile.js +41 -11
- package/dist/dottie-compile.mjs +42 -12
- package/dist/dottie-player.js +413 -67
- package/dist/dottie-player.min.js +53 -53
- package/dist/dottie.js +413 -67
- package/dist/types/clicks.d.ts +8 -2
- package/dist/types/connector.d.ts +6 -6
- package/dist/types/element.d.ts +3 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/model.d.ts +16 -1
- package/dist/types/player.d.ts +19 -2
- package/dist/types/shapes.d.ts +17 -4
- package/dist/types/state.d.ts +20 -0
- package/dist/types/timeline.d.ts +5 -3
- package/package.json +1 -1
package/PARITY.md
CHANGED
|
@@ -24,7 +24,9 @@ fixture, so the gap is visible rather than silent.
|
|
|
24
24
|
| Ports and edge-following, rotated shapes, free ends | Supported | [edge/connectors](../fixtures/edge/connectors.dottie) | |
|
|
25
25
|
| Connectors and labels on outlines (ADR 0001) | Supported | [edge/extensions](../fixtures/edge/extensions.dottie) | Edge-following meets a `.path`'s actual outline, not its box (ray against 16-step flattened curves). Endpoints pinned with `portIndex` attach to the element's `ports`. A path's label goes in its `labelRect`. |
|
|
26
26
|
| Extension shapes as stored (ADR 0001) | Supported | [edge/extensions](../fixtures/edge/extensions.dottie) | Drawn from the stored path with no extension installed. The `extension` field is kept as metadata and nothing runs. Parameters, commands and handles are Dottie-only. |
|
|
27
|
+
| Waypoints (bends) on every routing, and hops | Supported | [edge/waypoints](../fixtures/edge/waypoints.dottie), [edge/waypoints-symbol](../fixtures/edge/waypoints-symbol.dottie) | Hops need the page, so `connectorParts` takes it; without one a line draws none. |
|
|
27
28
|
| Arrowheads: arrow, triangle, dot, bar | Supported | [edge/connectors](../fixtures/edge/connectors.dottie) | |
|
|
29
|
+
| Label colors (`textColor`, apart from the stroke) | Supported | [edge/text-colors](../fixtures/edge/text-colors.dottie) | Text boxes and notes ignore it, as in Dottie |
|
|
28
30
|
| Connector labels | Supported | [edge/connectors](../fixtures/edge/connectors.dottie) | Label boxes sized with CoreText's measurements. The player paints them on the page color, like the app; Dottie's flipbook export leaves them unpainted |
|
|
29
31
|
| Keys and eases (linear, in, out, in-out, hold, spring, bounce, elastic) | Supported | [edge/timeline](../fixtures/edge/timeline.dottie), [edge/eases](../fixtures/edge/eases.dottie) | Unknown ease names play linear, with a warning |
|
|
30
32
|
| Visibility, reveal (draw-on, typing), opacity | Supported | [edge/timeline](../fixtures/edge/timeline.dottie) | |
|
|
@@ -45,6 +47,9 @@ fixture, so the gap is visible rather than silent.
|
|
|
45
47
|
| Symbol parameters (`{{name}}` in a symbol's text, filled per copy) | Supported | [edge/params](../fixtures/edge/params.dottie) | Defaults, undeclared names left as written, values passed into nested copies, filled before text types out |
|
|
46
48
|
| Copies that play when clicked | Supported | [edge/buttons](../fixtures/edge/buttons.dottie) | `<dottie-player>` only: the HTML export is drawn ahead of time and shows them at rest |
|
|
47
49
|
| Clicks: play a scene, open a link, hover looks, keyboard | Supported | [edge/clicks](../fixtures/edge/clicks.dottie) | As the HTML export does; only http, https and mailto links are followed |
|
|
50
|
+
| Page variables and conditions (`variables`, `when`) | Supported | [edge/state](../fixtures/edge/state.dottie) | Starting values in every still and export; connectors go with a shape the state hides |
|
|
51
|
+
| Clicks that set and toggle variables | Supported | [edge/state](../fixtures/edge/state.dottie) | Change what shows without touching the playhead. The HTML export of a page with state is this player |
|
|
52
|
+
| Looping scenes (`loop` on a marker) | Supported | [edge/state](../fixtures/edge/state.dottie) | As the HTML export plays them: no stop on entering, round from the scene's end to its start |
|
|
48
53
|
| Links out of the drawing (`url`) | Supported | [edge/links](../fixtures/edge/links.dottie) | A web or mail `url` opens when clicked if there is no `click`, and SVG export wraps it in `<a>`; a link to another drawing does nothing on the web |
|
|
49
54
|
| Links between shapes and pages | Partial | [edge/clicks](../fixtures/edge/clicks.dottie) | A link to a shape on another page shows that page; one on the same page does nothing. The HTML export holds one page, so it has neither |
|
|
50
55
|
| Editing | Missing | | |
|
package/README.md
CHANGED
|
@@ -33,11 +33,16 @@ Elements the drawing makes clickable work with the mouse and the keyboard (Tab,
|
|
|
33
33
|
a named scene on to the next one, opens a link in a new tab (only `http`, `https` and `mailto`), or shows the page a
|
|
34
34
|
shape's link points at. Each shows its hover look under the pointer; button symbols show their over and down looks
|
|
35
35
|
and take clicks on their hit area, and a symbol's copy set to play when clicked plays its animation through. Every
|
|
36
|
-
click first fires a cancelable `action` event whose `detail` is `{element, scene | url | page,
|
|
37
|
-
`preventDefault()` to handle it yourself.
|
|
36
|
+
click first fires a cancelable `action` event whose `detail` is `{element, scene | url | page | state, set?, toggle?,
|
|
37
|
+
replay?}`; call `preventDefault()` to handle it yourself.
|
|
38
|
+
|
|
39
|
+
A click can also set or toggle the page's variables, which show and hide the elements with a `when` while the
|
|
40
|
+
animation keeps playing: a diagram you leave running that people poke. A looping scene plays round until a click
|
|
41
|
+
or next leaves it, instead of stopping.
|
|
38
42
|
|
|
39
43
|
The element has `play()`, `pause()`, `nextScene()`, `prevScene()`, `activate(elementId)`, `currentTime`
|
|
40
|
-
(settable), `duration`, `paused`, and fires `load`, `frame`, `action
|
|
44
|
+
(settable), `duration`, `paused`, `variables` and `setState({name: value})`, and fires `load`, `frame`, `action`,
|
|
45
|
+
`state` (with `{variables}`, after a change) and `error` events. Its page color comes from the drawing's theme; set
|
|
41
46
|
`--dottie-radius` to round it, and style its parts with `::part(stage)` and `::part(controls)`.
|
|
42
47
|
|
|
43
48
|
Without modules, `dist/dottie-player.min.js` is a classic script that registers the element and sets
|
package/dist/compile.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! dottie.js 0.
|
|
1
|
+
/*! dottie.js 0.7.0 | Apache-2.0 | https://github.com/phin-tech/dottie */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
4
4
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -44,17 +44,23 @@ function defaultBase() {
|
|
|
44
44
|
}
|
|
45
45
|
var base = defaultBase();
|
|
46
46
|
|
|
47
|
+
// src/state.ts
|
|
48
|
+
var MAX_NAME = 64;
|
|
49
|
+
function isName(name) {
|
|
50
|
+
return name.length <= MAX_NAME && /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
|
|
51
|
+
}
|
|
52
|
+
|
|
47
53
|
// src/model.ts
|
|
48
54
|
var SUPPORTED_VERSION = 2;
|
|
49
55
|
var KINDS = ["rectangle", "ellipse", "diamond", "text", "connector", "freehand", "path", "note", "image", "symbol"];
|
|
50
56
|
var EASES = ["linear", "easeIn", "easeOut", "easeInOut", "hold", "spring", "bounce", "elastic"];
|
|
51
57
|
var KNOWN_FIELDS = {
|
|
52
58
|
file: ["version", "pages", "images"],
|
|
53
|
-
page: ["id", "name", "layers", "elements", "theme", "guidesX", "guidesY", "guidesLocked", "timeline", "symbols"],
|
|
59
|
+
page: ["id", "name", "layers", "elements", "theme", "guidesX", "guidesY", "guidesLocked", "timeline", "symbols", "variables"],
|
|
54
60
|
symbol: ["id", "name", "width", "height", "layers", "elements", "timeline", "button", "params"],
|
|
55
61
|
layer: ["id", "name", "visible", "locked"],
|
|
56
62
|
rgba: ["r", "g", "b", "a"],
|
|
57
|
-
style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "font", "gridSize", "opacity", "dashOffset"],
|
|
63
|
+
style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "font", "gridSize", "opacity", "dashOffset", "textColor"],
|
|
58
64
|
element: [
|
|
59
65
|
"id",
|
|
60
66
|
"kind",
|
|
@@ -78,6 +84,7 @@ var KNOWN_FIELDS = {
|
|
|
78
84
|
"anchor",
|
|
79
85
|
"click",
|
|
80
86
|
"hover",
|
|
87
|
+
"when",
|
|
81
88
|
"symbol",
|
|
82
89
|
"playback",
|
|
83
90
|
"offset",
|
|
@@ -95,15 +102,16 @@ var KNOWN_FIELDS = {
|
|
|
95
102
|
extensionRef: ["id", "shape", "version", "params"],
|
|
96
103
|
normalizedPoint: ["x", "y"],
|
|
97
104
|
normalizedRect: ["x", "y", "width", "height"],
|
|
98
|
-
connector: ["start", "end", "routing", "startHead", "endHead"],
|
|
105
|
+
connector: ["start", "end", "routing", "startHead", "endHead", "waypoints", "hops"],
|
|
106
|
+
waypoint: ["x", "y"],
|
|
99
107
|
timeline: ["fps", "duration", "boil", "settle", "poster", "tracks", "camera", "markers"],
|
|
100
108
|
track: ["element", "keys", "boil", "follow", "repeats", "march"],
|
|
101
109
|
keyframe: ["t", "x", "y", "width", "height", "rotation", "strokeWidth", "stroke", "fill", "visible", "reveal", "opacity", "ease"],
|
|
102
110
|
follow: ["path", "start", "end", "ease", "reverse", "orient", "laps"],
|
|
103
111
|
repeat: ["start", "end", "count"],
|
|
104
112
|
cameraKey: ["t", "x", "y", "width", "height", "ease"],
|
|
105
|
-
marker: ["t", "name"],
|
|
106
|
-
click: ["scene", "url"],
|
|
113
|
+
marker: ["t", "name", "loop"],
|
|
114
|
+
click: ["scene", "url", "set", "toggle"],
|
|
107
115
|
hover: ["stroke", "fill", "opacity"]
|
|
108
116
|
};
|
|
109
117
|
var MAX_DURATION = 3600;
|
|
@@ -172,7 +180,8 @@ var Reader = class {
|
|
|
172
180
|
font: str(s.font) || null,
|
|
173
181
|
gridSize: num(s.gridSize) ?? null,
|
|
174
182
|
opacity: num(s.opacity) ?? null,
|
|
175
|
-
dashOffset: num(s.dashOffset) ?? null
|
|
183
|
+
dashOffset: num(s.dashOffset) ?? null,
|
|
184
|
+
textColor: rgba(s.textColor) ?? null
|
|
176
185
|
};
|
|
177
186
|
}
|
|
178
187
|
endpoint(v) {
|
|
@@ -200,7 +209,12 @@ var Reader = class {
|
|
|
200
209
|
end: this.endpoint(v.end),
|
|
201
210
|
routing: routing && ["straight", "curved", "elbow"].includes(routing) ? routing : "straight",
|
|
202
211
|
startHead: head(v.startHead, "none"),
|
|
203
|
-
endHead: head(v.endHead, "arrow")
|
|
212
|
+
endHead: head(v.endHead, "arrow"),
|
|
213
|
+
waypoints: Array.isArray(v.waypoints) ? v.waypoints.filter(isObj).map((w) => {
|
|
214
|
+
this.fields(w, "waypoint");
|
|
215
|
+
return { x: num(w.x) ?? 0, y: num(w.y) ?? 0 };
|
|
216
|
+
}) : null,
|
|
217
|
+
hops: typeof v.hops === "boolean" ? v.hops : null
|
|
204
218
|
};
|
|
205
219
|
}
|
|
206
220
|
image(v, table) {
|
|
@@ -251,6 +265,7 @@ var Reader = class {
|
|
|
251
265
|
anchor: str(v.anchor) ?? null,
|
|
252
266
|
click: this.click(v.click),
|
|
253
267
|
hover: this.hover(v.hover),
|
|
268
|
+
when: str(v.when) ?? null,
|
|
254
269
|
symbol: uuid(v.symbol) ?? null,
|
|
255
270
|
playback: this.playback(v.playback),
|
|
256
271
|
offset: num(v.offset) ?? null,
|
|
@@ -286,13 +301,27 @@ var Reader = class {
|
|
|
286
301
|
}
|
|
287
302
|
return { id, shape, version, params };
|
|
288
303
|
}
|
|
304
|
+
variables(v) {
|
|
305
|
+
if (!isObj(v)) return null;
|
|
306
|
+
const out = {};
|
|
307
|
+
for (const [k, b] of Object.entries(v)) if (typeof b === "boolean") out[k] = b;
|
|
308
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
309
|
+
}
|
|
289
310
|
click(v) {
|
|
290
311
|
if (!isObj(v)) return null;
|
|
291
312
|
this.fields(v, "click");
|
|
292
313
|
const url = str(v.url);
|
|
293
314
|
const safe = url === void 0 ? null : allowedURL(url);
|
|
294
315
|
if (url !== void 0 && safe === null) this.warn("Skipped a click link that isn't http, https or mailto");
|
|
295
|
-
|
|
316
|
+
let set = null;
|
|
317
|
+
if (isObj(v.set)) {
|
|
318
|
+
set = {};
|
|
319
|
+
for (const [k, b] of Object.entries(v.set)) if (typeof b === "boolean" && isName(k)) set[k] = b;
|
|
320
|
+
if (Object.keys(set).length === 0) set = null;
|
|
321
|
+
}
|
|
322
|
+
const raw = typeof v.toggle === "string" ? [v.toggle] : Array.isArray(v.toggle) && v.toggle.every((x) => typeof x === "string") ? v.toggle : null;
|
|
323
|
+
const toggle = raw ? raw.filter(isName) : null;
|
|
324
|
+
return { scene: str(v.scene) ?? null, url: safe, set, toggle: toggle && toggle.length > 0 ? toggle : null };
|
|
296
325
|
}
|
|
297
326
|
playback(v) {
|
|
298
327
|
const s = str(v);
|
|
@@ -393,7 +422,7 @@ var Reader = class {
|
|
|
393
422
|
if (camera) stableSortBy(camera, (c) => c.t);
|
|
394
423
|
const markers = Array.isArray(v.markers) ? v.markers.filter(isObj).flatMap((m) => {
|
|
395
424
|
const t = num(m.t);
|
|
396
|
-
return t !== void 0 && t >= 0 ? [{ t, name: str(m.name) ?? "" }] : [];
|
|
425
|
+
return t !== void 0 && t >= 0 ? [{ t, name: str(m.name) ?? "", loop: bool(m.loop) ?? null }] : [];
|
|
397
426
|
}) : null;
|
|
398
427
|
if (markers) stableSortBy(markers, (m) => m.t);
|
|
399
428
|
const poster = num(v.poster);
|
|
@@ -426,7 +455,8 @@ var Reader = class {
|
|
|
426
455
|
elements: (Array.isArray(v.elements) ? v.elements : []).map((e) => this.element(e, images)).filter((e) => e !== null),
|
|
427
456
|
theme: str(v.theme) ?? null,
|
|
428
457
|
timeline: this.timeline(v.timeline),
|
|
429
|
-
symbols: Array.isArray(v.symbols) ? v.symbols.map((x) => this.symbol(x, images)).filter((x) => x !== null) : null
|
|
458
|
+
symbols: Array.isArray(v.symbols) ? v.symbols.map((x) => this.symbol(x, images)).filter((x) => x !== null) : null,
|
|
459
|
+
variables: this.variables(v.variables)
|
|
430
460
|
};
|
|
431
461
|
}
|
|
432
462
|
};
|
package/dist/dottie-compile.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
/*! dottie.js 0.
|
|
2
|
+
/*! dottie.js 0.7.0 | Apache-2.0 | https://github.com/phin-tech/dottie */
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
5
5
|
var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
@@ -52,17 +52,23 @@ function defaultBase() {
|
|
|
52
52
|
}
|
|
53
53
|
var base = defaultBase();
|
|
54
54
|
|
|
55
|
+
// src/state.ts
|
|
56
|
+
var MAX_NAME = 64;
|
|
57
|
+
function isName(name) {
|
|
58
|
+
return name.length <= MAX_NAME && /^[A-Za-z_][A-Za-z0-9_]*$/.test(name);
|
|
59
|
+
}
|
|
60
|
+
|
|
55
61
|
// src/model.ts
|
|
56
62
|
var SUPPORTED_VERSION = 2;
|
|
57
63
|
var KINDS = ["rectangle", "ellipse", "diamond", "text", "connector", "freehand", "path", "note", "image", "symbol"];
|
|
58
64
|
var EASES = ["linear", "easeIn", "easeOut", "easeInOut", "hold", "spring", "bounce", "elastic"];
|
|
59
65
|
var KNOWN_FIELDS = {
|
|
60
66
|
file: ["version", "pages", "images"],
|
|
61
|
-
page: ["id", "name", "layers", "elements", "theme", "guidesX", "guidesY", "guidesLocked", "timeline", "symbols"],
|
|
67
|
+
page: ["id", "name", "layers", "elements", "theme", "guidesX", "guidesY", "guidesLocked", "timeline", "symbols", "variables"],
|
|
62
68
|
symbol: ["id", "name", "width", "height", "layers", "elements", "timeline", "button", "params"],
|
|
63
69
|
layer: ["id", "name", "visible", "locked"],
|
|
64
70
|
rgba: ["r", "g", "b", "a"],
|
|
65
|
-
style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "font", "gridSize", "opacity", "dashOffset"],
|
|
71
|
+
style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "font", "gridSize", "opacity", "dashOffset", "textColor"],
|
|
66
72
|
element: [
|
|
67
73
|
"id",
|
|
68
74
|
"kind",
|
|
@@ -86,6 +92,7 @@ var KNOWN_FIELDS = {
|
|
|
86
92
|
"anchor",
|
|
87
93
|
"click",
|
|
88
94
|
"hover",
|
|
95
|
+
"when",
|
|
89
96
|
"symbol",
|
|
90
97
|
"playback",
|
|
91
98
|
"offset",
|
|
@@ -103,15 +110,16 @@ var KNOWN_FIELDS = {
|
|
|
103
110
|
extensionRef: ["id", "shape", "version", "params"],
|
|
104
111
|
normalizedPoint: ["x", "y"],
|
|
105
112
|
normalizedRect: ["x", "y", "width", "height"],
|
|
106
|
-
connector: ["start", "end", "routing", "startHead", "endHead"],
|
|
113
|
+
connector: ["start", "end", "routing", "startHead", "endHead", "waypoints", "hops"],
|
|
114
|
+
waypoint: ["x", "y"],
|
|
107
115
|
timeline: ["fps", "duration", "boil", "settle", "poster", "tracks", "camera", "markers"],
|
|
108
116
|
track: ["element", "keys", "boil", "follow", "repeats", "march"],
|
|
109
117
|
keyframe: ["t", "x", "y", "width", "height", "rotation", "strokeWidth", "stroke", "fill", "visible", "reveal", "opacity", "ease"],
|
|
110
118
|
follow: ["path", "start", "end", "ease", "reverse", "orient", "laps"],
|
|
111
119
|
repeat: ["start", "end", "count"],
|
|
112
120
|
cameraKey: ["t", "x", "y", "width", "height", "ease"],
|
|
113
|
-
marker: ["t", "name"],
|
|
114
|
-
click: ["scene", "url"],
|
|
121
|
+
marker: ["t", "name", "loop"],
|
|
122
|
+
click: ["scene", "url", "set", "toggle"],
|
|
115
123
|
hover: ["stroke", "fill", "opacity"]
|
|
116
124
|
};
|
|
117
125
|
var MAX_DURATION = 3600;
|
|
@@ -180,7 +188,8 @@ var Reader = class {
|
|
|
180
188
|
font: str(s.font) || null,
|
|
181
189
|
gridSize: num(s.gridSize) ?? null,
|
|
182
190
|
opacity: num(s.opacity) ?? null,
|
|
183
|
-
dashOffset: num(s.dashOffset) ?? null
|
|
191
|
+
dashOffset: num(s.dashOffset) ?? null,
|
|
192
|
+
textColor: rgba(s.textColor) ?? null
|
|
184
193
|
};
|
|
185
194
|
}
|
|
186
195
|
endpoint(v) {
|
|
@@ -208,7 +217,12 @@ var Reader = class {
|
|
|
208
217
|
end: this.endpoint(v.end),
|
|
209
218
|
routing: routing && ["straight", "curved", "elbow"].includes(routing) ? routing : "straight",
|
|
210
219
|
startHead: head(v.startHead, "none"),
|
|
211
|
-
endHead: head(v.endHead, "arrow")
|
|
220
|
+
endHead: head(v.endHead, "arrow"),
|
|
221
|
+
waypoints: Array.isArray(v.waypoints) ? v.waypoints.filter(isObj).map((w) => {
|
|
222
|
+
this.fields(w, "waypoint");
|
|
223
|
+
return { x: num(w.x) ?? 0, y: num(w.y) ?? 0 };
|
|
224
|
+
}) : null,
|
|
225
|
+
hops: typeof v.hops === "boolean" ? v.hops : null
|
|
212
226
|
};
|
|
213
227
|
}
|
|
214
228
|
image(v, table) {
|
|
@@ -259,6 +273,7 @@ var Reader = class {
|
|
|
259
273
|
anchor: str(v.anchor) ?? null,
|
|
260
274
|
click: this.click(v.click),
|
|
261
275
|
hover: this.hover(v.hover),
|
|
276
|
+
when: str(v.when) ?? null,
|
|
262
277
|
symbol: uuid(v.symbol) ?? null,
|
|
263
278
|
playback: this.playback(v.playback),
|
|
264
279
|
offset: num(v.offset) ?? null,
|
|
@@ -294,13 +309,27 @@ var Reader = class {
|
|
|
294
309
|
}
|
|
295
310
|
return { id, shape, version, params };
|
|
296
311
|
}
|
|
312
|
+
variables(v) {
|
|
313
|
+
if (!isObj(v)) return null;
|
|
314
|
+
const out = {};
|
|
315
|
+
for (const [k, b] of Object.entries(v)) if (typeof b === "boolean") out[k] = b;
|
|
316
|
+
return Object.keys(out).length > 0 ? out : null;
|
|
317
|
+
}
|
|
297
318
|
click(v) {
|
|
298
319
|
if (!isObj(v)) return null;
|
|
299
320
|
this.fields(v, "click");
|
|
300
321
|
const url = str(v.url);
|
|
301
322
|
const safe = url === void 0 ? null : allowedURL(url);
|
|
302
323
|
if (url !== void 0 && safe === null) this.warn("Skipped a click link that isn't http, https or mailto");
|
|
303
|
-
|
|
324
|
+
let set = null;
|
|
325
|
+
if (isObj(v.set)) {
|
|
326
|
+
set = {};
|
|
327
|
+
for (const [k, b] of Object.entries(v.set)) if (typeof b === "boolean" && isName(k)) set[k] = b;
|
|
328
|
+
if (Object.keys(set).length === 0) set = null;
|
|
329
|
+
}
|
|
330
|
+
const raw = typeof v.toggle === "string" ? [v.toggle] : Array.isArray(v.toggle) && v.toggle.every((x) => typeof x === "string") ? v.toggle : null;
|
|
331
|
+
const toggle = raw ? raw.filter(isName) : null;
|
|
332
|
+
return { scene: str(v.scene) ?? null, url: safe, set, toggle: toggle && toggle.length > 0 ? toggle : null };
|
|
304
333
|
}
|
|
305
334
|
playback(v) {
|
|
306
335
|
const s = str(v);
|
|
@@ -401,7 +430,7 @@ var Reader = class {
|
|
|
401
430
|
if (camera) stableSortBy(camera, (c) => c.t);
|
|
402
431
|
const markers = Array.isArray(v.markers) ? v.markers.filter(isObj).flatMap((m) => {
|
|
403
432
|
const t = num(m.t);
|
|
404
|
-
return t !== void 0 && t >= 0 ? [{ t, name: str(m.name) ?? "" }] : [];
|
|
433
|
+
return t !== void 0 && t >= 0 ? [{ t, name: str(m.name) ?? "", loop: bool(m.loop) ?? null }] : [];
|
|
405
434
|
}) : null;
|
|
406
435
|
if (markers) stableSortBy(markers, (m) => m.t);
|
|
407
436
|
const poster = num(v.poster);
|
|
@@ -434,7 +463,8 @@ var Reader = class {
|
|
|
434
463
|
elements: (Array.isArray(v.elements) ? v.elements : []).map((e) => this.element(e, images)).filter((e) => e !== null),
|
|
435
464
|
theme: str(v.theme) ?? null,
|
|
436
465
|
timeline: this.timeline(v.timeline),
|
|
437
|
-
symbols: Array.isArray(v.symbols) ? v.symbols.map((x) => this.symbol(x, images)).filter((x) => x !== null) : null
|
|
466
|
+
symbols: Array.isArray(v.symbols) ? v.symbols.map((x) => this.symbol(x, images)).filter((x) => x !== null) : null,
|
|
467
|
+
variables: this.variables(v.variables)
|
|
438
468
|
};
|
|
439
469
|
}
|
|
440
470
|
};
|
|
@@ -581,7 +611,7 @@ function compile(source2, runtime, options2 = {}) {
|
|
|
581
611
|
}
|
|
582
612
|
|
|
583
613
|
// src/index.ts
|
|
584
|
-
var VERSION = "0.
|
|
614
|
+
var VERSION = "0.7.0";
|
|
585
615
|
|
|
586
616
|
// src/cli.ts
|
|
587
617
|
var usage = `dottie-compile ${VERSION}: a Dottie drawing as one script that plays it on any page.
|