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/components.php +117 -89 0.9.01.1.10 View file →
@@ -1,33 +1,34 @@
1 1 <?php
2 2 /**
3 - * Desktop Mode — PHP helpers for plugin authors.
3 + * OpenStation — PHP helpers for plugin authors.
4 4 *
5 5 * Two companion helpers live here:
6 6 *
7 - * - {@see desktop_mode_component()} prints a `<wpd-*>` tag with
8 - * safely-escaped attributes. The intent is explicit (we're
9 - * rendering a kit component, not arbitrary HTML) and the
10 - * escape discipline is automatic.
7 + * - {@see openstation_component()} prints a `<os-*>` tag with
8 + * safely-escaped attributes (plus its style-array
9 + * serializers). The intent is explicit (we're rendering a kit
10 + * component, not arbitrary HTML) and the escape discipline is
11 + * automatic.
11 12 *
12 - * - {@see desktop_mode_register_window()} collapses the
13 - * boilerplate for declaring a PHP-owned native window: one
14 - * call emits the `<template>` the shell clones, enqueues
15 - * the plugin's JS render bundle, and wires a dock tile on
16 - * window-ready. Plugins write the template callback
17 - * + the render callback on the JS side — the plumbing is ours.
13 + * - {@see openstation_enqueue_script()} wraps
14 + * `wp_enqueue_script()` with the `openstation` + `wp-hooks`
15 + * dependencies pre-wired, so shell-extending scripts always
16 + * load after `wp.os.*` and `wp.hooks` are available.
18 17 *
19 - * @package WPDesktopMode
20 - * @since 0.10.0
18 + * {@see openstation_register_window()} moved to
19 + * `includes/registries/native-windows.php`.
20 + *
21 + * @package OpenStation
21 22 */
22 23
23 24 defined( 'ABSPATH' ) || exit;
24 25
25 26 /**
26 - * Output a `<wpd-*>` component with safely escaped attributes.
27 + * Output a `<os-*>` component with safely escaped attributes.
27 28 *
28 29 * ```php
29 - * desktop_mode_component( 'wpd-button', array(
30 + * openstation_component( 'os-button', array(
30 31 * 'variant' => 'primary',
31 32 * 'data-op' => 'add',
32 33 * 'aria-label' => __( 'Add', 'my-plugin' ),
33 34 * ), '+' );
@@ -40,9 +41,9 @@
40 41 *
41 42 * Boolean-style attributes (present with a `true` value or an
42 43 * empty string) render as bare attributes (`disabled`,
43 44 * `fill-cell`) — matches the HTML5 boolean-attribute convention
44 - * every `<wpd-*>` follows.
45 + * every `<os-*>` follows.
45 46 *
46 47 * ## Inline styles
47 48 *
48 49 * The `style` key accepts either the usual string value or an
@@ -52,9 +53,9 @@
52 53 * …) so `'padding' => 0` produces `padding: 0` and
53 54 * `'padding' => 16` produces `padding: 16px`.
54 55 *
55 56 * ```php
56 - * desktop_mode_component( 'wpd-stack', array(
57 + * openstation_component( 'os-stack', array(
57 58 * 'gap' => 12,
58 59 * 'style' => array(
59 60 * 'padding' => 0,
60 61 * 'background' => 'rgba(0,0,0,0.04)',
@@ -60,34 +61,31 @@
60 61 * 'background' => 'rgba(0,0,0,0.04)',
61 62 * 'border-radius' => 8,
62 63 * ),
63 64 * ), $children );
64 - * // <wpd-stack gap="12" style="padding: 0; background: rgba(0,0,0,0.04); border-radius: 8px">
65 + * // <os-stack gap="12" style="padding: 0; background: rgba(0,0,0,0.04); border-radius: 8px">
65 66 * ```
66 67 *
67 68 * Plain string form (for one-line overrides) keeps working:
68 69 *
69 70 * ```php
70 - * desktop_mode_component( 'wpd-stack', array(
71 + * openstation_component( 'os-stack', array(
71 72 * 'style' => 'padding: 0; margin-top: 16px',
72 73 * ), $children );
73 74 * ```
74 75 *
75 - * @since 0.10.0
76 - * @since 0.13.0 `style` accepts an array of CSS declarations.
77 - *
78 - * @param string $tag Tag name, e.g. `wpd-button`.
79 - * Whitelisted to the `wpd-*` prefix
80 - * to prevent the helper being
81 - * misused as a generic HTML emitter.
82 - * @param array<string,mixed> $attrs Attribute key/value pairs.
83 - * `style` may be a string or an
84 - * associative array (see above).
85 - * @param string $content Inner HTML. Pass pre-escaped.
76 + * @param string $tag Tag name, e.g. `os-button`.
77 + * Whitelisted to the `os-*` prefix
78 + * to prevent the helper being
79 + * misused as a generic HTML emitter.
80 + * @param array<string,mixed> $attrs Attribute key/value pairs.
81 + * `style` may be a string or an
82 + * associative array (see above).
83 + * @param string $content Inner HTML. Pass pre-escaped.
86 84 */
87 -function desktop_mode_component( $tag, $attrs = array(), $content = '' ) {
85 +function openstation_component( $tag, $attrs = array(), $content = '' ) {
88 86 $tag = strtolower( (string) $tag );
89 - if ( ! preg_match( '/^wpd-[a-z][a-z0-9-]*$/', $tag ) ) {
87 + if ( ! preg_match( '/^os-[a-z][a-z0-9-]*$/', $tag ) ) {
90 88 // Fail loud in debug so a typo surfaces immediately; silently
91 89 // drop the output in production so a plugin with a bad tag
92 90 // doesn't blow up the page.
93 91 if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
@@ -94,12 +92,12 @@
94 92 _doing_it_wrong(
95 93 __FUNCTION__,
96 94 sprintf(
97 95 /* translators: %s: the attempted tag name. */
98 - esc_html__( 'desktop_mode_component() only accepts tags with the wpd- prefix; got "%s".', 'desktop-mode' ),
96 + esc_html__( 'openstation_component() only accepts tags with the os- prefix; got "%s".', 'desktop-mode' ),
99 97 esc_html( $tag )
100 98 ),
101 - '0.10.0'
99 + '0.5.0'
102 100 );
103 101 }
104 102 return;
105 103 }
@@ -118,9 +116,9 @@
118 116 // Style array — serialize to a CSS declaration list. Plain
119 117 // string values fall through to the generic attribute path
120 118 // below so `'style' => 'padding:0'` keeps working.
121 119 if ( 'style' === strtolower( $key ) && is_array( $value ) ) {
122 - $serialized = desktop_mode_serialize_style_array( $value );
120 + $serialized = openstation_serialize_style_array( $value );
123 121 if ( '' === $serialized ) {
124 122 continue;
125 123 }
126 124 $attr_parts[] = sprintf(
@@ -147,9 +145,9 @@
147 145 esc_html__( 'Attribute "%1$s" on <%2$s> received a non-scalar value (array/object). Only the `style` attribute accepts an array; other attributes must be strings, booleans, or null. The attribute was skipped.', 'desktop-mode' ),
148 146 esc_html( $key ),
149 147 esc_html( $tag )
150 148 ),
151 - '0.18.0'
149 + '0.5.2'
152 150 );
153 151 continue;
154 152 }
155 153 $attr_parts[] = sprintf(
@@ -162,9 +160,9 @@
162 160 $attr_str = $attr_parts ? ' ' . implode( ' ', $attr_parts ) : '';
163 161
164 162 printf(
165 163 '<%1$s%2$s>%3$s</%1$s>',
166 - // `$tag` is validated above against the wpd- allowlist; safe.
164 + // `$tag` is validated above against the os- allowlist; safe.
167 165 $tag, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
168 166 // `$attr_str` is pre-escaped via esc_attr() for each component.
169 167 $attr_str, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
170 168 // `$content` is the caller's responsibility to pre-escape.
@@ -177,32 +175,66 @@
177 175 * the length-shaped property list used by plugin JS code when
178 176 * interpreting raw numeric values — keeping the same list in
179 177 * one place so PHP `'padding' => 16` and JS `padding: 16` make
180 178 * the same visual decision.
181 - *
182 - * @since 0.13.0
183 179 */
184 -const DESKTOP_MODE_LENGTH_CSS_PROPERTIES = array(
185 - 'width', 'height',
186 - 'min-width', 'min-height', 'max-width', 'max-height',
187 - 'padding', 'padding-top', 'padding-right', 'padding-bottom', 'padding-left',
188 - 'padding-inline', 'padding-inline-start', 'padding-inline-end',
189 - 'padding-block', 'padding-block-start', 'padding-block-end',
190 - 'margin', 'margin-top', 'margin-right', 'margin-bottom', 'margin-left',
191 - 'margin-inline', 'margin-inline-start', 'margin-inline-end',
192 - 'margin-block', 'margin-block-start', 'margin-block-end',
193 - 'gap', 'row-gap', 'column-gap',
194 - 'border-width', 'border-top-width', 'border-right-width',
195 - 'border-bottom-width', 'border-left-width',
180 +const OPENSTATION_LENGTH_CSS_PROPERTIES = array(
181 + 'width',
182 + 'height',
183 + 'min-width',
184 + 'min-height',
185 + 'max-width',
186 + 'max-height',
187 + 'padding',
188 + 'padding-top',
189 + 'padding-right',
190 + 'padding-bottom',
191 + 'padding-left',
192 + 'padding-inline',
193 + 'padding-inline-start',
194 + 'padding-inline-end',
195 + 'padding-block',
196 + 'padding-block-start',
197 + 'padding-block-end',
198 + 'margin',
199 + 'margin-top',
200 + 'margin-right',
201 + 'margin-bottom',
202 + 'margin-left',
203 + 'margin-inline',
204 + 'margin-inline-start',
205 + 'margin-inline-end',
206 + 'margin-block',
207 + 'margin-block-start',
208 + 'margin-block-end',
209 + 'gap',
210 + 'row-gap',
211 + 'column-gap',
212 + 'border-width',
213 + 'border-top-width',
214 + 'border-right-width',
215 + 'border-bottom-width',
216 + 'border-left-width',
196 217 'border-radius',
197 - 'border-top-left-radius', 'border-top-right-radius',
198 - 'border-bottom-left-radius', 'border-bottom-right-radius',
199 - 'top', 'right', 'bottom', 'left',
218 + 'border-top-left-radius',
219 + 'border-top-right-radius',
220 + 'border-bottom-left-radius',
221 + 'border-bottom-right-radius',
222 + 'top',
223 + 'right',
224 + 'bottom',
225 + 'left',
200 226 'inset',
201 - 'inset-inline-start', 'inset-inline-end',
202 - 'inset-block-start', 'inset-block-end',
203 - 'font-size', 'letter-spacing', 'word-spacing', 'text-indent',
204 - 'outline-width', 'outline-offset',
227 + 'inset-inline-start',
228 + 'inset-inline-end',
229 + 'inset-block-start',
230 + 'inset-block-end',
231 + 'font-size',
232 + 'letter-spacing',
233 + 'word-spacing',
234 + 'text-indent',
235 + 'outline-width',
236 + 'outline-offset',
205 237 );
206 238
207 239 /**
208 240 * Serialize an associative array of CSS declarations into a
@@ -214,15 +246,13 @@
214 246 * so callers can write `'padding' => 16` without remembering the
215 247 * unit. The literal `0` is left unit-less because CSS treats it
216 248 * as dimensionally valid on any property.
217 249 *
218 - * @since 0.13.0
219 - *
220 250 * @param array<string,mixed> $styles
221 251 * @return string CSS declaration list, or empty string when no
222 252 * valid declarations were produced.
223 253 */
224 -function desktop_mode_serialize_style_array( $styles ) {
254 +function openstation_serialize_style_array( $styles ) {
225 255 if ( ! is_array( $styles ) ) {
226 256 return '';
227 257 }
228 258 $parts = array();
@@ -233,9 +263,9 @@
233 263 }
234 264 if ( false === $value || null === $value ) {
235 265 continue;
236 266 }
237 - $serialized = desktop_mode_format_css_value( $prop, $value );
267 + $serialized = openstation_format_css_value( $prop, $value );
238 268 if ( '' === $serialized ) {
239 269 continue;
240 270 }
241 271 $parts[] = $prop . ': ' . $serialized;
@@ -255,16 +285,14 @@
255 285 *
256 286 * Everything else (strings, floats already unitted, calc(…)
257 287 * expressions, color keywords) passes through verbatim.
258 288 *
259 - * @since 0.13.0
260 - *
261 289 * @param string $property CSS property name.
262 290 * @param mixed $value Raw value (int, float, string).
263 291 * @return string CSS value, or empty string when $value is
264 292 * not serializable.
265 293 */
266 -function desktop_mode_format_css_value( $property, $value ) {
294 +function openstation_format_css_value( $property, $value ) {
267 295 if ( is_bool( $value ) || null === $value ) {
268 296 return '';
269 297 }
270 298 $text = trim( (string) $value );
@@ -274,9 +302,9 @@
274 302 if ( preg_match( '/^-?\d+(\.\d+)?$/', $text ) ) {
275 303 if ( '0' === $text ) {
276 304 return '0';
277 305 }
278 - if ( in_array( $property, DESKTOP_MODE_LENGTH_CSS_PROPERTIES, true ) ) {
306 + if ( in_array( $property, OPENSTATION_LENGTH_CSS_PROPERTIES, true ) ) {
279 307 return $text . 'px';
280 308 }
281 309 }
282 310 return $text;
@@ -284,28 +312,28 @@
284 312
285 313
286 314 // Native-windows registry (register_window, allowed_html,
287 315 // template-html builder, enqueue + render hooks) was moved to
288 -// `includes/registries/native-windows.php` in 0.8.1.
316 +// `includes/registries/native-windows.php`.
289 317
290 318
291 319
292 320 // Widgets registry was moved to
293 -// `includes/registries/widgets.php` in 0.8.1.
321 +// `includes/registries/widgets.php`.
294 322
295 323
296 324
297 325 // Wallpapers registry was moved to
298 -// `includes/registries/wallpapers.php` in 0.8.1.
326 +// `includes/registries/wallpapers.php`.
299 327
300 328
301 329 // Desktop-icons registry was moved to
302 -// `includes/registries/icons.php` in 0.8.1.
330 +// `includes/registries/icons.php`.
303 331
304 332
305 333
306 334 // Native-window tabs registry was moved to
307 -// `includes/registries/window-tabs.php` in 0.8.1.
335 +// `includes/registries/window-tabs.php`.
308 336
309 337
310 338 /**
311 339 * Enqueue a plugin script that extends the desktop shell.
@@ -312,14 +340,16 @@
312 340 *
313 341 * Thin wrapper around `wp_enqueue_script` that pre-wires the correct
314 342 * dependencies so the script:
315 343 *
316 - * - Runs AFTER `desktop-mode` (the shell bundle) so `wp.desktop.*` is
344 + * - Runs AFTER `openstation` (the shell bundle) so `wp.os.*` is
317 345 * guaranteed available.
318 - * - Runs AFTER `wp-hooks` so `wp.hooks.addAction( 'desktop-mode.init', ... )`
346 + * - Runs AFTER `wp-hooks` so `wp.hooks.addAction( 'os.init', ... )`
319 347 * works without the plugin author having to remember that dep.
320 - * - Is only enqueued in the admin (shell only boots there).
321 348 *
349 + * Intended to be called from `admin_enqueue_scripts` — the wrapper
350 + * itself does not add an `is_admin()` guard.
351 + *
322 352 * Drop-in replacement for the boilerplate:
323 353 *
324 354 * ```php
325 355 * add_action( 'admin_enqueue_scripts', function () {
@@ -325,9 +355,9 @@
325 355 * add_action( 'admin_enqueue_scripts', function () {
326 356 * wp_enqueue_script(
327 357 * 'my-plugin',
328 358 * plugins_url( 'my-plugin.js', __FILE__ ),
329 - * array( 'desktop-mode', 'wp-hooks' ),
359 + * array( 'openstation', 'wp-hooks' ),
330 360 * '1.0.0',
331 361 * true
332 362 * );
333 363 * } );
@@ -336,9 +366,9 @@
336 366 * which becomes:
337 367 *
338 368 * ```php
339 369 * add_action( 'admin_enqueue_scripts', function () {
340 - * desktop_mode_enqueue_script(
370 + * openstation_enqueue_script(
341 371 * 'my-plugin',
342 372 * plugins_url( 'my-plugin.js', __FILE__ ),
343 373 * array(), // extra deps on top of the desktop defaults
344 374 * '1.0.0'
@@ -345,25 +375,23 @@
345 375 * );
346 376 * } );
347 377 * ```
348 378 *
349 - * @since 0.14.0
350 - *
351 - * @param string $handle Script handle.
352 - * @param string $src Full URL of the script, or path relative
353 - * to the WordPress root directory.
354 - * @param string[] $extra_deps Additional dependency handles. `desktop-mode`
355 - * and `wp-hooks` are always prepended.
379 + * @param string $handle Script handle.
380 + * @param string $src Full URL of the script, or path relative
381 + * to the WordPress root directory.
382 + * @param string[] $extra_deps Additional dependency handles. `openstation`
383 + * and `wp-hooks` are always prepended.
356 384 * @param string|bool|null $version Version string, or `false` for none.
357 - * Defaults to `DESKTOP_MODE_VERSION` so plugin authors
385 + * Defaults to `OPENSTATION_VERSION` so plugin authors
358 386 * don't have to busy-track cache busting.
359 - * @param bool $in_footer Whether to enqueue in the footer. Defaults
360 - * to `true` — the shell is always in head.
387 + * @param bool $in_footer Whether to enqueue in the footer. Defaults
388 + * to `true` — the shell is always in head.
361 389 * @return void
362 390 */
363 -function desktop_mode_enqueue_script( $handle, $src, $extra_deps = array(), $version = null, $in_footer = true ) {
391 +function openstation_enqueue_script( $handle, $src, $extra_deps = array(), $version = null, $in_footer = true ) {
364 392 $deps = array_merge(
365 - array( 'desktop-mode', 'wp-hooks' ),
393 + array( 'openstation', 'wp-hooks' ),
366 394 is_array( $extra_deps ) ? $extra_deps : array()
367 395 );
368 396
369 397 wp_enqueue_script(
@@ -369,8 +397,8 @@
369 397 wp_enqueue_script(
370 398 $handle,
371 399 $src,
372 400 $deps,
373 - null === $version ? DESKTOP_MODE_VERSION : $version,
401 + null === $version ? OPENSTATION_VERSION : $version,
374 402 $in_footer
375 403 );
376 404 }