PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.3
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.3
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
desktop-mode / includes / assets.php

assets.php in OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin 0.9.3, at includes/assets.php

349 lines 14.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Desktop Mode asset registration.
4 *
5 * Registers all desktop-mode CSS and JS handles with WordPress so they can
6 * be enqueued from anywhere in the plugin (or by third parties).
7 *
8 * @package WPDesktopMode
9 */
10
11 defined( 'ABSPATH' ) || exit;
12
13 /**
14 * Registers the desktop mode CSS and JS handles.
15 *
16 * @since 0.1.0
17 */
18 function desktop_mode_register_assets() {
19 $version = DESKTOP_MODE_VERSION;
20 $suffix = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
21
22 // `filemtime`-stamped version for built bundles. The plugin-wide
23 // `DESKTOP_MODE_VERSION` is bumped per release, but the bundles
24 // iterate faster — without a per-file mtime stamp, two clients
25 // loading the same `?ver=…` URL can be served different bytes
26 // (whichever build was on disk at upload time). Stamping with the
27 // file's modification time guarantees the URL changes whenever the
28 // file does, so "is my fix deployed?" is answerable from the
29 // network tab. Falls back to `$version` when the file is missing
30 // (test envs that import this file before the build runs).
31 $built_version = static function ( $relative ) use ( $version ) {
32 $path = DESKTOP_MODE_DIR . $relative;
33 return file_exists( $path ) ? (string) filemtime( $path ) : $version;
34 };
35
36 // Styles.
37 wp_register_style(
38 'desktop-mode-variables',
39 DESKTOP_MODE_URL . 'assets/css/variables.css',
40 array(),
41 $version
42 );
43 // `filemtime`-stamped so the `<link rel="stylesheet">` URL matches the
44 // `<link rel="preload" as="style">` hint emitted by
45 // `desktop_mode_print_preload_hints()` (which stamps with filemtime).
46 // Registering this with the plain `$version` instead produced two
47 // different `?ver=` query strings for the same file, so the browser
48 // never matched the preload to the stylesheet and logged "preloaded
49 // but not used within a few seconds from the window's load event".
50 wp_register_style(
51 'desktop-mode',
52 DESKTOP_MODE_URL . 'assets/css/desktop.css',
53 array( 'desktop-mode-variables' ),
54 $built_version( 'assets/css/desktop.css' )
55 );
56 // `filemtime`-stamped — window-chrome iteration (drop overlays,
57 // new drag affordances, third-party-plugin compat) lands faster
58 // than plugin version bumps. Without an mtime stamp the browser
59 // keeps `?ver=<plugin-version>` valid for the whole release cycle
60 // and the user keeps seeing yesterday's CSS even after a hard
61 // reload. Stamps the parent `windows.css` only; the @imports inside
62 // (`window-chrome.css`, `window-states.css`, …) inherit the cache
63 // directive from the parent fetch, so a busted `windows.css` busts
64 // the whole subtree.
65 wp_register_style(
66 'desktop-mode-windows',
67 DESKTOP_MODE_URL . 'assets/css/windows.css',
68 array( 'desktop-mode-variables', 'dashicons' ),
69 $built_version( 'assets/css/windows.css' )
70 );
71 wp_register_style(
72 'desktop-mode-dock',
73 DESKTOP_MODE_URL . 'assets/css/dock.css',
74 array( 'desktop-mode-variables', 'dashicons' ),
75 $version
76 );
77 wp_register_style(
78 'desktop-mode-dock-peek',
79 DESKTOP_MODE_URL . 'assets/css/dock-peek.css',
80 array( 'desktop-mode-dock' ),
81 $version
82 );
83 // `filemtime`-stamped — the chromeless overrides iterate faster
84 // than the plugin-wide version bumps (per-page compat shims and
85 // page-title-action exceptions land in patches), and a stale
86 // cached copy means the user sees yesterday's rules. Without the
87 // stamp, the browser keeps `?ver=0.8.1` valid for the whole
88 // release cycle.
89 wp_register_style(
90 'desktop-mode-chromeless',
91 DESKTOP_MODE_URL . 'assets/css/chromeless.css',
92 array( 'desktop-mode' ),
93 $built_version( 'assets/css/chromeless.css' )
94 );
95
96 // `filemtime`-stamped — the AI assistant surface (error states,
97 // inline affordances) iterates faster than plugin version bumps.
98 // Without an mtime stamp the browser keeps `?ver=<plugin-version>`
99 // valid for the whole release cycle and the user keeps seeing
100 // yesterday's CSS even after a hard reload.
101 wp_register_style(
102 'desktop-mode-ai-assistant',
103 DESKTOP_MODE_URL . 'assets/css/ai-assistant.css',
104 array( 'desktop-mode-variables' ),
105 $built_version( 'assets/css/ai-assistant.css' )
106 );
107
108 wp_register_style(
109 'desktop-mode-bug-report',
110 DESKTOP_MODE_URL . 'assets/css/bug-report.css',
111 array( 'desktop-mode-variables' ),
112 $version
113 );
114
115 // `filemtime` instead of the plugin-wide `$version` for the
116 // recycle-bin CSS — this file iterates faster than the bundle
117 // and we never want a stale CSS cache to mask a real fix.
118 $recycle_bin_css = DESKTOP_MODE_DIR . 'assets/css/recycle-bin.css';
119 wp_register_style(
120 'desktop-mode-recycle-bin',
121 DESKTOP_MODE_URL . 'assets/css/recycle-bin.css',
122 array( 'desktop-mode-variables', 'dashicons' ),
123 file_exists( $recycle_bin_css ) ? (string) filemtime( $recycle_bin_css ) : $version
124 );
125
126 // `filemtime` for the native Posts window CSS — same rationale as
127 // the recycle-bin CSS: bundle iterates faster than the plugin
128 // version and stale caches are worse than the cost of a 304.
129 $posts_window_css = DESKTOP_MODE_DIR . 'assets/css/posts-window.css';
130 wp_register_style(
131 'desktop-mode-posts-window',
132 DESKTOP_MODE_URL . 'assets/css/posts-window.css',
133 array( 'desktop-mode-variables', 'dashicons' ),
134 file_exists( $posts_window_css ) ? (string) filemtime( $posts_window_css ) : $version
135 );
136
137 // Native Plugins window CSS — same `filemtime`-cache-bust posture
138 // as the Posts/Recycle Bin styles.
139 $plugins_window_css = DESKTOP_MODE_DIR . 'assets/css/plugins-window.css';
140 wp_register_style(
141 'desktop-mode-plugins-window',
142 DESKTOP_MODE_URL . 'assets/css/plugins-window.css',
143 array( 'desktop-mode-variables', 'dashicons' ),
144 file_exists( $plugins_window_css ) ? (string) filemtime( $plugins_window_css ) : $version
145 );
146
147 // Native Comments window CSS — same `filemtime` posture.
148 $comments_window_css = DESKTOP_MODE_DIR . 'assets/css/comments-window.css';
149 wp_register_style(
150 'desktop-mode-comments-window',
151 DESKTOP_MODE_URL . 'assets/css/comments-window.css',
152 array( 'desktop-mode-variables', 'dashicons' ),
153 file_exists( $comments_window_css ) ? (string) filemtime( $comments_window_css ) : $version
154 );
155
156 // Files-on-the-Desktop tile + layer styles. `filemtime` for the
157 // same reason as the recycle-bin / posts-window CSS: this file
158 // iterates faster than the plugin version, and a stale cache
159 // would mask a real fix.
160 $desktop_files_css = DESKTOP_MODE_DIR . 'assets/css/desktop-files.css';
161 wp_register_style(
162 'desktop-mode-files',
163 DESKTOP_MODE_URL . 'assets/css/desktop-files.css',
164 array( 'desktop-mode-variables', 'dashicons' ),
165 file_exists( $desktop_files_css ) ? (string) filemtime( $desktop_files_css ) : $version
166 );
167
168 // Scripts.
169 //
170 // `wp-hooks` — the shell exposes a WordPress-style filter/action
171 // API (`window.wp.hooks`) to third-party plugins.
172 // `wp-i18n` — the TS `__()` / `_x()` / `sprintf()` wrappers in
173 // `src/i18n.ts` delegate to `window.wp.i18n` for translation
174 // lookups. Both handles are core-shipped but only pre-enqueued
175 // when Gutenberg-adjacent deps pull them in, so we list them
176 // explicitly to guarantee load order.
177 wp_register_script(
178 'desktop-mode',
179 DESKTOP_MODE_URL . 'assets/js/desktop' . $suffix . '.js',
180 // `heartbeat` + `jquery` — the recycle-bin badge module
181 // (loaded as part of this bundle) opts into the WordPress
182 // Heartbeat API so the count tile / desktop-icon badge
183 // stays in sync even when the bin window is closed.
184 array( 'wp-hooks', 'wp-i18n', 'heartbeat', 'jquery' ),
185 $built_version( 'assets/js/desktop' . $suffix . '.js' ),
186 true
187 );
188
189 // `desktop-mode-iframe-bridge` — opt-in iframe-side bridge that
190 // provides `wp.desktop.iframe.publish/subscribe/onConnection/
191 // requestConnection` to any same-origin iframe that enqueues it.
192 // Same code is also injected inline by the chromeless bridge
193 // (so chromeless wp-admin pages don't need a separate enqueue)
194 // and auto-injected when a native window opts in via
195 // `iframeContent: { bridge: true }`. Plugins targeting their
196 // own iframe pages just enqueue this handle.
197 wp_register_script(
198 'desktop-mode-iframe-bridge',
199 DESKTOP_MODE_URL . 'assets/js/iframe-bridge' . $suffix . '.js',
200 array(),
201 $built_version( 'assets/js/iframe-bridge' . $suffix . '.js' ),
202 true
203 );
204
205 // `desktop-mode-gutenberg-drop-receiver` — iframe-side bundle
206 // enqueued only on the Block Editor screens (`post.php` /
207 // `post-new.php`) for desktop-mode users. Listens for
208 // `desktop-mode-drop` postMessages from the parent shell (see
209 // `src/drag/iframe-drop-targets.ts`) and inserts the matching
210 // Gutenberg block via `wp.data.dispatch('core/block-editor')`.
211 // Depends on `wp-blocks` + `wp-data` so the editor stores are
212 // guaranteed enqueued before the receiver runs its first message
213 // handler.
214 wp_register_script(
215 'desktop-mode-gutenberg-drop-receiver',
216 DESKTOP_MODE_URL . 'assets/js/gutenberg-drop-receiver' . $suffix . '.js',
217 array( 'wp-blocks', 'wp-data' ),
218 $built_version( 'assets/js/gutenberg-drop-receiver' . $suffix . '.js' ),
219 true
220 );
221
222 // `desktop-mode-recycle-bin` — small bundle for the Recycle Bin
223 // native window. Lazy-loaded by the native-window sync the first
224 // time the bin opens; registers a render callback on
225 // `window.desktopModeNativeWindows['desktop-mode-recycle-bin']`.
226 $recycle_bin_js = DESKTOP_MODE_DIR . 'assets/js/recycle-bin' . $suffix . '.js';
227 wp_register_script(
228 'desktop-mode-recycle-bin',
229 DESKTOP_MODE_URL . 'assets/js/recycle-bin' . $suffix . '.js',
230 // `heartbeat` + `jquery` — the bin opts in to the WordPress
231 // Heartbeat API while its window is open as the catch-all
232 // real-time channel for deletes that don't render an admin
233 // footer (REST/AJAX/other tabs/WP-CLI). See
234 // `src/recycle-bin/realtime.ts` for the subscriber.
235 array( 'wp-i18n', 'heartbeat', 'jquery' ),
236 file_exists( $recycle_bin_js ) ? (string) filemtime( $recycle_bin_js ) : $version,
237 true
238 );
239 wp_set_script_translations(
240 'desktop-mode-recycle-bin',
241 'desktop-mode',
242 DESKTOP_MODE_DIR . 'languages'
243 );
244
245 // `desktop-mode-posts-window` — small bundle for the native Posts
246 // window. Lazy-loaded by the native-window sync the first time the
247 // window opens (via the dock-click swap when the user opts in);
248 // registers a render callback on
249 // `window.desktopModeNativeWindows['desktop-mode-posts']`.
250 $posts_window_js = DESKTOP_MODE_DIR . 'assets/js/posts-window' . $suffix . '.js';
251 wp_register_script(
252 'desktop-mode-posts-window',
253 DESKTOP_MODE_URL . 'assets/js/posts-window' . $suffix . '.js',
254 array( 'wp-i18n' ),
255 file_exists( $posts_window_js ) ? (string) filemtime( $posts_window_js ) : $version,
256 true
257 );
258 wp_set_script_translations(
259 'desktop-mode-posts-window',
260 'desktop-mode',
261 DESKTOP_MODE_DIR . 'languages'
262 );
263
264 // `desktop-mode-plugins-window` — small bundle for the native
265 // Plugins window. Lazy-loaded by the native-window sync the first
266 // time the window opens (via the dock-click swap when the user
267 // opts in); registers a render callback on
268 // `window.desktopModeNativeWindows['desktop-mode-plugins']`.
269 $plugins_window_js = DESKTOP_MODE_DIR . 'assets/js/plugins-window' . $suffix . '.js';
270 wp_register_script(
271 'desktop-mode-plugins-window',
272 DESKTOP_MODE_URL . 'assets/js/plugins-window' . $suffix . '.js',
273 array( 'wp-i18n' ),
274 file_exists( $plugins_window_js ) ? (string) filemtime( $plugins_window_js ) : $version,
275 true
276 );
277 wp_set_script_translations(
278 'desktop-mode-plugins-window',
279 'desktop-mode',
280 DESKTOP_MODE_DIR . 'languages'
281 );
282
283 // `desktop-mode-comments-window` — small bundle for the native
284 // Comments window. Lazy-loaded by the native-window sync the first
285 // time the window opens (via the dock-click swap when the user
286 // opts in); registers a render callback on
287 // `window.desktopModeNativeWindows['desktop-mode-comments']`.
288 $comments_window_js = DESKTOP_MODE_DIR . 'assets/js/comments-window' . $suffix . '.js';
289 wp_register_script(
290 'desktop-mode-comments-window',
291 DESKTOP_MODE_URL . 'assets/js/comments-window' . $suffix . '.js',
292 array( 'wp-i18n' ),
293 file_exists( $comments_window_js ) ? (string) filemtime( $comments_window_js ) : $version,
294 true
295 );
296 wp_set_script_translations(
297 'desktop-mode-comments-window',
298 'desktop-mode',
299 DESKTOP_MODE_DIR . 'languages'
300 );
301
302 // `desktop-mode-animated-logo-wallpaper` — built-in PixiJS canvas
303 // wallpaper, moved out of `desktop.min.js` in 0.8.4. The wallpaper
304 // `server-sync` loads this handle when the user selects the
305 // `wp-animated-logo` wallpaper (or opens OS Settings → Wallpaper
306 // and the picker pulls every registered canvas def in). The
307 // bundle's only side effect is publishing the `WallpaperDef` on
308 // `window.desktopModeWallpapers['wp-animated-logo']`.
309 $animated_logo_js = DESKTOP_MODE_DIR . 'assets/js/animated-logo-wallpaper' . $suffix . '.js';
310 wp_register_script(
311 'desktop-mode-animated-logo-wallpaper',
312 DESKTOP_MODE_URL . 'assets/js/animated-logo-wallpaper' . $suffix . '.js',
313 array( 'wp-hooks' ),
314 file_exists( $animated_logo_js ) ? (string) filemtime( $animated_logo_js ) : $version,
315 true
316 );
317
318 // `desktop-mode-ai-assistant` — AI Copilot spotlight overlay,
319 // moved out of `desktop.min.js` in 0.8.4. The main bundle ships a
320 // stub matching the public `wp.desktop.ai` contract; the stub
321 // `<script>`-injects this handle the first time the user opens
322 // the assistant (Cmd+K or admin-bar button).
323 $ai_assistant_js = DESKTOP_MODE_DIR . 'assets/js/ai-assistant' . $suffix . '.js';
324 wp_register_script(
325 'desktop-mode-ai-assistant',
326 DESKTOP_MODE_URL . 'assets/js/ai-assistant' . $suffix . '.js',
327 array( 'wp-hooks', 'wp-i18n' ),
328 file_exists( $ai_assistant_js ) ? (string) filemtime( $ai_assistant_js ) : $version,
329 true
330 );
331 wp_set_script_translations(
332 'desktop-mode-ai-assistant',
333 'desktop-mode',
334 DESKTOP_MODE_DIR . 'languages'
335 );
336
337 // Wire the translation bundle to this script handle. WP looks
338 // for `languages/desktop-mode-{locale}-desktop-mode.json` and
339 // injects its `locale_data` into `wp.i18n` just before the
340 // script runs — so every `__()` call resolves to the right
341 // language without any runtime fetch.
342 wp_set_script_translations(
343 'desktop-mode',
344 'desktop-mode',
345 DESKTOP_MODE_DIR . 'languages'
346 );
347 }
348 add_action( 'init', 'desktop_mode_register_assets' );
349