PluginProbe
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin / 1.1.12
OpenStation: Desktop Windows, Dock & Virtual Desktops for WP Admin v1.1.12
1.1.12 1.1.11 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 All 36 releases
← All changes | includes/registries/wallpapers.php +90 -79 0.9.6 → 1.1.12 View file →
@@ -1,11 +1,11 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — Wallpapers registry.
3 + * OpenStation — Wallpapers registry.
4 4 *
5 5 * Server-side registration API + payload builder + asset enqueue
6 6 * for the desktop wallpaper picker. Wallpaper definitions live
7 - * on `window.desktopModeWallpapers[ id ]` (set by the plugin's
7 + * on `window.openStationWallpapers[ id ]` (set by the plugin's
8 8 * own JS); this module is the PHP side that announces them to
9 9 * the shell and ships their script handles into the boot
10 10 * payload.
11 11 *
@@ -12,10 +12,9 @@
12 12 * Extracted from `components.php` during the architecture-0.8.1
13 13 * PHP slicing (phase 6). Behaviour, function names, filter
14 14 * contracts, and error codes all unchanged.
15 15 *
16 - * @package Desktop_Mode
17 - * @since 0.8.1
16 + * @package OpenStation
18 17 */
19 18
20 19 defined( 'ABSPATH' ) || exit;
21 20
@@ -20,12 +19,12 @@
20 19 defined( 'ABSPATH' ) || exit;
21 20
22 21 /**
23 22 * Register a server-side desktop wallpaper. Symmetrical to
24 - * {@see desktop_mode_register_widget()}. The plugin's JS side
23 + * {@see openstation_register_widget()}. The plugin's JS side
25 24 * publishes the full `WallpaperDef` (with mount / resolveValue /
26 25 * renderEditor callbacks as appropriate) on
27 - * `window.desktopModeWallpapers[ <id> ]`; the shell loads the
26 + * `window.openStationWallpapers[ <id> ]`; the shell loads the
28 27 * declared script, reads that global, and registers the def via
29 28 * the normal wallpaper registry. Deactivation unregisters the
30 29 * def and re-applies the current selection (which falls back to
31 30 * a built-in if the user's active wallpaper was the one leaving).
@@ -32,9 +31,9 @@
32 31 *
33 32 * Example:
34 33 *
35 34 * ```php
36 - * desktop_mode_register_wallpaper( 'myplugin/snow', array(
35 + * openstation_register_wallpaper( 'myplugin/snow', array(
37 36 * 'label' => __( 'Snow', 'my-plugin' ),
38 37 * 'preview' => 'linear-gradient(#fff, #ddd)',
39 38 * 'type' => 'canvas',
40 39 * 'script' => 'my-plugin-snow-wallpaper',
@@ -42,10 +41,10 @@
42 41 * ```
43 42 *
44 43 * ```js
45 44 * // Inside my-plugin-snow-wallpaper.js
46 - * window.desktopModeWallpapers = window.desktopModeWallpapers || {};
47 - * window.desktopModeWallpapers[ 'myplugin/snow' ] = {
45 + * window.openStationWallpapers = window.openStationWallpapers || {};
46 + * window.openStationWallpapers[ 'myplugin/snow' ] = {
48 47 * id: 'myplugin/snow',
49 48 * label: 'Snow',
50 49 * type: 'canvas',
51 50 * preview: 'linear-gradient(#fff, #ddd)',
@@ -53,15 +52,10 @@
53 52 * mount: function ( container, ctx ) { return function () {}; },
54 53 * };
55 54 * ```
56 55 *
57 - * @since 0.8.1
58 - * @since 0.8.1 Returns `WP_Error` on validation failure instead of
59 - * silent `false`. Legacy `if ( $result )` callers remain
60 - * correct because `WP_Error` is truthy.
61 - *
62 56 * @param string $id Wallpaper id. For canvas wallpapers this must
63 - * match the `window.desktopModeWallpapers[<id>]`
57 + * match the `window.openStationWallpapers[<id>]`
64 58 * key the plugin's JS publishes.
65 59 * @param array $args {
66 60 * @type string $label Picker label. Required.
67 61 * @type string $preview CSS value rendered in the picker
@@ -82,20 +76,27 @@
82 76 * @type string $description Plain-text description shown in OS
83 77 * Settings when the wallpaper is the
84 78 * active selection — what it is, where
85 79 * its data comes from, the story behind
86 - * it. Optional. Since 0.9.4.
80 + * it. Optional.
81 + * @type string $tone 'light' | 'dark'. Whether the desk
82 + * paints its icons and labels in
83 + * Starlight or in Void. Optional;
84 + * unset reads as 'dark'. Declare
85 + * 'light' if a user would call your
86 + * surface pale. See
87 + * docs/desktop-themes.md.
87 88 * @type string[] $capabilities Gate: ALL caps must match. Any
88 89 * missed cap returns
89 - * `WP_Error desktop_mode_capability_denied`.
90 + * `WP_Error openstation_capability_denied`.
90 91 * }
91 92 * @return true|WP_Error `true` on success; `WP_Error` otherwise.
92 93 */
93 -function desktop_mode_register_wallpaper( $id, $args = array() ) {
94 +function openstation_register_wallpaper( $id, $args = array() ) {
94 95 $id = (string) $id;
95 96 if ( '' === $id ) {
96 - return desktop_mode_registration_error(
97 - 'desktop_mode_missing_id',
97 + return openstation_registration_error(
98 + 'openstation_missing_id',
98 99 __( 'Wallpaper id is required.', 'desktop-mode' )
99 100 );
100 101 }
101 102
@@ -105,28 +106,32 @@
105 106 'type' => 'canvas',
106 107 'value' => '',
107 108 'script' => '',
108 109 'description' => '',
110 + 'tone' => '',
109 111 'capabilities' => array(),
110 112 );
111 - $args = wp_parse_args( $args, $defaults );
113 + $args = wp_parse_args( $args, $defaults );
112 114
113 115 foreach ( (array) $args['capabilities'] as $cap ) {
114 116 if ( ! current_user_can( (string) $cap ) ) {
115 - return desktop_mode_registration_error(
116 - 'desktop_mode_capability_denied',
117 + return openstation_registration_error(
118 + 'openstation_capability_denied',
117 119 sprintf(
118 120 /* translators: %s: capability slug. */
119 121 __( 'Current user lacks the %s capability required to register this wallpaper.', 'desktop-mode' ),
120 122 (string) $cap
121 123 ),
122 - array( 'capability' => (string) $cap, 'id' => $id )
124 + array(
125 + 'capability' => (string) $cap,
126 + 'id' => $id,
127 + )
123 128 );
124 129 }
125 130 }
126 131 if ( '' === (string) $args['label'] ) {
127 - return desktop_mode_registration_error(
128 - 'desktop_mode_missing_label',
132 + return openstation_registration_error(
133 + 'openstation_missing_label',
129 134 __( 'Wallpaper registration requires a non-empty `label`.', 'desktop-mode' ),
130 135 array( 'id' => $id )
131 136 );
132 137 }
@@ -137,10 +142,10 @@
137 142 // `mount` callback is published on the JS global by that
138 143 // script). CSS wallpapers can skip the script — the shell can
139 144 // render from the `value` / `preview` string alone.
140 145 if ( 'canvas' === $type && '' === (string) $args['script'] ) {
141 - return desktop_mode_registration_error(
142 - 'desktop_mode_missing_script',
146 + return openstation_registration_error(
147 + 'openstation_missing_script',
143 148 __( 'Canvas wallpaper registration requires a `script` handle that publishes the def.', 'desktop-mode' ),
144 149 array( 'id' => $id )
145 150 );
146 151 }
@@ -155,9 +160,19 @@
155 160 }
156 161
157 162 $entry = array(
158 163 'id' => $id,
159 - 'label' => (string) $args['label'],
164 + // Plain text by contract, same as `description` below. The
165 + // shell paints labels through the `html` tagged template, whose
166 + // text slots build DOM with `createTextNode()` — never
167 + // `innerHTML` — so a label cannot become markup downstream.
168 + //
169 + // Note this STRIPS rather than ESCAPES, and that distinction is
170 + // load-bearing: `esc_html()` here would encode `&` in a
171 + // perfectly ordinary label ("Black & White") and the text node
172 + // would then render the entity literally as `&amp;`. Escaping
173 + // belongs at an HTML boundary; there isn't one on this path.
174 + 'label' => sanitize_text_field( (string) $args['label'] ),
160 175 'preview' => (string) $args['preview'],
161 176 'type' => $type,
162 177 'value' => $value,
163 178 'script' => (string) $args['script'],
@@ -163,23 +178,24 @@
163 178 'script' => (string) $args['script'],
164 179 // Plain text by contract — the shell renders it as text, never
165 180 // as HTML, so strip tags here rather than trusting every caller.
166 181 'description' => sanitize_textarea_field( (string) $args['description'] ),
182 + // Anything else stores empty and reads as 'dark', so a typo
183 + // lands on the old look rather than on invisible icons.
184 + 'tone' => in_array( $args['tone'], array( 'light', 'dark' ), true ) ? (string) $args['tone'] : '',
167 185 );
168 - desktop_mode_desktop_wallpaper_registry( $id, $entry );
186 + openstation_desktop_wallpaper_registry( $id, $entry );
169 187
170 188 /**
171 189 * Fires after a desktop wallpaper is successfully registered.
172 190 *
173 - * Does NOT fire when `desktop_mode_register_wallpaper()` returns a
191 + * Does NOT fire when `openstation_register_wallpaper()` returns a
174 192 * `WP_Error`.
175 193 *
176 - * @since 0.8.1
177 - *
178 194 * @param string $id The wallpaper id.
179 195 * @param array $entry The stored registry entry.
180 196 */
181 - do_action( 'desktop_mode_wallpaper_registered', $id, $entry );
197 + do_action( 'openstation_wallpaper_registered', $id, $entry );
182 198
183 199 return true;
184 200 }
185 201
@@ -184,15 +200,14 @@
184 200 }
185 201
186 202 /**
187 203 * Internal module-level registry for wallpapers registered via
188 - * {@see desktop_mode_register_wallpaper()}. Same static-store
204 + * {@see openstation_register_wallpaper()}. Same static-store
189 205 * pattern as the widget + native-window registries.
190 206 *
191 - * @since 0.8.1
192 207 * @internal
193 208 */
194 -function desktop_mode_desktop_wallpaper_registry( $id = '', $entry = null ) {
209 +function openstation_desktop_wallpaper_registry( $id = '', $entry = null ) {
195 210 static $store = array();
196 211
197 212 if ( '' === (string) $id ) {
198 213 return $store;
@@ -207,28 +222,24 @@
207 222 * Build the wallpaper list for the shell payload. Only metadata +
208 223 * the resolved script URL cross the wire; the plugin's mount
209 224 * callback is announced via the JS global the script sets up.
210 225 *
211 - * @since 0.8.1
212 - *
213 226 * @return array[]
214 227 */
215 -function desktop_mode_build_desktop_wallpapers_payload() {
216 - $registry = desktop_mode_desktop_wallpaper_registry();
228 +function openstation_build_desktop_wallpapers_payload() {
229 + $registry = openstation_desktop_wallpaper_registry();
217 230 if ( ! is_array( $registry ) || empty( $registry ) ) {
218 231 return array();
219 232 }
220 233 /**
221 234 * Filters the server-declared wallpaper list before it ships to
222 - * the shell. Mirrors the JS-side `desktop-mode.wallpapers` filter
235 + * the shell. Mirrors the JS-side `os.wallpapers` filter
223 236 * so plugins can rearrange, hide, or override entries at boot
224 237 * without round-tripping through the JS registry.
225 238 *
226 - * @since 0.8.1
227 - *
228 239 * @param array[] $registry The registered wallpaper entries.
229 240 */
230 - $registry = apply_filters( 'desktop_mode_wallpapers', $registry );
241 + $registry = apply_filters( 'openstation_wallpapers', $registry );
231 242 if ( ! is_array( $registry ) ) {
232 243 return array();
233 244 }
234 245 $out = array();
@@ -236,22 +247,26 @@
236 247 if ( ! is_array( $entry ) || empty( $entry['id'] ) ) {
237 248 continue;
238 249 }
239 250 $handle = isset( $entry['script'] ) ? (string) $entry['script'] : '';
240 - $payload = desktop_mode_resolve_script_payload( $handle );
241 - $out[] = array(
242 - 'id' => (string) $entry['id'],
243 - 'label' => isset( $entry['label'] ) ? (string) $entry['label'] : '',
244 - 'preview' => isset( $entry['preview'] ) ? (string) $entry['preview'] : '',
245 - 'type' => isset( $entry['type'] ) ? (string) $entry['type'] : 'canvas',
246 - 'value' => isset( $entry['value'] ) ? (string) $entry['value'] : '',
247 - 'description' => isset( $entry['description'] ) ? (string) $entry['description'] : '',
248 - 'scriptUrl' => $payload['url'],
249 - 'scriptHandle' => $handle,
250 - 'scriptBefore' => $payload['before'],
251 - 'scriptAfter' => $payload['after'],
252 - 'scriptL10n' => $payload['l10n'],
251 + $payload = openstation_resolve_script_payload( $handle );
252 + $out[] = array(
253 + 'id' => (string) $entry['id'],
254 + 'label' => isset( $entry['label'] ) ? (string) $entry['label'] : '',
255 + 'preview' => isset( $entry['preview'] ) ? (string) $entry['preview'] : '',
256 + 'type' => isset( $entry['type'] ) ? (string) $entry['type'] : 'canvas',
257 + 'value' => isset( $entry['value'] ) ? (string) $entry['value'] : '',
258 + 'description' => isset( $entry['description'] ) ? (string) $entry['description'] : '',
259 + 'tone' => isset( $entry['tone'] ) ? (string) $entry['tone'] : '',
260 + 'scriptUrl' => $payload['url'],
261 + 'scriptHandle' => $handle,
262 + 'scriptBefore' => $payload['before'],
263 + 'scriptAfter' => $payload['after'],
264 + 'scriptL10n' => $payload['l10n'],
253 265 'scriptTranslations' => $payload['translations'],
266 + // The handle's dependency closure, replayed before the bundle
267 + // on its lazy load — see `openstation_resolve_script_dependencies()`.
268 + 'scriptDeps' => openstation_resolve_script_dependencies( $handle ),
254 269 );
255 270 }
256 271 return $out;
257 272 }
@@ -256,27 +271,23 @@
256 271 return $out;
257 272 }
258 273
259 274
260 -/**
261 - * Enqueue plugin-registered wallpaper scripts on the shell page
262 - * so wallpapers active at boot time have their defs available
263 - * without any dynamic-load roundtrip.
275 +/*
276 + * Wallpaper scripts are NOT enqueued here, and that is deliberate.
264 277 *
265 - * @since 0.8.1
278 + * A canvas wallpaper's bundle IS the wallpaper — Living Tree is 58 KB
279 + * of PixiJS scene, Snow is 42 KB — and this file used to
280 + * `wp_enqueue_script()` every registered one on every admin page, so
281 + * that every user downloaded and parsed every wallpaper in the
282 + * install including the ones they were not wearing. The metadata in
283 + * the boot payload (label, preview swatch, description) is enough for
284 + * the shell to register a stub and paint a picker tile without any of
285 + * it.
286 + *
287 + * The bundle arrives when something needs the callbacks: the shell
288 + * hydrates the user's ACTIVE wallpaper during the boot sync, and the
289 + * wallpaper picker hydrates the rest when it opens. See
290 + * `src/wallpapers/lazy.ts`. `scriptUrl` in the payload (built above)
291 + * is what makes that possible; nothing else on the PHP side is
292 + * involved.
266 293 */
267 -function desktop_mode_enqueue_desktop_wallpaper_scripts() {
268 - if ( ! desktop_mode_is_enabled() || desktop_mode_is_chromeless_request() || desktop_mode_is_classic_request() ) {
269 - return;
270 - }
271 - $registry = desktop_mode_desktop_wallpaper_registry();
272 - if ( ! is_array( $registry ) ) {
273 - return;
274 - }
275 - foreach ( $registry as $entry ) {
276 - if ( ! empty( $entry['script'] ) ) {
277 - wp_enqueue_script( $entry['script'] );
278 - }
279 - }
280 -}
281 -add_action( 'admin_enqueue_scripts', 'desktop_mode_enqueue_desktop_wallpaper_scripts', 20 );
282 -