flexdesk 0.13.0 → 0.14.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/README.md +53 -0
- package/css/flexdesk.css +99 -0
- package/dist/flexdesk.css +99 -0
- package/dist/flow.js +3 -0
- package/dist/flow.js.map +2 -2
- package/dist/host.js +138 -0
- package/dist/host.js.map +3 -3
- package/dist/widgets.js +563 -5
- package/dist/widgets.js.map +3 -3
- package/dist/wm.js +146 -0
- package/dist/wm.js.map +3 -3
- package/package.json +1 -1
- package/src/flow/kit/dom.js +6 -0
- package/src/host/photino_host.js +176 -0
- package/src/host/photino_host.md +98 -0
- package/src/tiling/bottom_panel_tabs.js +201 -0
- package/src/ui/components/alert_log.js +274 -0
- package/src/ui/components/alerts_pane.js +294 -0
- package/src/ui/components/notification_history.js +54 -4
- package/src/ui/utils/auto_scrollbars.js +30 -0
|
@@ -21,6 +21,9 @@
|
|
|
21
21
|
* it actually overflows. They fade out a moment after the pointer leaves
|
|
22
22
|
* or the scrolling stops. Nested scroll areas each show their own.
|
|
23
23
|
* - The thumb drags and the track pages, as a native bar does.
|
|
24
|
+
* - The layer is above everything, so a bar would also draw over whatever
|
|
25
|
+
* covers its element — a popover, a menu, a dialog. A bar whose track is
|
|
26
|
+
* covered anywhere is not drawn; it comes back when it is uncovered.
|
|
24
27
|
*
|
|
25
28
|
* Discovery is lazy: the pointer and scroll events name the elements worth
|
|
26
29
|
* measuring, so nothing walks the DOM looking for scroll areas.
|
|
@@ -49,6 +52,22 @@ export function thumbGeometry(scrollSize, clientSize, scrollPos, trackLen) {
|
|
|
49
52
|
return { size, pos };
|
|
50
53
|
}
|
|
51
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Whether something else covers `el` at any of the points a bar runs along.
|
|
57
|
+
* Pure, so it can be tested without a layout engine.
|
|
58
|
+
*
|
|
59
|
+
* @param {Element} el
|
|
60
|
+
* @param {Element[][]} stacks what `elementsFromPoint` gave at each point,
|
|
61
|
+
* topmost first. The overlay layer's own bars are skipped.
|
|
62
|
+
* @returns {boolean}
|
|
63
|
+
*/
|
|
64
|
+
export function barCovered(el, stacks) {
|
|
65
|
+
return stacks.some((stack) => {
|
|
66
|
+
const top = (stack || []).find((h) => !h.closest?.('.twm-autoscroll-layer'));
|
|
67
|
+
return Boolean(top) && top !== el && !el.contains(top);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
52
71
|
/** Whether an element scrolls on an axis: its overflow allows it and its
|
|
53
72
|
* content is larger than its box. */
|
|
54
73
|
function scrollsOn(el, axis) {
|
|
@@ -151,6 +170,9 @@ export function installAutoScrollbars(root = document.body, { exclude = null } =
|
|
|
151
170
|
return rec;
|
|
152
171
|
};
|
|
153
172
|
|
|
173
|
+
const coveredAlong = (el, points) => typeof doc.elementsFromPoint === 'function'
|
|
174
|
+
&& barCovered(el, points.map(([x, y]) => doc.elementsFromPoint(x, y)));
|
|
175
|
+
|
|
154
176
|
/** Place and size an element's bars; drop the element when it is gone. */
|
|
155
177
|
const place = (el) => {
|
|
156
178
|
const rec = managed.get(el);
|
|
@@ -178,12 +200,16 @@ export function installAutoScrollbars(root = document.body, { exclude = null } =
|
|
|
178
200
|
const g = thumbGeometry(el.scrollHeight * z, el.clientHeight * z, el.scrollTop * z, len);
|
|
179
201
|
if (!g) { bar.style.display = 'none'; continue; }
|
|
180
202
|
Object.assign(thumb.style, { top: `${g.pos}px`, height: `${g.size}px`, left: '0', width: '100%' });
|
|
203
|
+
const x = right - BAR / 2 - 1;
|
|
204
|
+
if (coveredAlong(el, [[x, top + 2], [x, top + len / 2], [x, bottom - 2]])) bar.style.display = 'none';
|
|
181
205
|
} else {
|
|
182
206
|
const len = right - left;
|
|
183
207
|
Object.assign(bar.style, { left: `${left}px`, top: `${bottom - BAR - 1}px`, width: `${len}px`, height: `${BAR}px` });
|
|
184
208
|
const g = thumbGeometry(el.scrollWidth * z, el.clientWidth * z, el.scrollLeft * z, len);
|
|
185
209
|
if (!g) { bar.style.display = 'none'; continue; }
|
|
186
210
|
Object.assign(thumb.style, { left: `${g.pos}px`, width: `${g.size}px`, top: '0', height: '100%' });
|
|
211
|
+
const y = bottom - BAR / 2 - 1;
|
|
212
|
+
if (coveredAlong(el, [[left + 2, y], [left + len / 2, y], [right - 2, y]])) bar.style.display = 'none';
|
|
187
213
|
}
|
|
188
214
|
}
|
|
189
215
|
};
|
|
@@ -256,6 +282,9 @@ export function installAutoScrollbars(root = document.body, { exclude = null } =
|
|
|
256
282
|
doc.addEventListener('mouseout', onLeaveWindow, true);
|
|
257
283
|
doc.addEventListener('scroll', onScroll, true);
|
|
258
284
|
win.addEventListener('resize', onResize);
|
|
285
|
+
// A popover or dialog takes the focus as it opens, often over a bar that
|
|
286
|
+
// is showing because the pointer has not moved: look again once it is drawn.
|
|
287
|
+
doc.addEventListener('focusin', onResize, true);
|
|
259
288
|
|
|
260
289
|
return {
|
|
261
290
|
dispose() {
|
|
@@ -263,6 +292,7 @@ export function installAutoScrollbars(root = document.body, { exclude = null } =
|
|
|
263
292
|
doc.removeEventListener('mouseout', onLeaveWindow, true);
|
|
264
293
|
doc.removeEventListener('scroll', onScroll, true);
|
|
265
294
|
win.removeEventListener('resize', onResize);
|
|
295
|
+
doc.removeEventListener('focusin', onResize, true);
|
|
266
296
|
for (const el of [...managed.keys()]) drop(el);
|
|
267
297
|
root.classList.remove(ROOT_CLASS);
|
|
268
298
|
},
|