flexdesk 0.14.1 → 0.15.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.
Files changed (189) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +35 -3
  3. package/THIRD_PARTY_LICENSES.md +0 -0
  4. package/css/base.css +0 -0
  5. package/css/flexdesk.css +34 -0
  6. package/css/overrides.css +0 -0
  7. package/css/reset.css +0 -0
  8. package/css/tokens.css +0 -0
  9. package/dist/canvas.js +0 -0
  10. package/dist/canvas.js.map +0 -0
  11. package/dist/charts.js +0 -0
  12. package/dist/charts.js.map +0 -0
  13. package/dist/chunk-3PHCPZHT.js +0 -0
  14. package/dist/chunk-3PHCPZHT.js.map +0 -0
  15. package/dist/chunk-6JSOVNID.js +0 -0
  16. package/dist/chunk-6JSOVNID.js.map +0 -0
  17. package/dist/chunk-CWPMLX67.js +0 -0
  18. package/dist/chunk-CWPMLX67.js.map +0 -0
  19. package/dist/chunk-FBGP5KN5.js +0 -0
  20. package/dist/chunk-FBGP5KN5.js.map +0 -0
  21. package/dist/chunk-FL5KFNQH.js +0 -0
  22. package/dist/chunk-FL5KFNQH.js.map +0 -0
  23. package/dist/chunk-FOOS3T5L.js +0 -0
  24. package/dist/chunk-FOOS3T5L.js.map +0 -0
  25. package/dist/chunk-JYWURG5T.js +0 -0
  26. package/dist/chunk-JYWURG5T.js.map +0 -0
  27. package/dist/chunk-NLTOY57M.js +0 -0
  28. package/dist/chunk-NLTOY57M.js.map +0 -0
  29. package/dist/chunk-NNFTETK3.js +0 -0
  30. package/dist/chunk-NNFTETK3.js.map +0 -0
  31. package/dist/chunk-O5OHMWBB.js +0 -0
  32. package/dist/chunk-O5OHMWBB.js.map +0 -0
  33. package/dist/chunk-RQM5Z2MU.js +0 -0
  34. package/dist/chunk-RQM5Z2MU.js.map +0 -0
  35. package/dist/chunk-SN4LSOAR.js +0 -0
  36. package/dist/chunk-SN4LSOAR.js.map +0 -0
  37. package/dist/chunk-WVFGV5FT.js +0 -0
  38. package/dist/chunk-WVFGV5FT.js.map +0 -0
  39. package/dist/core.js +0 -0
  40. package/dist/core.js.map +0 -0
  41. package/dist/editor.js +0 -0
  42. package/dist/editor.js.map +0 -0
  43. package/dist/flexdesk.css +34 -0
  44. package/dist/flow.js +0 -0
  45. package/dist/flow.js.map +0 -0
  46. package/dist/host.js +28 -5
  47. package/dist/host.js.map +2 -2
  48. package/dist/reset.css +0 -0
  49. package/dist/tile_registry-6WZPTUZV.js +0 -0
  50. package/dist/tile_registry-6WZPTUZV.js.map +0 -0
  51. package/dist/tiles.js +0 -0
  52. package/dist/tiles.js.map +0 -0
  53. package/dist/tokens.css +0 -0
  54. package/dist/widgets.js +100 -9
  55. package/dist/widgets.js.map +2 -2
  56. package/dist/wm.js +0 -0
  57. package/dist/wm.js.map +0 -0
  58. package/package.json +1 -1
  59. package/src/canvas/canvas_adapter.js +0 -0
  60. package/src/canvas/edge_router.js +0 -0
  61. package/src/canvas/graph/connector_router.js +0 -0
  62. package/src/canvas/graph/history_service.js +0 -0
  63. package/src/canvas/graph/node_platform.js +0 -0
  64. package/src/canvas/index.js +0 -0
  65. package/src/charts/chart_types.js +0 -0
  66. package/src/charts/data_series_plot_window.js +0 -0
  67. package/src/charts/downsample.js +0 -0
  68. package/src/charts/plot_config.js +0 -0
  69. package/src/charts/plot_popout_window.js +0 -0
  70. package/src/charts/plotly_wrapper.js +0 -0
  71. package/src/core/event_bus.js +0 -0
  72. package/src/core/logging.js +0 -0
  73. package/src/core/settings.js +0 -0
  74. package/src/core/state_guard.js +0 -0
  75. package/src/core/state_guard_config.js +0 -0
  76. package/src/core/state_machine.js +0 -0
  77. package/src/editor/editor_pane.js +0 -0
  78. package/src/editor/monaco_editor_factory.js +0 -0
  79. package/src/editor/monaco_loader.js +0 -0
  80. package/src/editor/notebook_search.js +0 -0
  81. package/src/editor/notebook_tab_bar.js +0 -0
  82. package/src/editor/notebook_undo_manager.js +0 -0
  83. package/src/editor/split_pane_container.js +0 -0
  84. package/src/flow/canvas_editor/editor.js +0 -0
  85. package/src/flow/canvas_editor/index.js +0 -0
  86. package/src/flow/canvas_editor/layout.js +0 -0
  87. package/src/flow/canvas_editor/strings.js +0 -0
  88. package/src/flow/kit/always_before.js +0 -0
  89. package/src/flow/kit/catalogue.js +0 -0
  90. package/src/flow/kit/chip_input.js +0 -0
  91. package/src/flow/kit/dom.js +0 -0
  92. package/src/flow/kit/findings.js +0 -0
  93. package/src/flow/kit/history.js +0 -0
  94. package/src/flow/kit/index.js +0 -0
  95. package/src/flow/kit/keys.js +0 -0
  96. package/src/flow/kit/logic_graph.js +0 -0
  97. package/src/flow/kit/references.js +0 -0
  98. package/src/flow/kit/settings_panel.js +0 -0
  99. package/src/flow/kit/settings_schema.js +0 -0
  100. package/src/flow/kit/step_picker.js +0 -0
  101. package/src/flow/kit/strings.js +0 -0
  102. package/src/flow/kit/value_picker.js +0 -0
  103. package/src/flow/kit/widgets.js +0 -0
  104. package/src/flow/lanes/editor.js +0 -0
  105. package/src/flow/lanes/index.js +0 -0
  106. package/src/flow/lanes/layout.js +0 -0
  107. package/src/flow/lanes/pipeline.js +0 -0
  108. package/src/flow/lanes/preview.js +0 -0
  109. package/src/flow/lanes/strings.js +0 -0
  110. package/src/flow/outline/editor.js +0 -0
  111. package/src/flow/outline/index.js +0 -0
  112. package/src/flow/outline/mapping.js +0 -0
  113. package/src/flow/outline/menu.js +0 -0
  114. package/src/flow/outline/operations.js +0 -0
  115. package/src/flow/outline/recognise.js +0 -0
  116. package/src/flow/outline/strings.js +0 -0
  117. package/src/help/help_modal.js +0 -0
  118. package/src/help/help_registry.js +0 -0
  119. package/src/host/host.js +2 -1
  120. package/src/host/photino_host.js +31 -3
  121. package/src/host/photino_host.md +56 -3
  122. package/src/host/pywebview_host.js +0 -0
  123. package/src/tiles/chart_tiles.js +0 -0
  124. package/src/tiles/config_schema.js +0 -0
  125. package/src/tiles/layout_persistence.js +0 -0
  126. package/src/tiles/tile_base.js +0 -0
  127. package/src/tiles/tile_grid.js +0 -0
  128. package/src/tiles/tile_registry.js +0 -0
  129. package/src/tiling/bottom_panel_tabs.js +0 -0
  130. package/src/tiling/command_palette.js +0 -0
  131. package/src/tiling/content_registry.js +0 -0
  132. package/src/tiling/desktops.js +0 -0
  133. package/src/tiling/entity_sources.js +0 -0
  134. package/src/tiling/keymap.js +0 -0
  135. package/src/tiling/kind_taxonomy.js +0 -0
  136. package/src/tiling/landing_table.js +0 -0
  137. package/src/tiling/loading_overlay.js +0 -0
  138. package/src/tiling/nav_panel.js +0 -0
  139. package/src/tiling/page_factory.js +0 -0
  140. package/src/tiling/panel_keys.js +0 -0
  141. package/src/tiling/shell.js +0 -0
  142. package/src/tiling/tab_strip.js +0 -0
  143. package/src/tiling/tile_breadcrumb.js +0 -0
  144. package/src/tiling/tile_renderer.js +0 -0
  145. package/src/tiling/tile_tab_menu.js +0 -0
  146. package/src/tiling/tile_tree.js +0 -0
  147. package/src/tiling/wm.js +0 -0
  148. package/src/tiling/zoom.js +0 -0
  149. package/src/ui/base/component_base.js +0 -0
  150. package/src/ui/base/controller_base.js +0 -0
  151. package/src/ui/base/page_base.js +0 -0
  152. package/src/ui/components/about_dialog.js +0 -0
  153. package/src/ui/components/action_dropdown.js +0 -0
  154. package/src/ui/components/alert_log.js +0 -0
  155. package/src/ui/components/alerts_pane.js +0 -0
  156. package/src/ui/components/attribute_list_editor.js +0 -0
  157. package/src/ui/components/autocomplete_field.js +0 -0
  158. package/src/ui/components/column_fit.js +0 -0
  159. package/src/ui/components/computing_status_window.js +0 -0
  160. package/src/ui/components/confirm_dialog.js +0 -0
  161. package/src/ui/components/context_menu.js +0 -0
  162. package/src/ui/components/data_table.js +0 -0
  163. package/src/ui/components/detail_header.js +0 -0
  164. package/src/ui/components/drag_reorder.js +0 -0
  165. package/src/ui/components/fact_table.js +0 -0
  166. package/src/ui/components/gallery_picker.js +0 -0
  167. package/src/ui/components/inline_renamer.js +0 -0
  168. package/src/ui/components/managed_window.js +0 -0
  169. package/src/ui/components/modal.js +0 -0
  170. package/src/ui/components/notification_history.js +0 -0
  171. package/src/ui/components/record_list.js +0 -0
  172. package/src/ui/components/row_activation.js +0 -0
  173. package/src/ui/components/slide_out_panel.js +0 -0
  174. package/src/ui/components/slider_field.js +0 -0
  175. package/src/ui/components/sortable_list.js +0 -0
  176. package/src/ui/components/table_filter_chips.js +0 -0
  177. package/src/ui/components/table_state_store.js +0 -0
  178. package/src/ui/components/table_values.js +0 -0
  179. package/src/ui/components/toast.js +0 -0
  180. package/src/ui/components/tree_view.js +0 -0
  181. package/src/ui/components/window_taskbar.js +0 -0
  182. package/src/ui/controllers/panel_state_machine.js +0 -0
  183. package/src/ui/controllers/window_chrome_controller.js +106 -11
  184. package/src/ui/notification_center.js +0 -0
  185. package/src/ui/utils/auto_scrollbars.js +0 -0
  186. package/src/ui/utils/overlay_scrollbar.js +0 -0
  187. package/src/ui/utils/raf_resize_observer.js +0 -0
  188. package/src/ui/utils/scroll_lock.js +0 -0
  189. package/src/ui/utils/tooltip_service.js +0 -0
