From 53ca6f62b90b8d9035af7f4af023258477ef6c11 Mon Sep 17 00:00:00 2001 From: NixReaper Date: Sun, 12 Jul 2026 11:44:57 -0500 Subject: [PATCH] Remove macOS window-chrome (traffic-light dots, minimize taskbar) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Strip the whole window metaphor as UI baggage: the traffic-light dots injected at the top of every page, the minimize taskbar, and the minimize/maximize state and all their CSS. windowChrome.js and taskbar.js are gone; the only structural DOM the shell still does — wrapping the takeover Dashboard in .aurora-dashboard-frame and reparenting its notices into the card — moved to a focused dashboardFrame.js (initDashboardFrame()). SiteShell.vue drops the taskbar rendering/state; shell-frame.css drops the .aurora-winbar*/.aurora-taskbar*/minimized/maximized rules and the --aurora-taskbar-h / --aurora-editor-winbar-h vars, and zeroes the editor and theme-install frame offsets that reserved a top strip for the dots. shell.js 16.4->13.4 kB. The editor "back to list" crumb lived in the bar and was removed with it (Gutenberg's own W-logo still navigates back). Co-Authored-By: Claude Opus 4.8 --- .../pages/dashboard/components/AuroraCard.vue | 2 +- app/src/shell/SiteShell.vue | 84 +------- app/src/shell/dashboardFrame.js | 35 ++++ app/src/shell/shell-frame.css | 183 ++--------------- app/src/shell/taskbar.js | 57 ------ app/src/shell/windowChrome.js | 185 ------------------ 6 files changed, 51 insertions(+), 495 deletions(-) create mode 100644 app/src/shell/dashboardFrame.js delete mode 100644 app/src/shell/taskbar.js delete mode 100644 app/src/shell/windowChrome.js diff --git a/app/src/pages/dashboard/components/AuroraCard.vue b/app/src/pages/dashboard/components/AuroraCard.vue index 7c470b0..063eea7 100644 --- a/app/src/pages/dashboard/components/AuroraCard.vue +++ b/app/src/pages/dashboard/components/AuroraCard.vue @@ -31,7 +31,7 @@ defineProps({ flex-direction: column; height: 100%; /* Deeper than the generic --aurora-card-bg — the Dashboard is now - wrapped in its own frame (windowChrome.js's .aurora-dashboard-frame, + wrapped in its own frame (dashboardFrame.js's .aurora-dashboard-frame, using --aurora-frame-bg), and that's close in tone to --aurora-card-bg for most presets, so cards would nearly disappear into it otherwise. */ background: var(--aurora-card-bg-deep, var(--aurora-card-bg)); diff --git a/app/src/shell/SiteShell.vue b/app/src/shell/SiteShell.vue index 0d4f4ae..bbbfc3e 100644 --- a/app/src/shell/SiteShell.vue +++ b/app/src/shell/SiteShell.vue @@ -3,8 +3,7 @@ import { ref, onMounted } from 'vue'; import Sidebar from './components/Sidebar.vue'; import Toolbar from './components/Toolbar.vue'; import { applyThemePalette, applyFontFamily } from '@/pages/settings/applyLiveTheme.js'; -import { initWindowChrome } from './windowChrome.js'; -import { getMinimizedWindows, removeMinimizedWindow } from './taskbar.js'; +import { initDashboardFrame } from './dashboardFrame.js'; const props = defineProps({ serverData: { @@ -25,21 +24,7 @@ const toggleMenu = () => { localStorage.setItem('aurora-menu-collapsed', collapsed.value ? '1' : '0'); }; -// Every minimized window (taskbar.js persists the list in sessionStorage -// across the page loads minimizing triggers). Rendered as taskbar items at -// the bottom of every page since SiteShell mounts on all of them — clicking -// one navigates back to it and removes just that entry. -const minimizedWindows = ref([]); -const restoreWindow = (win) => { - removeMinimizedWindow(win.id); - window.location.href = win.url; -}; - onMounted(() => { - minimizedWindows.value = getMinimizedWindows(); - // Reserve bottom space for the taskbar (shell-frame.css) so page content - // stops above it instead of running underneath. - document.documentElement.classList.toggle('aurora-has-taskbar', minimizedWindows.value.length > 0); const settings = props.serverData?.settings || {}; // Every theme preset is its own self-contained dark-toned palette now — // no separate light/dark mode, so this class is always on. It's kept @@ -49,7 +34,7 @@ onMounted(() => { applyThemePalette(settings.theme_preset || 'indigo'); applyCollapsed(); applyFontFamily(settings.font_family); - initWindowChrome(props.serverData?.adminUrl); + initDashboardFrame(); // Signal the shell is live: reveals the framed content and commits to // keeping native chrome hidden (the PHP failsafe stops watching once // aurora-ready is present). @@ -73,74 +58,13 @@ onMounted(() => { :server-data="serverData" @toggle-menu="toggleMenu" /> -
- -
diff --git a/app/src/shell/dashboardFrame.js b/app/src/shell/dashboardFrame.js new file mode 100644 index 0000000..2b5f42a --- /dev/null +++ b/app/src/shell/dashboardFrame.js @@ -0,0 +1,35 @@ +/** + * Structural setup for the takeover Dashboard. + * + * DashboardTakeover.php renders the dashboard into a separate + * #aurora-admin-dashboard-root sibling (above the hidden #wpbody), so unlike + * every other page it never sits inside #wpbody-content and never got that + * element's card frame. Wrap it in .aurora-dashboard-frame so it gets the + * same card treatment, and pull the custom admin notices + * (Notices::render_for_dashboard(), printed as a sibling just before the + * mount point) into that frame so they render as part of the card. + * + * This is the only DOM restructuring the shell does — there is no window + * chrome (title bars, traffic-light controls, minimize taskbar); that whole + * macOS-window metaphor was removed. + */ +export function initDashboardFrame() { + const dashboardRoot = document.getElementById('aurora-admin-dashboard-root'); + if (!dashboardRoot) { + return; + } + // Dedupe: if SiteShell re-mounts, don't wrap a second time. + if (dashboardRoot.parentNode.querySelector('.aurora-dashboard-frame')) { + return; + } + + const frame = document.createElement('div'); + frame.className = 'aurora-dashboard-frame'; + dashboardRoot.parentNode.insertBefore(frame, dashboardRoot); + + const notices = document.getElementById('aurora-admin-dashboard-notices'); + if (notices) { + frame.appendChild(notices); + } + frame.appendChild(dashboardRoot); +} diff --git a/app/src/shell/shell-frame.css b/app/src/shell/shell-frame.css index d8fef43..dc212f4 100644 --- a/app/src/shell/shell-frame.css +++ b/app/src/shell/shell-frame.css @@ -14,13 +14,6 @@ :root { --aurora-sidebar-w: 264px; --aurora-toolbar-h: 56px; - /* SiteShell.vue's taskbar, shown only while a window is minimized - (html.aurora-has-taskbar toggles the bottom space reserved for it). */ - --aurora-taskbar-h: 56px; - /* Height of the strip reserved at the top of the block editor's frame - for .aurora-winbar--editor's traffic-light dots (a sibling element, - not a child of the skeleton — see windowChrome.js). */ - --aurora-editor-winbar-h: 44px; /* Space between the sidebar card and the browser's left/top/bottom edges (Sidebar.vue) — the toolbar and #wpcontent offsets below add the same amount so nothing overlaps the floating sidebar. */ @@ -170,12 +163,6 @@ html.aurora-ready #site-editor { border-radius: var(--aurora-radius-lg); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06); transition: left 0.2s ease; - /* Reserves a strip at the top for .aurora-winbar--editor's dots (a - sibling, not a child — see windowChrome.js) so they sit in their own - clear space instead of overlapping the editor's own logo/toolbar row. - border-box so the padding comes out of the top/left/right/bottom - inset box already defined above, rather than adding to it. */ - padding-top: var(--aurora-editor-winbar-h); box-sizing: border-box; /* border-radius alone doesn't clip children — Gutenberg's own white canvas background ran straight past the rounded bottom corners as a @@ -250,48 +237,6 @@ html.aurora-ready body.post-php #wpbody-content { padding: 0 !important; } -html.aurora-ready body.block-editor-page #wpbody-content > .aurora-winbar, -html.aurora-ready body.post-new-php #wpbody-content > .aurora-winbar, -html.aurora-ready body.post-php #wpbody-content > .aurora-winbar { - display: none !important; -} - -/* SiteShell.vue's taskbar floats along the bottom edge (inset by - --aurora-sidebar-gap, same as the sidebar) only while a window is - minimized. A plain margin-bottom only guarantees a gap once the page is - scrolled all the way down — content taller than the viewport still - renders underneath the fixed taskbar on first paint, since a fixed - element doesn't reserve space from the rest of the page's flow. Instead, - cap the content box's own height to whatever's actually left between the - toolbar and the taskbar and let *it* scroll internally — the same way - the toolbar's reserved space at the top never lets content start behind - it, not just "eventually scroll clear of it". */ -html.aurora-has-taskbar #wpbody-content, -html.aurora-has-taskbar .aurora-dashboard-frame { - /* #wpbody-content's base rule sets min-height: calc(100vh - toolbar-h - - 40px) for the normal (no-taskbar) case — per spec, when min-height is - larger than max-height, min-height always wins and max-height is - silently ignored. Without this override the box kept sizing to that - taller min-height regardless of the taskbar, which is why the - max-height below appeared to do nothing. */ - min-height: 0; - max-height: calc( - 100vh - var(--aurora-toolbar-h) - 16px - 24px - var(--aurora-taskbar-h) - - var(--aurora-sidebar-gap) * 2 - ); - overflow-y: auto; - overflow-anchor: none; -} - -/* The block editor's skeleton is already positioned with fixed insets - (top/left/right/bottom) rather than margin, so reserving taskbar space - is just moving its bottom inset in — no max-height/overflow trick - needed there, unlike the margin-based elements above. */ -html.aurora-has-taskbar .interface-interface-skeleton, -html.aurora-has-taskbar #site-editor { - bottom: calc(24px + var(--aurora-taskbar-h) + var(--aurora-sidebar-gap) * 2) !important; -} - /* Theme installer preview ("Add Themes" > click a theme > full "Preview & Install" overlay, theme-install.php). WP core's own .wp-full-overlay component (shared with the Customizer, but only .theme-install-overlay @@ -355,86 +300,21 @@ html.aurora-ready .theme-install-overlay.collapsed { html.aurora-ready .theme-install-overlay .wp-full-overlay-sidebar { left: calc(var(--aurora-sidebar-w) + var(--aurora-sidebar-gap) * 2 + 24px) !important; - top: calc(var(--aurora-toolbar-h) + 16px + var(--aurora-editor-winbar-h)) !important; + top: calc(var(--aurora-toolbar-h) + 16px) !important; bottom: 24px !important; height: auto !important; border-top-left-radius: var(--aurora-radius-lg); } html.aurora-ready .theme-install-overlay .wp-full-overlay-main { - top: var(--aurora-editor-winbar-h) !important; + top: 0 !important; border-top-right-radius: var(--aurora-radius-lg); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06); } -/* macOS-style title bar (windowChrome.js). Most pages get it injected as - the first child of #wpbody-content — negative margins cancel the 32px - padding above so it spans edge-to-edge like a real window title bar. */ -.aurora-winbar { - display: flex; - align-items: center; - gap: 8px; -} -.aurora-winbar--editor { - position: fixed; - /* Centered vertically within the skeleton's reserved top strip - (--aurora-editor-winbar-h), inset from its left edge to line up with - the padding every other title bar uses. */ - top: calc( - var(--aurora-toolbar-h) + 16px + (var(--aurora-editor-winbar-h) - 12px) / 2 - ); - left: calc(var(--aurora-sidebar-w) + var(--aurora-sidebar-gap) * 2 + 24px + 20px); - height: 12px; - padding: 0; - background: transparent; - border: 0; - border-radius: 0; - box-shadow: none; - z-index: 100000; - transition: left 0.2s ease; -} -#wpbody-content > .aurora-winbar { - margin: -32px -32px 20px -32px; - padding: 14px 16px; - border-bottom: 1px solid var(--aurora-frame-border); - border-top-left-radius: var(--aurora-radius-lg); - border-top-right-radius: var(--aurora-radius-lg); -} -.aurora-winbar__crumb { - margin-left: 8px; - font-size: 0.75rem; - font-weight: 500; - color: var(--aurora-text-muted); - text-decoration: none; - white-space: nowrap; -} -.aurora-winbar__crumb:hover { - color: var(--aurora-text); -} -.aurora-winbar__dot { - width: 12px; - height: 12px; - border-radius: 50%; - border: none; - padding: 0; - cursor: pointer; -} -.aurora-winbar__dot:hover { - filter: brightness(1.15); -} -.aurora-winbar__dot--close { - background: #ff5f57; -} -.aurora-winbar__dot--minimize { - background: #febc2e; -} -.aurora-winbar__dot--maximize { - background: #28c840; -} - /* The Dashboard bypasses #wpbody-content (DashboardTakeover.php renders - it into a separate sibling — see windowChrome.js), so it never got the - card frame every other page has. windowChrome.js wraps the bar + the - dashboard's mount point in this div to give it the same treatment. */ + it into a separate sibling — see dashboardFrame.js), so it never got the + card frame every other page has. dashboardFrame.js wraps the dashboard's + mount point in this div to give it the same treatment. */ .aurora-dashboard-frame { background: var(--aurora-frame-bg); border: 1px solid var(--aurora-frame-border); @@ -444,25 +324,19 @@ html.aurora-ready .theme-install-overlay .wp-full-overlay-main { box-sizing: border-box; /* Same unconditional height cap as #wpbody-content's base rule — this element never got it, since the Dashboard bypasses #wpbody-content - entirely (a separate sibling — see windowChrome.js) and only had the - taskbar-present variant below. Once html/body were locked to - overflow:hidden (to kill a phantom document-level scrollbar on - another page), the dashboard's content past the first ~1500px became - completely unreachable: no internal scroll here, and no document + entirely (a separate sibling — see dashboardFrame.js). Once html/body + were locked to overflow:hidden (to kill a phantom document-level + scrollbar on another page), the dashboard's content past the first + ~1500px became completely unreachable: no internal scroll here, and + no document scroll left to fall back on either. */ max-height: calc(100vh - var(--aurora-toolbar-h) - 40px); overflow-y: auto; overflow-anchor: none; } -.aurora-dashboard-frame > .aurora-winbar { - padding: 14px 20px; - border-bottom: 1px solid var(--aurora-frame-border); - border-top-left-radius: var(--aurora-radius-lg); - border-top-right-radius: var(--aurora-radius-lg); -} /* Custom admin notices (Notices::render_for_dashboard(), reparented in - here by windowChrome.js) — native-dark.css already themes .notice + here by dashboardFrame.js) — native-dark.css already themes .notice elsewhere via #wpbody-content, but that stylesheet isn't loaded on the Dashboard at all (Shell::is_own_page() treats index.php as one of Aurora's own pages), so it needs its own copy of the same treatment @@ -476,41 +350,6 @@ html.aurora-ready .theme-install-overlay .wp-full-overlay-main { margin: 16px 20px 0; } -/* Yellow dot: on the Dashboard itself there's nowhere further "home" to - send it, so minimize just collapses the frame down to the title bar in - place — everywhere else, minimize navigates to the dashboard instead - (see windowChrome.js) and SiteShell.vue's taskbar offers a way back. */ -html.aurora-minimized #aurora-admin-dashboard-root { - display: none !important; -} - -/* Green dot: hide Aurora's own chrome (sidebar/toolbar) and let the - content reclaim the full browser window, like restoring a real OS - window to fullscreen. */ -html.aurora-maximized .sidebar, -html.aurora-maximized .toolbar { - display: none !important; -} -html.aurora-ready.aurora-maximized #wpcontent { - margin-left: 0 !important; -} -html.aurora-ready.aurora-maximized .interface-interface-skeleton, -html.aurora-ready.aurora-maximized #site-editor { - top: 0 !important; - left: 0 !important; - right: 0 !important; - bottom: 0 !important; - height: auto !important; - border-radius: 0; -} -html.aurora-maximized .aurora-winbar--editor { - top: calc((var(--aurora-editor-winbar-h) - 12px) / 2); - left: 20px; -} -html.aurora-maximized .aurora-taskbar { - left: 0 !important; -} - /* The settings page renders its own two boxed panels, so drop the outer content frame there — leaving just those panels on the dark backdrop. No background here: #wpbody-content is inset from the sidebar/gutter, diff --git a/app/src/shell/taskbar.js b/app/src/shell/taskbar.js deleted file mode 100644 index 672749e..0000000 --- a/app/src/shell/taskbar.js +++ /dev/null @@ -1,57 +0,0 @@ -/** - * Tracks every "minimized" window across page loads. Aurora is a normal - * multi-page WP admin (each nav is a full page load), so a real taskbar - * needs to survive navigation — sessionStorage (tab-scoped, clears when the - * tab closes) is enough for that. Stored as a list, not a single slot — - * minimizing a second page used to silently overwrite the first one's - * entry, so only the most recent minimize ever showed up in the taskbar. - */ -const STORAGE_KEY = 'aurora-minimized-windows'; - -export function getMinimizedWindows() { - try { - const raw = sessionStorage.getItem(STORAGE_KEY); - const parsed = raw ? JSON.parse(raw) : []; - return Array.isArray(parsed) ? parsed : []; - } catch { - return []; - } -} - -function saveMinimizedWindows(list) { - try { - sessionStorage.setItem(STORAGE_KEY, JSON.stringify(list)); - } catch { - /* sessionStorage unavailable (e.g. private mode) — minimize just won't persist */ - } -} - -/** Adds (or, if the same page is already minimized, replaces) an entry. */ -export function addMinimizedWindow(title, url) { - const list = getMinimizedWindows().filter((w) => w.url !== url); - list.push({ id: `${Date.now()}-${Math.random().toString(36).slice(2)}`, title, url }); - saveMinimizedWindows(list); -} - -export function removeMinimizedWindow(id) { - saveMinimizedWindows(getMinimizedWindows().filter((w) => w.id !== id)); -} - -/** - * Best-effort readable label for the current page, used as the taskbar - * item's title. Prefers the page's own on-screen

over document.title — - * WordPress's title-tag lookup walks the $submenu global to find a page's - * title, which comes up empty for Aurora's sub-app pages (SubApps.php - * registers each one normally, then immediately remove_submenu_page()s it - * to keep it out of the native menu — that breaks WP's own title lookup, - * not just this). document.title is still the fallback for pages where - * that isn't an issue (Settings, native WP pages, the Dashboard). - */ -export function currentPageTitle() { - const heading = document.querySelector('#wpbody-content h1, #aurora-admin-dashboard-root h1'); - if (heading && heading.textContent.trim()) { - return heading.textContent.trim(); - } - const raw = document.title || ''; - return raw.split('‹')[0].trim() || 'Window'; -} diff --git a/app/src/shell/windowChrome.js b/app/src/shell/windowChrome.js deleted file mode 100644 index df3851d..0000000 --- a/app/src/shell/windowChrome.js +++ /dev/null @@ -1,185 +0,0 @@ -/** - * Adds a macOS-style traffic-light title bar to the top of the page content. - * Three cases, in priority order: - * 1. The Dashboard — DashboardTakeover.php renders it into a separate - * #aurora-admin-dashboard-root sibling, above #wpbody (which it hides), - * to fully replace the native dashboard. Gets wrapped in a new - * .aurora-dashboard-frame div to match the card treatment - * #wpbody-content already has everywhere else. - * 2. The block editor — gets only the traffic-light controls, overlaid on - * the editor frame without a full-width titlebar surface. - * 3. Everything else — native WP pages and all of Aurora's own Vue pages, - * since each mounts its root div inside #wpbody-content. The bar is - * inserted as its first child. - * - * Red closes (navigates back to the Aurora dashboard). Yellow minimizes — - * on any page other than the dashboard, that means "save where I am and - * send me home", with SiteShell.vue's taskbar offering a way back; on the - * dashboard itself (already home) it just collapses in place instead, - * since there's nowhere further back to send it. Green hides Aurora's own - * sidebar/toolbar so the content fills the browser window. Minimized pages - * are tracked as a list (taskbar.js), not a single slot, so minimizing - * more than one shows up as separate taskbar items rather than the latest - * silently replacing the previous one. - */ -import { addMinimizedWindow, currentPageTitle } from './taskbar.js'; - -function buildBar(adminUrl, isDashboard) { - const bar = document.createElement('div'); - bar.className = 'aurora-winbar'; - - const makeDot = (variant, label, onClick) => { - const dot = document.createElement('button'); - dot.type = 'button'; - dot.className = 'aurora-winbar__dot aurora-winbar__dot--' + variant; - dot.setAttribute('aria-label', label); - dot.title = label; - dot.addEventListener('click', onClick); - return dot; - }; - - const root = document.documentElement; - - bar.appendChild( - makeDot('close', 'Close', () => { - window.location.href = adminUrl || '/wp-admin/'; - }) - ); - bar.appendChild( - makeDot('minimize', 'Minimize', () => { - if (isDashboard) { - root.classList.toggle('aurora-minimized'); - root.classList.remove('aurora-maximized'); - } else { - addMinimizedWindow(currentPageTitle(), window.location.href); - window.location.href = adminUrl || '/wp-admin/'; - } - }) - ); - bar.appendChild( - makeDot('maximize', 'Maximize', () => { - root.classList.toggle('aurora-maximized'); - root.classList.remove('aurora-minimized'); - }) - ); - - return bar; -} - -function isBlockEditorPage() { - const path = window.location.pathname; - return ( - document.body.classList.contains('block-editor-page') || - path.endsWith('/post-new.php') || - path.endsWith('/post.php') - ); -} - -// WP core adds a "post-type-{slug}" class to on every post edit -// screen — the same signal used here to build a "back to the list" link, -// since Posts ("edit.php") and Pages ("edit.php?post_type=page") are now -// hijacked in place at their native URLs (see HijackedNativePages.php) and -// there's no single admin.php?page=... URL to hardcode anymore. -// -// The Site Editor (site-editor.php) also carries the "block-editor-page" -// body class isBlockEditorPage() matches on, but has no "post-type-*" -// class (it edits templates/template parts, not a post) — returning null -// here rather than guessing "Posts" is what keeps the crumb from showing -// up somewhere it doesn't make sense. -function editorBackLink(adminUrl) { - const match = [...document.body.classList].find((c) => c.startsWith('post-type-')); - if (!match) { - return null; - } - - const postType = match.replace('post-type-', ''); - const base = adminUrl || '/wp-admin/'; - if (postType === 'post') { - return { label: 'Posts', href: base + 'edit.php' }; - } - if (postType === 'page') { - return { label: 'Pages', href: base + 'edit.php?post_type=page' }; - } - return { label: postType, href: base + 'edit.php?post_type=' + encodeURIComponent(postType) }; -} - -// theme-install.php's "Preview & Install" overlay (WP core's -// .wp-full-overlay component) needs a permanently-running observer, not a -// one-shot check, for two reasons: (1) core's own Backbone view creates it -// lazily the first time a theme is clicked, so it's missing from the -// initial DOM at initWindowChrome()'s call time; (2) every subsequent -// theme selection re-renders the overlay's contents from scratch (its own -// view.render() replaces all children to show the newly-selected theme's -// details), wiping out anything inserted into it — confirmed live: the bar -// was there after the very first click, gone after picking a second theme. -// Kept running for the page's whole lifetime rather than disconnecting -// after the first successful insert. Independent of the rest of this -// file's dedupe guard (a normal page winbar already exists in -// #wpbody-content here too; this is a second, additional bar for the -// overlay specifically, not a replacement for it). -function watchForThemeOverlay(adminUrl) { - const ensureInserted = () => { - const overlay = document.querySelector('.theme-install-overlay'); - if (overlay && !overlay.querySelector('.aurora-winbar')) { - const bar = buildBar(adminUrl, false); - bar.classList.add('aurora-winbar--editor'); - overlay.insertBefore(bar, overlay.firstChild); - } - }; - - ensureInserted(); - new MutationObserver(ensureInserted).observe(document.body, { childList: true, subtree: true }); -} - -export function initWindowChrome(adminUrl) { - if (document.body.classList.contains('theme-install-php')) { - watchForThemeOverlay(adminUrl); - } - - if (document.querySelector('.aurora-winbar')) { - return; - } - - const dashboardRoot = document.getElementById('aurora-admin-dashboard-root'); - if (dashboardRoot) { - const bar = buildBar(adminUrl, true); - const frame = document.createElement('div'); - frame.className = 'aurora-dashboard-frame'; - dashboardRoot.parentNode.insertBefore(frame, dashboardRoot); - frame.appendChild(bar); - // Custom admin notices (Notices::render_for_dashboard(), printed as a - // sibling right before the mount point) — reparented into the frame - // here too, so they render as part of the dashboard's own card - // instead of sitting outside it unstyled. Normally these reach the - // user via the plain admin_notices hook, but that renders inside - // #wpbody, which the Dashboard hides entirely to hide the *native* - // dashboard widgets — this is the replacement path for that one page. - const notices = document.getElementById('aurora-admin-dashboard-notices'); - if (notices) frame.appendChild(notices); - frame.appendChild(dashboardRoot); - return; - } - - if (isBlockEditorPage()) { - const bar = buildBar(adminUrl, false); - bar.classList.add('aurora-winbar--editor'); - - const back = editorBackLink(adminUrl); - if (back) { - const crumb = document.createElement('a'); - crumb.className = 'aurora-winbar__crumb'; - crumb.href = back.href; - crumb.textContent = '← ' + back.label; - bar.appendChild(crumb); - } - - document.body.appendChild(bar); - return; - } - - const wpbodyContent = document.getElementById('wpbody-content'); - if (wpbodyContent) { - const bar = buildBar(adminUrl, false); - wpbodyContent.insertBefore(bar, wpbodyContent.firstChild); - } -}