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/registries/wallpapers.php +91 -82 0.8.71.1.10 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.10.0
58 - * @since 0.11.0 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
@@ -78,19 +72,24 @@
78 72 * @type string $script Enqueued script handle that
79 73 * publishes the def on the global.
80 74 * Required for `canvas` type;
81 75 * optional for `css`.
76 + * @type string $description Plain-text description shown in OS
77 + * Settings when the wallpaper is the
78 + * active selection — what it is, where
79 + * its data comes from, the story behind
80 + * it. Optional.
82 81 * @type string[] $capabilities Gate: ALL caps must match. Any
83 82 * missed cap returns
84 - * `WP_Error desktop_mode_capability_denied`.
83 + * `WP_Error openstation_capability_denied`.
85 84 * }
86 85 * @return true|WP_Error `true` on success; `WP_Error` otherwise.
87 86 */
88 -function desktop_mode_register_wallpaper( $id, $args = array() ) {
87 +function openstation_register_wallpaper( $id, $args = array() ) {
89 88 $id = (string) $id;
90 89 if ( '' === $id ) {
91 - return desktop_mode_registration_error(
92 - 'desktop_mode_missing_id',
90 + return openstation_registration_error(
91 + 'openstation_missing_id',
93 92 __( 'Wallpaper id is required.', 'desktop-mode' )
94 93 );
95 94 }
96 95
@@ -99,28 +98,32 @@
99 98 'preview' => '',
100 99 'type' => 'canvas',
101 100 'value' => '',
102 101 'script' => '',
102 + 'description' => '',
103 103 'capabilities' => array(),
104 104 );
105 - $args = wp_parse_args( $args, $defaults );
105 + $args = wp_parse_args( $args, $defaults );
106 106
107 107 foreach ( (array) $args['capabilities'] as $cap ) {
108 108 if ( ! current_user_can( (string) $cap ) ) {
109 - return desktop_mode_registration_error(
110 - 'desktop_mode_capability_denied',
109 + return openstation_registration_error(
110 + 'openstation_capability_denied',
111 111 sprintf(
112 112 /* translators: %s: capability slug. */
113 113 __( 'Current user lacks the %s capability required to register this wallpaper.', 'desktop-mode' ),
114 114 (string) $cap
115 115 ),
116 - array( 'capability' => (string) $cap, 'id' => $id )
116 + array(
117 + 'capability' => (string) $cap,
118 + 'id' => $id,
119 + )
117 120 );
118 121 }
119 122 }
120 123 if ( '' === (string) $args['label'] ) {
121 - return desktop_mode_registration_error(
122 - 'desktop_mode_missing_label',
124 + return openstation_registration_error(
125 + 'openstation_missing_label',
123 126 __( 'Wallpaper registration requires a non-empty `label`.', 'desktop-mode' ),
124 127 array( 'id' => $id )
125 128 );
126 129 }
@@ -131,10 +134,10 @@
131 134 // `mount` callback is published on the JS global by that
132 135 // script). CSS wallpapers can skip the script — the shell can
133 136 // render from the `value` / `preview` string alone.
134 137 if ( 'canvas' === $type && '' === (string) $args['script'] ) {
135 - return desktop_mode_registration_error(
136 - 'desktop_mode_missing_script',
138 + return openstation_registration_error(
139 + 'openstation_missing_script',
137 140 __( 'Canvas wallpaper registration requires a `script` handle that publishes the def.', 'desktop-mode' ),
138 141 array( 'id' => $id )
139 142 );
140 143 }
@@ -148,29 +151,40 @@
148 151 $value = (string) $args['preview'];
149 152 }
150 153
151 154 $entry = array(
152 - 'id' => $id,
153 - 'label' => (string) $args['label'],
154 - 'preview' => (string) $args['preview'],
155 - 'type' => $type,
156 - 'value' => $value,
157 - 'script' => (string) $args['script'],
155 + 'id' => $id,
156 + // Plain text by contract, same as `description` below. The
157 + // shell paints labels through the `html` tagged template, whose
158 + // text slots build DOM with `createTextNode()` — never
159 + // `innerHTML` — so a label cannot become markup downstream.
160 + //
161 + // Note this STRIPS rather than ESCAPES, and that distinction is
162 + // load-bearing: `esc_html()` here would encode `&` in a
163 + // perfectly ordinary label ("Black & White") and the text node
164 + // would then render the entity literally as `&amp;`. Escaping
165 + // belongs at an HTML boundary; there isn't one on this path.
166 + 'label' => sanitize_text_field( (string) $args['label'] ),
167 + 'preview' => (string) $args['preview'],
168 + 'type' => $type,
169 + 'value' => $value,
170 + 'script' => (string) $args['script'],
171 + // Plain text by contract — the shell renders it as text, never
172 + // as HTML, so strip tags here rather than trusting every caller.
173 + 'description' => sanitize_textarea_field( (string) $args['description'] ),
158 174 );
159 - desktop_mode_desktop_wallpaper_registry( $id, $entry );
175 + openstation_desktop_wallpaper_registry( $id, $entry );
160 176
161 177 /**
162 178 * Fires after a desktop wallpaper is successfully registered.
163 179 *
164 - * Does NOT fire when `desktop_mode_register_wallpaper()` returns a
180 + * Does NOT fire when `openstation_register_wallpaper()` returns a
165 181 * `WP_Error`.
166 182 *
167 - * @since 0.11.0
168 - *
169 183 * @param string $id The wallpaper id.
170 184 * @param array $entry The stored registry entry.
171 185 */
172 - do_action( 'desktop_mode_wallpaper_registered', $id, $entry );
186 + do_action( 'openstation_wallpaper_registered', $id, $entry );
173 187
174 188 return true;
175 189 }
176 190
@@ -175,15 +189,14 @@
175 189 }
176 190
177 191 /**
178 192 * Internal module-level registry for wallpapers registered via
179 - * {@see desktop_mode_register_wallpaper()}. Same static-store
193 + * {@see openstation_register_wallpaper()}. Same static-store
180 194 * pattern as the widget + native-window registries.
181 195 *
182 - * @since 0.10.0
183 196 * @internal
184 197 */
185 -function desktop_mode_desktop_wallpaper_registry( $id = '', $entry = null ) {
198 +function openstation_desktop_wallpaper_registry( $id = '', $entry = null ) {
186 199 static $store = array();
187 200
188 201 if ( '' === (string) $id ) {
189 202 return $store;
@@ -198,28 +211,24 @@
198 211 * Build the wallpaper list for the shell payload. Only metadata +
199 212 * the resolved script URL cross the wire; the plugin's mount
200 213 * callback is announced via the JS global the script sets up.
201 214 *
202 - * @since 0.10.0
203 - *
204 215 * @return array[]
205 216 */
206 -function desktop_mode_build_desktop_wallpapers_payload() {
207 - $registry = desktop_mode_desktop_wallpaper_registry();
217 +function openstation_build_desktop_wallpapers_payload() {
218 + $registry = openstation_desktop_wallpaper_registry();
208 219 if ( ! is_array( $registry ) || empty( $registry ) ) {
209 220 return array();
210 221 }
211 222 /**
212 223 * Filters the server-declared wallpaper list before it ships to
213 - * the shell. Mirrors the JS-side `desktop-mode.wallpapers` filter
224 + * the shell. Mirrors the JS-side `os.wallpapers` filter
214 225 * so plugins can rearrange, hide, or override entries at boot
215 226 * without round-tripping through the JS registry.
216 227 *
217 - * @since 0.11.0
218 - *
219 228 * @param array[] $registry The registered wallpaper entries.
220 229 */
221 - $registry = apply_filters( 'desktop_mode_wallpapers', $registry );
230 + $registry = apply_filters( 'openstation_wallpapers', $registry );
222 231 if ( ! is_array( $registry ) ) {
223 232 return array();
224 233 }
225 234 $out = array();
@@ -227,21 +236,25 @@
227 236 if ( ! is_array( $entry ) || empty( $entry['id'] ) ) {
228 237 continue;
229 238 }
230 239 $handle = isset( $entry['script'] ) ? (string) $entry['script'] : '';
231 - $payload = desktop_mode_resolve_script_payload( $handle );
232 - $out[] = array(
233 - 'id' => (string) $entry['id'],
234 - 'label' => isset( $entry['label'] ) ? (string) $entry['label'] : '',
235 - 'preview' => isset( $entry['preview'] ) ? (string) $entry['preview'] : '',
236 - 'type' => isset( $entry['type'] ) ? (string) $entry['type'] : 'canvas',
237 - 'value' => isset( $entry['value'] ) ? (string) $entry['value'] : '',
238 - 'scriptUrl' => $payload['url'],
239 - 'scriptHandle' => $handle,
240 - 'scriptBefore' => $payload['before'],
241 - 'scriptAfter' => $payload['after'],
242 - 'scriptL10n' => $payload['l10n'],
240 + $payload = openstation_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'],
243 253 'scriptTranslations' => $payload['translations'],
254 + // The handle's dependency closure, replayed before the bundle
255 + // on its lazy load — see `openstation_resolve_script_dependencies()`.
256 + 'scriptDeps' => openstation_resolve_script_dependencies( $handle ),
244 257 );
245 258 }
246 259 return $out;
247 260 }
@@ -246,27 +259,23 @@
246 259 return $out;
247 260 }
248 261
249 262
250 -/**
251 - * Enqueue plugin-registered wallpaper scripts on the shell page
252 - * so wallpapers active at boot time have their defs available
253 - * without any dynamic-load roundtrip.
263 +/*
264 + * Wallpaper scripts are NOT enqueued here, and that is deliberate.
254 265 *
255 - * @since 0.10.0
266 + * A canvas wallpaper's bundle IS the wallpaper — Living Tree is 58 KB
267 + * of PixiJS scene, Snow is 42 KB — and this file used to
268 + * `wp_enqueue_script()` every registered one on every admin page, so
269 + * that every user downloaded and parsed every wallpaper in the
270 + * install including the ones they were not wearing. The metadata in
271 + * the boot payload (label, preview swatch, description) is enough for
272 + * the shell to register a stub and paint a picker tile without any of
273 + * it.
274 + *
275 + * The bundle arrives when something needs the callbacks: the shell
276 + * hydrates the user's ACTIVE wallpaper during the boot sync, and the
277 + * wallpaper picker hydrates the rest when it opens. See
278 + * `src/wallpapers/lazy.ts`. `scriptUrl` in the payload (built above)
279 + * is what makes that possible; nothing else on the PHP side is
280 + * involved.
256 281 */
257 -function desktop_mode_enqueue_desktop_wallpaper_scripts() {
258 - if ( ! desktop_mode_is_enabled() || desktop_mode_is_chromeless_request() || desktop_mode_is_classic_request() ) {
259 - return;
260 - }
261 - $registry = desktop_mode_desktop_wallpaper_registry();
262 - if ( ! is_array( $registry ) ) {
263 - return;
264 - }
265 - foreach ( $registry as $entry ) {
266 - if ( ! empty( $entry['script'] ) ) {
267 - wp_enqueue_script( $entry['script'] );
268 - }
269 - }
270 -}
271 -add_action( 'admin_enqueue_scripts', 'desktop_mode_enqueue_desktop_wallpaper_scripts', 20 );
272 -