flexdesk 0.17.17 → 0.17.18

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 (211) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/LICENSE +0 -0
  3. package/README.md +0 -0
  4. package/THIRD_PARTY_LICENSES.md +0 -0
  5. package/canvas.js +0 -0
  6. package/charts.js +0 -0
  7. package/core.js +0 -0
  8. package/css/base.css +20 -0
  9. package/css/flexdesk.css +20 -0
  10. package/css/reset.css +0 -0
  11. package/dist/canvas.js +0 -0
  12. package/dist/canvas.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-FOOS3T5L.js +0 -0
  16. package/dist/chunk-FOOS3T5L.js.map +0 -0
  17. package/dist/chunk-GOQLR5WR.js +0 -0
  18. package/dist/chunk-GOQLR5WR.js.map +0 -0
  19. package/dist/{chunk-JKZLNKG6.js → chunk-HKPB6OFA.js} +90 -25
  20. package/dist/{chunk-JKZLNKG6.js.map → chunk-HKPB6OFA.js.map} +2 -2
  21. package/dist/chunk-HNU6MM2B.js +0 -0
  22. package/dist/chunk-HNU6MM2B.js.map +0 -0
  23. package/dist/chunk-JYWURG5T.js +0 -0
  24. package/dist/chunk-JYWURG5T.js.map +0 -0
  25. package/dist/chunk-N7HC3ADV.js +0 -0
  26. package/dist/chunk-N7HC3ADV.js.map +0 -0
  27. package/dist/editor.js.map +0 -0
  28. package/dist/flexdesk.css +20 -0
  29. package/dist/flow.js.map +0 -0
  30. package/dist/host.js +0 -0
  31. package/dist/host.js.map +0 -0
  32. package/dist/reset.css +0 -0
  33. package/dist/tile_registry-6WZPTUZV.js +0 -0
  34. package/dist/tile_registry-6WZPTUZV.js.map +0 -0
  35. package/dist/widgets.js +2 -1
  36. package/dist/widgets.js.map +2 -2
  37. package/dist/wm.js +1 -1
  38. package/docs/components/command-palette.md +0 -0
  39. package/docs/components/conversation.md +0 -0
  40. package/docs/components/data-table-grid.md +0 -0
  41. package/docs/components/data-table.md +0 -0
  42. package/docs/components/editor.md +0 -0
  43. package/docs/components/flow-canvas-editor.md +0 -0
  44. package/docs/components/flow-editors.md +0 -0
  45. package/docs/components/flow-lane-editor.md +0 -0
  46. package/docs/components/flow-outline-editor.md +0 -0
  47. package/docs/components/input-fields.md +0 -0
  48. package/docs/components/markdown-and-outline.md +0 -0
  49. package/docs/components/menus.md +38 -1
  50. package/docs/components/record-list-and-fact-table.md +0 -0
  51. package/docs/components/settings-view.md +0 -0
  52. package/docs/components/wizard.md +0 -0
  53. package/docs/concepts/building-and-packaging.md +0 -0
  54. package/docs/concepts/domain-neutrality.md +0 -0
  55. package/docs/concepts/host-port.md +0 -0
  56. package/docs/concepts/packages-and-entry-points.md +0 -0
  57. package/docs/concepts/peer-dependencies.md +0 -0
  58. package/docs/quickstart.md +0 -0
  59. package/editor.js +0 -0
  60. package/flow.js +0 -0
  61. package/host.js +0 -0
  62. package/package.json +1 -1
  63. package/src/canvas/canvas_adapter.js +0 -0
  64. package/src/canvas/edge_router.js +0 -0
  65. package/src/canvas/graph/connector_router.js +0 -0
  66. package/src/canvas/graph/history_service.js +0 -0
  67. package/src/canvas/graph/node_platform.js +0 -0
  68. package/src/canvas/index.js +0 -0
  69. package/src/canvas/layered_layout.js +0 -0
  70. package/src/charts/data_series_plot_window.js +0 -0
  71. package/src/charts/downsample.js +0 -0
  72. package/src/charts/plot_config.js +0 -0
  73. package/src/charts/plotly_wrapper.js +0 -0
  74. package/src/core/event_bus.js +0 -0
  75. package/src/core/logging.js +0 -0
  76. package/src/core/settings.js +0 -0
  77. package/src/core/state_guard.js +0 -0
  78. package/src/core/state_machine.js +0 -0
  79. package/src/editor/editor_pane.js +0 -0
  80. package/src/editor/monaco_editor_factory.js +0 -0
  81. package/src/editor/monaco_loader.js +0 -0
  82. package/src/editor/notebook_search.js +0 -0
  83. package/src/editor/notebook_undo_manager.js +0 -0
  84. package/src/editor/split_pane_container.js +0 -0
  85. package/src/flow/canvas_editor/connections.js +0 -0
  86. package/src/flow/canvas_editor/editor.js +0 -0
  87. package/src/flow/canvas_editor/index.js +0 -0
  88. package/src/flow/canvas_editor/layout.js +0 -0
  89. package/src/flow/canvas_editor/strings.js +0 -0
  90. package/src/flow/kit/always_before.js +0 -0
  91. package/src/flow/kit/catalogue.js +0 -0
  92. package/src/flow/kit/chip_input.js +0 -0
  93. package/src/flow/kit/dom.js +0 -0
  94. package/src/flow/kit/findings.js +0 -0
  95. package/src/flow/kit/history.js +0 -0
  96. package/src/flow/kit/index.js +0 -0
  97. package/src/flow/kit/keys.js +0 -0
  98. package/src/flow/kit/logic_graph.js +0 -0
  99. package/src/flow/kit/references.js +0 -0
  100. package/src/flow/kit/settings_panel.js +0 -0
  101. package/src/flow/kit/settings_schema.js +0 -0
  102. package/src/flow/kit/step_picker.js +0 -0
  103. package/src/flow/kit/strings.js +0 -0
  104. package/src/flow/kit/value_picker.js +0 -0
  105. package/src/flow/kit/widgets.js +0 -0
  106. package/src/flow/lanes/editor.js +0 -0
  107. package/src/flow/lanes/index.js +0 -0
  108. package/src/flow/lanes/layout.js +0 -0
  109. package/src/flow/lanes/pipeline.js +0 -0
  110. package/src/flow/lanes/preview.js +0 -0
  111. package/src/flow/lanes/strings.js +0 -0
  112. package/src/flow/outline/editor.js +0 -0
  113. package/src/flow/outline/index.js +0 -0
  114. package/src/flow/outline/mapping.js +0 -0
  115. package/src/flow/outline/menu.js +0 -0
  116. package/src/flow/outline/operations.js +0 -0
  117. package/src/flow/outline/recognise.js +0 -0
  118. package/src/flow/outline/strings.js +0 -0
  119. package/src/help/help_modal.js +0 -0
  120. package/src/help/help_registry.js +0 -0
  121. package/src/host/external_links.js +0 -0
  122. package/src/host/file_picker.js +0 -0
  123. package/src/host/host.js +0 -0
  124. package/src/host/photino_host.js +0 -0
  125. package/src/host/photino_host.md +0 -0
  126. package/src/host/pywebview_host.js +0 -0
  127. package/src/tiles/chart_tiles.js +0 -0
  128. package/src/tiles/config_schema.js +0 -0
  129. package/src/tiles/figure_tile.js +0 -0
  130. package/src/tiles/layout_persistence.js +0 -0
  131. package/src/tiles/list_tiles.js +0 -0
  132. package/src/tiles/scope_picker.js +0 -0
  133. package/src/tiles/tile_config_form.js +0 -0
  134. package/src/tiles/tile_registry.js +0 -0
  135. package/src/tiling/bottom_panel_tabs.js +0 -0
  136. package/src/tiling/command_palette.js +0 -0
  137. package/src/tiling/content_registry.js +0 -0
  138. package/src/tiling/entity_sources.js +0 -0
  139. package/src/tiling/landing_table.js +0 -0
  140. package/src/tiling/loading_overlay.js +0 -0
  141. package/src/tiling/nav_panel.js +0 -0
  142. package/src/tiling/page_factory.js +0 -0
  143. package/src/tiling/panel_availability.js +0 -0
  144. package/src/tiling/panel_keys.js +0 -0
  145. package/src/tiling/tab_strip.js +0 -0
  146. package/src/tiling/tile_renderer.js +0 -0
  147. package/src/tiling/tile_tab_menu.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/alert_log.js +0 -0
  154. package/src/ui/components/alerts_pane.js +0 -0
  155. package/src/ui/components/attribute_list_editor.js +0 -0
  156. package/src/ui/components/autocomplete_field.js +0 -0
  157. package/src/ui/components/cell_editor_host.js +0 -0
  158. package/src/ui/components/cell_editors.js +0 -0
  159. package/src/ui/components/cell_grid.js +0 -0
  160. package/src/ui/components/cell_paste.js +0 -0
  161. package/src/ui/components/cell_selection.js +0 -0
  162. package/src/ui/components/choice_controls.js +0 -0
  163. package/src/ui/components/color_field.js +0 -0
  164. package/src/ui/components/color_list_field.js +0 -0
  165. package/src/ui/components/column_fit.js +0 -0
  166. package/src/ui/components/column_groups.js +0 -0
  167. package/src/ui/components/column_order.js +0 -0
  168. package/src/ui/components/conversation_view.js +0 -0
  169. package/src/ui/components/crosstab.js +0 -0
  170. package/src/ui/components/detail_header.js +0 -0
  171. package/src/ui/components/document_outline.js +0 -0
  172. package/src/ui/components/drag_reorder.js +0 -0
  173. package/src/ui/components/fact_table.js +0 -0
  174. package/src/ui/components/fill_handle.js +0 -0
  175. package/src/ui/components/gallery_picker.js +0 -0
  176. package/src/ui/components/header_actions.js +0 -0
  177. package/src/ui/components/inline_renamer.js +0 -0
  178. package/src/ui/components/job_progress.js +0 -0
  179. package/src/ui/components/menu_bar.js +101 -24
  180. package/src/ui/components/progress.js +0 -0
  181. package/src/ui/components/record_list.js +0 -0
  182. package/src/ui/components/row_activation.js +0 -0
  183. package/src/ui/components/section_stack.js +0 -0
  184. package/src/ui/components/series.js +0 -0
  185. package/src/ui/components/settings_view.js +0 -0
  186. package/src/ui/components/slide_out_panel.js +0 -0
  187. package/src/ui/components/slider_field.js +0 -0
  188. package/src/ui/components/sortable_list.js +0 -0
  189. package/src/ui/components/staged_edits.js +0 -0
  190. package/src/ui/components/staged_history.js +0 -0
  191. package/src/ui/components/table_filter_chips.js +0 -0
  192. package/src/ui/components/table_state_store.js +0 -0
  193. package/src/ui/components/table_structure.js +0 -0
  194. package/src/ui/components/table_values.js +0 -0
  195. package/src/ui/components/tabs.js +0 -0
  196. package/src/ui/components/tag_input.js +0 -0
  197. package/src/ui/components/toast.js +0 -0
  198. package/src/ui/components/toggle_field.js +0 -0
  199. package/src/ui/components/tsv.js +0 -0
  200. package/src/ui/components/window_taskbar.js +0 -0
  201. package/src/ui/controllers/window_chrome_controller.js +4 -1
  202. package/src/ui/utils/auto_scrollbars.js +0 -0
  203. package/src/ui/utils/markdown.js +0 -0
  204. package/src/ui/utils/native_context_menu.js +0 -0
  205. package/src/ui/utils/overlay_scrollbar.js +0 -0
  206. package/src/ui/utils/raf_resize_observer.js +0 -0
  207. package/src/ui/utils/scroll_lock.js +0 -0
  208. package/src/ui/utils/strip_scroll.js +0 -0
  209. package/src/ui/utils/tooltip_service.js +0 -0
  210. package/tiles.js +0 -0
  211. package/wm.js +0 -0
