@statewalker/fsm-charts 0.2.5 → 0.2.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.
Files changed (75) hide show
  1. package/README.md +213 -1
  2. package/dist/StateChart-cXyVRcs-.d.ts +94 -0
  3. package/dist/StateChart-cXyVRcs-.d.ts.map +1 -0
  4. package/dist/StateChartIndex-BK2315qj.d.ts +142 -0
  5. package/dist/StateChartIndex-BK2315qj.d.ts.map +1 -0
  6. package/dist/StateChartIndex-BOIrc_nq.js +355 -0
  7. package/dist/StateChartIndex-BOIrc_nq.js.map +1 -0
  8. package/dist/buildStatechartsPanel-BX7e0GzA.js +494 -0
  9. package/dist/buildStatechartsPanel-BX7e0GzA.js.map +1 -0
  10. package/dist/buildStatechartsPanel-hCtZbdiF.d.ts +79 -0
  11. package/dist/buildStatechartsPanel-hCtZbdiF.d.ts.map +1 -0
  12. package/dist/defineProperty-C0rC37pP.js +39 -0
  13. package/dist/description-panels-DI2MNlbK.js +184 -0
  14. package/dist/description-panels-DI2MNlbK.js.map +1 -0
  15. package/dist/getLabelDimensions-BY0q7j3D.d.ts +79 -0
  16. package/dist/getLabelDimensions-BY0q7j3D.d.ts.map +1 -0
  17. package/dist/getPadding-Cw0e7G2v.js +25 -0
  18. package/dist/getPadding-Cw0e7G2v.js.map +1 -0
  19. package/dist/index-config.d.ts +3 -12
  20. package/dist/index-config.js +2 -2
  21. package/dist/index-dom.d.ts +2 -49
  22. package/dist/index-dom.js +2 -2
  23. package/dist/index-html.d.ts +3 -2
  24. package/dist/index-html.js +2 -3
  25. package/dist/index-layout.d.ts +3 -77
  26. package/dist/index-layout.js +2 -3
  27. package/dist/index-runtime.d.ts +3 -141
  28. package/dist/index-runtime.js +2 -2
  29. package/dist/index.d.ts +11 -10
  30. package/dist/index.d.ts.map +1 -0
  31. package/dist/index.js +6 -7
  32. package/dist/layout-Dp671N6q.js +2465 -0
  33. package/dist/layout-Dp671N6q.js.map +1 -0
  34. package/dist/newTreeBuilder-CvtLDjGj.d.ts +54 -0
  35. package/dist/newTreeBuilder-CvtLDjGj.d.ts.map +1 -0
  36. package/dist/toFsmStateConfig-DlJkyZni.js +135 -0
  37. package/dist/toFsmStateConfig-DlJkyZni.js.map +1 -0
  38. package/dist/toFsmStateConfig-DmOlTRjv.d.ts +15 -0
  39. package/dist/toFsmStateConfig-DmOlTRjv.d.ts.map +1 -0
  40. package/package.json +52 -27
  41. package/src/config/concatTransitionsToString.ts +2 -2
  42. package/src/config/splitTransitionString.ts +1 -3
  43. package/src/config/toFsmStateConfig.ts +2 -9
  44. package/src/dom/buildSections.ts +3 -11
  45. package/src/dom/description-panels.ts +2 -4
  46. package/src/dom/getStatesDescriptions.ts +3 -9
  47. package/src/html/buildStatechartStyles.ts +4 -14
  48. package/src/html/buildStatechartSvg.ts +2 -14
  49. package/src/html/buildStatechartsPanel.ts +1 -3
  50. package/src/layout/buildCharts.ts +1 -2
  51. package/src/layout/buildFlatCharts.ts +6 -8
  52. package/src/layout/getGraphParamsProvider.ts +3 -12
  53. package/src/runtime/RuntimeStatechartApi.ts +10 -32
  54. package/src/runtime/StateChartIndex.ts +6 -23
  55. package/src/types/GraphParamsProvider.ts +1 -4
  56. package/src/utils/BasisCurve.ts +5 -14
  57. package/src/utils/domToText.ts +2 -6
  58. package/src/utils/getPadding.ts +1 -2
  59. package/src/utils/newId.ts +2 -1
  60. package/src/utils/newRegistry.ts +12 -12
  61. package/src/utils/serializeAttrs.ts +3 -13
  62. package/src/utils/serializeCss.ts +1 -5
  63. package/src/utils/serializeStyle.ts +1 -4
  64. package/src/utils/toKebabCase.ts +1 -4
  65. package/dist/StateChart-BYBjTmC2.d.ts +0 -82
  66. package/dist/chunk-2LFUT2C6.js +0 -2691
  67. package/dist/chunk-ARZYBFNA.js +0 -133
  68. package/dist/chunk-CR2M4445.js +0 -608
  69. package/dist/chunk-FIQDLBWD.js +0 -9
  70. package/dist/chunk-GW2Z65BN.js +0 -429
  71. package/dist/chunk-PKBMQBKP.js +0 -5
  72. package/dist/chunk-RZ4FP6JB.js +0 -233
  73. package/dist/index-html-BBQqYoST.d.ts +0 -75
  74. package/src/full/index.ts +0 -1
  75. package/src/full/toFsmStateCharts.ts +0 -119
