mirror of
https://github.com/got-feedBack/feedBack.git
synced 2026-08-12 03:41:40 +00:00
fix(panes): don't hide a docked pane; don't force display; restore visibility
Six more findings from CodeRabbit on #928. Three are real bugs. 1. THE CHIP HID DOCKED PANES. `_onOpened` decided "did the pane take my element?" from `ownerDocument !== document`. That is true for a pane in a pop-out window — and false for a pane moved into the DOCK, which lives in this very document. So docking a pane stamped `.fb-pane-detached` (display:none !important) onto the panel the user was looking at, and put the stub next to it instead of at its home. The element cannot answer this question — `isConnected` is true in a pane window, `ownerDocument` is this one in the dock. Both were live bugs. Ask the manager, which knows exactly what it handed to the host: `panes.elementOf(id)`. That holds for every host, and for reconciling after the fact (detail == null), which is what a plugin rebuilding its panel mid-pop-out triggers. 2. `.fb-paned` FORCED `display: block !important`. A panel that is `display:flex` or `grid` would be silently re-laid-out while detached — the exact opposite of "placement only", and precisely the kind of surprise this feature exists to avoid. Removed. Making a hidden panel visible is a separate job, and it now belongs to the manager, which does it without touching the panel's display MODE: clear `hidden`, and clear an inline `display:none` if that is how the panel hides. 3. VISIBILITY IS NOW RESTORED. The hosts used to set `el.hidden = false` and never put it back, so the docs' "core only changes placement" was a lie and a panel's hidden state was quietly lost. The manager stashes both `hidden` and the inline `display` on open and restores them on dock: a panel that was closed when you opened its pane from the tray goes back to being closed; one that was open stays open. Plus: - The launcher rebuilt its whole list on every panes:opened/closed — including the one fired by clicking a button in that list — destroying the button under the user's finger and dropping focus to <body>. It now restores focus to the toggled pane's button. - `_copyStyles` cloned every stylesheet link, including the panes.css that pane.html already loads. Skip sheets the pane document already has. - Docs: the chip may route to the DOCK, not always a window (it goes through detach() → the host router). `header` precedence was documented backwards — an explicit `header` wins. And the visibility contract above is now written down rather than being a surprise. Signed-off-by: topkoa <topkoa@gmail.com>
This commit is contained in:
@@ -135,14 +135,30 @@
|
||||
// the pane window, which then renders nothing at all.
|
||||
el.classList.remove('fb-pane-detached');
|
||||
|
||||
// Make it visible, and remember exactly how it wasn't.
|
||||
//
|
||||
// A plugin's panel is usually hidden until its launcher is clicked, and a
|
||||
// pane can be opened from the tray or the rail without that ever happening.
|
||||
// So we un-hide it — but only in the two ways a panel is actually hidden
|
||||
// (`hidden`, or an inline `display:none`), and we put both back on dock.
|
||||
//
|
||||
// Note what we do NOT do: force a `display`. A panel that is `display:flex`
|
||||
// must stay flex. Neutralising placement is one thing; silently re-laying
|
||||
// out someone's panel is another.
|
||||
const vis = { hidden: el.hidden, display: el.style.display };
|
||||
el.hidden = false;
|
||||
if (el.style.display === 'none') el.style.display = '';
|
||||
|
||||
try {
|
||||
host.place(spec, el);
|
||||
} catch (e) {
|
||||
console.error('[panes] host', host.id, 'failed to take', id, e);
|
||||
el.hidden = vis.hidden;
|
||||
el.style.display = vis.display;
|
||||
return false;
|
||||
}
|
||||
|
||||
open.set(id, { spec, hostId: host.id, el, home });
|
||||
open.set(id, { spec, hostId: host.id, el, home, vis });
|
||||
if (opts.remember !== false) _rememberHost(id, host.id);
|
||||
if (spec.onHost) { try { spec.onHost(host.id, el); } catch (e) { console.error('[panes]', id, 'onHost threw', e); } }
|
||||
// `home` rides along because the element has LEFT this document — anything
|
||||
@@ -207,6 +223,14 @@
|
||||
const host = hosts.get(entry.hostId);
|
||||
try { if (host) host.unplace(id, entry.el); } catch (e) { console.error('[panes] host', entry.hostId, 'threw releasing', id, e); }
|
||||
|
||||
// Put its visibility back exactly as we found it. A panel that was closed
|
||||
// when the pane was opened from the tray goes back to being closed; one that
|
||||
// was open stays open. We forced it visible; we un-force it.
|
||||
if (entry.vis) {
|
||||
entry.el.hidden = entry.vis.hidden;
|
||||
entry.el.style.display = entry.vis.display;
|
||||
}
|
||||
|
||||
if (opts.remember !== false) _rememberHost(id, null);
|
||||
if (entry.spec.onHost) { try { entry.spec.onHost(null, entry.el); } catch (e) { /* non-fatal */ } }
|
||||
_emit('panes:closed', { id: id, host: entry.hostId });
|
||||
@@ -298,6 +322,10 @@
|
||||
// Where an open pane's element came from. The chip needs this to mark the
|
||||
// hole the element left, since it can no longer ask the element itself.
|
||||
homeOf: (id) => { const e = open.get(id); return e ? e.home : null; },
|
||||
// The element a host actually took. The chip needs this to tell "the pane
|
||||
// took MY element" from "the pane took something else" — and it cannot ask
|
||||
// the element, which may now be in a dock card or another window entirely.
|
||||
elementOf: (id) => { const e = open.get(id); return e ? e.el : null; },
|
||||
get: (id) => specs.get(id) || null,
|
||||
list: () => Array.from(specs.values()).map((s) => ({
|
||||
id: s.id, title: s.title, icon: s.icon,
|
||||
|
||||
Reference in New Issue
Block a user