flexdesk 0.15.2 → 0.16.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 (191) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +26 -0
  3. package/THIRD_PARTY_LICENSES.md +0 -0
  4. package/css/base.css +0 -0
  5. package/css/flexdesk.css +0 -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 +0 -0
  44. package/dist/flow.js +0 -0
  45. package/dist/flow.js.map +0 -0
  46. package/dist/host.js +80 -1
  47. package/dist/host.js.map +3 -3
  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 +50 -0
  55. package/dist/widgets.js.map +3 -3
  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/external_links.js +94 -0
  120. package/src/host/host.js +4 -1
  121. package/src/host/photino_host.js +7 -0
  122. package/src/host/photino_host.md +18 -0
  123. package/src/host/pywebview_host.js +0 -0
  124. package/src/tiles/chart_tiles.js +0 -0
  125. package/src/tiles/config_schema.js +0 -0
  126. package/src/tiles/layout_persistence.js +0 -0
  127. package/src/tiles/tile_base.js +0 -0
  128. package/src/tiles/tile_grid.js +0 -0
  129. package/src/tiles/tile_registry.js +0 -0
  130. package/src/tiling/bottom_panel_tabs.js +0 -0
  131. package/src/tiling/command_palette.js +0 -0
  132. package/src/tiling/content_registry.js +0 -0
  133. package/src/tiling/desktops.js +0 -0
  134. package/src/tiling/entity_sources.js +0 -0
  135. package/src/tiling/keymap.js +0 -0
  136. package/src/tiling/kind_taxonomy.js +0 -0
  137. package/src/tiling/landing_table.js +0 -0
  138. package/src/tiling/loading_overlay.js +0 -0
  139. package/src/tiling/nav_panel.js +0 -0
  140. package/src/tiling/page_factory.js +0 -0
  141. package/src/tiling/panel_keys.js +0 -0
  142. package/src/tiling/shell.js +0 -0
  143. package/src/tiling/tab_strip.js +0 -0
  144. package/src/tiling/tile_breadcrumb.js +0 -0
  145. package/src/tiling/tile_renderer.js +0 -0
  146. package/src/tiling/tile_tab_menu.js +0 -0
  147. package/src/tiling/tile_tree.js +0 -0
  148. package/src/tiling/wm.js +0 -0
  149. package/src/tiling/zoom.js +0 -0
  150. package/src/ui/base/component_base.js +0 -0
  151. package/src/ui/base/controller_base.js +0 -0
  152. package/src/ui/base/page_base.js +0 -0
  153. package/src/ui/components/about_dialog.js +0 -0
  154. package/src/ui/components/action_dropdown.js +0 -0
  155. package/src/ui/components/alert_log.js +0 -0
  156. package/src/ui/components/alerts_pane.js +0 -0
  157. package/src/ui/components/attribute_list_editor.js +0 -0
  158. package/src/ui/components/autocomplete_field.js +0 -0
  159. package/src/ui/components/column_fit.js +0 -0
  160. package/src/ui/components/computing_status_window.js +0 -0
  161. package/src/ui/components/confirm_dialog.js +0 -0
  162. package/src/ui/components/context_menu.js +0 -0
  163. package/src/ui/components/data_table.js +0 -0
  164. package/src/ui/components/detail_header.js +0 -0
  165. package/src/ui/components/drag_reorder.js +0 -0
  166. package/src/ui/components/fact_table.js +0 -0
  167. package/src/ui/components/gallery_picker.js +0 -0
  168. package/src/ui/components/inline_renamer.js +0 -0
  169. package/src/ui/components/managed_window.js +0 -0
  170. package/src/ui/components/modal.js +0 -0
  171. package/src/ui/components/notification_history.js +0 -0
  172. package/src/ui/components/record_list.js +0 -0
  173. package/src/ui/components/row_activation.js +0 -0
  174. package/src/ui/components/slide_out_panel.js +0 -0
  175. package/src/ui/components/slider_field.js +0 -0
  176. package/src/ui/components/sortable_list.js +0 -0
  177. package/src/ui/components/table_filter_chips.js +0 -0
  178. package/src/ui/components/table_state_store.js +0 -0
  179. package/src/ui/components/table_values.js +0 -0
  180. package/src/ui/components/toast.js +0 -0
  181. package/src/ui/components/tree_view.js +0 -0
  182. package/src/ui/components/window_taskbar.js +0 -0
  183. package/src/ui/controllers/panel_state_machine.js +0 -0
  184. package/src/ui/controllers/window_chrome_controller.js +0 -0
  185. package/src/ui/notification_center.js +0 -0
  186. package/src/ui/utils/auto_scrollbars.js +0 -0
  187. package/src/ui/utils/native_context_menu.js +61 -0
  188. package/src/ui/utils/overlay_scrollbar.js +0 -0
  189. package/src/ui/utils/raf_resize_observer.js +0 -0
  190. package/src/ui/utils/scroll_lock.js +0 -0
  191. package/src/ui/utils/tooltip_service.js +0 -0