@@ -1,429 +0,0 @@
1
- import { __publicField } from './chunk-PKBMQBKP.js';
2
-
3
- // src/runtime/RuntimeStatechartApi.ts
4
- var RuntimeStatechartApi = class {
5
- constructor({
6
- element,
7
- statechart
8
- }) {
9
- __publicField(this, "element");
10
- __publicField(this, "statechart");
11
- __publicField(this, "_listenersCounter", 0);
12
- __publicField(this, "_transitionsClickListeners", {});
13
- __publicField(this, "_statesClickListeners", {});
14
- __publicField(this, "_registry", {});
15
- this.element = element;
16
- this.statechart = statechart;
17
- this._bindListeners();
18
- }
19
- close() {
20
- Object.values(this._registry).forEach((r) => r?.());
21
- this._registry = {};
22
- this._transitionsClickListeners = {};
23
- this._statesClickListeners = {};
24
- }
25
- onStateClick(listener) {
26
- return this._addListener(this._statesClickListeners, listener);
27
- }
28
- onTransitionClick(listener) {
29
- return this._addListener(this._transitionsClickListeners, listener);
30
- }
31
- openStatePanels() {
32
- this._setStatePanelStatus(`details[data-state-id]`, true);
33
- }
34
- closeStatePanels() {
35
- this._setStatePanelStatus(`details[data-state-id]`, false);
36
- }
37
- isStatePanelOpen(stateId) {
38
- const elm = this.element.querySelector(
39
- `details[data-state-id="${stateId}"]`
40
- );
41
- return elm && !!elm.open;
42
- }
43
- toggleState(...stateIds) {
44
- const lastId = stateIds[stateIds.length - 1];
45
- const selected = this.isStateSelected(lastId);
46
- this.deselectStates();
47
- this.closeStatePanels();
48
- this.activateStates(...stateIds);
49
- if (selected) {
50
- this.deselectState(lastId);
51
- this.closeStatePanel(lastId);
52
- }
53
- return !selected;
54
- }
55
- activateStates(...stateIds) {
56
- for (let i = 0; i < stateIds.length; i++) {
57
- const id = stateIds[i];
58
- this.openStatePanel(id);
59
- this.selectState(id);
60
- }
61
- }
62
- focusStates(...stateIds) {
63
- for (let i = 0; i < stateIds.length; i++) {
64
- const stateId = stateIds[i];
65
- for (const tagName of ["details", "g"]) {
66
- const elm = this.element.querySelector(
67
- `${tagName}[data-state-id="${stateId}"]`
68
- );
69
- elm?.scrollIntoView();
70
- }
71
- }
72
- }
73
- setStateDescription(stateId, description) {
74
- const descriptionContainer = this.element.querySelector(
75
- `details[data-state-id="${stateId}"] .state-details__description`
76
- );
77
- if (descriptionContainer) {
78
- descriptionContainer.innerHTML = "";
79
- descriptionContainer.append(description ?? "");
80
- }
81
- }
82
- closeStatePanel(stateId) {
83
- this._setStatePanelStatus(`details[data-state-id="${stateId}"]`, false);
84
- }
85
- openStatePanel(stateId) {
86
- this._setStatePanelStatus(`details[data-state-id="${stateId}"]`, true);
87
- }
88
- deselectTransitions(modifier = "selected") {
89
- this._removeTransitionsModifier("[data-transition-id]", modifier);
90
- }
91
- deselectTransition(id, modifier = "selected") {
92
- this._removeTransitionsModifier(`[data-transition-id="${id}"]`, modifier);
93
- }
94
- selectTransition(id, modifier = "selected") {
95
- this._addTransitionsModifier(`[data-transition-id="${id}"]`, modifier);
96
- }
97
- toggleTransition(id, modifier = "selected") {
98
- const selected = this.isTransitionSelected(id, modifier);
99
- this.deselectTransitions();
100
- if (!selected) {
101
- this.selectTransition(id, modifier);
102
- }
103
- }
104
- isTransitionSelected(id, modifier = "selected") {
105
- const elm = this.element.querySelector(`[data-transition-id="${id}"]`);
106
- const stateModifier = `transition--${modifier}`;
107
- return !!elm?.classList.contains(stateModifier);
108
- }
109
- deselectStates(modifier = "selected") {
110
- this._removeStateModifier("[data-state-id]", modifier);
111
- }
112
- isStateSelected(id, modifier = "selected") {
113
- const elm = this.element.querySelector(`[data-state-id="${id}"]`);
114
- const stateModifier = `state--${modifier}`;
115
- return !!elm?.classList.contains(stateModifier);
116
- }
117
- deselectState(id, modifier = "selected") {
118
- this._removeStateModifier(`[data-state-id="${id}"]`, modifier);
119
- }
120
- selectState(id, modifier = "selected") {
121
- this._addStateModifier(`[data-state-id="${id}"]`, modifier);
122
- }
123
- // Internal methods
124
- _addListener(index, listener) {
125
- const id = this._listenersCounter++;
126
- index[id] = listener;
127
- return () => {
128
- delete index[id];
129
- };
130
- }
131
- _bindListeners() {
132
- const bindListeners = (index, dataField, eventType) => {
133
- function newEventListener(index2, elm) {
134
- return (ev) => {
135
- ev.preventDefault();
136
- ev.stopPropagation();
137
- let id = elm.getAttribute(dataField);
138
- if (!id) {
139
- id = elm.closest(`[${dataField}]`)?.getAttribute(dataField);
140
- }
141
- if (id) {
142
- for (const listener of Object.values(index2)) {
143
- listener(id);
144
- }
145
- }
146
- };
147
- }
148
- [...this.element.querySelectorAll(`[${dataField}]`)].forEach((elm) => {
149
- const eventListener = newEventListener(index, elm);
150
- elm.addEventListener(eventType, eventListener);
151
- this._addListener(
152
- this._registry,
153
- () => elm.removeEventListener(eventType, eventListener)
154
- );
155
- });
156
- };
157
- bindListeners(this._statesClickListeners, "data-state-id", "click");
158
- bindListeners(
159
- this._transitionsClickListeners,
160
- "data-transition-id",
161
- "click"
162
- );
163
- }
164
- _setStatePanelStatus(selector, open) {
165
- [...this.element.querySelectorAll(selector)].forEach((elm) => {
166
- if (open) elm.setAttribute("open", "open");
167
- else elm.removeAttribute("open");
168
- });
169
- }
170
- _addStateModifier(cssSelector, modifier = "selected") {
171
- this._applyStateModifier(
172
- cssSelector,
173
- modifier,
174
- (elm, cls) => elm?.classList.add(cls)
175
- );
176
- }
177
- _removeStateModifier(cssSelector, modifier = "selected") {
178
- this._applyStateModifier(
179
- cssSelector,
180
- modifier,
181
- (elm, cls) => elm?.classList.remove(cls)
182
- );
183
- }
184
- _applyStateModifier(cssSelector, modifier = "selected", apply) {
185
- const detailsModifier = `state-details--${modifier}`;
186
- const stateLabelsModifier = `state-details__label--${modifier}`;
187
- const stateModifier = `state--${modifier}`;
188
- [...this.element.querySelectorAll(cssSelector)].forEach((elm) => {
189
- if (elm.tagName.toLowerCase() === "details") {
190
- apply(elm, detailsModifier);
191
- const labelElm = elm.querySelector(".state-details__label");
192
- if (labelElm) apply(labelElm, stateLabelsModifier);
193
- } else {
194
- apply(elm, stateModifier);
195
- }
196
- });
197
- }
198
- _addTransitionsModifier(cssSelector, modifier = "selected") {
199
- this._applyTransitionsModifier(
200
- cssSelector,
201
- modifier,
202
- (elm, cls) => elm?.classList.add(cls)
203
- );
204
- }
205
- _removeTransitionsModifier(cssSelector, modifier = "selected") {
206
- this._applyTransitionsModifier(
207
- cssSelector,
208
- modifier,
209
- (elm, cls) => elm?.classList.remove(cls)
210
- );
211
- }
212
- _applyTransitionsModifier(cssSelector, modifier = "selected", apply) {
213
- const transitionModifier = `transition--${modifier}`;
214
- const transitionLineModifier = `transition__line--${modifier}`;
215
- const transitionBoxModifier = `transition__box--${modifier}`;
216
- const transitionLabelModifier = `transition__label--${modifier}`;
217
- [...this.element.querySelectorAll(cssSelector)].forEach((elm) => {
218
- apply(elm, transitionModifier);
219
- apply(elm.querySelector(".transition__line"), transitionLineModifier);
220
- apply(elm.querySelector(".transition__box"), transitionBoxModifier);
221
- apply(elm.querySelector(".transition__label"), transitionLabelModifier);
222
- });
223
- }
224
- };
225
-
226
- // src/runtime/StateChartIndex.ts
227
- var StateChartIndex = class {
228
- constructor({
229
- statechart,
230
- initialStateKey = "<initial>",
231
- finalStateKey = "<final>"
232
- }) {
233
- __publicField(this, "statechart");
234
- __publicField(this, "_chartsIndex", {});
235
- __publicField(this, "_nodesIndex", {});
236
- __publicField(this, "_nodesParentsIndex", {});
237
- __publicField(this, "_edgeIndex", {});
238
- __publicField(this, "_edgesParentsIndex", {});
239
- __publicField(this, "initialStateKey");
240
- __publicField(this, "finalStateKey");
241
- this.statechart = statechart;
242
- this.initialStateKey = initialStateKey;
243
- this.finalStateKey = finalStateKey;
244
- this._buildIndexes();
245
- }
246
- /**
247
- * Returns a state node or a chart by the specified identifier.
248
- * @param id the id of a state node or a chart
249
- * @returns a state node or a chart
250
- */
251
- getNodeById(id) {
252
- return this._nodesIndex[id] || this._chartsIndex[id];
253
- }
254
- /**
255
- * Returns a chart by the specified identifier.
256
- * @param id the id of a state node or a chart
257
- * @returns a state node or a chart
258
- */
259
- getChartById(id) {
260
- return this._chartsIndex[id];
261
- }
262
- /**
263
- * Returns an edge by the specified identifier.
264
- * @param id the id of a graph edge
265
- * @returns a graph edge
266
- */
267
- getEdgeById(id) {
268
- return this._edgeIndex[id];
269
- }
270
- /**
271
- * Returns a list of all nodes in this chart.
272
- * @return a list of all nodes
273
- */
274
- getAllNodes() {
275
- return [
276
- .../* @__PURE__ */ new Set([
277
- ...Object.values(this._chartsIndex),
278
- ...Object.values(this._nodesIndex)
279
- ])
280
- ];
281
- }
282
- /**
283
- * Returns a list of all non-empty state nodes in this chart.
284
- * The result excludes nodes for initial and fina states.
285
- * @return a list of all non-empty state nodes
286
- */
287
- getStateNodes() {
288
- return this.getAllNodes().filter(
289
- (node) => node.key !== this.initialStateKey && node.key !== this.finalStateKey
290
- );
291
- }
292
- /**
293
- * Transforms a stack of state keys to the corresponding identifiers.
294
- * If a key in the stack was not found then this method returns
295
- * an empty stack.
296
- * @param stack a stack of state keys
297
- * @returns a stack of state identifiers for the given states
298
- */
299
- getStatesIds(...stack) {
300
- const result = [];
301
- let list = [this.statechart];
302
- for (let i = 0; list?.length > 0 && i < stack.length; i++) {
303
- const key = stack[i];
304
- const node = list.find((node2) => node2.key === key);
305
- if (!node) break;
306
- result.push(node.id);
307
- list = [...node.children || [], ...node.nodes || []];
308
- }
309
- return result.length === stack.length ? result : [];
310
- }
311
- /**
312
- * Returns graph nodes for the specified identifier.
313
- * @param id the id of a node
314
- * @returns a stack of nodes
315
- */
316
- getStackByStateId(id) {
317
- if (!id) return [];
318
- const node = this._chartsIndex[id] || this._nodesIndex[id];
319
- if (!node) return [];
320
- const parentId = this._nodesParentsIndex[id];
321
- if (parentId) {
322
- const parentStack = this.getStackByStateId(parentId);
323
- if (!parentStack.length) return [];
324
- parentStack.push(node);
325
- return parentStack;
326
- } else {
327
- return [node];
328
- }
329
- }
330
- /**
331
- * Returns an edge object corresponding to the transition from the state
332
- * @param stateId identifier of the source state
333
- * @param event an event triggering the transition
334
- * @returns graph edge
335
- */
336
- getTransition(stateId, event) {
337
- const stack = this.getStackByStateId(stateId);
338
- const state = stack.pop();
339
- if (!state || !stack.length) return;
340
- const parent = stack[stack.length - 1];
341
- const t = parent.edges.find(
342
- (t2) => t2.from === state.key && t2.event === event
343
- );
344
- return t;
345
- }
346
- /**
347
- * Returns a list of edge objects corresponding to all transitions from the state
348
- * @param stateId identifier of the source state
349
- * @returns a list of graph edges
350
- */
351
- getTransitions(stateId) {
352
- const stack = this.getStackByStateId(stateId);
353
- const state = stack.pop();
354
- if (!state || !stack.length) return [];
355
- const parent = stack[stack.length - 1];
356
- return parent.edges.filter((t) => t.from === state.key);
357
- }
358
- /**
359
- * Returns a graph node corresponding to the specified state id.
360
- * @param stateId identifier of the state
361
- * @returns graph node
362
- * @see getStateChart
363
- */
364
- getStateNode(stateId) {
365
- return stateId ? this._nodesIndex[stateId] : void 0;
366
- }
367
- /**
368
- * Returns a chart corresponding to the specified state id.
369
- * @param stateId identifier of the state
370
- * @returns graph node
371
- * @see getStateNode
372
- */
373
- getStateChart(stateId) {
374
- return stateId ? this._chartsIndex[stateId] : void 0;
375
- }
376
- /**
377
- * Returns ids of the previous and next state for the specified transition
378
- * @param transition a graph edge instance defining transition
379
- * @returns an array with two identifiers - [sourceStateId, targetStateId] - the source state id and target state id
380
- */
381
- getTransitionStateIds(transition) {
382
- const result = [
383
- void 0,
384
- void 0
385
- ];
386
- if (!transition) return result;
387
- const parentId = this._edgesParentsIndex[transition.id];
388
- if (!parentId) return result;
389
- const parent = this._chartsIndex[parentId];
390
- if (!parent) return result;
391
- parent.nodes.forEach((node) => {
392
- if (node.key === transition.from) {
393
- result[0] = node.id;
394
- }
395
- if (node.key === transition.to) {
396
- result[1] = node.id;
397
- }
398
- });
399
- return result;
400
- }
401
- // ----------------------------------------------------------
402
- // Internal methods
403
- _buildIndexes() {
404
- const addToIndex = (chart) => {
405
- const chartId = chart.id;
406
- this._chartsIndex[chartId] = chart;
407
- if (!(chartId in this._nodesIndex)) {
408
- this._nodesIndex[chartId] = chart;
409
- }
410
- chart.nodes.forEach((node) => {
411
- const nodeId = node.id;
412
- this._nodesIndex[nodeId] = node;
413
- this._nodesParentsIndex[nodeId] = chartId;
414
- });
415
- chart.edges.forEach((edge) => {
416
- const edgeId = edge.id;
417
- this._edgeIndex[edgeId] = edge;
418
- this._edgesParentsIndex[edgeId] = chartId;
419
- });
420
- (chart.children || []).forEach((child) => {
421
- this._nodesParentsIndex[child.id] = chartId;
422
- addToIndex(child);
423
- });
424
- };
425
- addToIndex(this.statechart);
426
- }
427
- };
428
-
429
- export { RuntimeStatechartApi, StateChartIndex };
@@ -1,5 +0,0 @@
1
- var __defProp = Object.defineProperty;
2
- var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
- var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
-
5
- export { __publicField };
@@ -1,233 +0,0 @@
1
- // src/dom/newTreeBuilder.ts
2
- function newTreeBuilder(context) {
3
- let level = -1;
4
- return (newLevel, ...params) => {
5
- while (level >= 0 && level >= newLevel) {
6
- context.exit(level--, ...params);
7
- }
8
- while (level < newLevel) {
9
- context.enter(++level, ...params);
10
- }
11
- };
12
- }
13
-
14
- // src/dom/buildSections.ts
15
- function buildSections(root) {
16
- const nodes = toDomNodesIterator(root);
17
- let top = null;
18
- let peek = null;
19
- const stack = [];
20
- const aligner = newTreeBuilder({
21
- enter(_level, header) {
22
- const section = {
23
- header,
24
- content: [],
25
- children: []
26
- };
27
- top = top || section;
28
- peek?.children.push(section);
29
- peek = section;
30
- stack.push(section);
31
- },
32
- exit() {
33
- stack.pop();
34
- peek = stack[stack.length - 1];
35
- }
36
- });
37
- aligner(0);
38
- const headerLevels = [];
39
- for (const node of nodes) {
40
- if (isDomElement(node)) {
41
- if (/^H[1-6]$/i.test(node.tagName)) {
42
- const headerLevel = +node.tagName.replace(/^H/, "");
43
- while (headerLevels.length > 0 && headerLevels[headerLevels.length - 1] >= headerLevel) {
44
- headerLevels.pop();
45
- }
46
- headerLevels.push(headerLevel);
47
- aligner(headerLevels.length, node);
48
- } else {
49
- peek.content.push(node);
50
- }
51
- } else {
52
- peek.content.push(node);
53
- }
54
- }
55
- return top.content.length === 0 && top.children.length === 1 && !top.header ? top.children[0] : top;
56
- }
57
- function* visitSectionNodes(section) {
58
- if (section.header) yield section.header;
59
- yield* section.content;
60
- for (const s of vistSections(section, true)) {
61
- yield* visitSectionNodes(s);
62
- }
63
- }
64
- function* vistSections(root, ignoreRoot = false) {
65
- !ignoreRoot && (yield root);
66
- for (const child of root.children) {
67
- yield* vistSections(child, false);
68
- }
69
- }
70
- function findSection(section, accept) {
71
- for (const s of vistSections(section)) {
72
- if (accept(s) === true) return s;
73
- }
74
- return void 0;
75
- }
76
- function isDomElement(node) {
77
- return node.nodeType === Node.ELEMENT_NODE;
78
- }
79
- function* toDomNodesIterator(root) {
80
- yield* root instanceof Node ? visitDom(root) : root;
81
- }
82
- function* visitDom(elm) {
83
- if (isDomElement(elm) && elm.tagName === "TEMPLATE") {
84
- elm = elm.content;
85
- }
86
- for (let node = elm.firstChild; node; node = node.nextSibling) {
87
- if (isDomElement(node)) {
88
- if (node.tagName === "DIV" || node.tagName === "TEMPLATE") {
89
- yield* visitDom(node);
90
- } else {
91
- yield node;
92
- }
93
- } else {
94
- yield node;
95
- }
96
- }
97
- }
98
-
99
- // src/dom/getStatesDescriptions.ts
100
- function* visitStateDescriptions({
101
- element,
102
- rootStateKey,
103
- removeFromDom = true,
104
- splitHeader = (header) => {
105
- if (!header) return [void 0, ""];
106
- const text = header.innerText.trim();
107
- let key;
108
- let label = text;
109
- text.replace(/^\s*\[(.*)\]\s*(.*)$/, (_, k, l) => {
110
- key = k.trim();
111
- label = l.trim() || key;
112
- return "";
113
- });
114
- return [key, label];
115
- }
116
- }) {
117
- const docSections = buildSections(element);
118
- const rootDescription = findSection(docSections, (section) => {
119
- if (!section.header) return false;
120
- const [key] = splitHeader(section.header);
121
- return key === rootStateKey;
122
- });
123
- if (!rootDescription) return;
124
- if (removeFromDom) {
125
- for (const node of visitSectionNodes(rootDescription)) {
126
- if (node.nodeName[0] === "#") continue;
127
- node.parentElement?.removeChild(node);
128
- }
129
- }
130
- for (const section of vistSections(rootDescription, false)) {
131
- if (!section.header) continue;
132
- const [state, title] = splitHeader(section.header);
133
- if (state)
134
- yield {
135
- state,
136
- title,
137
- ...section
138
- };
139
- }
140
- }
141
- function getStatesDescriptions(options) {
142
- const index = {};
143
- for (const description of visitStateDescriptions(options)) {
144
- index[description.state] = description;
145
- }
146
- return index;
147
- }
148
-
149
- // src/dom/description-panels.ts
150
- function getStateDescriptionRenderer(options) {
151
- const descriptionsIndex = getStatesDescriptions(options);
152
- return (statesStack) => {
153
- const stateKey = [...statesStack].pop();
154
- if (!stateKey) return;
155
- const section = descriptionsIndex[stateKey];
156
- if (!section) return;
157
- const elm = renderSections({
158
- section,
159
- deep: (_section) => false,
160
- // section.state !== options.rootStateKey, // ???
161
- header: (section2) => {
162
- if (section2.state === stateKey) {
163
- return section2.title || section2.state;
164
- }
165
- return;
166
- }
167
- });
168
- const details = elm?.querySelector("details");
169
- details && (details.open = true);
170
- return elm;
171
- };
172
- }
173
- function renderSections({
174
- section,
175
- deep = (_s) => true,
176
- header = (section2) => section2.header?.cloneNode(true)
177
- }) {
178
- const container = document.createElement("div");
179
- const id = `id-${String(Math.random()).split(".")[1]}-${Date.now()}`;
180
- container.setAttribute("id", id);
181
- if (!section) return container;
182
- const sectionView = renderSection(section);
183
- container.append(sectionView);
184
- const style = renderSectionStyles(id);
185
- container.append(style);
186
- return container;
187
- function renderSectionStyles(id2) {
188
- const prefix = id2 ? `#${id2}` : "";
189
- const style2 = document.createElement("style");
190
- container.appendChild(style2);
191
- style2.innerHTML = `
192
- ${prefix} details {
193
- border: 1px solid #aaa;
194
- border-radius: 4px;
195
- padding: 0.5em 0.5em 0;
196
- margin-bottom: 0.5em;
197
- }
198
-
199
- ${prefix} details > summary {
200
- font-weight: bold;
201
- margin: -0.5em -0.5em 0;
202
- padding: 0.5em;
203
- cursor: pointer;
204
- }
205
-
206
- ${prefix} details[open] {
207
- padding: 0.5em;
208
- }
209
- `;
210
- return style2;
211
- }
212
- function renderSection(section2) {
213
- const details = document.createElement("details");
214
- const summary = document.createElement("summary");
215
- details.appendChild(summary);
216
- const content = document.createElement("div");
217
- details.appendChild(content);
218
- const headerElm = header(section2);
219
- headerElm && summary.append(headerElm);
220
- for (const node of section2.content) {
221
- if (node.nodeName[0] === "#") continue;
222
- content.append(node.cloneNode(true));
223
- }
224
- if (deep(section2)) {
225
- for (const child of section2.children) {
226
- content.append(renderSection(child));
227
- }
228
- }
229
- return details;
230
- }
231
- }
232
-
233
- export { buildSections, findSection, getStateDescriptionRenderer, getStatesDescriptions, isDomElement, newTreeBuilder, renderSections, toDomNodesIterator, visitDom, visitSectionNodes, visitStateDescriptions, vistSections };