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