PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.10
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.10
1.1.10 1.1.9 1.1.8 1.1.7 1.1.6 1.1.5 1.1.4 1.1.3 1.1.2 1.1.1 1.1.0 1.0.1 1.0.0 0.9.8 0.9.7 0.9.6 0.9.4 0.9.5 0.9.3 0.9.2 0.9.1 0.9.0 0.8.9 0.8.8 0.8.7 All 34 releases
← All changes | includes/assets.php +253 -243 0.9.81.1.10 View file →
@@ -1,12 +1,12 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode asset registration.
3 + * OpenStation asset registration.
4 4 *
5 - * Registers all desktop-mode CSS and JS handles with WordPress so they can
5 + * Registers all openstation CSS and JS handles with WordPress so they can
6 6 * be enqueued from anywhere in the plugin (or by third parties).
7 7 *
8 - * @package WPDesktopMode
8 + * @package OpenStation
9 9 */
10 10
11 11 defined( 'ABSPATH' ) || exit;
12 12
@@ -20,10 +20,10 @@
20 20 * @param string $relative Stylesheet path relative to the plugin dir.
21 21 * @param string $fallback Version to use when the file is missing.
22 22 * @return string Version string.
23 23 */
24 -function desktop_mode_css_subtree_version( $relative, $fallback ) {
25 - $root = DESKTOP_MODE_DIR . $relative;
24 +function openstation_css_subtree_version( $relative, $fallback ) {
25 + $root = OPENSTATION_DIR . $relative;
26 26 if ( ! file_exists( $root ) ) {
27 27 return (string) $fallback;
28 28 }
29 29 $max = (int) filemtime( $root );
@@ -48,16 +48,16 @@
48 48 return (string) $max;
49 49 }
50 50
51 51 /**
52 - * Registers the desktop mode CSS and JS handles.
52 + * Registers the OpenStation CSS and JS handles.
53 53 */
54 -function desktop_mode_register_assets() {
55 - $version = DESKTOP_MODE_VERSION;
56 - $suffix = desktop_mode_asset_suffix();
54 +function openstation_register_assets() {
55 + $version = OPENSTATION_VERSION;
56 + $suffix = openstation_asset_suffix();
57 57
58 58 // `filemtime`-stamped version for built bundles. The plugin-wide
59 - // `DESKTOP_MODE_VERSION` is bumped per release, but the bundles
59 + // `OPENSTATION_VERSION` is bumped per release, but the bundles
60 60 // iterate faster — without a per-file mtime stamp, two clients
61 61 // loading the same `?ver=…` URL can be served different bytes
62 62 // (whichever build was on disk at upload time). Stamping with the
63 63 // file's modification time guarantees the URL changes whenever the
@@ -64,13 +64,12 @@
64 64 // file does, so "is my fix deployed?" is answerable from the
65 65 // network tab. Falls back to `$version` when the file is missing
66 66 // (test envs that import this file before the build runs).
67 67 $built_version = static function ( $relative ) use ( $version ) {
68 - $path = DESKTOP_MODE_DIR . $relative;
68 + $path = OPENSTATION_DIR . $relative;
69 69 return file_exists( $path ) ? (string) filemtime( $path ) : $version;
70 70 };
71 71
72 -
73 72 // Styles.
74 73 // `filemtime`-stamped, NOT the plugin-wide `$version`. This file
75 74 // is the token catalogue every other sheet resolves `var()`s
76 75 // against, and it changes whenever the palette does — which is a
@@ -78,35 +77,36 @@
78 77 // stamp the browser holds the old palette until a hard reload,
79 78 // and the symptom is maddening: a themed shell where some
80 79 // surfaces update and others don't.
81 80 wp_register_style(
82 - 'desktop-mode-variables',
83 - DESKTOP_MODE_URL . 'assets/css/variables.css',
81 + 'os-variables',
82 + OPENSTATION_URL . 'assets/css/variables.css',
84 83 array(),
85 84 $built_version( 'assets/css/variables.css' )
86 85 );
87 86 // `filemtime`-stamped so the `<link rel="stylesheet">` URL matches the
88 87 // `<link rel="preload" as="style">` hint emitted by
89 - // `desktop_mode_print_preload_hints()` (which stamps with filemtime).
88 + // `openstation_print_preload_hints()` (which stamps with filemtime).
90 89 // Registering this with the plain `$version` instead produced two
91 90 // different `?ver=` query strings for the same file, so the browser
92 91 // never matched the preload to the stylesheet and logged "preloaded
93 92 // but not used within a few seconds from the window's load event".
94 93 wp_register_style(
95 - 'desktop-mode',
96 - DESKTOP_MODE_URL . 'assets/css/desktop.css',
97 - array( 'desktop-mode-variables' ),
94 + 'openstation',
95 + OPENSTATION_URL . 'assets/css/desktop.css',
96 + array( 'os-variables' ),
98 97 $built_version( 'assets/css/desktop.css' )
99 98 );
99 +
100 100 /*
101 101 * Window styles — one handle per sheet, chained by dependency.
102 102 *
103 103 * These used to be `@import url( … )`ed from `windows.css` under
104 - * the single `desktop-mode-windows` handle. That was a standing
104 + * the single `os-windows` handle. That was a standing
105 105 * cache bug: an `@import` URL carries no `?ver=`, so a changed
106 106 * sub-sheet had no URL for the browser to invalidate. Stamping the
107 107 * PARENT with the subtree's max mtime (which is what
108 - * `desktop_mode_css_subtree_version()` was for) made the browser
108 + * `openstation_css_subtree_version()` was for) made the browser
109 109 * re-fetch `windows.css` and then request each sub-sheet at an
110 110 * unchanged URL — free to be served from its heuristic cache. The
111 111 * result was edits not landing until a hard refresh, and rules
112 112 * being relocated into `windows.css` purely to dodge it.
@@ -116,31 +116,32 @@
116 116 *
117 117 * THE DEPENDENCY CHAIN IS LOAD-BEARING. WordPress prints
118 118 * dependencies before dependents, so chaining each sheet to the
119 119 * previous one reproduces the order the `@import` block had, and
120 - * `desktop-mode-windows` (which depends on the last link) still
120 + * `os-windows` (which depends on the last link) still
121 121 * prints after them and still wins ties:
122 122 *
123 123 * window-chrome → window-states → effects → window-links
124 124 * → windows
125 125 *
126 - * `window-overview` and `os-settings` are deliberately NOT in this
127 - * chain — they are registered below, after `desktop-mode-windows`,
128 - * so they can load deferred. Adding a sheet here means splicing it
129 - * into the chain, not appending an unrelated dependency: order is
130 - * the contract.
126 + * `window-overview` is deliberately NOT in this chain — it is
127 + * registered below, after `os-windows`, so it can load deferred.
128 + * Adding a sheet here means splicing it into the chain, not
129 + * appending an unrelated dependency: order is the contract.
130 + * (The Preferences window's sheet is not here at all: it rides
131 + * the `apps/os-settings/` app as a first-open companion style.)
131 132 */
132 133 $window_sheets = array(
133 - 'desktop-mode-window-chrome' => 'assets/css/window-chrome.css',
134 - 'desktop-mode-window-states' => 'assets/css/window-states.css',
135 - 'desktop-mode-effects' => 'assets/css/effects.css',
136 - 'desktop-mode-window-links' => 'assets/css/window-links.css',
134 + 'os-window-chrome' => 'assets/css/window-chrome.css',
135 + 'os-window-states' => 'assets/css/window-states.css',
136 + 'os-effects' => 'assets/css/effects.css',
137 + 'os-window-links' => 'assets/css/window-links.css',
137 138 );
138 - $previous = array( 'desktop-mode-variables', 'dashicons' );
139 + $previous = array( 'os-variables', 'dashicons' );
139 140 foreach ( $window_sheets as $handle => $relative ) {
140 141 wp_register_style(
141 142 $handle,
142 - DESKTOP_MODE_URL . $relative,
143 + OPENSTATION_URL . $relative,
143 144 $previous,
144 145 $built_version( $relative )
145 146 );
146 147 $previous = array( $handle );
@@ -149,43 +150,98 @@
149 150 // Entry point. Depends on the tail of the chain above, so
150 151 // enqueuing this one handle still pulls in every critical window
151 152 // sheet — the behaviour callers had when they were `@import`s.
152 153 wp_register_style(
153 - 'desktop-mode-windows',
154 - DESKTOP_MODE_URL . 'assets/css/windows.css',
154 + 'os-windows',
155 + OPENSTATION_URL . 'assets/css/windows.css',
155 156 $previous,
156 157 $built_version( 'assets/css/windows.css' )
157 158 );
158 - // These two load DEFERRED (see `desktop_mode_defer_non_critical_styles()`):
159 - // the UI they style — the OS Settings panel and the window
160 - // overview — is lazy-loaded JS that can never be on screen at
161 - // first paint, so ~47 KB of CSS has no business blocking render.
162 - // They depend on `desktop-mode-windows` so they print after it,
163 - // preserving the cascade position they had as `@import`s.
159 + // Loads DEFERRED (see `openstation_defer_non_critical_styles()`):
160 + // the UI it styles — the window overview — is lazy-loaded JS that
161 + // can never be on screen at first paint, so its CSS has no
162 + // business blocking render. It depends on `os-windows` so it
163 + // prints after it, preserving the cascade position it had as an
164 + // `@import`.
164 165 wp_register_style(
165 - 'desktop-mode-window-overview',
166 - DESKTOP_MODE_URL . 'assets/css/window-overview.css',
167 - array( 'desktop-mode-windows' ),
166 + 'os-window-overview',
167 + OPENSTATION_URL . 'assets/css/window-overview.css',
168 + array( 'os-windows' ),
168 169 $built_version( 'assets/css/window-overview.css' )
169 170 );
171 + // Solo mode — one window, no desk around it. Loads last so it can
172 + // hide surfaces the sheets above declared, and only enqueues on a
173 + // solo request, so a normal shell never pays for it.
170 174 wp_register_style(
171 - 'desktop-mode-os-settings',
172 - DESKTOP_MODE_URL . 'assets/css/os-settings.css',
173 - array( 'desktop-mode-windows' ),
174 - $built_version( 'assets/css/os-settings.css' )
175 + 'os-solo',
176 + OPENSTATION_URL . 'assets/css/solo.css',
177 + array( 'os-windows' ),
178 + $built_version( 'assets/css/solo.css' )
175 179 );
176 180 wp_register_style(
177 - 'desktop-mode-dock',
178 - DESKTOP_MODE_URL . 'assets/css/dock.css',
179 - array( 'desktop-mode-variables', 'dashicons' ),
181 + 'os-dock',
182 + OPENSTATION_URL . 'assets/css/dock.css',
183 + array( 'os-variables', 'dashicons' ),
180 184 $built_version( 'assets/css/dock.css' )
181 185 );
182 186 wp_register_style(
183 - 'desktop-mode-dock-peek',
184 - DESKTOP_MODE_URL . 'assets/css/dock-peek.css',
185 - array( 'desktop-mode-dock' ),
187 + 'os-dock-peek',
188 + OPENSTATION_URL . 'assets/css/dock-peek.css',
189 + array( 'os-dock' ),
186 190 $built_version( 'assets/css/dock-peek.css' )
187 191 );
192 + // The phone layer. Every rule is scoped to
193 + // `html[data-os-mode="mobile"]`, so the sheet is inert on a
194 + // desktop and the first paint on a phone is already right (the
195 + // head stamp writes the attribute before any stylesheet applies).
196 + // Depends on the dock and window sheets because it overrides them.
197 + wp_register_style(
198 + 'os-mobile',
199 + OPENSTATION_URL . 'assets/css/mobile.css',
200 + array( 'os-variables', 'dashicons', 'os-dock', 'os-windows' ),
201 + $built_version( 'assets/css/mobile.css' )
202 + );
203 + // The notch — the shell's top-centre voice and the site
204 + // assistant's front door. Scoped to `.os-notch`.
205 + wp_register_style(
206 + 'os-notch',
207 + OPENSTATION_URL . 'assets/css/notch.css',
208 + array( 'os-variables' ),
209 + $built_version( 'assets/css/notch.css' )
210 + );
211 + // The workspace wizard. Scoped to `.os-workspace-wizard`, so it is
212 + // inert until the user opens it from the overview bar's `+` or a
213 + // tile's Edit. Those controls are styled with the rest of the bar
214 + // in `window-overview.css`.
215 + wp_register_style(
216 + 'os-workspaces',
217 + OPENSTATION_URL . 'assets/css/workspaces.css',
218 + array( 'os-variables', 'dashicons' ),
219 + $built_version( 'assets/css/workspaces.css' )
220 + );
221 + // Keyboard-shortcuts window. Scoped to `.os-shortcuts`, so it is
222 + // inert until the System menu opens the window, and unconditional
223 + // for the same reason the layout sheet is: the window can be
224 + // opened at any moment and a deferred sheet would paint it raw.
225 + wp_register_style(
226 + 'os-shortcuts',
227 + OPENSTATION_URL . 'assets/css/shortcuts.css',
228 + array( 'os-variables' ),
229 + $built_version( 'assets/css/shortcuts.css' )
230 + );
231 + // The OpenStation desktop layout — the core/plugin seam on the rail
232 + // plus the constellation hover-submenu flyout. Both surfaces are
233 + // scoped (`[data-os-layout="openstation"]` / `.os-constellation`),
234 + // so the sheet is inert in every other layout and is loaded
235 + // unconditionally rather than gated on the user's current pick:
236 + // the layout is switchable live from OpenStation Preferences, and a
237 + // conditional enqueue would leave the first switch unstyled.
238 + wp_register_style(
239 + 'os-openstation-layout',
240 + OPENSTATION_URL . 'assets/css/openstation-layout.css',
241 + array( 'os-dock' ),
242 + $built_version( 'assets/css/openstation-layout.css' )
243 + );
188 244 // `filemtime`-stamped — the chromeless overrides iterate faster
189 245 // than the plugin-wide version bumps (per-page compat shims and
190 246 // page-title-action exceptions land in patches), and a stale
191 247 // cached copy means the user sees yesterday's rules. Without the
@@ -191,11 +247,11 @@
191 247 // cached copy means the user sees yesterday's rules. Without the
192 248 // stamp, the browser keeps `?ver=0.8.1` valid for the whole
193 249 // release cycle.
194 250 wp_register_style(
195 - 'desktop-mode-chromeless',
196 - DESKTOP_MODE_URL . 'assets/css/chromeless.css',
197 - array( 'desktop-mode' ),
251 + 'os-chromeless',
252 + OPENSTATION_URL . 'assets/css/chromeless.css',
253 + array( 'openstation' ),
198 254 $built_version( 'assets/css/chromeless.css' )
199 255 );
200 256
201 257 // `filemtime`-stamped — the AI assistant surface (error states,
@@ -204,17 +260,17 @@
204 260 // valid for the whole release cycle and the user keeps seeing
205 261 // yesterday's CSS even after a hard reload.
206 262 wp_register_style(
207 263 'desktop-mode-ai-assistant',
208 - DESKTOP_MODE_URL . 'assets/css/ai-assistant.css',
209 - array( 'desktop-mode-variables' ),
264 + OPENSTATION_URL . 'assets/css/ai-assistant.css',
265 + array( 'os-variables' ),
210 266 $built_version( 'assets/css/ai-assistant.css' )
211 267 );
212 268
213 269 wp_register_style(
214 270 'desktop-mode-bug-report',
215 - DESKTOP_MODE_URL . 'assets/css/bug-report.css',
216 - array( 'desktop-mode-variables' ),
271 + OPENSTATION_URL . 'assets/css/bug-report.css',
272 + array( 'os-variables' ),
217 273 $built_version( 'assets/css/bug-report.css' )
218 274 );
219 275
220 276 // `filemtime` instead of the plugin-wide `$version` for the
@@ -219,55 +275,25 @@
219 275
220 276 // `filemtime` instead of the plugin-wide `$version` for the
221 277 // recycle-bin CSS — this file iterates faster than the bundle
222 278 // and we never want a stale CSS cache to mask a real fix.
223 - $recycle_bin_css = DESKTOP_MODE_DIR . 'assets/css/recycle-bin.css';
279 + $recycle_bin_css = OPENSTATION_DIR . 'assets/css/recycle-bin.css';
224 280 wp_register_style(
225 281 'desktop-mode-recycle-bin',
226 - DESKTOP_MODE_URL . 'assets/css/recycle-bin.css',
227 - array( 'desktop-mode-variables', 'dashicons' ),
282 + OPENSTATION_URL . 'assets/css/recycle-bin.css',
283 + array( 'os-variables', 'dashicons' ),
228 284 file_exists( $recycle_bin_css ) ? (string) filemtime( $recycle_bin_css ) : $version
229 285 );
230 286
231 - // `filemtime` for the native Posts window CSS — same rationale as
232 - // the recycle-bin CSS: bundle iterates faster than the plugin
233 - // version and stale caches are worse than the cost of a 304.
234 - $posts_window_css = DESKTOP_MODE_DIR . 'assets/css/posts-window.css';
235 - wp_register_style(
236 - 'desktop-mode-posts-window',
237 - DESKTOP_MODE_URL . 'assets/css/posts-window.css',
238 - array( 'desktop-mode-variables', 'dashicons' ),
239 - file_exists( $posts_window_css ) ? (string) filemtime( $posts_window_css ) : $version
240 - );
241 -
242 - // Native Plugins window CSS — same `filemtime`-cache-bust posture
243 - // as the Posts/Recycle Bin styles.
244 - $plugins_window_css = DESKTOP_MODE_DIR . 'assets/css/plugins-window.css';
245 - wp_register_style(
246 - 'desktop-mode-plugins-window',
247 - DESKTOP_MODE_URL . 'assets/css/plugins-window.css',
248 - array( 'desktop-mode-variables', 'dashicons' ),
249 - file_exists( $plugins_window_css ) ? (string) filemtime( $plugins_window_css ) : $version
250 - );
251 -
252 - // Native Comments window CSS — same `filemtime` posture.
253 - $comments_window_css = DESKTOP_MODE_DIR . 'assets/css/comments-window.css';
254 - wp_register_style(
255 - 'desktop-mode-comments-window',
256 - DESKTOP_MODE_URL . 'assets/css/comments-window.css',
257 - array( 'desktop-mode-variables', 'dashicons' ),
258 - file_exists( $comments_window_css ) ? (string) filemtime( $comments_window_css ) : $version
259 - );
260 -
261 287 // Files-on-the-Desktop tile + layer styles. `filemtime` for the
262 - // same reason as the recycle-bin / posts-window CSS: this file
288 + // same reason as the recycle-bin CSS: this file
263 289 // iterates faster than the plugin version, and a stale cache
264 290 // would mask a real fix.
265 - $desktop_files_css = DESKTOP_MODE_DIR . 'assets/css/desktop-files.css';
291 + $desktop_files_css = OPENSTATION_DIR . 'assets/css/desktop-files.css';
266 292 wp_register_style(
267 - 'desktop-mode-files',
268 - DESKTOP_MODE_URL . 'assets/css/desktop-files.css',
269 - array( 'desktop-mode-variables', 'dashicons' ),
293 + 'os-files',
294 + OPENSTATION_URL . 'assets/css/desktop-files.css',
295 + array( 'os-variables', 'dashicons' ),
270 296 file_exists( $desktop_files_css ) ? (string) filemtime( $desktop_files_css ) : $version
271 297 );
272 298
273 299 // Games hub window (launcher grid, scoreboard, challenges) +
@@ -272,41 +298,58 @@
272 298
273 299 // Games hub window (launcher grid, scoreboard, challenges) +
274 300 // per-game styles. Same `filemtime` cache-bust posture as the
275 301 // other fast-iterating feature stylesheets.
276 - $games_css = DESKTOP_MODE_DIR . 'assets/css/games.css';
302 + $games_css = OPENSTATION_DIR . 'assets/css/games.css';
277 303 wp_register_style(
278 304 'desktop-mode-games',
279 - DESKTOP_MODE_URL . 'assets/css/games.css',
280 - array( 'desktop-mode-variables', 'dashicons' ),
305 + OPENSTATION_URL . 'assets/css/games.css',
306 + array( 'os-variables', 'dashicons' ),
281 307 file_exists( $games_css ) ? (string) filemtime( $games_css ) : $version
282 308 );
283 - $game_inkfall_css = DESKTOP_MODE_DIR . 'assets/css/game-inkfall.css';
309 + $game_inkfall_css = OPENSTATION_DIR . 'assets/css/game-inkfall.css';
284 310 wp_register_style(
285 - 'desktop-mode-game-inkfall',
286 - DESKTOP_MODE_URL . 'assets/css/game-inkfall.css',
287 - array( 'desktop-mode-variables' ),
311 + 'os-game-inkfall',
312 + OPENSTATION_URL . 'assets/css/game-inkfall.css',
313 + array( 'os-variables' ),
288 314 file_exists( $game_inkfall_css ) ? (string) filemtime( $game_inkfall_css ) : $version
289 315 );
290 - $game_alphabet_soup_css = DESKTOP_MODE_DIR . 'assets/css/game-alphabet-soup.css';
316 + $game_alphabet_soup_css = OPENSTATION_DIR . 'assets/css/game-alphabet-soup.css';
291 317 wp_register_style(
292 - 'desktop-mode-game-alphabet-soup',
293 - DESKTOP_MODE_URL . 'assets/css/game-alphabet-soup.css',
294 - array( 'desktop-mode-variables' ),
318 + 'os-game-alphabet-soup',
319 + OPENSTATION_URL . 'assets/css/game-alphabet-soup.css',
320 + array( 'os-variables' ),
295 321 file_exists( $game_alphabet_soup_css ) ? (string) filemtime( $game_alphabet_soup_css ) : $version
296 322 );
297 323
298 324 // Pinned-notes layer styles (paper, pushpin, pastel tokens, pin
299 325 // animations). Same `filemtime` cache-bust posture as the other
300 - // fast-iterating feature stylesheets above.
301 - $notes_css = DESKTOP_MODE_DIR . 'assets/css/notes.css';
326 + // fast-iterating feature stylesheets above. Depends on `os-files`
327 + // because a pinned note dresses the canonical `.os-file-tile`
328 + // chrome — anything that restyles a tile has to print after the
329 + // file that declares one.
330 + $notes_css = OPENSTATION_DIR . 'assets/css/notes.css';
302 331 wp_register_style(
303 - 'desktop-mode-notes',
304 - DESKTOP_MODE_URL . 'assets/css/notes.css',
305 - array( 'desktop-mode-variables', 'dashicons' ),
332 + 'os-notes',
333 + OPENSTATION_URL . 'assets/css/notes.css',
334 + array( 'os-variables', 'dashicons', 'os-files' ),
306 335 file_exists( $notes_css ) ? (string) filemtime( $notes_css ) : $version
307 336 );
308 337
338 + // Announcement-dialog styles (scrim, hero card, buttons). Registered
339 + // always, enqueued only for a user who is actually owed the
340 + // announcement — see the gate in `openstation_enqueue_assets()`. It
341 + // is not lazy-loaded on top of that: on the one boot where it does
342 + // go out, the dialog opens from the main bundle a second later, and
343 + // a fetch racing that would show an unstyled card.
344 + $announce_css = OPENSTATION_DIR . 'assets/css/announce.css';
345 + wp_register_style(
346 + 'os-announce',
347 + OPENSTATION_URL . 'assets/css/announce.css',
348 + array( 'os-variables' ),
349 + file_exists( $announce_css ) ? (string) filemtime( $announce_css ) : $version
350 + );
351 +
309 352 // Scripts.
310 353 //
311 354 // `wp-hooks` — the shell exposes a WordPress-style filter/action
312 355 // API (`window.wp.hooks`) to third-party plugins.
@@ -315,10 +358,10 @@
315 358 // lookups. Both handles are core-shipped but only pre-enqueued
316 359 // when Gutenberg-adjacent deps pull them in, so we list them
317 360 // explicitly to guarantee load order.
318 361 wp_register_script(
319 - 'desktop-mode',
320 - DESKTOP_MODE_URL . 'assets/js/desktop' . $suffix . '.js',
362 + 'openstation',
363 + OPENSTATION_URL . 'assets/js/desktop' . $suffix . '.js',
321 364 // `heartbeat` + `jquery` — the recycle-bin badge module
322 365 // (loaded as part of this bundle) opts into the WordPress
323 366 // Heartbeat API so the count tile / desktop-icon badge
324 367 // stays in sync even when the bin window is closed.
@@ -326,9 +369,9 @@
326 369 $built_version( 'assets/js/desktop' . $suffix . '.js' ),
327 370 // Footer + defer: the shell boots on DOMContentLoaded anyway,
328 371 // so deferring frees the parser instead of blocking at the
329 372 // footer print point. Both inline payloads attached to this
330 - // handle (`__desktopModeMenuCommands`, the jazz-quote version
373 + // handle (`__openStationMenuCommands`, the jazz-quote version
331 374 // stamp) are `'before'`-position, which WP keeps as blocking
332 375 // inline ahead of a deferred tag — order is preserved. On WP
333 376 // < 6.3 the array collapses to a truthy `$in_footer`, same as
334 377 // before.
@@ -337,10 +380,10 @@
337 380 'strategy' => 'defer',
338 381 )
339 382 );
340 383
341 - // `desktop-mode-iframe-bridge` — opt-in iframe-side bridge that
342 - // provides `wp.desktop.iframe.publish/subscribe/onConnection/
384 + // `os-iframe-bridge` — opt-in iframe-side bridge that
385 + // provides `wp.os.iframe.publish/subscribe/onConnection/
343 386 // requestConnection` to any same-origin iframe that enqueues it.
344 387 // Same code is also injected inline by the chromeless bridge
345 388 // (so chromeless wp-admin pages don't need a separate enqueue)
346 389 // and auto-injected when a native window opts in via
@@ -346,19 +389,60 @@
346 389 // and auto-injected when a native window opts in via
347 390 // `iframeContent: { bridge: true }`. Plugins targeting their
348 391 // own iframe pages just enqueue this handle.
349 392 wp_register_script(
350 - 'desktop-mode-iframe-bridge',
351 - DESKTOP_MODE_URL . 'assets/js/iframe-bridge' . $suffix . '.js',
393 + 'os-iframe-bridge',
394 + OPENSTATION_URL . 'assets/js/iframe-bridge' . $suffix . '.js',
352 395 array(),
353 396 $built_version( 'assets/js/iframe-bridge' . $suffix . '.js' ),
354 397 true
355 398 );
356 399
357 - // `desktop-mode-gutenberg-drop-receiver` — iframe-side bundle
400 + // `os-deactivation-feedback` — the dialog that asks one optional
401 + // question when an admin deactivates OpenStation. Enqueued on
402 + // `plugins.php` (classic, chromeless and network admin) by
403 + // `includes/feedback/deactivation.php`, and lazy-loaded by the
404 + // native Plugins app from its config block. Plain DOM on purpose:
405 + // the classic screen has no `<os-*>` kit.
406 + wp_register_script(
407 + 'os-deactivation-feedback',
408 + OPENSTATION_URL . 'assets/js/deactivation-feedback' . $suffix . '.js',
409 + array( 'wp-i18n' ),
410 + $built_version( 'assets/js/deactivation-feedback' . $suffix . '.js' ),
411 + true
412 + );
413 + wp_set_script_translations(
414 + 'os-deactivation-feedback',
415 + 'desktop-mode',
416 + OPENSTATION_DIR . 'languages'
417 + );
418 + $feedback_css = OPENSTATION_DIR . 'assets/css/deactivation-feedback.css';
419 + wp_register_style(
420 + 'os-deactivation-feedback',
421 + OPENSTATION_URL . 'assets/css/deactivation-feedback.css',
422 + array(),
423 + file_exists( $feedback_css ) ? (string) filemtime( $feedback_css ) : $version
424 + );
425 +
426 + // `os-chromeless-bridge` — the iframe side of every window,
427 + // enqueued on `admin_footer` by
428 + // `openstation_chromeless_bridge_script()` with its per-request
429 + // data attached as a `before` inline block. Registered here (not
430 + // there) so the handle exists before the enqueue and so the asset
431 + // guard's OPENSTATION_URL snapshot protects it like every other
432 + // bundle of ours.
433 + wp_register_script(
434 + 'os-chromeless-bridge',
435 + OPENSTATION_URL . 'assets/js/chromeless-bridge' . $suffix . '.js',
436 + array(),
437 + $built_version( 'assets/js/chromeless-bridge' . $suffix . '.js' ),
438 + true
439 + );
440 +
441 + // `os-gutenberg-drop-receiver` — iframe-side bundle
358 442 // enqueued only on the Block Editor screens (`post.php` /
359 - // `post-new.php`) for desktop-mode users. Listens for
360 - // `desktop-mode-drop` postMessages from the parent shell (see
443 + // `post-new.php`) for openstation users. Listens for
444 + // `os-drop` postMessages from the parent shell (see
361 445 // `src/drag/iframe-drop-targets.ts`) and inserts the matching
362 446 // Gutenberg block via `wp.data.dispatch('core/block-editor')`.
363 447 // Depends on `wp-blocks` + `wp-data` so the editor stores are
364 448 // guaranteed enqueued before the receiver runs its first message
@@ -363,49 +447,32 @@
363 447 // Depends on `wp-blocks` + `wp-data` so the editor stores are
364 448 // guaranteed enqueued before the receiver runs its first message
365 449 // handler.
366 450 wp_register_script(
367 - 'desktop-mode-gutenberg-drop-receiver',
368 - DESKTOP_MODE_URL . 'assets/js/gutenberg-drop-receiver' . $suffix . '.js',
451 + 'os-gutenberg-drop-receiver',
452 + OPENSTATION_URL . 'assets/js/gutenberg-drop-receiver' . $suffix . '.js',
369 453 array( 'wp-blocks', 'wp-data' ),
370 454 $built_version( 'assets/js/gutenberg-drop-receiver' . $suffix . '.js' ),
371 455 true
372 456 );
373 457
374 - // `desktop-mode-recycle-bin` — small bundle for the Recycle Bin
375 - // native window. Lazy-loaded by the native-window sync the first
376 - // time the bin opens; registers a render callback on
377 - // `window.desktopModeNativeWindows['desktop-mode-recycle-bin']`.
378 - $recycle_bin_js = DESKTOP_MODE_DIR . 'assets/js/recycle-bin' . $suffix . '.js';
379 - wp_register_script(
380 - 'desktop-mode-recycle-bin',
381 - DESKTOP_MODE_URL . 'assets/js/recycle-bin' . $suffix . '.js',
382 - // `heartbeat` + `jquery` — the bin opts in to the WordPress
383 - // Heartbeat API while its window is open as the catch-all
384 - // real-time channel for deletes that don't render an admin
385 - // footer (REST/AJAX/other tabs/WP-CLI). See
386 - // `src/recycle-bin/realtime.ts` for the subscriber.
387 - array( 'wp-i18n', 'heartbeat', 'jquery' ),
388 - file_exists( $recycle_bin_js ) ? (string) filemtime( $recycle_bin_js ) : $version,
389 - true
390 - );
391 - wp_set_script_translations(
392 - 'desktop-mode-recycle-bin',
393 - 'desktop-mode',
394 - DESKTOP_MODE_DIR . 'languages'
395 - );
458 + // The Recycle Bin window is an App Framework app (`apps/trash/`);
459 + // its client view rides the app-bundle pipeline, so no dedicated
460 + // script handle. The `desktop-mode-recycle-bin` STYLE handle above
461 + // stays — the drag-to-trash drop-target highlight must be present
462 + // at boot (dropping on the closed bin's dock tile), not window-open.
396 463
397 464 // `desktop-mode-games` — bundle for the Games hub native window
398 465 // (launcher grid, scoreboard, challenges client). Lazy-loaded by
399 466 // the native-window sync the first time the hub opens; registers a
400 467 // render callback on
401 - // `window.desktopModeNativeWindows['desktop-mode-games']`.
468 + // `window.openStationNativeWindows['desktop-mode-games']`.
402 469 // `heartbeat` + `jquery` — the challenges client rides the
403 470 // WordPress Heartbeat bus for live delivery.
404 - $games_js = DESKTOP_MODE_DIR . 'assets/js/games' . $suffix . '.js';
471 + $games_js = OPENSTATION_DIR . 'assets/js/games' . $suffix . '.js';
405 472 wp_register_script(
406 473 'desktop-mode-games',
407 - DESKTOP_MODE_URL . 'assets/js/games' . $suffix . '.js',
474 + OPENSTATION_URL . 'assets/js/games' . $suffix . '.js',
408 475 array( 'wp-i18n', 'heartbeat', 'jquery' ),
409 476 file_exists( $games_js ) ? (string) filemtime( $games_js ) : $version,
410 477 true
411 478 );
@@ -411,120 +478,63 @@
411 478 );
412 479 wp_set_script_translations(
413 480 'desktop-mode-games',
414 481 'desktop-mode',
415 - DESKTOP_MODE_DIR . 'languages'
482 + OPENSTATION_DIR . 'languages'
416 483 );
417 484
418 - // `desktop-mode-game-inkfall` — the Inkfall game bundle. Loaded
485 + // `os-game-inkfall` — the Inkfall game bundle. Loaded
419 486 // lazily by the games framework on first launch; publishes the
420 - // game def on `window.desktopModeGames.inkfall`.
421 - $game_inkfall_js = DESKTOP_MODE_DIR . 'assets/js/game-inkfall' . $suffix . '.js';
487 + // game def on `window.openStationGames.inkfall`.
488 + $game_inkfall_js = OPENSTATION_DIR . 'assets/js/game-inkfall' . $suffix . '.js';
422 489 wp_register_script(
423 - 'desktop-mode-game-inkfall',
424 - DESKTOP_MODE_URL . 'assets/js/game-inkfall' . $suffix . '.js',
490 + 'os-game-inkfall',
491 + OPENSTATION_URL . 'assets/js/game-inkfall' . $suffix . '.js',
425 492 array( 'wp-i18n' ),
426 493 file_exists( $game_inkfall_js ) ? (string) filemtime( $game_inkfall_js ) : $version,
427 494 true
428 495 );
429 496 wp_set_script_translations(
430 - 'desktop-mode-game-inkfall',
497 + 'os-game-inkfall',
431 498 'desktop-mode',
432 - DESKTOP_MODE_DIR . 'languages'
499 + OPENSTATION_DIR . 'languages'
433 500 );
434 501
435 - // `desktop-mode-game-alphabet-soup` — the Alphabet Soup game
502 + // `os-game-alphabet-soup` — the Alphabet Soup game
436 503 // bundle. Loaded lazily by the games framework on first launch;
437 504 // publishes the game def on
438 - // `window.desktopModeGames['alphabet-soup']`.
439 - $game_alphabet_soup_js = DESKTOP_MODE_DIR . 'assets/js/game-alphabet-soup' . $suffix . '.js';
505 + // `window.openStationGames['alphabet-soup']`.
506 + $game_alphabet_soup_js = OPENSTATION_DIR . 'assets/js/game-alphabet-soup' . $suffix . '.js';
440 507 wp_register_script(
441 - 'desktop-mode-game-alphabet-soup',
442 - DESKTOP_MODE_URL . 'assets/js/game-alphabet-soup' . $suffix . '.js',
508 + 'os-game-alphabet-soup',
509 + OPENSTATION_URL . 'assets/js/game-alphabet-soup' . $suffix . '.js',
443 510 array( 'wp-i18n' ),
444 511 file_exists( $game_alphabet_soup_js ) ? (string) filemtime( $game_alphabet_soup_js ) : $version,
445 512 true
446 513 );
447 514 wp_set_script_translations(
448 - 'desktop-mode-game-alphabet-soup',
515 + 'os-game-alphabet-soup',
449 516 'desktop-mode',
450 - DESKTOP_MODE_DIR . 'languages'
517 + OPENSTATION_DIR . 'languages'
451 518 );
452 519
453 - // `desktop-mode-posts-window` — small bundle for the native Posts
454 - // window. Lazy-loaded by the native-window sync the first time the
455 - // window opens (via the dock-click swap when the user opts in);
456 - // registers a render callback on
457 - // `window.desktopModeNativeWindows['desktop-mode-posts']`.
458 - $posts_window_js = DESKTOP_MODE_DIR . 'assets/js/posts-window' . $suffix . '.js';
459 - wp_register_script(
460 - 'desktop-mode-posts-window',
461 - DESKTOP_MODE_URL . 'assets/js/posts-window' . $suffix . '.js',
462 - array( 'wp-i18n' ),
463 - file_exists( $posts_window_js ) ? (string) filemtime( $posts_window_js ) : $version,
464 - true
465 - );
466 - wp_set_script_translations(
467 - 'desktop-mode-posts-window',
468 - 'desktop-mode',
469 - DESKTOP_MODE_DIR . 'languages'
470 - );
471 -
472 - // `desktop-mode-plugins-window` — small bundle for the native
473 - // Plugins window. Lazy-loaded by the native-window sync the first
474 - // time the window opens (via the dock-click swap when the user
475 - // opts in); registers a render callback on
476 - // `window.desktopModeNativeWindows['desktop-mode-plugins']`.
477 - $plugins_window_js = DESKTOP_MODE_DIR . 'assets/js/plugins-window' . $suffix . '.js';
478 - wp_register_script(
479 - 'desktop-mode-plugins-window',
480 - DESKTOP_MODE_URL . 'assets/js/plugins-window' . $suffix . '.js',
481 - array( 'wp-i18n' ),
482 - file_exists( $plugins_window_js ) ? (string) filemtime( $plugins_window_js ) : $version,
483 - true
484 - );
485 - wp_set_script_translations(
486 - 'desktop-mode-plugins-window',
487 - 'desktop-mode',
488 - DESKTOP_MODE_DIR . 'languages'
489 - );
490 -
491 - // `desktop-mode-comments-window` — small bundle for the native
492 - // Comments window. Lazy-loaded by the native-window sync the first
493 - // time the window opens (via the dock-click swap when the user
494 - // opts in); registers a render callback on
495 - // `window.desktopModeNativeWindows['desktop-mode-comments']`.
496 - $comments_window_js = DESKTOP_MODE_DIR . 'assets/js/comments-window' . $suffix . '.js';
497 - wp_register_script(
498 - 'desktop-mode-comments-window',
499 - DESKTOP_MODE_URL . 'assets/js/comments-window' . $suffix . '.js',
500 - array( 'wp-i18n' ),
501 - file_exists( $comments_window_js ) ? (string) filemtime( $comments_window_js ) : $version,
502 - true
503 - );
504 - wp_set_script_translations(
505 - 'desktop-mode-comments-window',
506 - 'desktop-mode',
507 - DESKTOP_MODE_DIR . 'languages'
508 - );
509 -
510 - // `desktop-mode-animated-logo-wallpaper` — built-in PixiJS canvas
520 + // `os-animated-logo-wallpaper` — built-in PixiJS canvas
511 521 // wallpaper, moved out of `desktop.min.js`. The wallpaper
512 522 // `server-sync` loads this handle when the user selects the
513 523 // `wp-animated-logo` wallpaper (or opens OS Settings → Wallpaper
514 524 // and the picker pulls every registered canvas def in). The
515 525 // bundle's only side effect is publishing the `WallpaperDef` on
516 - // `window.desktopModeWallpapers['wp-animated-logo']`.
517 - $animated_logo_js = DESKTOP_MODE_DIR . 'assets/js/animated-logo-wallpaper' . $suffix . '.js';
526 + // `window.openStationWallpapers['wp-animated-logo']`.
527 + $animated_logo_js = OPENSTATION_DIR . 'assets/js/animated-logo-wallpaper' . $suffix . '.js';
518 528 wp_register_script(
519 - 'desktop-mode-animated-logo-wallpaper',
520 - DESKTOP_MODE_URL . 'assets/js/animated-logo-wallpaper' . $suffix . '.js',
529 + 'os-animated-logo-wallpaper',
530 + OPENSTATION_URL . 'assets/js/animated-logo-wallpaper' . $suffix . '.js',
521 531 array( 'wp-hooks' ),
522 532 file_exists( $animated_logo_js ) ? (string) filemtime( $animated_logo_js ) : $version,
523 533 true
524 534 );
525 535
526 - // `desktop-mode-snow-wallpaper` — built-in PixiJS canvas
536 + // `os-snow-wallpaper` — built-in PixiJS canvas
527 537 // wallpaper: snowfall that accumulates on window tops and melts
528 538 // away. Same lazy-load path as the animated logo: the wallpaper
529 539 // `server-sync` injects this handle when the user selects the
530 540 // `wp-snow` wallpaper (or opens OS Settings → Wallpaper and the
@@ -529,32 +539,32 @@
529 539 // `server-sync` injects this handle when the user selects the
530 540 // `wp-snow` wallpaper (or opens OS Settings → Wallpaper and the
531 541 // picker pulls the def in). The bundle's only side effect is
532 542 // publishing the `WallpaperDef` on
533 - // `window.desktopModeWallpapers['wp-snow']`.
534 - $snow_js = DESKTOP_MODE_DIR . 'assets/js/snow-wallpaper' . $suffix . '.js';
543 + // `window.openStationWallpapers['wp-snow']`.
544 + $snow_js = OPENSTATION_DIR . 'assets/js/snow-wallpaper' . $suffix . '.js';
535 545 wp_register_script(
536 - 'desktop-mode-snow-wallpaper',
537 - DESKTOP_MODE_URL . 'assets/js/snow-wallpaper' . $suffix . '.js',
546 + 'os-snow-wallpaper',
547 + OPENSTATION_URL . 'assets/js/snow-wallpaper' . $suffix . '.js',
538 548 array( 'wp-hooks', 'wp-i18n' ),
539 549 file_exists( $snow_js ) ? (string) filemtime( $snow_js ) : $version,
540 550 true
541 551 );
542 552 wp_set_script_translations(
543 - 'desktop-mode-snow-wallpaper',
553 + 'os-snow-wallpaper',
544 554 'desktop-mode',
545 - DESKTOP_MODE_DIR . 'languages'
555 + OPENSTATION_DIR . 'languages'
546 556 );
547 557
548 558 // `desktop-mode-ai-assistant` — AI Copilot spotlight overlay,
549 559 // moved out of `desktop.min.js`. The main bundle ships a
550 - // stub matching the public `wp.desktop.ai` contract; the stub
560 + // stub matching the public `wp.os.ai` contract; the stub
551 561 // `<script>`-injects this handle the first time the user opens
552 562 // the assistant (Cmd+K or admin-bar button).
553 - $ai_assistant_js = DESKTOP_MODE_DIR . 'assets/js/ai-assistant' . $suffix . '.js';
563 + $ai_assistant_js = OPENSTATION_DIR . 'assets/js/ai-assistant' . $suffix . '.js';
554 564 wp_register_script(
555 565 'desktop-mode-ai-assistant',
556 - DESKTOP_MODE_URL . 'assets/js/ai-assistant' . $suffix . '.js',
566 + OPENSTATION_URL . 'assets/js/ai-assistant' . $suffix . '.js',
557 567 array( 'wp-hooks', 'wp-i18n' ),
558 568 file_exists( $ai_assistant_js ) ? (string) filemtime( $ai_assistant_js ) : $version,
559 569 true
560 570 );
@@ -560,19 +570,19 @@
560 570 );
561 571 wp_set_script_translations(
562 572 'desktop-mode-ai-assistant',
563 573 'desktop-mode',
564 - DESKTOP_MODE_DIR . 'languages'
574 + OPENSTATION_DIR . 'languages'
565 575 );
566 576
567 577 // Wire the translation bundle to this script handle. WP looks
568 - // for `languages/desktop-mode-{locale}-desktop-mode.json` and
578 + // for `languages/os-{locale}-os.json` and
569 579 // injects its `locale_data` into `wp.i18n` just before the
570 580 // script runs — so every `__()` call resolves to the right
571 581 // language without any runtime fetch.
572 582 wp_set_script_translations(
583 + 'openstation',
573 584 'desktop-mode',
574 - 'desktop-mode',
575 - DESKTOP_MODE_DIR . 'languages'
585 + OPENSTATION_DIR . 'languages'
576 586 );
577 587 }
578 -add_action( 'init', 'desktop_mode_register_assets' );
588 +add_action( 'init', 'openstation_register_assets' );