@@ -8,10 +8,29 @@
8
8
  * - F11 fullscreen toggle
9
9
  *
10
10
  * Talks to the embedder ONLY through a Host's `window` capability
11
- * (see ui/js/host/host.js). A host with no `window` capability — a browser
11
+ * (see src/host/host.js). A host with no `window` capability — a browser
12
12
  * tab, a VS Code webview, the standalone demo — is legal: we simply don't
13
13
  * install custom chrome. That degraded path is also the production path on
14
14
  * Linux, macOS and `--browser`, where the OS/browser draws the title bar.
15
+ *
16
+ * THREE MODES, decided by `host.window.chrome()` (which may answer with a
17
+ * promise: the Photino host asks its native side): a browser tab and a window
18
+ * with native chrome get NOTHING from this class (no handles, no buttons, no
19
+ * body class), and only a window that answers `custom` gets the chrome.
20
+ *
21
+ * NATIVE GESTURES. A host that offers `startNativeDrag()` and
22
+ * `startNativeResize(edge)` gets drags on the top bar and presses on the
23
+ * resize handles handed to the OS, which brings snapping and a resize that
24
+ * keeps up with the pointer. A host without them gets the JS move and resize
25
+ * over getBounds/setBounds.
26
+ *
27
+ * @param {object} [opts]
28
+ * @param {object} [opts.host] a Host; only its `window` capability is used
29
+ * @param {string|Element} [opts.topBar='.twm-global-top-bar'] the bar that drags the window
30
+ * @param {string|Element} [opts.controls] where to draw minimise/maximise/close when
31
+ * the page has no `#win-minimize`/`#win-maximize`/`#win-close` of its own
32
+ * (default: the top bar's `.twm-bar-right`, else the top bar itself)
33
+ * @param {string} [opts.noDrag] more selectors that never start a drag
15
34
  */
16
35
 
17
36
  const SUPPORTS_POINTER = typeof window !== 'undefined' && 'onpointerdown' in window;
@@ -20,9 +39,13 @@ const MIN_HEIGHT = 350;
20
39
  const DRAG_THRESHOLD = 4;
21
40
 
22
41
  export class WindowChromeController {
23
- constructor({ eventBus, logger, host } = {}) {
42
+ constructor({ eventBus, logger, host, topBar = '.twm-global-top-bar', controls = null, noDrag = '' } = {}) {
24
43
  this.eventBus = eventBus;
25
44
  this.logger = logger || console;
45
+ this._topBarOpt = topBar;
46
+ this._controlsOpt = controls;
47
+ this._noDrag = noDrag;
48
+ this._createdControls = null;
26
49
 
27
50
  // The host's window capability, or null. Never throw on a missing
28
51
  // one — see the class comment.
@@ -40,17 +63,22 @@ export class WindowChromeController {
40
63
  /**
41
64
  * Initialize the window chrome controller
42
65
  */
43
- initialize() {
44
- if (this._disposed) return;
66
+ async initialize() {
67
+ if (this._disposed) return false;
45
68
 
46
- if (!this.win || this.win.chrome() !== 'custom') {
69
+ let chrome = 'native';
70
+ try { chrome = this.win ? await this.win.chrome() : 'native'; } catch (_) { chrome = 'native'; }
71
+ if (this._disposed) return false;
72
+ if (chrome !== 'custom') {
47
73
  // Native window decorations (Linux/macOS) or the browser already
48
74
  // provide a title bar + window controls; our custom chrome would be
49
75
  // a redundant second set. Skip it entirely.
50
76
  this.logger.info?.('[WindowChrome] Native/browser chrome detected — custom window chrome disabled');
51
- return;
77
+ return false;
52
78
  }
53
79
 
80
+ document.body.classList.add('twm-custom-chrome');
81
+ this.#createWindowControls();
54
82
  this.#wireWindowButtons();
55
83
  this.#createResizeHandles();
56
84
  this.#wireTopBarDrag();
@@ -59,6 +87,47 @@ export class WindowChromeController {
59
87
  this.#initializeState();
60
88
 
61
89
  this.logger.info?.('[WindowChrome] Initialized');
90
+ return true;
91
+ }
92
+
93
+ /** An element from a selector or an element; null when there is none. */
94
+ #resolve(target, within = document) {
95
+ if (!target) return null;
96
+ if (typeof target !== 'string') return target;
97
+ return within.querySelector(target);
98
+ }
99
+
100
+ /**
101
+ * Draw minimise, maximise/restore and close, unless the page has its own
102
+ * `#win-*` buttons (EcoSim's markup), which are then wired instead.
103
+ */
104
+ #createWindowControls() {
105
+ if (document.getElementById('win-minimize') || document.getElementById('win-close')) return;
106
+ const bar = this.#resolve(this._topBarOpt);
107
+ const host = this.#resolve(this._controlsOpt)
108
+ || bar?.querySelector('.twm-bar-right')
109
+ || bar;
110
+ if (!host) return;
111
+ const box = document.createElement('div');
112
+ box.className = 'twm-window-controls';
113
+ const button = (id, icon, label, extra = '') => {
114
+ const b = document.createElement('button');
115
+ b.type = 'button';
116
+ b.id = id;
117
+ b.className = `twm-window-controls__btn${extra}`;
118
+ b.setAttribute('aria-label', label);
119
+ b.title = label;
120
+ const i = document.createElement('span');
121
+ i.className = 'material-symbols-outlined';
122
+ i.textContent = icon;
123
+ b.appendChild(i);
124
+ box.appendChild(b);
125
+ };
126
+ button('win-minimize', 'remove', 'Minimize');
127
+ button('win-maximize', 'check_box_outline_blank', 'Maximize');
128
+ button('win-close', 'close', 'Close', ' twm-window-controls__btn--close');
129
+ host.appendChild(box);
130
+ this._createdControls = box;
62
131
  }
63
132
 
64
133
  /**
@@ -110,6 +179,7 @@ export class WindowChromeController {
110
179
  const tooltipText = isMax ? 'Restore' : 'Maximize';
111
180
  window.LatexTooltip?.set(maxBtn, tooltipText);
112
181
  maxBtn.setAttribute('aria-label', tooltipText);
182
+ maxBtn.title = tooltipText;
113
183
 
114
184
  document.body.classList.toggle('twm-window-maximized', isMax);
115
185
  }
@@ -188,8 +258,23 @@ export class WindowChromeController {
188
258
 
189
259
  let activePointerId = null;
190
260
 
261
+ const EDGE = {
262
+ right: 'e', left: 'w', top: 'n', bottom: 's',
263
+ cornerBR: 'se', cornerBL: 'sw', cornerTR: 'ne', cornerTL: 'nw',
264
+ };
265
+
191
266
  const startDrag = async (e) => {
267
+ if (e.button != null && e.button !== 0) return;
192
268
  e.preventDefault();
269
+ // ── Native resize: the OS runs its own size loop (it blocks until
270
+ // mouse-up), so the edge stays under the pointer. ──
271
+ if (this.win.startNativeResize) {
272
+ this.resizingActive = true;
273
+ let handled = false;
274
+ try { handled = await this.win.startNativeResize(EDGE[mode]); } catch (_) { handled = false; }
275
+ this.resizingActive = false;
276
+ if (handled) return;
277
+ }
193
278
  this.resizingActive = true;
194
279
  startX = e.clientX;
195
280
  startY = e.clientY;
@@ -313,10 +398,18 @@ export class WindowChromeController {
313
398
  * Setup top bar dragging for window movement
314
399
  */
315
400
  #wireTopBarDrag() {
316
- this.topBar = document.querySelector('.twm-global-top-bar');
401
+ this.topBar = this.#resolve(this._topBarOpt);
317
402
  if (!this.topBar) return;
318
403
 
319
- const NO_DRAG_SELECTOR = '.no-drag, button, input, select, textarea, .menu-item, .menu-dropdown, .window-controls, .panel-toggles, .global-search-dropdown';
404
+ // What never starts a drag: anything you can click or type into. An
405
+ // embedder adds its own with `noDrag`. (`.window-controls` and
406
+ // `.panel-toggles` are kept for EcoSim-shaped markup.)
407
+ const NO_DRAG_SELECTOR = [
408
+ '.no-drag', 'button', 'a', 'input', 'select', 'textarea', 'label',
409
+ '[role="button"]', '[role="menuitem"]', '[role="tab"]', '[contenteditable="true"]',
410
+ '.twm-window-controls', '.window-controls', '.panel-toggles',
411
+ this._noDrag,
412
+ ].filter(Boolean).join(', ');
320
413
 
321
414
  let dragging = false;
322
415
  let startSX = 0, startSY = 0, startX = null, startY = null, winW = 0, winH = 0;
@@ -533,8 +626,7 @@ export class WindowChromeController {
533
626
  // Double-click to toggle maximize (only on blank surfaces)
534
627
  const dblClickHandler = async (e) => {
535
628
  // Skip maximize if double-click is on interactive elements
536
- const interactiveSelector = 'button, input, select, textarea, a, [role="button"], [role="menuitem"], .menu-bar, .fl-bar, .fl-item, .global-search-wrapper, .panel-toggle-btn';
537
- if (e.target.closest(interactiveSelector)) {
629
+ if (isInteractiveTarget(e.target)) {
538
630
  return;
539
631
  }
540
632
 
@@ -646,13 +738,16 @@ export class WindowChromeController {
646
738
  });
647
739
  this._disposers = [];
648
740
 
649
- // Remove resize handles
741
+ // Remove resize handles, and the buttons this drew
650
742
  Object.values(this.handles).forEach(handle => {
651
743
  if (handle && handle.parentNode) {
652
744
  handle.parentNode.removeChild(handle);
653
745
  }
654
746
  });
655
747
  this.handles = {};
748
+ this._createdControls?.remove();
749
+ this._createdControls = null;
750
+ document.body.classList.remove('twm-custom-chrome', 'twm-window-maximized', 'window-fullscreen');
656
751
 
657
752
  this.logger.info?.('[WindowChrome] Disposed');
658
753
  }
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes