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/games/registry.php +74 -0 1.1.21.1.10 View file →
@@ -75,8 +75,21 @@
75 75 * underneath (`wordsUrl` — see
76 76 * includes/games/config.php); the
77 77 * game's keys win on collision.
78 78 * @type string[] $capabilities Gate: ALL caps must match.
79 + * @type array $window The game window's size, as any
80 + * subset of `{ width, height,
81 + * minWidth, minHeight }` in pixels.
82 + * Declare it here as well as in the
83 + * JS def: a game's bundle is fetched
84 + * on first play, so the shell opens
85 + * the window — and paints its loading
86 + * spinner — before it has seen the
87 + * def. Without this the first window
88 + * of a session opens at the framework
89 + * default. The def still wins once it
90 + * arrives, so declaring only in JS
91 + * keeps working.
79 92 * }
80 93 * @return true|WP_Error `true` on success; `WP_Error` otherwise.
81 94 */
82 95 function openstation_register_game( $id, $args = array() ) {
@@ -96,8 +109,9 @@
96 109 'script' => '',
97 110 'score_columns' => array(),
98 111 'config' => array(),
99 112 'capabilities' => array(),
113 + 'window' => array(),
100 114 );
101 115 $args = wp_parse_args( $args, $defaults );
102 116
103 117 $svg = trim( (string) $args['icon_svg'] );
@@ -161,8 +175,9 @@
161 175 'icon' => openstation_sanitize_dock_icon( (string) $args['icon'] ),
162 176 'script' => (string) $args['script'],
163 177 'score_columns' => openstation_games_sanitize_score_columns( $args['score_columns'] ),
164 178 'config' => is_array( $args['config'] ) ? $args['config'] : array(),
179 + 'window' => openstation_games_sanitize_window( $args['window'] ),
165 180 );
166 181 openstation_games_registry( $id, $entry );
167 182
168 183 /**
@@ -179,8 +194,56 @@
179 194 return true;
180 195 }
181 196
182 197 /**
198 + * Normalize the `window` declaration — the game window's size, known
199 + * before its bundle is.
200 + *
201 + * **Why this is registered server-side at all**, when the JS def
202 + * already carries a `window` block: a game's bundle is heavyweight
203 + * (the game, its engine, sometimes a dictionary asset), so it is
204 + * fetched on first play rather than at boot. The shell therefore has
205 + * to open the window — and paint its loading spinner — *before* it has
206 + * ever seen the def. Without a size here that first window opens at
207 + * the framework default and would have to jump to the real size once
208 + * the def landed. With it, the size is right from the first frame.
209 + *
210 + * The JS def still wins once it arrives, so a game that declares only
211 + * in JS keeps working exactly as before; it simply gets the default
212 + * size on the first open of a session.
213 + *
214 + * Values are clamped rather than rejected: a nonsensical size is a
215 + * plugin bug that should not stop the game opening, and an unopenable
216 + * window is a worse answer than an oddly-sized one.
217 + *
218 + * @internal
219 + *
220 + * @param mixed $window Raw caller input.
221 + * @return array Sanitized subset of `{ width, height, minWidth, minHeight }`.
222 + */
223 +function openstation_games_sanitize_window( $window ) {
224 + if ( ! is_array( $window ) ) {
225 + return array();
226 + }
227 + $out = array();
228 + foreach ( array( 'width', 'height', 'minWidth', 'minHeight' ) as $key ) {
229 + if ( ! isset( $window[ $key ] ) || ! is_numeric( $window[ $key ] ) ) {
230 + continue;
231 + }
232 + $value = (int) $window[ $key ];
233 + if ( $value <= 0 ) {
234 + continue;
235 + }
236 + // The ceiling is generous on purpose — it exists to catch a
237 + // typo'd pixel value, not to have an opinion about how big a
238 + // game may be. The window manager clamps to the viewport anyway.
239 + $out[ $key ] = min( $value, 10000 );
240 + }
241 +
242 + return $out;
243 +}
244 +
245 +/**
183 246 * Normalize the `score_columns` declaration: drop rows without a
184 247 * valid key, default labels to the key, and clamp `type` to the
185 248 * supported set.
186 249 *
@@ -348,8 +411,16 @@
348 411 'config' => array_merge(
349 412 openstation_games_framework_config(),
350 413 isset( $entry['config'] ) && is_array( $entry['config'] ) ? $entry['config'] : array()
351 414 ),
415 + // The window's size, known before its bundle is — so the
416 + // shell can open the window (and start its loading spinner)
417 + // on the click rather than after the download. Omitted
418 + // entirely when the game declared none, which reads as
419 + // "use the framework defaults" on the JS side.
420 + 'window' => isset( $entry['window'] ) && is_array( $entry['window'] )
421 + ? $entry['window']
422 + : array(),
352 423 'scriptUrl' => $payload['url'],
353 424 'scriptHandle' => $handle,
354 425 'scriptBefore' => $payload['before'],
355 426 'scriptAfter' => $payload['after'],
@@ -354,8 +425,11 @@
354 425 'scriptBefore' => $payload['before'],
355 426 'scriptAfter' => $payload['after'],
356 427 'scriptL10n' => $payload['l10n'],
357 428 'scriptTranslations' => $payload['translations'],
429 + // The handle's dependency closure, replayed before the bundle
430 + // on its lazy load — see `openstation_resolve_script_dependencies()`.
431 + 'scriptDeps' => openstation_resolve_script_dependencies( $handle ),
358 432 );
359 433 }
360 434 return $out;
361 435 }