package/dist/wm.js CHANGED
File without changes
package/dist/wm.js.map CHANGED
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flexdesk",
3
- "version": "0.15.2",
3
+ "version": "0.16.0",
4
4
  "description": "A tiling window manager and widget set for desktop-class web applications. Zero runtime dependencies.",
5
5
  "license": "MIT",
6
6
  "repository": {
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,94 @@
1
+ /**
2
+ * external_links.js — links that leave the app open in the system browser.
3
+ *
4
+ * In a browser tab, `target="_blank"` and `window.open()` open a new tab, which
5
+ * is what everyone expects. In a native window (Photino, a webview) they open
6
+ * either nothing or a bare popup with no address bar and no way back. The host
7
+ * knows how to hand a URL to the OS (`host.shell.openExternal`); this routes
8
+ * the page's outbound links there.
9
+ *
10
+ * Without a `shell` capability it changes nothing, so an app can call it
11
+ * unconditionally at boot: in a browser tab it is a no-op.
12
+ */
13
+
14
+ const SCHEMES = new Set(['http:', 'https:', 'mailto:']);
15
+
16
+ /** The URL as an absolute URL when it is one we would send out, else null. */
17
+ function outbound(href, base) {
18
+ let url;
19
+ try { url = new URL(String(href), base); } catch { return null; }
20
+ return SCHEMES.has(url.protocol) ? url : null;
21
+ }
22
+
23
+ /**
24
+ * Send external link clicks and `window.open` calls to `host.shell.openExternal`.
25
+ *
26
+ * A link goes out when it is http(s) or mailto AND it has `target="_blank"`,
27
+ * points to another origin, or is mailto. A same-origin link without a target
28
+ * is the app's own navigation and is left alone; a same-origin `_blank` goes
29
+ * out too, because in a native window the alternative is a bare popup. A
30
+ * handler that already called `preventDefault()` on the click keeps it.
31
+ *
32
+ * When `openExternal` resolves false (the native side refused it), the original
33
+ * `window.open` runs instead, so the click still does something.
34
+ *
35
+ * @param {object} opts
36
+ * @param {object} opts.host a Host; does nothing without `host.shell`
37
+ * @param {EventTarget} [opts.root=document] where clicks are listened for
38
+ * @param {Window} [opts.win=window] whose `open` is wrapped
39
+ * @returns {{ dispose: () => void }}
40
+ */
41
+ export function routeExternalLinks({ host, root, win } = {}) {
42
+ const w = win ?? (typeof window !== 'undefined' ? window : null);
43
+ const r = root ?? (typeof document !== 'undefined' ? document : null);
44
+ const shell = host?.shell;
45
+ if (!shell || typeof shell.openExternal !== 'function' || !w || !r) return { dispose() {} };
46
+
47
+ const base = () => w.location?.href;
48
+ const origin = () => { try { return new URL(base()).origin; } catch { return null; } };
49
+ const nativeOpen = w.open;
50
+ const fallback = (href) => { try { nativeOpen?.call(w, href, '_blank', 'noopener'); } catch { /* blocked */ } };
51
+ const send = (href) => {
52
+ Promise.resolve()
53
+ .then(() => shell.openExternal(href))
54
+ .then((opened) => { if (opened !== true) fallback(href); }, () => fallback(href));
55
+ };
56
+
57
+ const onClick = (e) => {
58
+ if (e.defaultPrevented) return;
59
+ // Left click, or a middle click (auxclick): both open a new window.
60
+ if (e.type === 'click' ? e.button !== 0 : e.button !== 1) return;
61
+ const a = e.target?.closest?.('a[href]');
62
+ if (!a || a.hasAttribute('download')) return;
63
+ const url = outbound(a.getAttribute('href'), base());
64
+ if (!url) return;
65
+ const leaves = url.protocol === 'mailto:'
66
+ || (a.getAttribute('target') || '').toLowerCase() === '_blank'
67
+ || url.origin !== origin()
68
+ || e.button === 1;
69
+ if (!leaves) return;
70
+ e.preventDefault();
71
+ send(url.href);
72
+ };
73
+
74
+ const routedOpen = function open(href, target, features) {
75
+ const url = href == null ? null : outbound(href, base());
76
+ if (url && (url.protocol === 'mailto:' || url.origin !== origin())) {
77
+ send(url.href);
78
+ return null;
79
+ }
80
+ return nativeOpen.call(w, href, target, features);
81
+ };
82
+
83
+ r.addEventListener('click', onClick);
84
+ r.addEventListener('auxclick', onClick);
85
+ w.open = routedOpen;
86
+
87
+ return {
88
+ dispose() {
89
+ r.removeEventListener('click', onClick);
90
+ r.removeEventListener('auxclick', onClick);
91
+ if (w.open === routedOpen) w.open = nativeOpen;
92
+ },
93
+ };
94
+ }
package/src/host/host.js CHANGED
@@ -24,6 +24,9 @@ export const HOST_CONTRACT = Object.freeze({
24
24
  }),
25
25
  dialogs: Object.freeze({ required: Object.freeze(['saveFile']), optional: Object.freeze([]) }),
26
26
  state: Object.freeze({ required: Object.freeze(['read', 'write']), optional: Object.freeze([]) }),
27
+ // `openExternal(url)` hands a web address to the OS's default browser and
28
+ // resolves true when it did. See external_links.js.
29
+ shell: Object.freeze({ required: Object.freeze(['openExternal']), optional: Object.freeze([]) }),
27
30
  });
