PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 0.9.0
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v0.9.0
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.0, at includes/assets.php

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