@@ -62,6 +62,15 @@
62
62
  * shortcut, context, action }`), so the palette and the bar list identical
63
63
  * verbs.
64
64
  *
65
+ * ── Two styles: a bar, or one hamburger button (STORY-0133) ───────────
66
+ * `style: 'bar'` (the default) draws a title per menu: File Edit Help.
67
+ * `style: 'hamburger'` draws ONE icon button (`icon`, 'menu' by default,
68
+ * named by `label`) whose menu lists the menus, each flying out its items:
69
+ * ☰ › File › Open…. It is the same model, so `commands()`, `setEnabled`,
70
+ * `setChecked` and `onAction` do not change; `open(menuId)` opens the
71
+ * hamburger with that menu flown out. `setStyle(style)` switches at run
72
+ * time (a setting, a narrow window), closing whatever is open.
73
+ *
65
74
  * ── Roles ─────────────────────────────────────────────────────────────
66
75
  * The WAI-ARIA menubar pattern: `role="menubar"` on the element you pass,
67
76
  * a `role="menuitem"` title per menu inside a `role="none"` wrapper, each
@@ -77,6 +86,9 @@
77
86
  const SEL_TITLE = '.twm-menubar__title';
78
87
  const SEL_ITEM = '.twm-menubar__item';
79
88
  const SEL_MENU = '.twm-menubar__menu';
89
+ const STYLES = ['bar', 'hamburger'];
90
+ /** The hamburger's own model ids. A menu's row in it is `${HAMBURGER}:${menu.id}`. */
91
+ const HAMBURGER = 'twm-menubar:hamburger';
80
92
 
81
93
  /** @returns {MenuBar} */
82
94
  export function createMenuBar(el, opts) {
@@ -91,16 +103,22 @@ export class MenuBar {
91
103
  * @param {Function} [opts.onAction] `(id, { item, checked }) => void`
92
104
  * @param {string} [opts.label] the bar's accessible name ('Menu')
93
105
  * @param {string} [opts.emptyLabel] the disabled row an empty submenu shows ('Empty')
106
+ * @param {string} [opts.style] 'bar' (a title per menu, the default) or 'hamburger' (one button)
107
+ * @param {string} [opts.icon] the hamburger's Material Symbols icon ('menu')
94
108
  */
95
- constructor(el, { menus, onAction = null, label = 'Menu', emptyLabel = 'Empty' } = {}) {
109
+ constructor(el, { menus, onAction = null, label = 'Menu', emptyLabel = 'Empty', style = 'bar', icon = 'menu' } = {}) {
96
110
  if (!el || typeof el.appendChild !== 'function') {
97
111
  throw new TypeError('createMenuBar: `el` must be an element');
98
112
  }
99
113
  _validateMenus(menus);
114
+ _validateStyle(style);
100
115
  this.el = el;
101
116
  this.menus = menus;
102
117
  this._onAction = typeof onAction === 'function' ? onAction : null;
103
118
  this._emptyLabel = emptyLabel;
119
+ this._label = label;
120
+ this._icon = icon;
121
+ this._style = style;
104
122
  this._doc = el.ownerDocument;
105
123
  this._disabled = new Map(); // id -> boolean (override)
106
124
  this._checked = new Map(); // id -> boolean (override, check items)
@@ -112,26 +130,10 @@ export class MenuBar {
112
130
  this._returnTo = null; // what had focus before the bar did
113
131
  this._altArmed = false;
114
132
 
115
- el.innerHTML = '';
116
133
  el.classList.add('twm-menubar');
117
134
  el.setAttribute('role', 'menubar');
118
135
  el.setAttribute('aria-label', label);
119
- this._titles = menus.map((m, i) => {
120
- const entry = this._doc.createElement('div');
121
- entry.className = 'twm-menubar__entry';
122
- entry.setAttribute('role', 'none');
123
- const btn = this._doc.createElement('button');
124
- btn.type = 'button';
125
- btn.className = 'twm-menubar__title';
126
- btn.setAttribute('role', 'menuitem');
127
- btn.setAttribute('aria-haspopup', 'menu');
128
- btn.setAttribute('aria-expanded', 'false');
129
- btn.tabIndex = i === 0 ? 0 : -1;
130
- btn.textContent = m.label;
131
- entry.appendChild(btn);
132
- el.appendChild(entry);
133
- return btn;
134
- });
136
+ this._renderTitles();
135
137
 
136
138
  this._h = {
137
139
  mousedown: (e) => this._onMouseDown(e),
@@ -163,12 +165,35 @@ export class MenuBar {
163
165
  /** Whether a menu is open. */
164
166
  isOpen() { return this._openIdx >= 0; }
165
167
 
166
- /** Open the menu with this id (focus on its title, or on its first item). */
168
+ /** Open the menu with this id (focus on its title, or on its first item).
169
+ * A hamburger opens with that menu flown out (focus on its row, or on
170
+ * the menu's first item). */
167
171
  open(menuId, { focusItem = false } = {}) {
168
172
  const i = this.menus.findIndex((m) => m.id === menuId);
169
173
  if (i < 0) return;
170
174
  this._enter();
171
- this._open(i, focusItem ? 'first' : null);
175
+ if (this._style !== 'hamburger') { this._open(i, focusItem ? 'first' : null); return; }
176
+ this._open(0, null);
177
+ const row = this._itemsIn(this._stack[0].menu)
178
+ .find((b) => this._models.get(b)?.id === `${HAMBURGER}:${menuId}`);
179
+ if (!row) return;
180
+ row.focus({ preventScroll: true });
181
+ this._openSub(row, focusItem ? 'first' : null);
182
+ }
183
+
184
+ /** 'bar' or 'hamburger'. */
185
+ get style() { return this._style; }
186
+
187
+ /** Draw the menus as a bar or as one hamburger button. Whatever is open
188
+ * closes; the model and every setEnabled / setChecked stay. */
189
+ setStyle(style) {
190
+ _validateStyle(style);
191
+ if (style === this._style) return;
192
+ const hadFocus = this.el.contains(this._doc.activeElement);
193
+ this._deactivate();
194
+ this._style = style;
195
+ this._renderTitles();
196
+ if (hadFocus) this._focusTitle(0);
172
197
  }
173
198
 
174
199
  /** Close every open menu. Focus stays in the bar if it was there. */
@@ -239,7 +264,7 @@ export class MenuBar {
239
264
  this._doc.removeEventListener('mousedown', this._h.docMousedown, true);
240
265
  this._doc.defaultView?.removeEventListener('blur', this._h.winBlur);
241
266
  this.el.innerHTML = '';
242
- this.el.classList.remove('twm-menubar');
267
+ this.el.classList.remove('twm-menubar', 'twm-menubar--hamburger');
243
268
  this.el.removeAttribute('role');
244
269
  this.el.removeAttribute('aria-label');
245
270
  }
@@ -317,6 +342,50 @@ export class MenuBar {
317
342
  }
318
343
  }
319
344
 
345
+ // ── titles ────────────────────────────────────────────────────────
346
+
347
+ /** The titles for the current style. `_top` is what they open: the
348
+ * menus themselves, or the hamburger's one menu that lists them. */
349
+ _renderTitles() {
350
+ const d = this._doc;
351
+ const burger = this._style === 'hamburger';
352
+ this.el.innerHTML = '';
353
+ this.el.classList.toggle('twm-menubar--hamburger', burger);
354
+ this._top = burger
355
+ ? [{ id: HAMBURGER, label: this._label, items: this.menus.map((m) => ({
356
+ id: `${HAMBURGER}:${m.id}`, label: m.label, submenu: m.items,
357
+ })) }]
358
+ : this.menus;
359
+ this._titles = this._top.map((m, i) => {
360
+ const entry = d.createElement('div');
361
+ entry.className = 'twm-menubar__entry';
362
+ entry.setAttribute('role', 'none');
363
+ const btn = d.createElement('button');
364
+ btn.type = 'button';
365
+ btn.className = 'twm-menubar__title';
366
+ btn.setAttribute('role', 'menuitem');
367
+ btn.setAttribute('aria-haspopup', 'menu');
368
+ btn.setAttribute('aria-expanded', 'false');
369
+ btn.tabIndex = i === 0 ? 0 : -1;
370
+ if (burger) {
371
+ btn.classList.add('twm-menubar__title--icon', 'twm-has-tooltip');
372
+ btn.setAttribute('aria-label', m.label);
373
+ btn.dataset.tooltip = m.label;
374
+ btn.dataset.tooltipPlacement = 'bottom';
375
+ const icon = d.createElement('span');
376
+ icon.className = 'material-symbols-outlined';
377
+ icon.setAttribute('aria-hidden', 'true');
378
+ icon.textContent = this._icon;
379
+ btn.appendChild(icon);
380
+ } else {
381
+ btn.textContent = m.label;
382
+ }
383
+ entry.appendChild(btn);
384
+ this.el.appendChild(entry);
385
+ return btn;
386
+ });
387
+ }
388
+
320
389
  // ── open / close ──────────────────────────────────────────────────
321
390
 
322
391
  _setRoving(i) {
@@ -359,7 +428,7 @@ export class MenuBar {
359
428
  // being removed never holds focus.
360
429
  this._focusTitle(i);
361
430
  this._closeAll();
362
- const m = this.menus[i];
431
+ const m = this._top[i];
363
432
  const title = this._titles[i];
364
433
  const menu = this._buildMenu(m.items, m.label);
365
434
  title.parentElement.appendChild(menu);
@@ -596,6 +665,8 @@ export class MenuBar {
596
665
  _titleKey(key, i) {
597
666
  const n = this._titles.length;
598
667
  const open = this._openIdx >= 0;
668
+ // One title (a hamburger): there is no next or previous menu.
669
+ if (n === 1 && (key === 'ArrowRight' || key === 'ArrowLeft' || key === 'Home' || key === 'End')) return true;
599
670
  switch (key) {
600
671
  case 'ArrowRight': open ? this._open(i + 1, null) : this._focusTitle((i + 1) % n); return true;
601
672
  case 'ArrowLeft': open ? this._open(i - 1, null) : this._focusTitle((i - 1 + n) % n); return true;
@@ -642,11 +713,11 @@ export class MenuBar {
642
713
  case 'End': this._focusIn(menu, 'last'); return true;
643
714
  case 'ArrowRight':
644
715
  if (item?.submenu != null && !this._isDisabled(item)) this._openSub(btn, 'first');
645
- else this._open(this._openIdx + 1, 'first');
716
+ else if (this._titles.length > 1) this._open(this._openIdx + 1, 'first');
646
717
  return true;
647
718
  case 'ArrowLeft':
648
719
  if (level > 0) this._closeFrom(level);
649
- else this._open(this._openIdx - 1, 'first');
720
+ else if (this._titles.length > 1) this._open(this._openIdx - 1, 'first');
650
721
  return true;
651
722
  case 'Enter': case ' ':
652
723
  this._activate(btn);
@@ -706,6 +777,12 @@ function _kind(item) {
706
777
  return 'menuitem';
707
778
  }
708
779
 
780
+ function _validateStyle(style) {
781
+ if (!STYLES.includes(style)) {
782
+ throw new TypeError(`createMenuBar: \`style\` must be ${STYLES.map((s) => `'${s}'`).join(' or ')}`);
783
+ }
784
+ }
785
+
709
786
  /** A bad model is a boot error, not a menu that silently lacks a row. */
710
787
  function _validateMenus(menus) {
711
788
  if (!Array.isArray(menus) || !menus.length) {
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
@@ -404,10 +404,13 @@ export class WindowChromeController {
404
404
  // What never starts a drag: anything you can click or type into. An
405
405
  // embedder adds its own with `noDrag`. (`.window-controls` and
406
406
  // `.panel-toggles` are kept for embedders' own markup of that shape.)
407
+ // A menu bar in the top bar (a hamburger, STORY-0133) drops its menus
408
+ // inside the bar's DOM: a press on a menu's padding or separator is
409
+ // in the bar, not a drag.
407
410
  const NO_DRAG_SELECTOR = [
408
411
  '.no-drag', 'button', 'a', 'input', 'select', 'textarea', 'label',
409
412
  '[role="button"]', '[role="menuitem"]', '[role="tab"]', '[contenteditable="true"]',
410
- '.twm-window-controls', '.window-controls', '.panel-toggles',
413
+ '.twm-window-controls', '.window-controls', '.panel-toggles', '.twm-menubar',
411
414
  this._noDrag,
412
415
  ].filter(Boolean).join(', ');
413
416
 
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/tiles.js CHANGED
File without changes
package/wm.js CHANGED
File without changes