28
31
 
29
32
  /**
@@ -49,7 +52,7 @@ export function validateCapability(name, cap) {
49
52
  * Throws at boot on an incomplete capability — a half-wired host is a bug,
50
53
  * and a bug at boot beats a silent degrade at click time.
51
54
  *
52
- * @param {{ window?: object, dialogs?: object, state?: object }} caps
55
+ * @param {{ window?: object, dialogs?: object, state?: object, shell?: object }} caps
53
56
  * @returns {Readonly<object>} the Host
54
57
  */
55
58
  export function createHost(caps = {}) {
@@ -106,6 +106,7 @@ export function createPhotinoTransport({ external, timeoutMs = 10000, onEvent =
106
106
  * @param {object|null} [opts.window] replace the window capability, or `null` to leave it out
107
107
  * @param {object|null} [opts.dialogs] replace the dialogs capability, or `null` to leave it out
108
108
  * @param {object|null} [opts.state] replace the state capability, or `null` to leave it out
109
+ * @param {object|null} [opts.shell] replace the shell capability, or `null` to leave it out
109
110
  * @returns {Readonly<object>} a Host, or NULL_HOST outside a Photino window
110
111
  */
111
112
  export function createPhotinoHost(opts = {}) {
@@ -182,6 +183,12 @@ export function createPhotinoHost(opts = {}) {
182
183
  return r && typeof r === 'object' ? r : null;
183
184
  },
184
185
  },
186
+ shell: {
187
+ // True when the native side opened it in the system browser; false
188
+ // when it refused (a scheme it won't open, an older native side
189
+ // without the op): the caller falls back to window.open.
190
+ openExternal: async (url) => (await soft(false, 'shell', 'openExternal', String(url || ''))) === true,
191
+ },
185
192
  state: {
186
193
  async read(key) {
187
194
  const v = await soft(null, 'state', 'read', key);
@@ -40,6 +40,7 @@ host → page {"event": "window.maximizedChanged", "value": true}
40
40
  | `window.startDrag` | `[]` | anything, **after mouse-up** | custom chrome only: the OS move loop (below) |
41
41
  | `window.startResize` | `[edge]`: `n` `s` `e` `w` `ne` `nw` `se` `sw` | anything, **after mouse-up** | custom chrome only: the OS size loop (below) |
42
42
  | `dialogs.saveFile` | `[{data, filename, kind}]` | see below | `ShowSaveFile(...)` + write |
43
+ | `shell.openExternal` | `[url]` | `true` when opened | the OS's default browser (below) |
43
44
  | `state.read` | `[key]` | the stored value, or `null` | a file per key |
44
45
  | `state.write` | `[key, value]` | `true` | a file per key |
45
46
 
@@ -149,3 +150,20 @@ window.RegisterWebMessageReceivedHandler((sender, message) =>
149
150
 
150
151
  The handler runs on the window's thread; a save dialog shown from it is modal to
151
152
  the window, which is what you want.
153
+
154
+ ## Opening links in the system browser
155
+
156
+ `shell.openExternal` takes one absolute URL and opens it with the OS's default
157
+ handler: `Process.Start(new ProcessStartInfo(url) { UseShellExecute = true })`
158
+ on Windows, `xdg-open` on Linux, `open` on macOS. Answer `true` once it has
159
+ been handed over.
160
+
161
+ **Refuse anything but `http:`, `https:` and `mailto:`** with `ok: false`. The
162
+ URL comes from page content (a link in a record somebody else wrote), and a
163
+ `file:` path or a custom protocol handed to the shell runs whatever the OS
164
+ associates with it. Refused, the page falls back to `window.open`, which is
165
+ no worse than a native side that doesn't have the op.
166
+
167
+ The page side is `routeExternalLinks({ host })` (`external_links.js`). It
168
+ sends external link clicks and `window.open` calls here; without a `shell`
169
+ capability it changes nothing.
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
package/src/tiling/wm.js CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,61 @@
1
+ /**
2
+ * native_context_menu.js — the browser's own right-click menu, only where it helps.
3
+ *
4
+ * A FlexDesk app draws its own context menus (DataTable rows and headers, tabs,
5
+ * tiles, the top bar). Everywhere else a right-click shows the browser's or the
6
+ * webview's menu: Back, Reload, Save as, Print, Inspect. In a desktop window
7
+ * that makes the app look like a web page and offers moves that break it.
8
+ *
9
+ * This keeps the native menu where it is the useful one, editable text (Paste)
10
+ * and selected text (Copy), and prevents it everywhere nobody else claimed the
11
+ * right-click.
12
+ */
13
+
14
+ /** Input types that take typed text, where Paste belongs. */
15
+ const TEXT_INPUTS = new Set(['', 'text', 'search', 'url', 'tel', 'email', 'password', 'number',
16
+ 'date', 'datetime-local', 'month', 'week', 'time']);
17
+
18
+ function isEditable(el) {
19
+ if (!el || el.nodeType !== 1) return false;
20
+ const tag = el.tagName;
21
+ if (tag === 'TEXTAREA' || tag === 'SELECT') return true;
22
+ if (tag === 'INPUT') return TEXT_INPUTS.has(String(el.getAttribute('type') || '').toLowerCase());
23
+ return !!el.closest?.('[contenteditable=""],[contenteditable="true"],[contenteditable="plaintext-only"]');
24
+ }
25
+
26
+ /** A non-empty selection that the click landed inside. */
27
+ function onSelection(target, doc) {
28
+ const sel = doc?.getSelection?.();
29
+ if (!sel || sel.isCollapsed || !String(sel).trim()) return false;
30
+ for (let i = 0; i < sel.rangeCount; i += 1) {
31
+ if (sel.getRangeAt(i).intersectsNode?.(target)) return true;
32
+ }
33
+ return false;
34
+ }
35
+
36
+ /**
37
+ * Prevent the native context menu wherever no handler claimed the right-click.
38
+ *
39
+ * Listens in the bubble phase, so every element handler runs first: one that
40
+ * shows its own menu calls `preventDefault()`, and this leaves it alone. A
41
+ * handler that stops propagation never reaches here at all.
42
+ *
43
+ * @param {object} [opts]
44
+ * @param {EventTarget} [opts.root=document]
45
+ * @param {(e: MouseEvent) => boolean} [opts.allow] true keeps the native menu for that event
46
+ * @returns {{ dispose: () => void }}
47
+ */
48
+ export function suppressNativeContextMenu({ root, allow } = {}) {
49
+ const r = root ?? (typeof document !== 'undefined' ? document : null);
50
+ if (!r) return { dispose() {} };
51
+ const onMenu = (e) => {
52
+ if (e.defaultPrevented) return;
53
+ const t = e.target;
54
+ if (isEditable(t)) return;
55
+ if (onSelection(t, t?.ownerDocument)) return;
56
+ if (allow?.(e)) return;
57
+ e.preventDefault();
58
+ };
59
+ r.addEventListener('contextmenu', onMenu);
60
+ return { dispose() { r.removeEventListener('contextmenu', onMenu); } };
61
+ }
File without changes
File without changes
File without changes
File without changes