flexdesk 0.16.1 → 0.17.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/CHANGELOG.md +93 -0
- package/LICENSE +0 -0
- package/README.md +2217 -42
- package/THIRD_PARTY_LICENSES.md +0 -0
- package/css/base.css +1834 -75
- package/css/flexdesk.css +3146 -164
- package/css/overrides.css +16 -0
- package/css/reset.css +0 -0
- package/css/tokens.css +0 -0
- package/dist/canvas.js +6 -239
- package/dist/canvas.js.map +3 -3
- package/dist/charts.js +709 -18
- package/dist/charts.js.map +4 -4
- package/dist/chunk-3PHCPZHT.js +0 -0
- package/dist/chunk-3PHCPZHT.js.map +0 -0
- package/dist/chunk-4A7SJC3T.js +503 -0
- package/dist/chunk-4A7SJC3T.js.map +7 -0
- package/dist/{chunk-6JSOVNID.js → chunk-CVMCZZX2.js} +635 -10
- package/dist/chunk-CVMCZZX2.js.map +7 -0
- package/dist/chunk-D3COLZZ2.js +1311 -0
- package/dist/chunk-D3COLZZ2.js.map +7 -0
- package/dist/chunk-FOOS3T5L.js +0 -0
- package/dist/chunk-FOOS3T5L.js.map +0 -0
- package/dist/{chunk-SN4LSOAR.js → chunk-GOQLR5WR.js} +452 -2
- package/dist/chunk-GOQLR5WR.js.map +7 -0
- package/dist/{chunk-FL5KFNQH.js → chunk-HNU6MM2B.js} +52 -17
- package/dist/chunk-HNU6MM2B.js.map +7 -0
- package/dist/chunk-HYJYYEPK.js +375 -0
- package/dist/chunk-HYJYYEPK.js.map +7 -0
- package/dist/chunk-JKZLNKG6.js +2041 -0
- package/dist/chunk-JKZLNKG6.js.map +7 -0
- package/dist/chunk-JYWURG5T.js +0 -0
- package/dist/chunk-JYWURG5T.js.map +0 -0
- package/dist/{chunk-RQM5Z2MU.js → chunk-MCIXFNVF.js} +633 -311
- package/dist/chunk-MCIXFNVF.js.map +7 -0
- package/dist/chunk-N7HC3ADV.js +30 -0
- package/dist/chunk-N7HC3ADV.js.map +7 -0
- package/dist/{chunk-FBGP5KN5.js → chunk-Q36EPT2R.js} +3268 -203
- package/dist/chunk-Q36EPT2R.js.map +7 -0
- package/dist/chunk-QWQJUDPD.js +610 -0
- package/dist/chunk-QWQJUDPD.js.map +7 -0
- package/dist/{chunk-NLTOY57M.js → chunk-UURZ37SD.js} +28 -48
- package/dist/chunk-UURZ37SD.js.map +7 -0
- package/dist/{chunk-B5Q53LAJ.js → chunk-UWO43BZU.js} +2 -2
- package/dist/chunk-UWO43BZU.js.map +7 -0
- package/dist/chunk-WVFGV5FT.js +0 -0
- package/dist/chunk-WVFGV5FT.js.map +0 -0
- package/dist/core.js +170 -118
- package/dist/core.js.map +2 -2
- package/dist/editor.js +156 -70
- package/dist/editor.js.map +2 -2
- package/dist/flexdesk.css +3146 -164
- package/dist/flow.js +2789 -306
- package/dist/flow.js.map +4 -4
- package/dist/host.js +109 -3
- package/dist/host.js.map +3 -3
- package/dist/reset.css +0 -0
- package/dist/tile_registry-6WZPTUZV.js +0 -0
- package/dist/tile_registry-6WZPTUZV.js.map +0 -0
- package/dist/tiles.js +657 -234
- package/dist/tiles.js.map +4 -4
- package/dist/tokens.css +0 -0
- package/dist/widgets.js +3252 -2124
- package/dist/widgets.js.map +4 -4
- package/dist/wm.js +1227 -347
- package/dist/wm.js.map +4 -4
- package/package.json +3 -1
- package/src/canvas/canvas_adapter.js +5 -0
- package/src/canvas/edge_router.js +0 -0
- package/src/canvas/graph/connector_router.js +0 -0
- package/src/canvas/graph/history_service.js +0 -0
- package/src/canvas/graph/node_platform.js +0 -0
- package/src/canvas/index.js +1 -0
- package/src/canvas/layered_layout.js +244 -0
- package/src/charts/chart_types.js +0 -0
- package/src/charts/data_series_plot_window.js +0 -0
- package/src/charts/downsample.js +2 -2
- package/src/charts/plot_config.js +53 -29
- package/src/charts/plot_config_editor.js +627 -0
- package/src/charts/plot_grid.js +449 -0
- package/src/charts/plot_popout_window.js +103 -317
- package/src/charts/plotly_wrapper.js +22 -2
- package/src/charts/series_transforms.js +206 -0
- package/src/core/event_bus.js +0 -0
- package/src/core/logging.js +1 -1
- package/src/core/settings.js +105 -19
- package/src/core/state_guard.js +93 -51
- package/src/core/state_guard_config.js +85 -74
- package/src/core/state_machine.js +0 -0
- package/src/editor/editor_pane.js +3 -3
- package/src/editor/monaco_editor_factory.js +124 -60
- package/src/editor/monaco_loader.js +103 -28
- package/src/editor/notebook_search.js +0 -0
- package/src/editor/notebook_tab_bar.js +38 -52
- package/src/editor/notebook_undo_manager.js +0 -0
- package/src/editor/split_pane_container.js +6 -3
- package/src/flow/canvas_editor/connections.js +90 -0
- package/src/flow/canvas_editor/editor.js +2351 -153
- package/src/flow/canvas_editor/index.js +2 -1
- package/src/flow/canvas_editor/layout.js +119 -12
- package/src/flow/canvas_editor/strings.js +80 -0
- package/src/flow/kit/always_before.js +0 -0
- package/src/flow/kit/catalogue.js +97 -3
- package/src/flow/kit/chip_input.js +0 -0
- package/src/flow/kit/dom.js +0 -0
- package/src/flow/kit/findings.js +0 -0
- package/src/flow/kit/history.js +0 -0
- package/src/flow/kit/index.js +3 -3
- package/src/flow/kit/keys.js +7 -1
- package/src/flow/kit/logic_graph.js +97 -15
- package/src/flow/kit/references.js +0 -0
- package/src/flow/kit/settings_panel.js +0 -0
- package/src/flow/kit/settings_schema.js +2 -1
- package/src/flow/kit/step_picker.js +0 -0
- package/src/flow/kit/strings.js +3 -1
- package/src/flow/kit/value_picker.js +0 -0
- package/src/flow/kit/widgets.js +86 -109
- package/src/flow/lanes/editor.js +136 -14
- package/src/flow/lanes/index.js +3 -1
- package/src/flow/lanes/layout.js +0 -0
- package/src/flow/lanes/pipeline.js +44 -2
- package/src/flow/lanes/preview.js +0 -0
- package/src/flow/lanes/strings.js +1 -0
- package/src/flow/outline/editor.js +0 -0
- package/src/flow/outline/index.js +0 -0
- package/src/flow/outline/mapping.js +0 -0
- package/src/flow/outline/menu.js +0 -0
- package/src/flow/outline/operations.js +0 -0
- package/src/flow/outline/recognise.js +0 -0
- package/src/flow/outline/strings.js +0 -0
- package/src/help/help_modal.js +168 -42
- package/src/help/help_registry.js +12 -1
- package/src/host/external_links.js +0 -0
- package/src/host/file_picker.js +117 -0
- package/src/host/host.js +10 -2
- package/src/host/photino_host.js +9 -0
- package/src/host/photino_host.md +21 -3
- package/src/host/pywebview_host.js +10 -0
- package/src/tiles/chart_tiles.js +53 -245
- package/src/tiles/config_schema.js +8 -0
- package/src/tiles/figure_tile.js +322 -0
- package/src/tiles/layout_persistence.js +3 -3
- package/src/tiles/list_tiles.js +7 -7
- package/src/tiles/scope_picker.js +0 -0
- package/src/tiles/tile_base.js +1 -1
- package/src/tiles/tile_config_form.js +442 -0
- package/src/tiles/tile_grid.js +2 -0
- package/src/tiles/tile_registry.js +0 -0
- package/src/tiling/bottom_panel_tabs.js +67 -99
- package/src/tiling/command_palette.js +64 -19
- package/src/tiling/content_registry.js +4 -1
- package/src/tiling/desktops.js +11 -1
- package/src/tiling/entity_sources.js +0 -0
- package/src/tiling/keymap.js +403 -128
- package/src/tiling/kind_taxonomy.js +78 -0
- package/src/tiling/landing_table.js +0 -0
- package/src/tiling/loading_overlay.js +0 -0
- package/src/tiling/nav_panel.js +59 -10
- package/src/tiling/page_factory.js +5 -5
- package/src/tiling/panel_availability.js +49 -0
- package/src/tiling/panel_keys.js +0 -0
- package/src/tiling/shell.js +114 -12
- package/src/tiling/tab_strip.js +0 -0
- package/src/tiling/tile_breadcrumb.js +0 -0
- package/src/tiling/tile_renderer.js +105 -9
- package/src/tiling/tile_tab_menu.js +0 -0
- package/src/tiling/tile_tree.js +0 -0
- package/src/tiling/wm.js +562 -30
- package/src/tiling/zoom.js +0 -0
- package/src/ui/base/component_base.js +0 -0
- package/src/ui/base/controller_base.js +0 -0
- package/src/ui/base/page_base.js +0 -0
- package/src/ui/components/about_dialog.js +0 -0
- package/src/ui/components/action_dropdown.js +30 -2
- package/src/ui/components/alert_log.js +0 -0
- package/src/ui/components/alerts_pane.js +0 -0
- package/src/ui/components/attribute_list_editor.js +0 -0
- package/src/ui/components/autocomplete_field.js +0 -0
- package/src/ui/components/cell_editor_host.js +211 -0
- package/src/ui/components/cell_grid.js +648 -0
- package/src/ui/components/cell_selection.js +220 -0
- package/src/ui/components/choice_controls.js +351 -0
- package/src/ui/components/color_field.js +211 -0
- package/src/ui/components/color_list_field.js +210 -0
- package/src/ui/components/column_fit.js +0 -0
- package/src/ui/components/column_groups.js +314 -0
- package/src/ui/components/column_order.js +142 -0
- package/src/ui/components/computing_status_window.js +98 -25
- package/src/ui/components/confirm_dialog.js +81 -38
- package/src/ui/components/context_menu.js +2 -2
- package/src/ui/components/conversation_view.js +440 -0
- package/src/ui/components/crosstab.js +289 -0
- package/src/ui/components/data_table.js +601 -62
- package/src/ui/components/detail_header.js +22 -11
- package/src/ui/components/document_outline.js +397 -0
- package/src/ui/components/drag_reorder.js +0 -0
- package/src/ui/components/fact_table.js +0 -0
- package/src/ui/components/fill_handle.js +322 -0
- package/src/ui/components/gallery_picker.js +19 -8
- package/src/ui/components/header_actions.js +55 -0
- package/src/ui/components/inline_renamer.js +0 -0
- package/src/ui/components/job_progress.js +51 -0
- package/src/ui/components/managed_window.js +27 -4
- package/src/ui/components/menu_bar.js +745 -0
- package/src/ui/components/modal.js +449 -75
- package/src/ui/components/notification_history.js +3 -3
- package/src/ui/components/progress.js +483 -0
- package/src/ui/components/record_list.js +0 -0
- package/src/ui/components/row_activation.js +0 -0
- package/src/ui/components/section_stack.js +298 -0
- package/src/ui/components/series.js +173 -0
- package/src/ui/components/settings_view.js +634 -0
- package/src/ui/components/slide_out_panel.js +43 -6
- package/src/ui/components/slider_field.js +275 -18
- package/src/ui/components/sortable_list.js +0 -0
- package/src/ui/components/staged_edits.js +343 -0
- package/src/ui/components/staged_history.js +172 -0
- package/src/ui/components/table_filter_chips.js +0 -0
- package/src/ui/components/table_state_store.js +0 -0
- package/src/ui/components/table_structure.js +182 -0
- package/src/ui/components/table_values.js +0 -0
- package/src/ui/components/tabs.js +497 -0
- package/src/ui/components/tag_input.js +215 -0
- package/src/ui/components/toast.js +25 -8
- package/src/ui/components/toggle_field.js +175 -0
- package/src/ui/components/tree_view.js +55 -34
- package/src/ui/components/window_taskbar.js +0 -0
- package/src/ui/components/wizard.js +563 -0
- package/src/ui/controllers/window_chrome_controller.js +2 -2
- package/src/ui/notification_center.js +375 -119
- package/src/ui/utils/auto_scrollbars.js +0 -0
- package/src/ui/utils/markdown.js +709 -0
- package/src/ui/utils/native_context_menu.js +0 -0
- package/src/ui/utils/overlay_scrollbar.js +16 -12
- package/src/ui/utils/raf_resize_observer.js +0 -0
- package/src/ui/utils/scroll_lock.js +0 -0
- package/src/ui/utils/strip_scroll.js +55 -0
- package/src/ui/utils/tooltip_service.js +0 -8
- package/dist/chunk-6JSOVNID.js.map +0 -7
- package/dist/chunk-B5Q53LAJ.js.map +0 -7
- package/dist/chunk-FBGP5KN5.js.map +0 -7
- package/dist/chunk-FL5KFNQH.js.map +0 -7
- package/dist/chunk-NLTOY57M.js.map +0 -7
- package/dist/chunk-NNFTETK3.js +0 -633
- package/dist/chunk-NNFTETK3.js.map +0 -7
- package/dist/chunk-O5OHMWBB.js +0 -284
- package/dist/chunk-O5OHMWBB.js.map +0 -7
- package/dist/chunk-RQM5Z2MU.js.map +0 -7
- package/dist/chunk-SN4LSOAR.js.map +0 -7
- package/dist/chunk-W6FBJLPW.js +0 -367
- package/dist/chunk-W6FBJLPW.js.map +0 -7
- package/src/ui/controllers/panel_state_machine.js +0 -634
package/dist/core.js
CHANGED
|
@@ -2,6 +2,8 @@ import {
|
|
|
2
2
|
StateMachine
|
|
3
3
|
} from "./chunk-3PHCPZHT.js";
|
|
4
4
|
import {
|
|
5
|
+
DEFAULT_SETTINGS_STORAGE_KEY,
|
|
6
|
+
configureSettings,
|
|
5
7
|
createSettingsStore,
|
|
6
8
|
getAllSettings,
|
|
7
9
|
getCategories,
|
|
@@ -9,13 +11,15 @@ import {
|
|
|
9
11
|
getSchema,
|
|
10
12
|
getSetting,
|
|
11
13
|
getSettingsByCategory,
|
|
14
|
+
getSettingsStorageKey,
|
|
15
|
+
getSettingsStore,
|
|
12
16
|
registerSettings,
|
|
13
17
|
registerSettingsEventBus,
|
|
14
18
|
resetAllSettings,
|
|
15
19
|
resetCategory,
|
|
16
20
|
resetSetting,
|
|
17
21
|
setSetting
|
|
18
|
-
} from "./chunk-
|
|
22
|
+
} from "./chunk-HNU6MM2B.js";
|
|
19
23
|
import "./chunk-JYWURG5T.js";
|
|
20
24
|
|
|
21
25
|
// src/core/event_bus.js
|
|
@@ -213,7 +217,7 @@ var DEFAULT_NAMESPACE = "app";
|
|
|
213
217
|
var QUIET_MODE_LEVEL = "warn";
|
|
214
218
|
var LoggingService = class {
|
|
215
219
|
constructor({
|
|
216
|
-
name = "
|
|
220
|
+
name = "flexdesk",
|
|
217
221
|
eventBus = null,
|
|
218
222
|
minLevel = "info",
|
|
219
223
|
historyLimit = 500,
|
|
@@ -464,7 +468,6 @@ var DEFAULT_ALLOWED_ATTRIBUTES = Object.freeze([
|
|
|
464
468
|
"aria-busy",
|
|
465
469
|
"role",
|
|
466
470
|
"title",
|
|
467
|
-
"twm-has-tooltip",
|
|
468
471
|
"data-tooltip",
|
|
469
472
|
"data-help-topic"
|
|
470
473
|
]);
|
|
@@ -476,7 +479,6 @@ var DEFAULT_ALLOWED_DATASET_KEYS = Object.freeze([
|
|
|
476
479
|
"deleting",
|
|
477
480
|
// Notification center
|
|
478
481
|
"notification-id",
|
|
479
|
-
"notificationId",
|
|
480
482
|
// Plotly.js internal attributes (third-party charting library)
|
|
481
483
|
"unformatted",
|
|
482
484
|
"toggle",
|
|
@@ -491,56 +493,37 @@ var DEFAULT_ALLOWED_DATASET_KEYS = Object.freeze([
|
|
|
491
493
|
"group",
|
|
492
494
|
"trace",
|
|
493
495
|
"point",
|
|
494
|
-
"
|
|
495
|
-
"
|
|
496
|
+
"curve-number",
|
|
497
|
+
"point-number",
|
|
496
498
|
// UI state keys used by original HTML structure
|
|
497
499
|
"active-content",
|
|
498
|
-
"activeContent",
|
|
499
500
|
"panel-content",
|
|
500
|
-
"panelContent",
|
|
501
501
|
"collapsible-id",
|
|
502
|
-
"collapsibleId",
|
|
503
502
|
"collapsible-default",
|
|
504
|
-
"
|
|
505
|
-
"
|
|
506
|
-
"collapsibleHeader",
|
|
507
|
-
"twm-collapsible-content",
|
|
508
|
-
"collapsibleContent",
|
|
503
|
+
"collapsible-header",
|
|
504
|
+
"collapsible-content",
|
|
509
505
|
"collapsible-group",
|
|
510
|
-
"collapsibleGroup",
|
|
511
506
|
"collapsible-exclusive",
|
|
512
|
-
"collapsibleExclusive",
|
|
513
507
|
"collapsible-float",
|
|
514
|
-
"collapsibleFloat",
|
|
515
508
|
"collapsible-fill",
|
|
516
|
-
"collapsibleFill",
|
|
517
509
|
"tool",
|
|
518
510
|
"tab",
|
|
519
511
|
"role",
|
|
520
512
|
"op",
|
|
521
513
|
"func-name",
|
|
522
|
-
"funcName",
|
|
523
514
|
"func-expr",
|
|
524
|
-
"funcExpr",
|
|
525
515
|
"arity",
|
|
526
516
|
"tooltip",
|
|
527
|
-
"
|
|
528
|
-
"latexTooltip",
|
|
517
|
+
"latex-tooltip",
|
|
529
518
|
"node-type",
|
|
530
|
-
"
|
|
531
|
-
"twm-node-name",
|
|
532
|
-
"nodeName",
|
|
519
|
+
"node-name",
|
|
533
520
|
"lang",
|
|
534
521
|
"playback-control",
|
|
535
|
-
"playbackControl",
|
|
536
522
|
// Simulation/scenario state keys
|
|
537
523
|
"status",
|
|
538
524
|
"scenario-id",
|
|
539
|
-
"scenarioId",
|
|
540
525
|
"run-id",
|
|
541
|
-
"runId",
|
|
542
526
|
"run-state",
|
|
543
|
-
"runState",
|
|
544
527
|
"selected",
|
|
545
528
|
"active",
|
|
546
529
|
"disabled",
|
|
@@ -550,53 +533,33 @@ var DEFAULT_ALLOWED_DATASET_KEYS = Object.freeze([
|
|
|
550
533
|
"hidden",
|
|
551
534
|
// Node/canvas state keys
|
|
552
535
|
"node-id",
|
|
553
|
-
"nodeId",
|
|
554
536
|
"connector-id",
|
|
555
|
-
"connectorId",
|
|
556
537
|
"connector-type",
|
|
557
|
-
"connectorType",
|
|
558
538
|
"connection-id",
|
|
559
|
-
"connectionId",
|
|
560
539
|
"input-index",
|
|
561
|
-
"inputIndex",
|
|
562
540
|
"output-index",
|
|
563
|
-
"outputIndex",
|
|
564
541
|
"port-index",
|
|
565
|
-
"portIndex",
|
|
566
542
|
// Scenario editor keys
|
|
567
543
|
"source",
|
|
568
544
|
"series-id",
|
|
569
|
-
"seriesId",
|
|
570
545
|
"dataset-id",
|
|
571
|
-
"datasetId",
|
|
572
546
|
"mirror-input-bound",
|
|
573
|
-
"mirrorInputBound",
|
|
574
547
|
"mirror-change-bound",
|
|
575
|
-
"mirrorChangeBound",
|
|
576
548
|
"mirror-input",
|
|
577
|
-
"mirrorInput",
|
|
578
549
|
"bound",
|
|
579
550
|
"field",
|
|
580
551
|
"key",
|
|
581
552
|
"namespace",
|
|
582
553
|
"namespace-id",
|
|
583
|
-
"namespaceId",
|
|
584
554
|
"tab-id",
|
|
585
|
-
"tabId",
|
|
586
555
|
"param-id",
|
|
587
|
-
"paramId",
|
|
588
556
|
"target-id",
|
|
589
|
-
"targetId",
|
|
590
557
|
"override-type",
|
|
591
|
-
"overrideType",
|
|
592
558
|
// Tree view component keys
|
|
593
559
|
"item-id",
|
|
594
|
-
"itemId",
|
|
595
560
|
"category-id",
|
|
596
|
-
"categoryId",
|
|
597
561
|
// Calibration page keys
|
|
598
562
|
"info-for",
|
|
599
|
-
"infoFor",
|
|
600
563
|
"column",
|
|
601
564
|
// Data page keys
|
|
602
565
|
"readonly",
|
|
@@ -619,48 +582,101 @@ var DEFAULT_ALLOWED_DATASET_KEYS = Object.freeze([
|
|
|
619
582
|
"description",
|
|
620
583
|
// DSL generator keys
|
|
621
584
|
"dsl-state",
|
|
622
|
-
"dslState",
|
|
623
585
|
"dsl-section-registered",
|
|
624
|
-
"dslSectionRegistered",
|
|
625
586
|
"dsl-scrollbars-installed",
|
|
626
|
-
"dslScrollbarsInstalled",
|
|
627
587
|
"dsl-tabs-bound",
|
|
628
|
-
"dslTabsBound",
|
|
629
588
|
"dsl-controls-bound",
|
|
630
|
-
"dslControlsBound",
|
|
631
589
|
// Inline highlighter keys
|
|
632
590
|
"inline-hl",
|
|
633
|
-
"inlineHl",
|
|
634
|
-
"tooltip",
|
|
635
591
|
// Overlay scrollbar keys (UI-only, not state storage)
|
|
636
592
|
"scrollable",
|
|
637
593
|
"scrollable-x",
|
|
638
|
-
"scrollableX",
|
|
639
594
|
"scrollable-y",
|
|
640
|
-
"scrollableY",
|
|
641
595
|
// ManagedWindow component keys
|
|
642
596
|
"window-id",
|
|
643
|
-
"windowId",
|
|
644
597
|
// Help system keys
|
|
645
598
|
"help-topic",
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
599
|
+
// FlexDesk widgets: every literal data key written under src/ is listed
|
|
600
|
+
// here (tests/state_guard_defaults.test.mjs scans for them), so the
|
|
601
|
+
// shell, dialogs, forms, tooltips and editors pass a strict guard.
|
|
602
|
+
"accent",
|
|
603
|
+
"act",
|
|
604
|
+
"action-idx",
|
|
605
|
+
"action-value",
|
|
606
|
+
"add",
|
|
607
|
+
"category",
|
|
608
|
+
"code",
|
|
609
|
+
"data",
|
|
610
|
+
"direction",
|
|
611
|
+
"dismiss",
|
|
612
|
+
"entry",
|
|
613
|
+
"error",
|
|
614
|
+
"extra",
|
|
615
|
+
"flow",
|
|
616
|
+
"from",
|
|
617
|
+
"gap",
|
|
618
|
+
"group-id",
|
|
619
|
+
"item",
|
|
620
|
+
"kind",
|
|
621
|
+
"lane",
|
|
622
|
+
"leaf-id",
|
|
623
|
+
"level",
|
|
624
|
+
"list-action",
|
|
625
|
+
"match",
|
|
626
|
+
"mode",
|
|
627
|
+
"node",
|
|
628
|
+
"note-id",
|
|
629
|
+
"notification-summary",
|
|
630
|
+
"open",
|
|
631
|
+
"pager",
|
|
632
|
+
"pane",
|
|
633
|
+
"pane-id",
|
|
634
|
+
"parameter",
|
|
635
|
+
"placeholder",
|
|
636
|
+
"placement",
|
|
637
|
+
"port",
|
|
638
|
+
"record-key",
|
|
639
|
+
"ref",
|
|
640
|
+
"refusal",
|
|
641
|
+
"refusal-for",
|
|
642
|
+
"renameable",
|
|
643
|
+
"row-key",
|
|
644
|
+
"rule",
|
|
645
|
+
"scope",
|
|
646
|
+
"shape",
|
|
647
|
+
"slot",
|
|
648
|
+
"slot-idx",
|
|
649
|
+
"split-id",
|
|
650
|
+
"state",
|
|
651
|
+
"step",
|
|
652
|
+
"syntax",
|
|
653
|
+
"tile-id",
|
|
654
|
+
"tile-type",
|
|
655
|
+
"tip",
|
|
656
|
+
"to",
|
|
657
|
+
"tone",
|
|
658
|
+
"tooltip-max-width",
|
|
659
|
+
"tooltip-placement",
|
|
660
|
+
"twm-flow-item",
|
|
661
|
+
"twm-flow-title",
|
|
662
|
+
"twm-icon",
|
|
663
|
+
"twm-required",
|
|
664
|
+
"twm-tabs",
|
|
665
|
+
"twm-tail",
|
|
666
|
+
"verb"
|
|
656
667
|
]);
|
|
657
|
-
var DEFAULT_MODE = typeof window !== "undefined" && Boolean(window.__ECOSIM_DEBUG__) ? "strict" : "warn";
|
|
658
668
|
var DEFAULT_STATE_GUARD_CONFIG = Object.freeze({
|
|
659
|
-
mode:
|
|
669
|
+
mode: "warn",
|
|
660
670
|
allowedAttributes: DEFAULT_ALLOWED_ATTRIBUTES,
|
|
661
671
|
allowedAttributePrefixes: DEFAULT_ALLOWED_ATTRIBUTE_PREFIXES,
|
|
662
672
|
allowedDatasetKeys: DEFAULT_ALLOWED_DATASET_KEYS,
|
|
663
|
-
|
|
673
|
+
// FlexDesk ships no module overrides: which of YOUR modules may write which
|
|
674
|
+
// keys is yours to say, through `moduleOverrides` or `allow()`.
|
|
675
|
+
moduleOverrides: Object.freeze([]),
|
|
676
|
+
// null: a write is attributed to the frame that made it. A RegExp (or a
|
|
677
|
+
// literal string) picks the first frame from there up whose location
|
|
678
|
+
// matches instead; its first capture group, if any, names the module.
|
|
679
|
+
moduleFramePattern: null
|
|
664
680
|
});
|
|
665
681
|
function normalizeStateGuardConfig(config = {}) {
|
|
666
682
|
if (!config || typeof config !== "object") {
|
|
@@ -679,7 +695,8 @@ function normalizeStateGuardConfig(config = {}) {
|
|
|
679
695
|
),
|
|
680
696
|
moduleOverrides: normalizeOverrides(
|
|
681
697
|
config.moduleOverrides ?? DEFAULT_STATE_GUARD_CONFIG.moduleOverrides
|
|
682
|
-
)
|
|
698
|
+
),
|
|
699
|
+
moduleFramePattern: config.moduleFramePattern == null || config.moduleFramePattern === "" ? DEFAULT_STATE_GUARD_CONFIG.moduleFramePattern : patternToRegExp(config.moduleFramePattern)
|
|
683
700
|
};
|
|
684
701
|
}
|
|
685
702
|
function normalizeMode(mode) {
|
|
@@ -744,8 +761,10 @@ var HOOK_REGISTRY = {
|
|
|
744
761
|
datasetDescriptor: null,
|
|
745
762
|
datasetProxyCache: /* @__PURE__ */ new WeakMap()
|
|
746
763
|
};
|
|
747
|
-
var
|
|
764
|
+
var STACK_CACHE_LIMIT = 500;
|
|
765
|
+
var FRAME_LOCATION = /(?:\(|@|\bat\s+)([^()\s@][^()\s]*?):\d+(?::\d+)?\)?\s*$/;
|
|
748
766
|
var DATA_ATTRIBUTE_PREFIX = "data-";
|
|
767
|
+
var VIA_DOM_HOOK = /* @__PURE__ */ Symbol("state-guard:via-dom-hook");
|
|
749
768
|
var EVENT_CHANNELS = Object.freeze({
|
|
750
769
|
READY: "state-guard:ready",
|
|
751
770
|
VIOLATION: "state-guard:violation",
|
|
@@ -765,13 +784,15 @@ var StateGuardService = class {
|
|
|
765
784
|
this.mode = this.config.mode;
|
|
766
785
|
this.allowedAttributes = new Set(this.config.allowedAttributes.map((attr) => attr.toLowerCase()));
|
|
767
786
|
this.allowedAttributePrefixes = this.config.allowedAttributePrefixes.map((attr) => attr.toLowerCase());
|
|
768
|
-
this.allowedDatasetKeys = new Set(this.config.allowedDatasetKeys.map(
|
|
787
|
+
this.allowedDatasetKeys = new Set(this.config.allowedDatasetKeys.map(normalizeDatasetKey));
|
|
769
788
|
this.moduleOverrides = (this.config.moduleOverrides ?? []).map((entry) => ({
|
|
770
789
|
pattern: entry.pattern,
|
|
771
790
|
attributes: new Set(entry.attributes.map((attr) => attr.toLowerCase())),
|
|
772
|
-
datasetKeys: new Set(entry.datasetKeys.map(
|
|
791
|
+
datasetKeys: new Set(entry.datasetKeys.map(normalizeDatasetKey)),
|
|
773
792
|
attributePrefixes: entry.attributePrefixes.map((prefix) => prefix.toLowerCase())
|
|
774
793
|
}));
|
|
794
|
+
this.moduleFramePattern = this.config.moduleFramePattern;
|
|
795
|
+
this.stackCache = /* @__PURE__ */ new Map();
|
|
775
796
|
this.#installHooks();
|
|
776
797
|
}
|
|
777
798
|
setMode(mode) {
|
|
@@ -797,7 +818,7 @@ var StateGuardService = class {
|
|
|
797
818
|
const entry = {
|
|
798
819
|
pattern,
|
|
799
820
|
attributes: new Set(attributes.map((attr) => String(attr).toLowerCase())),
|
|
800
|
-
datasetKeys: new Set(datasetKeys.map(
|
|
821
|
+
datasetKeys: new Set(datasetKeys.map(normalizeDatasetKey)),
|
|
801
822
|
attributePrefixes: attributePrefixes.map((prefix) => String(prefix).toLowerCase())
|
|
802
823
|
};
|
|
803
824
|
this.moduleOverrides.push(entry);
|
|
@@ -837,7 +858,11 @@ var StateGuardService = class {
|
|
|
837
858
|
this.bypassDepth = Math.max(0, this.bypassDepth - 1);
|
|
838
859
|
}
|
|
839
860
|
}
|
|
840
|
-
|
|
861
|
+
/**
|
|
862
|
+
* Check one attribute write. The write is attributed to the caller of this
|
|
863
|
+
* method, or to the caller of the patched DOM API when it came through one.
|
|
864
|
+
*/
|
|
865
|
+
handleAttributeMutation(element, action, attribute, value, options = {}) {
|
|
841
866
|
const attrName = this.#normalizeAttribute(attribute);
|
|
842
867
|
if (!this.#shouldGuard(attrName)) {
|
|
843
868
|
return;
|
|
@@ -847,15 +872,19 @@ var StateGuardService = class {
|
|
|
847
872
|
attribute: attrName,
|
|
848
873
|
element,
|
|
849
874
|
value,
|
|
850
|
-
source: "attribute"
|
|
875
|
+
source: "attribute",
|
|
876
|
+
stack: new Error().stack,
|
|
877
|
+
writerFrame: options?.[VIA_DOM_HOOK] ? 2 : 1
|
|
851
878
|
});
|
|
852
879
|
}
|
|
853
|
-
handleDatasetMutation(element, key, value, { deleting = false } = {}) {
|
|
854
|
-
const attrName =
|
|
880
|
+
handleDatasetMutation(element, key, value, { deleting = false, [VIA_DOM_HOOK]: viaHook = false } = {}) {
|
|
881
|
+
const attrName = datasetKeyToAttribute(key);
|
|
855
882
|
if (!this.#shouldGuard(attrName)) {
|
|
856
883
|
return;
|
|
857
884
|
}
|
|
858
885
|
this.#evaluateMutation({
|
|
886
|
+
stack: new Error().stack,
|
|
887
|
+
writerFrame: viaHook ? 2 : 1,
|
|
859
888
|
action: deleting ? "dataset:delete" : "dataset:set",
|
|
860
889
|
attribute: attrName,
|
|
861
890
|
element,
|
|
@@ -902,8 +931,8 @@ var StateGuardService = class {
|
|
|
902
931
|
}
|
|
903
932
|
return true;
|
|
904
933
|
}
|
|
905
|
-
#evaluateMutation({ action, attribute, element, value, source }) {
|
|
906
|
-
const moduleKey = this.#resolveModuleFromStack();
|
|
934
|
+
#evaluateMutation({ action, attribute, element, value, source, stack, writerFrame }) {
|
|
935
|
+
const moduleKey = this.#resolveModuleFromStack(stack, writerFrame);
|
|
907
936
|
if (this.#isAllowedForModule(moduleKey, attribute)) {
|
|
908
937
|
return;
|
|
909
938
|
}
|
|
@@ -955,37 +984,48 @@ var StateGuardService = class {
|
|
|
955
984
|
}
|
|
956
985
|
return String(attribute).toLowerCase();
|
|
957
986
|
}
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
#resolveModuleFromStack() {
|
|
969
|
-
const stack = new Error().stack;
|
|
987
|
+
/**
|
|
988
|
+
* The module a write is attributed to. `stack` was captured in a
|
|
989
|
+
* handle*Mutation method (frame 0); `writerFrame` is the index of the frame
|
|
990
|
+
* that made the write (1 for a direct call, 2 through a DOM hook). Without a
|
|
991
|
+
* `moduleFramePattern` that writer's location (its URL or path, line and
|
|
992
|
+
* column dropped) is the module. With one, the first frame from the writer
|
|
993
|
+
* up whose location matches is used, and the module is the pattern's first
|
|
994
|
+
* capture group, or that frame's whole location when it has none.
|
|
995
|
+
*/
|
|
996
|
+
#resolveModuleFromStack(stack, writerFrame) {
|
|
970
997
|
if (!stack) {
|
|
971
998
|
return null;
|
|
972
999
|
}
|
|
973
|
-
|
|
974
|
-
|
|
1000
|
+
const cacheKey = `${writerFrame}
|
|
1001
|
+
${stack}`;
|
|
1002
|
+
if (this.stackCache.has(cacheKey)) {
|
|
1003
|
+
return this.stackCache.get(cacheKey);
|
|
975
1004
|
}
|
|
976
|
-
const
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
const match = line.match(/(js_new\/[^)\s]+)/);
|
|
1005
|
+
const locations = [];
|
|
1006
|
+
for (const line of String(stack).split("\n")) {
|
|
1007
|
+
const match = line.match(FRAME_LOCATION);
|
|
980
1008
|
if (match) {
|
|
981
|
-
|
|
982
|
-
break;
|
|
1009
|
+
locations.push(match[1]);
|
|
983
1010
|
}
|
|
984
1011
|
}
|
|
985
|
-
|
|
986
|
-
|
|
1012
|
+
const callers = locations.slice(writerFrame);
|
|
1013
|
+
let modulePath = null;
|
|
1014
|
+
if (!this.moduleFramePattern) {
|
|
1015
|
+
modulePath = callers[0] ?? null;
|
|
1016
|
+
} else {
|
|
1017
|
+
for (const location of callers) {
|
|
1018
|
+
const match = location.match(this.moduleFramePattern);
|
|
1019
|
+
if (match) {
|
|
1020
|
+
modulePath = match[1] ?? location;
|
|
1021
|
+
break;
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
}
|
|
1025
|
+
if (this.stackCache.size > STACK_CACHE_LIMIT) {
|
|
1026
|
+
this.stackCache.clear();
|
|
987
1027
|
}
|
|
988
|
-
|
|
1028
|
+
this.stackCache.set(cacheKey, modulePath);
|
|
989
1029
|
return modulePath;
|
|
990
1030
|
}
|
|
991
1031
|
#previewValue(value) {
|
|
@@ -999,6 +1039,19 @@ var StateGuardService = class {
|
|
|
999
1039
|
return str.length > 50 ? `${str.slice(0, 47)}...` : str;
|
|
1000
1040
|
}
|
|
1001
1041
|
};
|
|
1042
|
+
function datasetKeyToAttribute(key) {
|
|
1043
|
+
if (!key && key !== 0) {
|
|
1044
|
+
return "";
|
|
1045
|
+
}
|
|
1046
|
+
const normalized = String(key).replace(/([A-Z])/g, "-$1").replace(/[^a-zA-Z0-9_-]/g, "-").toLowerCase().replace(/-{2,}/g, "-").replace(/^-+/, "").replace(/-+$/, "");
|
|
1047
|
+
if (!normalized) {
|
|
1048
|
+
return "";
|
|
1049
|
+
}
|
|
1050
|
+
return `${DATA_ATTRIBUTE_PREFIX}${normalized}`;
|
|
1051
|
+
}
|
|
1052
|
+
function normalizeDatasetKey(key) {
|
|
1053
|
+
return datasetKeyToAttribute(key).slice(DATA_ATTRIBUTE_PREFIX.length);
|
|
1054
|
+
}
|
|
1002
1055
|
function installDomHooks(service) {
|
|
1003
1056
|
if (HOOK_REGISTRY.installed) {
|
|
1004
1057
|
HOOK_REGISTRY.service = service;
|
|
@@ -1013,20 +1066,12 @@ function installDomHooks(service) {
|
|
|
1013
1066
|
HOOK_REGISTRY.originals.removeAttribute = nativeRemoveAttribute;
|
|
1014
1067
|
Element.prototype.setAttribute = function patchedSetAttribute(name, value) {
|
|
1015
1068
|
const guard = HOOK_REGISTRY.service;
|
|
1016
|
-
|
|
1017
|
-
guard?.handleAttributeMutation(this, "setAttribute", name, value);
|
|
1018
|
-
} catch (error) {
|
|
1019
|
-
throw error;
|
|
1020
|
-
}
|
|
1069
|
+
guard?.handleAttributeMutation(this, "setAttribute", name, value, { [VIA_DOM_HOOK]: true });
|
|
1021
1070
|
return nativeSetAttribute.call(this, name, value);
|
|
1022
1071
|
};
|
|
1023
1072
|
Element.prototype.removeAttribute = function patchedRemoveAttribute(name) {
|
|
1024
1073
|
const guard = HOOK_REGISTRY.service;
|
|
1025
|
-
|
|
1026
|
-
guard?.handleAttributeMutation(this, "removeAttribute", name, void 0);
|
|
1027
|
-
} catch (error) {
|
|
1028
|
-
throw error;
|
|
1029
|
-
}
|
|
1074
|
+
guard?.handleAttributeMutation(this, "removeAttribute", name, void 0, { [VIA_DOM_HOOK]: true });
|
|
1030
1075
|
return nativeRemoveAttribute.call(this, name);
|
|
1031
1076
|
};
|
|
1032
1077
|
wrapDataset(service);
|
|
@@ -1056,7 +1101,7 @@ function wrapDataset(service) {
|
|
|
1056
1101
|
const guard = HOOK_REGISTRY.service;
|
|
1057
1102
|
const key = typeof prop === "string" ? prop : null;
|
|
1058
1103
|
if (guard && key) {
|
|
1059
|
-
guard.handleDatasetMutation(proxyState.element, key, value);
|
|
1104
|
+
guard.handleDatasetMutation(proxyState.element, key, value, { [VIA_DOM_HOOK]: true });
|
|
1060
1105
|
}
|
|
1061
1106
|
return Reflect.set(target, prop, value);
|
|
1062
1107
|
},
|
|
@@ -1064,7 +1109,10 @@ function wrapDataset(service) {
|
|
|
1064
1109
|
const guard = HOOK_REGISTRY.service;
|
|
1065
1110
|
const key = typeof prop === "string" ? prop : null;
|
|
1066
1111
|
if (guard && key) {
|
|
1067
|
-
guard.handleDatasetMutation(proxyState.element, key, void 0, {
|
|
1112
|
+
guard.handleDatasetMutation(proxyState.element, key, void 0, {
|
|
1113
|
+
deleting: true,
|
|
1114
|
+
[VIA_DOM_HOOK]: true
|
|
1115
|
+
});
|
|
1068
1116
|
}
|
|
1069
1117
|
return Reflect.deleteProperty(target, prop);
|
|
1070
1118
|
}
|
|
@@ -1075,11 +1123,13 @@ function wrapDataset(service) {
|
|
|
1075
1123
|
});
|
|
1076
1124
|
}
|
|
1077
1125
|
export {
|
|
1126
|
+
DEFAULT_SETTINGS_STORAGE_KEY,
|
|
1078
1127
|
DEFAULT_STATE_GUARD_CONFIG,
|
|
1079
1128
|
EventBus,
|
|
1080
1129
|
LoggingService,
|
|
1081
1130
|
StateGuardService,
|
|
1082
1131
|
StateMachine,
|
|
1132
|
+
configureSettings,
|
|
1083
1133
|
createSettingsStore,
|
|
1084
1134
|
getAllSettings,
|
|
1085
1135
|
getCategories,
|
|
@@ -1087,6 +1137,8 @@ export {
|
|
|
1087
1137
|
getSchema,
|
|
1088
1138
|
getSetting,
|
|
1089
1139
|
getSettingsByCategory,
|
|
1140
|
+
getSettingsStorageKey,
|
|
1141
|
+
getSettingsStore,
|
|
1090
1142
|
normalizeStateGuardConfig,
|
|
1091
1143
|
registerSettings,
|
|
1092
1144
|
registerSettingsEventBus,
|